ReactOS  0.4.15-dev-2991-g632fa1c
pnpnotify.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for pnpnotify.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

 _Guarded_by_ (PiNotifyHwProfileLock)
 
VOID PiInitializeNotifications (VOID)
 
static VOID PiDereferencePnpNotifyEntry (_In_ PPNP_NOTIFY_ENTRY Entry)
 
static VOID PiReferencePnpNotifyEntry (_In_ PPNP_NOTIFY_ENTRY Entry)
 
static VOID PiCallNotifyProc (_In_ PDRIVER_NOTIFICATION_CALLBACK_ROUTINE Proc, _In_ PVOID NotificationStructure, _In_ PVOID Context)
 Calls PnP notification routine and makes some checks to detect faulty drivers. More...
 
static _Requires_lock_held_ (Lock)
 
VOID PiNotifyDeviceInterfaceChange (_In_ LPCGUID Event, _In_ LPCGUID InterfaceClassGuid, _In_ PUNICODE_STRING SymbolicLinkName)
 Delivers the event to all drivers subscribed to EventCategoryDeviceInterfaceChange. More...
 
VOID PiNotifyHardwareProfileChange (_In_ LPCGUID Event)
 Delivers the event to all drivers subscribed to EventCategoryHardwareProfileChange PnP event. More...
 
VOID PiNotifyTargetDeviceChange (_In_ LPCGUID Event, _In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PTARGET_DEVICE_CUSTOM_NOTIFICATION CustomNotification)
 Delivers the event to all drivers subscribed to EventCategoryTargetDeviceChange PnP event. More...
 
ULONG NTAPI IoPnPDeliverServicePowerNotification (_In_ ULONG VetoedPowerOperation, _In_ ULONG PowerNotificationCode, _In_ ULONG PowerNotificationData, _In_ BOOLEAN Synchronous)
 
NTSTATUS NTAPI IoRegisterPlugPlayNotification (_In_ IO_NOTIFICATION_EVENT_CATEGORY EventCategory, _In_ ULONG EventCategoryFlags, _In_opt_ PVOID EventCategoryData, _In_ PDRIVER_OBJECT DriverObject, _In_ PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine, _Inout_opt_ PVOID Context, _Out_ PVOID *NotificationEntry)
 
NTSTATUS NTAPI IoUnregisterPlugPlayNotification (_In_ PVOID NotificationEntry)
 

Variables

KGUARDED_MUTEX PiNotifyTargetDeviceLock
 
KGUARDED_MUTEX PiNotifyHwProfileLock
 
KGUARDED_MUTEX PiNotifyDeviceInterfaceLock
 
 PNP_NOTIFY_ENTRY
 
PPNP_NOTIFY_ENTRY
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file pnpnotify.c.

Function Documentation

◆ _Guarded_by_()

_Guarded_by_ ( PiNotifyHwProfileLock  )

Definition at line 23 of file pnpnotify.c.

