2 * PROJECT: ReactOS FAT file system driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/filesystems/fastfat/fsctl.c
5 * PURPOSE: Filesystem control
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
9 /* INCLUDES *****************************************************************/
14 /* FUNCTIONS ****************************************************************/
18 FatUserFsCtrl(PFAT_IRP_CONTEXT IrpContext
, PIRP Irp
)
20 DPRINT1("FatUserFsCtrl()\n");
21 FatCompleteRequest(IrpContext
, Irp
, STATUS_INVALID_DEVICE_REQUEST
);
22 return STATUS_INVALID_DEVICE_REQUEST
;
27 FatVerifyVolume(PFAT_IRP_CONTEXT IrpContext
, PIRP Irp
)
29 DPRINT1("FatVerifyVolume()\n");
30 FatCompleteRequest(IrpContext
, Irp
, STATUS_INVALID_DEVICE_REQUEST
);
31 return STATUS_INVALID_DEVICE_REQUEST
;
36 FatiCleanVcbs(PFAT_IRP_CONTEXT IrpContext
)
38 /* Make sure this IRP is waitable */
39 ASSERT(IrpContext
->Flags
& IRPCONTEXT_CANWAIT
);
41 /* Acquire global resource */
42 ExAcquireResourceExclusiveLite(&FatGlobalData
.Resource
, TRUE
);
44 /* TODO: Go through all VCBs and delete unmounted ones */
46 /* Release global resource */
47 ExReleaseResourceLite(&FatGlobalData
.Resource
);
52 FatMountVolume(PFAT_IRP_CONTEXT IrpContext
,
53 PDEVICE_OBJECT TargetDeviceObject
,
55 PDEVICE_OBJECT FsDeviceObject
)
58 DISK_GEOMETRY DiskGeometry
;
59 ULONG MediaChangeCount
= 0;
60 PVOLUME_DEVICE_OBJECT VolumeDevice
;
62 DPRINT1("FatMountVolume()\n");
64 /* Make sure this IRP is waitable */
65 ASSERT(IrpContext
->Flags
& IRPCONTEXT_CANWAIT
);
67 /* Request media changes count, mostly usefull for removable devices */
68 Status
= FatPerformDevIoCtrl(TargetDeviceObject
,
69 IOCTL_STORAGE_CHECK_VERIFY
,
76 if (!NT_SUCCESS(Status
)) return Status
;
78 /* TODO: Check if data-track present in case of a CD drive */
79 /* TODO: IOCTL_DISK_GET_PARTITION_INFO_EX */
81 /* Remove unmounted VCBs */
82 FatiCleanVcbs(IrpContext
);
84 /* Create a new volume device object */
85 Status
= IoCreateDevice(FatGlobalData
.DriverObject
,
86 sizeof(VOLUME_DEVICE_OBJECT
) - sizeof(DEVICE_OBJECT
),
88 FILE_DEVICE_DISK_FILE_SYSTEM
,
91 (PDEVICE_OBJECT
*)&VolumeDevice
);
93 if (!NT_SUCCESS(Status
)) return Status
;
95 /* Match alignment requirements */
96 if (TargetDeviceObject
->AlignmentRequirement
> VolumeDevice
->DeviceObject
.AlignmentRequirement
)
98 VolumeDevice
->DeviceObject
.AlignmentRequirement
= TargetDeviceObject
->AlignmentRequirement
;
101 /* Init stack size */
102 VolumeDevice
->DeviceObject
.StackSize
= TargetDeviceObject
->StackSize
+ 1;
104 /* Get sector size */
105 Status
= FatPerformDevIoCtrl(TargetDeviceObject
,
106 IOCTL_DISK_GET_DRIVE_GEOMETRY
,
110 sizeof(DISK_GEOMETRY
),
113 if (!NT_SUCCESS(Status
)) goto FatMountVolumeCleanup
;
115 VolumeDevice
->DeviceObject
.SectorSize
= DiskGeometry
.BytesPerSector
;
117 /* Signal we're done with initializing */
118 VolumeDevice
->DeviceObject
.Flags
&= ~DO_DEVICE_INITIALIZING
;
120 /* Save device object in a VPB */
121 Vpb
->DeviceObject
= (PDEVICE_OBJECT
)VolumeDevice
;
123 /* Initialize VCB for this volume */
124 Status
= FatInitializeVcb(&VolumeDevice
->Vcb
, TargetDeviceObject
, Vpb
);
125 if (!NT_SUCCESS(Status
)) goto FatMountVolumeCleanup
;
127 /* Keep trace of media changes */
128 VolumeDevice
->Vcb
.MediaChangeCount
= MediaChangeCount
;
130 /* Notify about volume mount */
131 FsRtlNotifyVolumeEvent(VolumeDevice
->Vcb
.VolumeFileObject
, FSRTL_VOLUME_MOUNT
);
134 return STATUS_SUCCESS
;
137 FatMountVolumeCleanup
:
139 /* Unwind the routine actions */
140 IoDeleteDevice((PDEVICE_OBJECT
)VolumeDevice
);
148 FatiFileSystemControl(PFAT_IRP_CONTEXT IrpContext
, PIRP Irp
)
150 PIO_STACK_LOCATION IrpSp
;
153 /* Get current IRP stack location */
154 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
156 /* Dispatch depending on the minor function */
157 switch (IrpSp
->MinorFunction
)
159 case IRP_MN_USER_FS_REQUEST
:
160 Status
= FatUserFsCtrl(IrpContext
, Irp
);
163 case IRP_MN_MOUNT_VOLUME
:
164 Status
= FatMountVolume(IrpContext
,
165 IrpSp
->Parameters
.MountVolume
.DeviceObject
,
166 IrpSp
->Parameters
.MountVolume
.Vpb
,
167 IrpSp
->DeviceObject
);
169 FatCompleteRequest(IrpContext
, Irp
, Status
);
173 case IRP_MN_VERIFY_VOLUME
:
174 Status
= FatVerifyVolume(IrpContext
, Irp
);
178 DPRINT1("Unhandled FSCTL minor 0x%x\n", IrpSp
->MinorFunction
);
179 FatCompleteRequest(IrpContext
, Irp
, STATUS_INVALID_DEVICE_REQUEST
);
180 Status
= STATUS_INVALID_DEVICE_REQUEST
;
189 FatFileSystemControl(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
191 NTSTATUS Status
= STATUS_SUCCESS
;
192 PFAT_IRP_CONTEXT IrpContext
;
193 BOOLEAN CanWait
= TRUE
;
195 DPRINT1("FatFileSystemControl(DeviceObject %p, Irp %p)\n", DeviceObject
, Irp
);
197 /* Get CanWait flag */
198 if (IoGetCurrentIrpStackLocation(Irp
)->FileObject
)
200 CanWait
= IoIsOperationSynchronous(Irp
);
203 /* Enter FsRtl critical region */
204 FsRtlEnterFileSystem();
206 /* Build an irp context */
207 IrpContext
= FatBuildIrpContext(Irp
, CanWait
);
209 /* Call internal function */
210 Status
= FatiFileSystemControl(IrpContext
, Irp
);
212 /* Leave FsRtl critical region */
213 FsRtlExitFileSystem();