ReactOS 0.4.15-dev-8222-g9164419
notify.c File Reference
#include "mntmgr.h"
#include <ioevent.h>
#include <debug.h>
Include dependency graph for notify.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID SendOnlineNotification (IN PUNICODE_STRING SymbolicName)
 
VOID NTAPI SendOnlineNotificationWorker (IN PVOID Parameter)
 
VOID PostOnlineNotification (IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName)
 
VOID WaitForOnlinesToComplete (IN PDEVICE_EXTENSION DeviceExtension)
 
NTSTATUS NTAPI MountMgrTargetDeviceNotification (IN PVOID NotificationStructure, IN PVOID Context)
 
VOID RegisterForTargetDeviceNotification (IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
 
VOID MountMgrNotify (IN PDEVICE_EXTENSION DeviceExtension)
 
VOID MountMgrNotifyNameChange (IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, IN BOOLEAN ValidateVolume)
 
VOID RemoveWorkItem (IN PUNIQUE_ID_WORK_ITEM WorkItem)
 
VOID NTAPI UniqueIdChangeNotifyWorker (IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
 
NTSTATUS NTAPI UniqueIdChangeNotifyCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
VOID IssueUniqueIdChangeNotifyWorker (IN PUNIQUE_ID_WORK_ITEM WorkItem, IN PMOUNTDEV_UNIQUE_ID UniqueId)
 
VOID IssueUniqueIdChangeNotify (IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, IN PMOUNTDEV_UNIQUE_ID UniqueId)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 31 of file notify.c.

Function Documentation

◆ IssueUniqueIdChangeNotify()

VOID IssueUniqueIdChangeNotify ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  DeviceName,
IN PMOUNTDEV_UNIQUE_ID  UniqueId 
)

Definition at line 637 of file notify.c.

640{
642 PVOID IrpBuffer = NULL;
646
647 /* Get the associated device object */
650 &FileObject,
651 &DeviceObject);
652 if (!NT_SUCCESS(Status))
653 {
654 return;
655 }
656
657 /* And then, get attached device */
659
661
662 /* Allocate a work item */
664 if (!WorkItem)
665 {
667 return;
668 }
669
670 WorkItem->Event = NULL;
671 WorkItem->WorkItem = IoAllocateWorkItem(DeviceExtension->DeviceObject);
672 if (!WorkItem->WorkItem)
673 {
675 goto Cleanup;
676 }
677
678 WorkItem->DeviceExtension = DeviceExtension;
679 WorkItem->StackSize = DeviceObject->StackSize;
680 /* Already provide the IRP */
681 WorkItem->Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
682
684
685 if (!WorkItem->Irp)
686 {
687 goto Cleanup;
688 }
689
690 /* Ensure it has enough space */
691 IrpBuffer = AllocatePool(sizeof(MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT) + 1024);
692 if (!IrpBuffer)
693 {
694 goto Cleanup;
695 }
696
697 WorkItem->DeviceName.Length = DeviceName->Length;
698 WorkItem->DeviceName.MaximumLength = DeviceName->Length + sizeof(WCHAR);
699 WorkItem->DeviceName.Buffer = AllocatePool(WorkItem->DeviceName.MaximumLength);
700 if (!WorkItem->DeviceName.Buffer)
701 {
702 goto Cleanup;
703 }
704
705 RtlCopyMemory(WorkItem->DeviceName.Buffer, DeviceName->Buffer, DeviceName->Length);
706 WorkItem->DeviceName.Buffer[DeviceName->Length / sizeof(WCHAR)] = UNICODE_NULL;
707
708 WorkItem->IrpBuffer = IrpBuffer;
709 WorkItem->IrpBufferLength = sizeof(MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT) + 1024;
710
711 /* Add the worker in the list */
712 KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
713 InsertHeadList(&(DeviceExtension->UniqueIdWorkerItemListHead), &(WorkItem->UniqueIdWorkerItemListEntry));
714 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
715
716 /* And call the worker */
718
719 return;
720
721Cleanup:
722 if (IrpBuffer)
723 {
724 FreePool(IrpBuffer);
725 }
726
727 if (WorkItem->Irp)
728 {
729 IoFreeIrp(WorkItem->Irp);
730 }
731
732 if (WorkItem->WorkItem)
733 {
734 IoFreeWorkItem(WorkItem->WorkItem);
735 }
736
737 if (WorkItem)
738 {
740 }
741}
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR Cleanup[]
Definition: register.c:80
VOID IssueUniqueIdChangeNotifyWorker(IN PUNIQUE_ID_WORK_ITEM WorkItem, IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: notify.c:567
#define InsertHeadList(ListHead, Entry)
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
Status
Definition: gdiplustypes.h:25
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
#define AllocatePool(Size)
Definition: mntmgr.h:153
#define FreePool(P)
Definition: mntmgr.h:154
struct _MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT
#define KernelMode
Definition: asm.h:34
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define UNICODE_NULL
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:115
#define IO_NO_INCREMENT
Definition: iotypes.h:598
* PFILE_OBJECT
Definition: iotypes.h:1998
@ Executive
Definition: ketypes.h:415
#define ObDereferenceObject
Definition: obfuncs.h:203
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by MountMgrMountedDeviceArrival().

◆ IssueUniqueIdChangeNotifyWorker()

VOID IssueUniqueIdChangeNotifyWorker ( IN PUNIQUE_ID_WORK_ITEM  WorkItem,
IN PMOUNTDEV_UNIQUE_ID  UniqueId 
)

Definition at line 567 of file notify.c.

569{
570 PIRP Irp;
575
576 /* Get the device object */
579 &FileObject,
580 &DeviceObject);
581 if (!NT_SUCCESS(Status))
582 {
584 return;
585 }
586
587 /* And then, the attached device */
589
590 /* Initialize the IRP */
591 Irp = WorkItem->Irp;
592 IoInitializeIrp(Irp, IoSizeOfIrp(WorkItem->StackSize), (CCHAR)WorkItem->StackSize);
593
594 if (InterlockedExchange((PLONG)&(WorkItem->Event), 0) != 0)
595 {
599 return;
600 }
601
602 Irp->AssociatedIrp.SystemBuffer = WorkItem->IrpBuffer;
603 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
604 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, UniqueId, UniqueId->UniqueIdLength + sizeof(USHORT));
605
607
608 Stack->Parameters.DeviceIoControl.InputBufferLength = UniqueId->UniqueIdLength + sizeof(USHORT);
609 Stack->Parameters.DeviceIoControl.OutputBufferLength = WorkItem->IrpBufferLength;
610 Stack->Parameters.DeviceIoControl.Type3InputBuffer = 0;
611 Stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY;
612 Stack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
613
614 Status = IoSetCompletionRoutineEx(WorkItem->DeviceExtension->DeviceObject,
615 Irp,
617 WorkItem,
618 TRUE, TRUE, TRUE);
619 if (!NT_SUCCESS(Status))
620 {
624 return;
625 }
626
627 /* Call the driver */
631}
#define InterlockedExchange
Definition: armddk.h:54
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
VOID RemoveWorkItem(IN PUNIQUE_ID_WORK_ITEM WorkItem)
Definition: notify.c:457
NTSTATUS NTAPI UniqueIdChangeNotifyCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: notify.c:545
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
NTSTATUS NTAPI IoSetCompletionRoutineEx(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_COMPLETION_ROUTINE CompletionRoutine, IN PVOID Context, IN BOOLEAN InvokeOnSuccess, IN BOOLEAN InvokeOnError, IN BOOLEAN InvokeOnCancel)
Definition: iocomp.c:220
#define IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY
Definition: imports.h:86
VOID NTAPI IoInitializeIrp(IN PIRP Irp, IN USHORT PacketSize, IN CCHAR StackSize)
Definition: irp.c:1854
#define IoCallDriver
Definition: irp.c:1225
unsigned short USHORT
Definition: pedump.c:61
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
int32_t * PLONG
Definition: typedefs.h:58
char CCHAR
Definition: typedefs.h:51
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define IoSizeOfIrp(_StackSize)

