ReactOS  0.4.13-dev-464-g6b95727
pnpnotify.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for pnpnotify.c:

Go to the source code of this file.

Classes

struct  _PNP_NOTIFY_ENTRY
 

Macros

#define NDEBUG
 

Typedefs

typedef struct _PNP_NOTIFY_ENTRY PNP_NOTIFY_ENTRY
 
typedef struct _PNP_NOTIFY_ENTRYPPNP_NOTIFY_ENTRY
 

Functions

VOID IopNotifyPlugPlayNotification (IN PDEVICE_OBJECT DeviceObject, IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory, IN LPCGUID Event, IN PVOID EventCategoryData1, IN PVOID EventCategoryData2)
 
ULONG NTAPI IoPnPDeliverServicePowerNotification (ULONG VetoedPowerOperation OPTIONAL, ULONG PowerNotification, ULONG Unknown OPTIONAL, BOOLEAN Synchronous)
 
NTSTATUS NTAPI IoRegisterPlugPlayNotification (IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory, IN ULONG EventCategoryFlags, IN PVOID EventCategoryData OPTIONAL, IN PDRIVER_OBJECT DriverObject, IN PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine, IN PVOID Context, OUT PVOID *NotificationEntry)
 
NTSTATUS NTAPI IoUnregisterPlugPlayNotification (IN PVOID NotificationEntry)
 

Variables

KGUARDED_MUTEX PnpNotifyListLock
 
LIST_ENTRY PnpNotifyListHead
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file pnpnotify.c.

Typedef Documentation

◆ PNP_NOTIFY_ENTRY

◆ PPNP_NOTIFY_ENTRY

Function Documentation

◆ IopNotifyPlugPlayNotification()

VOID IopNotifyPlugPlayNotification ( IN PDEVICE_OBJECT  DeviceObject,
IN IO_NOTIFICATION_EVENT_CATEGORY  EventCategory,
IN LPCGUID  Event,
IN PVOID  EventCategoryData1,
IN PVOID  EventCategoryData2 
)

Definition at line 36 of file pnpnotify.c.

