207 lines
4.5 KiB
C
207 lines
4.5 KiB
C
/*++
|
||
|
||
Copyright (c) 2001 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
res.c
|
||
|
||
Abstract:
|
||
|
||
This module implements Win32 Resource Manager APIs
|
||
|
||
Author:
|
||
|
||
Rob Earhart (Earhart) 04-Apr-2001
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "basedll.h"
|
||
|
||
//
|
||
// N.B. This is a stub implementation intended to provide basic
|
||
// resource management interfaces for applications which care
|
||
// about their memory usage. It is NOT the final version of the
|
||
// usermode side of the resource manager.
|
||
//
|
||
|
||
|
||
//
|
||
// Globals used by the routines in this module
|
||
//
|
||
|
||
const WCHAR BasepMmLowMemoryConditionEventName[] = L"\\KernelObjects\\LowMemoryCondition";
|
||
const WCHAR BasepMmHighMemoryConditionEventName[] = L"\\KernelObjects\\HighMemoryCondition";
|
||
|
||
HANDLE
|
||
APIENTRY
|
||
CreateMemoryResourceNotification(
|
||
IN MEMORY_RESOURCE_NOTIFICATION_TYPE NotificationType
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Creates a memory resource notification handle. Memory resource
|
||
notification handles monitor memory for changes, and are used
|
||
to query information about memory.
|
||
|
||
Arguments:
|
||
|
||
NotificationType -- the type of notification requested
|
||
|
||
Return Value:
|
||
|
||
Non-NULL - a handle to the new subscription object.
|
||
|
||
NULL - The operation failed. Extended error status is available
|
||
using GetLastError.
|
||
|
||
--*/
|
||
|
||
{
|
||
LPCWSTR EventName;
|
||
HANDLE Handle;
|
||
OBJECT_ATTRIBUTES Obja;
|
||
UNICODE_STRING ObjectName;
|
||
NTSTATUS Status;
|
||
|
||
//
|
||
// Determine the event in which the caller's interested.
|
||
//
|
||
switch (NotificationType) {
|
||
case LowMemoryResourceNotification:
|
||
//
|
||
// It's the low memory condition event
|
||
//
|
||
EventName = BasepMmLowMemoryConditionEventName;
|
||
break;
|
||
|
||
case HighMemoryResourceNotification:
|
||
//
|
||
// It's the high memory condition event
|
||
//
|
||
EventName = BasepMmHighMemoryConditionEventName;
|
||
break;
|
||
|
||
default:
|
||
//
|
||
// Not one of our known event-of-interest types; all we can do
|
||
// is indicate an invalid parameter, and return a failure
|
||
// condition.
|
||
//
|
||
|
||
SetLastError(ERROR_INVALID_PARAMETER);
|
||
return NULL;
|
||
|
||
}
|
||
|
||
|
||
//
|
||
// Attempt the actual event open
|
||
//
|
||
RtlInitUnicodeString(&ObjectName, EventName);
|
||
|
||
InitializeObjectAttributes(&Obja,
|
||
&ObjectName,
|
||
0,
|
||
NULL,
|
||
NULL);
|
||
|
||
Status = NtOpenEvent(&Handle,
|
||
SYNCHRONIZE | EVENT_QUERY_STATE,
|
||
&Obja);
|
||
|
||
if (! NT_SUCCESS(Status)) {
|
||
//
|
||
// We failed to open the event for some reason.
|
||
//
|
||
BaseSetLastNTError(Status);
|
||
return NULL;
|
||
}
|
||
|
||
//
|
||
// Otherwise, we have the handle, so we're all set; just return it.
|
||
//
|
||
|
||
return Handle;
|
||
}
|
||
|
||
BOOL
|
||
APIENTRY
|
||
QueryMemoryResourceNotification(
|
||
IN HANDLE ResourceNotificationHandle,
|
||
IN PBOOL ResourceState
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Query a memory resource notification handle for information about
|
||
the associated memory resources.
|
||
|
||
Arguments:
|
||
|
||
ResourceNotificationHandle - a handle to the memory resource
|
||
notification to query.
|
||
|
||
ResourceState - location to put the information about the memory
|
||
resource
|
||
|
||
Return Value:
|
||
|
||
TRUE - The query succeeded.
|
||
|
||
FALSE - The query failed. Extended error status is available
|
||
using GetLastError.
|
||
|
||
--*/
|
||
|
||
{
|
||
EVENT_BASIC_INFORMATION EventInfo;
|
||
NTSTATUS Status;
|
||
|
||
//
|
||
// Check parameter validity
|
||
//
|
||
if (! ResourceNotificationHandle
|
||
|| ResourceNotificationHandle == INVALID_HANDLE_VALUE
|
||
|| ! ResourceState) {
|
||
|
||
SetLastError(ERROR_INVALID_PARAMETER);
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// Get the event's current state
|
||
//
|
||
Status = NtQueryEvent(ResourceNotificationHandle,
|
||
EventBasicInformation,
|
||
&EventInfo,
|
||
sizeof(EventInfo),
|
||
NULL);
|
||
|
||
if (! NT_SUCCESS(Status)) {
|
||
//
|
||
// On failure, set the last NT error and indicate the failure
|
||
// condition to our caller.
|
||
//
|
||
BaseSetLastNTError(Status);
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// Fill in the state
|
||
//
|
||
*ResourceState = (EventInfo.EventState == 1);
|
||
|
||
//
|
||
// And we're done -- return success to our caller.
|
||
//
|
||
return TRUE;
|
||
}
|