Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfsctl.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS FAT file system driver 00003 * LICENSE: GNU GPLv3 as published by the Free Software Foundation 00004 * FILE: drivers/filesystems/fastfat/fsctl.c 00005 * PURPOSE: Filesystem control 00006 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org) 00007 */ 00008 00009 /* INCLUDES *****************************************************************/ 00010 00011 #define NDEBUG 00012 #include "fastfat.h" 00013 00014 /* FUNCTIONS ****************************************************************/ 00015 00016 NTSTATUS 00017 NTAPI 00018 FatOplockRequest(IN PFAT_IRP_CONTEXT IrpContext, 00019 IN PIRP Irp) 00020 { 00021 NTSTATUS Status; 00022 DPRINT1("Oplock request!\n"); 00023 00024 Status = STATUS_INVALID_DEVICE_REQUEST; 00025 FatCompleteRequest(IrpContext, Irp, Status); 00026 00027 return Status; 00028 } 00029 00030 NTSTATUS 00031 NTAPI 00032 FatMarkVolumeDirty(IN PFAT_IRP_CONTEXT IrpContext, 00033 IN PIRP Irp) 00034 { 00035 NTSTATUS Status; 00036 DPRINT1("Marking volume as dirty\n"); 00037 00038 Status = STATUS_SUCCESS; 00039 FatCompleteRequest(IrpContext, Irp, Status); 00040 00041 return Status; 00042 } 00043 00044 NTSTATUS 00045 NTAPI 00046 FatUserFsCtrl(PFAT_IRP_CONTEXT IrpContext, PIRP Irp) 00047 { 00048 PIO_STACK_LOCATION IrpSp; 00049 NTSTATUS Status; 00050 ULONG Code; 00051 00052 /* Get current IRP stack location */ 00053 IrpSp = IoGetCurrentIrpStackLocation(Irp); 00054 00055 Code = IrpSp->Parameters.FileSystemControl.FsControlCode; 00056 00057 /* Set the wait flag */ 00058 if (Irp->RequestorMode != KernelMode && 00059 (Code & 3) == METHOD_NEITHER) 00060 { 00061 SetFlag(IrpContext->Flags, IRPCONTEXT_CANWAIT); 00062 } 00063 00064 /* Branch according to the code */ 00065 switch (Code) 00066 { 00067 case FSCTL_REQUEST_OPLOCK_LEVEL_1: 00068 case FSCTL_REQUEST_OPLOCK_LEVEL_2: 00069 case FSCTL_REQUEST_BATCH_OPLOCK: 00070 case FSCTL_OPLOCK_BREAK_ACKNOWLEDGE: 00071 case FSCTL_OPBATCH_ACK_CLOSE_PENDING: 00072 case FSCTL_OPLOCK_BREAK_NOTIFY: 00073 case FSCTL_OPLOCK_BREAK_ACK_NO_2: 00074 case FSCTL_REQUEST_FILTER_OPLOCK : 00075 Status = FatOplockRequest(IrpContext, Irp); 00076 break; 00077 00078 case FSCTL_LOCK_VOLUME: 00079 //Status = FatLockVolume( IrpContext, Irp ); 00080 DPRINT1("FSCTL_LOCK_VOLUME\n"); 00081 Status = STATUS_INVALID_DEVICE_REQUEST; 00082 FatCompleteRequest(IrpContext, Irp, Status); 00083 break; 00084 00085 case FSCTL_UNLOCK_VOLUME: 00086 //Status = FatUnlockVolume( IrpContext, Irp ); 00087 DPRINT1("FSCTL_UNLOCK_VOLUME\n"); 00088 Status = STATUS_INVALID_DEVICE_REQUEST; 00089 FatCompleteRequest(IrpContext, Irp, Status); 00090 break; 00091 00092 case FSCTL_DISMOUNT_VOLUME: 00093 //Status = FatDismountVolume( IrpContext, Irp ); 00094 DPRINT1("FSCTL_DISMOUNT_VOLUME\n"); 00095 Status = STATUS_INVALID_DEVICE_REQUEST; 00096 FatCompleteRequest(IrpContext, Irp, Status); 00097 break; 00098 00099 case FSCTL_MARK_VOLUME_DIRTY: 00100 Status = FatMarkVolumeDirty(IrpContext, Irp); 00101 break; 00102 00103 case FSCTL_IS_VOLUME_DIRTY: 00104 //Status = FatIsVolumeDirty( IrpContext, Irp ); 00105 DPRINT1("FSCTL_IS_VOLUME_DIRTY\n"); 00106 Status = STATUS_INVALID_DEVICE_REQUEST; 00107 FatCompleteRequest(IrpContext, Irp, Status); 00108 break; 00109 00110 case FSCTL_IS_VOLUME_MOUNTED: 00111 //Status = FatIsVolumeMounted( IrpContext, Irp ); 00112 DPRINT1("FSCTL_IS_VOLUME_MOUNTED\n"); 00113 Status = STATUS_INVALID_DEVICE_REQUEST; 00114 FatCompleteRequest(IrpContext, Irp, Status); 00115 break; 00116 00117 case FSCTL_IS_PATHNAME_VALID: 00118 //Status = FatIsPathnameValid( IrpContext, Irp ); 00119 DPRINT1("FSCTL_IS_PATHNAME_VALID\n"); 00120 Status = STATUS_INVALID_DEVICE_REQUEST; 00121 FatCompleteRequest(IrpContext, Irp, Status); 00122 break; 00123 00124 case FSCTL_QUERY_RETRIEVAL_POINTERS: 00125 //Status = FatQueryRetrievalPointers( IrpContext, Irp ); 00126 DPRINT1("FSCTL_QUERY_RETRIEVAL_POINTERS\n"); 00127 Status = STATUS_INVALID_DEVICE_REQUEST; 00128 FatCompleteRequest(IrpContext, Irp, Status); 00129 break; 00130 00131 case FSCTL_QUERY_FAT_BPB: 00132 //Status = FatQueryBpb( IrpContext, Irp ); 00133 DPRINT1("FSCTL_QUERY_FAT_BPB\n"); 00134 Status = STATUS_INVALID_DEVICE_REQUEST; 00135 FatCompleteRequest(IrpContext, Irp, Status); 00136 break; 00137 00138 case FSCTL_FILESYSTEM_GET_STATISTICS: 00139 //Status = FatGetStatistics( IrpContext, Irp ); 00140 DPRINT1("FSCTL_FILESYSTEM_GET_STATISTICS\n"); 00141 Status = STATUS_INVALID_DEVICE_REQUEST; 00142 FatCompleteRequest(IrpContext, Irp, Status); 00143 break; 00144 00145 case FSCTL_GET_VOLUME_BITMAP: 00146 //Status = FatGetVolumeBitmap( IrpContext, Irp ); 00147 DPRINT1("FSCTL_GET_VOLUME_BITMAP\n"); 00148 Status = STATUS_INVALID_DEVICE_REQUEST; 00149 FatCompleteRequest(IrpContext, Irp, Status); 00150 break; 00151 00152 case FSCTL_GET_RETRIEVAL_POINTERS: 00153 //Status = FatGetRetrievalPointers( IrpContext, Irp ); 00154 DPRINT1("FSCTL_GET_RETRIEVAL_POINTERS\n"); 00155 Status = STATUS_INVALID_DEVICE_REQUEST; 00156 FatCompleteRequest(IrpContext, Irp, Status); 00157 break; 00158 00159 case FSCTL_MOVE_FILE: 00160 //Status = FatMoveFile( IrpContext, Irp ); 00161 DPRINT1("FSCTL_MOVE_FILE\n"); 00162 Status = STATUS_INVALID_DEVICE_REQUEST; 00163 FatCompleteRequest(IrpContext, Irp, Status); 00164 break; 00165 00166 case FSCTL_ALLOW_EXTENDED_DASD_IO: 00167 //Status = FatAllowExtendedDasdIo( IrpContext, Irp ); 00168 DPRINT1("FSCTL_ALLOW_EXTENDED_DASD_IO\n"); 00169 Status = STATUS_INVALID_DEVICE_REQUEST; 00170 FatCompleteRequest(IrpContext, Irp, Status); 00171 break; 00172 00173 default: 00174 DPRINT("FatUserFsCtrl(), unhandled fs control code 0x%x\n", Code); 00175 Status = STATUS_INVALID_DEVICE_REQUEST; 00176 FatCompleteRequest(IrpContext, Irp, Status); 00177 } 00178 00179 //(((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)) 00180 00181 // 9c040 00182 // 1 1 0 0 0 00183 // 6 4 8 4 0 00184 // 10011100000001000000 00185 // DT = 1001 = 9 00186 // Access = 11 = 3 00187 // Function = 10000 = 16 00188 // Method = 0 00189 00190 return Status; 00191 } 00192 00193 NTSTATUS 00194 NTAPI 00195 FatVerifyVolume(PFAT_IRP_CONTEXT IrpContext, PIRP Irp) 00196 { 00197 DPRINT1("FatVerifyVolume()\n"); 00198 FatCompleteRequest(IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST); 00199 return STATUS_INVALID_DEVICE_REQUEST; 00200 } 00201 00202 VOID 00203 NTAPI 00204 FatiCleanVcbs(PFAT_IRP_CONTEXT IrpContext) 00205 { 00206 /* Make sure this IRP is waitable */ 00207 ASSERT(IrpContext->Flags & IRPCONTEXT_CANWAIT); 00208 00209 /* Acquire global resource */ 00210 ExAcquireResourceExclusiveLite(&FatGlobalData.Resource, TRUE); 00211 00212 /* TODO: Go through all VCBs and delete unmounted ones */ 00213 00214 /* Release global resource */ 00215 ExReleaseResourceLite(&FatGlobalData.Resource); 00216 } 00217 00218 VOID 00219 NTAPI 00220 FatiUnpackBpb(PBIOS_PARAMETER_BLOCK Bpb, PPACKED_BIOS_PARAMETER_BLOCK PackedBpb) 00221 { 00222 CopyUchar2(&Bpb->BytesPerSector, &PackedBpb->BytesPerSector[0]); 00223 CopyUchar1(&Bpb->SectorsPerCluster, &PackedBpb->SectorsPerCluster[0]); 00224 CopyUchar2(&Bpb->ReservedSectors, &PackedBpb->ReservedSectors[0]); 00225 CopyUchar1(&Bpb->Fats, &PackedBpb->Fats[0]); 00226 CopyUchar2(&Bpb->RootEntries, &PackedBpb->RootEntries[0]); 00227 CopyUchar2(&Bpb->Sectors, &PackedBpb->Sectors[0]); 00228 CopyUchar1(&Bpb->Media, &PackedBpb->Media[0]); 00229 CopyUchar2(&Bpb->SectorsPerFat, &PackedBpb->SectorsPerFat[0]); 00230 CopyUchar2(&Bpb->SectorsPerTrack, &PackedBpb->SectorsPerTrack[0]); 00231 CopyUchar2(&Bpb->Heads, &PackedBpb->Heads[0]); 00232 CopyUchar4(&Bpb->HiddenSectors, &PackedBpb->HiddenSectors[0]); 00233 CopyUchar4(&Bpb->LargeSectors, &PackedBpb->LargeSectors[0]); 00234 CopyUchar4(&Bpb->LargeSectorsPerFat, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->LargeSectorsPerFat[0]); 00235 CopyUchar2(&Bpb->ExtendedFlags, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->ExtendedFlags[0]); 00236 CopyUchar2(&Bpb->FsVersion, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->FsVersion[0]); 00237 CopyUchar4(&Bpb->RootDirFirstCluster,&((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->RootDirFirstCluster[0]); 00238 CopyUchar2(&Bpb->FsInfoSector, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->FsInfoSector[0]); 00239 CopyUchar2(&Bpb->BackupBootSector, &((PPACKED_BIOS_PARAMETER_BLOCK_EX)PackedBpb)->BackupBootSector[0]); 00240 } 00241 00242 BOOLEAN 00243 NTAPI 00244 FatiBpbFat32(PPACKED_BIOS_PARAMETER_BLOCK PackedBpb) 00245 { 00246 return (*(USHORT *)(&PackedBpb->SectorsPerFat) == 0); 00247 } 00248 00249 NTSTATUS 00250 NTAPI 00251 FatMountVolume(PFAT_IRP_CONTEXT IrpContext, 00252 PDEVICE_OBJECT TargetDeviceObject, 00253 PVPB Vpb, 00254 PDEVICE_OBJECT FsDeviceObject) 00255 { 00256 NTSTATUS Status; 00257 DISK_GEOMETRY DiskGeometry; 00258 ULONG MediaChangeCount = 0; 00259 PVOLUME_DEVICE_OBJECT VolumeDevice; 00260 VCB *Vcb; 00261 FF_ERROR Error; 00262 PBCB BootBcb; 00263 PPACKED_BOOT_SECTOR BootSector; 00264 00265 DPRINT1("FatMountVolume()\n"); 00266 00267 /* Make sure this IRP is waitable */ 00268 ASSERT(IrpContext->Flags & IRPCONTEXT_CANWAIT); 00269 00270 /* Request media changes count, mostly useful for removable devices */ 00271 Status = FatPerformDevIoCtrl(TargetDeviceObject, 00272 IOCTL_STORAGE_CHECK_VERIFY, 00273 NULL, 00274 0, 00275 &MediaChangeCount, 00276 sizeof(ULONG), 00277 TRUE); 00278 00279 if (!NT_SUCCESS(Status)) return Status; 00280 00281 /* TODO: Check if data-track present in case of a CD drive */ 00282 /* TODO: IOCTL_DISK_GET_PARTITION_INFO_EX */ 00283 00284 /* Remove unmounted VCBs */ 00285 FatiCleanVcbs(IrpContext); 00286 00287 /* Acquire the global exclusive lock */ 00288 FatAcquireExclusiveGlobal(IrpContext); 00289 00290 /* Create a new volume device object */ 00291 Status = IoCreateDevice(FatGlobalData.DriverObject, 00292 sizeof(VOLUME_DEVICE_OBJECT) - sizeof(DEVICE_OBJECT), 00293 NULL, 00294 FILE_DEVICE_DISK_FILE_SYSTEM, 00295 0, 00296 FALSE, 00297 (PDEVICE_OBJECT *)&VolumeDevice); 00298 00299 if (!NT_SUCCESS(Status)) 00300 { 00301 /* Release the global lock */ 00302 FatReleaseGlobal(IrpContext); 00303 00304 return Status; 00305 } 00306 00307 /* Match alignment requirements */ 00308 if (TargetDeviceObject->AlignmentRequirement > VolumeDevice->DeviceObject.AlignmentRequirement) 00309 { 00310 VolumeDevice->DeviceObject.AlignmentRequirement = TargetDeviceObject->AlignmentRequirement; 00311 } 00312 00313 /* Init stack size */ 00314 VolumeDevice->DeviceObject.StackSize = TargetDeviceObject->StackSize + 1; 00315 00316 /* Get sector size */ 00317 Status = FatPerformDevIoCtrl(TargetDeviceObject, 00318 IOCTL_DISK_GET_DRIVE_GEOMETRY, 00319 NULL, 00320 0, 00321 &DiskGeometry, 00322 sizeof(DISK_GEOMETRY), 00323 TRUE); 00324 00325 if (!NT_SUCCESS(Status)) goto FatMountVolumeCleanup; 00326 00327 VolumeDevice->DeviceObject.SectorSize = (USHORT) DiskGeometry.BytesPerSector; 00328 00329 /* Signal we're done with initializing */ 00330 VolumeDevice->DeviceObject.Flags &= ~DO_DEVICE_INITIALIZING; 00331 00332 /* Save device object in a VPB */ 00333 Vpb->DeviceObject = (PDEVICE_OBJECT)VolumeDevice; 00334 00335 /* Initialize VCB for this volume */ 00336 Status = FatInitializeVcb(IrpContext, &VolumeDevice->Vcb, TargetDeviceObject, Vpb); 00337 if (!NT_SUCCESS(Status)) goto FatMountVolumeCleanup; 00338 00339 Vcb = &VolumeDevice->Vcb; 00340 00341 /* Initialize FullFAT library */ 00342 Vcb->Ioman = FF_CreateIOMAN(NULL, 00343 8192, 00344 VolumeDevice->DeviceObject.SectorSize, 00345 &Error); 00346 00347 ASSERT(Vcb->Ioman); 00348 00349 /* Register block device read/write functions */ 00350 Error = FF_RegisterBlkDevice(Vcb->Ioman, 00351 VolumeDevice->DeviceObject.SectorSize, 00352 (FF_WRITE_BLOCKS)FatWriteBlocks, 00353 (FF_READ_BLOCKS)FatReadBlocks, 00354 Vcb); 00355 00356 if (Error) 00357 { 00358 DPRINT1("Registering block device with FullFAT failed with error %d\n", Error); 00359 FF_DestroyIOMAN(Vcb->Ioman); 00360 goto FatMountVolumeCleanup; 00361 } 00362 00363 /* Mount the volume using FullFAT */ 00364 if(FF_MountPartition(Vcb->Ioman, 0)) 00365 { 00366 DPRINT1("Partition mounting failed\n"); 00367 FF_DestroyIOMAN(Vcb->Ioman); 00368 goto FatMountVolumeCleanup; 00369 } 00370 00371 /* Read the boot sector */ 00372 FatReadStreamFile(Vcb, 0, sizeof(PACKED_BOOT_SECTOR), &BootBcb, (PVOID)&BootSector); 00373 00374 /* Check if it's successful */ 00375 if (!BootBcb) 00376 { 00377 Status = STATUS_UNRECOGNIZED_VOLUME; 00378 goto FatMountVolumeCleanup; 00379 } 00380 00381 /* Unpack data */ 00382 FatiUnpackBpb(&Vcb->Bpb, &BootSector->PackedBpb); 00383 00384 /* Verify if sector size matches */ 00385 if (DiskGeometry.BytesPerSector != Vcb->Bpb.BytesPerSector) 00386 { 00387 DPRINT1("Disk geometry BPS %d and bios BPS %d don't match!\n", 00388 DiskGeometry.BytesPerSector, Vcb->Bpb.BytesPerSector); 00389 00390 /* Fail */ 00391 Status = STATUS_UNRECOGNIZED_VOLUME; 00392 goto FatMountVolumeCleanup; 00393 } 00394 00395 /* If Sectors value is set, discard the LargeSectors value */ 00396 if (Vcb->Bpb.Sectors) Vcb->Bpb.LargeSectors = 0; 00397 00398 /* Copy serial number */ 00399 if (FatiBpbFat32(&BootSector->PackedBpb)) 00400 { 00401 CopyUchar4(&Vpb->SerialNumber, ((PPACKED_BOOT_SECTOR_EX)BootSector)->Id); 00402 } 00403 else 00404 { 00405 /* This is FAT12/16 */ 00406 CopyUchar4(&Vpb->SerialNumber, BootSector->Id); 00407 } 00408 00409 /* Unpin the BCB */ 00410 CcUnpinData(BootBcb); 00411 00412 /* Create root DCB for it */ 00413 FatCreateRootDcb(IrpContext, &VolumeDevice->Vcb); 00414 00415 /* Keep trace of media changes */ 00416 VolumeDevice->Vcb.MediaChangeCount = MediaChangeCount; 00417 00418 //ObDereferenceObject(TargetDeviceObject); 00419 00420 /* Release the global lock */ 00421 FatReleaseGlobal(IrpContext); 00422 00423 /* Notify about volume mount */ 00424 //FsRtlNotifyVolumeEvent(VolumeDevice->Vcb.StreamFileObject, FSRTL_VOLUME_MOUNT); 00425 00426 /* Return success */ 00427 return STATUS_SUCCESS; 00428 00429 00430 FatMountVolumeCleanup: 00431 00432 /* Unwind the routine actions */ 00433 IoDeleteDevice((PDEVICE_OBJECT)VolumeDevice); 00434 00435 /* Release the global lock */ 00436 FatReleaseGlobal(IrpContext); 00437 00438 return Status; 00439 } 00440 00441 00442 00443 NTSTATUS 00444 NTAPI 00445 FatiFileSystemControl(PFAT_IRP_CONTEXT IrpContext, PIRP Irp) 00446 { 00447 PIO_STACK_LOCATION IrpSp; 00448 NTSTATUS Status; 00449 00450 /* Get current IRP stack location */ 00451 IrpSp = IoGetCurrentIrpStackLocation(Irp); 00452 00453 /* Dispatch depending on the minor function */ 00454 switch (IrpSp->MinorFunction) 00455 { 00456 case IRP_MN_KERNEL_CALL: 00457 case IRP_MN_USER_FS_REQUEST: 00458 Status = FatUserFsCtrl(IrpContext, Irp); 00459 break; 00460 00461 case IRP_MN_MOUNT_VOLUME: 00462 Status = FatMountVolume(IrpContext, 00463 IrpSp->Parameters.MountVolume.DeviceObject, 00464 IrpSp->Parameters.MountVolume.Vpb, 00465 IrpSp->DeviceObject); 00466 00467 FatCompleteRequest(IrpContext, Irp, Status); 00468 00469 break; 00470 00471 case IRP_MN_VERIFY_VOLUME: 00472 Status = FatVerifyVolume(IrpContext, Irp); 00473 break; 00474 00475 default: 00476 DPRINT1("Unhandled FSCTL minor 0x%x\n", IrpSp->MinorFunction); 00477 FatCompleteRequest(IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST); 00478 Status = STATUS_INVALID_DEVICE_REQUEST; 00479 } 00480 00481 return Status; 00482 } 00483 00484 00485 NTSTATUS 00486 NTAPI 00487 FatFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) 00488 { 00489 NTSTATUS Status = STATUS_SUCCESS; 00490 PFAT_IRP_CONTEXT IrpContext; 00491 BOOLEAN CanWait = TRUE; 00492 00493 DPRINT("FatFileSystemControl(DeviceObject %p, Irp %p)\n", DeviceObject, Irp); 00494 00495 /* Get CanWait flag */ 00496 if (IoGetCurrentIrpStackLocation(Irp)->FileObject) 00497 { 00498 CanWait = IoIsOperationSynchronous(Irp); 00499 } 00500 00501 /* Enter FsRtl critical region */ 00502 FsRtlEnterFileSystem(); 00503 00504 /* Build an irp context */ 00505 IrpContext = FatBuildIrpContext(Irp, CanWait); 00506 00507 /* Call internal function */ 00508 Status = FatiFileSystemControl(IrpContext, Irp); 00509 00510 /* Leave FsRtl critical region */ 00511 FsRtlExitFileSystem(); 00512 00513 return Status; 00514 } Generated on Sun May 27 2012 04:27:36 for ReactOS by
1.7.6.1
|