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));
|
|
|
|
}
|
|
|