ReactOS  0.4.11-dev-465-g0e6bc23
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  */
37 VOID
39 {
40  PIRP Irp;
41  KEVENT Event;
44  PIO_STACK_LOCATION Stack;
47 
48  /* Get device object */
49  Status = IoGetDeviceObjectPointer(SymbolicName,
51  &FileObject,
52  &DeviceObject);
53  if (!NT_SUCCESS(Status))
54  {
55  return;
56  }
57 
58  /* And attached device object */
59  DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);
60 
61  /* And send VOLUME_ONLINE */
64  DeviceObject,
65  NULL, 0,
66  NULL, 0,
67  FALSE,
68  &Event,
69  &IoStatusBlock);
70  if (!Irp)
71  {
72  goto Cleanup;
73  }
74 
75  Stack = IoGetNextIrpStackLocation(Irp);
76  Stack->FileObject = FileObject;
77 
78  Status = IoCallDriver(DeviceObject, Irp);
79  if (Status == STATUS_PENDING)
80  {
82  }
83 
84 Cleanup:
85  ObDereferenceObject(DeviceObject);
86  ObDereferenceObject(FileObject);
87 
88  return;
89 }
90 
91 /*
92  * @implemented
93  */
94 VOID
95 NTAPI
97 {
98  KIRQL OldIrql;
99  PLIST_ENTRY Head;
100  PDEVICE_EXTENSION DeviceExtension;
102  PONLINE_NOTIFICATION_WORK_ITEM NewWorkItem;
103 
104  WorkItem = (PONLINE_NOTIFICATION_WORK_ITEM)Parameter;
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));
122  NewWorkItem = CONTAINING_RECORD(Head, ONLINE_NOTIFICATION_WORK_ITEM, WorkItem.List);
123  KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
124  NewWorkItem->WorkItem.List.Blink = NULL;
125  NewWorkItem->WorkItem.List.Flink = NULL;
126  ExQueueWorkItem(&NewWorkItem->WorkItem, DelayedWorkQueue);
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);
136  FreePool(WorkItem);
137 
138  return;
139 }
140 
141 /*
142  * @implemented
143  */
144 VOID
147 {
148  KIRQL OldIrql;
150 
151  /* Allocate a notification work item */
152  WorkItem = AllocatePool(sizeof(ONLINE_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);
163  if (!WorkItem->SymbolicName.Buffer)
164  {
165  FreePool(WorkItem);
166  return;
167  }
168 
169  RtlCopyMemory(WorkItem->SymbolicName.Buffer, SymbolicName->Buffer, SymbolicName->Length);
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  */
196 VOID
198 {
199  KIRQL OldIrql;
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,
213  KernelMode,
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  */
227 NTSTATUS
228 NTAPI
230  IN PVOID Context)
231 {
232  PDEVICE_EXTENSION DeviceExtension;
233  PDEVICE_INFORMATION DeviceInformation;
235 
236  DeviceInformation = Context;
237  DeviceExtension = DeviceInformation->DeviceExtension;
238  Notification = NotificationStructure;
239 
240  /* If it's to signal that removal is complete, then, execute the function */
241  if (IsEqualGUID(&(Notification->Event), &GUID_TARGET_DEVICE_REMOVE_COMPLETE))
242  {
243  MountMgrMountedDeviceRemoval(DeviceExtension, Notification->SymbolicLinkName);
244  }
245  /* It it's to signal that a volume has been mounted
246  * Verify if a database sync is required and execute it
247  */
248  else if (IsEqualGUID(&(Notification->Event), &GUID_IO_VOLUME_MOUNT))
249  {
250  if (InterlockedCompareExchange(&(DeviceInformation->MountState),
251  FALSE,
252  TRUE) == TRUE)
253  {
254  InterlockedDecrement(&(DeviceInformation->MountState));
255  }
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  */
272 VOID
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 
302  ObDereferenceObject(FileObject);
303 
304  return;
305 }
306 
307 /*
308  * @implemented
309  */
310 VOID
312 {
313  PIRP Irp;
314  KIRQL OldIrql;
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 */
324  IoAcquireCancelSpinLock(&OldIrql);
325  while (!IsListEmpty(&(DeviceExtension->IrpListHead)))
326  {
327  NextEntry = RemoveHeadList(&(DeviceExtension->IrpListHead));
328  Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
329  InsertTailList(&CopyList, &(Irp->Tail.Overlay.ListEntry));
330  }
331  IoReleaseCancelSpinLock(OldIrql);
332 
333  /* Then, notify them one by one */
334  while (!IsListEmpty(&CopyList))
335  {
336  NextEntry = RemoveHeadList(&CopyList);
337  Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
338 
339  *((PULONG)Irp->AssociatedIrp.SystemBuffer) = DeviceExtension->EpicNumber;
340  Irp->IoStatus.Information = sizeof(DeviceExtension->EpicNumber);
341 
343  }
344 }
345 
346 /*
347  * @implemented
348  */
349 VOID
352  IN BOOLEAN ValidateVolume)
353 {
354  PIRP Irp;
355  KEVENT Event;
357  PLIST_ENTRY NextEntry;
359  PIO_STACK_LOCATION Stack;
362  PDEVICE_RELATIONS DeviceRelations;
363  PDEVICE_INFORMATION DeviceInformation;
364  TARGET_DEVICE_CUSTOM_NOTIFICATION DeviceNotification;
365 
366  /* If we have to validate volume */
367  if (ValidateVolume)
368  {
369  /* Then, ensure we can find the device */
370  NextEntry = DeviceExtension->DeviceListHead.Flink;
371  while (NextEntry != &(DeviceExtension->DeviceListHead))
372  {
373  DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
374  if (RtlCompareUnicodeString(DeviceName, &(DeviceInformation->DeviceName), TRUE) == 0)
375  {
376  break;
377  }
378  }
379 
380  /* No need to notify for a PnP device or if we didn't find the device */
381  if (NextEntry == &(DeviceExtension->DeviceListHead) ||
382  !DeviceInformation->ManuallyRegistered)
383  {
384  return;
385  }
386  }
387 
388  /* Then, get device object */
389  Status = IoGetDeviceObjectPointer(DeviceName,
391  &FileObject,
392  &DeviceObject);
393  if (!NT_SUCCESS(Status))
394  {
395  return;
396  }
397 
398  DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);
399 
401 
402  /* Set up empty IRP (yes, yes!) */
404  DeviceObject,
405  NULL,
406  0,
407  NULL,
408  0,
409  FALSE,
410  &Event,
411  &IoStatusBlock);
412  if (!Irp)
413  {
414  ObDereferenceObject(DeviceObject);
415  ObDereferenceObject(FileObject);
416  return;
417  }
418 
419  Stack = IoGetNextIrpStackLocation(Irp);
420 
421  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
422  Irp->IoStatus.Information = 0;
423 
424  /* Properly set it, we want to query device relations */
425  Stack->MajorFunction = IRP_MJ_PNP;
427  Stack->Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
428  Stack->FileObject = FileObject;
429 
430  /* And call driver */
431  Status = IoCallDriver(DeviceObject, Irp);
432  if (Status == STATUS_PENDING)
433  {
435  Status = IoStatusBlock.Status;
436  }
437 
438  ObDereferenceObject(DeviceObject);
439  ObDereferenceObject(FileObject);
440 
441  if (!NT_SUCCESS(Status))
442  {
443  return;
444  }
445 
446  /* Validate device return */
447  DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
448  if (DeviceRelations->Count < 1)
449  {
450  ExFreePool(DeviceRelations);
451  return;
452  }
453 
454  DeviceObject = DeviceRelations->Objects[0];
455  ExFreePool(DeviceRelations);
456 
457  /* Set up real notification */
458  DeviceNotification.Version = 1;
459  DeviceNotification.Size = sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION);
460  DeviceNotification.Event = GUID_IO_VOLUME_NAME_CHANGE;
461  DeviceNotification.FileObject = NULL;
462  DeviceNotification.NameBufferOffset = -1;
463 
464  /* And report */
466  &DeviceNotification,
467  NULL, NULL);
468 
469  ObDereferenceObject(DeviceObject);
470 
471  return;
472 }
473 
474 /*
475  * @implemented
476  */
477 VOID
479 {
480  PDEVICE_EXTENSION DeviceExtension = WorkItem->DeviceExtension;
481 
482  KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
483 
484  /* If even if being worked, it's too late */
485  if (WorkItem->Event)
486  {
487  KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
488  KeSetEvent(WorkItem->Event, 0, FALSE);
489  }
490  else
491  {
492  /* Otherwise, remove it from the list, and delete it */
493  RemoveEntryList(&(WorkItem->UniqueIdWorkerItemListEntry));
494  KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
495  IoFreeIrp(WorkItem->Irp);
496  FreePool(WorkItem->DeviceName.Buffer);
497  FreePool(WorkItem->IrpBuffer);
498  FreePool(WorkItem);
499  }
500 }
501 
502 /*
503  * @implemented
504  */
505 VOID
506 NTAPI
508  IN PVOID Context)
509 {
510  PUNIQUE_ID_WORK_ITEM WorkItem = Context;
511  PMOUNTDEV_UNIQUE_ID OldUniqueId, NewUniqueId;
513 
514  UNREFERENCED_PARAMETER(DeviceObject);
515 
516  /* Validate worker */
517  if (!NT_SUCCESS(WorkItem->Irp->IoStatus.Status))
518  {
519  RemoveWorkItem(WorkItem);
520  return;
521  }
522 
523  UniqueIdChange = WorkItem->Irp->AssociatedIrp.SystemBuffer;
524  /* Get the old unique ID */
525  OldUniqueId = AllocatePool(UniqueIdChange->OldUniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
526  if (!OldUniqueId)
527  {
528  RemoveWorkItem(WorkItem);
529  return;
530  }
531 
532  OldUniqueId->UniqueIdLength = UniqueIdChange->OldUniqueIdLength;
533  RtlCopyMemory(OldUniqueId->UniqueId,
534  (PVOID)((ULONG_PTR)UniqueIdChange + UniqueIdChange->OldUniqueIdOffset),
535  UniqueIdChange->OldUniqueIdLength);
536 
537  /* Get the new unique ID */
538  NewUniqueId = AllocatePool(UniqueIdChange->NewUniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
539  if (!NewUniqueId)
540  {
541  FreePool(OldUniqueId);
542  RemoveWorkItem(WorkItem);
543  return;
544  }
545 
546  NewUniqueId->UniqueIdLength = UniqueIdChange->NewUniqueIdLength;
547  RtlCopyMemory(NewUniqueId->UniqueId,
548  (PVOID)((ULONG_PTR)UniqueIdChange + UniqueIdChange->NewUniqueIdOffset),
549  UniqueIdChange->NewUniqueIdLength);
550 
551  /* Call the real worker */
552  MountMgrUniqueIdChangeRoutine(WorkItem->DeviceExtension, OldUniqueId, NewUniqueId);
553  IssueUniqueIdChangeNotifyWorker(WorkItem, NewUniqueId);
554 
555  FreePool(NewUniqueId);
556  FreePool(OldUniqueId);
557 
558  return;
559 }
560 
561 /*
562  * @implemented
563  */
564 NTSTATUS
565 NTAPI
567  IN PIRP Irp,
568  IN PVOID Context)
569 {
570  PUNIQUE_ID_WORK_ITEM WorkItem = Context;
571 
572  UNREFERENCED_PARAMETER(DeviceObject);
574 
575  /* Simply queue the work item */
576  IoQueueWorkItem(WorkItem->WorkItem,
579  WorkItem);
580 
582 }
583 
584 /*
585  * @implemented
586  */
587 VOID
590 {
591  PIRP Irp;
594  PIO_STACK_LOCATION Stack;
596 
597  /* Get the device object */
598  Status = IoGetDeviceObjectPointer(&(WorkItem->DeviceName),
600  &FileObject,
601  &DeviceObject);
602  if (!NT_SUCCESS(Status))
603  {
604  RemoveWorkItem(WorkItem);
605  return;
606  }
607 
608  /* And then, the attached device */
609  DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);
610 
611  /* Initialize the IRP */
612  Irp = WorkItem->Irp;
613  IoInitializeIrp(Irp, IoSizeOfIrp(WorkItem->StackSize), (CCHAR)WorkItem->StackSize);
614 
615  if (InterlockedExchange((PLONG)&(WorkItem->Event), 0) != 0)
616  {
617  ObDereferenceObject(FileObject);
618  ObDereferenceObject(DeviceObject);
619  RemoveWorkItem(WorkItem);
620  return;
621  }
622 
623  Irp->AssociatedIrp.SystemBuffer = WorkItem->IrpBuffer;
624  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
625  RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, UniqueId, UniqueId->UniqueIdLength + sizeof(USHORT));
626 
627  Stack = IoGetNextIrpStackLocation(Irp);
628 
629  Stack->Parameters.DeviceIoControl.InputBufferLength = UniqueId->UniqueIdLength + sizeof(USHORT);
630  Stack->Parameters.DeviceIoControl.OutputBufferLength = WorkItem->IrpBufferLength;
631  Stack->Parameters.DeviceIoControl.Type3InputBuffer = 0;
632  Stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY;
634 
635  Status = IoSetCompletionRoutineEx(WorkItem->DeviceExtension->DeviceObject,
636  Irp,
638  WorkItem,
639  TRUE, TRUE, TRUE);
640  if (!NT_SUCCESS(Status))
641  {
642  ObDereferenceObject(FileObject);
643  ObDereferenceObject(DeviceObject);
644  RemoveWorkItem(WorkItem);
645  return;
646  }
647 
648  /* Call the driver */
649  IoCallDriver(DeviceObject, Irp);
650  ObDereferenceObject(FileObject);
651  ObDereferenceObject(DeviceObject);
652 }
653 
654 /*
655  * @implemented
656  */
657 VOID
661 {
663  PVOID IrpBuffer = NULL;
666  PUNIQUE_ID_WORK_ITEM WorkItem = NULL;
667 
668  /* Get the associated device object */
669  Status = IoGetDeviceObjectPointer(DeviceName,
671  &FileObject,
672  &DeviceObject);
673  if (!NT_SUCCESS(Status))
674  {
675  return;
676  }
677 
678  /* And then, get attached device */
679  DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);
680 
681  ObDereferenceObject(FileObject);
682 
683  /* Allocate a work item */
684  WorkItem = AllocatePool(sizeof(UNIQUE_ID_WORK_ITEM));
685  if (!WorkItem)
686  {
687  ObDereferenceObject(DeviceObject);
688  return;
689  }
690 
691  WorkItem->Event = NULL;
692  WorkItem->WorkItem = IoAllocateWorkItem(DeviceExtension->DeviceObject);
693  if (!WorkItem->WorkItem)
694  {
695  ObDereferenceObject(DeviceObject);
696  goto Cleanup;
697  }
698 
699  WorkItem->DeviceExtension = DeviceExtension;
700  WorkItem->StackSize = DeviceObject->StackSize;
701  /* Already provide the IRP */
702  WorkItem->Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
703 
704  ObDereferenceObject(DeviceObject);
705 
706  if (!WorkItem->Irp)
707  {
708  goto Cleanup;
709  }
710 
711  /* Ensure it has enough space */
712  IrpBuffer = AllocatePool(sizeof(MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT) + 1024);
713  if (!IrpBuffer)
714  {
715  goto Cleanup;
716  }
717 
718  WorkItem->DeviceName.Length = DeviceName->Length;
719  WorkItem->DeviceName.MaximumLength = DeviceName->Length + sizeof(WCHAR);
720  WorkItem->DeviceName.Buffer = AllocatePool(WorkItem->DeviceName.MaximumLength);
721  if (!WorkItem->DeviceName.Buffer)
722  {
723  goto Cleanup;
724  }
725 
726  RtlCopyMemory(WorkItem->DeviceName.Buffer, DeviceName->Buffer, DeviceName->Length);
727  WorkItem->DeviceName.Buffer[DeviceName->Length / sizeof(WCHAR)] = UNICODE_NULL;
728 
729  WorkItem->IrpBuffer = IrpBuffer;
730  WorkItem->IrpBufferLength = sizeof(MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT) + 1024;
731 
732  /* Add the worker in the list */
733  KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
734  InsertHeadList(&(DeviceExtension->UniqueIdWorkerItemListHead), &(WorkItem->UniqueIdWorkerItemListEntry));
735  KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
736 
737  /* And call the worker */
738  IssueUniqueIdChangeNotifyWorker(WorkItem, UniqueId);
739 
740  return;
741 
742 Cleanup:
743  if (IrpBuffer)
744  {
745  FreePool(IrpBuffer);
746  }
747 
748  if (WorkItem->Irp)
749  {
750  IoFreeIrp(WorkItem->Irp);
751  }
752 
753  if (WorkItem->WorkItem)
754  {
755  IoFreeWorkItem(WorkItem->WorkItem);
756  }
757 
758  if (WorkItem)
759  {
760  FreePool(WorkItem);
761  }
762 }
DWORD *typedef PVOID
Definition: winlogon.h:61
_In_ PVOID NotificationStructure
Definition: iofuncs.h:1203
#define IN
Definition: typedefs.h:38
UNICODE_STRING DeviceName
Definition: mntmgr.h:152
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
LIST_ENTRY List
Definition: extypes.h:203
#define IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY
Definition: imports.h:86
struct _TARGET_DEVICE_CUSTOM_NOTIFICATION TARGET_DEVICE_CUSTOM_NOTIFICATION
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
VOID SendOnlineNotification(IN PUNICODE_STRING SymbolicName)
Definition: notify.c:38
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:51
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
VOID WaitForOnlinesToComplete(IN PDEVICE_EXTENSION DeviceExtension)
Definition: notify.c:197
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2054
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4658
USHORT UniqueIdLength
Definition: imports.h:138
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
NTSTATUS NTAPI MountMgrTargetDeviceNotification(IN PVOID NotificationStructure, IN PVOID Context)
Definition: notify.c:229
#define InterlockedCompareExchange
Definition: interlocked.h:104
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1243
VOID NTAPI UniqueIdChangeNotifyWorker(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
Definition: notify.c:507
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
IRP
Definition: iotypes.h:2462
WCHAR DeviceName[]
Definition: adapter.cpp:21
_In_ PVOID Parameter
Definition: ldrtypes.h:239
#define InsertTailList(ListHead, Entry)
VOID MountMgrMountedDeviceRemoval(IN PDEVICE_EXTENSION Extension, IN PUNICODE_STRING DeviceName)
Definition: mountmgr.c:1460
#define WCHAR
Definition: msvc.h:43
PDEVICE_EXTENSION DeviceExtension
Definition: mntmgr.h:148
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define FreePool(P)
Definition: mntmgr.h:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
VOID NTAPI IoInitializeIrp(IN PIRP Irp, IN USHORT PacketSize, IN CCHAR StackSize)
Definition: irp.c:1854
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
ACPI_EFI_EVENT Event
Definition: acefiex.h:633
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
PIO_WORKITEM WorkItem
Definition: mntmgr.h:147
VOID ReconcileThisDatabaseWithMaster(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
Definition: database.c:1594
WORK_QUEUE_ITEM WorkItem
Definition: mntmgr.h:115
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
VOID IssueUniqueIdChangeNotifyWorker(IN PUNIQUE_ID_WORK_ITEM WorkItem, IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: notify.c:588
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
VOID NTAPI SendOnlineNotificationWorker(IN PVOID Parameter)
Definition: notify.c:96
BOOLEAN NeedsReconcile
Definition: mntmgr.h:61
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
smooth NULL
Definition: ftsmooth.c:416
#define IOCTL_VOLUME_ONLINE
Definition: ntddvol.h:62
#define IoCompleteRequest
Definition: irp.c:1240
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
PDEVICE_EXTENSION DeviceExtension
Definition: mntmgr.h:67
ULONG IrpBufferLength
Definition: mntmgr.h:153
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
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
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1214
VOID MountMgrNotify(IN PDEVICE_EXTENSION DeviceExtension)
Definition: notify.c:311
VOID RegisterForTargetDeviceNotification(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
Definition: notify.c:273
struct _MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
unsigned char BOOLEAN
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
LONG NTSTATUS
Definition: precomp.h:26
_Inout_ PRX_CONNECTION_ID UniqueId
Definition: mrx.h:224
if(!(yy_init))
Definition: macro.lex.yy.c:717
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
#define STATUS_PENDING
Definition: ntstatus.h:82
char CCHAR
Definition: typedefs.h:50
PDEVICE_EXTENSION DeviceExtension
Definition: mntmgr.h:116
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
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
* PFILE_OBJECT
Definition: iotypes.h:1954
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
LIST_ENTRY UniqueIdWorkerItemListEntry
Definition: mntmgr.h:146
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
#define InterlockedDecrement
Definition: armddk.h:52
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
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: pnpnotify.c:250
Definition: typedefs.h:117
static const WCHAR Cleanup[]
Definition: register.c:80
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
BOOLEAN ManuallyRegistered
Definition: mntmgr.h:58
#define AllocatePool(Size)
Definition: mntmgr.h:158
#define InterlockedExchange
Definition: armddk.h:54
NTSTATUS NTAPI UniqueIdChangeNotifyCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: notify.c:566
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
Status
Definition: gdiplustypes.h:24
struct _ONLINE_NOTIFICATION_WORK_ITEM * PONLINE_NOTIFICATION_WORK_ITEM
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
PFILE_OBJECT FileObject
Definition: iotypes.h:2812
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
VOID PostOnlineNotification(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName)
Definition: notify.c:145
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
unsigned short USHORT
Definition: pedump.c:61
#define IoSizeOfIrp(_StackSize)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int * PULONG
Definition: retypes.h:1
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4024
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
VOID RemoveWorkItem(IN PUNIQUE_ID_WORK_ITEM WorkItem)
Definition: notify.c:478
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define IRP_MN_QUERY_DEVICE_RELATIONS
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
UNICODE_STRING DeviceName
Definition: mntmgr.h:55
UNICODE_STRING SymbolicName
Definition: mntmgr.h:117
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
PVOID PIRP
Definition: usb.h:38
struct tagContext Context
Definition: acpixf.h:1014
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
#define IO_NO_INCREMENT
Definition: iotypes.h:565
struct _FILE_OBJECT * FileObject
Definition: iotypes.h:974
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
return STATUS_SUCCESS
Definition: btrfs.c:2710
VOID MountMgrUniqueIdChangeRoutine(IN PDEVICE_EXTENSION DeviceExtension, IN PMOUNTDEV_UNIQUE_ID OldUniqueId, IN PMOUNTDEV_UNIQUE_ID NewUniqueId)
Definition: uniqueid.c:71
NTSTATUS NTAPI IoReportTargetDeviceChangeAsynchronous(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PVOID NotificationStructure, IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL, IN PVOID Context OPTIONAL)
Definition: pnpreport.c:520
signed int * PLONG
Definition: retypes.h:5
UCHAR UniqueId[1]
Definition: imports.h:139
VOID IssueUniqueIdChangeNotify(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: notify.c:658
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
VOID MountMgrNotifyNameChange(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, IN BOOLEAN ValidateVolume)
Definition: notify.c:350