ReactOS 0.4.16-dev-197-g92996da
volume.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for volume.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID NTAPI IopDecrementDeviceObjectRef (IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN UnloadIfUnused)
 
VOID NTAPI IopDecrementDeviceObjectHandleCount (IN PDEVICE_OBJECT DeviceObject)
 
PVPB NTAPI IopCheckVpbMounted (IN POPEN_PACKET OpenPacket, IN PDEVICE_OBJECT DeviceObject, IN PUNICODE_STRING RemainingName, OUT PNTSTATUS Status)
 
NTSTATUS NTAPI IopCreateVpb (IN PDEVICE_OBJECT DeviceObject)
 
VOID NTAPI IopDereferenceVpbAndFree (IN PVPB Vpb)
 
BOOLEAN NTAPI IopReferenceVerifyVpb (IN PDEVICE_OBJECT DeviceObject, OUT PDEVICE_OBJECT *FileSystemObject, OUT PVPB *Vpb)
 
PVPB NTAPI IopMountInitializeVpb (IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT AttachedDeviceObject, IN BOOLEAN Raw)
 
FORCEINLINE VOID IopNotifyFileSystemChange (IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN DriverActive)
 
ULONG FASTCALL IopInterlockedIncrementUlong (IN KSPIN_LOCK_QUEUE_NUMBER Queue, IN PULONG Ulong)
 
ULONG FASTCALL IopInterlockedDecrementUlong (IN KSPIN_LOCK_QUEUE_NUMBER Queue, IN PULONG Ulong)
 
VOID NTAPI IopShutdownBaseFileSystems (IN PLIST_ENTRY ListHead)
 