Referenced by IssueUniqueIdChangeNotify(), and UniqueIdChangeNotifyWorker().

◆ MountMgrNotify()

VOID MountMgrNotify ( IN PDEVICE_EXTENSION  DeviceExtension)

Definition at line 288 of file notify.c.

289{
290 PIRP Irp;
292 LIST_ENTRY CopyList;
293 PLIST_ENTRY NextEntry;
294
295 /* Increase the epic number */
296 DeviceExtension->EpicNumber++;
297
298 InitializeListHead(&CopyList);
299
300 /* Copy all the pending IRPs for notification */
302 while (!IsListEmpty(&(DeviceExtension->IrpListHead)))
303 {
304 NextEntry = RemoveHeadList(&(DeviceExtension->IrpListHead));
305 Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
307 InsertTailList(&CopyList, &(Irp->Tail.Overlay.ListEntry));
308 }
310
311 /* Then, notify them one by one */
312 while (!IsListEmpty(&CopyList))
313 {
314 NextEntry = RemoveHeadList(&CopyList);
315 Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
316
317 *((PULONG)Irp->AssociatedIrp.SystemBuffer) = DeviceExtension->EpicNumber;
318 Irp->IoStatus.Information = sizeof(DeviceExtension->EpicNumber);
319
321 }
322}
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
IoSetCancelRoutine(Irp, CancelRoutine)
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
Definition: typedefs.h:120
uint32_t * PULONG
Definition: typedefs.h:59
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by MountMgrCreatePointWorker(), MountMgrDeletePoints(), and MountMgrVolumeMountPointChanged().

