Exemplo n.º 1
0
static BT_HANDLE fullfat_mount(BT_HANDLE hFS, BT_HANDLE hVolume, BT_ERROR *pError) {

	FF_ERROR ffError;
	BT_ERROR Error = BT_ERR_GENERIC;
	BT_FF_MOUNT *pMount = (BT_FF_MOUNT *) BT_CreateHandle(&oHandleInterface, sizeof(BT_FF_MOUNT), pError);
	if(!pMount) {
		return NULL;
	}

	pMount->pBlockCache = BT_kMalloc(8192);
	pMount->hVolume = hVolume;
	pMount->pIoman = FF_CreateIOMAN(pMount->pBlockCache, 8192, 512, &ffError);
	if(!pMount->pIoman) {
		Error = BT_ERR_GENERIC;
		goto err_free_out;
	}

	ffError = FF_RegisterBlkDevice(pMount->pIoman, 512, fullfat_writeblocks, fullfat_readblocks, pMount);

	ffError = FF_MountPartition(pMount->pIoman, 0);

return (BT_HANDLE) pMount;

err_free_out:
	BT_kFree(pMount->pBlockCache);
	BT_DestroyHandle((BT_HANDLE)pMount);

	*pError = Error;
	return NULL;
}
Exemplo n.º 2
0
/**
 * @public
 * @brief	Mounts and Image with FullFAT.
 *
 *
 **/
DLL_EXPORT int FFC_MountImage(char *szFilename, unsigned long ulBlockSize, unsigned long ulPartitionNumber) {

	FF_ERROR Error = FF_ERR_NONE;

	if(g_pIoman || g_hDisk) {
		return FFD_ERR_IMAGE_ALREADY_MOUNTED;
	}

	g_hDisk = fnOpen(szFilename, ulBlockSize);

	if(!g_hDisk) {
		return FFD_ERR_COULD_NOT_OPEN_IMAGE;
	}
	
	g_pIoman = FF_CreateIOMAN(NULL, 8192, GetBlockSize(g_hDisk), &Error);	// Using the BlockSize from the Device Driver (see blkdev_win32.c)

	if(!g_pIoman) {
		return FFD_ERR_COULD_NOT_INITIALISE_FULLFAT;
	} else {
		Error = FF_RegisterBlkDevice(g_pIoman, GetBlockSize(g_hDisk), (FF_WRITE_BLOCKS) fnWrite, (FF_READ_BLOCKS) fnRead, g_hDisk);

		if(Error) {
			printError(Error);

			FF_DestroyIOMAN(g_pIoman);
			fnClose(g_hDisk);

			return -1;
		}

		// Attempt to mount!

		Error = FF_MountPartition(g_pIoman, (FF_T_UINT8) ulPartitionNumber);
		if(Error) {
			if(g_hDisk) {
				fnClose(g_hDisk);
			}
			FF_DestroyIOMAN(g_pIoman);
			g_pIoman = NULL;
			return -1;
		}

		g_Env.pIoman = g_pIoman;
		strcpy(g_Env.WorkingDir, "\\");	// Reset working dir!
	}

	return FFD_ERR_NONE;
}
Exemplo n.º 3
0
NTSTATUS
NTAPI
FatMountVolume(PFAT_IRP_CONTEXT IrpContext,
               PDEVICE_OBJECT TargetDeviceObject,
               PVPB Vpb,
               PDEVICE_OBJECT FsDeviceObject)
{
    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;
}