VOID NTAPI IopLoadFileSystemDriver (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI IopMountVolume (IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount, IN BOOLEAN DeviceIsLocked, IN BOOLEAN Alertable, OUT PVPB *Vpb)
 
VOID NTAPI IopNotifyAlreadyRegisteredFileSystems (IN PLIST_ENTRY ListHead, IN PDRIVER_FS_NOTIFICATION DriverNotificationRoutine, BOOLEAN SkipRawFs)
 
NTSTATUS NTAPI IoEnumerateRegisteredFiltersList (OUT PDRIVER_OBJECT *DriverObjectList, IN ULONG DriverObjectListSize, OUT PULONG ActualNumberDriverObjects)
 
NTSTATUS NTAPI IoVerifyVolume (IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount)
 
VOID NTAPI IoRegisterFileSystem (IN PDEVICE_OBJECT DeviceObject)
 
VOID NTAPI IoUnregisterFileSystem (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI IoRegisterFsRegistrationChange (IN PDRIVER_OBJECT DriverObject, IN PDRIVER_FS_NOTIFICATION DriverNotificationRoutine)
 
VOID NTAPI IoUnregisterFsRegistrationChange (IN PDRIVER_OBJECT DriverObject, IN PDRIVER_FS_NOTIFICATION FSDNotificationProc)
 
VOID NTAPI IoAcquireVpbSpinLock (OUT PKIRQL Irql)
 
VOID NTAPI IoReleaseVpbSpinLock (IN KIRQL Irql)
 
NTSTATUS NTAPI IoSetSystemPartition (IN PUNICODE_STRING VolumeNameString)
 
NTSTATUS NTAPI IoVolumeDeviceToDosName (IN PVOID VolumeDeviceObject, OUT PUNICODE_STRING DosName)
 

Variables

ERESOURCE IopDatabaseResource
 
LIST_ENTRY IopDiskFileSystemQueueHead
 
LIST_ENTRY IopNetworkFileSystemQueueHead
 
LIST_ENTRY IopCdRomFileSystemQueueHead
 
LIST_ENTRY IopTapeFileSystemQueueHead
 
LIST_ENTRY IopFsNotifyChangeQueueHead
 
ULONG IopFsRegistrationOps
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 15 of file volume.c.

Function Documentation

◆ IoAcquireVpbSpinLock()

◆ IoEnumerateRegisteredFiltersList()

NTSTATUS NTAPI IoEnumerateRegisteredFiltersList ( OUT PDRIVER_OBJECT DriverObjectList,
IN ULONG  DriverObjectListSize,
OUT PULONG  ActualNumberDriverObjects 
)

Definition at line 821 of file volume.c.

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 */
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}
LONG NTSTATUS
Definition: precomp.h:26
#define TRUE
Definition: types.h:120
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
Status
Definition: gdiplustypes.h:25
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:362
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
ERESOURCE IopDatabaseResource
Definition: volume.c:20
LIST_ENTRY IopFsNotifyChangeQueueHead
Definition: volume.c:23
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
Definition: io.h:437
PDRIVER_OBJECT DriverObject
Definition: io.h:439
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
ActualNumberDriverObjects _In_ ULONG DriverObjectListSize
Definition: iofuncs.h:2285
ActualNumberDriverObjects _In_ ULONG _Out_ PULONG ActualNumberDriverObjects
Definition: iofuncs.h:2286
struct _DRIVER_OBJECT * PDRIVER_OBJECT
#define ObReferenceObject
Definition: obfuncs.h:204

◆ IopCheckVpbMounted()

PVPB NTAPI IopCheckVpbMounted ( IN POPEN_PACKET  OpenPacket,
IN PDEVICE_OBJECT  DeviceObject,
IN PUNICODE_STRING  RemainingName,
OUT PNTSTATUS  Status 
)

Definition at line 76 of file volume.c.

80{
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) ||
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 */
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}
unsigned char BOOLEAN
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:802
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
UCHAR KIRQL
Definition: env_spec_w32.h:591
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1676
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
_In_ PVOID _In_ BOOLEAN Alertable
Definition: exfuncs.h:453
VOID NTAPI IopDereferenceDeviceObject(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN ForceUnload)
Definition: device.c:462
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
NTSTATUS NTAPI IopMountVolume(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount, IN BOOLEAN DeviceIsLocked, IN BOOLEAN Alertable, OUT PVPB *Vpb)
Definition: volume.c:462
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204
#define STATUS_ALERTED
Definition: ntstatus.h:80
#define STATUS_USER_APC
Definition: ntstatus.h:78
@ Raw
Definition: sacdrv.h:279
PVPB Vpb
Definition: cdstruc.h:511
Definition: iotypes.h:189
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define VPB_MOUNTED
Definition: iotypes.h:1807
#define VPB_LOCKED
Definition: iotypes.h:1808
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by IopParseDevice().

◆ IopCreateVpb()

NTSTATUS NTAPI IopCreateVpb ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 158 of file volume.c.

159{
160 PVPB Vpb;
161
162 /* Allocate the Vpb */
164 sizeof(VPB),
165 TAG_VPB);
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}
#define TAG_VPB
Definition: cdprocs.h:106
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IO_TYPE_VPB
struct _VPB VPB

Referenced by IoCreateDevice(), and IoVerifyVolume().

◆ IopDecrementDeviceObjectHandleCount()

VOID NTAPI IopDecrementDeviceObjectHandleCount ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 65 of file volume.c.

66{
67 /* Just decrease reference count */
69}
VOID NTAPI IopDecrementDeviceObjectRef(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN UnloadIfUnused)
Definition: volume.c:33

◆ IopDecrementDeviceObjectRef()

VOID NTAPI IopDecrementDeviceObjectRef ( IN PDEVICE_OBJECT  DeviceObject,
IN BOOLEAN  UnloadIfUnused 
)

Definition at line 33 of file volume.c.

35{
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}
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
#define ASSERT(a)
Definition: mode.c:44
#define DOE_DELETE_PENDING
Definition: iotypes.h:150
#define DOE_UNLOAD_PENDING
Definition: iotypes.h:149
#define DOE_REMOVE_PENDING
Definition: iotypes.h:151
VOID NTAPI IopUnloadDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:390
#define IoGetDevObjExtension(DeviceObject)
Definition: io.h:129
@ LockQueueIoDatabaseLock
Definition: ketypes.h:668

