windows-nt/Source/XPSP1/NT/base/ntos/wmi/notify.c
2020-09-26 16:20:57 +08:00

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