42 {
43  PPNP_NOTIFY_ENTRY ChangeEntry;
44  PLIST_ENTRY ListEntry;
46  BOOLEAN CallCurrentEntry;
49  PDEVICE_OBJECT EntryDeviceObject = NULL;
50 
52 
55  {
57  return;
58  }
59 
60  switch (EventCategory)
61  {
63  {
64  PDEVICE_INTERFACE_CHANGE_NOTIFICATION NotificationInfos;
65  NotificationStructure = NotificationInfos = ExAllocatePoolWithTag(
66  PagedPool,
69  if (!NotificationInfos)
70  {
72  return;
73  }
74  NotificationInfos->Version = 1;
75  NotificationInfos->Size = sizeof(DEVICE_INTERFACE_CHANGE_NOTIFICATION);
76  RtlCopyMemory(&NotificationInfos->Event, Event, sizeof(GUID));
77  RtlCopyMemory(&NotificationInfos->InterfaceClassGuid, EventCategoryData1, sizeof(GUID));
78  NotificationInfos->SymbolicLinkName = (PUNICODE_STRING)EventCategoryData2;
79  Status = RtlStringFromGUID(&NotificationInfos->InterfaceClassGuid, &GuidString);
80  if (!NT_SUCCESS(Status))
81  {
84  return;
85  }
86  break;
87  }
89  {
90  PHWPROFILE_CHANGE_NOTIFICATION NotificationInfos;
91  NotificationStructure = NotificationInfos = ExAllocatePoolWithTag(
92  PagedPool,
95  if (!NotificationInfos)
96  {
98  return;
99  }
100  NotificationInfos->Version = 1;
101  NotificationInfos->Size = sizeof(HWPROFILE_CHANGE_NOTIFICATION);
102  RtlCopyMemory(&NotificationInfos->Event, Event, sizeof(GUID));
103  break;
104  }
106  {
107  if (Event != &GUID_PNP_CUSTOM_NOTIFICATION)
108  {
109  PTARGET_DEVICE_REMOVAL_NOTIFICATION NotificationInfos;
110  NotificationStructure = NotificationInfos = ExAllocatePoolWithTag(
111  PagedPool,
114  if (!NotificationInfos)
115  {
117  return;
118  }
119  NotificationInfos->Version = 1;
120  NotificationInfos->Size = sizeof(TARGET_DEVICE_REMOVAL_NOTIFICATION);
121  RtlCopyMemory(&NotificationInfos->Event, Event, sizeof(GUID));
122  }
123  else
124  {
125  PTARGET_DEVICE_CUSTOM_NOTIFICATION NotificationInfos;
126  NotificationStructure = NotificationInfos = ExAllocatePoolWithTag(
127  PagedPool,
130  if (!NotificationInfos)
131  {
133  return;
134  }
135  RtlCopyMemory(NotificationInfos, EventCategoryData1, sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION));
136  }
137  break;
138  }
139  default:
140  {
141  DPRINT1("IopNotifyPlugPlayNotification(): unknown EventCategory 0x%x UNIMPLEMENTED\n", EventCategory);
143  return;
144  }
145  }
146 
147  /* Loop through procedures registred in PnpNotifyListHead
148  * list to find those that meet some criteria.
149  */
150  ListEntry = PnpNotifyListHead.Flink;
151  while (ListEntry != &PnpNotifyListHead)
152  {
153  ChangeEntry = CONTAINING_RECORD(ListEntry, PNP_NOTIFY_ENTRY, PnpNotifyList);
154  CallCurrentEntry = FALSE;
155 
156  if (ChangeEntry->EventCategory != EventCategory)
157  {
158  ListEntry = ListEntry->Flink;
159  continue;
160  }
161 
162  switch (EventCategory)
163  {
165  {
166  if (RtlCompareUnicodeString(&ChangeEntry->Guid, &GuidString, FALSE) == 0)
167  {
168  CallCurrentEntry = TRUE;
169  }
170  break;
171  }
173  {
174  CallCurrentEntry = TRUE;
175  break;
176  }
178  {
179  Status = IoGetRelatedTargetDevice(ChangeEntry->FileObject, &EntryDeviceObject);
180  if (NT_SUCCESS(Status))
181  {
182  if (DeviceObject == EntryDeviceObject)
183  {
184  if (Event == &GUID_PNP_CUSTOM_NOTIFICATION)
185  {
187  }
188  else
189  {
191  }
192  CallCurrentEntry = TRUE;
193  }
194  }
195  break;
196  }
197  default:
198  {
199  DPRINT1("IopNotifyPlugPlayNotification(): unknown EventCategory 0x%x UNIMPLEMENTED\n", EventCategory);
200  break;
201  }
202  }
203 
204  /* Move to the next element now, as callback may unregister itself */
205  ListEntry = ListEntry->Flink;
206  /* FIXME: If ListEntry was the last element and that callback registers
207  * new notifications, those won't be checked... */
208 
209  if (CallCurrentEntry)
210  {
211  /* Call entry into new allocated memory */
212  DPRINT("IopNotifyPlugPlayNotification(): found suitable callback %p\n",
213  ChangeEntry);
214 
216  (ChangeEntry->PnpNotificationProc)(
218  ChangeEntry->Context);
220  }
221 
222  }
225  if (EventCategory == EventCategoryDeviceInterfaceChange)
227 }
_In_ PVOID NotificationStructure
Definition: iofuncs.h:1203
static PWSTR GuidString
Definition: apphelp.c:91
struct _TARGET_DEVICE_REMOVAL_NOTIFICATION TARGET_DEVICE_REMOVAL_NOTIFICATION
NTSTATUS NTAPI IoGetRelatedTargetDevice(IN PFILE_OBJECT FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1606
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
struct _TARGET_DEVICE_REMOVAL_NOTIFICATION * PTARGET_DEVICE_REMOVAL_NOTIFICATION
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
LONG NTSTATUS
Definition: precomp.h:26
LIST_ENTRY PnpNotifyListHead
Definition: pnpnotify.c:31
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
struct _HWPROFILE_CHANGE_NOTIFICATION HWPROFILE_CHANGE_NOTIFICATION
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
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
PDRIVER_NOTIFICATION_CALLBACK_ROUTINE PnpNotificationProc
Definition: pnpnotify.c:27
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
struct _TARGET_DEVICE_CUSTOM_NOTIFICATION * PTARGET_DEVICE_CUSTOM_NOTIFICATION
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: pnpnotify.c:19
IO_NOTIFICATION_EVENT_CATEGORY EventCategory
Definition: pnpnotify.c:22
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
UNICODE_STRING Guid
Definition: pnpnotify.c:24
Definition: typedefs.h:117
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define TAG_PNP_NOTIFY
Definition: tag.h:92
struct _DEVICE_INTERFACE_CHANGE_NOTIFICATION DEVICE_INTERFACE_CHANGE_NOTIFICATION
PFILE_OBJECT FileObject
Definition: pnpnotify.c:25
KGUARDED_MUTEX PnpNotifyListLock
Definition: pnpnotify.c:30
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT1
Definition: precomp.h:8
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
PVOID Context
Definition: pnpnotify.c:23

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

◆ IoPnPDeliverServicePowerNotification()

ULONG NTAPI IoPnPDeliverServicePowerNotification ( ULONG VetoedPowerOperation  OPTIONAL,
ULONG  PowerNotification,
ULONG Unknown  OPTIONAL,
BOOLEAN  Synchronous 
)

Definition at line 236 of file pnpnotify.c.

240 {
242  return 0;
243 }
#define UNIMPLEMENTED
Definition: debug.h:114

◆ IoRegisterPlugPlayNotification()

NTSTATUS NTAPI IoRegisterPlugPlayNotification ( IN IO_NOTIFICATION_EVENT_CATEGORY  EventCategory,
IN ULONG  EventCategoryFlags,
IN PVOID EventCategoryData  OPTIONAL,
IN PDRIVER_OBJECT  DriverObject,
IN PDRIVER_NOTIFICATION_CALLBACK_ROUTINE  CallbackRoutine,
IN PVOID  Context,
OUT PVOID NotificationEntry 
)

Definition at line 250 of file pnpnotify.c.

257 {
261  PAGED_CODE();
262 
263  DPRINT("%s(EventCategory 0x%x, EventCategoryFlags 0x%lx, DriverObject %p) called.\n",
264  __FUNCTION__,
265  EventCategory,
267  DriverObject);
268 
270 
271  /* Try to allocate entry for notification before sending any notification */
273  sizeof(PNP_NOTIFY_ENTRY),
275 
276  if (!Entry)
277  {
278  DPRINT("ExAllocatePool() failed\n");
281  }
282 
283  if (EventCategory == EventCategoryDeviceInterfaceChange &&
285  {
286  DEVICE_INTERFACE_CHANGE_NOTIFICATION NotificationInfos;
287  UNICODE_STRING SymbolicLinkU;
289 
291  NULL, /* PhysicalDeviceObject OPTIONAL */
292  0, /* Flags */
294  if (NT_SUCCESS(Status))
295  {
296  /* Enumerate SymbolicLinkList */
297  NotificationInfos.Version = 1;
298  NotificationInfos.Size = sizeof(DEVICE_INTERFACE_CHANGE_NOTIFICATION);
299  RtlCopyMemory(&NotificationInfos.Event,
301  sizeof(GUID));
302  RtlCopyMemory(&NotificationInfos.InterfaceClassGuid,
304  sizeof(GUID));
305  NotificationInfos.SymbolicLinkName = &SymbolicLinkU;
306 
308  *SymbolicLink;
310  {
311  RtlInitUnicodeString(&SymbolicLinkU, SymbolicLink);
312  DPRINT("Calling callback routine for %S\n", SymbolicLink);
313  (*CallbackRoutine)(&NotificationInfos, Context);
314  }
315 
317  }
318  }
319 
320  Entry->PnpNotificationProc = CallbackRoutine;
321  Entry->EventCategory = EventCategory;
322  Entry->Context = Context;
323  Entry->DriverObject = DriverObject;
324  switch (EventCategory)
325  {
327  {
329  if (!NT_SUCCESS(Status))
330  {
333  return Status;
334  }
335  break;
336  }
338  {
339  /* nothing to do */
340  break;
341  }
343  {
344  Entry->FileObject = (PFILE_OBJECT)EventCategoryData;
345  break;
346  }
347  default:
348  {
349  DPRINT1("%s: unknown EventCategory 0x%x UNIMPLEMENTED\n",
350  __FUNCTION__, EventCategory);
351  break;
352  }
353  }
354 
357  &Entry->PnpNotifyList);
359 
360  DPRINT("%s returns NotificationEntry %p\n", __FUNCTION__, Entry);
361 
363 
364  return STATUS_SUCCESS;
365 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
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:640
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
_In_ ULONG _In_opt_ PVOID EventCategoryData
Definition: iofuncs.h:1146
uint16_t * PWSTR
Definition: typedefs.h:54
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
LONG NTSTATUS
Definition: precomp.h:26
LIST_ENTRY PnpNotifyListHead
Definition: pnpnotify.c:31
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:1195
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
_In_ ULONG EventCategoryFlags
Definition: iofuncs.h:1146
#define PAGED_CODE()
Definition: video.h:57
_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
smooth NULL
Definition: ftsmooth.c:416
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
void DPRINT(...)
Definition: polytest.cpp:61
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: pnpnotify.c:19
* PFILE_OBJECT
Definition: iotypes.h:1954
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
Status
Definition: gdiplustypes.h:24
#define TAG_PNP_NOTIFY
Definition: tag.h:92
struct _DEVICE_INTERFACE_CHANGE_NOTIFICATION DEVICE_INTERFACE_CHANGE_NOTIFICATION
KGUARDED_MUTEX PnpNotifyListLock
Definition: pnpnotify.c:30
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT1
Definition: precomp.h:8
#define ObReferenceObject
Definition: obfuncs.h:204
struct tagContext Context
Definition: acpixf.h:1012
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:2777
#define __FUNCTION__
Definition: types.h:112
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
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

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

◆ IoUnregisterPlugPlayNotification()

NTSTATUS NTAPI IoUnregisterPlugPlayNotification ( IN PVOID  NotificationEntry)

Definition at line 372 of file pnpnotify.c.

373 {
375  PAGED_CODE();
376 
378  DPRINT("%s(NotificationEntry %p) called\n", __FUNCTION__, Entry);
379 
381  RemoveEntryList(&Entry->PnpNotifyList);
383 
384  RtlFreeUnicodeString(&Entry->Guid);
385 
386  ObDereferenceObject(Entry->DriverObject);
387 
389 
390  return STATUS_SUCCESS;
391 }
struct _Entry Entry
Definition: kefuncs.h:640
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define PAGED_CODE()
Definition: video.h:57
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
_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
void DPRINT(...)
Definition: polytest.cpp:61
Definition: pnpnotify.c:19
struct _PNP_NOTIFY_ENTRY * PPNP_NOTIFY_ENTRY
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define TAG_PNP_NOTIFY
Definition: tag.h:92
KGUARDED_MUTEX PnpNotifyListLock
Definition: pnpnotify.c:30
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:2777
#define __FUNCTION__
Definition: types.h:112
base of all file and directory entries
Definition: entries.h:82

Referenced by _Function_class_(), MountMgrFreeMountedDeviceInfo(), MountMgrMountedDeviceRemoval(), MountMgrUnload(), remove_volume_child(), SysAudio_AddDevice(), SysAudio_Pnp(), Test_IoRegisterPlugPlayNotification(), and WdmAudClose().

Variable Documentation

◆ PnpNotifyListHead

LIST_ENTRY PnpNotifyListHead

◆ PnpNotifyListLock