From ccf76a23c748740d723670f200050617656b186b Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Sun, 22 Nov 2015 12:03:25 -0800 Subject: [PATCH] sys: fsctl.c --- build/VStudio/winfsp.vcxproj | 1 + build/VStudio/winfsp.vcxproj.filters | 3 + inc/winfsp/fsctl.h | 6 +- src/sys/debug.c | 26 ++++-- src/sys/driver.h | 5 ++ src/sys/fsctl.c | 126 ++++++++++++++++----------- src/sys/misc.c | 24 +++++ 7 files changed, 129 insertions(+), 62 deletions(-) create mode 100644 src/sys/misc.c diff --git a/build/VStudio/winfsp.vcxproj b/build/VStudio/winfsp.vcxproj index c78a834a..4a4418c9 100644 --- a/build/VStudio/winfsp.vcxproj +++ b/build/VStudio/winfsp.vcxproj @@ -143,6 +143,7 @@ + diff --git a/build/VStudio/winfsp.vcxproj.filters b/build/VStudio/winfsp.vcxproj.filters index a144f466..f49c593f 100644 --- a/build/VStudio/winfsp.vcxproj.filters +++ b/build/VStudio/winfsp.vcxproj.filters @@ -71,6 +71,9 @@ Source + + Source + diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index 6ff2a3b3..347f39f9 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -19,11 +19,13 @@ extern const __declspec(selectany) GUID FspDeviceClassGuid = /* fsctl device codes */ #define FSP_FSCTL_CREATE \ CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'C', METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA) -#define FSP_FSCTL_DELETE \ - CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'D', METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA) /* fsvrt device codes */ +#define FSP_FSCTL_DELETE \ + CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'D', METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA) #define FSP_FSCTL_TRANSACT \ CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800 + 'T', METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA) +#define FSP_FSCTL_CREATE_BUFFER_SIZEMAX 64 + #endif diff --git a/src/sys/debug.c b/src/sys/debug.c index 6827eb90..aae2ace2 100644 --- a/src/sys/debug.c +++ b/src/sys/debug.c @@ -86,7 +86,7 @@ const char *IrpMinorFunctionSym(UCHAR MajorFunction, UCHAR MinorFunction) SYMBRC(IRP_MN_COMPLETE_MDL) SYMBRC(IRP_MN_COMPLETE_MDL_DPC) default: - return "[Unknown]"; + return "[IRP_MN:Unknown]"; } case IRP_MJ_DIRECTORY_CONTROL: switch (MinorFunction) @@ -94,7 +94,7 @@ const char *IrpMinorFunctionSym(UCHAR MajorFunction, UCHAR MinorFunction) SYMBRC(IRP_MN_QUERY_DIRECTORY) SYMBRC(IRP_MN_NOTIFY_CHANGE_DIRECTORY) default: - return "[Unknown]"; + return "[IRP_MN:Unknown]"; } case IRP_MJ_FILE_SYSTEM_CONTROL: switch (MinorFunction) @@ -105,7 +105,7 @@ const char *IrpMinorFunctionSym(UCHAR MajorFunction, UCHAR MinorFunction) SYMBRC(IRP_MN_LOAD_FILE_SYSTEM) SYMBRC(IRP_MN_KERNEL_CALL) default: - return "[Unknown]"; + return "[IRP_MN:Unknown]"; } case IRP_MJ_LOCK_CONTROL: switch (MinorFunction) @@ -115,7 +115,7 @@ const char *IrpMinorFunctionSym(UCHAR MajorFunction, UCHAR MinorFunction) SYMBRC(IRP_MN_UNLOCK_ALL) SYMBRC(IRP_MN_UNLOCK_ALL_BY_KEY) default: - return "[Unknown]"; + return "[IRP_MN:Unknown]"; } case IRP_MJ_POWER: switch (MinorFunction) @@ -125,7 +125,7 @@ const char *IrpMinorFunctionSym(UCHAR MajorFunction, UCHAR MinorFunction) SYMBRC(IRP_MN_SET_POWER) SYMBRC(IRP_MN_QUERY_POWER) default: - return "[Unknown]"; + return "[IRP_MN:Unknown]"; } case IRP_MJ_SYSTEM_CONTROL: switch (MinorFunction) @@ -142,7 +142,7 @@ const char *IrpMinorFunctionSym(UCHAR MajorFunction, UCHAR MinorFunction) SYMBRC(IRP_MN_EXECUTE_METHOD) SYMBRC(IRP_MN_REGINFO_EX) default: - return "[Unknown]"; + return "[IRP_MN:Unknown]"; } case IRP_MJ_PNP: switch (MinorFunction) @@ -153,10 +153,22 @@ const char *IrpMinorFunctionSym(UCHAR MajorFunction, UCHAR MinorFunction) SYMBRC(IRP_MN_CANCEL_REMOVE_DEVICE) SYMBRC(IRP_MN_SURPRISE_REMOVAL) default: - return "[Unknown]"; + return "[IRP_MN:Unknown]"; } default: return ""; } } + +const char *IoctlCodeSym(ULONG ControlCode) +{ + switch (ControlCode) + { + SYM(FSP_FSCTL_CREATE) + SYM(FSP_FSCTL_DELETE) + SYM(FSP_FSCTL_TRANSACT) + default: + return "IOCTL:Unknown"; + } +} #endif diff --git a/src/sys/driver.h b/src/sys/driver.h index 3349e7c6..652e4925 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -8,6 +8,7 @@ #define WINFSP_SYS_DRIVER_H_INCLUDED #include +#include #include #include @@ -176,12 +177,16 @@ FAST_IO_RELEASE_FOR_MOD_WRITE FspReleaseForModWrite; FAST_IO_ACQUIRE_FOR_CCFLUSH FspAcquireForCcFlush; FAST_IO_RELEASE_FOR_CCFLUSH FspReleaseForCcFlush; +/* misc */ +NTSTATUS CreateGuid(GUID *Guid); + /* debug */ #if DBG BOOLEAN HasDbgBreakPoint(const char *Function); const char *NtStatusSym(NTSTATUS Status); const char *IrpMajorFunctionSym(UCHAR MajorFunction); const char *IrpMinorFunctionSym(UCHAR MajorFunction, UCHAR MinorFunction); +const char *IoctlCodeSym(ULONG ControlCode); #endif /* extern */ diff --git a/src/sys/fsctl.c b/src/sys/fsctl.c index 0c1aafc8..60bca7e0 100644 --- a/src/sys/fsctl.c +++ b/src/sys/fsctl.c @@ -6,23 +6,23 @@ #include -static -NTSTATUS -FspFsctlCreateVolume(PDEVICE_OBJECT DeviceObject, PIO_STACK_LOCATION IrpSp); -static -NTSTATUS -FspFsctlDeleteVolume(PDEVICE_OBJECT DeviceObject, PIO_STACK_LOCATION IrpSp); -static -NTSTATUS -FspFsvolTransact(PDEVICE_OBJECT DeviceObject, PIO_STACK_LOCATION IrpSp); -static DRIVER_DISPATCH FspFsctlFileSystemControl; -static DRIVER_DISPATCH FspFsvrtFileSystemControl; -static DRIVER_DISPATCH FspFsvolFileSystemControl; +static NTSTATUS FspFsctlCreateVolume( + PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); +static NTSTATUS FspFsvolDeleteVolume( + PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); +static NTSTATUS FspFsvolTransact( + PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); +static NTSTATUS FspFsctlFileSystemControl( + PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); +static NTSTATUS FspFsvrtFileSystemControl( + PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); +static NTSTATUS FspFsvolFileSystemControl( + PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); DRIVER_DISPATCH FspFileSystemControl; #ifdef ALLOC_PRAGMA #pragma alloc_text(PAGE, FspFsctlCreateVolume) -#pragma alloc_text(PAGE, FspFsctlDeleteVolume) +#pragma alloc_text(PAGE, FspFsvolDeleteVolume) #pragma alloc_text(PAGE, FspFsvolTransact) #pragma alloc_text(PAGE, FspFsctlFileSystemControl) #pragma alloc_text(PAGE, FspFsvrtFileSystemControl) @@ -30,66 +30,85 @@ DRIVER_DISPATCH FspFileSystemControl; #pragma alloc_text(PAGE, FspFileSystemControl) #endif -static -NTSTATUS -FspFsctlCreateVolume(PDEVICE_OBJECT DeviceObject, PIO_STACK_LOCATION IrpSp) +static NTSTATUS FspFsctlCreateVolume( + PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) +{ + if (FSP_FSCTL_CREATE_BUFFER_SIZEMAX > IrpSp->Parameters.FileSystemControl.OutputBufferLength) + return STATUS_BUFFER_TOO_SMALL; + + NTSTATUS Result; + + GUID Guid; + Result = CreateGuid(&Guid); + if (!NT_SUCCESS(Result)) + return Result; + + PDEVICE_OBJECT FsvrtDeviceObject; + UNICODE_STRING DeviceSddl; + UNICODE_STRING DeviceName; + RtlInitUnicodeString(&DeviceSddl, L"" DEVICE_SDDL); + RtlInitEmptyUnicodeString(&DeviceName, Irp->AssociatedIrp.SystemBuffer, FSP_FSCTL_CREATE_BUFFER_SIZEMAX); + Result = RtlUnicodeStringPrintf(&DeviceName, + L"\\Device\\Volume{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + Guid.Data1, Guid.Data2, Guid.Data3, + Guid.Data4[0], Guid.Data4[1], Guid.Data4[2], Guid.Data4[3], + Guid.Data4[4], Guid.Data4[5], Guid.Data4[6], Guid.Data4[7]); + ASSERT(NT_SUCCESS(Result)); + Result = IoCreateDeviceSecure(DeviceObject->DriverObject, + sizeof(FSP_FSVRT_DEVICE_EXTENSION), &DeviceName, DeviceObject->DeviceType, 0, FALSE, + &DeviceSddl, 0, + &FsvrtDeviceObject); + if (!NT_SUCCESS(Result)) + return Result; + FspDeviceExtension(FsvrtDeviceObject)->Kind = FspFsvrtDeviceExtensionKind; + Irp->IoStatus.Information = DeviceName.Length + 1; + + return Result; +} + +static NTSTATUS FspFsvolDeleteVolume( + PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) { return STATUS_INVALID_DEVICE_REQUEST; } -static -NTSTATUS -FspFsctlDeleteVolume(PDEVICE_OBJECT DeviceObject, PIO_STACK_LOCATION IrpSp) +static NTSTATUS FspFsvolTransact( + PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) { return STATUS_INVALID_DEVICE_REQUEST; } -static -NTSTATUS -FspFsvolTransact(PDEVICE_OBJECT DeviceObject, PIO_STACK_LOCATION IrpSp) -{ - return STATUS_INVALID_DEVICE_REQUEST; -} - -static -NTSTATUS -FspFsctlFileSystemControl( - _In_ PDEVICE_OBJECT DeviceObject, - _In_ PIRP Irp) +static NTSTATUS FspFsctlFileSystemControl( + PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) { NTSTATUS Result = STATUS_INVALID_DEVICE_REQUEST; - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); switch (IrpSp->MinorFunction) { case IRP_MN_USER_FS_REQUEST: switch (IrpSp->Parameters.FileSystemControl.FsControlCode) { case FSP_FSCTL_CREATE: - Result = FspFsctlCreateVolume(DeviceObject, IrpSp); - break; - case FSP_FSCTL_DELETE: - Result = FspFsctlDeleteVolume(DeviceObject, IrpSp); + Result = FspFsctlCreateVolume(DeviceObject, Irp, IrpSp); break; } } return Result; } -static -NTSTATUS -FspFsvrtFileSystemControl( - _In_ PDEVICE_OBJECT DeviceObject, - _In_ PIRP Irp) +static NTSTATUS FspFsvrtFileSystemControl( + PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) { NTSTATUS Result = STATUS_INVALID_DEVICE_REQUEST; - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); switch (IrpSp->MinorFunction) { case IRP_MN_USER_FS_REQUEST: switch (IrpSp->Parameters.FileSystemControl.FsControlCode) { + case FSP_FSCTL_DELETE: + Result = FspFsvolDeleteVolume(DeviceObject, Irp, IrpSp); + break; case FSP_FSCTL_TRANSACT: - Result = FspFsvolTransact(DeviceObject, IrpSp); + Result = FspFsvolTransact(DeviceObject, Irp, IrpSp); break; } break; @@ -97,14 +116,10 @@ FspFsvrtFileSystemControl( return Result; } -static -NTSTATUS -FspFsvolFileSystemControl( - _In_ PDEVICE_OBJECT DeviceObject, - _In_ PIRP Irp) +static NTSTATUS FspFsvolFileSystemControl( + PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) { NTSTATUS Result = STATUS_INVALID_DEVICE_REQUEST; - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); switch (IrpSp->MinorFunction) { case IRP_MN_USER_FS_REQUEST: @@ -129,14 +144,19 @@ FspFileSystemControl( switch (FspDeviceExtension(DeviceObject)->Kind) { case FspFsvolDeviceExtensionKind: - FSP_RETURN(Result = FspFsctlFileSystemControl(DeviceObject, Irp)); + FSP_RETURN(Result = FspFsctlFileSystemControl(DeviceObject, Irp, IrpSp)); case FspFsvrtDeviceExtensionKind: - FSP_RETURN(Result = FspFsvrtFileSystemControl(DeviceObject, Irp)); + FSP_RETURN(Result = FspFsvrtFileSystemControl(DeviceObject, Irp, IrpSp)); case FspFsctlDeviceExtensionKind: - FSP_RETURN(Result = FspFsvolFileSystemControl(DeviceObject, Irp)); + FSP_RETURN(Result = FspFsvolFileSystemControl(DeviceObject, Irp, IrpSp)); default: FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST); } - FSP_LEAVE_MJ("", 0); + FSP_LEAVE_MJ( + "FileObject=%p%s%s", + IrpSp->FileObject, + IRP_MN_USER_FS_REQUEST == IrpSp->MinorFunction ? ", " : "", + IRP_MN_USER_FS_REQUEST == IrpSp->MinorFunction ? + IoctlCodeSym(IrpSp->Parameters.FileSystemControl.FsControlCode) : ""); } diff --git a/src/sys/misc.c b/src/sys/misc.c new file mode 100644 index 00000000..14a71d91 --- /dev/null +++ b/src/sys/misc.c @@ -0,0 +1,24 @@ +/** + * @file sys/misc.c + * + * @copyright 2015 Bill Zissimopoulos + */ + +#include + +NTSTATUS CreateGuid(GUID *Guid); + +#ifdef ALLOC_PRAGMA +#pragma alloc_text(PAGE, CreateGuid) +#endif + +NTSTATUS CreateGuid(GUID *Guid) +{ + NTSTATUS Result; + int Retries = 3; + do + { + Result = ExUuidCreate(Guid); + } while (!NT_SUCCESS(Result) && 0 < --Retries); + return Result; +}