◆ MountMgrNotifyNameChange()

VOID MountMgrNotifyNameChange ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  DeviceName,
IN BOOLEAN  ValidateVolume 
)

Definition at line 328 of file notify.c.

331{
332 PIRP Irp;
335 PLIST_ENTRY NextEntry;
340 PDEVICE_RELATIONS DeviceRelations;
341 PDEVICE_INFORMATION DeviceInformation;
342 TARGET_DEVICE_CUSTOM_NOTIFICATION DeviceNotification;
343
344 /* If we have to validate volume */
345 if (ValidateVolume)
346 {
347 /* Then, ensure we can find the device */
348 for (NextEntry = DeviceExtension->DeviceListHead.Flink;
349 NextEntry != &DeviceExtension->DeviceListHead;
350 NextEntry = NextEntry->Flink)
351 {
352 DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
353 if (RtlCompareUnicodeString(DeviceName, &(DeviceInformation->DeviceName), TRUE) == 0)
354 {
355 break;
356 }
357 }
358
359 /* No need to notify for a PnP device or if we didn't find the device */
360 if (NextEntry == &(DeviceExtension->DeviceListHead) ||
361 !DeviceInformation->ManuallyRegistered)
362 {
363 return;
364 }
365 }
366
367 /* Then, get device object */
370 &FileObject,
371 &DeviceObject);
372 if (!NT_SUCCESS(Status))
373 {
374 return;
375 }
376
378
380
381 /* Set up empty IRP (yes, yes!) */
384 NULL,
385 0,
386 NULL,
387 0,
388 FALSE,
389 &Event,
391 if (!Irp)
392 {
395 return;
396 }
397
399
400 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
401 Irp->IoStatus.Information = 0;
402
403 /* Properly set it, we want to query device relations */
404 Stack->MajorFunction = IRP_MJ_PNP;
405 Stack->MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS;
406 Stack->Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
407 Stack->FileObject = FileObject;
408
409 /* And call driver */
411 if (Status == STATUS_PENDING)
412 {
415 }
416
419
420 if (!NT_SUCCESS(Status))
421 {
422 return;
423 }
424
425 /* Validate device return */
427 if (DeviceRelations->Count < 1)
428 {
429 ExFreePool(DeviceRelations);
430 return;
431 }
432
433 DeviceObject = DeviceRelations->Objects[0];
434 ExFreePool(DeviceRelations);
435
436 /* Set up real notification */
437 DeviceNotification.Version = 1;
438 DeviceNotification.Size = sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION);
439 DeviceNotification.Event = GUID_IO_VOLUME_NAME_CHANGE;
440 DeviceNotification.FileObject = NULL;
441 DeviceNotification.NameBufferOffset = -1;
442
443 /* And report */
445 &DeviceNotification,
446 NULL, NULL);
447
449
450 return;
451}
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
if(dx< 0)
Definition: linetemp.h:194
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
@ NotificationEvent
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
NTSTATUS NTAPI IoReportTargetDeviceChangeAsynchronous(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PVOID NotificationStructure, IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL, IN PVOID Context OPTIONAL)
Definition: pnpreport.c:498
BOOLEAN ManuallyRegistered
Definition: mntmgr.h:53
UNICODE_STRING DeviceName
Definition: mntmgr.h:50
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _FILE_OBJECT * FileObject
Definition: iotypes.h:1012
@ TargetDeviceRelation
Definition: iotypes.h:2156
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
#define IRP_MN_QUERY_DEVICE_RELATIONS
struct _TARGET_DEVICE_CUSTOM_NOTIFICATION TARGET_DEVICE_CUSTOM_NOTIFICATION

