129 lines
2.3 KiB
C
129 lines
2.3 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1997-1999 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
notify.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Manages KM to UM notification queue
|
||
|
|
||
|
Author:
|
||
|
|
||
|
AlanWar
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
Kernel Mode
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "wmikmp.h"
|
||
|
|
||
|
|
||
|
void WmipInitializeNotifications(
|
||
|
void
|
||
|
);
|
||
|
|
||
|
void WmipEventNotification(
|
||
|
IN PVOID Context
|
||
|
);
|
||
|
|
||
|
#ifdef ALLOC_PRAGMA
|
||
|
#pragma alloc_text(INIT,WmipInitializeNotifications)
|
||
|
#pragma alloc_text(PAGE,WmipEventNotification)
|
||
|
#endif
|
||
|
|
||
|
WORK_QUEUE_ITEM WmipEventWorkQueueItem;
|
||
|
LIST_ENTRY WmipNPEvent = {&WmipNPEvent, &WmipNPEvent};
|
||
|
KSPIN_LOCK WmipNPNotificationSpinlock;
|
||
|
LONG WmipEventWorkItems;
|
||
|
#if DBG
|
||
|
ULONG WmipNPAllocFail;
|
||
|
#endif
|
||
|
|
||
|
void WmipInitializeNotifications(
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
PAGED_CODE();
|
||
|
|
||
|
ExInitializeWorkItem( &WmipEventWorkQueueItem,
|
||
|
WmipEventNotification,
|
||
|
NULL );
|
||
|
|
||
|
KeInitializeSpinLock(&WmipNPNotificationSpinlock);
|
||
|
|
||
|
}
|
||
|
|
||
|
void WmipEventNotification(
|
||
|
IN PVOID Context
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Work item routine to call WmipNotifyUserMode on behalf of an event fired
|
||
|
by a driver
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
Context is not used
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
PWNODE_HEADER WnodeEventItem;
|
||
|
PLIST_ENTRY NotificationPacketList;
|
||
|
PREGENTRY RegEntry;
|
||
|
PEVENTWORKCONTEXT EventContext;
|
||
|
|
||
|
PAGED_CODE();
|
||
|
|
||
|
do
|
||
|
{
|
||
|
NotificationPacketList = ExInterlockedRemoveHeadList(
|
||
|
&WmipNPEvent,
|
||
|
&WmipNPNotificationSpinlock);
|
||
|
|
||
|
WmipAssert(NotificationPacketList != NULL);
|
||
|
|
||
|
EventContext = (PEVENTWORKCONTEXT)
|
||
|
CONTAINING_RECORD(NotificationPacketList,
|
||
|
EVENTWORKCONTEXT,
|
||
|
ListEntry);
|
||
|
|
||
|
WnodeEventItem = EventContext->Wnode;
|
||
|
|
||
|
//
|
||
|
// Restore the Wnode->Version from ->ClientContext
|
||
|
//
|
||
|
WnodeEventItem->Version = WnodeEventItem->ClientContext;
|
||
|
WnodeEventItem->ClientContext = 0;
|
||
|
WnodeEventItem->Linkage = 0;
|
||
|
|
||
|
WmipProcessEvent(WnodeEventItem,
|
||
|
FALSE,
|
||
|
TRUE);
|
||
|
|
||
|
if (EventContext->RegEntry != NULL)
|
||
|
{
|
||
|
//
|
||
|
// Unref for the ref count taken in IoWMIWriteEvent
|
||
|
//
|
||
|
WmipUnreferenceRegEntry(EventContext->RegEntry);
|
||
|
}
|
||
|
|
||
|
ExFreePool(EventContext);
|
||
|
} while (InterlockedDecrement(&WmipEventWorkItems));
|
||
|
|
||
|
}
|
||
|
|