32 {
33  LIST_ENTRY PnpNotifyList;
34  PVOID Context;
36  PDRIVER_NOTIFICATION_CALLBACK_ROUTINE PnpNotificationProc;
37  union
38  {
39  GUID Guid; // for EventCategoryDeviceInterfaceChange
40  struct
41  {
42  PFILE_OBJECT FileObject; // for EventCategoryTargetDeviceChange
44  };
45  };
46  IO_NOTIFICATION_EVENT_CATEGORY EventCategory;
47  UINT8 RefCount;
DRIVER_NOTIFICATION_CALLBACK_ROUTINE * PDRIVER_NOTIFICATION_CALLBACK_ROUTINE
Definition: iotypes.h:1247
enum _IO_NOTIFICATION_EVENT_CATEGORY IO_NOTIFICATION_EVENT_CATEGORY
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
unsigned char BOOLEAN
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
* PPNP_NOTIFY_ENTRY
Definition: pnpnotify.c:49
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_Must_inspect_result_ _In_ WDFOBJECT _In_ CONST GUID * Guid
Definition: wdfobject.h:760
* PFILE_OBJECT
Definition: iotypes.h:1998
Definition: typedefs.h:119
PNP_NOTIFY_ENTRY
Definition: pnpnotify.c:49
struct tagContext Context
Definition: acpixf.h:1034
unsigned char UINT8

◆ _Requires_lock_held_()

static _Requires_lock_held_ ( Lock  )
static

Definition at line 125 of file pnpnotify.c.

132 {
133  PAGED_CODE();
134 
135  // the notification may be unregistered inside the procedure
136  // thus reference the entry so we may proceed
138 
139  // release the lock because the notification routine has to be called without any
140  // limitations regarding APCs
142  PiCallNotifyProc(Entry->PnpNotificationProc, NotificationStructure, Entry->Context);
144 
145  // take the next entry link only after the callback finishes
146  // the lock is not held there, so Entry may have changed at this point
147  *NextEntry = Entry->PnpNotifyList.Flink;
149 }
_In_ PVOID NotificationStructure
Definition: iofuncs.h:1206
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
static VOID PiDereferencePnpNotifyEntry(_In_ PPNP_NOTIFY_ENTRY Entry)
Definition: pnpnotify.c:67
static VOID PiCallNotifyProc(_In_ PDRIVER_NOTIFICATION_CALLBACK_ROUTINE Proc, _In_ PVOID NotificationStructure, _In_ PVOID Context)
Calls PnP notification routine and makes some checks to detect faulty drivers.
Definition: pnpnotify.c:106
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
static VOID PiReferencePnpNotifyEntry(_In_ PPNP_NOTIFY_ENTRY Entry)
Definition: pnpnotify.c:92
base of all file and directory entries
Definition: entries.h:82
#define PAGED_CODE()

◆ IoPnPDeliverServicePowerNotification()

ULONG NTAPI IoPnPDeliverServicePowerNotification ( _In_ ULONG  VetoedPowerOperation,
_In_ ULONG  PowerNotificationCode,
_In_ ULONG  PowerNotificationData,
_In_ BOOLEAN  Synchronous 
)

Definition at line 329 of file pnpnotify.c.

334 {
336  return 0;
337 }
#define UNIMPLEMENTED
Definition: debug.h:115

◆ IoRegisterPlugPlayNotification()

NTSTATUS NTAPI IoRegisterPlugPlayNotification ( _In_ IO_NOTIFICATION_EVENT_CATEGORY  EventCategory,
_In_ ULONG  EventCategoryFlags,
_In_opt_ PVOID  EventCategoryData,
_In_ PDRIVER_OBJECT  DriverObject,
_In_ PDRIVER_NOTIFICATION_CALLBACK_ROUTINE  CallbackRoutine,
_Inout_opt_ PVOID  Context,
_Out_ PVOID NotificationEntry 
)

Definition at line 345 of file pnpnotify.c.

353 {
357  PAGED_CODE();
358 
359  DPRINT("%s(EventCategory 0x%x, EventCategoryFlags 0x%lx, DriverObject %p) called.\n",
360  __FUNCTION__, EventCategory, EventCategoryFlags, DriverObject);
361 
363 
364  /* Try to allocate entry for notification before sending any notification */
366  if (!Entry)
367  {
368  DPRINT("ExAllocatePool() failed\n");
371  }
372 
373  *Entry = (PNP_NOTIFY_ENTRY) {
374  .PnpNotificationProc = CallbackRoutine,
375  .Context = Context,
376  .DriverObject = DriverObject,
377  .EventCategory = EventCategory,
378  .RefCount = 1
379  };
380 
381  switch (EventCategory)
382  {
384  {
385  Entry->Guid = *(LPGUID)EventCategoryData;
386 
387  // first register the notification
389  InsertTailList(&PiNotifyDeviceInterfaceListHead, &Entry->PnpNotifyList);
391 
392  // then process existing interfaces if asked
394  {
395  DEVICE_INTERFACE_CHANGE_NOTIFICATION NotificationInfos;
396  UNICODE_STRING SymbolicLinkU;
398 
400  NULL, /* PhysicalDeviceObject OPTIONAL */
401  0, /* Flags */
403  if (NT_SUCCESS(Status))
404  {
405  /* Enumerate SymbolicLinkList */
406  NotificationInfos.Version = 1;
407  NotificationInfos.Size = sizeof(DEVICE_INTERFACE_CHANGE_NOTIFICATION);
408  NotificationInfos.Event = GUID_DEVICE_INTERFACE_ARRIVAL;
409  NotificationInfos.InterfaceClassGuid = *(LPGUID)EventCategoryData;
410  NotificationInfos.SymbolicLinkName = &SymbolicLinkU;
411 
413  *SymbolicLink;
414  SymbolicLink += (SymbolicLinkU.Length / sizeof(WCHAR)) + 1)
415  {
416  RtlInitUnicodeString(&SymbolicLinkU, SymbolicLink);
417  DPRINT("Calling callback routine for %S\n", SymbolicLink);
418  PiCallNotifyProc(CallbackRoutine, &NotificationInfos, Context);
419  }
420 
422  }
423  }
424  break;
425  }
427  {
429  InsertTailList(&PiNotifyHwProfileListHead, &Entry->PnpNotifyList);
431  break;
432  }
434  {
435  PDEVICE_NODE deviceNode;
436  Entry->FileObject = (PFILE_OBJECT)EventCategoryData;
437 
438  // NOTE: the device node's PDO is referenced here
439  Status = IopGetRelatedTargetDevice(Entry->FileObject, &deviceNode);
440  if (!NT_SUCCESS(Status))
441  {
444  return Status;
445  }
446  // save it so we can dereference it later
447  Entry->DeviceObject = deviceNode->PhysicalDeviceObject;
448 
449  // each DEVICE_NODE has its own registered notifications list
451  InsertTailList(&deviceNode->TargetDeviceNotify, &Entry->PnpNotifyList);
453  break;
454  }
455  default:
456  {
457  DPRINT1("%s: unknown EventCategory 0x%x UNIMPLEMENTED\n",
458  __FUNCTION__, EventCategory);
459 
462  return STATUS_NOT_SUPPORTED;
463  }
464  }
465 
466  DPRINT("%s returns NotificationEntry %p\n", __FUNCTION__, Entry);
467 
469 
470  return STATUS_SUCCESS;
471 }
return STATUS_NOT_SUPPORTED
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:850
const GUID GUID_DEVICE_INTERFACE_ARRIVAL
Definition: deviface.c:14
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_opt_ PDEVICE_OBJECT _In_ ULONG _Outptr_result_nullonfailure_ _At_ * SymbolicLinkList(return==0, __drv_allocatesMem(Mem))) PZZWSTR *SymbolicLinkList
struct _Entry Entry
Definition: kefuncs.h:627
LIST_ENTRY TargetDeviceNotify
Definition: iotypes.h:864
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
_In_ ULONG _In_opt_ PVOID EventCategoryData
Definition: iofuncs.h:1149
uint16_t * PWSTR
Definition: typedefs.h:56
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI IopGetRelatedTargetDevice(IN PFILE_OBJECT FileObject, OUT PDEVICE_NODE *DeviceNode)
Definition: device.c:653
NTSTATUS NTAPI IoGetDeviceInterfaces(IN CONST GUID *InterfaceClassGuid, IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL, IN ULONG Flags, OUT PWSTR *SymbolicLinkList)
Definition: deviface.c:454
#define PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES
Definition: iotypes.h:1239
_In_ ULONG EventCategoryFlags
Definition: iofuncs.h:1149
#define InsertTailList(ListHead, Entry)
static VOID PiCallNotifyProc(_In_ PDRIVER_NOTIFICATION_CALLBACK_ROUTINE Proc, _In_ PVOID NotificationStructure, _In_ PVOID Context)
Calls PnP notification routine and makes some checks to detect faulty drivers.
Definition: pnpnotify.c:106
_Must_inspect_result_ _In_ PFLT_GET_OPERATION_STATUS_CALLBACK CallbackRoutine
Definition: fltkernel.h:1035
_In_ ULONG _In_opt_ PVOID _In_ PDRIVER_OBJECT _In_ PDRIVER_NOTIFICATION_CALLBACK_ROUTINE _Inout_opt_ __drv_aliasesMem PVOID _Outptr_result_nullonfailure_ _At_ * NotificationEntry(return==0, __drv_allocatesMem(Mem))) PVOID *NotificationEntry
* PPNP_NOTIFY_ENTRY
Definition: pnpnotify.c:49
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
Status
Definition: gdiplustypes.h:24
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
KGUARDED_MUTEX PiNotifyTargetDeviceLock
Definition: pnpnotify.c:19
PNP_NOTIFY_ENTRY
Definition: pnpnotify.c:49
#define TAG_PNP_NOTIFY
Definition: tag.h:92
KGUARDED_MUTEX PiNotifyHwProfileLock
Definition: pnpnotify.c:20
#define NULL
Definition: types.h:112
struct _DEVICE_INTERFACE_CHANGE_NOTIFICATION DEVICE_INTERFACE_CHANGE_NOTIFICATION
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT1
Definition: precomp.h:8
struct tagContext Context
Definition: acpixf.h:1034
#define ObReferenceObject
Definition: obfuncs.h:204
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
#define __FUNCTION__
Definition: types.h:112
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
base of all file and directory entries
Definition: entries.h:82
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
static const WCHAR SymbolicLink[]
Definition: interface.c:31
#define PAGED_CODE()
GUID * LPGUID
Definition: guiddef.h:81
KGUARDED_MUTEX PiNotifyDeviceInterfaceLock
Definition: pnpnotify.c:21

