ReactOS 0.4.15-dev-7953-g1f49173
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 660 of file notify.c.

663{
665 PVOID IrpBuffer = NULL;
669
670 /* Get the associated device object */
673 &FileObject,
674 &DeviceObject);
675 if (!NT_SUCCESS(Status))
676 {
677 return;
678 }
679
680 /* And then, get attached device */
682
684
685 /* Allocate a work item */
687 if (!WorkItem)
688 {
690 return;
691 }
692
693 WorkItem->Event = NULL;
694 WorkItem->WorkItem = IoAllocateWorkItem(DeviceExtension->DeviceObject);
695 if (!WorkItem->WorkItem)
696 {
698 goto Cleanup;
699 }
700
701 WorkItem->DeviceExtension = DeviceExtension;
702 WorkItem->StackSize = DeviceObject->StackSize;
703 /* Already provide the IRP */
704 WorkItem->Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
705
707
708 if (!WorkItem->Irp)
709 {
710 goto Cleanup;
711 }
712
713 /* Ensure it has enough space */
714 IrpBuffer = AllocatePool(sizeof(MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT) + 1024);
715 if (!IrpBuffer)
716 {
717 goto Cleanup;
718 }
719
720 WorkItem->DeviceName.Length = DeviceName->Length;
721 WorkItem->DeviceName.MaximumLength = DeviceName->Length + sizeof(WCHAR);
722 WorkItem->DeviceName.Buffer = AllocatePool(WorkItem->DeviceName.MaximumLength);
723 if (!WorkItem->DeviceName.Buffer)
724 {
725 goto Cleanup;
726 }
727
728 RtlCopyMemory(WorkItem->DeviceName.Buffer, DeviceName->Buffer, DeviceName->Length);
729 WorkItem->DeviceName.Buffer[DeviceName->Length / sizeof(WCHAR)] = UNICODE_NULL;
730
731 WorkItem->IrpBuffer = IrpBuffer;
732 WorkItem->IrpBufferLength = sizeof(MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT) + 1024;
733
734 /* Add the worker in the list */
735 KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
736 InsertHeadList(&(DeviceExtension->UniqueIdWorkerItemListHead), &(WorkItem->UniqueIdWorkerItemListEntry));
737 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
738
739 /* And call the worker */
741
742 return;
743
744Cleanup:
745 if (IrpBuffer)
746 {
747 FreePool(IrpBuffer);
748 }
749
750 if (WorkItem->Irp)
751 {
752 IoFreeIrp(WorkItem->Irp);
753 }
754
755 if (WorkItem->WorkItem)
756 {
757 IoFreeWorkItem(WorkItem->WorkItem);
758 }
759
760 if (WorkItem)
761 {
763 }
764}
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:590
#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 590 of file notify.c.

592{
593 PIRP Irp;
598
599 /* Get the device object */
602 &FileObject,
603 &DeviceObject);
604 if (!NT_SUCCESS(Status))
605 {
607 return;
608 }
609
610 /* And then, the attached device */
612
613 /* Initialize the IRP */
614 Irp = WorkItem->Irp;
615 IoInitializeIrp(Irp, IoSizeOfIrp(WorkItem->StackSize), (CCHAR)WorkItem->StackSize);
616
617 if (InterlockedExchange((PLONG)&(WorkItem->Event), 0) != 0)
618 {
622 return;
623 }
624
625 Irp->AssociatedIrp.SystemBuffer = WorkItem->IrpBuffer;
626 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
627 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, UniqueId, UniqueId->UniqueIdLength + sizeof(USHORT));
628
630
631 Stack->Parameters.DeviceIoControl.InputBufferLength = UniqueId->UniqueIdLength + sizeof(USHORT);
632 Stack->Parameters.DeviceIoControl.OutputBufferLength = WorkItem->IrpBufferLength;
633 Stack->Parameters.DeviceIoControl.Type3InputBuffer = 0;
634 Stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY;
635 Stack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
636
637 Status = IoSetCompletionRoutineEx(WorkItem->DeviceExtension->DeviceObject,
638 Irp,
640 WorkItem,
641 TRUE, TRUE, TRUE);
642 if (!NT_SUCCESS(Status))
643 {
647 return;
648 }
649
650 /* Call the driver */
654}
#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:480
NTSTATUS NTAPI UniqueIdChangeNotifyCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: notify.c:568
#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 311 of file notify.c.

