From 42762d49eae473ddf3883e1b74c6218266e9707e Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Wed, 23 Dec 2015 12:08:50 -0800 Subject: [PATCH] dll: Major refactoring: WIP --- build/VStudio/winfsp_dll.vcxproj | 1 + build/VStudio/winfsp_dll.vcxproj.filters | 3 + src/dll/fsctl.c | 110 +++++++++++++++++++++++ src/dll/library.h | 8 -- src/sys/volume.c | 3 +- 5 files changed, 116 insertions(+), 9 deletions(-) create mode 100644 src/dll/fsctl.c diff --git a/build/VStudio/winfsp_dll.vcxproj b/build/VStudio/winfsp_dll.vcxproj index e4ee655d..f020d1aa 100644 --- a/build/VStudio/winfsp_dll.vcxproj +++ b/build/VStudio/winfsp_dll.vcxproj @@ -25,6 +25,7 @@ + diff --git a/build/VStudio/winfsp_dll.vcxproj.filters b/build/VStudio/winfsp_dll.vcxproj.filters index 77379d2c..9b711ee0 100644 --- a/build/VStudio/winfsp_dll.vcxproj.filters +++ b/build/VStudio/winfsp_dll.vcxproj.filters @@ -34,6 +34,9 @@ Source + + Source + diff --git a/src/dll/fsctl.c b/src/dll/fsctl.c new file mode 100644 index 00000000..89f66c95 --- /dev/null +++ b/src/dll/fsctl.c @@ -0,0 +1,110 @@ +/** + * @file dll/fsctl.c + * + * @copyright 2015 Bill Zissimopoulos + */ + +#include + +#define GLOBALROOT L"\\\\?\\GLOBALROOT" +#define PREFIXW L"" FSP_FSCTL_VOLUME_PARAMS_PREFIX +#define PREFIXW_SIZE (sizeof PREFIXW - sizeof(WCHAR)) + +FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, + const FSP_FSCTL_VOLUME_PARAMS *VolumeParams, + PWCHAR VolumePathBuf, SIZE_T VolumePathSize, + PHANDLE PVolumeHandle) +{ + NTSTATUS Result; + PWSTR DeviceRoot; + SIZE_T DeviceRootSize, DevicePathSize; + WCHAR DevicePathBuf[MAX_PATH], *DevicePathPtr, *DevicePathEnd; + HANDLE VolumeHandle = INVALID_HANDLE_VALUE; + DWORD Bytes; + + if (sizeof(WCHAR) <= VolumePathSize) + VolumePathBuf[0] = L'\0'; + *PVolumeHandle = INVALID_HANDLE_VALUE; + + /* check lengths; everything (including encoded volume params) must fit within MAX_PATH */ + DeviceRoot = L'\\' == DevicePath[0] ? GLOBALROOT : GLOBALROOT "\\Device\\"; + DeviceRootSize = lstrlenW(DeviceRoot) * sizeof(WCHAR); + DevicePathSize = lstrlenW(DevicePath) * sizeof(WCHAR); + if (DeviceRootSize + DevicePathSize + PREFIXW_SIZE + + sizeof *VolumeParams * sizeof(WCHAR) + sizeof(WCHAR) > sizeof DevicePathBuf) + return STATUS_INVALID_PARAMETER; + + /* prepare the device path to be opened; encode the volume params in the Unicode private area */ + DevicePathPtr = DevicePathBuf; + memcpy(DevicePathPtr, DeviceRoot, DeviceRootSize); + DevicePathPtr = (PVOID)((PUINT8)DevicePathPtr + DeviceRootSize); + memcpy(DevicePathPtr, DevicePath, DevicePathSize); + DevicePathPtr = (PVOID)((PUINT8)DevicePathPtr + DevicePathSize); + memcpy(DevicePathPtr, PREFIXW, PREFIXW_SIZE); + DevicePathPtr = (PVOID)((PUINT8)DevicePathPtr + PREFIXW_SIZE); + DevicePathEnd = (PVOID)((PUINT8)DevicePathPtr + sizeof *VolumeParams * sizeof(WCHAR)); + for (PUINT8 VolumeParamsPtr = (PVOID)VolumeParams; + DevicePathEnd > DevicePathPtr; DevicePathPtr++, VolumeParamsPtr++) + { + WCHAR Value = 0xF000 | *VolumeParamsPtr; + *DevicePathPtr = Value; + } + *DevicePathPtr = L'\0'; + + VolumeHandle = CreateFileW(DevicePathBuf, + 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); + if (INVALID_HANDLE_VALUE == VolumeHandle) + { + Result = FspNtStatusFromWin32(GetLastError()); + if (STATUS_OBJECT_NAME_NOT_FOUND == Result) + Result = STATUS_NO_SUCH_DEVICE; + goto exit; + } + + if (!DeviceIoControl(VolumeHandle, FSP_FSCTL_VOLUME_NAME, + 0, 0, + VolumePathBuf, (DWORD)VolumePathSize, + &Bytes, 0)) + { + Result = FspNtStatusFromWin32(GetLastError()); + goto exit; + } + + Result = STATUS_SUCCESS; + +exit: + if (NT_SUCCESS(Result)) + *PVolumeHandle = VolumeHandle; + else + CloseHandle(VolumeHandle); + + return Result; +} + +FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle, + PVOID ResponseBuf, SIZE_T ResponseBufSize, + PVOID RequestBuf, SIZE_T *PRequestBufSize) +{ + NTSTATUS Result = STATUS_SUCCESS; + DWORD Bytes = 0; + + if (0 != PRequestBufSize) + { + Bytes = (DWORD)*PRequestBufSize; + *PRequestBufSize = 0; + } + + if (!DeviceIoControl(VolumeHandle, FSP_FSCTL_TRANSACT, + ResponseBuf, (DWORD)ResponseBufSize, RequestBuf, Bytes, + &Bytes, 0)) + { + Result = FspNtStatusFromWin32(GetLastError()); + goto exit; + } + + if (0 != PRequestBufSize) + *PRequestBufSize = Bytes; + +exit: + return Result; +} diff --git a/src/dll/library.h b/src/dll/library.h index 786de058..bb084683 100644 --- a/src/dll/library.h +++ b/src/dll/library.h @@ -26,14 +26,6 @@ static inline PVOID MemAlloc(SIZE_T Size) extern HANDLE ProcessHeap; return HeapAlloc(ProcessHeap, 0, Size); } -static inline PVOID MemAllocSLE(SIZE_T Size) -{ - extern HANDLE ProcessHeap; - PVOID Pointer = HeapAlloc(ProcessHeap, 0, Size); - if (0 == Pointer) - SetLastError(ERROR_NO_SYSTEM_RESOURCES); - return Pointer; -} static inline VOID MemFree(PVOID Pointer) { extern HANDLE ProcessHeap; diff --git a/src/sys/volume.c b/src/sys/volume.c index 8b37d312..2a95609c 100644 --- a/src/sys/volume.c +++ b/src/sys/volume.c @@ -67,7 +67,8 @@ NTSTATUS FspVolumeCreate( return STATUS_INVALID_PARAMETER; /* copy the VolumeParams */ - for (USHORT Index = 0, Length = FileObject->FileName.Length / 2; Length > Index; Index++) + for (USHORT Index = PREFIXW_SIZE / sizeof(WCHAR), Length = FileObject->FileName.Length / 2; + Length > Index; Index++) { WCHAR Value = FileObject->FileName.Buffer[Index]; if (0xF000 != (Value & 0xFF00))