diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index 09a630e8..1ead2dc9 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -115,9 +115,10 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE typedef struct _FSP_FILE_SYSTEM { UINT16 Version; + PVOID UserContext; + WCHAR VolumePrefix[sizeof(((FSP_FSCTL_VOLUME_PARAMS *)0)->Prefix) / sizeof(WCHAR)]; WCHAR VolumeName[FSP_FSCTL_VOLUME_NAME_SIZEMAX / sizeof(WCHAR)]; HANDLE VolumeHandle; - PVOID UserContext; FSP_FILE_SYSTEM_OPERATION_GUARD *EnterOperation, *LeaveOperation; FSP_FILE_SYSTEM_OPERATION *Operations[FspFsctlTransactKindCount]; const FSP_FILE_SYSTEM_INTERFACE *Interface; diff --git a/src/dll/dispatch.c b/src/dll/dispatch.c index 1c341891..67dc2955 100644 --- a/src/dll/dispatch.c +++ b/src/dll/dispatch.c @@ -16,6 +16,29 @@ static FSP_FILE_SYSTEM_INTERFACE FspFileSystemNullInterface; static CRITICAL_SECTION FspFileSystemMountListGuard; static LIST_ENTRY FspFileSystemMountList = { &FspFileSystemMountList, &FspFileSystemMountList }; +static inline +BOOL FspFileSystemDefineDosDevice(DWORD Flags, PWSTR MountPoint, FSP_FILE_SYSTEM *FileSystem) +{ + WCHAR TargetBuf[( + sizeof(((FSP_FILE_SYSTEM *)0)->VolumePrefix) + + sizeof(((FSP_FILE_SYSTEM *)0)->VolumeName)) / sizeof(WCHAR)]; + PWSTR P; + ULONG L0, L1; + + for (P = FileSystem->VolumeName; *P; P++) + ; + L0 = (ULONG)(P - FileSystem->VolumeName); + memcpy(TargetBuf, FileSystem->VolumeName, L0 * sizeof(WCHAR)); + + for (P = FileSystem->VolumePrefix; *P; P++) + ; + L1 = (ULONG)(P - FileSystem->VolumePrefix); + memcpy(TargetBuf + L0, FileSystem->VolumePrefix, L1 * sizeof(WCHAR)); + TargetBuf[L0 + L1] = L'\0'; + + return DefineDosDeviceW(Flags, MountPoint, TargetBuf); +} + VOID FspFileSystemInitialize(VOID) { /* @@ -62,8 +85,9 @@ VOID FspFileSystemFinalize(VOID) { FileSystem = CONTAINING_RECORD(MountEntry, FSP_FILE_SYSTEM, MountEntry); - DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, - FileSystem->MountPoint, FileSystem->VolumeName); + FspFileSystemDefineDosDevice( + DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, + FileSystem->MountPoint, FileSystem); } LeaveCriticalSection(&FspFileSystemMountListGuard); @@ -76,6 +100,7 @@ FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath, { NTSTATUS Result; FSP_FILE_SYSTEM *FileSystem; + ULONG PrefixLength; *PFileSystem = 0; @@ -96,6 +121,14 @@ FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath, return Result; } + memcpy(FileSystem->VolumePrefix, VolumeParams->Prefix, sizeof VolumeParams->Prefix); + FileSystem->VolumePrefix[sizeof FileSystem->VolumePrefix / sizeof(WCHAR) - 1] = L'\0'; + for (PrefixLength = 0; L'\0' != FileSystem->VolumePrefix[PrefixLength]; PrefixLength++) + ; + for (; 0 < PrefixLength && L'\\' == FileSystem->VolumePrefix[PrefixLength - 1]; PrefixLength--) + ; + FileSystem->VolumePrefix[PrefixLength] = L'\0'; + FileSystem->Operations[FspFsctlTransactCreateKind] = FspFileSystemOpCreate; FileSystem->Operations[FspFsctlTransactOverwriteKind] = FspFileSystemOpOverwrite; FileSystem->Operations[FspFsctlTransactCleanupKind] = FspFileSystemOpCleanup; @@ -150,7 +183,7 @@ FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR M if (0 == (Drives & (1 << (Drive - 'A')))) { MountPoint[0] = Drive; - if (DefineDosDeviceW(DDD_RAW_TARGET_PATH, MountPoint, FileSystem->VolumeName)) + if (FspFileSystemDefineDosDevice(DDD_RAW_TARGET_PATH, MountPoint, FileSystem)) { Result = STATUS_SUCCESS; goto exit; @@ -176,7 +209,7 @@ FSP_API NTSTATUS FspFileSystemSetMountPoint(FSP_FILE_SYSTEM *FileSystem, PWSTR M memcpy(P, MountPoint, L); MountPoint = P; - if (DefineDosDeviceW(DDD_RAW_TARGET_PATH, MountPoint, FileSystem->VolumeName)) + if (FspFileSystemDefineDosDevice(DDD_RAW_TARGET_PATH, MountPoint, FileSystem)) Result = STATUS_SUCCESS; else Result = FspNtStatusFromWin32(GetLastError()); @@ -206,8 +239,8 @@ FSP_API VOID FspFileSystemRemoveMountPoint(FSP_FILE_SYSTEM *FileSystem) RemoveEntryList(&FileSystem->MountEntry); LeaveCriticalSection(&FspFileSystemMountListGuard); - DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, - FileSystem->MountPoint, FileSystem->VolumeName); + FspFileSystemDefineDosDevice(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, + FileSystem->MountPoint, FileSystem); MemFree(FileSystem->MountPoint); FileSystem->MountPoint = 0;