Referenced by MountMgrCreatePointWorker(), MountMgrDeletePoints(), MountMgrQueryDosVolumePaths(), and MountMgrVolumeMountPointChanged().

◆ MountMgrTargetDeviceNotification()

NTSTATUS NTAPI MountMgrTargetDeviceNotification ( IN PVOID  NotificationStructure,
IN PVOID  Context 
)

Definition at line 206 of file notify.c.

208{
209 PDEVICE_EXTENSION DeviceExtension;
210 PDEVICE_INFORMATION DeviceInformation;
212
213 DeviceInformation = Context;
214 DeviceExtension = DeviceInformation->DeviceExtension;
216
217 /* The notification have to be unregistered already (in device interface change handler) */
218 ASSERT(!IsEqualGUID(&Notification->Event, &GUID_TARGET_DEVICE_REMOVE_COMPLETE));
219
220 /* It it's to signal that a volume has been mounted
221 * Verify if a database sync is required and execute it
222 */
223 if (IsEqualGUID(&(Notification->Event), &GUID_IO_VOLUME_MOUNT))
224 {
225 /* If we were already mounted, then mark us unmounted */
226 if (InterlockedCompareExchange(&(DeviceInformation->MountState),
227 FALSE,
228 FALSE) == TRUE)
229 {
230 InterlockedDecrement(&(DeviceInformation->MountState));
231 }
232 /* Otherwise, start mounting the device and first, reconcile its DB if required */
233 else
234 {
235 if (DeviceInformation->NeedsReconcile)
236 {
237 DeviceInformation->NeedsReconcile = FALSE;
238 ReconcileThisDatabaseWithMaster(DeviceExtension, DeviceInformation);
239 }
240 }
241 }
242
243 return STATUS_SUCCESS;
244}
#define InterlockedDecrement
Definition: armddk.h:52
VOID ReconcileThisDatabaseWithMaster(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
Definition: database.c:1613
#define InterlockedCompareExchange
Definition: interlocked.h:104
#define ASSERT(a)
Definition: mode.c:44
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define STATUS_SUCCESS
Definition: shellext.h:65
PDEVICE_EXTENSION DeviceExtension
Definition: mntmgr.h:62
BOOLEAN NeedsReconcile
Definition: mntmgr.h:56
_In_ PWDFDEVICE_INIT _In_ PFN_WDF_DEVICE_SHUTDOWN_NOTIFICATION Notification
Definition: wdfcontrol.h:115
_In_ PVOID NotificationStructure
Definition: iofuncs.h:1206

Referenced by RegisterForTargetDeviceNotification().

◆ PostOnlineNotification()

VOID PostOnlineNotification ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  SymbolicName 
)

Definition at line 122 of file notify.c.

124{
127
128 /* Allocate a notification work item */
130 if (!WorkItem)
131 {
132 return;
133 }
134
136 WorkItem->DeviceExtension = DeviceExtension;
137 WorkItem->SymbolicName.Length = SymbolicName->Length;
138 WorkItem->SymbolicName.MaximumLength = SymbolicName->Length + sizeof(WCHAR);
139 WorkItem->SymbolicName.Buffer = AllocatePool(WorkItem->SymbolicName.MaximumLength);
140 if (!WorkItem->SymbolicName.Buffer)
141 {
143 return;
144 }
145
147 WorkItem->SymbolicName.Buffer[SymbolicName->Length / sizeof(WCHAR)] = UNICODE_NULL;
148
149 KeAcquireSpinLock(&(DeviceExtension->WorkerLock), &OldIrql);
150 DeviceExtension->OnlineNotificationCount++;
151
152 /* If no worker are active */
153 if (DeviceExtension->OnlineNotificationWorkerActive == 0)
154 {
155 /* Queue that one for execution */
156 DeviceExtension->OnlineNotificationWorkerActive = 1;
158 }
159 else
160 {
161 /* Otherwise, just put it in the queue list */
162 InsertTailList(&(DeviceExtension->OnlineNotificationListHead), &(WorkItem->WorkItem.List));
163 }
164
165 KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
166
167 return;
168}
VOID NTAPI SendOnlineNotificationWorker(IN PVOID Parameter)
Definition: notify.c:73
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4677
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
@ DelayedWorkQueue
Definition: extypes.h:190

Referenced by MountMgrCreatePointWorker(), MountMgrVolumeMountPointCreated(), OnlineMountedVolumes(), and ReconcileThisDatabaseWithMasterWorker().

