ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

fsctl.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.