Home | Info | Community | Development | myReactOS | Contact Us
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; }