ReactOS 0.4.15-dev-7958-gcd0bb1a
notify.c
Go to the documentation of this file.
1/*
2 * ReactOS kernel
3 * Copyright (C) 2011 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
18 *
19 * COPYRIGHT: See COPYING in the top level directory
20 * PROJECT: ReactOS kernel
21 * FILE: drivers/filesystem/mountmgr/notify.c
22 * PURPOSE: Mount Manager - Notifications handlers
23 * PROGRAMMER: Pierre Schweitzer (pierre.schweitzer@reactos.org)
24 * Alex Ionescu (alex.ionescu@reactos.org)
25 */
26
27#include "mntmgr.h"
28
29#include <ioevent.h>
30
31#define NDEBUG
32#include <debug.h>
33
34/*
35 * @implemented
36 */
37VOID
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}
90
91/*
92 * @implemented
93 */
94VOID
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}
140
141/*
142 * @implemented
143 */
144VOID
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}
192
193/*
194 * @implemented
195 */
196VOID
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}
223
224/*
225 * @implemented
226 */
228NTAPI
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}
268
269/*
270 * @implemented
271 */
272VOID
274 IN PDEVICE_INFORMATION DeviceInformation)
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}
306
307/*
308 * @implemented
309 */
310VOID
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}
346
347/*
348 * @implemented
349 */
350VOID
353 IN BOOLEAN ValidateVolume)
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}
475
476/*
477 * @implemented
478 */
479VOID
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}
503
504/*
505 * @implemented
506 */
507VOID
508NTAPI
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}
562
563/*
564 * @implemented
565 */
567NTAPI
569 IN PIRP Irp,
571{
573
576
577 /* Simply queue the work item */
578 IoQueueWorkItem(WorkItem->WorkItem,
581 WorkItem);
582
584}
585
586/*
587 * @implemented
588 */
589VOID
591 IN PMOUNTDEV_UNIQUE_ID UniqueId)
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}
655
656/*
657 * @implemented
658 */
659VOID
662 IN PMOUNTDEV_UNIQUE_ID UniqueId)
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}
unsigned char BOOLEAN
#define InterlockedExchange
Definition: armddk.h:54
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR Cleanup[]
Definition: register.c:80
VOID ReconcileThisDatabaseWithMaster(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
Definition: database.c:1613
VOID SendOnlineNotification(IN PUNICODE_STRING SymbolicName)
Definition: notify.c:38
VOID NTAPI SendOnlineNotificationWorker(IN PVOID Parameter)
Definition: notify.c:96
NTSTATUS NTAPI MountMgrTargetDeviceNotification(IN PVOID NotificationStructure, IN PVOID Context)
Definition: notify.c:229
VOID RemoveWorkItem(IN PUNIQUE_ID_WORK_ITEM WorkItem)
Definition: notify.c:480
VOID MountMgrNotifyNameChange(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, IN BOOLEAN ValidateVolume)
Definition: notify.c:351
VOID PostOnlineNotification(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName)
Definition: notify.c:145
VOID NTAPI UniqueIdChangeNotifyWorker(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
Definition: notify.c:509
VOID RegisterForTargetDeviceNotification(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
Definition: notify.c:273
VOID IssueUniqueIdChangeNotify(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: notify.c:660
VOID MountMgrNotify(IN PDEVICE_EXTENSION DeviceExtension)
Definition: notify.c:311
VOID IssueUniqueIdChangeNotifyWorker(IN PUNIQUE_ID_WORK_ITEM WorkItem, IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: notify.c:590
VOID WaitForOnlinesToComplete(IN PDEVICE_EXTENSION DeviceExtension)
Definition: notify.c:197
NTSTATUS NTAPI UniqueIdChangeNotifyCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: notify.c:568
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
Status
Definition: gdiplustypes.h:25
#define InterlockedCompareExchange
Definition: interlocked.h:104
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
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
IoSetCancelRoutine(Irp, CancelRoutine)
if(dx< 0)
Definition: linetemp.h:194
VOID MountMgrUniqueIdChangeRoutine(IN PDEVICE_EXTENSION DeviceExtension, IN PMOUNTDEV_UNIQUE_ID OldUniqueId, IN PMOUNTDEV_UNIQUE_ID NewUniqueId)
Definition: uniqueid.c:71
#define AllocatePool(Size)
Definition: mntmgr.h:153
#define FreePool(P)
Definition: mntmgr.h:154
struct _ONLINE_NOTIFICATION_WORK_ITEM * PONLINE_NOTIFICATION_WORK_ITEM
#define ASSERT(a)
Definition: mode.c:44
#define IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY
Definition: imports.h:86
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
struct _MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4677
#define KernelMode
Definition: asm.h:34
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define IOCTL_VOLUME_ONLINE
Definition: ntddvol.h:62
@ NotificationEvent
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
VOID NTAPI IoInitializeIrp(IN PIRP Irp, IN USHORT PacketSize, IN CCHAR StackSize)
Definition: irp.c:1854
#define IoCompleteRequest
Definition: irp.c:1240
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
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 IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
unsigned short USHORT
Definition: pedump.c:61
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
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
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define STATUS_SUCCESS
Definition: shellext.h:65
PDEVICE_EXTENSION DeviceExtension
Definition: mntmgr.h:62
BOOLEAN ManuallyRegistered
Definition: mntmgr.h:53
UNICODE_STRING DeviceName
Definition: mntmgr.h:50
BOOLEAN NeedsReconcile
Definition: mntmgr.h:56
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT UniqueIdLength
Definition: imports.h:138
UCHAR UniqueId[1]
Definition: imports.h:139
WORK_QUEUE_ITEM WorkItem
Definition: mntmgr.h:110
struct _FILE_OBJECT * FileObject
Definition: iotypes.h:1012
LIST_ENTRY List
Definition: extypes.h:203
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
char CCHAR
Definition: typedefs.h:51
_In_ PWDFDEVICE_INIT _In_ PFN_WDF_DEVICE_SHUTDOWN_NOTIFICATION Notification
Definition: wdfcontrol.h:115
_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
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:115
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
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define IoSizeOfIrp(_StackSize)
_In_ PVOID NotificationStructure
Definition: iofuncs.h:1206
@ TargetDeviceRelation
Definition: iotypes.h:2156
#define IO_NO_INCREMENT
Definition: iotypes.h:598
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
#define IRP_MN_QUERY_DEVICE_RELATIONS
@ EventCategoryTargetDeviceChange
Definition: iotypes.h:1227
* PFILE_OBJECT
Definition: iotypes.h:1998
struct _TARGET_DEVICE_CUSTOM_NOTIFICATION TARGET_DEVICE_CUSTOM_NOTIFICATION
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
@ Executive
Definition: ketypes.h:415
#define ObDereferenceObject
Definition: obfuncs.h:203
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323
__wchar_t WCHAR
Definition: xmlstorage.h:180