ReactOS  0.4.15-dev-1636-gf634010
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 /* GLOBALS ******************************************************************/
19 
25 
26 /* PRIVATE FUNCTIONS *********************************************************/
27 
28 /*
29  * @halfplemented
30  */
31 VOID
32 NTAPI
34  IN BOOLEAN UnloadIfUnused)
35 {
36  KIRQL OldIrql;
37 
38  /* Acquire lock */
40  ASSERT(DeviceObject->ReferenceCount > 0);
41 
42  if (--DeviceObject->ReferenceCount > 0)
43  {
45  return;
46  }
47 
48  /* Release lock */
50 
51  /* Here, DO is not referenced any longer, check if we have to unload it */
52  if (UnloadIfUnused || IoGetDevObjExtension(DeviceObject)->ExtensionFlags &
54  {
55  /* Unload the driver */
57  }
58 }
59 
60 /*
61  * @implemented
62  */
63 VOID
64 NTAPI
66 {
67  /* Just decrease reference count */
69 }
70 
71 /*
72  * @implemented
73  */
74 PVPB
75 NTAPI
80 {
82  KIRQL OldIrql;
83  PVPB Vpb = NULL;
84 
85  /* Lock the VPBs */
87 
88  /* Set VPB mount settings */
89  Raw = !RemainingName->Length && !OpenPacket->RelatedFileObject;
90  Alertable = (OpenPacket->CreateOptions & FILE_SYNCHRONOUS_IO_ALERT) ?
91  TRUE: FALSE;
92 
93  /* Start looping until the VPB is mounted */
94  while (!(DeviceObject->Vpb->Flags & VPB_MOUNTED))
95  {
96  /* Release the lock */
98 
99  /* Mount the volume */
101  Raw,
102  FALSE,
103  Alertable,
104  &Vpb);
105 
106  /* Check if we failed or if we were alerted */
107  if (!(NT_SUCCESS(*Status)) ||
108  (*Status == STATUS_USER_APC) ||
109  (*Status == STATUS_ALERTED))
110  {
111  /* Dereference the device, since IopParseDevice referenced it */
113 
114  /* Check if it was a total failure */
115  if (!NT_SUCCESS(*Status)) return NULL;
116 
117  /* Otherwise we were alerted */
119  return NULL;
120  }
121  /*
122  * In case IopMountVolume returns a valid VPB
123  * Then, the volume is mounted, return it
124  */
125  else if (Vpb != NULL)
126  {
127  return Vpb;
128  }
129 
130  /* Re-acquire the lock */
132  }
133 
134  /* Make sure the VPB isn't locked */
135  Vpb = DeviceObject->Vpb;
136  if (Vpb->Flags & VPB_LOCKED)
137  {
138  /* We're locked, so fail */
140  Vpb = NULL;
141  }
142  else
143  {
144  /* Success! Reference the VPB */
145  Vpb->ReferenceCount++;
146  }
147 
148  /* Release the lock and return the VPB */
150  return Vpb;
151 }
152 
153 /*
154  * @implemented
155  */
156 NTSTATUS
157 NTAPI
159 {
160  PVPB Vpb;
161 
162  /* Allocate the Vpb */
164  sizeof(VPB),
165  TAG_VPB);
166  if (!Vpb) return STATUS_INSUFFICIENT_RESOURCES;
167 
168  /* Clear it so we don't waste time manually */
169  RtlZeroMemory(Vpb, sizeof(VPB));
170 
171  /* Set the Header and Device Field */
172  Vpb->Type = IO_TYPE_VPB;
173  Vpb->Size = sizeof(VPB);
174  Vpb->RealDevice = DeviceObject;
175 
176  /* Link it to the Device Object */
177  DeviceObject->Vpb = Vpb;
178  return STATUS_SUCCESS;
179 }
180 
181 /*
182  * @implemented
183  */
184 VOID
185 NTAPI
187 {
188  KIRQL OldIrql;
189 
190  /* Lock the VPBs and decrease references */
192  Vpb->ReferenceCount--;
193 
194  /* Check if we're out of references */
195  if (!Vpb->ReferenceCount && Vpb->RealDevice->Vpb == Vpb &&
196  !(Vpb->Flags & VPB_PERSISTENT))
197  {
198  /* Release VPB lock */
200 
201  /* And free VPB */
203  }
204  else
205  {
206  /* Release VPB lock */
208  }
209 }
210 
211 /*
212  * @implemented
213  */
214 BOOLEAN
215 NTAPI
217  OUT PDEVICE_OBJECT *FileSystemObject,
218  OUT PVPB *Vpb)
219 {
220  KIRQL OldIrql;
221  PVPB LocalVpb;
222  BOOLEAN Result = FALSE;
223 
224  /* Lock the VPBs and assume failure */
226  *Vpb = NULL;
227  *FileSystemObject = NULL;
228 
229  /* Get the VPB and make sure it's mounted */
230  LocalVpb = DeviceObject->Vpb;
231  if ((LocalVpb) && (LocalVpb->Flags & VPB_MOUNTED))
232  {
233  /* Return it */
234  *Vpb = LocalVpb;
235  *FileSystemObject = LocalVpb->DeviceObject;
236 
237  /* Reference it */
238  LocalVpb->ReferenceCount++;
239  Result = TRUE;
240  }
241 
242  /* Release the VPB lock and return status */
244  return Result;
245 }
246 
247 PVPB
248 NTAPI
251  IN BOOLEAN Raw)
252 {
253  KIRQL OldIrql;
254  PVPB Vpb;
255 
256  /* Lock the VPBs */
258  Vpb = DeviceObject->Vpb;
259 
260  /* Set the VPB as mounted and possibly raw */
261  Vpb->Flags |= VPB_MOUNTED | (Raw ? VPB_RAW_MOUNT : 0);
262 
263  /* Set the stack size */
264  Vpb->DeviceObject->StackSize = AttachedDeviceObject->StackSize;
265 
266  /* Add one for the FS Driver */
267  Vpb->DeviceObject->StackSize++;
268 
269  /* Set the VPB in the device extension */
270  IoGetDevObjExtension(Vpb->DeviceObject)->Vpb = Vpb;
271 
272  /* Reference it */
273  Vpb->ReferenceCount++;
274 
275  /* Release the VPB lock and return it */
277  return Vpb;
278 }
279 
280 /*
281  * @implemented
282  */
284 VOID
286  IN BOOLEAN DriverActive)
287 {
288  PFS_CHANGE_NOTIFY_ENTRY ChangeEntry;
289  PLIST_ENTRY ListEntry;
290 
291  /* Loop the list */
292  ListEntry = IopFsNotifyChangeQueueHead.Flink;
293  while (ListEntry != &IopFsNotifyChangeQueueHead)
294  {
295  /* Get the entry */
296  ChangeEntry = CONTAINING_RECORD(ListEntry,
298  FsChangeNotifyList);
299 
300  /* Call the notification procedure */
301  ChangeEntry->FSDNotificationProc(DeviceObject, DriverActive);
302 
303  /* Go to the next entry */
304  ListEntry = ListEntry->Flink;
305  }
306 }
307 
308 /*
309  * @implemented
310  */
311 ULONG
312 FASTCALL
314  IN PULONG Ulong)
315 {
316  KIRQL Irql;
317  ULONG OldValue;
318 
320  OldValue = (*Ulong)++;
322 
323  return OldValue;
324 }
325 
326 /*
327  * @implemented
328  */
329 ULONG
330 FASTCALL
332  IN PULONG Ulong)
333 {
334  KIRQL Irql;
335  ULONG OldValue;
336 
338  OldValue = (*Ulong)--;
340 
341  return OldValue;
342 }
343 
344 /*
345  * @implemented
346  */
347 VOID
348 NTAPI
350 {
351  PLIST_ENTRY ListEntry;
353  IO_STATUS_BLOCK StatusBlock;
354  PIRP Irp;
355  KEVENT Event;
357 
359 
360  /* Get the first entry and start looping */
361  ListEntry = ListHead->Flink;
362  while (ListEntry != ListHead)
363  {
364  /* Get the device object */
365  DeviceObject = CONTAINING_RECORD(ListEntry,
367  Queue.ListEntry);
368 
369  /* Go to the next entry */
370  ListEntry = ListEntry->Flink;
371 
372  /* Get the attached device */
374 
377 
378  /* Build the shutdown IRP and call the driver */
380  DeviceObject,
381  NULL,
382  0,
383  NULL,
384  &Event,
385  &StatusBlock);
386  if (Irp)
387  {
389  if (Status == STATUS_PENDING)
390  {
391  /* Wait on the driver */
393  }
394  }
395 
396  /* Reset the event */
398 
401  }
402 }
403 
404 /*
405  * @implemented
406  */
407 VOID
408 NTAPI
410 {
412  PIO_STACK_LOCATION StackPtr;
413  KEVENT Event;
414  PIRP Irp;
417  PAGED_CODE();
418 
419  /* Loop as long as we're attached */
420  while (AttachedDeviceObject->AttachedDevice)
421  {
422  /* Get the attached device object */
423  AttachedDeviceObject = AttachedDeviceObject->AttachedDevice;
424  }
425 
426  /* Initialize the event and build the IRP */
430  NULL,
431  0,
432  NULL,
433  0,
434  FALSE,
435  &Event,
436  &IoStatusBlock);
437  if (Irp)
438  {
439  /* Set the major and minor functions */
440  StackPtr = IoGetNextIrpStackLocation(Irp);
443 
444  /* Call the driver */
446  if (Status == STATUS_PENDING)
447  {
448  /* Wait on it */
450  }
451  }
452 
453  /* Dereference DO - FsRec? - Comment out call, since it breaks up 2nd stage boot, needs more research. */
454 // IopDecrementDeviceObjectRef(AttachedDeviceObject, TRUE);
455 }
456 
457 /*
458  * @implemented
459  */
460 NTSTATUS
461 NTAPI
463  IN BOOLEAN AllowRawMount,
464  IN BOOLEAN DeviceIsLocked,
466  OUT PVPB *Vpb)
467 {
468  KEVENT Event;
471  PIRP Irp;
472  PIO_STACK_LOCATION StackPtr;
473  PLIST_ENTRY FsList, ListEntry;
474  LIST_ENTRY LocalList;
476  PDEVICE_OBJECT FileSystemDeviceObject, ParentFsDeviceObject;
477  ULONG FsStackOverhead, RegistrationOps;
478  PAGED_CODE();
479 
480  /* Check if the device isn't already locked */
481  if (!DeviceIsLocked)
482  {
483  /* Lock it ourselves */
485  Executive,
487  Alertable,
488  NULL);
489  if ((Status == STATUS_ALERTED) || (Status == STATUS_USER_APC))
490  {
491  /* Don't mount if we were interrupted */
492  return Status;
493  }
494  }
495 
496  /* Acquire the FS Lock*/
499 
500  /* Make sure we weren't already mounted */
501  if (!(DeviceObject->Vpb->Flags & (VPB_MOUNTED | VPB_REMOVE_PENDING)))
502  {
503  /* Initialize the event to wait on */
505 
506  /* Remove the verify flag and get the actual device to mount */
507  DeviceObject->Flags &= ~DO_VERIFY_VOLUME;
508  while (AttachedDeviceObject->AttachedDevice)
509  {
510  /* Get the next one */
511  AttachedDeviceObject = AttachedDeviceObject->AttachedDevice;
512  }
513 
514  /* Reference it */
516 
517  /* For a mount operation, this can only be a Disk, CD-ROM or tape */
518  if ((DeviceObject->DeviceType == FILE_DEVICE_DISK) ||
519  (DeviceObject->DeviceType == FILE_DEVICE_VIRTUAL_DISK))
520  {
521  /* Use the disk list */
522  FsList = &IopDiskFileSystemQueueHead;
523  }
524  else if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM)
525  {
526  /* Use the CD-ROM list */
527  FsList = &IopCdRomFileSystemQueueHead;
528  }
529  else
530  {
531  /* It's gotta be a tape... */
532  FsList = &IopTapeFileSystemQueueHead;
533  }
534 
535  /* Now loop the fs list until one of the file systems accepts us */
537  ListEntry = FsList->Flink;
538  while ((ListEntry != FsList) && !(NT_SUCCESS(Status)))
539  {
540  /*
541  * If we're not allowed to mount this volume and this is our last
542  * (but not only) chance to mount it...
543  */
544  if (!(AllowRawMount) &&
545  (ListEntry->Flink == FsList) &&
546  (ListEntry != FsList->Flink))
547  {
548  /* Then fail this mount request */
549  break;
550  }
551 
552  /*
553  * Also check if this is a raw mount and there are other file
554  * systems on the list.
555  */
556  if ((DeviceObject->Vpb->Flags & VPB_RAW_MOUNT) &&
557  (ListEntry->Flink != FsList))
558  {
559  /* Then skip this entry */
560  ListEntry = ListEntry->Flink;
561  continue;
562  }
563 
564  /* Get the Device Object for this FS */
565  FileSystemDeviceObject = CONTAINING_RECORD(ListEntry,
567  Queue.ListEntry);
568  ParentFsDeviceObject = FileSystemDeviceObject;
569 
570  /*
571  * If this file system device is attached to some other device,
572  * then we must make sure to increase the stack size for the IRP.
573  * The default is +1, for the FS device itself.
574  */
575  FsStackOverhead = 1;
576  while (FileSystemDeviceObject->AttachedDevice)
577  {
578  /* Get the next attached device and increase overhead */
579  FileSystemDeviceObject = FileSystemDeviceObject->
580  AttachedDevice;
581  FsStackOverhead++;
582  }
583 
584  /* Clear the event */
586 
587  /* Allocate the IRP */
588  Irp = IoAllocateIrp(AttachedDeviceObject->StackSize +
589  (UCHAR)FsStackOverhead,
590  TRUE);
591  if (!Irp)
592  {
593  /* Fail */
595  break;
596  }
597 
598  /* Setup the IRP */
599  Irp->UserIosb = &IoStatusBlock;
600  Irp->UserEvent = &Event;
601  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
603  Irp->RequestorMode = KernelMode;
604 
605  /* Get the I/O Stack location and set it up */
606  StackPtr = IoGetNextIrpStackLocation(Irp);
609  StackPtr->Flags = AllowRawMount;
610  StackPtr->Parameters.MountVolume.Vpb = DeviceObject->Vpb;
611  StackPtr->Parameters.MountVolume.DeviceObject =
613 
614  /* Save registration operations */
615  RegistrationOps = IopFsRegistrationOps;
616 
617  /* Release locks */
620 
621  /* Call the driver */
622  Status = IoCallDriver(FileSystemDeviceObject, Irp);
623  if (Status == STATUS_PENDING)
624  {
625  /* Wait on it */
627  Executive,
628  KernelMode,
629  FALSE,
630  NULL);
632  }
633 
636 
637  /* Check if mounting was successful */
638  if (NT_SUCCESS(Status))
639  {
640  /* Mount the VPB */
643  (DeviceObject->Vpb->Flags &
644  VPB_RAW_MOUNT));
645  }
646  else
647  {
648  /* Check if we failed because of the user */
649  if ((IoIsErrorUserInduced(Status)) &&
650  (IoStatusBlock.Information == 1))
651  {
652  /* Break out and fail */
653  break;
654  }
655 
656  /* If there were registration operations in the meanwhile */
657  if (RegistrationOps != IopFsRegistrationOps)
658  {
659  /* We need to setup a local list to pickup where we left */
660  LocalList.Flink = FsList->Flink;
661  ListEntry = &LocalList;
662 
664  }
665 
666  /* Otherwise, check if we need to load the FS driver */
668  {
669  /* We need to release the lock */
672 
673  /* Release the device lock if we're holding it */
674  if (!DeviceIsLocked)
675  {
676  KeSetEvent(&DeviceObject->DeviceLock, 0, FALSE);
677  }
678 
679  /* Leave critical section */
681 
682  /* Load the FS */
683  IopLoadFileSystemDriver(ParentFsDeviceObject);
684 
685  /* Check if the device isn't already locked */
686  if (!DeviceIsLocked)
687  {
688  /* Lock it ourselves */
690  DeviceLock,
691  Executive,
693  Alertable,
694  NULL);
695  if ((Status == STATUS_ALERTED) ||
696  (Status == STATUS_USER_APC))
697  {
698  /* Don't mount if we were interrupted */
700  return Status;
701  }
702  }
703 
704  /* Reacquire the lock */
707 
708  /* When we released the lock, make sure nobody beat us */
709  if (DeviceObject->Vpb->Flags & VPB_MOUNTED)
710  {
711  /* Someone did, break out */
713  break;
714  }
715 
716  /* Start over by setting a failure */
718 
719  /* We need to setup a local list to pickup where we left */
720  LocalList.Flink = FsList->Flink;
721  ListEntry = &LocalList;
722  }
723 
724  /*
725  * Check if we failed with any other error then an unrecognized
726  * volume, and if this request doesn't allow mounting the raw
727  * file system.
728  */
729  if (!(AllowRawMount) &&
732  {
733  /* Break out and give up */
734  break;
735  }
736  }
737 
738  /* Go to the next FS entry */
739  ListEntry = ListEntry->Flink;
740  }
741 
742  /* Dereference the device if we failed */
744  }
745  else if (DeviceObject->Vpb->Flags & VPB_REMOVE_PENDING)
746  {
747  /* Someone wants to remove us */
749  }
750  else
751  {
752  /* Someone already mounted us */
754  }
755 
756  /* Release the FS lock */
759 
760  /* Release the device lock if we're holding it */
761  if (!DeviceIsLocked) KeSetEvent(&DeviceObject->DeviceLock, 0, FALSE);
762 
763  /* Check if we failed to mount the boot partition */
764  if ((!NT_SUCCESS(Status)) &&
767  {
768  /* Bugcheck the system */
769  KeBugCheckEx(INACCESSIBLE_BOOT_DEVICE,
771  Status,
772  0,
773  0);
774  }
775 
776  /* Return the mount status */
777  return Status;
778 }
779 
780 /*
781  * @implemented
782  */
783 VOID
784 NTAPI
787  BOOLEAN SkipRawFs)
788 {
789  PLIST_ENTRY ListEntry;
791 
792  /* Browse the whole list */
793  ListEntry = ListHead->Flink;
794  while (ListEntry != ListHead)
795  {
796  /* Check if we reached rawfs and if we have to skip it */
797  if (ListEntry->Flink == ListHead && SkipRawFs)
798  {
799  return;
800  }
801 
802  /* Otherwise, get DO and notify */
803  DeviceObject = CONTAINING_RECORD(ListEntry,
805  Queue.ListEntry);
806 
808 
809  /* Go to the next entry */
810  ListEntry = ListEntry->Flink;
811  }
812 }
813 
814 /* PUBLIC FUNCTIONS **********************************************************/
815 
816 /*
817  * @implemented
818  */
819 NTSTATUS
820 NTAPI
824 {
825  PLIST_ENTRY ListEntry;
827  PFS_CHANGE_NOTIFY_ENTRY ChangeEntry;
828  ULONG ListSize = 0, MaximumSize = DriverObjectListSize / sizeof(PDRIVER_OBJECT);
829 
830  /* Acquire the FS lock */
833 
834  /* Browse the whole list */
835  ListEntry = IopFsNotifyChangeQueueHead.Flink;
836  while (ListEntry != &IopFsNotifyChangeQueueHead)
837  {
838  ChangeEntry = CONTAINING_RECORD(ListEntry,
840  FsChangeNotifyList);
841 
842  /* If buffer is still big enough */
843  if (ListSize < MaximumSize)
844  {
845  /* Reference the driver object */
846  ObReferenceObject(ChangeEntry->DriverObject);
847  /* And pass it to the caller */
848  DriverObjectList[ListSize] = ChangeEntry->DriverObject;
849  }
850  else
851  {
853  }
854 
855  /* Increase size counter */
856  ListSize++;
857 
858  /* Go to the next entry */
859  ListEntry = ListEntry->Flink;
860  }
861 
862  /* Return list size */
863  *ActualNumberDriverObjects = ListSize;
864 
865  /* Release the FS lock */
868 
869  return Status;
870 }
871 
872 /*
873  * @implemented
874  */
875 NTSTATUS
876 NTAPI
878  IN BOOLEAN AllowRawMount)
879 {
881  PIO_STACK_LOCATION StackPtr;
882  KEVENT Event;
883  PIRP Irp;
884  NTSTATUS Status, VpbStatus;
885  PDEVICE_OBJECT FileSystemDeviceObject;
886  PVPB Vpb, NewVpb;
887  //BOOLEAN WasNotMounted = TRUE;
888 
889  /* Wait on the device lock */
891  Executive,
892  KernelMode,
893  FALSE,
894  NULL);
896 
897  /* Reference the VPB */
898  if (IopReferenceVerifyVpb(DeviceObject, &FileSystemDeviceObject, &Vpb))
899  {
900  /* Initialize the event */
902 
903  /* Find the actual File System DO */
904  //WasNotMounted = FALSE;
905  FileSystemDeviceObject = DeviceObject->Vpb->DeviceObject;
906  while (FileSystemDeviceObject->AttachedDevice)
907  {
908  /* Go to the next one */
909  FileSystemDeviceObject = FileSystemDeviceObject->AttachedDevice;
910  }
911 
912  /* Allocate the IRP */
913  Irp = IoAllocateIrp(FileSystemDeviceObject->StackSize, FALSE);
914  if (!Irp)
915  {
917  goto Release;
918  }
919 
920  /* Set it up */
921  Irp->UserIosb = &IoStatusBlock;
922  Irp->UserEvent = &Event;
923  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
925  Irp->RequestorMode = KernelMode;
926 
927  /* Get the I/O Stack location and set it */
928  StackPtr = IoGetNextIrpStackLocation(Irp);
931  StackPtr->Flags = AllowRawMount ? SL_ALLOW_RAW_MOUNT : 0;
932  StackPtr->Parameters.VerifyVolume.Vpb = Vpb;
933  StackPtr->Parameters.VerifyVolume.DeviceObject =
934  DeviceObject->Vpb->DeviceObject;
935 
936  /* Call the driver */
937  Status = IoCallDriver(FileSystemDeviceObject, Irp);
938  if (Status == STATUS_PENDING)
939  {
940  /* Wait on it */
943  }
944 
945  /* Dereference the VPB */
947  }
948 
949  /* Check if we had the wrong volume or didn't mount at all */
951  {
952  /* Create a VPB */
953  VpbStatus = IopCreateVpb(DeviceObject);
954  if (NT_SUCCESS(VpbStatus))
955  {
957 
958  /* Mount it */
959  VpbStatus = IopMountVolume(DeviceObject,
960  AllowRawMount,
961  TRUE,
962  FALSE,
963  &NewVpb);
964 
965  /* If we got a new VPB, dereference it */
966  if (NewVpb)
967  {
969  }
970  }
971 
972  /* If we failed, remove the verify flag */
973  if (!NT_SUCCESS(VpbStatus)) DeviceObject->Flags &= ~DO_VERIFY_VOLUME;
974  }
975 
976 Release:
977  /* Signal the device lock and return */
979  return Status;
980 }
981 
982 /*
983  * @implemented
984  */
985 VOID
986 NTAPI
988 {
989  PLIST_ENTRY FsList = NULL;
990  PAGED_CODE();
991 
992  /* Acquire the FS lock */
995 
996  /* Check what kind of FS this is */
997  if (DeviceObject->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM)
998  {
999  /* Use the disk list */
1000  FsList = &IopDiskFileSystemQueueHead;
1001  }
1002  else if (DeviceObject->DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM)
1003  {
1004  /* Use the network device list */
1006  }
1007  else if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM)
1008  {
1009  /* Use the CD-ROM list */
1010  FsList = &IopCdRomFileSystemQueueHead;
1011  }
1012  else if (DeviceObject->DeviceType == FILE_DEVICE_TAPE_FILE_SYSTEM)
1013  {
1014  /* Use the tape list */
1015  FsList = &IopTapeFileSystemQueueHead;
1016  }
1017 
1018  /* Make sure that we have a valid list */
1019  if (FsList)
1020  {
1021  /* Check if we should insert it at the top or bottom of the list */
1023  {
1024  /* At the bottom */
1025  InsertTailList(FsList->Blink, &DeviceObject->Queue.ListEntry);
1026  }
1027  else
1028  {
1029  /* On top */
1030  InsertHeadList(FsList, &DeviceObject->Queue.ListEntry);
1031  }
1032  }
1033 
1034  /* Update operations counter */
1036 
1037  /* Clear the initializing flag */
1039 
1040  /* Notify file systems of the addition */
1042 
1043  /* Release the FS Lock */
1046 
1047  /* Ensure driver won't be unloaded */
1049 }
1050 
1051 /*
1052  * @implemented
1053  */
1054 VOID
1055 NTAPI
1057 {
1058  PAGED_CODE();
1059 
1060  /* Acquire the FS lock */
1063 
1064  /* Simply remove the entry - if queued */
1065  if (DeviceObject->Queue.ListEntry.Flink)
1066  {
1067  RemoveEntryList(&DeviceObject->Queue.ListEntry);
1068  }
1069 
1070  /* And notify all registered file systems */
1072 
1073  /* Update operations counter */
1075 
1076  /* Then release the lock */
1079 
1080  /* Decrease reference count to allow unload */
1082 }
1083 
1084 /*
1085  * @implemented
1086  */
1087 NTSTATUS
1088 NTAPI
1091 {
1093  PAGED_CODE();
1094 
1095  /* Acquire the list lock */
1098 
1099  /* Check if that driver is already registered (successive calls)
1100  * See MSDN note: http://msdn.microsoft.com/en-us/library/ff548499%28v=vs.85%29.aspx
1101  */
1103  {
1106  FsChangeNotifyList);
1107 
1108  if (Entry->DriverObject == DriverObject &&
1109  Entry->FSDNotificationProc == DriverNotificationRoutine)
1110  {
1111  /* Release the lock */
1113 
1115  }
1116  }
1117 
1118  /* Allocate a notification entry */
1120  sizeof(FS_CHANGE_NOTIFY_ENTRY),
1122  if (!Entry)
1123  {
1124  /* Release the lock */
1126 
1128  }
1129 
1130  /* Save the driver object and notification routine */
1131  Entry->DriverObject = DriverObject;
1132  Entry->FSDNotificationProc = DriverNotificationRoutine;
1133 
1134  /* Insert it into the notification list */
1135  InsertTailList(&IopFsNotifyChangeQueueHead, &Entry->FsChangeNotifyList);
1136 
1137  /* Start notifying all already present FS */
1142 
1143  /* Release the lock */
1146 
1147  /* Reference the driver */
1149  return STATUS_SUCCESS;
1150 }
1151 
1152 /*
1153  * @implemented
1154  */
1155 VOID
1156 NTAPI
1158  IN PDRIVER_FS_NOTIFICATION FSDNotificationProc)
1159 {
1160  PFS_CHANGE_NOTIFY_ENTRY ChangeEntry;
1161  PLIST_ENTRY NextEntry;
1162  PAGED_CODE();
1163 
1164  /* Acquire the list lock */
1167 
1168  /* Loop the list */
1169  NextEntry = IopFsNotifyChangeQueueHead.Flink;
1170  while (NextEntry != &IopFsNotifyChangeQueueHead)
1171  {
1172  /* Get the entry */
1173  ChangeEntry = CONTAINING_RECORD(NextEntry,
1175  FsChangeNotifyList);
1176 
1177  /* Check if it matches this de-registration */
1178  if ((ChangeEntry->DriverObject == DriverObject) &&
1179  (ChangeEntry->FSDNotificationProc == FSDNotificationProc))
1180  {
1181  /* It does, remove it from the list */
1182  RemoveEntryList(&ChangeEntry->FsChangeNotifyList);
1184  break;
1185  }
1186 
1187  /* Go to the next entry */
1188  NextEntry = NextEntry->Flink;
1189  }
1190 
1191  /* Release the lock and dereference the driver */
1194 
1195  /* Dereference the driver */
1197 }
1198 
1199 /*
1200  * @implemented
1201  */
1202 VOID
1203 NTAPI
1205 {
1206  /* Simply acquire the lock */
1208 }
1209 
1210 /*
1211  * @implemented
1212  */
1213 VOID
1214 NTAPI
1216 {
1217  /* Just release the lock */
1219 }
1220 
1221 /*
1222  * @implemented
1223  */
1224 NTSTATUS
1225 NTAPI
1227 {
1228  NTSTATUS Status;
1229  HANDLE RootHandle, KeyHandle;
1230  UNICODE_STRING HKLMSystem, KeyString;
1231  WCHAR Buffer[sizeof(L"SystemPartition") / sizeof(WCHAR)];
1232 
1233  RtlInitUnicodeString(&HKLMSystem, L"\\REGISTRY\\MACHINE\\SYSTEM");
1234 
1235  /* Open registry to save data (HKLM\SYSTEM) */
1236  Status = IopOpenRegistryKeyEx(&RootHandle, 0, &HKLMSystem, KEY_ALL_ACCESS);
1237  if (!NT_SUCCESS(Status))
1238  {
1239  return Status;
1240  }
1241 
1242  /* Create or open Setup subkey */
1243  KeyString.Buffer = Buffer;
1244  KeyString.Length = sizeof(L"Setup") - sizeof(UNICODE_NULL);
1245  KeyString.MaximumLength = sizeof(L"Setup");
1246  RtlCopyMemory(Buffer, L"Setup", sizeof(L"Setup"));
1248  RootHandle,
1249  &KeyString,
1252  NULL);
1253  ZwClose(RootHandle);
1254  if (!NT_SUCCESS(Status))
1255  {
1256  return Status;
1257  }
1258 
1259  /* Store caller value */
1260  KeyString.Length = sizeof(L"SystemPartition") - sizeof(UNICODE_NULL);
1261  KeyString.MaximumLength = sizeof(L"SystemPartition");
1262  RtlCopyMemory(Buffer, L"SystemPartition", sizeof(L"SystemPartition"));
1263  Status = ZwSetValueKey(KeyHandle,
1264  &KeyString,
1265  0,
1266  REG_SZ,
1267  VolumeNameString->Buffer,
1268  VolumeNameString->Length + sizeof(UNICODE_NULL));
1269  ZwClose(KeyHandle);
1270 
1271  return Status;
1272 }
1273 
1274 /*
1275  * @implemented
1276  */
1277 NTSTATUS
1278 NTAPI
1279 IoVolumeDeviceToDosName(IN PVOID VolumeDeviceObject,
1281 {
1282  PIRP Irp;
1283  ULONG Length;
1284  KEVENT Event;
1285  NTSTATUS Status;
1289  UNICODE_STRING MountMgrDevice;
1290  MOUNTMGR_VOLUME_PATHS VolumePath;
1291  PMOUNTMGR_VOLUME_PATHS VolumePathPtr;
1292  /*
1293  * This variable with be required to query device name.
1294  * It's based on MOUNTDEV_NAME (mountmgr.h).
1295  * Doing it that way will prevent dyn memory allocation.
1296  * Device name won't be longer.
1297  */
1298  struct
1299  {
1300  USHORT NameLength;
1301  WCHAR DeviceName[256];
1302  } DeviceName;
1303 
1304  PAGED_CODE();
1305 
1306  /* First step, getting device name */
1309  VolumeDeviceObject, NULL, 0,
1310  &DeviceName, sizeof(DeviceName),
1311  FALSE, &Event, &IoStatusBlock);
1312  if (!Irp)
1313  {
1315  }
1316 
1317  Status = IoCallDriver(VolumeDeviceObject, Irp);
1318  if (Status == STATUS_PENDING)
1319  {
1322  }
1323 
1324  if (!NT_SUCCESS(Status))
1325  {
1326  return Status;
1327  }
1328 
1329  /* Now that we have the device name, we can query the MountMgr
1330  * So, get its device object first.
1331  */
1332  RtlInitUnicodeString(&MountMgrDevice, MOUNTMGR_DEVICE_NAME);
1335  if (!NT_SUCCESS(Status))
1336  {
1337  return Status;
1338  }
1339 
1340  /* Then, use the proper IOCTL to query the DOS name */
1343  DeviceObject, &DeviceName, sizeof(DeviceName),
1344  &VolumePath, sizeof(VolumePath),
1345  FALSE, &Event, &IoStatusBlock);
1346  if (!Irp)
1347  {
1349  goto DereferenceFO;
1350  }
1351 
1353  if (Status == STATUS_PENDING)
1354  {
1357  }
1358 
1359  /* Only tolerated failure here is buffer too small, which is
1360  * expected.
1361  */
1363  {
1364  goto DereferenceFO;
1365  }
1366 
1367  /* Compute needed size to store DOS name.
1368  * Even if MOUNTMGR_VOLUME_PATHS allows bigger
1369  * name lengths than MAXUSHORT, we can't use
1370  * them, because we have to return this in an UNICODE_STRING
1371  * that stores length on USHORT.
1372  */
1373  Length = VolumePath.MultiSzLength + sizeof(VolumePath);
1374  if (Length > MAXUSHORT)
1375  {
1377  goto DereferenceFO;
1378  }
1379 
1380  /* Reallocate memory, even in case of success, because
1381  * that's the buffer that will be returned to caller
1382  */
1383  VolumePathPtr = ExAllocatePoolWithTag(PagedPool, Length, 'D2d ');
1384  if (!VolumePathPtr)
1385  {
1387  goto DereferenceFO;
1388  }
1389 
1390  /* Requery DOS path with proper size */
1393  DeviceObject, &DeviceName, sizeof(DeviceName),
1394  VolumePathPtr, Length,
1395  FALSE, &Event, &IoStatusBlock);
1396  if (!Irp)
1397  {
1399  goto ReleaseMemory;
1400  }
1401 
1403  if (Status == STATUS_PENDING)
1404  {
1407  }
1408 
1409  if (!NT_SUCCESS(Status))
1410  {
1411  goto ReleaseMemory;
1412  }
1413 
1414  /* Set output string */
1415  DosName->Length = (USHORT)VolumePathPtr->MultiSzLength;
1416  DosName->MaximumLength = (USHORT)VolumePathPtr->MultiSzLength + sizeof(UNICODE_NULL);
1417  /* Our MOUNTMGR_VOLUME_PATHS will be used as output buffer */
1418  DosName->Buffer = (PWSTR)VolumePathPtr;
1419  /* Move name at the begin, RtlMoveMemory is OK with overlapping */
1420  RtlMoveMemory(DosName->Buffer, VolumePathPtr->MultiSz, VolumePathPtr->MultiSzLength);
1421  DosName->Buffer[DosName->Length / sizeof(WCHAR)] = UNICODE_NULL;
1422 
1423  /* DON'T release buffer, just dereference FO, and return success */
1425  goto DereferenceFO;
1426 
1428  ExFreePoolWithTag(VolumePathPtr, 'D2d ');
1429 
1430 DereferenceFO:
1432 
1433  return Status;
1434 }
1435 
1436 /* EOF */
VOID NTAPI IopLoadFileSystemDriver(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:409
#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:292
* PNTSTATUS
Definition: strlen.c:14
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:428
_In_ PVOID _In_ BOOLEAN Alertable
Definition: exfuncs.h:452
#define IN
Definition: typedefs.h:39
#define FILE_DEVICE_DISK
Definition: winioctl.h:113
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID NTAPI IopDecrementDeviceObjectHandleCount(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:65
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
USHORT Flags
Definition: iotypes.h:192
struct _Entry Entry
Definition: kefuncs.h:627
VOID NTAPI IopDereferenceVpbAndFree(IN PVPB Vpb)
Definition: volume.c:186
#define FILE_DEVICE_TAPE_FILE_SYSTEM
Definition: winioctl.h:138
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
_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
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define IRP_MJ_SHUTDOWN
NTSTATUS NTAPI IopCreateVpb(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:158
#define TRUE
Definition: types.h:120
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:56
BOOLEAN NTAPI IopReferenceVerifyVpb(IN PDEVICE_OBJECT DeviceObject, OUT PDEVICE_OBJECT *FileSystemObject, OUT PVPB *Vpb)
Definition: volume.c:216
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
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
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2221
VOID NTAPI IoUnregisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:1056
#define KeGetPreviousMode()
Definition: ketypes.h:1107
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2813
#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:462
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define IRP_MN_LOAD_FILE_SYSTEM
Definition: iotypes.h:4402
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204
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:511
#define FILE_DEVICE_VIRTUAL_DISK
Definition: winioctl.h:142
#define VPB_PERSISTENT
Definition: iotypes.h:1806
LIST_ENTRY IopDiskFileSystemQueueHead
Definition: volume.c:21
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
#define InsertTailList(ListHead, Entry)
#define STATUS_FS_DRIVER_REQUIRED
Definition: ntstatus.h:645
LIST_ENTRY IopCdRomFileSystemQueueHead
Definition: volume.c:22
#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:285
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:106
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define MOUNTMGR_DEVICE_NAME
Definition: imports.h:76
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
uint32_t ULONG_PTR
Definition: typedefs.h:65
NTSTATUS NTAPI IoEnumerateRegisteredFiltersList(OUT PDRIVER_OBJECT *DriverObjectList, IN ULONG DriverObjectListSize, OUT PULONG ActualNumberDriverObjects)
Definition: volume.c:821
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:108
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:1279
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IRP_MN_VERIFY_VOLUME
Definition: iotypes.h:4401
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
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3272
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
_In_ PIRP Irp
Definition: csq.h:116
LIST_ENTRY IopTapeFileSystemQueueHead
Definition: volume.c:22
#define STATUS_UNRECOGNIZED_VOLUME
Definition: udferr_usr.h:173
ULONG ReferenceCount
Definition: iotypes.h:197
ULONG FASTCALL IopInterlockedDecrementUlong(IN KSPIN_LOCK_QUEUE_NUMBER Queue, IN PULONG Ulong)
Definition: volume.c:331
#define VPB_LOCKED
Definition: iotypes.h:1805
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:467
unsigned char BOOLEAN
#define DO_SYSTEM_BOOT_PARTITION
Definition: env_spec_w32.h:400
_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
Definition: bufpool.h:45
struct _DEVICE_OBJECT * DeviceObject
Definition: iotypes.h:194
#define VPB_REMOVE_PENDING
Definition: ntifs_ex.h:428
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
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define FILE_DEVICE_DISK_FILE_SYSTEM
Definition: winioctl.h:114
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI IoSetSystemPartition(IN PUNICODE_STRING VolumeNameString)
Definition: volume.c:1226
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:650
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4400
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
ULONG FASTCALL IopInterlockedIncrementUlong(IN KSPIN_LOCK_QUEUE_NUMBER Queue, IN PULONG Ulong)
Definition: volume.c:313
PDRIVER_OBJECT DriverObject
Definition: io.h:447
#define ASSERT(a)
Definition: mode.c:45
#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:349
#define IRP_MJ_FILE_SYSTEM_CONTROL
VOID NTAPI IopDecrementDeviceObjectRef(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN UnloadIfUnused)
Definition: volume.c:33
#define ObDereferenceObject
Definition: obfuncs.h:203
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
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
#define SL_ALLOW_RAW_MOUNT
Definition: iotypes.h:1838
* PFILE_OBJECT
Definition: iotypes.h:1995
VOID NTAPI IoUnregisterFsRegistrationChange(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_FS_NOTIFICATION FSDNotificationProc)
Definition: volume.c:1157
ERESOURCE IopDatabaseResource
Definition: volume.c:20
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
ULONG IopFsRegistrationOps
Definition: volume.c:24
#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:790
#define DOE_REMOVE_PENDING
Definition: iotypes.h:151
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
ULONG ExpInitializationPhase
Definition: init.c:66
KIRQL * PKIRQL
Definition: env_spec_w32.h:592
Definition: typedefs.h:119
PDRIVER_FS_NOTIFICATION FSDNotificationProc
Definition: io.h:448
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
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
#define VPB_RAW_MOUNT
Definition: iotypes.h:1808
#define STATUS_USER_APC
Definition: ntstatus.h:78
#define IRP_MOUNT_COMPLETION
VOID NTAPI IopUnloadDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:390
enum _KSPIN_LOCK_QUEUE_NUMBER KSPIN_LOCK_QUEUE_NUMBER
_In_ BOOLEAN Release
Definition: cdrom.h:920
PVPB NTAPI IopMountInitializeVpb(IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT AttachedDeviceObject, IN BOOLEAN Raw)
Definition: volume.c:249
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
WDF_EXTERN_C_START typedef _Must_inspect_result_ _In_ WDFDRIVER _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ PDEVICE_OBJECT _In_opt_ PDEVICE_OBJECT AttachedDeviceObject
Definition: wdfminiport.h:64
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1532
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
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
#define FORCEINLINE
Definition: wdftypes.h:67
VOID NTAPI IopNotifyAlreadyRegisteredFileSystems(IN PLIST_ENTRY ListHead, IN PDRIVER_FS_NOTIFICATION DriverNotificationRoutine, BOOLEAN SkipRawFs)
Definition: volume.c:785
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:126
#define NULL
Definition: types.h:112
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:83
LIST_ENTRY IopFsNotifyChangeQueueHead
Definition: volume.c:23
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:987
Definition: iotypes.h:189
#define OUT
Definition: typedefs.h:40
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM
Definition: winioctl.h:109
#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:598
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
LIST_ENTRY FsChangeNotifyList
Definition: io.h:446
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:76
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3124
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
unsigned long Ulong
Definition: utypes.h:42
#define IoGetDevObjExtension(DeviceObject)
Definition: io.h:125
#define VPB_MOUNTED
Definition: iotypes.h:1804
NTSTATUS NTAPI IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount)
Definition: volume.c:877
LIST_ENTRY IopNetworkFileSystemQueueHead
Definition: volume.c:21
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
NTSTATUS NTAPI IoRegisterFsRegistrationChange(IN PDRIVER_OBJECT DriverObject, IN PDRIVER_FS_NOTIFICATION DriverNotificationRoutine)
Definition: volume.c:1089
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:108
struct _DRIVER_OBJECT * PDRIVER_OBJECT
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1673
DRIVER_FS_NOTIFICATION * PDRIVER_FS_NOTIFICATION
Definition: iotypes.h:7357
#define IRP_SYNCHRONOUS_PAGING_IO
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
Definition: io.h:444
#define PAGED_CODE()
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:801
#define REG_SZ
Definition: layer.c:22