ReactOS  0.4.10-dev-234-g15c29d0
volume.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/io/iomgr/volume.c
5  * PURPOSE: Volume and File System I/O Support
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  * Hervé Poussineau (hpoussin@reactos.org)
8  * Eric Kohl
9  * Pierre Schweitzer (pierre.schweitzer@reactos.org)
10  */
11 
12 /* INCLUDES *****************************************************************/
13 
14 #include <ntoskrnl.h>
15 #define NDEBUG
16 #include <debug.h>
17 
18 #if defined (ALLOC_PRAGMA)
19 #pragma alloc_text(INIT, IoInitFileSystemImplementation)
20 #pragma alloc_text(INIT, IoInitVpbImplementation)
21 #endif
22 
23 /* GLOBALS ******************************************************************/
24 
30 
31 /* PRIVATE FUNCTIONS *********************************************************/
32 
33 /*
34  * @halfplemented
35  */
36 VOID
37 NTAPI
39  IN BOOLEAN UnloadIfUnused)
40 {
41  KIRQL OldIrql;
42 
43  /* Acquire lock */
45  ASSERT(DeviceObject->ReferenceCount > 0);
46 
47  if (--DeviceObject->ReferenceCount > 0)
48  {
50  return;
51  }
52 
53  /* Release lock */
55 
56  /* Here, DO is not referenced any longer, check if we have to unload it */
57  if (UnloadIfUnused || IoGetDevObjExtension(DeviceObject)->ExtensionFlags &
59  {
60  /* Unload the driver */
61  IopUnloadDevice(DeviceObject);
62  }
63 }
64 
65 /*
66  * @implemented
67  */
68 VOID
69 NTAPI
71 {
72  /* Just decrease reference count */
73  IopDecrementDeviceObjectRef(DeviceObject, FALSE);
74 }
75 
76 /*
77  * @implemented
78  */
79 PVPB
80 NTAPI
85 {
87  KIRQL OldIrql;
88  PVPB Vpb = NULL;
89 
90  /* Lock the VPBs */
91  IoAcquireVpbSpinLock(&OldIrql);
92 
93  /* Set VPB mount settings */
94  Raw = !RemainingName->Length && !OpenPacket->RelatedFileObject;
95  Alertable = (OpenPacket->CreateOptions & FILE_SYNCHRONOUS_IO_ALERT) ?
96  TRUE: FALSE;
97 
98  /* Start looping until the VPB is mounted */
99  while (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
100  {
101  /* Release the lock */
102  IoReleaseVpbSpinLock(OldIrql);
103 
104  /* Mount the volume */
105  *Status = IopMountVolume(DeviceObject,
106  Raw,
107  FALSE,
108  Alertable,
109  &Vpb);
110 
111  /* Check if we failed or if we were alerted */
112  if (!(NT_SUCCESS(*Status)) ||
113  (*Status == STATUS_USER_APC) ||
114  (*Status == STATUS_ALERTED))
115  {
116  /* Dereference the device, since IopParseDevice referenced it */
117  IopDereferenceDeviceObject(DeviceObject, FALSE);
118 
119  /* Check if it was a total failure */
120  if (!NT_SUCCESS(*Status)) return NULL;
121 
122  /* Otherwise we were alerted */
123  *Status = STATUS_WRONG_VOLUME;
124  return NULL;
125  }
126 
127  /* Re-acquire the lock */
128  IoAcquireVpbSpinLock(&OldIrql);
129  }
130 
131  /* Make sure the VPB isn't locked */
132  Vpb = DeviceObject->Vpb;
133  if (Vpb->Flags & VPB_LOCKED)
134  {
135  /* We're locked, so fail */
136  *Status = STATUS_ACCESS_DENIED;
137  Vpb = NULL;
138  }
139  else
140  {
141  /* Success! Reference the VPB */
142  Vpb->ReferenceCount++;
143  }
144 
145  /* Release the lock and return the VPB */
146  IoReleaseVpbSpinLock(OldIrql);
147  return Vpb;
148 }
149 
150 /*
151  * @implemented
152  */
153 NTSTATUS
154 NTAPI
156 {
157  PVPB Vpb;
158 
159  /* Allocate the Vpb */
161  sizeof(VPB),
162  TAG_VPB);
163  if (!Vpb) return STATUS_INSUFFICIENT_RESOURCES;
164 
165  /* Clear it so we don't waste time manually */
166  RtlZeroMemory(Vpb, sizeof(VPB));
167 
168  /* Set the Header and Device Field */
169  Vpb->Type = IO_TYPE_VPB;
170  Vpb->Size = sizeof(VPB);
171  Vpb->RealDevice = DeviceObject;
172 
173  /* Link it to the Device Object */
174  DeviceObject->Vpb = Vpb;
175  return STATUS_SUCCESS;
176 }
177 
178 /*
179  * @implemented
180  */
181 VOID
182 NTAPI
184 {
185  KIRQL OldIrql;
186 
187  /* Lock the VPBs and decrease references */
188  IoAcquireVpbSpinLock(&OldIrql);
189  Vpb->ReferenceCount--;
190 
191  /* Check if we're out of references */
192  if (!Vpb->ReferenceCount && Vpb->RealDevice->Vpb == Vpb &&
193  !(Vpb->Flags & VPB_PERSISTENT))
194  {
195  /* Release VPB lock */
196  IoReleaseVpbSpinLock(OldIrql);
197 
198  /* And free VPB */
200  }
201  else
202  {
203  /* Release VPB lock */
204  IoReleaseVpbSpinLock(OldIrql);
205  }
206 }
207 
208 /*
209  * @implemented
210  */
211 BOOLEAN
212 NTAPI
214  OUT PDEVICE_OBJECT *FileSystemObject,
215  OUT PVPB *Vpb)
216 {
217  KIRQL OldIrql;
218  PVPB LocalVpb;
219  BOOLEAN Result = FALSE;
220 
221  /* Lock the VPBs and assume failure */
222  IoAcquireVpbSpinLock(&OldIrql);
223  *Vpb = NULL;
224  *FileSystemObject = NULL;
225 
226  /* Get the VPB and make sure it's mounted */
227  LocalVpb = DeviceObject->Vpb;
228  if ((LocalVpb) && (LocalVpb->Flags & VPB_MOUNTED))
229  {
230  /* Return it */
231  *Vpb = LocalVpb;
232  *FileSystemObject = LocalVpb->DeviceObject;
233 
234  /* Reference it */
235  LocalVpb->ReferenceCount++;
236  Result = TRUE;
237  }
238 
239  /* Release the VPB lock and return status */
240  IoReleaseVpbSpinLock(OldIrql);
241  return Result;
242 }
243 
244 PVPB
245 NTAPI
247  IN PDEVICE_OBJECT AttachedDeviceObject,
248  IN BOOLEAN Raw)
249 {
250  KIRQL OldIrql;
251  PVPB Vpb;
252 
253  /* Lock the VPBs */
254  IoAcquireVpbSpinLock(&OldIrql);
255  Vpb = DeviceObject->Vpb;
256 
257  /* Set the VPB as mounted and possibly raw */
258  Vpb->Flags |= VPB_MOUNTED | (Raw ? VPB_RAW_MOUNT : 0);
259 
260  /* Set the stack size */
261  Vpb->DeviceObject->StackSize = AttachedDeviceObject->StackSize;
262 
263  /* Add one for the FS Driver */
264  Vpb->DeviceObject->StackSize++;
265 
266  /* Set the VPB in the device extension */
268 
269  /* Reference it */
270  Vpb->ReferenceCount++;
271 
272  /* Release the VPB lock and return it */
273  IoReleaseVpbSpinLock(OldIrql);
274  return Vpb;
275 }
276 
277 /*
278  * @implemented
279  */
281 VOID
283  IN BOOLEAN DriverActive)
284 {
285  PFS_CHANGE_NOTIFY_ENTRY ChangeEntry;
286  PLIST_ENTRY ListEntry;
287 
288  /* Loop the list */
289  ListEntry = IopFsNotifyChangeQueueHead.Flink;
290  while (ListEntry != &IopFsNotifyChangeQueueHead)
291  {
292  /* Get the entry */
293  ChangeEntry = CONTAINING_RECORD(ListEntry,
295  FsChangeNotifyList);
296 
297  /* Call the notification procedure */
298  ChangeEntry->FSDNotificationProc(DeviceObject, DriverActive);
299 
300  /* Go to the next entry */
301  ListEntry = ListEntry->Flink;
302  }
303 }
304 
305 /*
306  * @implemented
307  */
308 ULONG
309 FASTCALL
311  IN PULONG Ulong)
312 {
313  KIRQL Irql;
314  ULONG OldValue;
315 
316  Irql = KeAcquireQueuedSpinLock(Queue);
317  OldValue = (*Ulong)++;
318  KeReleaseQueuedSpinLock(Queue, Irql);
319 
320  return OldValue;
321 }
322 
323 /*
324  * @implemented
325  */
326 ULONG
327 FASTCALL
329  IN PULONG Ulong)
330 {
331  KIRQL Irql;
332  ULONG OldValue;
333 
334  Irql = KeAcquireQueuedSpinLock(Queue);
335  OldValue = (*Ulong)--;
336  KeReleaseQueuedSpinLock(Queue, Irql);
337 
338  return OldValue;
339 }
340 
341 /*
342  * @implemented
343  */
344 VOID
345 NTAPI
347 {
348  PLIST_ENTRY ListEntry;
350  IO_STATUS_BLOCK StatusBlock;
351  PIRP Irp;
352  KEVENT Event;
354 
356 
357  /* Get the first entry and start looping */
358  ListEntry = ListHead->Flink;
359  while (ListEntry != ListHead)
360  {
361  /* Get the device object */
362  DeviceObject = CONTAINING_RECORD(ListEntry,
364  Queue.ListEntry);
365 
366  /* Get the attached device */
367  DeviceObject = IoGetAttachedDevice(DeviceObject);
368 
369  ObReferenceObject(DeviceObject);
370  IopInterlockedIncrementUlong(LockQueueIoDatabaseLock, (PULONG)&DeviceObject->ReferenceCount);
371 
372  /* Build the shutdown IRP and call the driver */
374  DeviceObject,
375  NULL,
376  0,
377  NULL,
378  &Event,
379  &StatusBlock);
380  if (Irp)
381  {
382  Status = IoCallDriver(DeviceObject, Irp);
383  if (Status == STATUS_PENDING)
384  {
385  /* Wait on the driver */
387  }
388  }
389 
390  /* Reset the event */
391  KeClearEvent(&Event);
392 
393  IopDecrementDeviceObjectRef(DeviceObject, FALSE);
394  ObDereferenceObject(DeviceObject);
395 
396  /* Go to the next entry */
397  ListEntry = ListEntry->Flink;
398  }
399 }
400 
401 /*
402  * @implemented
403  */
404 VOID
405 NTAPI
407 {
409  PIO_STACK_LOCATION StackPtr;
410  KEVENT Event;
411  PIRP Irp;
413  PDEVICE_OBJECT AttachedDeviceObject = DeviceObject;
414  PAGED_CODE();
415 
416  /* Loop as long as we're attached */
417  while (AttachedDeviceObject->AttachedDevice)
418  {
419  /* Get the attached device object */
420  AttachedDeviceObject = AttachedDeviceObject->AttachedDevice;
421  }
422 
423  /* Initialize the event and build the IRP */
426  AttachedDeviceObject,
427  NULL,
428  0,
429  NULL,
430  0,
431  FALSE,
432  &Event,
433  &IoStatusBlock);
434  if (Irp)
435  {
436  /* Set the major and minor functions */
437  StackPtr = IoGetNextIrpStackLocation(Irp);
440 
441  /* Call the driver */
442  Status = IoCallDriver(AttachedDeviceObject, Irp);
443  if (Status == STATUS_PENDING)
444  {
445  /* Wait on it */
447  }
448  }
449 
450  /* Dereference DO - FsRec? - Comment out call, since it breaks up 2nd stage boot, needs more research. */
451 // IopDecrementDeviceObjectRef(AttachedDeviceObject, TRUE);
452 }
453 
454 /*
455  * @implemented
456  */
457 NTSTATUS
458 NTAPI
460  IN BOOLEAN AllowRawMount,
461  IN BOOLEAN DeviceIsLocked,
463  OUT PVPB *Vpb)
464 {
465  KEVENT Event;
468  PIRP Irp;
469  PIO_STACK_LOCATION StackPtr;
470  PLIST_ENTRY FsList, ListEntry;
471  LIST_ENTRY LocalList;
472  PDEVICE_OBJECT AttachedDeviceObject = DeviceObject;
473  PDEVICE_OBJECT FileSystemDeviceObject, ParentFsDeviceObject;
474  ULONG FsStackOverhead, RegistrationOps;
475  PAGED_CODE();
476 
477  /* Check if the device isn't already locked */
478  if (!DeviceIsLocked)
479  {
480  /* Lock it ourselves */
481  Status = KeWaitForSingleObject(&DeviceObject->DeviceLock,
482  Executive,
484  Alertable,
485  NULL);
486  if ((Status == STATUS_ALERTED) || (Status == STATUS_USER_APC))
487  {
488  /* Don't mount if we were interrupted */
489  return Status;
490  }
491  }
492 
493  /* Acquire the FS Lock*/
496 
497  /* Make sure we weren't already mounted */
498  if (!(DeviceObject->Vpb->Flags & (VPB_MOUNTED | VPB_REMOVE_PENDING)))
499  {
500  /* Initialize the event to wait on */
502 
503  /* Remove the verify flag and get the actual device to mount */
504  DeviceObject->Flags &= ~DO_VERIFY_VOLUME;
505  while (AttachedDeviceObject->AttachedDevice)
506  {
507  /* Get the next one */
508  AttachedDeviceObject = AttachedDeviceObject->AttachedDevice;
509  }
510 
511  /* Reference it */
512  ObReferenceObject(AttachedDeviceObject);
513 
514  /* For a mount operation, this can only be a Disk, CD-ROM or tape */
515  if ((DeviceObject->DeviceType == FILE_DEVICE_DISK) ||
516  (DeviceObject->DeviceType == FILE_DEVICE_VIRTUAL_DISK))
517  {
518  /* Use the disk list */
519  FsList = &IopDiskFileSystemQueueHead;
520  }
521  else if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM)
522  {
523  /* Use the CD-ROM list */
524  FsList = &IopCdRomFileSystemQueueHead;
525  }
526  else
527  {
528  /* It's gotta be a tape... */
529  FsList = &IopTapeFileSystemQueueHead;
530  }
531 
532  /* Now loop the fs list until one of the file systems accepts us */
533  Status = STATUS_UNSUCCESSFUL;
534  ListEntry = FsList->Flink;
535  while ((ListEntry != FsList) && !(NT_SUCCESS(Status)))
536  {
537  /*
538  * If we're not allowed to mount this volume and this is our last
539  * (but not only) chance to mount it...
540  */
541  if (!(AllowRawMount) &&
542  (ListEntry->Flink == FsList) &&
543  (ListEntry != FsList->Flink))
544  {
545  /* Then fail this mount request */
546  break;
547  }
548 
549  /*
550  * Also check if this is a raw mount and there are other file
551  * systems on the list.
552  */
553  if ((DeviceObject->Vpb->Flags & VPB_RAW_MOUNT) &&
554  (ListEntry->Flink != FsList))
555  {
556  /* Then skip this entry */
557  ListEntry = ListEntry->Flink;
558  continue;
559  }
560 
561  /* Get the Device Object for this FS */
562  FileSystemDeviceObject = CONTAINING_RECORD(ListEntry,
564  Queue.ListEntry);
565  ParentFsDeviceObject = FileSystemDeviceObject;
566 
567  /*
568  * If this file system device is attached to some other device,
569  * then we must make sure to increase the stack size for the IRP.
570  * The default is +1, for the FS device itself.
571  */
572  FsStackOverhead = 1;
573  while (FileSystemDeviceObject->AttachedDevice)
574  {
575  /* Get the next attached device and increase overhead */
576  FileSystemDeviceObject = FileSystemDeviceObject->
577  AttachedDevice;
578  FsStackOverhead++;
579  }
580 
581  /* Clear the event */
582  KeClearEvent(&Event);
583 
584  /* Allocate the IRP */
585  Irp = IoAllocateIrp(AttachedDeviceObject->StackSize +
586  (UCHAR)FsStackOverhead,
587  TRUE);
588  if (!Irp)
589  {
590  /* Fail */
592  break;
593  }
594 
595  /* Setup the IRP */
596  Irp->UserIosb = &IoStatusBlock;
597  Irp->UserEvent = &Event;
598  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
600  Irp->RequestorMode = KernelMode;
601 
602  /* Get the I/O Stack location and set it up */
603  StackPtr = IoGetNextIrpStackLocation(Irp);
606  StackPtr->Flags = AllowRawMount;
607  StackPtr->Parameters.MountVolume.Vpb = DeviceObject->Vpb;
608  StackPtr->Parameters.MountVolume.DeviceObject =
609  AttachedDeviceObject;
610 
611  /* Save registration operations */
612  RegistrationOps = IopFsRegistrationOps;
613 
614  /* Release locks */
615  IopInterlockedIncrementUlong(LockQueueIoDatabaseLock, (PULONG)&DeviceObject->ReferenceCount);
617 
618  /* Call the driver */
619  Status = IoCallDriver(FileSystemDeviceObject, Irp);
620  if (Status == STATUS_PENDING)
621  {
622  /* Wait on it */
623  KeWaitForSingleObject(&Event,
624  Executive,
625  KernelMode,
626  FALSE,
627  NULL);
628  Status = IoStatusBlock.Status;
629  }
630 
632  IopInterlockedDecrementUlong(LockQueueIoDatabaseLock, (PULONG)&DeviceObject->ReferenceCount);
633 
634  /* Check if mounting was successful */
635  if (NT_SUCCESS(Status))
636  {
637  /* Mount the VPB */
638  *Vpb = IopMountInitializeVpb(DeviceObject,
639  AttachedDeviceObject,
640  (DeviceObject->Vpb->Flags &
641  VPB_RAW_MOUNT));
642  }
643  else
644  {
645  /* Check if we failed because of the user */
646  if ((IoIsErrorUserInduced(Status)) &&
647  (IoStatusBlock.Information == 1))
648  {
649  /* Break out and fail */
650  break;
651  }
652 
653  /* If there were registration operations in the meanwhile */
654  if (RegistrationOps != IopFsRegistrationOps)
655  {
656  /* We need to setup a local list to pickup where we left */
657  LocalList.Flink = FsList->Flink;
658  ListEntry = &LocalList;
659 
661  }
662 
663  /* Otherwise, check if we need to load the FS driver */
664  if (Status == STATUS_FS_DRIVER_REQUIRED)
665  {
666  /* We need to release the lock */
667  IopInterlockedIncrementUlong(LockQueueIoDatabaseLock, (PULONG)&DeviceObject->ReferenceCount);
669 
670  /* Release the device lock if we're holding it */
671  if (!DeviceIsLocked)
672  {
673  KeSetEvent(&DeviceObject->DeviceLock, 0, FALSE);
674  }
675 
676  /* Leave critical section */
678 
679  /* Load the FS */
680  IopLoadFileSystemDriver(ParentFsDeviceObject);
681 
682  /* Check if the device isn't already locked */
683  if (!DeviceIsLocked)
684  {
685  /* Lock it ourselves */
686  Status = KeWaitForSingleObject(&DeviceObject->
687  DeviceLock,
688  Executive,
690  Alertable,
691  NULL);
692  if ((Status == STATUS_ALERTED) ||
693  (Status == STATUS_USER_APC))
694  {
695  /* Don't mount if we were interrupted */
696  ObDereferenceObject(AttachedDeviceObject);
697  return Status;
698  }
699  }
700 
701  /* Reacquire the lock */
704 
705  /* When we released the lock, make sure nobody beat us */
706  if (DeviceObject->Vpb->Flags & VPB_MOUNTED)
707  {
708  /* Someone did, break out */
709  Status = STATUS_SUCCESS;
710  break;
711  }
712 
713  /* Start over by setting a failure */
715 
716  /* We need to setup a local list to pickup where we left */
717  LocalList.Flink = FsList->Flink;
718  ListEntry = &LocalList;
719  }
720 
721  /*
722  * Check if we failed with any other error then an unrecognized
723  * volume, and if this request doesn't allow mounting the raw
724  * file system.
725  */
726  if (!(AllowRawMount) &&
727  (Status != STATUS_UNRECOGNIZED_VOLUME) &&
728  (FsRtlIsTotalDeviceFailure(Status)))
729  {
730  /* Break out and give up */
731  break;
732  }
733  }
734 
735  /* Go to the next FS entry */
736  ListEntry = ListEntry->Flink;
737  }
738 
739  /* Dereference the device if we failed */
740  if (!NT_SUCCESS(Status)) ObDereferenceObject(AttachedDeviceObject);
741  }
742  else if (DeviceObject->Vpb->Flags & VPB_REMOVE_PENDING)
743  {
744  /* Someone wants to remove us */
746  }
747  else
748  {
749  /* Someone already mounted us */
750  Status = STATUS_SUCCESS;
751  }
752 
753  /* Release the FS lock */
756 
757  /* Release the device lock if we're holding it */
758  if (!DeviceIsLocked) KeSetEvent(&DeviceObject->DeviceLock, 0, FALSE);
759 
760  /* Check if we failed to mount the boot partition */
761  if ((!NT_SUCCESS(Status)) &&
762  (DeviceObject->Flags & DO_SYSTEM_BOOT_PARTITION) &&
764  {
765  /* Bugcheck the system */
766  KeBugCheckEx(INACCESSIBLE_BOOT_DEVICE,
767  (ULONG_PTR)DeviceObject,
768  Status,
769  0,
770  0);
771  }
772 
773  /* Return the mount status */
774  return Status;
775 }
776 
777 /*
778  * @implemented
779  */
780 VOID
781 NTAPI
784  BOOLEAN SkipRawFs)
785 {
786  PLIST_ENTRY ListEntry;
788 
789  /* Browse the whole list */
790  ListEntry = ListHead->Flink;
791  while (ListEntry != ListHead)
792  {
793  /* Check if we reached rawfs and if we have to skip it */
794  if (ListEntry->Flink == ListHead && SkipRawFs)
795  {
796  return;
797  }
798 
799  /* Otherwise, get DO and notify */
800  DeviceObject = CONTAINING_RECORD(ListEntry,
802  Queue.ListEntry);
803 
804  DriverNotificationRoutine(DeviceObject, TRUE);
805 
806  /* Go to the next entry */
807  ListEntry = ListEntry->Flink;
808  }
809 }
810 
811 /* PUBLIC FUNCTIONS **********************************************************/
812 
813 /*
814  * @implemented
815  */
816 NTSTATUS
817 NTAPI
821 {
822  PLIST_ENTRY ListEntry;
824  PFS_CHANGE_NOTIFY_ENTRY ChangeEntry;
825  ULONG ListSize = 0, MaximumSize = DriverObjectListSize / sizeof(PDRIVER_OBJECT);
826 
827  /* Acquire the FS lock */
830 
831  /* Browse the whole list */
832  ListEntry = IopFsNotifyChangeQueueHead.Flink;
833  while (ListEntry != &IopFsNotifyChangeQueueHead)
834  {
835  ChangeEntry = CONTAINING_RECORD(ListEntry,
837  FsChangeNotifyList);
838 
839  /* If buffer is still big enough */
840  if (ListSize < MaximumSize)
841  {
842  /* Reference the driver object */
843  ObReferenceObject(ChangeEntry->DriverObject);
844  /* And pass it to the caller */
845  DriverObjectList[ListSize] = ChangeEntry->DriverObject;
846  }
847  else
848  {
849  Status = STATUS_BUFFER_TOO_SMALL;
850  }
851 
852  /* Increase size counter */
853  ListSize++;
854 
855  /* Go to the next entry */
856  ListEntry = ListEntry->Flink;
857  }
858 
859  /* Return list size */
860  *ActualNumberDriverObjects = ListSize;
861 
862  /* Release the FS lock */
865 
866  return Status;
867 }
868 
869 /*
870  * @implemented
871  */
872 NTSTATUS
873 NTAPI
875  IN BOOLEAN AllowRawMount)
876 {
878  PIO_STACK_LOCATION StackPtr;
879  KEVENT Event;
880  PIRP Irp;
881  NTSTATUS Status, VpbStatus;
882  PDEVICE_OBJECT FileSystemDeviceObject;
883  PVPB Vpb, NewVpb;
884  //BOOLEAN WasNotMounted = TRUE;
885 
886  /* Wait on the device lock */
887  Status = KeWaitForSingleObject(&DeviceObject->DeviceLock,
888  Executive,
889  KernelMode,
890  FALSE,
891  NULL);
892  ASSERT(Status == STATUS_SUCCESS);
893 
894  /* Reference the VPB */
895  if (IopReferenceVerifyVpb(DeviceObject, &FileSystemDeviceObject, &Vpb))
896  {
897  /* Initialize the event */
899 
900  /* Find the actual File System DO */
901  //WasNotMounted = FALSE;
902  FileSystemDeviceObject = DeviceObject->Vpb->DeviceObject;
903  while (FileSystemDeviceObject->AttachedDevice)
904  {
905  /* Go to the next one */
906  FileSystemDeviceObject = FileSystemDeviceObject->AttachedDevice;
907  }
908 
909  /* Allocate the IRP */
910  Irp = IoAllocateIrp(FileSystemDeviceObject->StackSize, FALSE);
911  if (!Irp)
912  {
914  goto Release;
915  }
916 
917  /* Set it up */
918  Irp->UserIosb = &IoStatusBlock;
919  Irp->UserEvent = &Event;
920  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
922  Irp->RequestorMode = KernelMode;
923 
924  /* Get the I/O Stack location and set it */
925  StackPtr = IoGetNextIrpStackLocation(Irp);
928  StackPtr->Flags = AllowRawMount ? SL_ALLOW_RAW_MOUNT : 0;
929  StackPtr->Parameters.VerifyVolume.Vpb = Vpb;
930  StackPtr->Parameters.VerifyVolume.DeviceObject =
931  DeviceObject->Vpb->DeviceObject;
932 
933  /* Call the driver */
934  Status = IoCallDriver(FileSystemDeviceObject, Irp);
935  if (Status == STATUS_PENDING)
936  {
937  /* Wait on it */
939  Status = IoStatusBlock.Status;
940  }
941 
942  /* Dereference the VPB */
944  }
945 
946  /* Check if we had the wrong volume or didn't mount at all */
947  if (Status == STATUS_WRONG_VOLUME)
948  {
949  /* Create a VPB */
950  VpbStatus = IopCreateVpb(DeviceObject);
951  if (NT_SUCCESS(VpbStatus))
952  {
953  PoVolumeDevice(DeviceObject);
954 
955  /* Mount it */
956  VpbStatus = IopMountVolume(DeviceObject,
957  AllowRawMount,
958  TRUE,
959  FALSE,
960  &NewVpb);
961 
962  /* If we got a new VPB, dereference it */
963  if (NewVpb)
964  {
966  }
967  }
968 
969  /* If we failed, remove the verify flag */
970  if (!NT_SUCCESS(VpbStatus)) DeviceObject->Flags &= ~DO_VERIFY_VOLUME;
971  }
972 
973 Release:
974  /* Signal the device lock and return */
975  KeSetEvent(&DeviceObject->DeviceLock, IO_NO_INCREMENT, FALSE);
976  return Status;
977 }
978 
979 /*
980  * @implemented
981  */
982 VOID
983 NTAPI
985 {
986  PLIST_ENTRY FsList = NULL;
987  PAGED_CODE();
988 
989  /* Acquire the FS lock */
992 
993  /* Check what kind of FS this is */
994  if (DeviceObject->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM)
995  {
996  /* Use the disk list */
997  FsList = &IopDiskFileSystemQueueHead;
998  }
999  else if (DeviceObject->DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM)
1000  {
1001  /* Use the network device list */
1003  }
1004  else if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM)
1005  {
1006  /* Use the CD-ROM list */
1007  FsList = &IopCdRomFileSystemQueueHead;
1008  }
1009  else if (DeviceObject->DeviceType == FILE_DEVICE_TAPE_FILE_SYSTEM)
1010  {
1011  /* Use the tape list */
1012  FsList = &IopTapeFileSystemQueueHead;
1013  }
1014 
1015  /* Make sure that we have a valid list */
1016  if (FsList)
1017  {
1018  /* Check if we should insert it at the top or bottom of the list */
1019  if (DeviceObject->Flags & DO_LOW_PRIORITY_FILESYSTEM)
1020  {
1021  /* At the bottom */
1022  InsertTailList(FsList->Blink, &DeviceObject->Queue.ListEntry);
1023  }
1024  else
1025  {
1026  /* On top */
1027  InsertHeadList(FsList, &DeviceObject->Queue.ListEntry);
1028  }
1029  }
1030 
1031  /* Update operations counter */
1033 
1034  /* Clear the initializing flag */
1035  DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1036 
1037  /* Notify file systems of the addition */
1038  IopNotifyFileSystemChange(DeviceObject, TRUE);
1039 
1040  /* Release the FS Lock */
1043 
1044  /* Ensure driver won't be unloaded */
1045  IopInterlockedIncrementUlong(LockQueueIoDatabaseLock, (PULONG)&DeviceObject->ReferenceCount);
1046 }
1047 
1048 /*
1049  * @implemented
1050  */
1051 VOID
1052 NTAPI
1054 {
1055  PAGED_CODE();
1056 
1057  /* Acquire the FS lock */
1060 
1061  /* Simply remove the entry - if queued */
1062  if (DeviceObject->Queue.ListEntry.Flink)
1063  {
1064  RemoveEntryList(&DeviceObject->Queue.ListEntry);
1065  }
1066 
1067  /* And notify all registered file systems */
1068  IopNotifyFileSystemChange(DeviceObject, FALSE);
1069 
1070  /* Update operations counter */
1072 
1073  /* Then release the lock */
1076 
1077  /* Decrease reference count to allow unload */
1078  IopInterlockedDecrementUlong(LockQueueIoDatabaseLock, (PULONG)&DeviceObject->ReferenceCount);
1079 }
1080 
1081 /*
1082  * @implemented
1083  */
1084 NTSTATUS
1085 NTAPI
1088 {
1090  PAGED_CODE();
1091 
1092  /* Acquire the list lock */
1095 
1096  /* Check if that driver is already registered (successive calls)
1097  * See MSDN note: http://msdn.microsoft.com/en-us/library/ff548499%28v=vs.85%29.aspx
1098  */
1099  if (!IsListEmpty(&IopFsNotifyChangeQueueHead))
1100  {
1101  Entry = CONTAINING_RECORD(IopFsNotifyChangeQueueHead.Blink,
1103  FsChangeNotifyList);
1104 
1105  if (Entry->DriverObject == DriverObject &&
1106  Entry->FSDNotificationProc == DriverNotificationRoutine)
1107  {
1108  /* Release the lock */
1110 
1112  }
1113  }
1114 
1115  /* Allocate a notification entry */
1117  sizeof(FS_CHANGE_NOTIFY_ENTRY),
1119  if (!Entry)
1120  {
1121  /* Release the lock */
1123 
1125  }
1126 
1127  /* Save the driver object and notification routine */
1128  Entry->DriverObject = DriverObject;
1130 
1131  /* Insert it into the notification list */
1132  InsertTailList(&IopFsNotifyChangeQueueHead, &Entry->FsChangeNotifyList);
1133 
1134  /* Start notifying all already present FS */
1135  IopNotifyAlreadyRegisteredFileSystems(&IopNetworkFileSystemQueueHead, DriverNotificationRoutine, FALSE);
1136  IopNotifyAlreadyRegisteredFileSystems(&IopCdRomFileSystemQueueHead, DriverNotificationRoutine, TRUE);
1137  IopNotifyAlreadyRegisteredFileSystems(&IopDiskFileSystemQueueHead, DriverNotificationRoutine, TRUE);
1138  IopNotifyAlreadyRegisteredFileSystems(&IopTapeFileSystemQueueHead, DriverNotificationRoutine, TRUE);
1139 
1140  /* Release the lock */
1143 
1144  /* Reference the driver */
1145  ObReferenceObject(DriverObject);
1146  return STATUS_SUCCESS;
1147 }
1148 
1149 /*
1150  * @implemented
1151  */
1152 VOID
1153 NTAPI
1155  IN PDRIVER_FS_NOTIFICATION FSDNotificationProc)
1156 {
1157  PFS_CHANGE_NOTIFY_ENTRY ChangeEntry;
1158  PLIST_ENTRY NextEntry;
1159  PAGED_CODE();
1160 
1161  /* Acquire the list lock */
1164 
1165  /* Loop the list */
1166  NextEntry = IopFsNotifyChangeQueueHead.Flink;
1167  while (NextEntry != &IopFsNotifyChangeQueueHead)
1168  {
1169  /* Get the entry */
1170  ChangeEntry = CONTAINING_RECORD(NextEntry,
1172  FsChangeNotifyList);
1173 
1174  /* Check if it matches this de-registration */
1175  if ((ChangeEntry->DriverObject == DriverObject) &&
1176  (ChangeEntry->FSDNotificationProc == FSDNotificationProc))
1177  {
1178  /* It does, remove it from the list */
1179  RemoveEntryList(&ChangeEntry->FsChangeNotifyList);
1181  break;
1182  }
1183 
1184  /* Go to the next entry */
1185  NextEntry = NextEntry->Flink;
1186  }
1187 
1188  /* Release the lock and dereference the driver */
1191 
1192  /* Dereference the driver */
1193  ObDereferenceObject(DriverObject);
1194 }
1195 
1196 /*
1197  * @implemented
1198  */
1199 VOID
1200 NTAPI
1202 {
1203  /* Simply acquire the lock */
1205 }
1206 
1207 /*
1208  * @implemented
1209  */
1210 VOID
1211 NTAPI
1213 {
1214  /* Just release the lock */
1216 }
1217 
1218 /*
1219  * @implemented
1220  */
1221 NTSTATUS
1222 NTAPI
1224 {
1225  NTSTATUS Status;
1226  HANDLE RootHandle, KeyHandle;
1227  UNICODE_STRING HKLMSystem, KeyString;
1228  WCHAR Buffer[sizeof(L"SystemPartition") / sizeof(WCHAR)];
1229 
1230  RtlInitUnicodeString(&HKLMSystem, L"\\REGISTRY\\MACHINE\\SYSTEM");
1231 
1232  /* Open registry to save data (HKLM\SYSTEM) */
1233  Status = IopOpenRegistryKeyEx(&RootHandle, 0, &HKLMSystem, KEY_ALL_ACCESS);
1234  if (!NT_SUCCESS(Status))
1235  {
1236  return Status;
1237  }
1238 
1239  /* Create or open Setup subkey */
1240  KeyString.Buffer = Buffer;
1241  KeyString.Length = sizeof(L"Setup") - sizeof(UNICODE_NULL);
1242  KeyString.MaximumLength = sizeof(L"Setup");
1243  RtlCopyMemory(Buffer, L"Setup", sizeof(L"Setup"));
1244  Status = IopCreateRegistryKeyEx(&KeyHandle,
1245  RootHandle,
1246  &KeyString,
1249  NULL);
1250  ZwClose(RootHandle);
1251  if (!NT_SUCCESS(Status))
1252  {
1253  return Status;
1254  }
1255 
1256  /* Store caller value */
1257  KeyString.Length = sizeof(L"SystemPartition") - sizeof(UNICODE_NULL);
1258  KeyString.MaximumLength = sizeof(L"SystemPartition");
1259  RtlCopyMemory(Buffer, L"SystemPartition", sizeof(L"SystemPartition"));
1260  Status = ZwSetValueKey(KeyHandle,
1261  &KeyString,
1262  0,
1263  REG_SZ,
1264  VolumeNameString->Buffer,
1265  VolumeNameString->Length + sizeof(UNICODE_NULL));
1266  ZwClose(KeyHandle);
1267 
1268  return Status;
1269 }
1270 
1271 /*
1272  * @implemented
1273  */
1274 NTSTATUS
1275 NTAPI
1276 IoVolumeDeviceToDosName(IN PVOID VolumeDeviceObject,
1278 {
1279  PIRP Irp;
1280  ULONG Length;
1281  KEVENT Event;
1282  NTSTATUS Status;
1286  UNICODE_STRING MountMgrDevice;
1287  MOUNTMGR_VOLUME_PATHS VolumePath;
1288  PMOUNTMGR_VOLUME_PATHS VolumePathPtr;
1289  /*
1290  * This variable with be required to query device name.
1291  * It's based on MOUNTDEV_NAME (mountmgr.h).
1292  * Doing it that way will prevent dyn memory allocation.
1293  * Device name won't be longer.
1294  */
1295  struct
1296  {
1297  USHORT NameLength;
1298  WCHAR DeviceName[256];
1299  } DeviceName;
1300 
1301  PAGED_CODE();
1302 
1303  /* First step, getting device name */
1306  VolumeDeviceObject, NULL, 0,
1307  &DeviceName, sizeof(DeviceName),
1308  FALSE, &Event, &IoStatusBlock);
1309  if (!Irp)
1310  {
1312  }
1313 
1314  Status = IoCallDriver(VolumeDeviceObject, Irp);
1315  if (Status == STATUS_PENDING)
1316  {
1318  Status = IoStatusBlock.Status;
1319  }
1320 
1321  if (!NT_SUCCESS(Status))
1322  {
1323  return Status;
1324  }
1325 
1326  /* Now that we have the device name, we can query the MountMgr
1327  * So, get its device object first.
1328  */
1329  RtlInitUnicodeString(&MountMgrDevice, MOUNTMGR_DEVICE_NAME);
1330  Status = IoGetDeviceObjectPointer(&MountMgrDevice, FILE_READ_ATTRIBUTES,
1331  &FileObject, &DeviceObject);
1332  if (!NT_SUCCESS(Status))
1333  {
1334  return Status;
1335  }
1336 
1337  /* Then, use the proper IOCTL to query the DOS name */
1340  DeviceObject, &DeviceName, sizeof(DeviceName),
1341  &VolumePath, sizeof(VolumePath),
1342  FALSE, &Event, &IoStatusBlock);
1343  if (!Irp)
1344  {
1346  goto DereferenceFO;
1347  }
1348 
1349  Status = IoCallDriver(VolumeDeviceObject, Irp);
1350  if (Status == STATUS_PENDING)
1351  {
1353  Status = IoStatusBlock.Status;
1354  }
1355 
1356  /* Only tolerated failure here is buffer too small, which is
1357  * expected.
1358  */
1359  if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
1360  {
1361  goto DereferenceFO;
1362  }
1363 
1364  /* Compute needed size to store DOS name.
1365  * Even if MOUNTMGR_VOLUME_PATHS allows bigger
1366  * name lengths than MAXUSHORT, we can't use
1367  * them, because we have to return this in an UNICODE_STRING
1368  * that stores length on USHORT.
1369  */
1370  Length = VolumePath.MultiSzLength + sizeof(VolumePath);
1371  if (Length > MAXUSHORT)
1372  {
1373  Status = STATUS_INVALID_BUFFER_SIZE;
1374  goto DereferenceFO;
1375  }
1376 
1377  /* Reallocate memory, even in case of success, because
1378  * that's the buffer that will be returned to caller
1379  */
1380  VolumePathPtr = ExAllocatePoolWithTag(PagedPool, Length, 'D2d ');
1381  if (!VolumePathPtr)
1382  {
1384  goto DereferenceFO;
1385  }
1386 
1387  /* Requery DOS path with proper size */
1390  DeviceObject, &DeviceName, sizeof(DeviceName),
1391  VolumePathPtr, Length,
1392  FALSE, &Event, &IoStatusBlock);
1393  if (!Irp)
1394  {
1396  goto ReleaseMemory;
1397  }
1398 
1399  Status = IoCallDriver(VolumeDeviceObject, Irp);
1400  if (Status == STATUS_PENDING)
1401  {
1403  Status = IoStatusBlock.Status;
1404  }
1405 
1406  if (!NT_SUCCESS(Status))
1407  {
1408  goto ReleaseMemory;
1409  }
1410 
1411  /* Set output string */
1412  DosName->Length = (USHORT)VolumePathPtr->MultiSzLength;
1413  DosName->MaximumLength = (USHORT)VolumePathPtr->MultiSzLength + sizeof(UNICODE_NULL);
1414  /* Our MOUNTMGR_VOLUME_PATHS will be used as output buffer */
1415  DosName->Buffer = (PWSTR)VolumePathPtr;
1416  /* Move name at the begin, RtlMoveMemory is OK with overlapping */
1417  RtlMoveMemory(DosName->Buffer, VolumePathPtr->MultiSz, VolumePathPtr->MultiSzLength);
1418  DosName->Buffer[DosName->Length / sizeof(WCHAR)] = UNICODE_NULL;
1419 
1420  /* DON'T release buffer, just dereference FO, and return success */
1421  Status = STATUS_SUCCESS;
1422  goto DereferenceFO;
1423 
1425  ExFreePoolWithTag(VolumePathPtr, 'D2d ');
1426 
1427 DereferenceFO:
1428  ObDereferenceObject(FileObject);
1429 
1430  return Status;
1431 }
1432 
1433 /* EOF */
DWORD *typedef PVOID
Definition: winlogon.h:52
VOID NTAPI IopLoadFileSystemDriver(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:406
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH
Definition: mountmgr.h:127
#define STATUS_DEVICE_ALREADY_ATTACHED
Definition: ntstatus.h:278
* PNTSTATUS
Definition: strlen.c:14
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:414
_In_ PVOID _In_ BOOLEAN Alertable
Definition: exfuncs.h:452
#define IN
Definition: typedefs.h:38
#define FILE_DEVICE_DISK
Definition: winioctl.h:112
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID NTAPI IopDecrementDeviceObjectHandleCount(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:70
USHORT Flags
Definition: iotypes.h:169
struct _Entry Entry
Definition: kefuncs.h:640
VOID NTAPI IopDereferenceVpbAndFree(IN PVPB Vpb)
Definition: volume.c:183
#define FILE_DEVICE_TAPE_FILE_SYSTEM
Definition: winioctl.h:137
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
_In_ BOOLEAN Release
Definition: classpnp.h:929
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4693
USHORT MaximumLength
Definition: env_spec_w32.h:370
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
#define IRP_MJ_SHUTDOWN
NTSTATUS NTAPI IopCreateVpb(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:155
_In_ PIRP Irp
Definition: csq.h:116
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
__wchar_t WCHAR
Definition: xmlstorage.h:180
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
BOOLEAN NTAPI IopReferenceVerifyVpb(IN PDEVICE_OBJECT DeviceObject, OUT PDEVICE_OBJECT *FileSystemObject, OUT PVPB *Vpb)
Definition: volume.c:213
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
BOOLEAN NTAPI FsRtlIsTotalDeviceFailure(IN NTSTATUS NtStatus)
Definition: filter.c:37
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
return STATUS_SUCCESS
Definition: btrfs.c:2690
VOID NTAPI IoUnregisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:1053
#define KeGetPreviousMode()
Definition: ketypes.h:1081
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2769
#define TAG_FS_CHANGE_NOTIFY
Definition: tag.h:51
VOID NTAPI IopDereferenceDeviceObject(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN ForceUnload)
Definition: device.c:459
ActualNumberDriverObjects _In_ ULONG DriverObjectListSize
Definition: iofuncs.h:2281
PVOID *typedef PWSTR
Definition: winlogon.h:57
NTSTATUS NTAPI IopMountVolume(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount, IN BOOLEAN DeviceIsLocked, IN BOOLEAN Alertable, OUT PVPB *Vpb)
Definition: volume.c:459
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define IRP_MN_LOAD_FILE_SYSTEM
Definition: iotypes.h:4017
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1201
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1208
#define FILE_DEVICE_VIRTUAL_DISK
Definition: winioctl.h:141
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define VPB_PERSISTENT
Definition: iotypes.h:1760
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
LIST_ENTRY IopDiskFileSystemQueueHead
Definition: volume.c:26
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define InsertTailList(ListHead, Entry)
#define STATUS_FS_DRIVER_REQUIRED
Definition: ntstatus.h:631
LIST_ENTRY IopCdRomFileSystemQueueHead
Definition: volume.c:27
#define WCHAR
Definition: msvc.h:43
#define STATUS_ALERTED
Definition: ntstatus.h:80
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
FORCEINLINE VOID IopNotifyFileSystemChange(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN DriverActive)
Definition: volume.c:282
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
#define FASTCALL
Definition: nt_native.h:50
_Out_ PKIRQL Irql
Definition: csq.h:179
#define TAG_VPB
Definition: cdprocs.h:98
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define MOUNTMGR_DEVICE_NAME
Definition: imports.h:76
#define PAGED_CODE()
Definition: video.h:57
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:52
uint32_t ULONG_PTR
Definition: typedefs.h:63
NTSTATUS NTAPI IoEnumerateRegisteredFiltersList(OUT PDRIVER_OBJECT *DriverObjectList, IN ULONG DriverObjectListSize, OUT PULONG ActualNumberDriverObjects)
Definition: volume.c:818
ACPI_EFI_EVENT Event
Definition: acefiex.h:633
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:107
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
NTSTATUS NTAPI IoVolumeDeviceToDosName(IN PVOID VolumeDeviceObject, OUT PUNICODE_STRING DosName)
Definition: volume.c:1276
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
#define IRP_MN_VERIFY_VOLUME
Definition: iotypes.h:4016
NTSTATUS NTAPI IopCreateRegistryKeyEx(OUT PHANDLE Handle, IN HANDLE BaseHandle OPTIONAL, IN PUNICODE_STRING KeyName, IN ACCESS_MASK DesiredAccess, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
LIST_ENTRY IopTapeFileSystemQueueHead
Definition: volume.c:27
#define STATUS_UNRECOGNIZED_VOLUME
Definition: udferr_usr.h:173
ULONG ReferenceCount
Definition: iotypes.h:174
ULONG FASTCALL IopInterlockedDecrementUlong(IN KSPIN_LOCK_QUEUE_NUMBER Queue, IN PULONG Ulong)
Definition: volume.c:328
#define VPB_LOCKED
Definition: iotypes.h:1759
union _IO_STACK_LOCATION::@3564 Parameters
#define DO_SYSTEM_BOOT_PARTITION
Definition: env_spec_w32.h:400
smooth NULL
Definition: ftsmooth.c:416
#define FORCEINLINE
Definition: ntbasedef.h:221
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
Definition: bufpool.h:45
struct _DEVICE_OBJECT * DeviceObject
Definition: iotypes.h:171
#define VPB_REMOVE_PENDING
Definition: ntifs_ex.h:428
_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
#define FILE_DEVICE_DISK_FILE_SYSTEM
Definition: winioctl.h:113
NTSTATUS NTAPI IoSetSystemPartition(IN PUNICODE_STRING VolumeNameString)
Definition: volume.c:1223
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:636
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4015
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
unsigned char BOOLEAN
ULONG FASTCALL IopInterlockedIncrementUlong(IN KSPIN_LOCK_QUEUE_NUMBER Queue, IN PULONG Ulong)
Definition: volume.c:310
PDRIVER_OBJECT DriverObject
Definition: io.h:458
LONG NTSTATUS
Definition: precomp.h:26
#define DOE_UNLOAD_PENDING
Definition: iotypes.h:149
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
#define STATUS_PENDING
Definition: ntstatus.h:82
VOID NTAPI IopShutdownBaseFileSystems(IN PLIST_ENTRY ListHead)
Definition: volume.c:346
#define IRP_MJ_FILE_SYSTEM_CONTROL
struct _DEVICE_OBJECT * RealDevice
Definition: iotypes.h:172
VOID NTAPI IopDecrementDeviceObjectRef(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN UnloadIfUnused)
Definition: volume.c:38
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
VOID NTAPI PoVolumeDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: povolume.c:83
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
struct _IO_STACK_LOCATION::@3564::@3581 MountVolume
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
#define SL_ALLOW_RAW_MOUNT
Definition: iotypes.h:1792
* PFILE_OBJECT
Definition: iotypes.h:1949
UINTN VOID * Buffer
Definition: acefiex.h:370
VOID NTAPI IoUnregisterFsRegistrationChange(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_FS_NOTIFICATION FSDNotificationProc)
Definition: volume.c:1154
CSHORT Size
Definition: iotypes.h:168
struct _IO_STACK_LOCATION::@3564::@3582 VerifyVolume
ERESOURCE IopDatabaseResource
Definition: volume.c:25
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
ULONG IopFsRegistrationOps
Definition: volume.c:29
#define DOE_DELETE_PENDING
Definition: iotypes.h:150
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
_In_ PDRIVER_FS_NOTIFICATION DriverNotificationRoutine
Definition: iofuncs.h:593
static const WCHAR L[]
Definition: oid.c:1087
VOID UINTN Length
Definition: acefiex.h:744
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define DOE_REMOVE_PENDING
Definition: iotypes.h:151
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
ULONG ExpInitializationPhase
Definition: init.c:65
KIRQL * PKIRQL
Definition: env_spec_w32.h:592
Definition: typedefs.h:117
PDRIVER_FS_NOTIFICATION FSDNotificationProc
Definition: io.h:459
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
#define DO_LOW_PRIORITY_FILESYSTEM
#define IO_TYPE_VPB
struct _VPB VPB
Status
Definition: gdiplustypes.h:24
#define VPB_RAW_MOUNT
Definition: iotypes.h:1762
#define STATUS_USER_APC
Definition: ntstatus.h:78
#define IRP_MOUNT_COMPLETION
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
VOID NTAPI IopUnloadDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:387
enum _KSPIN_LOCK_QUEUE_NUMBER KSPIN_LOCK_QUEUE_NUMBER
DWORD *typedef HANDLE
Definition: winlogon.h:52
PVPB NTAPI IopMountInitializeVpb(IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT AttachedDeviceObject, IN BOOLEAN Raw)
Definition: volume.c:246
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:3474
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:49
unsigned short USHORT
Definition: pedump.c:61
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
PDEVICE_OBJECT NTAPI IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1158
VOID NTAPI IopNotifyAlreadyRegisteredFileSystems(IN PLIST_ENTRY ListHead, IN PDRIVER_FS_NOTIFICATION DriverNotificationRoutine, BOOLEAN SkipRawFs)
Definition: volume.c:782
ActualNumberDriverObjects _In_ ULONG _Out_ PULONG ActualNumberDriverObjects
Definition: iofuncs.h:2281
_Out_ PUNICODE_STRING DosName
Definition: rtlfuncs.h:1270
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int * PULONG
Definition: retypes.h:1
#define FILE_DEVICE_NETWORK_FILE_SYSTEM
Definition: winioctl.h:125
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:360
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define MAXUSHORT
Definition: typedefs.h:81
LIST_ENTRY IopFsNotifyChangeQueueHead
Definition: volume.c:28
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
CSHORT Type
Definition: iotypes.h:167
VOID NTAPI IoRegisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:984
Definition: iotypes.h:166
#define OUT
Definition: typedefs.h:39
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM
Definition: winioctl.h:108
#define ObReferenceObject
Definition: obfuncs.h:204
PVOID PIRP
Definition: usb.h:38
ULONG ERESOURCE
Definition: env_spec_w32.h:594
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
LIST_ENTRY FsChangeNotifyList
Definition: io.h:457
Definition: sacdrv.h:279
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
PVPB NTAPI IopCheckVpbMounted(IN POPEN_PACKET OpenPacket, IN PDEVICE_OBJECT DeviceObject, IN PUNICODE_STRING RemainingName, OUT PNTSTATUS Status)
Definition: volume.c:81
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
unsigned long Ulong
Definition: utypes.h:42
#define IoGetDevObjExtension(DeviceObject)
Definition: io.h:124
#define VPB_MOUNTED
Definition: iotypes.h:1758
NTSTATUS NTAPI IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount)
Definition: volume.c:874
LIST_ENTRY IopNetworkFileSystemQueueHead
Definition: volume.c:26
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1212
NTSTATUS NTAPI IoRegisterFsRegistrationChange(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_FS_NOTIFICATION DriverNotificationRoutine)
Definition: volume.c:1086
NTSTATUS NTAPI ReleaseMemory(IN PDEVICE_OBJECT DeviceObject)
Definition: fbtpnp.c:1790
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:94
struct _DRIVER_OBJECT * PDRIVER_OBJECT
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1664
DRIVER_FS_NOTIFICATION * PDRIVER_FS_NOTIFICATION
Definition: iotypes.h:6972
#define IRP_SYNCHRONOUS_PAGING_IO
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
Definition: io.h:455
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:806
#define REG_SZ
Definition: layer.c:22