Referenced by IopDecrementDeviceObjectHandleCount(), and IopShutdownBaseFileSystems().

◆ IopDereferenceVpbAndFree()

VOID NTAPI IopDereferenceVpbAndFree ( IN PVPB  Vpb)

Definition at line 186 of file volume.c.

187{
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}
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define VPB_PERSISTENT
Definition: iotypes.h:1809

Referenced by IopParseDevice(), and IoVerifyVolume().

◆ IopInterlockedDecrementUlong()

ULONG FASTCALL IopInterlockedDecrementUlong ( IN KSPIN_LOCK_QUEUE_NUMBER  Queue,
IN PULONG  Ulong 
)

Definition at line 331 of file volume.c.

333{
334 KIRQL Irql;
335 ULONG OldValue;
336
338 OldValue = (*Ulong)--;
340
341 return OldValue;
342}
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2225

Referenced by IopMountVolume(), IoUnregisterFileSystem(), and IoVerifyVolume().

◆ IopInterlockedIncrementUlong()

ULONG FASTCALL IopInterlockedIncrementUlong ( IN KSPIN_LOCK_QUEUE_NUMBER  Queue,
IN PULONG  Ulong 
)

Definition at line 313 of file volume.c.

315{
316 KIRQL Irql;
317 ULONG OldValue;
318
320 OldValue = (*Ulong)++;
322
323 return OldValue;
324}

Referenced by IopMountVolume(), IopShutdownBaseFileSystems(), and IoRegisterFileSystem().

◆ IopLoadFileSystemDriver()

VOID NTAPI IopLoadFileSystemDriver ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 409 of file volume.c.

410{
412 PIO_STACK_LOCATION StackPtr;
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 */
424 }
425
426 /* Initialize the event and build the IRP */
430 NULL,
431 0,
432 NULL,
433 0,
434 FALSE,
435 &Event,
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}
#define PAGED_CODE()
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define KernelMode
Definition: asm.h:34
@ NotificationEvent
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define IoCallDriver
Definition: irp.c:1225
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
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:70
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_MN_LOAD_FILE_SYSTEM
Definition: iotypes.h:4406
@ Executive
Definition: ketypes.h:415

Referenced by IopMountVolume().

◆ IopMountInitializeVpb()

PVPB NTAPI IopMountInitializeVpb ( IN PDEVICE_OBJECT  DeviceObject,
IN PDEVICE_OBJECT  AttachedDeviceObject,
IN BOOLEAN  Raw 
)

Definition at line 249 of file volume.c.

252{
254 PVPB Vpb;
255
256 /* Lock the VPBs */
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}
#define VPB_RAW_MOUNT
Definition: iotypes.h:1811

Referenced by IopMountVolume().

◆ IopMountVolume()

NTSTATUS NTAPI IopMountVolume ( IN PDEVICE_OBJECT  DeviceObject,
IN BOOLEAN  AllowRawMount,
IN BOOLEAN  DeviceIsLocked,
IN BOOLEAN  Alertable,
OUT PVPB Vpb 
)

Definition at line 462 of file volume.c.

