diff --git a/src/sys/driver.h b/src/sys/driver.h index d168cf5d..e6f20591 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -290,6 +290,12 @@ VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response); NTSTATUS FspCreateGuid(GUID *Guid); NTSTATUS FspSecuritySubjectContextAccessCheck( PSECURITY_DESCRIPTOR SecurityDescriptor, ACCESS_MASK DesiredAccess, KPROCESSOR_MODE AccessMode); +NTSTATUS FspCreateDeviceObjectList( + PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount); +VOID FspDeleteDeviceObjectList( + PDEVICE_OBJECT *DeviceObjects, ULONG DeviceObjectCount); +NTSTATUS FspHasDeviceObject( + PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT DeviceObject); /* debug */ #if DBG diff --git a/src/sys/fsctl.c b/src/sys/fsctl.c index fb6f2b33..c38046ac 100644 --- a/src/sys/fsctl.c +++ b/src/sys/fsctl.c @@ -8,6 +8,8 @@ static NTSTATUS FspFsctlCreateVolume( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); +static NTSTATUS FspFsctlMountVolume( + PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); static NTSTATUS FspFsvrtDeleteVolume( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); static NTSTATUS FspFsvrtTransact( @@ -23,6 +25,7 @@ FSP_IOCMPL_DISPATCH FspFileSystemControlComplete; #ifdef ALLOC_PRAGMA #pragma alloc_text(PAGE, FspFsctlCreateVolume) +#pragma alloc_text(PAGE, FspFsctlMountVolume) #pragma alloc_text(PAGE, FspFsvrtDeleteVolume) #pragma alloc_text(PAGE, FspFsvrtTransact) #pragma alloc_text(PAGE, FspFsctlFileSystemControl) @@ -95,6 +98,29 @@ static NTSTATUS FspFsctlCreateVolume( return Result; } +static NTSTATUS FspFsctlMountVolume( + PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) +{ + PAGED_CODE(); + + NTSTATUS Result; + PDEVICE_OBJECT RealDevice = IrpSp->Parameters.MountVolume.DeviceObject; + + /* check the passed in volume object; it must be one of our own */ + Result = FspHasDeviceObject(DeviceObject->DriverObject, RealDevice); + if (!NT_SUCCESS(Result)) + { + if (STATUS_NO_SUCH_DEVICE == Result) + return STATUS_INVALID_PARAMETER; + else + return Result; + } + if (FILE_DEVICE_VIRTUAL_DISK != RealDevice->DeviceType) + return STATUS_INVALID_PARAMETER; + + return Result; +} + static NTSTATUS FspFsvrtDeleteVolume( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) { @@ -224,6 +250,14 @@ static NTSTATUS FspFsctlFileSystemControl( Result = FspFsctlCreateVolume(DeviceObject, Irp, IrpSp); break; } + break; + case IRP_MN_MOUNT_VOLUME: + Result = FspFsctlMountVolume(DeviceObject, Irp, IrpSp); + break; +#if 0 + case IRP_MN_VERIFY_VOLUME: + break; +#endif } return Result; } @@ -261,10 +295,6 @@ static NTSTATUS FspFsvolFileSystemControl( { case IRP_MN_USER_FS_REQUEST: break; - case IRP_MN_MOUNT_VOLUME: - break; - case IRP_MN_VERIFY_VOLUME: - break; } return Result; } diff --git a/src/sys/misc.c b/src/sys/misc.c index 6749a5d5..16e9ed38 100644 --- a/src/sys/misc.c +++ b/src/sys/misc.c @@ -49,3 +49,59 @@ NTSTATUS FspSecuritySubjectContextAccessCheck( return Result; } + +NTSTATUS FspCreateDeviceObjectList( + PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount) +{ + PDEVICE_OBJECT *DeviceObjects = 0; + ULONG DeviceObjectCount = 0; + + while (STATUS_BUFFER_TOO_SMALL == IoEnumerateDeviceObjectList(DriverObject, + DeviceObjects, DeviceObjectCount, &DeviceObjectCount)) + { + if (0 != DeviceObjects) + ExFreePoolWithTag(DeviceObjects, FSP_TAG); + DeviceObjects = ExAllocatePoolWithTag(NonPagedPool, + sizeof *DeviceObjects * DeviceObjectCount, FSP_TAG); + if (0 == DeviceObjects) + return STATUS_INSUFFICIENT_RESOURCES; + RtlZeroMemory(DeviceObjects, sizeof *DeviceObjects * DeviceObjectCount); + } + + *PDeviceObjects = DeviceObjects; + *PDeviceObjectCount = DeviceObjectCount; + + return STATUS_SUCCESS; +} + +VOID FspDeleteDeviceObjectList( + PDEVICE_OBJECT *DeviceObjects, ULONG DeviceObjectCount) +{ + for (ULONG i = 0; DeviceObjectCount > i; i++) + ObDereferenceObject(DeviceObjects[i]); + + ExFreePoolWithTag(DeviceObjects, FSP_TAG); +} + +NTSTATUS FspHasDeviceObject( + PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT DeviceObject) +{ + NTSTATUS Result = STATUS_NO_SUCH_DEVICE; + PDEVICE_OBJECT *DeviceObjects = 0; + ULONG DeviceObjectCount = 0; + + Result = FspCreateDeviceObjectList(DriverObject, &DeviceObjects, &DeviceObjectCount); + if (!NT_SUCCESS(Result)) + return Result; + + for (ULONG i = 0; DeviceObjectCount > i; i++) + if (DeviceObjects[i] == DeviceObject) + { + Result = STATUS_SUCCESS; + break; + } + + FspDeleteDeviceObjectList(DeviceObjects, DeviceObjectCount); + + return Result; +}