ReactOS  0.4.14-dev-604-gcfdd483
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 
217  ChangeEntry->Context);
219  }
220 
221  }
224  if (EventCategory == EventCategoryDeviceInterfaceChange)
226 }
_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:1607
#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 235 of file pnpnotify.c.

239 {
241  return 0;
242 }
#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 249 of file pnpnotify.c.

256 {
260  PAGED_CODE();
261 
262  DPRINT("%s(EventCategory 0x%x, EventCategoryFlags 0x%lx, DriverObject %p) called.\n",
263  __FUNCTION__,
264  EventCategory,
266  DriverObject);
267 
269 
270  /* Try to allocate entry for notification before sending any notification */
272  sizeof(PNP_NOTIFY_ENTRY),
274 
275  if (!Entry)
276  {
277  DPRINT("ExAllocatePool() failed\n");
280  }
281 
282  if (EventCategory == EventCategoryDeviceInterfaceChange &&
284  {
285  DEVICE_INTERFACE_CHANGE_NOTIFICATION NotificationInfos;
286  UNICODE_STRING SymbolicLinkU;
288 
290  NULL, /* PhysicalDeviceObject OPTIONAL */
291  0, /* Flags */
293  if (NT_SUCCESS(Status))
294  {
295  /* Enumerate SymbolicLinkList */
296  NotificationInfos.Version = 1;
297  NotificationInfos.Size = sizeof(DEVICE_INTERFACE_CHANGE_NOTIFICATION);
298  RtlCopyMemory(&NotificationInfos.Event,
300  sizeof(GUID));
301  RtlCopyMemory(&NotificationInfos.InterfaceClassGuid,
303  sizeof(GUID));
304  NotificationInfos.SymbolicLinkName = &SymbolicLinkU;
305 
307  *SymbolicLink;
309  {
310  RtlInitUnicodeString(&SymbolicLinkU, SymbolicLink);
311  DPRINT("Calling callback routine for %S\n", SymbolicLink);
312  (*CallbackRoutine)(&NotificationInfos, Context);
313  }
314 
316  }
317  }
318 
319  Entry->PnpNotificationProc = CallbackRoutine;
320  Entry->EventCategory = EventCategory;
321  Entry->Context = Context;
322  Entry->DriverObject = DriverObject;
323  switch (EventCategory)
324  {
326  {
328  if (!NT_SUCCESS(Status))
329  {
332  return Status;
333  }
334  break;
335  }
337  {
338  /* nothing to do */
339  break;
340  }
342  {
343  Entry->FileObject = (PFILE_OBJECT)EventCategoryData;
344  break;
345  }
346  default:
347  {
348  DPRINT1("%s: unknown EventCategory 0x%x UNIMPLEMENTED\n",
349  __FUNCTION__, EventCategory);
350  break;
351  }
352  }
353 
356  &Entry->PnpNotifyList);
358 
359  DPRINT("%s returns NotificationEntry %p\n", __FUNCTION__, Entry);
360 
362 
363  return STATUS_SUCCESS;
364 }
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:1196
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:1955
#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:1030
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:2938
#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 371 of file pnpnotify.c.

372 {
374  PAGED_CODE();
375 
377  DPRINT("%s(NotificationEntry %p) called\n", __FUNCTION__, Entry);
378 
380  RemoveEntryList(&Entry->PnpNotifyList);
382 
383  RtlFreeUnicodeString(&Entry->Guid);
384 
385  ObDereferenceObject(Entry->DriverObject);
386 
388 
389  return STATUS_SUCCESS;
390 }
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:2938
#define __FUNCTION__
Definition: types.h:112
base of all file and directory entries
Definition: entries.h:82

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

Variable Documentation

◆ PnpNotifyListHead

LIST_ENTRY PnpNotifyListHead

◆ PnpNotifyListLock