Referenced by _Function_class_(), add_device(), add_volume_device(), CompBattPnpDispatch(), DriverEntry(), PciVerifierInit(), PoInitSystem(), FxIoTargetRemote::RegisterForPnpNotification(), RegisterForTargetDeviceNotification(), SysAudioRegisterNotifications(), Test_IoRegisterPlugPlayNotification(), and WdmAudOpenSysAudioDevices().

◆ IoUnregisterPlugPlayNotification()

NTSTATUS NTAPI IoUnregisterPlugPlayNotification ( _In_ PVOID  NotificationEntry)

Definition at line 479 of file pnpnotify.c.

481 {
484 
485  PAGED_CODE();
486 
487  DPRINT("%s(NotificationEntry %p) called\n", __FUNCTION__, Entry);
488 
489  switch (Entry->EventCategory)
490  {
493  break;
496  break;
499  break;
500  default:
501  UNREACHABLE;
502  return STATUS_NOT_SUPPORTED;
503  }
504 
506  if (!Entry->Deleted)
507  {
508  Entry->Deleted = TRUE; // so it can't be unregistered two times
510  }
511  else
512  {
513  DPRINT1("IoUnregisterPlugPlayNotification called two times for 0x%p\n", NotificationEntry);
514  }
516 
517  return STATUS_SUCCESS;
518 }
return STATUS_NOT_SUPPORTED
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define TRUE
Definition: types.h:120
static VOID PiDereferencePnpNotifyEntry(_In_ PPNP_NOTIFY_ENTRY Entry)
Definition: pnpnotify.c:67
_In_ ULONG _In_opt_ PVOID _In_ PDRIVER_OBJECT _In_ PDRIVER_NOTIFICATION_CALLBACK_ROUTINE _Inout_opt_ __drv_aliasesMem PVOID _Outptr_result_nullonfailure_ _At_ * NotificationEntry(return==0, __drv_allocatesMem(Mem))) PVOID *NotificationEntry
* PPNP_NOTIFY_ENTRY
Definition: pnpnotify.c:49
KGUARDED_MUTEX PiNotifyTargetDeviceLock
Definition: pnpnotify.c:19
KGUARDED_MUTEX PiNotifyHwProfileLock
Definition: pnpnotify.c:20
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
#define UNREACHABLE
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
#define __FUNCTION__
Definition: types.h:112
base of all file and directory entries
Definition: entries.h:82
#define PAGED_CODE()
KGUARDED_MUTEX PiNotifyDeviceInterfaceLock
Definition: pnpnotify.c:21

