Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

406 lines
8.6 KiB

/*++
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;
}