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

NTSTATUS NTAPI FatMountVolume ( PFAT_IRP_CONTEXT  IrpContext,
PDEVICE_OBJECT  TargetDeviceObject,
PVPB  Vpb,
PDEVICE_OBJECT  FsDeviceObject 
)

Definition at line 251 of file fsctl.c.

Referenced by FatiFileSystemControl().

{
    NTSTATUS Status;
    DISK_GEOMETRY DiskGeometry;
    ULONG MediaChangeCount = 0;
    PVOLUME_DEVICE_OBJECT VolumeDevice;
    VCB *Vcb;
    FF_ERROR Error;
    PBCB BootBcb;
    PPACKED_BOOT_SECTOR BootSector;

    DPRINT1("FatMountVolume()\n");

    /* Make sure this IRP is waitable */
    ASSERT(IrpContext->Flags & IRPCONTEXT_CANWAIT);

    /* Request media changes count, mostly useful for removable devices */
    Status = FatPerformDevIoCtrl(TargetDeviceObject,
                                 IOCTL_STORAGE_CHECK_VERIFY,
                                 NULL,
                                 0,
                                 &MediaChangeCount,
                                 sizeof(ULONG),
                                 TRUE);

    if (!NT_SUCCESS(Status)) return Status;

    /* TODO: Check if data-track present in case of a CD drive */
    /* TODO: IOCTL_DISK_GET_PARTITION_INFO_EX */

    /* Remove unmounted VCBs */
    FatiCleanVcbs(IrpContext);

    /* Acquire the global exclusive lock */
    FatAcquireExclusiveGlobal(IrpContext);

    /* Create a new volume device object */
    Status = IoCreateDevice(FatGlobalData.DriverObject,
                            sizeof(VOLUME_DEVICE_OBJECT) - sizeof(DEVICE_OBJECT),
                            NULL,
                            FILE_DEVICE_DISK_FILE_SYSTEM,
                            0,
                            FALSE,
                            (PDEVICE_OBJECT *)&VolumeDevice);

    if (!NT_SUCCESS(Status))
    {
        /* Release the global lock */
        FatReleaseGlobal(IrpContext);

        return Status;
    }

    /* Match alignment requirements */
    if (TargetDeviceObject->AlignmentRequirement > VolumeDevice->DeviceObject.AlignmentRequirement)
    {
        VolumeDevice->DeviceObject.AlignmentRequirement = TargetDeviceObject->AlignmentRequirement;
    }

    /* Init stack size */
    VolumeDevice->DeviceObject.StackSize = TargetDeviceObject->StackSize + 1;

    /* Get sector size */
    Status = FatPerformDevIoCtrl(TargetDeviceObject,
                                 IOCTL_DISK_GET_DRIVE_GEOMETRY,
                                 NULL,
                                 0,
                                 &DiskGeometry,
                                 sizeof(DISK_GEOMETRY),
                                 TRUE);

    if (!NT_SUCCESS(Status)) goto FatMountVolumeCleanup;

    VolumeDevice->DeviceObject.SectorSize = (USHORT) DiskGeometry.BytesPerSector;

    /* Signal we're done with initializing */
    VolumeDevice->DeviceObject.Flags &= ~DO_DEVICE_INITIALIZING;

    /* Save device object in a VPB */
    Vpb->DeviceObject = (PDEVICE_OBJECT)VolumeDevice;

    /* Initialize VCB for this volume */
    Status = FatInitializeVcb(IrpContext, &VolumeDevice->Vcb, TargetDeviceObject, Vpb);
    if (!NT_SUCCESS(Status)) goto FatMountVolumeCleanup;

    Vcb = &VolumeDevice->Vcb;

    /* Initialize FullFAT library */
    Vcb->Ioman = FF_CreateIOMAN(NULL,
                                8192,
                                VolumeDevice->DeviceObject.SectorSize,
                                &Error);

    ASSERT(Vcb->Ioman);

    /* Register block device read/write functions */
    Error = FF_RegisterBlkDevice(Vcb->Ioman,
                                 VolumeDevice->DeviceObject.SectorSize,
                                 (FF_WRITE_BLOCKS)FatWriteBlocks,
                                 (FF_READ_BLOCKS)FatReadBlocks,
                                 Vcb);

    if (Error)
    {
        DPRINT1("Registering block device with FullFAT failed with error %d\n", Error);
        FF_DestroyIOMAN(Vcb->Ioman);
        goto FatMountVolumeCleanup;
    }

    /* Mount the volume using FullFAT */
    if(FF_MountPartition(Vcb->Ioman, 0))
    {
        DPRINT1("Partition mounting failed\n");
        FF_DestroyIOMAN(Vcb->Ioman);
        goto FatMountVolumeCleanup;
    }

    /* Read the boot sector */
    FatReadStreamFile(Vcb, 0, sizeof(PACKED_BOOT_SECTOR), &BootBcb, (PVOID)&BootSector);

    /* Check if it's successful */
    if (!BootBcb)
    {
        Status = STATUS_UNRECOGNIZED_VOLUME;
        goto FatMountVolumeCleanup;
    }

    /* Unpack data */
    FatiUnpackBpb(&Vcb->Bpb, &BootSector->PackedBpb);

    /* Verify if sector size matches */
    if (DiskGeometry.BytesPerSector != Vcb->Bpb.BytesPerSector)
    {
        DPRINT1("Disk geometry BPS %d and bios BPS %d don't match!\n",
            DiskGeometry.BytesPerSector, Vcb->Bpb.BytesPerSector);

        /* Fail */
        Status = STATUS_UNRECOGNIZED_VOLUME;
        goto FatMountVolumeCleanup;
    }

    /* If Sectors value is set, discard the LargeSectors value */
    if (Vcb->Bpb.Sectors) Vcb->Bpb.LargeSectors = 0;

    /* Copy serial number */
    if (FatiBpbFat32(&BootSector->PackedBpb))
    {
        CopyUchar4(&Vpb->SerialNumber, ((PPACKED_BOOT_SECTOR_EX)BootSector)->Id);
    }
    else
    {
        /* This is FAT12/16 */
        CopyUchar4(&Vpb->SerialNumber, BootSector->Id);
    }

    /* Unpin the BCB */
    CcUnpinData(BootBcb);

    /* Create root DCB for it */
    FatCreateRootDcb(IrpContext, &VolumeDevice->Vcb);

    /* Keep trace of media changes */
    VolumeDevice->Vcb.MediaChangeCount = MediaChangeCount;

    //ObDereferenceObject(TargetDeviceObject);

    /* Release the global lock */
    FatReleaseGlobal(IrpContext);

    /* Notify about volume mount */
    //FsRtlNotifyVolumeEvent(VolumeDevice->Vcb.StreamFileObject, FSRTL_VOLUME_MOUNT);

    /* Return success */
    return STATUS_SUCCESS;


FatMountVolumeCleanup:

    /* Unwind the routine actions */
    IoDeleteDevice((PDEVICE_OBJECT)VolumeDevice);

    /* Release the global lock */
    FatReleaseGlobal(IrpContext);

    return Status;
}

Generated on Sun May 27 2012 05:23:31 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.