467{
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);
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 */
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 */
523 }
524 else if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM)
525 {
526 /* Use the CD-ROM list */
528 }
529 else
530 {
531 /* It's gotta be a tape... */
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 */
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,
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 &
645 }
646 else
647 {
648 /* Check if we failed because of the user */
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) ||
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}
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define DO_SYSTEM_BOOT_PARTITION
Definition: env_spec_w32.h:400
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
#define KeGetPreviousMode()
Definition: ketypes.h:1115
#define VPB_REMOVE_PENDING
Definition: ntifs_ex.h:428
ULONG ExpInitializationPhase
Definition: init.c:68
BOOLEAN NTAPI FsRtlIsTotalDeviceFailure(IN NTSTATUS NtStatus)
Definition: filter.c:37
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
ULONG FASTCALL IopInterlockedDecrementUlong(IN KSPIN_LOCK_QUEUE_NUMBER Queue, IN PULONG Ulong)
Definition: volume.c:331
ULONG FASTCALL IopInterlockedIncrementUlong(IN KSPIN_LOCK_QUEUE_NUMBER Queue, IN PULONG Ulong)
Definition: volume.c:313
LIST_ENTRY IopCdRomFileSystemQueueHead
Definition: volume.c:22
VOID NTAPI IopLoadFileSystemDriver(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:409
ULONG IopFsRegistrationOps
Definition: volume.c:24
LIST_ENTRY IopDiskFileSystemQueueHead
Definition: volume.c:21
PVPB NTAPI IopMountInitializeVpb(IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT AttachedDeviceObject, IN BOOLEAN Raw)
Definition: volume.c:249
LIST_ENTRY IopTapeFileSystemQueueHead
Definition: volume.c:22
#define STATUS_FS_DRIVER_REQUIRED
Definition: ntstatus.h:645
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:428
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:47
#define FILE_DEVICE_DISK
Definition: winioctl.h:52
#define FILE_DEVICE_VIRTUAL_DISK
Definition: winioctl.h:81
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 _IO_STACK_LOCATION::@3974::@3994 MountVolume
union _IO_STACK_LOCATION::@1575 Parameters
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_UNRECOGNIZED_VOLUME
Definition: udferr_usr.h:173
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2817
#define IRP_MOUNT_COMPLETION
#define IRP_SYNCHRONOUS_PAGING_IO
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4404
#define ObDereferenceObject
Definition: obfuncs.h:203
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by IopCheckVpbMounted(), and IoVerifyVolume().

◆ IopNotifyAlreadyRegisteredFileSystems()

VOID NTAPI IopNotifyAlreadyRegisteredFileSystems ( IN PLIST_ENTRY  ListHead,
IN PDRIVER_FS_NOTIFICATION  DriverNotificationRoutine,
BOOLEAN  SkipRawFs 
)

Definition at line 785 of file volume.c.

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 */
805 Queue.ListEntry);
806
808
809 /* Go to the next entry */
810 ListEntry = ListEntry->Flink;
811 }
812}
_In_ PDRIVER_FS_NOTIFICATION DriverNotificationRoutine
Definition: iofuncs.h:595

Referenced by IoRegisterFsRegistrationChange().

◆ IopNotifyFileSystemChange()

FORCEINLINE VOID IopNotifyFileSystemChange ( IN PDEVICE_OBJECT  DeviceObject,
IN BOOLEAN  DriverActive 
)

Definition at line 285 of file volume.c.

287{
288 PFS_CHANGE_NOTIFY_ENTRY ChangeEntry;
289 PLIST_ENTRY ListEntry;
290
291 /* Loop the list */
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}
PDRIVER_FS_NOTIFICATION FSDNotificationProc
Definition: io.h:440

Referenced by IoRegisterFileSystem(), and IoUnregisterFileSystem().

◆ IopReferenceVerifyVpb()

BOOLEAN NTAPI IopReferenceVerifyVpb ( IN PDEVICE_OBJECT  DeviceObject,
OUT PDEVICE_OBJECT FileSystemObject,
OUT PVPB Vpb 
)

Definition at line 216 of file volume.c.

219{
221 PVPB LocalVpb;
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}
struct _DEVICE_OBJECT * DeviceObject
Definition: iotypes.h:194
USHORT Flags
Definition: iotypes.h:192
ULONG ReferenceCount
Definition: iotypes.h:197
_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:409

Referenced by IoVerifyVolume().

◆ IopShutdownBaseFileSystems()

VOID NTAPI IopShutdownBaseFileSystems ( IN PLIST_ENTRY  ListHead)

Definition at line 349 of file volume.c.