◆ RegisterForTargetDeviceNotification()

VOID RegisterForTargetDeviceNotification ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PDEVICE_INFORMATION  DeviceInformation 
)

Definition at line 250 of file notify.c.

252{
256
257 /* Get device object */
258 Status = IoGetDeviceObjectPointer(&(DeviceInformation->DeviceName),
260 &FileObject,
261 &DeviceObject);
262 if (!NT_SUCCESS(Status))
263 {
264 return;
265 }
266
267 /* And simply register for notifications */
269 0, FileObject,
270 DeviceExtension->DriverObject,
272 DeviceInformation,
273 &(DeviceInformation->TargetDeviceNotificationEntry));
274 if (!NT_SUCCESS(Status))
275 {
276 DeviceInformation->TargetDeviceNotificationEntry = NULL;
277 }
278
280
281 return;
282}
NTSTATUS NTAPI MountMgrTargetDeviceNotification(IN PVOID NotificationStructure, IN PVOID Context)
Definition: notify.c:206
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: pnpnotify.c:345
@ EventCategoryTargetDeviceChange
Definition: iotypes.h:1227

Referenced by MountMgrMountedDeviceArrival().

◆ RemoveWorkItem()

VOID RemoveWorkItem ( IN PUNIQUE_ID_WORK_ITEM  WorkItem)

Definition at line 457 of file notify.c.

458{
459 PDEVICE_EXTENSION DeviceExtension = WorkItem->DeviceExtension;
460
461 KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
462
463 /* If even if being worked, it's too late */
464 if (WorkItem->Event)
465 {
466 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
467 KeSetEvent(WorkItem->Event, 0, FALSE);
468 }
469 else
470 {
471 /* Otherwise, remove it from the list, and delete it */
472 RemoveEntryList(&(WorkItem->UniqueIdWorkerItemListEntry));
473 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
474 IoFreeIrp(WorkItem->Irp);
475 FreePool(WorkItem->DeviceName.Buffer);
476 FreePool(WorkItem->IrpBuffer);
478 }
479}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476

Referenced by IssueUniqueIdChangeNotifyWorker(), and UniqueIdChangeNotifyWorker().

◆ SendOnlineNotification()

VOID SendOnlineNotification ( IN PUNICODE_STRING  SymbolicName)

Definition at line 38 of file notify.c.

39{
43
44 /* Get device object */
49 if (!NT_SUCCESS(Status))
50 return;
51
52 /* And attached device object */
54
55 /* And send VOLUME_ONLINE */
56 Status = MountMgrSendSyncDeviceIoCtl(IOCTL_VOLUME_ONLINE,
58 NULL, 0,
59 NULL, 0,
62
65 return;
66}
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define IOCTL_VOLUME_ONLINE
Definition: ntddvol.h:63

Referenced by MountMgrMountedDeviceArrival(), and SendOnlineNotificationWorker().

◆ SendOnlineNotificationWorker()

VOID NTAPI SendOnlineNotificationWorker ( IN PVOID  Parameter)

Definition at line 73 of file notify.c.

74{
76 PLIST_ENTRY Head;
77 PDEVICE_EXTENSION DeviceExtension;
80
82 DeviceExtension = WorkItem->DeviceExtension;
83
84 /* First, send the notification */
85 SendOnlineNotification(&(WorkItem->SymbolicName));
86
87 KeAcquireSpinLock(&(DeviceExtension->WorkerLock), &OldIrql);
88 /* If there are no notifications running any longer, reset event */
89 if (--DeviceExtension->OnlineNotificationCount == 0)
90 {
91 KeSetEvent(&(DeviceExtension->OnlineNotificationEvent), 0, FALSE);
92 }
93
94 /* If there are still notifications in queue */
95 if (!IsListEmpty(&(DeviceExtension->OnlineNotificationListHead)))
96 {
97 /* Queue a new one for execution */
98 Head = RemoveHeadList(&(DeviceExtension->OnlineNotificationListHead));
100 KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
101 NewWorkItem->WorkItem.List.Blink = NULL;
102 NewWorkItem->WorkItem.List.Flink = NULL;
104 }
105 else
106 {
107 /* Mark it's over */
108 DeviceExtension->OnlineNotificationWorkerActive = 0;
109 KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
110 }
111
112 FreePool(WorkItem->SymbolicName.Buffer);
114
115 return;
116}
VOID SendOnlineNotification(IN PUNICODE_STRING SymbolicName)
Definition: notify.c:38
struct _ONLINE_NOTIFICATION_WORK_ITEM * PONLINE_NOTIFICATION_WORK_ITEM
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
WORK_QUEUE_ITEM WorkItem
Definition: mntmgr.h:110
LIST_ENTRY List
Definition: extypes.h:203
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:336

Referenced by PostOnlineNotification().

◆ UniqueIdChangeNotifyCompletion()

NTSTATUS NTAPI UniqueIdChangeNotifyCompletion ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  Context 
)