Referenced by do_shutdown(), free_vol(), MountMgrFreeMountedDeviceInfo(), MountMgrMountedDeviceRemoval(), MountMgrUnload(), Mx::MxUnRegisterPlugPlayNotification(), remove_volume_child(), SysAudio_AddDevice(), SysAudio_Pnp(), Test_IoRegisterPlugPlayNotification(), FxIoTargetRemote::UnregisterForPnpNotification(), and WdmAudClose().

◆ PiCallNotifyProc()

static VOID PiCallNotifyProc ( _In_ PDRIVER_NOTIFICATION_CALLBACK_ROUTINE  Proc,
_In_ PVOID  NotificationStructure,
_In_ PVOID  Context 
)
static

Calls PnP notification routine and makes some checks to detect faulty drivers.

Definition at line 106 of file pnpnotify.c.

110 {
111  PAGED_CODE();
112 #if DBG
113  KIRQL oldIrql = KeGetCurrentIrql();
114  ULONG oldApcDisable = KeGetCurrentThread()->CombinedApcDisable;
115 #endif
116 
118 
119  ASSERT(oldIrql == KeGetCurrentIrql() &&
120  oldApcDisable == KeGetCurrentThread()->CombinedApcDisable);
121 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
_In_ PVOID NotificationStructure
Definition: iofuncs.h:1206
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define ASSERT(a)
Definition: mode.c:44
unsigned int ULONG
Definition: retypes.h:1
#define KeGetCurrentThread
Definition: hal.h:55
#define PAGED_CODE()

Referenced by _Requires_lock_held_(), and IoRegisterPlugPlayNotification().

◆ PiDereferencePnpNotifyEntry()

static VOID PiDereferencePnpNotifyEntry ( _In_ PPNP_NOTIFY_ENTRY  Entry)
static

Definition at line 67 of file pnpnotify.c.

69 {
70  PAGED_CODE();
71  ASSERT(Entry->RefCount > 0);
72 
73  ObDereferenceObject(Entry->DriverObject);
74  Entry->RefCount--;
75  if (Entry->RefCount == 0)
76  {
77  ASSERT(Entry->Deleted);
78 
79  RemoveEntryList(&Entry->PnpNotifyList);
80  if (Entry->EventCategory == EventCategoryTargetDeviceChange)
81  {
82  // IopGetRelatedTargetDevice referenced the device upon the notification registration
83  ObDereferenceObject(Entry->DeviceObject);
84  }
86  }
87 }
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define ASSERT(a)
Definition: mode.c:44
#define ObDereferenceObject
Definition: obfuncs.h:203
#define TAG_PNP_NOTIFY
Definition: tag.h:92
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
base of all file and directory entries
Definition: entries.h:82
#define PAGED_CODE()

Referenced by _Requires_lock_held_(), and IoUnregisterPlugPlayNotification().

◆ PiInitializeNotifications()

VOID PiInitializeNotifications ( VOID  )

Definition at line 55 of file pnpnotify.c.

56 {
60  InitializeListHead(&PiNotifyHwProfileListHead);
61  InitializeListHead(&PiNotifyDeviceInterfaceListHead);
62 }
KGUARDED_MUTEX PiNotifyTargetDeviceLock
Definition: pnpnotify.c:19
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
KGUARDED_MUTEX PiNotifyHwProfileLock
Definition: pnpnotify.c:20
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
KGUARDED_MUTEX PiNotifyDeviceInterfaceLock
Definition: pnpnotify.c:21

Referenced by IoInitSystem().

◆ PiNotifyDeviceInterfaceChange()

VOID PiNotifyDeviceInterfaceChange ( _In_ LPCGUID  Event,
_In_ LPCGUID  InterfaceClassGuid,
_In_ PUNICODE_STRING  SymbolicLinkName 
)

Delivers the event to all drivers subscribed to EventCategoryDeviceInterfaceChange.

Parameters
[in]EventThe PnP event GUID
[in]InterfaceClassGuidThe GUID of an interface class
[in]SymbolicLinkNamePointer to a string identifying the device interface name

Definition at line 161 of file pnpnotify.c.

165 {
166  PAGED_CODE();
167 
169  notifyStruct = ExAllocatePoolWithTag(PagedPool, sizeof(*notifyStruct), TAG_PNP_NOTIFY);
170  if (!notifyStruct)
171  {
172  return;
173  }
174 
175  *notifyStruct = (DEVICE_INTERFACE_CHANGE_NOTIFICATION) {
176  .Version = 1,
177  .Size = sizeof(DEVICE_INTERFACE_CHANGE_NOTIFICATION),
178  .Event = *Event,
181  };
182 
183  DPRINT("Delivering a DeviceInterfaceChange PnP event\n");
184 
186 
187  PLIST_ENTRY entry = PiNotifyDeviceInterfaceListHead.Flink;
188  while (entry != &PiNotifyDeviceInterfaceListHead)
189  {
190  PPNP_NOTIFY_ENTRY nEntry = CONTAINING_RECORD(entry, PNP_NOTIFY_ENTRY, PnpNotifyList);
191 
192  if (!IsEqualGUID(&notifyStruct->InterfaceClassGuid, &nEntry->Guid))
193  {
194  entry = entry->Flink;
195  continue;
196  }
197 
198  PiProcessSingleNotification(nEntry, notifyStruct, &PiNotifyDeviceInterfaceLock, &entry);
199  }
200 
202  ExFreePoolWithTag(notifyStruct, TAG_PNP_NOTIFY);
203 }
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
* PPNP_NOTIFY_ENTRY
Definition: pnpnotify.c:49
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
uint32_t entry
Definition: isohybrid.c:63
Definition: typedefs.h:119
PNP_NOTIFY_ENTRY
Definition: pnpnotify.c:49
#define TAG_PNP_NOTIFY
Definition: tag.h:92
_In_ CONST GUID * InterfaceClassGuid
Definition: iofuncs.h:1136
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
struct _DEVICE_INTERFACE_CHANGE_NOTIFICATION DEVICE_INTERFACE_CHANGE_NOTIFICATION
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT
Definition: sndvol32.h:71
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING SymbolicLinkName
Definition: wdfdevice.h:3736
#define PAGED_CODE()
KGUARDED_MUTEX PiNotifyDeviceInterfaceLock
Definition: pnpnotify.c:21

Referenced by IoSetDeviceInterfaceState().

◆ PiNotifyHardwareProfileChange()

VOID PiNotifyHardwareProfileChange ( _In_ LPCGUID  Event)

Delivers the event to all drivers subscribed to EventCategoryHardwareProfileChange PnP event.

Parameters
[in]EventThe PnP event GUID

Definition at line 214 of file pnpnotify.c.

216 {
217  PAGED_CODE();
218 
219  PHWPROFILE_CHANGE_NOTIFICATION notifyStruct;
220  notifyStruct = ExAllocatePoolWithTag(PagedPool, sizeof(*notifyStruct), TAG_PNP_NOTIFY);
221  if (!notifyStruct)
222  {
223  return;
224  }
225 
226  *notifyStruct = (HWPROFILE_CHANGE_NOTIFICATION) {
227  .Version = 1,
228  .Size = sizeof(HWPROFILE_CHANGE_NOTIFICATION),
229  .Event = *Event
230  };
231 
232  DPRINT("Delivering a HardwareProfileChange PnP event\n");
233 
235 
236  PLIST_ENTRY entry = PiNotifyHwProfileListHead.Flink;
237  while (entry != &PiNotifyHwProfileListHead)
238  {
239  PPNP_NOTIFY_ENTRY nEntry = CONTAINING_RECORD(entry, PNP_NOTIFY_ENTRY, PnpNotifyList);
240 
241  PiProcessSingleNotification(nEntry, notifyStruct, &PiNotifyHwProfileLock, &entry);
242  }
243 
245  ExFreePoolWithTag(notifyStruct, TAG_PNP_NOTIFY);
246 }
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
struct _HWPROFILE_CHANGE_NOTIFICATION HWPROFILE_CHANGE_NOTIFICATION
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
* PPNP_NOTIFY_ENTRY
Definition: pnpnotify.c:49
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
uint32_t entry
Definition: isohybrid.c:63
Definition: typedefs.h:119
PNP_NOTIFY_ENTRY
Definition: pnpnotify.c:49
#define TAG_PNP_NOTIFY
Definition: tag.h:92
KGUARDED_MUTEX PiNotifyHwProfileLock
Definition: pnpnotify.c:20
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT
Definition: sndvol32.h:71
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define PAGED_CODE()

◆ PiNotifyTargetDeviceChange()

VOID PiNotifyTargetDeviceChange ( _In_ LPCGUID  Event,
_In_ PDEVICE_OBJECT  DeviceObject,
_In_opt_ PTARGET_DEVICE_CUSTOM_NOTIFICATION  CustomNotification 
)

Delivers the event to all drivers subscribed to EventCategoryTargetDeviceChange PnP event.

Parameters
[in]EventThe PnP event GUID
[in]DeviceObjectThe (target) device object
[in]CustomNotificationPointer to a custom notification for GUID_PNP_CUSTOM_NOTIFICATION

Definition at line 258 of file pnpnotify.c.

262 {
263  PAGED_CODE();
264 
265  PVOID notificationStruct;
266  // just in case our device is removed during the operation
268 
270  ASSERT(deviceNode);
271 
272  if (!IsEqualGUID(Event, &GUID_PNP_CUSTOM_NOTIFICATION))
273  {
275  notifStruct = ExAllocatePoolWithTag(PagedPool, sizeof(*notifStruct), TAG_PNP_NOTIFY);
276  if (!notifStruct)
277  {
278  return;
279  }
280 
281  *notifStruct = (TARGET_DEVICE_REMOVAL_NOTIFICATION) {
282  .Version = 1,
283  .Size = sizeof(TARGET_DEVICE_REMOVAL_NOTIFICATION),
284  .Event = *Event
285  };
286 
287  notificationStruct = notifStruct;
288 
289  DPRINT("Delivering a (non-custom) TargetDeviceChange PnP event\n");
290  }
291  else
292  {
293  ASSERT(CustomNotification);
294  // assuming everythng else is correct
295 
296  notificationStruct = CustomNotification;
297 
298  DPRINT("Delivering a (custom) TargetDeviceChange PnP event\n");
299  }
300 
302 
304  while (entry != &deviceNode->TargetDeviceNotify)
305  {
306  PPNP_NOTIFY_ENTRY nEntry = CONTAINING_RECORD(entry, PNP_NOTIFY_ENTRY, PnpNotifyList);
307 
308  // put the file object from our saved entry to this particular notification's struct
309  ((PTARGET_DEVICE_REMOVAL_NOTIFICATION)notificationStruct)->FileObject = nEntry->FileObject;
310  // so you don't need to look at the definition ;)
313 
314  PiProcessSingleNotification(nEntry, notificationStruct, &PiNotifyTargetDeviceLock, &entry);
315  }
316 
318  ExFreePoolWithTag(notificationStruct, TAG_PNP_NOTIFY);
320 }
struct _TARGET_DEVICE_REMOVAL_NOTIFICATION TARGET_DEVICE_REMOVAL_NOTIFICATION
struct _TARGET_DEVICE_REMOVAL_NOTIFICATION * PTARGET_DEVICE_REMOVAL_NOTIFICATION
LIST_ENTRY TargetDeviceNotify
Definition: iotypes.h:864
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define C_ASSERT(e)
Definition: intsafe.h:73
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
* PPNP_NOTIFY_ENTRY
Definition: pnpnotify.c:49
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define ASSERT(a)
Definition: mode.c:44
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
uint32_t entry
Definition: isohybrid.c:63
Definition: typedefs.h:119
KGUARDED_MUTEX PiNotifyTargetDeviceLock
Definition: pnpnotify.c:19
PNP_NOTIFY_ENTRY
Definition: pnpnotify.c:49
#define TAG_PNP_NOTIFY
Definition: tag.h:92
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define ObReferenceObject
Definition: obfuncs.h:204
#define DPRINT
Definition: sndvol32.h:71
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
PDEVICE_NODE FASTCALL IopGetDeviceNode(IN PDEVICE_OBJECT DeviceObject)
#define PAGED_CODE()

Referenced by IopCancelRemoveDevice(), IopQueryRemoveDevice(), IopSendRemoveDevice(), and PpSetCustomTargetEvent().

◆ PiReferencePnpNotifyEntry()

static VOID PiReferencePnpNotifyEntry ( _In_ PPNP_NOTIFY_ENTRY  Entry)
static

Definition at line 92 of file pnpnotify.c.

94 {
95  PAGED_CODE();
96  ObReferenceObject(Entry->DriverObject);
97  Entry->RefCount++;
98 }
#define ObReferenceObject
Definition: obfuncs.h:204
base of all file and directory entries
Definition: entries.h:82
#define PAGED_CODE()

Referenced by _Requires_lock_held_().

Variable Documentation

◆ PiNotifyDeviceInterfaceLock

◆ PiNotifyHwProfileLock

◆ PiNotifyTargetDeviceLock

◆ PNP_NOTIFY_ENTRY

◆ PPNP_NOTIFY_ENTRY