312{
313 PIRP Irp;
315 LIST_ENTRY CopyList;
316 PLIST_ENTRY NextEntry;
317
318 /* Increase the epic number */
319 DeviceExtension->EpicNumber++;
320
321 InitializeListHead(&CopyList);
322
323 /* Copy all the pending IRPs for notification */
325 while (!IsListEmpty(&(DeviceExtension->IrpListHead)))
326 {
327 NextEntry = RemoveHeadList(&(DeviceExtension->IrpListHead));
328 Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
330 InsertTailList(&CopyList, &(Irp->Tail.Overlay.ListEntry));
331 }
333
334 /* Then, notify them one by one */
335 while (!IsListEmpty(&CopyList))
336 {
337 NextEntry = RemoveHeadList(&CopyList);
338 Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
339
340 *((PULONG)Irp->AssociatedIrp.SystemBuffer) = DeviceExtension->EpicNumber;
341 Irp->IoStatus.Information = sizeof(DeviceExtension->EpicNumber);
342
344 }
345}
#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 351 of file notify.c.

354{
355 PIRP Irp;
358 PLIST_ENTRY NextEntry;
363 PDEVICE_RELATIONS DeviceRelations;
364 PDEVICE_INFORMATION DeviceInformation;
365 TARGET_DEVICE_CUSTOM_NOTIFICATION DeviceNotification;
366
367 /* If we have to validate volume */
368 if (ValidateVolume)
369 {
370 /* Then, ensure we can find the device */
371 for (NextEntry = DeviceExtension->DeviceListHead.Flink;
372 NextEntry != &DeviceExtension->DeviceListHead;
373 NextEntry = NextEntry->Flink)
374 {
375 DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
376 if (RtlCompareUnicodeString(DeviceName, &(DeviceInformation->DeviceName), TRUE) == 0)
377 {
378 break;
379 }
380 }
381
382 /* No need to notify for a PnP device or if we didn't find the device */
383 if (NextEntry == &(DeviceExtension->DeviceListHead) ||
384 !DeviceInformation->ManuallyRegistered)
385 {
386 return;
387 }
388 }
389
390 /* Then, get device object */
393 &FileObject,
394 &DeviceObject);
395 if (!NT_SUCCESS(Status))
396 {
397 return;
398 }
399
401
403
404 /* Set up empty IRP (yes, yes!) */
407 NULL,
408 0,
409 NULL,
410 0,
411 FALSE,
412 &Event,
414 if (!Irp)
415 {
418 return;
419 }
420
422
423 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
424 Irp->IoStatus.Information = 0;
425
426 /* Properly set it, we want to query device relations */
427 Stack->MajorFunction = IRP_MJ_PNP;
428 Stack->MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS;
429 Stack->Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
430 Stack->FileObject = FileObject;
431
432 /* And call driver */
434 if (Status == STATUS_PENDING)
435 {
438 }
439
442
443 if (!NT_SUCCESS(Status))
444 {
445 return;
446 }
447
448 /* Validate device return */
450 if (DeviceRelations->Count < 1)
451 {
452 ExFreePool(DeviceRelations);
453 return;
454 }
455
456 DeviceObject = DeviceRelations->Objects[0];
457 ExFreePool(DeviceRelations);
458
459 /* Set up real notification */
460 DeviceNotification.Version = 1;
461 DeviceNotification.Size = sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION);
462 DeviceNotification.Event = GUID_IO_VOLUME_NAME_CHANGE;
463 DeviceNotification.FileObject = NULL;
464 DeviceNotification.NameBufferOffset = -1;
465
466 /* And report */
468 &DeviceNotification,
469 NULL, NULL);
470
472
473 return;
474}
#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 229 of file notify.c.

231{
232 PDEVICE_EXTENSION DeviceExtension;
233 PDEVICE_INFORMATION DeviceInformation;
235
236 DeviceInformation = Context;
237 DeviceExtension = DeviceInformation->DeviceExtension;
239
240 /* The notification have to be unregistered already (in device interface change handler) */
241 ASSERT(!IsEqualGUID(&Notification->Event, &GUID_TARGET_DEVICE_REMOVE_COMPLETE));
242
243 /* It it's to signal that a volume has been mounted
244 * Verify if a database sync is required and execute it
245 */
246 if (IsEqualGUID(&(Notification->Event), &GUID_IO_VOLUME_MOUNT))
247 {
248 /* If we were already mounted, then mark us unmounted */
249 if (InterlockedCompareExchange(&(DeviceInformation->MountState),
250 FALSE,
251 FALSE) == TRUE)
252 {
253 InterlockedDecrement(&(DeviceInformation->MountState));
254 }
255 /* Otherwise, start mounting the device and first, reconcile its DB if required */
256 else
257 {
258 if (DeviceInformation->NeedsReconcile)
259 {
260 DeviceInformation->NeedsReconcile = FALSE;
261 ReconcileThisDatabaseWithMaster(DeviceExtension, DeviceInformation);
262 }
263 }
264 }
265
266 return STATUS_SUCCESS;
267}
#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 145 of file notify.c.