Definition at line 545 of file notify.c.

548{
550
553
554 /* Simply queue the work item */
555 IoQueueWorkItem(WorkItem->WorkItem,
558 WorkItem);
559
561}
VOID NTAPI UniqueIdChangeNotifyWorker(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
Definition: notify.c:486
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68

Referenced by IssueUniqueIdChangeNotifyWorker().

◆ UniqueIdChangeNotifyWorker()

VOID NTAPI UniqueIdChangeNotifyWorker ( IN PDEVICE_OBJECT  DeviceObject,
IN PVOID  Context 
)

Definition at line 486 of file notify.c.

488{
490 PMOUNTDEV_UNIQUE_ID OldUniqueId, NewUniqueId;
492
494
495 /* Validate worker */
496 if (!NT_SUCCESS(WorkItem->Irp->IoStatus.Status))
497 {
499 return;
500 }
501
502 UniqueIdChange = WorkItem->Irp->AssociatedIrp.SystemBuffer;
503 /* Get the old unique ID */
504 OldUniqueId = AllocatePool(UniqueIdChange->OldUniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
505 if (!OldUniqueId)
506 {
508 return;
509 }
510
511 OldUniqueId->UniqueIdLength = UniqueIdChange->OldUniqueIdLength;
512 RtlCopyMemory(OldUniqueId->UniqueId,
513 (PVOID)((ULONG_PTR)UniqueIdChange + UniqueIdChange->OldUniqueIdOffset),
514 UniqueIdChange->OldUniqueIdLength);
515
516 /* Get the new unique ID */
517 NewUniqueId = AllocatePool(UniqueIdChange->NewUniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
518 if (!NewUniqueId)
519 {
520 FreePool(OldUniqueId);
522 return;
523 }
524
525 NewUniqueId->UniqueIdLength = UniqueIdChange->NewUniqueIdLength;
526 RtlCopyMemory(NewUniqueId->UniqueId,
527 (PVOID)((ULONG_PTR)UniqueIdChange + UniqueIdChange->NewUniqueIdOffset),
528 UniqueIdChange->NewUniqueIdLength);
529
530 /* Call the real worker */
531 MountMgrUniqueIdChangeRoutine(WorkItem->DeviceExtension, OldUniqueId, NewUniqueId);
533
534 FreePool(NewUniqueId);
535 FreePool(OldUniqueId);
536
537 return;
538}
VOID MountMgrUniqueIdChangeRoutine(IN PDEVICE_EXTENSION DeviceExtension, IN PMOUNTDEV_UNIQUE_ID OldUniqueId, IN PMOUNTDEV_UNIQUE_ID NewUniqueId)
Definition: uniqueid.c:71
USHORT UniqueIdLength
Definition: imports.h:138
UCHAR UniqueId[1]
Definition: imports.h:139
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by UniqueIdChangeNotifyCompletion().

◆ WaitForOnlinesToComplete()

VOID WaitForOnlinesToComplete ( IN PDEVICE_EXTENSION  DeviceExtension)

Definition at line 174 of file notify.c.

175{
177
178 KeInitializeEvent(&(DeviceExtension->OnlineNotificationEvent), NotificationEvent, FALSE);
179
180 KeAcquireSpinLock(&(DeviceExtension->WorkerLock), &OldIrql);
181
182 /* Just wait all the worker are done */
183 if (DeviceExtension->OnlineNotificationCount != 1)
184 {
185 DeviceExtension->OnlineNotificationCount--;
186 KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
187
188 KeWaitForSingleObject(&(DeviceExtension->OnlineNotificationEvent),
189 Executive,
191 FALSE,
192 NULL);
193
194 KeAcquireSpinLock(&(DeviceExtension->WorkerLock), &OldIrql);
195 DeviceExtension->OnlineNotificationCount++;
196 }
197
198 KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
199}

Referenced by MountMgrDeviceControl().