|
|
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
eventpr.c
Abstract:
This module implements the executive event pair object. Functions are provided to create, open, waitlow, waithi, setlow, sethi, sethiwaitlo, setlowaithi.
Author:
Mark Lucovsky (markl) 18-Oct-1990
Environment:
Kernel mode only.
Revision History:
--*/
#include "exp.h"
//
// Define performance counters.
//
ULONG EvPrSetHigh = 0; ULONG EvPrSetLow = 0;
//
// Address of event pair object type descriptor.
//
POBJECT_TYPE ExEventPairObjectType;
//
// Structure that describes the mapping of generic access rights to object
// specific access rights for event pair objects.
//
#ifdef ALLOC_DATA_PRAGMA
#pragma const_seg("INITCONST")
#endif
const GENERIC_MAPPING ExpEventPairMapping = { STANDARD_RIGHTS_READ | SYNCHRONIZE, STANDARD_RIGHTS_WRITE | SYNCHRONIZE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, EVENT_PAIR_ALL_ACCESS }; #ifdef ALLOC_DATA_PRAGMA
#pragma const_seg()
#endif
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, ExpEventPairInitialization)
#pragma alloc_text(PAGE, NtCreateEventPair)
#pragma alloc_text(PAGE, NtOpenEventPair)
#pragma alloc_text(PAGE, NtWaitLowEventPair)
#pragma alloc_text(PAGE, NtWaitHighEventPair)
#pragma alloc_text(PAGE, NtSetLowWaitHighEventPair)
#pragma alloc_text(PAGE, NtSetHighWaitLowEventPair)
#pragma alloc_text(PAGE, NtSetHighEventPair)
#pragma alloc_text(PAGE, NtSetLowEventPair)
#endif
BOOLEAN ExpEventPairInitialization ( )
/*++
Routine Description:
This function creates the event pair object type descriptor at system initialization and stores the address of the object type descriptor in global storage.
Arguments:
None.
Return Value:
A value of TRUE is returned if the event pair object type descriptor is successfully initialized. Otherwise a value of FALSE is returned.
--*/
{
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; NTSTATUS Status; UNICODE_STRING TypeName;
//
// Initialize string descriptor.
//
RtlInitUnicodeString(&TypeName, L"EventPair");
//
// Create event object type descriptor.
//
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; ObjectTypeInitializer.GenericMapping = ExpEventPairMapping; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(EEVENT_PAIR); ObjectTypeInitializer.ValidAccessMask = EVENT_PAIR_ALL_ACCESS; ObjectTypeInitializer.UseDefaultObject = TRUE; Status = ObCreateObjectType(&TypeName, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR)NULL, &ExEventPairObjectType);
//
// If the event pair object type descriptor was successfully created, then
// return a value of TRUE. Otherwise return a value of FALSE.
//
return (BOOLEAN)(NT_SUCCESS(Status)); }
NTSTATUS NtCreateEventPair ( OUT PHANDLE EventPairHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL )
/*++
Routine Description:
This function creates an event pair object, sets it initial state, and opens a handle to the object with the specified desired access.
Arguments:
EventPairHandle - Supplies a pointer to a variable that will receive the event pair object handle.
DesiredAccess - Supplies the desired types of access for the event pair object.
ObjectAttributes - Supplies a pointer to an object attributes structure.
Return Value:
NTSTATUS.
--*/
{
PEEVENT_PAIR EventPair; HANDLE Handle; KPROCESSOR_MODE PreviousMode; NTSTATUS Status;
//
// Establish an exception handler, probe the output handle address, and
// attempt to create an event object. If the probe fails, then return the
// exception code as the service status. Otherwise return the status value
// returned by the object insertion routine.
//
//
// Get previous processor mode and probe output handle address if
// necessary.
//
PreviousMode = KeGetPreviousMode();
if (PreviousMode != KernelMode) { try { ProbeForWriteHandle(EventPairHandle); } except (ExSystemExceptionFilter()) { return GetExceptionCode(); } }
//
// Allocate event object.
//
Status = ObCreateObject(PreviousMode, ExEventPairObjectType, ObjectAttributes, PreviousMode, NULL, sizeof(EEVENT_PAIR), 0, 0, (PVOID *)&EventPair);
//
// If the event pair object was successfully allocated, then
// initialize the event pair object and attempt to insert the
// event pair object in the current process' handle table.
//
if (NT_SUCCESS(Status)) { KeInitializeEventPair(&EventPair->KernelEventPair); Status = ObInsertObject((PVOID)EventPair, NULL, DesiredAccess, 0, (PVOID *)NULL, &Handle);
//
// If the event pair object was successfully inserted in the
// current process' handle table, then attempt to write the
// event pair object handle value. If the write attempt
// fails, then do not report an error. When the caller
// attempts to access the handle value, an access violation
// will occur.
if (NT_SUCCESS(Status)) { if (PreviousMode != KernelMode) { try { *EventPairHandle = Handle;
} except(ExSystemExceptionFilter()) { NOTHING; } } else { *EventPairHandle = Handle; } } }
//
// Return service status.
//
return Status; }
NTSTATUS NtOpenEventPair( OUT PHANDLE EventPairHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes )
/*++
Routine Description:
This function opens a handle to an event pair object with the specified desired access.
Arguments:
EventPairHandle - Supplies a pointer to a variable that will receive the event pair object handle.
DesiredAccess - Supplies the desired types of access for the event pair object.
ObjectAttributes - Supplies a pointer to an object attributes structure.
Return Value:
NTSTATUS.
--*/
{
HANDLE Handle; KPROCESSOR_MODE PreviousMode; NTSTATUS Status;
//
// Establish an exception handler, probe the output handle address, and
// attempt to open the event object. If the probe fails, then return the
// exception code as the service status. Otherwise return the status value
// returned by the object open routine.
//
//
// Get previous processor mode and probe output handle address
// if necessary.
//
PreviousMode = KeGetPreviousMode();
if (PreviousMode != KernelMode) { try { ProbeForWriteHandle(EventPairHandle); } except (ExSystemExceptionFilter()) { return GetExceptionCode(); } }
//
// Open handle to the event pair object with the specified
// desired access.
//
Status = ObOpenObjectByName(ObjectAttributes, ExEventPairObjectType, PreviousMode, NULL, DesiredAccess, NULL, &Handle);
//
// If the open was successful, then attempt to write the event
// pair object handle value. If the write attempt fails, then do
// not report an error. When the caller attempts to access the
// handle value, an access violation will occur.
//
if (NT_SUCCESS(Status)) { if (PreviousMode != KernelMode) { try { *EventPairHandle = Handle;
} except(ExSystemExceptionFilter()) { NOTHING; } } else { *EventPairHandle = Handle; } }
//
// Return service status.
//
return Status; }
NTSTATUS NtWaitLowEventPair( IN HANDLE EventPairHandle )
/*++
Routine Description:
This function waits on the low event of an event pair object.
Arguments:
EventPairHandle - Supplies a handle to an event pair object.
Return Value:
NTSTATUS.
--*/
{
PEEVENT_PAIR EventPair; KPROCESSOR_MODE PreviousMode; NTSTATUS Status;
//
// Reference event pair object by handle.
//
PreviousMode = KeGetPreviousMode(); Status = ObReferenceObjectByHandle(EventPairHandle, SYNCHRONIZE, ExEventPairObjectType, PreviousMode, (PVOID *)&EventPair, NULL);
//
// If the reference was successful, then wait on the Low event
// of the event pair.
//
if (NT_SUCCESS(Status)) { Status = KeWaitForLowEventPair(&EventPair->KernelEventPair, PreviousMode, FALSE, NULL);
ObDereferenceObject(EventPair); }
//
// Return service status.
//
return Status; }
NTSTATUS NtWaitHighEventPair( IN HANDLE EventPairHandle )
/*++
Routine Description:
This function waits on the high event of an event pair object.
Arguments:
EventPairHandle - Supplies a handle to an event pair object.
Return Value:
NTSTATUS.
--*/
{
PEEVENT_PAIR EventPair; KPROCESSOR_MODE PreviousMode; NTSTATUS Status;
//
// Reference event pair object by handle.
//
PreviousMode = KeGetPreviousMode(); Status = ObReferenceObjectByHandle(EventPairHandle, SYNCHRONIZE, ExEventPairObjectType, PreviousMode, (PVOID *)&EventPair, NULL);
//
// If the reference was successful, then wait on the Low event
// of the event pair.
//
if (NT_SUCCESS(Status)) { Status = KeWaitForHighEventPair(&EventPair->KernelEventPair, PreviousMode, FALSE, NULL);
ObDereferenceObject(EventPair); }
//
// Return service status.
//
return Status; }
NTSTATUS NtSetLowWaitHighEventPair( IN HANDLE EventPairHandle )
/*++
Routine Description:
This function sets the low event of an event pair and then waits on the high event of an event pair object.
Arguments:
EventPairHandle - Supplies a handle to an event pair object.
Return Value:
NTSTATUS.
--*/
{
PEEVENT_PAIR EventPair; KPROCESSOR_MODE PreviousMode; NTSTATUS Status;
//
// Reference event pair object by handle.
//
PreviousMode = KeGetPreviousMode(); Status = ObReferenceObjectByHandle(EventPairHandle, SYNCHRONIZE, ExEventPairObjectType, PreviousMode, (PVOID *)&EventPair, NULL);
//
// If the reference was successful, then wait on the Low event
// of the event pair.
//
if (NT_SUCCESS(Status)) { EvPrSetLow += 1; Status = KeSetLowWaitHighEventPair(&EventPair->KernelEventPair, PreviousMode);
ObDereferenceObject(EventPair); }
//
// Return service status.
//
return Status; }
NTSTATUS NtSetHighWaitLowEventPair( IN HANDLE EventPairHandle )
/*++
Routine Description:
This function sets the high event of an event pair and then waits on the low event of an event pair object.
Arguments:
EventPairHandle - Supplies a handle to an event pair object.
Return Value:
NTSTATUS.
--*/
{
PEEVENT_PAIR EventPair; KPROCESSOR_MODE PreviousMode; NTSTATUS Status;
//
// Reference event pair object by handle.
//
PreviousMode = KeGetPreviousMode(); Status = ObReferenceObjectByHandle(EventPairHandle, SYNCHRONIZE, ExEventPairObjectType, PreviousMode, (PVOID *)&EventPair, NULL);
//
// If the reference was successful, then wait on the Low event
// of the event pair.
//
if (NT_SUCCESS(Status)) { EvPrSetHigh += 1; Status = KeSetHighWaitLowEventPair(&EventPair->KernelEventPair, PreviousMode);
ObDereferenceObject(EventPair); }
//
// Return service status.
//
return Status; }
NTSTATUS NtSetLowEventPair( IN HANDLE EventPairHandle )
/*++
Routine Description:
This function sets the low event of an event pair object.
Arguments:
EventPairHandle - Supplies a handle to an event pair object.
Return Value:
NTSTATUS.
--*/
{
PEEVENT_PAIR EventPair; KPROCESSOR_MODE PreviousMode; NTSTATUS Status;
//
// Reference event pair object by handle.
//
PreviousMode = KeGetPreviousMode(); Status = ObReferenceObjectByHandle(EventPairHandle, SYNCHRONIZE, ExEventPairObjectType, PreviousMode, (PVOID *)&EventPair, NULL);
//
// If the reference was successful, then wait on the Low event
// of the event pair.
//
if (NT_SUCCESS(Status)) { EvPrSetLow += 1; KeSetLowEventPair(&EventPair->KernelEventPair, EVENT_PAIR_INCREMENT,FALSE);
ObDereferenceObject(EventPair); }
//
// Return service status.
//
return Status; }
NTSTATUS NtSetHighEventPair( IN HANDLE EventPairHandle )
/*++
Routine Description:
This function sets the high event of an event pair object.
Arguments:
EventPairHandle - Supplies a handle to an event pair object.
Return Value:
NTSTATUS.
--*/
{
PEEVENT_PAIR EventPair; KPROCESSOR_MODE PreviousMode; NTSTATUS Status;
//
// Reference event pair object by handle.
//
PreviousMode = KeGetPreviousMode(); Status = ObReferenceObjectByHandle(EventPairHandle, SYNCHRONIZE, ExEventPairObjectType, PreviousMode, (PVOID *)&EventPair, NULL);
//
// If the reference was successful, then wait on the Low event
// of the event pair.
//
if (NT_SUCCESS(Status)) { EvPrSetHigh += 1; KeSetHighEventPair(&EventPair->KernelEventPair, EVENT_PAIR_INCREMENT,FALSE);
ObDereferenceObject(EventPair); }
//
// Return service status.
//
return Status; }
|