147{
150
151 /* Allocate a notification work item */
153 if (!WorkItem)
154 {
155 return;
156 }
157
159 WorkItem->DeviceExtension = DeviceExtension;
160 WorkItem->SymbolicName.Length = SymbolicName->Length;
161 WorkItem->SymbolicName.MaximumLength = SymbolicName->Length + sizeof(WCHAR);
162 WorkItem->SymbolicName.Buffer = AllocatePool(WorkItem->SymbolicName.MaximumLength);
163 if (!WorkItem->SymbolicName.Buffer)
164 {
166 return;
167 }
168
170 WorkItem->SymbolicName.Buffer[SymbolicName->Length / sizeof(WCHAR)] = UNICODE_NULL;
171
172 KeAcquireSpinLock(&(DeviceExtension->WorkerLock), &OldIrql);
173 DeviceExtension->OnlineNotificationCount++;
174
175 /* If no worker are active */
176 if (DeviceExtension->OnlineNotificationWorkerActive == 0)
177 {
178 /* Queue that one for execution */
179 DeviceExtension->OnlineNotificationWorkerActive = 1;
181 }
182 else
183 {
184 /* Otherwise, just put it in the queue list */
185 InsertTailList(&(DeviceExtension->OnlineNotificationListHead), &(WorkItem->WorkItem.List));
186 }
187
188 KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
189
190 return;
191}
VOID NTAPI SendOnlineNotificationWorker(IN PVOID Parameter)
Definition: notify.c:96
#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 273 of file notify.c.

275{
279
280 /* Get device object */
281 Status = IoGetDeviceObjectPointer(&(DeviceInformation->DeviceName),
283 &FileObject,
284 &DeviceObject);
285 if (!NT_SUCCESS(Status))
286 {
287 return;
288 }
289
290 /* And simply register for notifications */
292 0, FileObject,
293 DeviceExtension->DriverObject,
295 DeviceInformation,
296 &(DeviceInformation->TargetDeviceNotificationEntry));
297 if (!NT_SUCCESS(Status))
298 {
299 DeviceInformation->TargetDeviceNotificationEntry = NULL;
300 }
301
303
304 return;
305}
NTSTATUS NTAPI MountMgrTargetDeviceNotification(IN PVOID NotificationStructure, IN PVOID Context)
Definition: notify.c:229
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 480 of file notify.c.

481{
482 PDEVICE_EXTENSION DeviceExtension = WorkItem->DeviceExtension;
483
484 KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
485
486 /* If even if being worked, it's too late */
487 if (WorkItem->Event)
488 {
489 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
490 KeSetEvent(WorkItem->Event, 0, FALSE);
491 }
492 else
493 {
494 /* Otherwise, remove it from the list, and delete it */
495 RemoveEntryList(&(WorkItem->UniqueIdWorkerItemListEntry));
496 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
497 IoFreeIrp(WorkItem->Irp);
498 FreePool(WorkItem->DeviceName.Buffer);
499 FreePool(WorkItem->IrpBuffer);
501 }
502}
#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{
40 PIRP Irp;
47
48 /* Get device object */
53 if (!NT_SUCCESS(Status))
54 {
55 return;
56 }
57
58 /* And attached device object */
60
61 /* And send VOLUME_ONLINE */
65 NULL, 0,
66 NULL, 0,
67 FALSE,
68 &Event,
70 if (!Irp)
71 {
72 goto Cleanup;
73 }
74
76 Stack->FileObject = FileObject;
77
80 {
82 }
83
87
88 return;
89}
#define IOCTL_VOLUME_ONLINE
Definition: ntddvol.h:62

Referenced by MountMgrMountedDeviceArrival(), and SendOnlineNotificationWorker().

◆ SendOnlineNotificationWorker()

VOID NTAPI SendOnlineNotificationWorker ( IN PVOID  Parameter)

