ReactOS  0.4.15-dev-1367-g07cc0b5
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 */
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 }
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
ActualNumberDriverObjects _In_ ULONG DriverObjectListSize
Definition: iofuncs.h:2281
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
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
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PDRIVER_OBJECT DriverObject
Definition: io.h:459
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
ERESOURCE IopDatabaseResource
Definition: volume.c:20
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
Definition: typedefs.h:119
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
ActualNumberDriverObjects _In_ ULONG _Out_ PULONG ActualNumberDriverObjects
Definition: iofuncs.h:2281
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:360
LIST_ENTRY IopFsNotifyChangeQueueHead
Definition: volume.c:23
#define ObReferenceObject
Definition: obfuncs.h:204
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _DRIVER_OBJECT * PDRIVER_OBJECT
Definition: io.h:456

◆ 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 {
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 }
_In_ PVOID _In_ BOOLEAN Alertable
Definition: exfuncs.h:452
#define TRUE
Definition: types.h:120
VOID NTAPI IopDereferenceDeviceObject(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN ForceUnload)
Definition: device.c:462
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
PVPB Vpb
Definition: cdstruc.h:511
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
#define STATUS_ALERTED
Definition: ntstatus.h:80
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
#define FALSE
Definition: types.h:117
#define VPB_LOCKED
Definition: iotypes.h:1788
unsigned char BOOLEAN
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define STATUS_USER_APC
Definition: ntstatus.h:78
#define NULL
Definition: types.h:112
Definition: iotypes.h:168
Definition: sacdrv.h:278
#define VPB_MOUNTED
Definition: iotypes.h:1787
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1673
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:801

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);
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 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_VPB
Definition: cdprocs.h:106
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IO_TYPE_VPB
struct _VPB VPB
Definition: iotypes.h:168
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1673

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 }
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
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 {
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 }
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define ASSERT(a)
Definition: mode.c:45
#define DOE_UNLOAD_PENDING
Definition: iotypes.h:149
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
#define DOE_DELETE_PENDING
Definition: iotypes.h:150
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define DOE_REMOVE_PENDING
Definition: iotypes.h:151
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
VOID NTAPI IopUnloadDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:390
#define IoGetDevObjExtension(DeviceObject)
Definition: io.h:125

Referenced by IopDecrementDeviceObjectHandleCount(), and IopShutdownBaseFileSystems().

◆ IopDereferenceVpbAndFree()

VOID NTAPI IopDereferenceVpbAndFree ( IN PVPB  Vpb)