350{
351 PLIST_ENTRY ListEntry;
353 IO_STATUS_BLOCK StatusBlock;
354 PIRP Irp;
357
359
360 /* Get the first entry and start looping */
361 ListEntry = ListHead->Flink;
362 while (ListEntry != ListHead)
363 {
364 /* Get the device object */
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 */
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}
PDEVICE_OBJECT NTAPI IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1385
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

Referenced by IoShutdownSystem().

◆ IoRegisterFileSystem()

VOID NTAPI IoRegisterFileSystem ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 987 of file volume.c.

988{
989 PLIST_ENTRY FsList = NULL;
990 PAGED_CODE();
991
992 /* Acquire the FS lock */
995
996 /* Check what kind of FS this is */
998 {
999 /* Use the disk list */
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 */
1011 }
1012 else if (DeviceObject->DeviceType == FILE_DEVICE_TAPE_FILE_SYSTEM)
1013 {
1014 /* Use the tape list */
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 */
1038 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1039
1040 /* Notify file systems of the addition */
1042
1043 /* Release the FS Lock */
1046
1047 /* Ensure driver won't be unloaded */
1049}
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
FORCEINLINE VOID IopNotifyFileSystemChange(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN DriverActive)
Definition: volume.c:285
LIST_ENTRY IopNetworkFileSystemQueueHead
Definition: volume.c:21
#define FILE_DEVICE_DISK_FILE_SYSTEM
Definition: winioctl.h:53
#define FILE_DEVICE_TAPE_FILE_SYSTEM
Definition: winioctl.h:77
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM
Definition: winioctl.h:48
#define FILE_DEVICE_NETWORK_FILE_SYSTEM
Definition: winioctl.h:65
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
#define DO_LOW_PRIORITY_FILESYSTEM

Referenced by _Function_class_(), DriverEntry(), FsRecRegisterFs(), RawFsDriverEntry(), RxStartMinirdr(), and UDFFsNotification().

◆ IoRegisterFsRegistrationChange()

NTSTATUS NTAPI IoRegisterFsRegistrationChange ( IN PDRIVER_OBJECT  DriverObject,
IN PDRIVER_FS_NOTIFICATION  DriverNotificationRoutine 
)

Definition at line 1089 of file volume.c.

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}
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define PagedPool
Definition: env_spec_w32.h:308
VOID NTAPI IopNotifyAlreadyRegisteredFileSystems(IN PLIST_ENTRY ListHead, IN PDRIVER_FS_NOTIFICATION DriverNotificationRoutine, BOOLEAN SkipRawFs)
Definition: volume.c:785
#define STATUS_DEVICE_ALREADY_ATTACHED
Definition: ntstatus.h:292
base of all file and directory entries
Definition: entries.h:83
#define TAG_FS_CHANGE_NOTIFY
Definition: tag.h:66
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213

Referenced by CODE_SEG(), and DriverEntry().

◆ IoReleaseVpbSpinLock()

◆ IoSetSystemPartition()

NTSTATUS NTAPI IoSetSystemPartition ( IN PUNICODE_STRING  VolumeNameString)

Definition at line 1226 of file volume.c.

1227{
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));
1270
1271 return Status;
1272}
Definition: bufpool.h:45
#define REG_SZ
Definition: layer.c:22
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define UNICODE_NULL
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:885
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 L(x)
Definition: ntvdm.h:50
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by MountMgrMountedDeviceArrival().

◆ IoUnregisterFileSystem()

VOID NTAPI IoUnregisterFileSystem ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 1056 of file volume.c.

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}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986

Referenced by _Requires_lock_held_(), do_shutdown(), FsRecLoadFileSystem(), RawShutdown(), UDFCommonDeviceControl(), and UDFFsNotification().

◆ IoUnregisterFsRegistrationChange()

VOID NTAPI IoUnregisterFsRegistrationChange ( IN PDRIVER_OBJECT  DriverObject,
IN PDRIVER_FS_NOTIFICATION  FSDNotificationProc 
)

Definition at line 1157 of file volume.c.

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 */
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}
LIST_ENTRY FsChangeNotifyList
Definition: io.h:438

◆ IoVerifyVolume()

