From f4de97f3c6c9a006fbf05e8d4a69dde0bb0cf1f9 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Sun, 29 Nov 2015 13:21:32 -0800 Subject: [PATCH] sys: FspFsctlMountVolume --- src/dll/fsctl.c | 4 ++-- src/sys/driver.h | 4 ++++ src/sys/fsctl.c | 41 +++++++++++++++++++++++++++++++++++++---- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/dll/fsctl.c b/src/dll/fsctl.c index d2a6268b..48584218 100644 --- a/src/dll/fsctl.c +++ b/src/dll/fsctl.c @@ -48,7 +48,7 @@ FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, *ParamsBuf = *Params; DeviceHandle = CreateFileW(DevicePathBuf, - 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0); + 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); if (INVALID_HANDLE_VALUE == DeviceHandle) { Result = FspNtStatusFromWin32(GetLastError()); @@ -84,7 +84,7 @@ FSP_API NTSTATUS FspFsctlOpenVolume(PWSTR VolumePath, GlobalDevicePath(DevicePathBuf, sizeof DevicePathBuf, VolumePath); VolumeHandle = CreateFileW(DevicePathBuf, - 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, 0); + 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); if (INVALID_HANDLE_VALUE == VolumeHandle) { Result = FspNtStatusFromWin32(GetLastError()); diff --git a/src/sys/driver.h b/src/sys/driver.h index 28e35b4e..9d8f0be2 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -261,6 +261,7 @@ typedef struct { FSP_DEVICE_EXTENSION Base; PDEVICE_OBJECT FsvrtDeviceObject; + PVPB SwapVpb; } FSP_FSVOL_DEVICE_EXTENSION; static inline FSP_DEVICE_EXTENSION *FspDeviceExtension(PDEVICE_OBJECT DeviceObject) @@ -270,16 +271,19 @@ FSP_DEVICE_EXTENSION *FspDeviceExtension(PDEVICE_OBJECT DeviceObject) static inline FSP_FSCTL_DEVICE_EXTENSION *FspFsctlDeviceExtension(PDEVICE_OBJECT DeviceObject) { + ASSERT(FspFsctlDeviceExtensionKind == ((FSP_DEVICE_EXTENSION *)DeviceObject->DeviceExtension)->Kind); return DeviceObject->DeviceExtension; } static inline FSP_FSVRT_DEVICE_EXTENSION *FspFsvrtDeviceExtension(PDEVICE_OBJECT DeviceObject) { + ASSERT(FspFsvrtDeviceExtensionKind == ((FSP_DEVICE_EXTENSION *)DeviceObject->DeviceExtension)->Kind); return DeviceObject->DeviceExtension; } static inline FSP_FSVOL_DEVICE_EXTENSION *FspFsvolDeviceExtension(PDEVICE_OBJECT DeviceObject) { + ASSERT(FspFsvolDeviceExtensionKind == ((FSP_DEVICE_EXTENSION *)DeviceObject->DeviceExtension)->Kind); return DeviceObject->DeviceExtension; } diff --git a/src/sys/fsctl.c b/src/sys/fsctl.c index ccdd82ca..a1eb6f29 100644 --- a/src/sys/fsctl.c +++ b/src/sys/fsctl.c @@ -93,7 +93,7 @@ static NTSTATUS FspFsctlCreateVolume( FspIoqInitialize(&FsvrtDeviceExtension->Ioq); RtlCopyMemory(FspFsvrtDeviceExtension(FsvrtDeviceObject)->SecurityDescriptorBuf, SecurityDescriptorBuf, SecurityDescriptorSize); - ClearFlag(FsvrtDeviceObject->DO_DEVICE_INITIALIZING); + ClearFlag(FsvrtDeviceObject->Flags, DO_DEVICE_INITIALIZING); Irp->IoStatus.Information = DeviceName.Length + 1; } @@ -109,10 +109,14 @@ static NTSTATUS FspFsctlMountVolume( PAGED_CODE(); NTSTATUS Result; - PDEVICE_OBJECT RealDevice = IrpSp->Parameters.MountVolume.Vpb->RealDevice; + PVPB Vpb = IrpSp->Parameters.MountVolume.Vpb; + PVPB SwapVpb = 0; + PDEVICE_OBJECT FsvrtDeviceObject = Vpb->RealDevice; + PDEVICE_OBJECT FsvolDeviceObject; + FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension; /* check the passed in volume object; it must be one of our own */ - Result = FspHasDeviceObject(DeviceObject->DriverObject, RealDevice); + Result = FspHasDeviceObject(DeviceObject->DriverObject, FsvrtDeviceObject); if (!NT_SUCCESS(Result)) { if (STATUS_NO_SUCH_DEVICE == Result) @@ -120,9 +124,38 @@ static NTSTATUS FspFsctlMountVolume( else return Result; } - if (FILE_DEVICE_VIRTUAL_DISK != RealDevice->DeviceType) + if (FILE_DEVICE_VIRTUAL_DISK != FsvrtDeviceObject->DeviceType) return STATUS_UNRECOGNIZED_VOLUME; + /* preallocate swap VPB */ + SwapVpb = ExAllocatePoolWithTag(NonPagedPool, sizeof *SwapVpb, FSP_TAG); + if (0 == SwapVpb) + return STATUS_INSUFFICIENT_RESOURCES; + RtlZeroMemory(SwapVpb, sizeof *Vpb); + + /* create the file system device object */ + Result = IoCreateDevice(DeviceObject->DriverObject, + sizeof(FSP_FSVOL_DEVICE_EXTENSION), 0, DeviceObject->DeviceType, + 0, FALSE, + &FsvolDeviceObject); + if (NT_SUCCESS(Result)) + { + FsvolDeviceObject->SectorSize = + FspFsvrtDeviceExtension(FsvrtDeviceObject)->VolumeParams.SectorSize; + FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); + FsvolDeviceExtension->FsvrtDeviceObject = FsvrtDeviceObject; + FsvolDeviceExtension->SwapVpb = SwapVpb; + ClearFlag(FsvolDeviceObject->Flags, DO_DEVICE_INITIALIZING); + Vpb->VolumeLabelLength = 0; + Vpb->DeviceObject = FsvolDeviceObject; + Irp->IoStatus.Information = 0; + SwapVpb = 0; + } + + /* free swap VPB if we failed */ + if (0 != SwapVpb) + ExFreePoolWithTag(SwapVpb, FSP_TAG); + return Result; }