Definition at line 96 of file notify.c.

97{
99 PLIST_ENTRY Head;
100 PDEVICE_EXTENSION DeviceExtension;
103
105 DeviceExtension = WorkItem->DeviceExtension;
106
107 /* First, send the notification */
108 SendOnlineNotification(&(WorkItem->SymbolicName));
109
110 KeAcquireSpinLock(&(DeviceExtension->WorkerLock), &OldIrql);
111 /* If there are no notifications running any longer, reset event */
112 if (--DeviceExtension->OnlineNotificationCount == 0)
113 {
114 KeSetEvent(&(DeviceExtension->OnlineNotificationEvent), 0, FALSE);
115 }
116
117 /* If there are still notifications in queue */
118 if (!IsListEmpty(&(DeviceExtension->OnlineNotificationListHead)))
119 {
120 /* Queue a new one for execution */
121 Head = RemoveHeadList(&(DeviceExtension->OnlineNotificationListHead));
123 KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
124 NewWorkItem->WorkItem.List.Blink = NULL;
125 NewWorkItem->WorkItem.List.Flink = NULL;
127 }
128 else
129 {
130 /* Mark it's over */
131 DeviceExtension->OnlineNotificationWorkerActive = 0;
132 KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
133 }
134
135 FreePool(WorkItem->SymbolicName.Buffer);
137
138 return;
139}
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:323

Referenced by PostOnlineNotification().

◆ UniqueIdChangeNotifyCompletion()

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

Definition at line 568 of file notify.c.

571{
573
576
577 /* Simply queue the work item */
578 IoQueueWorkItem(WorkItem->WorkItem,
581 WorkItem);
582
584}
VOID NTAPI UniqueIdChangeNotifyWorker(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
Definition: notify.c:509
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 UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#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 509 of file notify.c.

511{
513 PMOUNTDEV_UNIQUE_ID OldUniqueId, NewUniqueId;
515
517
518 /* Validate worker */
519 if (!NT_SUCCESS(WorkItem->Irp->IoStatus.Status))
520 {
522 return;
523 }
524
525 UniqueIdChange = WorkItem->Irp->AssociatedIrp.SystemBuffer;
526 /* Get the old unique ID */
527 OldUniqueId = AllocatePool(UniqueIdChange->OldUniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
528 if (!OldUniqueId)
529 {
531 return;
532 }
533
534 OldUniqueId->UniqueIdLength = UniqueIdChange->OldUniqueIdLength;
535 RtlCopyMemory(OldUniqueId->UniqueId,
536 (PVOID)((ULONG_PTR)UniqueIdChange + UniqueIdChange->OldUniqueIdOffset),
537 UniqueIdChange->OldUniqueIdLength);
538
539 /* Get the new unique ID */
540 NewUniqueId = AllocatePool(UniqueIdChange->NewUniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
541 if (!NewUniqueId)
542 {
543 FreePool(OldUniqueId);
545 return;
546 }
547
548 NewUniqueId->UniqueIdLength = UniqueIdChange->NewUniqueIdLength;
549 RtlCopyMemory(NewUniqueId->UniqueId,
550 (PVOID)((ULONG_PTR)UniqueIdChange + UniqueIdChange->NewUniqueIdOffset),
551 UniqueIdChange->NewUniqueIdLength);
552
553 /* Call the real worker */
554 MountMgrUniqueIdChangeRoutine(WorkItem->DeviceExtension, OldUniqueId, NewUniqueId);
556
557 FreePool(NewUniqueId);
558 FreePool(OldUniqueId);
559
560 return;
561}
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 197 of file notify.c.

198{
200
201 KeInitializeEvent(&(DeviceExtension->OnlineNotificationEvent), NotificationEvent, FALSE);
202
203 KeAcquireSpinLock(&(DeviceExtension->WorkerLock), &OldIrql);
204
205 /* Just wait all the worker are done */
206 if (DeviceExtension->OnlineNotificationCount != 1)
207 {
208 DeviceExtension->OnlineNotificationCount--;
209 KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
210
211 KeWaitForSingleObject(&(DeviceExtension->OnlineNotificationEvent),
212 Executive,
214 FALSE,
215 NULL);
216
217 KeAcquireSpinLock(&(DeviceExtension->WorkerLock), &OldIrql);
218 DeviceExtension->OnlineNotificationCount++;
219 }
220
221 KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
222}

Referenced by MountMgrDeviceControl().