NTSTATUS NTAPI IoVerifyVolume ( IN PDEVICE_OBJECT  DeviceObject,
IN BOOLEAN  AllowRawMount 
)

Definition at line 877 of file volume.c.

879{
881 PIO_STACK_LOCATION StackPtr;
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,
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
976Release:
977 /* Signal the device lock and return */
979 return Status;
980}
_In_ BOOLEAN Release
Definition: cdrom.h:920
NTSTATUS NTAPI IopCreateVpb(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:158
BOOLEAN NTAPI IopReferenceVerifyVpb(IN PDEVICE_OBJECT DeviceObject, OUT PDEVICE_OBJECT *FileSystemObject, OUT PVPB *Vpb)
Definition: volume.c:216
VOID NTAPI IopDereferenceVpbAndFree(IN PVPB Vpb)
Definition: volume.c:186
VOID NTAPI PoVolumeDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: povolume.c:81
struct _IO_STACK_LOCATION::@3974::@3995 VerifyVolume
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_VERIFY_VOLUME
Definition: iotypes.h:4405
#define SL_ALLOW_RAW_MOUNT
Definition: iotypes.h:1841

Referenced by _Requires_lock_held_(), Ext2ExceptionHandler(), UDFPerformVerify(), verify_vcb(), VfatBlockDeviceIoControl(), VfatReadDisk(), VfatReadDiskPartial(), VfatWriteDisk(), and VfatWriteDiskPartial().

◆ IoVolumeDeviceToDosName()

NTSTATUS NTAPI IoVolumeDeviceToDosName ( IN PVOID  VolumeDeviceObject,
OUT PUNICODE_STRING  DosName 
)

Definition at line 1279 of file volume.c.

1281{
1282 PIRP Irp;
1283 ULONG Length;
1284 KEVENT Event;
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),
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 */
1335 if (!NT_SUCCESS(Status))
1336 {
1337 return Status;
1338 }
1339
1340 /* Then, use the proper IOCTL to query the DOS name */
1344 &VolumePath, sizeof(VolumePath),
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 */
1394 VolumePathPtr, Length,
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);
1422
1423 /* DON'T release buffer, just dereference FO, and return success */
1425 goto DereferenceFO;
1426
1428 ExFreePoolWithTag(VolumePathPtr, 'D2d ');
1429
1430DereferenceFO:
1432
1433 return Status;
1434}
NTSTATUS NTAPI ReleaseMemory(IN PDEVICE_OBJECT DeviceObject)
Definition: fbtpnp.c:1790
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:91
#define MOUNTMGR_DEVICE_NAME
Definition: imports.h:74
#define IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH
Definition: mountmgr.h:147
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:650
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
uint16_t * PWSTR
Definition: typedefs.h:56
#define MAXUSHORT
Definition: typedefs.h:83
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
* PFILE_OBJECT
Definition: iotypes.h:1998
_Out_ PUNICODE_STRING DosName
Definition: rtlfuncs.h:1283

Referenced by FilterInstanceSetup(), IopQueryNameInternal(), and TestIoVolumeDeviceToDosName().

Variable Documentation

◆ IopCdRomFileSystemQueueHead

LIST_ENTRY IopCdRomFileSystemQueueHead

◆ IopDatabaseResource

◆ IopDiskFileSystemQueueHead

LIST_ENTRY IopDiskFileSystemQueueHead

◆ IopFsNotifyChangeQueueHead

◆ IopFsRegistrationOps

ULONG IopFsRegistrationOps

Definition at line 24 of file volume.c.

Referenced by IopMountVolume(), IoRegisterFileSystem(), and IoUnregisterFileSystem().

◆ IopNetworkFileSystemQueueHead

LIST_ENTRY IopNetworkFileSystemQueueHead

Definition at line 21 of file volume.c.

Referenced by IoInitSystem(), IoRegisterFileSystem(), and IoRegisterFsRegistrationChange().

◆ IopTapeFileSystemQueueHead

LIST_ENTRY IopTapeFileSystemQueueHead