Definition at line 186 of file volume.c.

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 }
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204
PVPB Vpb
Definition: cdstruc.h:511
#define VPB_PERSISTENT
Definition: iotypes.h:1789
#define TAG_VPB
Definition: cdprocs.h:106
UCHAR KIRQL
Definition: env_spec_w32.h:591
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1673

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:2221
_Out_ PKIRQL Irql
Definition: csq.h:179
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
unsigned int ULONG
Definition: retypes.h:1

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 }
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2221
_Out_ PKIRQL Irql
Definition: csq.h:179
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
unsigned int ULONG
Definition: retypes.h:1

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;
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 }
LONG NTSTATUS
Definition: precomp.h:26
#define IRP_MN_LOAD_FILE_SYSTEM
Definition: iotypes.h:4385
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
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:450
Status
Definition: gdiplustypes.h:24
#define STATUS_PENDING
Definition: ntstatus.h:82
#define IRP_MJ_FILE_SYSTEM_CONTROL
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
#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
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
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 IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define PAGED_CODE()

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 {
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 }
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204
PVPB Vpb
Definition: cdstruc.h:511
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define VPB_RAW_MOUNT
Definition: iotypes.h:1791
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
Definition: iotypes.h:168
Definition: sacdrv.h:278
#define IoGetDevObjExtension(DeviceObject)
Definition: io.h:125
#define VPB_MOUNTED
Definition: iotypes.h:1787
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1673

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 {
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 }
VOID NTAPI IopLoadFileSystemDriver(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:409
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:428
_In_ PVOID _In_ BOOLEAN Alertable
Definition: exfuncs.h:452
#define FILE_DEVICE_DISK
Definition: winioctl.h:112
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI FsRtlIsTotalDeviceFailure(IN NTSTATUS NtStatus)
Definition: filter.c:37
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2221
#define KeGetPreviousMode()
Definition: ketypes.h:1107
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2813
LONG NTSTATUS
Definition: precomp.h:26
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define FILE_DEVICE_VIRTUAL_DISK
Definition: winioctl.h:141
LIST_ENTRY IopDiskFileSystemQueueHead
Definition: volume.c:21
#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
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
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:107
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
LIST_ENTRY IopTapeFileSystemQueueHead
Definition: volume.c:22
#define STATUS_UNRECOGNIZED_VOLUME
Definition: udferr_usr.h:173
ULONG FASTCALL IopInterlockedDecrementUlong(IN KSPIN_LOCK_QUEUE_NUMBER Queue, IN PULONG Ulong)
Definition: volume.c:331
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:450
#define DO_SYSTEM_BOOT_PARTITION
Definition: env_spec_w32.h:400
#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
Status
Definition: gdiplustypes.h:24
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4383
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
ULONG FASTCALL IopInterlockedIncrementUlong(IN KSPIN_LOCK_QUEUE_NUMBER Queue, IN PULONG Ulong)
Definition: volume.c:313
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define ObDereferenceObject
Definition: obfuncs.h:203
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
ERESOURCE IopDatabaseResource
Definition: volume.c:20
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
ULONG IopFsRegistrationOps
Definition: volume.c:24
unsigned char UCHAR
Definition: xmlstorage.h:181
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
ULONG ExpInitializationPhase
Definition: init.c:66
Definition: typedefs.h:119
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
#define VPB_RAW_MOUNT
Definition: iotypes.h:1791
#define STATUS_USER_APC
Definition: ntstatus.h:78
#define IRP_MOUNT_COMPLETION
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
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define ObReferenceObject
Definition: obfuncs.h:204
unsigned int ULONG
Definition: retypes.h:1
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
#define VPB_MOUNTED
Definition: iotypes.h:1787
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
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1673
#define IRP_SYNCHRONOUS_PAGING_IO
#define PAGED_CODE()

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 */
803  DeviceObject = CONTAINING_RECORD(ListEntry,
805  Queue.ListEntry);
806 
808 
809  /* Go to the next entry */
810  ListEntry = ListEntry->Flink;
811  }
812 }
#define TRUE
Definition: types.h:120
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2221
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
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
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
_In_ PDRIVER_FS_NOTIFICATION DriverNotificationRoutine
Definition: iofuncs.h:593
Definition: typedefs.h:119

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 */
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 }
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
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
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: typedefs.h:119
PDRIVER_FS_NOTIFICATION FSDNotificationProc
Definition: io.h:460
LIST_ENTRY IopFsNotifyChangeQueueHead
Definition: volume.c:23
Definition: io.h:456

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 {
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 }
USHORT Flags
Definition: iotypes.h:171
#define TRUE
Definition: types.h:120
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
ULONG ReferenceCount
Definition: iotypes.h:176
unsigned char BOOLEAN
_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
struct _DEVICE_OBJECT * DeviceObject
Definition: iotypes.h:173
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define NULL
Definition: types.h:112
Definition: iotypes.h:168
#define VPB_MOUNTED
Definition: iotypes.h:1787
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1673

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;
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 }
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
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2221
LONG NTSTATUS
Definition: precomp.h:26
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
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:450
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
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
ULONG FASTCALL IopInterlockedIncrementUlong(IN KSPIN_LOCK_QUEUE_NUMBER Queue, IN PULONG Ulong)
Definition: volume.c:313
#define STATUS_PENDING
Definition: ntstatus.h:82
VOID NTAPI IopDecrementDeviceObjectRef(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN UnloadIfUnused)
Definition: volume.c:33
#define ObDereferenceObject
Definition: obfuncs.h:203
Definition: typedefs.h:119
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
PDEVICE_OBJECT NTAPI IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1385
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define ObReferenceObject
Definition: obfuncs.h:204
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22

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 */
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 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define FILE_DEVICE_TAPE_FILE_SYSTEM
Definition: winioctl.h:137
#define TRUE
Definition: types.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
LIST_ENTRY IopDiskFileSystemQueueHead
Definition: volume.c:21
#define InsertTailList(ListHead, Entry)
LIST_ENTRY IopCdRomFileSystemQueueHead
Definition: volume.c:22
FORCEINLINE VOID IopNotifyFileSystemChange(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN DriverActive)
Definition: volume.c:285
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
LIST_ENTRY IopTapeFileSystemQueueHead
Definition: volume.c:22
#define FILE_DEVICE_DISK_FILE_SYSTEM
Definition: winioctl.h:113
ULONG FASTCALL IopInterlockedIncrementUlong(IN KSPIN_LOCK_QUEUE_NUMBER Queue, IN PULONG Ulong)
Definition: volume.c:313
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
ERESOURCE IopDatabaseResource
Definition: volume.c:20
ULONG IopFsRegistrationOps
Definition: volume.c:24
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
Definition: typedefs.h:119
#define DO_LOW_PRIORITY_FILESYSTEM
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
unsigned int * PULONG
Definition: retypes.h:1
#define FILE_DEVICE_NETWORK_FILE_SYSTEM
Definition: winioctl.h:125
#define NULL
Definition: types.h:112
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM
Definition: winioctl.h:108
LIST_ENTRY IopNetworkFileSystemQueueHead
Definition: volume.c:21
#define PAGED_CODE()

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 STATUS_DEVICE_ALREADY_ATTACHED
Definition: ntstatus.h:292
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _Entry Entry
Definition: kefuncs.h:627
#define TRUE
Definition: types.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
#define TAG_FS_CHANGE_NOTIFY
Definition: tag.h:51
LIST_ENTRY IopDiskFileSystemQueueHead
Definition: volume.c:21
#define InsertTailList(ListHead, Entry)
LIST_ENTRY IopCdRomFileSystemQueueHead
Definition: volume.c:22
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define FALSE
Definition: types.h:117
LIST_ENTRY IopTapeFileSystemQueueHead
Definition: volume.c:22
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
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
ERESOURCE IopDatabaseResource
Definition: volume.c:20
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_In_ PDRIVER_FS_NOTIFICATION DriverNotificationRoutine
Definition: iofuncs.h:593
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
VOID NTAPI IopNotifyAlreadyRegisteredFileSystems(IN PLIST_ENTRY ListHead, IN PDRIVER_FS_NOTIFICATION DriverNotificationRoutine, BOOLEAN SkipRawFs)
Definition: volume.c:785
LIST_ENTRY IopFsNotifyChangeQueueHead
Definition: volume.c:23
#define ObReferenceObject
Definition: obfuncs.h:204
#define STATUS_SUCCESS
Definition: shellext.h:65
LIST_ENTRY IopNetworkFileSystemQueueHead
Definition: volume.c:21
base of all file and directory entries
Definition: entries.h:82
Definition: io.h:456
#define PAGED_CODE()

