407 lines
8.6 KiB
C
407 lines
8.6 KiB
C
/*++
|
||
|
||
Copyright (c) 1989 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
EventSup.c
|
||
|
||
Abstract:
|
||
|
||
This module implements the Named Pipe Event support routines.
|
||
|
||
Author:
|
||
|
||
Gary Kimura [GaryKi] 30-Aug-1990
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "NpProcs.h"
|
||
|
||
//
|
||
// The debug trace level
|
||
//
|
||
|
||
#define Dbg (DEBUG_TRACE_EVENTSUP)
|
||
|
||
//
|
||
// The following variable is exported from the kernel and is needed by npfs to
|
||
// determine if an event was handed down.
|
||
//
|
||
|
||
extern POBJECT_TYPE *ExEventObjectType;
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
#pragma alloc_text (PAGE, NpAddEventTableEntry)
|
||
#pragma alloc_text (PAGE, NpDeleteEventTableEntry)
|
||
#pragma alloc_text (PAGE, NpGetNextEventTableEntry)
|
||
#pragma alloc_text (PAGE, NpEventTableCompareRoutine)
|
||
#pragma alloc_text (PAGE, NpEventTableAllocate)
|
||
#pragma alloc_text (PAGE, NpEventTableDeallocate)
|
||
#endif
|
||
|
||
NTSTATUS
|
||
NpAddEventTableEntry (
|
||
IN PEVENT_TABLE EventTable,
|
||
IN PCCB Ccb,
|
||
IN NAMED_PIPE_END NamedPipeEnd,
|
||
IN HANDLE EventHandle,
|
||
IN ULONG KeyValue,
|
||
IN PEPROCESS Process,
|
||
IN KPROCESSOR_MODE PreviousMode,
|
||
OUT PEVENT_TABLE_ENTRY *ppEventTableEntry
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine adds a new entry into the event table. If an entry already
|
||
exists it overwrites the existing entry.
|
||
|
||
Arguments:
|
||
|
||
EventTable - Supplies the event table being modified
|
||
|
||
Ccb - Supplies a pointer to the ccb to store in event table entry
|
||
|
||
NamedPipeEnd - Indicates the server or client end for the event
|
||
|
||
EventHandle - Supplies the handle to the event being added. The object
|
||
is referenced by this procedure
|
||
|
||
KeyValue - Supplies a key value to associate with the event
|
||
|
||
Process - Supplies a pointer to the process adding the event
|
||
|
||
PreviousMode - Supplies the mode of the user initiating the action
|
||
|
||
Return Value:
|
||
|
||
PEVENT_TABLE_ENTRY - Returns a pointer to the newly added event.
|
||
This is an actual pointer to the table entry.
|
||
|
||
This procedure also will raise status if the event handle cannot be
|
||
accessed by the caller
|
||
|
||
--*/
|
||
|
||
{
|
||
NTSTATUS Status;
|
||
KIRQL OldIrql;
|
||
|
||
EVENT_TABLE_ENTRY Template;
|
||
PEVENT_TABLE_ENTRY EventTableEntry;
|
||
PVOID Event;
|
||
|
||
DebugTrace(+1, Dbg, "NpAddEventTableEntry, EventTable = %08lx\n", EventTable);
|
||
|
||
//
|
||
// Reference the event object by handle.
|
||
//
|
||
|
||
if (!NT_SUCCESS(Status = ObReferenceObjectByHandle( EventHandle,
|
||
EVENT_MODIFY_STATE,
|
||
*ExEventObjectType,
|
||
PreviousMode,
|
||
&Event,
|
||
NULL ))) {
|
||
|
||
return Status;
|
||
}
|
||
|
||
//
|
||
// Set up the template event entry to lookup
|
||
//
|
||
|
||
Template.Ccb = Ccb;
|
||
Template.NamedPipeEnd = NamedPipeEnd;
|
||
Template.EventHandle = EventHandle;
|
||
Template.Event = Event;
|
||
Template.KeyValue = KeyValue;
|
||
Template.Process = Process;
|
||
|
||
//
|
||
// Now insert this new entry into the event table
|
||
//
|
||
|
||
EventTableEntry = RtlInsertElementGenericTable( &EventTable->Table,
|
||
&Template,
|
||
sizeof(EVENT_TABLE_ENTRY),
|
||
NULL );
|
||
if (EventTableEntry == NULL) {
|
||
ObDereferenceObject (Event);
|
||
return STATUS_INSUFFICIENT_RESOURCES;
|
||
}
|
||
|
||
//
|
||
// Copy over the template again just in case we were given an
|
||
// old entry
|
||
//
|
||
|
||
*EventTableEntry = Template;
|
||
|
||
DebugTrace(-1, Dbg, "NpAddEventTableEntry -> %08lx\n", EventTableEntry);
|
||
|
||
//
|
||
// And now return to our caller
|
||
//
|
||
*ppEventTableEntry = EventTableEntry;
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
|
||
VOID
|
||
NpDeleteEventTableEntry (
|
||
IN PEVENT_TABLE EventTable,
|
||
IN PEVENT_TABLE_ENTRY Template
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine removes an entry from the event table, it also dereferences
|
||
the event object that was referenced when the object was inserted
|
||
|
||
Arguments:
|
||
|
||
EventTable - Supplies a pointer to the event table being modified
|
||
|
||
Template - Supplies a copy of the event table entry we are lookin up.
|
||
Note that this can also be a pointer to the actual event table entry.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
KIRQL OldIrql;
|
||
|
||
DebugTrace(+1, Dbg, "NpDeleteEventTableEntry, EventTable = %08lx\n", EventTable);
|
||
|
||
//
|
||
// Only do the work if we are given a non null template
|
||
//
|
||
|
||
if (!ARGUMENT_PRESENT(Template)) {
|
||
|
||
DebugTrace(-1, Dbg, "NpDeleteEventTableEntry -> VOID\n", 0);
|
||
|
||
return;
|
||
}
|
||
|
||
//
|
||
// Dereference the event object
|
||
//
|
||
|
||
ObDereferenceObject(Template->Event);
|
||
|
||
//
|
||
// Now remove this element from the generic table
|
||
//
|
||
|
||
(VOID)RtlDeleteElementGenericTable( &EventTable->Table,
|
||
Template );
|
||
|
||
DebugTrace(-1, Dbg, "NpDeleteEventTableEntry -> VOID\n", 0);
|
||
|
||
//
|
||
// And now return to our caller
|
||
//
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
PEVENT_TABLE_ENTRY
|
||
NpGetNextEventTableEntry (
|
||
IN PEVENT_TABLE EventTable,
|
||
IN PVOID *RestartKey
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine enumerates the events stored within an event table.
|
||
|
||
Arguments:
|
||
|
||
EventTable - Supplies a pointer to the event being enumerated
|
||
|
||
Restart - Indicates if the enumeration should restart or continue
|
||
|
||
Return Value:
|
||
|
||
PEVENT_TABLE_ENTRY - Returns a pointer to the next event table entry
|
||
in the table, or NULL if the enumeration is complete.
|
||
|
||
--*/
|
||
|
||
{
|
||
KIRQL OldIrql;
|
||
PEVENT_TABLE_ENTRY EventTableEntry;
|
||
|
||
DebugTrace(+1, Dbg, "NpGetNextEventTableEntry, EventTable = %08lx\n", EventTable);
|
||
|
||
//
|
||
// Lookup the next element in the table
|
||
//
|
||
|
||
EventTableEntry = RtlEnumerateGenericTableWithoutSplaying( &EventTable->Table, RestartKey );
|
||
|
||
DebugTrace(-1, Dbg, "NpGetNextEventTableEntry -> %08lx\n", EventTableEntry);
|
||
|
||
//
|
||
// And now return to our caller
|
||
//
|
||
|
||
return EventTableEntry;
|
||
}
|
||
|
||
|
||
//
|
||
// Local support routines
|
||
//
|
||
|
||
RTL_GENERIC_COMPARE_RESULTS
|
||
NpEventTableCompareRoutine (
|
||
IN PRTL_GENERIC_TABLE EventTable,
|
||
IN PVOID FirstStruct,
|
||
IN PVOID SecondStruct
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the comparsion routine for the Event Table which is
|
||
implemented as a generic table.
|
||
|
||
Arguments:
|
||
|
||
EventTable - Supplies a pointer to the event table which is involved
|
||
in this action
|
||
|
||
FirstStruct - Supplies a pointer to the first event table entry to examine
|
||
|
||
SecondStruct - Supplies a pointer to the second event table entry to
|
||
examine
|
||
|
||
Return Value:
|
||
|
||
RTL_GENERIC_COMPARE_RESULTS - GenericLessThan if FirstEntry is less than
|
||
SecondEntry, GenericGreaterThan if FirstEntry is greater than
|
||
SecondEntry, and GenericEqual otherwise.
|
||
|
||
--*/
|
||
|
||
{
|
||
PEVENT_TABLE_ENTRY FirstEntry = FirstStruct;
|
||
PEVENT_TABLE_ENTRY SecondEntry = SecondStruct;
|
||
|
||
UNREFERENCED_PARAMETER( EventTable );
|
||
|
||
//
|
||
// We'll compare first the pointer to the ccb and then compare the
|
||
// pipe end types. This will guarantee a unique ordering based on
|
||
// the pipe instance and pipe end (i.e., server and client end).
|
||
//
|
||
|
||
if (FirstEntry->Ccb < SecondEntry->Ccb) {
|
||
|
||
return GenericLessThan;
|
||
|
||
} else if (FirstEntry->Ccb > SecondEntry->Ccb) {
|
||
|
||
return GenericGreaterThan;
|
||
|
||
} else if (FirstEntry->NamedPipeEnd < SecondEntry->NamedPipeEnd) {
|
||
|
||
return GenericLessThan;
|
||
|
||
} else if (FirstEntry->NamedPipeEnd > SecondEntry->NamedPipeEnd) {
|
||
|
||
return GenericGreaterThan;
|
||
|
||
} else {
|
||
|
||
return GenericEqual;
|
||
}
|
||
}
|
||
|
||
|
||
//
|
||
// Local support routines
|
||
//
|
||
|
||
PVOID
|
||
NpEventTableAllocate (
|
||
IN PRTL_GENERIC_TABLE EventTable,
|
||
IN CLONG ByteSize
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the generic allocation routine for the event table.
|
||
|
||
Arguments:
|
||
|
||
EventTable - Supplies a pointer to the event table being used
|
||
|
||
ByteSize - Supplies the size, in bytes, to allocate.
|
||
|
||
Return Value:
|
||
|
||
PVOID - Returns a pointer to the newly allocated buffer.
|
||
|
||
--*/
|
||
|
||
{
|
||
return NpAllocateNonPagedPoolWithQuota( ByteSize, 'gFpN' );
|
||
}
|
||
|
||
|
||
//
|
||
// Local support routines
|
||
//
|
||
|
||
VOID
|
||
NpEventTableDeallocate (
|
||
IN PRTL_GENERIC_TABLE EventTable,
|
||
IN PVOID Buffer
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is the generic deallocation routine for the event table.
|
||
|
||
Arguments:
|
||
|
||
EventTable - Supplies a pointer to the event table being used
|
||
|
||
Buffer - Supplies the buffer being deallocated
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
UNREFERENCED_PARAMETER( EventTable );
|
||
|
||
NpFreePool( Buffer );
|
||
|
||
return;
|
||
}
|