ReactOS  0.4.14-dev-52-g6116262
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 */
62  }
63 }
64 
65 /*
66  * @implemented
67  */
68 VOID
69 NTAPI
71 {
72  /* Just decrease reference count */
74 }
75 
76 /*
77  * @implemented
78  */
79 PVPB
80 NTAPI
85 {
87  KIRQL OldIrql;
88  PVPB Vpb = NULL;
89 
90  /* Lock the VPBs */
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 */
103 
104  /* Mount the volume */
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 */
118 
119  /* Check if it was a total failure */
120  if (!NT_SUCCESS(*Status)) return NULL;
121 
122  /* Otherwise we were alerted */
124  return NULL;
125  }
126  /*
127  * In case IopMountVolume returns a valid VPB
128  * Then, the volume is mounted, return it
129  */
130  else if (Vpb != NULL)
131  {
132  return Vpb;
133  }
134 
135  /* Re-acquire the lock */
137  }
138 
139  /* Make sure the VPB isn't locked */
140  Vpb = DeviceObject->Vpb;
141  if (Vpb->Flags & VPB_LOCKED)
142  {
143  /* We're locked, so fail */
145  Vpb = NULL;
146  }
147  else
148  {
149  /* Success! Reference the VPB */
150  Vpb->ReferenceCount++;
151  }
152 
153  /* Release the lock and return the VPB */
155  return Vpb;
156 }
157 
158 /*
159  * @implemented
160  */
161 NTSTATUS
162 NTAPI
164 {
165  PVPB Vpb;
166 
167  /* Allocate the Vpb */
169  sizeof(VPB),
170  TAG_VPB);
171  if (!Vpb) return STATUS_INSUFFICIENT_RESOURCES;
172 
173  /* Clear it so we don't waste time manually */
174  RtlZeroMemory(Vpb, sizeof(VPB));
175 
176  /* Set the Header and Device Field */
177  Vpb->Type = IO_TYPE_VPB;
178  Vpb->Size = sizeof(VPB);
179  Vpb->RealDevice = DeviceObject;
180 
181  /* Link it to the Device Object */
182  DeviceObject->Vpb = Vpb;
183  return STATUS_SUCCESS;
184 }
185 
186 /*
187  * @implemented
188  */
189 VOID
190 NTAPI
192 {
193  KIRQL OldIrql;
194 
195  /* Lock the VPBs and decrease references */
197  Vpb->ReferenceCount--;
198 
199  /* Check if we're out of references */
200  if (!Vpb->ReferenceCount && Vpb->RealDevice->Vpb == Vpb &&
201  !(Vpb->Flags & VPB_PERSISTENT))
202  {
203  /* Release VPB lock */
205 
206  /* And free VPB */
208  }
209  else
210  {
211  /* Release VPB lock */
213  }
214 }
215 
216 /*
217  * @implemented
218  */
219 BOOLEAN
220 NTAPI
222  OUT PDEVICE_OBJECT *FileSystemObject,
223  OUT PVPB *Vpb)
224 {
225  KIRQL OldIrql;
226  PVPB LocalVpb;
227  BOOLEAN Result = FALSE;
228 
229  /* Lock the VPBs and assume failure */
231  *Vpb = NULL;
232  *FileSystemObject = NULL;
233 
234  /* Get the VPB and make sure it's mounted */
235  LocalVpb = DeviceObject->Vpb;
236  if ((LocalVpb) && (LocalVpb->Flags & VPB_MOUNTED))
237  {
238  /* Return it */
239  *Vpb = LocalVpb;
240  *FileSystemObject = LocalVpb->DeviceObject;
241 
242  /* Reference it */
243  LocalVpb->ReferenceCount++;
244  Result = TRUE;
245  }
246 
247  /* Release the VPB lock and return status */
249  return Result;
250 }
251 
252 PVPB
253 NTAPI
255  IN PDEVICE_OBJECT AttachedDeviceObject,
256  IN BOOLEAN Raw)
257 {
258  KIRQL OldIrql;
259  PVPB Vpb;
260 
261  /* Lock the VPBs */
263  Vpb = DeviceObject->Vpb;
264 
265  /* Set the VPB as mounted and possibly raw */
266  Vpb->Flags |= VPB_MOUNTED | (Raw ? VPB_RAW_MOUNT : 0);
267 
268  /* Set the stack size */
269  Vpb->DeviceObject->StackSize = AttachedDeviceObject->StackSize;
270 
271  /* Add one for the FS Driver */
272  Vpb->DeviceObject->StackSize++;
273 
274  /* Set the VPB in the device extension */
275  IoGetDevObjExtension(Vpb->DeviceObject)->Vpb = Vpb;
276 
277  /* Reference it */
278  Vpb->ReferenceCount++;
279 
280  /* Release the VPB lock and return it */
282  return Vpb;
283 }
284 
285 /*
286  * @implemented
287  */
289 VOID
291  IN BOOLEAN DriverActive)
292 {
293  PFS_CHANGE_NOTIFY_ENTRY ChangeEntry;
294  PLIST_ENTRY ListEntry;
295 
296  /* Loop the list */
297  ListEntry = IopFsNotifyChangeQueueHead.Flink;
298  while (ListEntry != &IopFsNotifyChangeQueueHead)
299  {
300  /* Get the entry */
301  ChangeEntry = CONTAINING_RECORD(ListEntry,
303  FsChangeNotifyList);
304 
305  /* Call the notification procedure */
306  ChangeEntry->FSDNotificationProc(DeviceObject, DriverActive);
307 
308  /* Go to the next entry */
309  ListEntry = ListEntry->Flink;
310  }
311 }
312 
313 /*
314  * @implemented
315  */
316 ULONG
317 FASTCALL
319  IN PULONG Ulong)
320 {
321  KIRQL Irql;
322  ULONG OldValue;
323 
324  Irql = KeAcquireQueuedSpinLock(Queue);
325  OldValue = (*Ulong)++;
327 
328  return OldValue;
329 }
330 
331 /*
332  * @implemented
333  */
334 ULONG
335 FASTCALL
337  IN PULONG Ulong)
338 {
339  KIRQL Irql;
340  ULONG OldValue;
341 
342  Irql = KeAcquireQueuedSpinLock(Queue);
343  OldValue = (*Ulong)--;
345 
346  return OldValue;
347 }
348 
349 /*
350  * @implemented
351  */
352 VOID
353 NTAPI
355 {
356  PLIST_ENTRY ListEntry;
358  IO_STATUS_BLOCK StatusBlock;
359  PIRP Irp;
360  KEVENT Event;
362 
364 
365  /* Get the first entry and start looping */
366  ListEntry = ListHead->Flink;
367  while (ListEntry != ListHead)
368  {
369  /* Get the device object */
370  DeviceObject = CONTAINING_RECORD(ListEntry,
372  Queue.ListEntry);
373 
374  /* Get the attached device */
376 
379 
380  /* Build the shutdown IRP and call the driver */
382  DeviceObject,
383  NULL,
384  0,
385  NULL,
386  &Event,
387  &StatusBlock);
388  if (Irp)
389  {
391  if (Status == STATUS_PENDING)
392  {
393  /* Wait on the driver */
395  }
396  }
397 
398  /* Reset the event */
400 
403 
404  /* Go to the next entry */
405  ListEntry = ListEntry->Flink;
406  }
407 }
408 
409 /*
410  * @implemented
411  */
412 VOID
413 NTAPI
415 {
417  PIO_STACK_LOCATION StackPtr;
418  KEVENT Event;
419  PIRP Irp;
421  PDEVICE_OBJECT AttachedDeviceObject = DeviceObject;
422  PAGED_CODE();
423 
424  /* Loop as long as we're attached */
425  while (AttachedDeviceObject->AttachedDevice)
426  {
427  /* Get the attached device object */
428  AttachedDeviceObject = AttachedDeviceObject->AttachedDevice;
429  }
430 
431  /* Initialize the event and build the IRP */
434  AttachedDeviceObject,
435  NULL,
436  0,
437  NULL,
438  0,
439  FALSE,
440  &Event,
441  &IoStatusBlock);
442  if (Irp)
443  {
444  /* Set the major and minor functions */
445  StackPtr = IoGetNextIrpStackLocation(Irp);
448 
449  /* Call the driver */
450  Status = IoCallDriver(AttachedDeviceObject, Irp);
451  if (Status == STATUS_PENDING)
452  {
453  /* Wait on it */
455  }
456  }
457 
458  /* Dereference DO - FsRec? - Comment out call, since it breaks up 2nd stage boot, needs more research. */
459 // IopDecrementDeviceObjectRef(AttachedDeviceObject, TRUE);
460 }
461 
462 /*
463  * @implemented
464  */
465 NTSTATUS
466 NTAPI
468  IN BOOLEAN AllowRawMount,
469  IN BOOLEAN DeviceIsLocked,
471  OUT PVPB *Vpb)
472 {
473  KEVENT Event;
476  PIRP Irp;
477  PIO_STACK_LOCATION StackPtr;
478  PLIST_ENTRY FsList, ListEntry;
479  LIST_ENTRY LocalList;
480  PDEVICE_OBJECT AttachedDeviceObject = DeviceObject;
481  PDEVICE_OBJECT FileSystemDeviceObject, ParentFsDeviceObject;
482  ULONG FsStackOverhead, RegistrationOps;
483  PAGED_CODE();
484 
485  /* Check if the device isn't already locked */
486  if (!DeviceIsLocked)
487  {
488  /* Lock it ourselves */
490  Executive,
492  Alertable,
493  NULL);
494  if ((Status == STATUS_ALERTED) || (Status == STATUS_USER_APC))
495  {
496  /* Don't mount if we were interrupted */
497  return Status;
498  }
499  }
500 
501  /* Acquire the FS Lock*/
504 
505  /* Make sure we weren't already mounted */
507  {
508  /* Initialize the event to wait on */
510 
511  /* Remove the verify flag and get the actual device to mount */
513  while (AttachedDeviceObject->AttachedDevice)
514  {
515  /* Get the next one */
516  AttachedDeviceObject = AttachedDeviceObject->AttachedDevice;
517  }
518 
519  /* Reference it */
520  ObReferenceObject(AttachedDeviceObject);
521 
522  /* For a mount operation, this can only be a Disk, CD-ROM or tape */
523  if ((DeviceObject->DeviceType == FILE_DEVICE_DISK) ||
524  (DeviceObject->DeviceType == FILE_DEVICE_VIRTUAL_DISK))
525  {
526  /* Use the disk list */
527  FsList = &IopDiskFileSystemQueueHead;
528  }
529  else if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM)
530  {
531  /* Use the CD-ROM list */
532  FsList = &IopCdRomFileSystemQueueHead;
533  }
534  else
535  {
536  /* It's gotta be a tape... */
537  FsList = &IopTapeFileSystemQueueHead;
538  }
539 
540  /* Now loop the fs list until one of the file systems accepts us */
542  ListEntry = FsList->Flink;
543  while ((ListEntry != FsList) && !(NT_SUCCESS(Status)))
544  {
545  /*
546  * If we're not allowed to mount this volume and this is our last
547  * (but not only) chance to mount it...
548  */
549  if (!(AllowRawMount) &&
550  (ListEntry->Flink == FsList) &&
551  (ListEntry != FsList->Flink))
552  {
553  /* Then fail this mount request */
554  break;
555  }
556 
557  /*
558  * Also check if this is a raw mount and there are other file
559  * systems on the list.
560  */
561  if ((DeviceObject->Vpb->Flags & VPB_RAW_MOUNT) &&
562  (ListEntry->Flink != FsList))
563  {
564  /* Then skip this entry */
565  ListEntry = ListEntry->Flink;
566  continue;
567  }
568 
569  /* Get the Device Object for this FS */
570  FileSystemDeviceObject = CONTAINING_RECORD(ListEntry,
572  Queue.ListEntry);
573  ParentFsDeviceObject = FileSystemDeviceObject;
574 
575  /*
576  * If this file system device is attached to some other device,
577  * then we must make sure to increase the stack size for the IRP.
578  * The default is +1, for the FS device itself.
579  */
580  FsStackOverhead = 1;
581  while (FileSystemDeviceObject->AttachedDevice)
582  {
583  /* Get the next attached device and increase overhead */
584  FileSystemDeviceObject = FileSystemDeviceObject->
585  AttachedDevice;
586  FsStackOverhead++;
587  }
588 
589  /* Clear the event */
591 
592  /* Allocate the IRP */
593  Irp = IoAllocateIrp(AttachedDeviceObject->StackSize +
594  (UCHAR)FsStackOverhead,
595  TRUE);
596  if (!Irp)
597  {
598  /* Fail */
600  break;
601  }
602 
603  /* Setup the IRP */
604  Irp->UserIosb = &IoStatusBlock;
605  Irp->UserEvent = &Event;
606  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
608  Irp->RequestorMode = KernelMode;
609 
610  /* Get the I/O Stack location and set it up */
611  StackPtr = IoGetNextIrpStackLocation(Irp);
614  StackPtr->Flags = AllowRawMount;
615  StackPtr->Parameters.MountVolume.Vpb = DeviceObject->Vpb;
616  StackPtr->Parameters.MountVolume.DeviceObject =
617  AttachedDeviceObject;
618 
619  /* Save registration operations */
620  RegistrationOps = IopFsRegistrationOps;
621 
622  /* Release locks */
625 
626  /* Call the driver */
627  Status = IoCallDriver(FileSystemDeviceObject, Irp);
628  if (Status == STATUS_PENDING)
629  {
630  /* Wait on it */
632  Executive,
633  KernelMode,
634  FALSE,
635  NULL);
637  }
638 
641 
642  /* Check if mounting was successful */
643  if (NT_SUCCESS(Status))
644  {
645  /* Mount the VPB */
647  AttachedDeviceObject,
648  (DeviceObject->Vpb->Flags &
649  VPB_RAW_MOUNT));
650  }
651  else
652  {
653  /* Check if we failed because of the user */
654  if ((IoIsErrorUserInduced(Status)) &&
655  (IoStatusBlock.Information == 1))
656  {
657  /* Break out and fail */
658  break;
659  }
660 
661  /* If there were registration operations in the meanwhile */
662  if (RegistrationOps != IopFsRegistrationOps)
663  {
664  /* We need to setup a local list to pickup where we left */
665  LocalList.Flink = FsList->Flink;
666  ListEntry = &LocalList;
667 
669  }
670 
671  /* Otherwise, check if we need to load the FS driver */
673  {
674  /* We need to release the lock */
677 
678  /* Release the device lock if we're holding it */
679  if (!DeviceIsLocked)
680  {
681  KeSetEvent(&DeviceObject->DeviceLock, 0, FALSE);
682  }
683 
684  /* Leave critical section */
686 
687  /* Load the FS */
688  IopLoadFileSystemDriver(ParentFsDeviceObject);
689 
690  /* Check if the device isn't already locked */
691  if (!DeviceIsLocked)
692  {
693  /* Lock it ourselves */
695  DeviceLock,
696  Executive,
698  Alertable,
699  NULL);
700  if ((Status == STATUS_ALERTED) ||
701  (Status == STATUS_USER_APC))
702  {
703  /* Don't mount if we were interrupted */
704  ObDereferenceObject(AttachedDeviceObject);
705  return Status;
706  }
707  }
708 
709  /* Reacquire the lock */
712 
713  /* When we released the lock, make sure nobody beat us */
714  if (DeviceObject->Vpb->Flags & VPB_MOUNTED)
715  {
716  /* Someone did, break out */
718  break;
719  }
720 
721  /* Start over by setting a failure */
723 
724  /* We need to setup a local list to pickup where we left */
725  LocalList.Flink = FsList->Flink;
726  ListEntry = &LocalList;
727  }
728 
729  /*
730  * Check if we failed with any other error then an unrecognized
731  * volume, and if this request doesn't allow mounting the raw
732  * file system.
733  */
734  if (!(AllowRawMount) &&
737  {
738  /* Break out and give up */
739  break;
740  }
741  }
742 
743  /* Go to the next FS entry */
744  ListEntry = ListEntry->Flink;
745  }
746 
747  /* Dereference the device if we failed */
748  if (!NT_SUCCESS(Status)) ObDereferenceObject(AttachedDeviceObject);
749  }
750  else if (DeviceObject->Vpb->Flags & VPB_REMOVE_PENDING)
751  {
752  /* Someone wants to remove us */
754  }
755  else
756  {
757  /* Someone already mounted us */
759  }
760 
761  /* Release the FS lock */
764 
765  /* Release the device lock if we're holding it */
766  if (!DeviceIsLocked) KeSetEvent(&DeviceObject->DeviceLock, 0, FALSE);
767 
768  /* Check if we failed to mount the boot partition */
769  if ((!NT_SUCCESS(Status)) &&
772  {
773  /* Bugcheck the system */
774  KeBugCheckEx(INACCESSIBLE_BOOT_DEVICE,
776  Status,
777  0,
778  0);
779  }
780 
781  /* Return the mount status */
782  return Status;
783 }
784 
785 /*
786  * @implemented
787  */
788 VOID
789 NTAPI
792  BOOLEAN SkipRawFs)
793 {
794  PLIST_ENTRY ListEntry;
796 
797  /* Browse the whole list */
798  ListEntry = ListHead->Flink;
799  while (ListEntry != ListHead)
800  {
801  /* Check if we reached rawfs and if we have to skip it */
802  if (ListEntry->Flink == ListHead && SkipRawFs)
803  {
804  return;
805  }
806 
807  /* Otherwise, get DO and notify */
808  DeviceObject = CONTAINING_RECORD(ListEntry,
810  Queue.ListEntry);
811 
813 
814  /* Go to the next entry */
815  ListEntry = ListEntry->Flink;
816  }
817 }
818 
819 /* PUBLIC FUNCTIONS **********************************************************/
820 
821 /*
822  * @implemented
823  */
824 NTSTATUS
825 NTAPI
829 {
830  PLIST_ENTRY ListEntry;
832  PFS_CHANGE_NOTIFY_ENTRY ChangeEntry;
833  ULONG ListSize = 0, MaximumSize = DriverObjectListSize / sizeof(PDRIVER_OBJECT);
834 
835  /* Acquire the FS lock */
838 
839  /* Browse the whole list */
840  ListEntry = IopFsNotifyChangeQueueHead.Flink;
841  while (ListEntry != &IopFsNotifyChangeQueueHead)
842  {
843  ChangeEntry = CONTAINING_RECORD(ListEntry,
845  FsChangeNotifyList);
846 
847  /* If buffer is still big enough */
848  if (ListSize < MaximumSize)
849  {
850  /* Reference the driver object */
851  ObReferenceObject(ChangeEntry->DriverObject);
852  /* And pass it to the caller */
853  DriverObjectList[ListSize] = ChangeEntry->DriverObject;
854  }
855  else
856  {
858  }
859 
860  /* Increase size counter */
861  ListSize++;
862 
863  /* Go to the next entry */
864  ListEntry = ListEntry->Flink;
865  }
866 
867  /* Return list size */
868  *ActualNumberDriverObjects = ListSize;
869 
870  /* Release the FS lock */
873 
874  return Status;
875 }
876 
877 /*
878  * @implemented
879  */
880 NTSTATUS
881 NTAPI
883  IN BOOLEAN AllowRawMount)
884 {
886  PIO_STACK_LOCATION StackPtr;
887  KEVENT Event;
888  PIRP Irp;
889  NTSTATUS Status, VpbStatus;
890  PDEVICE_OBJECT FileSystemDeviceObject;
891  PVPB Vpb, NewVpb;
892  //BOOLEAN WasNotMounted = TRUE;
893 
894  /* Wait on the device lock */
896  Executive,
897  KernelMode,
898  FALSE,
899  NULL);
901 
902  /* Reference the VPB */
903  if (IopReferenceVerifyVpb(DeviceObject, &FileSystemDeviceObject, &Vpb))
904  {
905  /* Initialize the event */
907 
908  /* Find the actual File System DO */
909  //WasNotMounted = FALSE;
910  FileSystemDeviceObject = DeviceObject->Vpb->DeviceObject;
911  while (FileSystemDeviceObject->AttachedDevice)
912  {
913  /* Go to the next one */
914  FileSystemDeviceObject = FileSystemDeviceObject->AttachedDevice;
915  }
916 
917  /* Allocate the IRP */
918  Irp = IoAllocateIrp(FileSystemDeviceObject->StackSize, FALSE);
919  if (!Irp)
920  {
922  goto Release;
923  }
924 
925  /* Set it up */
926  Irp->UserIosb = &IoStatusBlock;
927  Irp->UserEvent = &Event;
928  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
930  Irp->RequestorMode = KernelMode;
931 
932  /* Get the I/O Stack location and set it */
933  StackPtr = IoGetNextIrpStackLocation(Irp);
936  StackPtr->Flags = AllowRawMount ? SL_ALLOW_RAW_MOUNT : 0;
937  StackPtr->Parameters.VerifyVolume.Vpb = Vpb;
938  StackPtr->Parameters.VerifyVolume.DeviceObject =
939  DeviceObject->Vpb->DeviceObject;
940 
941  /* Call the driver */
942  Status = IoCallDriver(FileSystemDeviceObject, Irp);
943  if (Status == STATUS_PENDING)
944  {
945  /* Wait on it */
948  }
949 
950  /* Dereference the VPB */
952  }
953 
954  /* Check if we had the wrong volume or didn't mount at all */
956  {
957  /* Create a VPB */
958  VpbStatus = IopCreateVpb(DeviceObject);
959  if (NT_SUCCESS(VpbStatus))
960  {
962 
963  /* Mount it */
964  VpbStatus = IopMountVolume(DeviceObject,
965  AllowRawMount,
966  TRUE,
967  FALSE,
968  &NewVpb);
969 
970  /* If we got a new VPB, dereference it */
971  if (NewVpb)
972  {
974  }
975  }
976 
977  /* If we failed, remove the verify flag */
978  if (!NT_SUCCESS(VpbStatus)) DeviceObject->Flags &= ~DO_VERIFY_VOLUME;
979  }
980 
981 Release:
982  /* Signal the device lock and return */
984  return Status;
985 }
986 
987 /*
988  * @implemented
989  */
990 VOID
991 NTAPI
993 {
994  PLIST_ENTRY FsList = NULL;
995  PAGED_CODE();
996 
997  /* Acquire the FS lock */
1000 
1001  /* Check what kind of FS this is */
1002  if (DeviceObject->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM)
1003  {
1004  /* Use the disk list */
1005  FsList = &IopDiskFileSystemQueueHead;
1006  }
1007  else if (DeviceObject->DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM)
1008  {
1009  /* Use the network device list */
1011  }
1012  else if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM)
1013  {
1014  /* Use the CD-ROM list */
1015  FsList = &IopCdRomFileSystemQueueHead;
1016  }
1017  else if (DeviceObject->DeviceType == FILE_DEVICE_TAPE_FILE_SYSTEM)
1018  {
1019  /* Use the tape list */
1020  FsList = &IopTapeFileSystemQueueHead;
1021  }
1022 
1023  /* Make sure that we have a valid list */
1024  if (FsList)
1025  {
1026  /* Check if we should insert it at the top or bottom of the list */
1028  {
1029  /* At the bottom */
1030  InsertTailList(FsList->Blink, &DeviceObject->Queue.ListEntry);
1031  }
1032  else
1033  {
1034  /* On top */
1035  InsertHeadList(FsList, &DeviceObject->Queue.ListEntry);
1036  }
1037  }
1038 
1039  /* Update operations counter */
1041 
1042  /* Clear the initializing flag */
1044 
1045  /* Notify file systems of the addition */
1047 
1048  /* Release the FS Lock */
1051 
1052  /* Ensure driver won't be unloaded */
1054 }
1055 
1056 /*
1057  * @implemented
1058  */
1059 VOID
1060 NTAPI
1062 {
1063  PAGED_CODE();
1064 
1065  /* Acquire the FS lock */
1068 
1069  /* Simply remove the entry - if queued */
1070  if (DeviceObject->Queue.ListEntry.Flink)
1071  {
1072  RemoveEntryList(&DeviceObject->Queue.ListEntry);
1073  }
1074 
1075  /* And notify all registered file systems */
1077 
1078  /* Update operations counter */
1080 
1081  /* Then release the lock */
1084 
1085  /* Decrease reference count to allow unload */
1087 }
1088 
1089 /*
1090  * @implemented
1091  */
1092 NTSTATUS
1093 NTAPI
1096 {
1098  PAGED_CODE();
1099 
1100  /* Acquire the list lock */
1103 
1104  /* Check if that driver is already registered (successive calls)
1105  * See MSDN note: http://msdn.microsoft.com/en-us/library/ff548499%28v=vs.85%29.aspx
1106  */
1108  {
1111  FsChangeNotifyList);
1112 
1113  if (Entry->DriverObject == DriverObject &&
1114  Entry->FSDNotificationProc == DriverNotificationRoutine)
1115  {
1116  /* Release the lock */
1118 
1120  }
1121  }
1122 
1123  /* Allocate a notification entry */
1125  sizeof(FS_CHANGE_NOTIFY_ENTRY),
1127  if (!Entry)
1128  {
1129  /* Release the lock */
1131 
1133  }
1134 
1135  /* Save the driver object and notification routine */
1136  Entry->DriverObject = DriverObject;
1137  Entry->FSDNotificationProc = DriverNotificationRoutine;
1138 
1139  /* Insert it into the notification list */
1140  InsertTailList(&IopFsNotifyChangeQueueHead, &Entry->FsChangeNotifyList);
1141 
1142  /* Start notifying all already present FS */
1147 
1148  /* Release the lock */
1151 
1152  /* Reference the driver */
1154  return STATUS_SUCCESS;
1155 }
1156 
1157 /*
1158  * @implemented
1159  */
1160 VOID
1161 NTAPI
1163  IN PDRIVER_FS_NOTIFICATION FSDNotificationProc)
1164 {
1165  PFS_CHANGE_NOTIFY_ENTRY ChangeEntry;
1166  PLIST_ENTRY NextEntry;
1167  PAGED_CODE();
1168 
1169  /* Acquire the list lock */
1172 
1173  /* Loop the list */
1174  NextEntry = IopFsNotifyChangeQueueHead.Flink;
1175  while (NextEntry != &IopFsNotifyChangeQueueHead)
1176  {
1177  /* Get the entry */
1178  ChangeEntry = CONTAINING_RECORD(NextEntry,
1180  FsChangeNotifyList);
1181 
1182  /* Check if it matches this de-registration */
1183  if ((ChangeEntry->DriverObject == DriverObject) &&
1184  (ChangeEntry->FSDNotificationProc == FSDNotificationProc))
1185  {
1186  /* It does, remove it from the list */
1187  RemoveEntryList(&ChangeEntry->FsChangeNotifyList);
1189  break;
1190  }
1191 
1192  /* Go to the next entry */
1193  NextEntry = NextEntry->Flink;
1194  }
1195 
1196  /* Release the lock and dereference the driver */
1199 
1200  /* Dereference the driver */
1202 }
1203 
1204 /*
1205  * @implemented
1206  */
1207 VOID
1208 NTAPI
1210 {
1211  /* Simply acquire the lock */
1213 }
1214 
1215 /*
1216  * @implemented
1217  */
1218 VOID
1219 NTAPI
1221 {
1222  /* Just release the lock */
1224 }
1225 
1226 /*
1227  * @implemented
1228  */
1229 NTSTATUS
1230 NTAPI
1232 {
1233  NTSTATUS Status;
1234  HANDLE RootHandle, KeyHandle;
1235  UNICODE_STRING HKLMSystem, KeyString;
1236  WCHAR Buffer[sizeof(L"SystemPartition") / sizeof(WCHAR)];
1237 
1238  RtlInitUnicodeString(&HKLMSystem, L"\\REGISTRY\\MACHINE\\SYSTEM");
1239 
1240  /* Open registry to save data (HKLM\SYSTEM) */
1241  Status = IopOpenRegistryKeyEx(&RootHandle, 0, &HKLMSystem, KEY_ALL_ACCESS);
1242  if (!NT_SUCCESS(Status))
1243  {
1244  return Status;
1245  }
1246 
1247  /* Create or open Setup subkey */
1248  KeyString.Buffer = Buffer;
1249  KeyString.Length = sizeof(L"Setup") - sizeof(UNICODE_NULL);
1250  KeyString.MaximumLength = sizeof(L"Setup");
1251  RtlCopyMemory(Buffer, L"Setup", sizeof(L"Setup"));
1253  RootHandle,
1254  &KeyString,
1257  NULL);
1258  ZwClose(RootHandle);
1259  if (!NT_SUCCESS(Status))
1260  {
1261  return Status;
1262  }
1263 
1264  /* Store caller value */
1265  KeyString.Length = sizeof(L"SystemPartition") - sizeof(UNICODE_NULL);
1266  KeyString.MaximumLength = sizeof(L"SystemPartition");
1267  RtlCopyMemory(Buffer, L"SystemPartition", sizeof(L"SystemPartition"));
1268  Status = ZwSetValueKey(KeyHandle,
1269  &KeyString,
1270  0,
1271  REG_SZ,
1272  VolumeNameString->Buffer,
1273  VolumeNameString->Length + sizeof(UNICODE_NULL));
1274  ZwClose(KeyHandle);
1275 
1276  return Status;
1277 }
1278 
1279 /*
1280  * @implemented
1281  */
1282 NTSTATUS
1283 NTAPI
1284 IoVolumeDeviceToDosName(IN PVOID VolumeDeviceObject,
1286 {
1287  PIRP Irp;
1288  ULONG Length;
1289  KEVENT Event;
1290  NTSTATUS Status;
1294  UNICODE_STRING MountMgrDevice;
1295  MOUNTMGR_VOLUME_PATHS VolumePath;
1296  PMOUNTMGR_VOLUME_PATHS VolumePathPtr;
1297  /*
1298  * This variable with be required to query device name.
1299  * It's based on MOUNTDEV_NAME (mountmgr.h).
1300  * Doing it that way will prevent dyn memory allocation.
1301  * Device name won't be longer.
1302  */
1303  struct
1304  {
1305  USHORT NameLength;
1306  WCHAR DeviceName[256];
1307  } DeviceName;
1308 
1309  PAGED_CODE();
1310 
1311  /* First step, getting device name */
1314  VolumeDeviceObject, NULL, 0,
1315  &DeviceName, sizeof(DeviceName),
1316  FALSE, &Event, &IoStatusBlock);
1317  if (!Irp)
1318  {
1320  }
1321 
1322  Status = IoCallDriver(VolumeDeviceObject, Irp);
1323  if (Status == STATUS_PENDING)
1324  {
1327  }
1328 
1329  if (!NT_SUCCESS(Status))
1330  {
1331  return Status;
1332  }
1333 
1334  /* Now that we have the device name, we can query the MountMgr
1335  * So, get its device object first.
1336  */
1337  RtlInitUnicodeString(&MountMgrDevice, MOUNTMGR_DEVICE_NAME);
1340  if (!NT_SUCCESS(Status))
1341  {
1342  return Status;
1343  }
1344 
1345  /* Then, use the proper IOCTL to query the DOS name */
1348  DeviceObject, &DeviceName, sizeof(DeviceName),
1349  &VolumePath, sizeof(VolumePath),
1350  FALSE, &Event, &IoStatusBlock);
1351  if (!Irp)
1352  {
1354  goto DereferenceFO;
1355  }
1356 
1358  if (Status == STATUS_PENDING)
1359  {
1362  }
1363 
1364  /* Only tolerated failure here is buffer too small, which is
1365  * expected.
1366  */
1368  {
1369  goto DereferenceFO;
1370  }
1371 
1372  /* Compute needed size to store DOS name.
1373  * Even if MOUNTMGR_VOLUME_PATHS allows bigger
1374  * name lengths than MAXUSHORT, we can't use
1375  * them, because we have to return this in an UNICODE_STRING
1376  * that stores length on USHORT.
1377  */
1378  Length = VolumePath.MultiSzLength + sizeof(VolumePath);
1379  if (Length > MAXUSHORT)
1380  {
1382  goto DereferenceFO;
1383  }
1384 
1385  /* Reallocate memory, even in case of success, because
1386  * that's the buffer that will be returned to caller
1387  */
1388  VolumePathPtr = ExAllocatePoolWithTag(PagedPool, Length, 'D2d ');
1389  if (!VolumePathPtr)
1390  {
1392  goto DereferenceFO;
1393  }
1394 
1395  /* Requery DOS path with proper size */
1398  DeviceObject, &DeviceName, sizeof(DeviceName),
1399  VolumePathPtr, Length,
1400  FALSE, &Event, &IoStatusBlock);
1401  if (!Irp)
1402  {
1404  goto ReleaseMemory;
1405  }
1406 
1408  if (Status == STATUS_PENDING)
1409  {
1412  }
1413 
1414  if (!NT_SUCCESS(Status))
1415  {
1416  goto ReleaseMemory;
1417  }
1418 
1419  /* Set output string */
1420  DosName->Length = (USHORT)VolumePathPtr->MultiSzLength;
1421  DosName->MaximumLength = (USHORT)VolumePathPtr->MultiSzLength + sizeof(UNICODE_NULL);
1422  /* Our MOUNTMGR_VOLUME_PATHS will be used as output buffer */
1423  DosName->Buffer = (PWSTR)VolumePathPtr;
1424  /* Move name at the begin, RtlMoveMemory is OK with overlapping */
1425  RtlMoveMemory(DosName->Buffer, VolumePathPtr->MultiSz, VolumePathPtr->MultiSzLength);
1426  DosName->Buffer[DosName->Length / sizeof(WCHAR)] = UNICODE_NULL;
1427 
1428  /* DON'T release buffer, just dereference FO, and return success */
1430  goto DereferenceFO;
1431 
1433  ExFreePoolWithTag(VolumePathPtr, 'D2d ');
1434 
1435 DereferenceFO:
1437 
1438  return Status;
1439 }
1440 
1441 /* EOF */
VOID NTAPI IopLoadFileSystemDriver(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:414
#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:191
#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:4711
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:163
_In_ PIRP Irp
Definition: csq.h:116
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
BOOLEAN NTAPI IopReferenceVerifyVpb(IN PDEVICE_OBJECT DeviceObject, OUT PDEVICE_OBJECT *FileSystemObject, OUT PVPB *Vpb)
Definition: volume.c:221
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
VOID NTAPI IoUnregisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:1061
#define KeGetPreviousMode()
Definition: ketypes.h:1107
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2769
#define TAG_FS_CHANGE_NOTIFY
Definition: tag.h:51
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI IopDereferenceDeviceObject(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN ForceUnload)
Definition: device.c:462
ActualNumberDriverObjects _In_ ULONG DriverObjectListSize
Definition: iofuncs.h:2281
NTSTATUS NTAPI IopMountVolume(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount, IN BOOLEAN DeviceIsLocked, IN BOOLEAN Alertable, OUT PVPB *Vpb)
Definition: volume.c:467
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define IRP_MN_LOAD_FILE_SYSTEM
Definition: iotypes.h:4050
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1209
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
PVPB Vpb
Definition: cdstruc.h:517
#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:1766
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 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:290
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:64
uint32_t ULONG_PTR
Definition: typedefs.h:63
NTSTATUS NTAPI IoEnumerateRegisteredFiltersList(OUT PDRIVER_OBJECT *DriverObjectList, IN ULONG DriverObjectListSize, OUT PULONG ActualNumberDriverObjects)
Definition: volume.c:826
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:1284
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:4049
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 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:336
#define VPB_LOCKED
Definition: iotypes.h:1765
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
unsigned char BOOLEAN
#define DO_SYSTEM_BOOT_PARTITION
Definition: env_spec_w32.h:400
smooth NULL
Definition: ftsmooth.c:416
#define FORCEINLINE
Definition: ntbasedef.h:221
_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
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:1231
#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:4048
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
ULONG FASTCALL IopInterlockedIncrementUlong(IN KSPIN_LOCK_QUEUE_NUMBER Queue, IN PULONG Ulong)
Definition: volume.c:318
PDRIVER_OBJECT DriverObject
Definition: io.h:459
#define DOE_UNLOAD_PENDING
Definition: iotypes.h:149
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
VOID NTAPI IopShutdownBaseFileSystems(IN PLIST_ENTRY ListHead)
Definition: volume.c:354
#define IRP_MJ_FILE_SYSTEM_CONTROL
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
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
#define SL_ALLOW_RAW_MOUNT
Definition: iotypes.h:1798
* PFILE_OBJECT
Definition: iotypes.h:1955
VOID NTAPI IoUnregisterFsRegistrationChange(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_FS_NOTIFICATION FSDNotificationProc)
Definition: volume.c:1162
ERESOURCE IopDatabaseResource
Definition: volume.c:25
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#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:1250
_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:460
__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:1768
#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:390
enum _KSPIN_LOCK_QUEUE_NUMBER KSPIN_LOCK_QUEUE_NUMBER
PVPB NTAPI IopMountInitializeVpb(IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT AttachedDeviceObject, IN BOOLEAN Raw)
Definition: volume.c:254
#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:3688
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
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:1385
VOID NTAPI IopNotifyAlreadyRegisteredFileSystems(IN PLIST_ENTRY ListHead, IN PDRIVER_FS_NOTIFICATION DriverNotificationRoutine, BOOLEAN SkipRawFs)
Definition: volume.c:790
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
VOID NTAPI IoRegisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:992
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
ULONG ERESOURCE
Definition: env_spec_w32.h:594
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
LIST_ENTRY FsChangeNotifyList
Definition: io.h:458
Definition: sacdrv.h:278
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
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
unsigned long Ulong
Definition: utypes.h:42
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define IoGetDevObjExtension(DeviceObject)
Definition: io.h:125
#define VPB_MOUNTED
Definition: iotypes.h:1764
NTSTATUS NTAPI IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount)
Definition: volume.c:882
LIST_ENTRY IopNetworkFileSystemQueueHead
Definition: volume.c:26
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1220
NTSTATUS NTAPI IoRegisterFsRegistrationChange(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_FS_NOTIFICATION DriverNotificationRoutine)
Definition: volume.c:1094
NTSTATUS NTAPI ReleaseMemory(IN PDEVICE_OBJECT DeviceObject)
Definition: fbtpnp.c:1790
base of all file and directory entries
Definition: entries.h:82
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:107
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:7005
#define IRP_SYNCHRONOUS_PAGING_IO
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
Definition: io.h:456
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:806
#define REG_SZ
Definition: layer.c:22