Referenced by DriverEntry().

◆ IoReleaseVpbSpinLock()

◆ IoSetSystemPartition()

NTSTATUS NTAPI IoSetSystemPartition ( IN PUNICODE_STRING  VolumeNameString)

Definition at line 1226 of file volume.c.

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 }
_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
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
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 UNICODE_NULL
Definition: bufpool.h:45
Status
Definition: gdiplustypes.h:24
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR L[]
Definition: oid.c:1250
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1599
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define NULL
Definition: types.h:112
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define REG_SZ
Definition: layer.c:22

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 TRUE
Definition: types.h:120
FORCEINLINE VOID IopNotifyFileSystemChange(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN DriverActive)
Definition: volume.c:285
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
ULONG FASTCALL IopInterlockedDecrementUlong(IN KSPIN_LOCK_QUEUE_NUMBER Queue, IN PULONG Ulong)
Definition: volume.c:331
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
ERESOURCE IopDatabaseResource
Definition: volume.c:20
ULONG IopFsRegistrationOps
Definition: volume.c:24
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
unsigned int * PULONG
Definition: retypes.h:1
#define PAGED_CODE()

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 */
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 }
#define TRUE
Definition: types.h:120
#define TAG_FS_CHANGE_NOTIFY
Definition: tag.h:51
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
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
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PDRIVER_OBJECT DriverObject
Definition: io.h:459
#define ObDereferenceObject
Definition: obfuncs.h:203
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
ERESOURCE IopDatabaseResource
Definition: volume.c:20
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
Definition: typedefs.h:119
PDRIVER_FS_NOTIFICATION FSDNotificationProc
Definition: io.h:460
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
LIST_ENTRY IopFsNotifyChangeQueueHead
Definition: volume.c:23
LIST_ENTRY FsChangeNotifyList
Definition: io.h:458
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
Definition: io.h:456
#define PAGED_CODE()

◆ 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;
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 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID NTAPI IopDereferenceVpbAndFree(IN PVPB Vpb)
Definition: volume.c:186
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
NTSTATUS NTAPI IopCreateVpb(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:158
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI IopReferenceVerifyVpb(IN PDEVICE_OBJECT DeviceObject, OUT PDEVICE_OBJECT *FileSystemObject, OUT PVPB *Vpb)
Definition: volume.c:216
LONG NTSTATUS
Definition: precomp.h:26
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 STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IRP_MN_VERIFY_VOLUME
Definition: iotypes.h:4384
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
ULONG ReferenceCount
Definition: iotypes.h:176
ULONG FASTCALL IopInterlockedDecrementUlong(IN KSPIN_LOCK_QUEUE_NUMBER Queue, IN PULONG Ulong)
Definition: volume.c:331
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:450
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define IRP_MJ_FILE_SYSTEM_CONTROL
VOID NTAPI PoVolumeDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: povolume.c:83
#define SL_ALLOW_RAW_MOUNT
Definition: iotypes.h:1821
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
#define IRP_MOUNT_COMPLETION
_In_ BOOLEAN Release
Definition: cdrom.h:920
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
Definition: iotypes.h:168
#define IO_NO_INCREMENT
Definition: iotypes.h:581
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1673
#define IRP_SYNCHRONOUS_PAGING_IO

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;
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 }
#define IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH
Definition: mountmgr.h:127
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWSTR
Definition: typedefs.h:56
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
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 MOUNTMGR_DEVICE_NAME
Definition: imports.h:76
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3272
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
_In_ PIRP Irp
Definition: csq.h:116
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:450
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
Status
Definition: gdiplustypes.h:24
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:650
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define ObDereferenceObject
Definition: obfuncs.h:203
* PFILE_OBJECT
Definition: iotypes.h:1978
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
unsigned short USHORT
Definition: pedump.c:61
_Out_ PUNICODE_STRING DosName
Definition: rtlfuncs.h:1270
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define MAXUSHORT
Definition: typedefs.h:83
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
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
NTSTATUS NTAPI ReleaseMemory(IN PDEVICE_OBJECT DeviceObject)
Definition: fbtpnp.c:1790
#define PAGED_CODE()

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