From a7bc306b2de6f95d195b6300bee937e5eca1d6fd Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Sat, 20 Aug 2022 11:58:00 +0100 Subject: [PATCH] dll: FspSxsAppendSuffix --- src/dll/fsctl.c | 25 ++++++++---- src/dll/library.h | 1 + src/dll/sxs.c | 101 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 117 insertions(+), 10 deletions(-) diff --git a/src/dll/fsctl.c b/src/dll/fsctl.c index e39aea0f..32fcac50 100644 --- a/src/dll/fsctl.c +++ b/src/dll/fsctl.c @@ -38,12 +38,15 @@ FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, PWCHAR VolumeNameBuf, SIZE_T VolumeNameSize, PHANDLE PVolumeHandle) { - NTSTATUS Result; + WCHAR SxsDevicePathBuf[MAX_PATH]; PWSTR DeviceRoot; SIZE_T DeviceRootSize, DevicePathSize, VolumeParamsSize; WCHAR DevicePathBuf[MAX_PATH + sizeof *VolumeParams], *DevicePathPtr, *DevicePathEnd; HANDLE VolumeHandle = INVALID_HANDLE_VALUE; DWORD Bytes; + NTSTATUS Result; + + DevicePath = FspSxsAppendSuffix(SxsDevicePathBuf, sizeof SxsDevicePathBuf, DevicePath); if (sizeof(WCHAR) <= VolumeNameSize) VolumeNameBuf[0] = L'\0'; @@ -228,12 +231,15 @@ exit: FSP_API NTSTATUS FspFsctlGetVolumeList(PWSTR DevicePath, PWCHAR VolumeListBuf, PSIZE_T PVolumeListSize) { - NTSTATUS Result; + WCHAR SxsDevicePathBuf[MAX_PATH]; PWSTR DeviceRoot; SIZE_T DeviceRootSize, DevicePathSize; WCHAR DevicePathBuf[MAX_PATH], *DevicePathPtr; HANDLE VolumeHandle = INVALID_HANDLE_VALUE; DWORD Bytes; + NTSTATUS Result; + + DevicePath = FspSxsAppendSuffix(SxsDevicePathBuf, sizeof SxsDevicePathBuf, DevicePath); /* check lengths; everything must fit within MAX_PATH */ DeviceRoot = L'\\' == DevicePath[0] ? GLOBALROOT : GLOBALROOT "\\Device\\"; @@ -299,12 +305,15 @@ FSP_API NTSTATUS FspFsctlPreflight(PWSTR DevicePath) static NTSTATUS FspFsctlUnload(PWSTR DevicePath) { - NTSTATUS Result; + WCHAR SxsDevicePathBuf[MAX_PATH]; PWSTR DeviceRoot; SIZE_T DeviceRootSize, DevicePathSize; WCHAR DevicePathBuf[MAX_PATH], *DevicePathPtr; HANDLE VolumeHandle = INVALID_HANDLE_VALUE; DWORD Bytes; + NTSTATUS Result; + + DevicePath = FspSxsAppendSuffix(SxsDevicePathBuf, sizeof SxsDevicePathBuf, DevicePath); /* check lengths; everything must fit within MAX_PATH */ DeviceRoot = L'\\' == DevicePath[0] ? GLOBALROOT : GLOBALROOT "\\Device\\"; @@ -357,7 +366,7 @@ static BOOL WINAPI FspFsctlServiceVersionInitialize( QUERY_SERVICE_CONFIGW *ServiceConfig = 0; DWORD Size; - wsprintfW(DriverName, L"" FSP_FSCTL_DRIVER_NAME "%s", FspSxsSuffix()); + FspSxsAppendSuffix(DriverName, sizeof DriverName, L"" FSP_FSCTL_DRIVER_NAME); ScmHandle = OpenSCManagerW(0, 0, 0); if (0 == ScmHandle) @@ -447,7 +456,7 @@ FSP_API NTSTATUS FspFsctlStartService(VOID) DWORD LastError; NTSTATUS Result; - wsprintfW(DriverName, L"" FSP_FSCTL_DRIVER_NAME "%s", FspSxsSuffix()); + FspSxsAppendSuffix(DriverName, sizeof DriverName, L"" FSP_FSCTL_DRIVER_NAME); AcquireSRWLockExclusive(&FspFsctlStartStopServiceLock); @@ -527,7 +536,7 @@ FSP_API NTSTATUS FspFsctlStopService(VOID) BOOL PrivilegeCheckResult; NTSTATUS Result; - wsprintfW(DriverName, L"" FSP_FSCTL_DRIVER_NAME "%s", FspSxsSuffix()); + FspSxsAppendSuffix(DriverName, sizeof DriverName, L"" FSP_FSCTL_DRIVER_NAME); AcquireSRWLockExclusive(&FspFsctlStartStopServiceLock); @@ -719,7 +728,7 @@ NTSTATUS FspFsctlRegister(VOID) SERVICE_DESCRIPTION ServiceDescription; NTSTATUS Result; - wsprintfW(DriverName, L"" FSP_FSCTL_DRIVER_NAME "%s", FspSxsSuffix()); + FspSxsAppendSuffix(DriverName, sizeof DriverName, L"" FSP_FSCTL_DRIVER_NAME); if (0 == GetModuleFileNameW(DllInstance, DriverPath, MAX_PATH)) return FspNtStatusFromWin32(GetLastError()); @@ -808,7 +817,7 @@ NTSTATUS FspFsctlUnregister(VOID) DWORD LastError; NTSTATUS Result; - wsprintfW(DriverName, L"" FSP_FSCTL_DRIVER_NAME "%s", FspSxsSuffix()); + FspSxsAppendSuffix(DriverName, sizeof DriverName, L"" FSP_FSCTL_DRIVER_NAME); ScmHandle = OpenSCManagerW(0, 0, SC_MANAGER_CREATE_SERVICE); /* diff --git a/src/dll/library.h b/src/dll/library.h index 539120c2..7eea06c6 100644 --- a/src/dll/library.h +++ b/src/dll/library.h @@ -72,6 +72,7 @@ NTSTATUS FspEventLogUnregister(VOID); PWSTR FspSxsIdent(VOID); PWSTR FspSxsSuffix(VOID); +PWSTR FspSxsAppendSuffix(PWCHAR Buffer, SIZE_T Size, PWSTR Ident); PSID FspWksidNew(WELL_KNOWN_SID_TYPE WellKnownSidType, PNTSTATUS PResult); PSID FspWksidGet(WELL_KNOWN_SID_TYPE WellKnownSidType); diff --git a/src/dll/sxs.c b/src/dll/sxs.c index 76d01044..93352cb7 100644 --- a/src/dll/sxs.c +++ b/src/dll/sxs.c @@ -24,8 +24,7 @@ static INIT_ONCE FspSxsIdentInitOnce = INIT_ONCE_STATIC_INIT; static WCHAR FspSxsIdentBuf[32 + 2] = L""; -static BOOL WINAPI FspSxsIdentInitialize( - PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) +static BOOLEAN FspSxsIdentInitializeFromFile(VOID) { extern HINSTANCE DllInstance; WCHAR Path[MAX_PATH]; @@ -33,6 +32,7 @@ static BOOL WINAPI FspSxsIdentInitialize( HANDLE Handle = INVALID_HANDLE_VALUE; CHAR Buffer[ARRAYSIZE(FspSxsIdentBuf) - 2]; WCHAR WBuffer[ARRAYSIZE(FspSxsIdentBuf) - 2]; + BOOLEAN Result = FALSE; if (0 == GetModuleFileNameW(DllInstance, Path, MAX_PATH)) goto exit; @@ -97,10 +97,89 @@ static BOOL WINAPI FspSxsIdentInitialize( memcpy(FspSxsIdentBuf + 1, WBuffer, Size * sizeof(WCHAR)); FspSxsIdentBuf[1 + Size] = L'\0'; + Result = TRUE; + exit: if (INVALID_HANDLE_VALUE != Handle) CloseHandle(Handle); + return Result; +} + +static BOOLEAN FspSxsIdentInitializeFromDirectory(VOID) +{ + extern HINSTANCE DllInstance; + WCHAR Path[MAX_PATH]; + HANDLE Handle = INVALID_HANDLE_VALUE; + WCHAR FinalPath[MAX_PATH]; + PWCHAR P, EndP, Q, EndQ; + PWCHAR Ident = 0; + BOOLEAN Result = FALSE; + + if (0 == GetModuleFileNameW(DllInstance, Path, MAX_PATH)) + goto exit; + + Handle = CreateFileW( + Path, + 0, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + 0, + OPEN_EXISTING, + 0, + 0); + if (INVALID_HANDLE_VALUE == Handle) + goto exit; + + if (!GetFinalPathNameByHandleW(Handle, FinalPath, MAX_PATH, VOLUME_NAME_NONE)) + goto exit; + + EndP = FinalPath + lstrlenW(FinalPath); + for (P = EndP - 1; FinalPath <= P; P--) + { + if (L'\\' == *P && + P + 9 < EndP && + (L'S' == P[1] || L's' == P[1]) && + (L'X' == P[2] || L'x' == P[2]) && + (L'S' == P[3] || L's' == P[3]) && + L'\\' == P[4] && + (L'S' == P[5] || L's' == P[5]) && + (L'X' == P[6] || L'x' == P[6]) && + (L'S' == P[7] || L's' == P[7]) && + L'.' == P[8] && + L'\\' != P[9]) + { + Ident = P + 9; + break; + } + } + if (0 == Ident) + goto exit; + + FspSxsIdentBuf[0] = L'+'; + EndQ = FspSxsIdentBuf + (ARRAYSIZE(FspSxsIdentBuf) - 1); + for (P = Ident, Q = FspSxsIdentBuf + 1; EndP > P && EndQ > Q && L'\\' != *P; P++, Q++) + *Q = *P; + *Q = L'\0'; + + Result = TRUE; + +exit: + if (INVALID_HANDLE_VALUE != Handle) + CloseHandle(Handle); + + return Result; +} + +static BOOL WINAPI FspSxsIdentInitialize( + PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) +{ + if (FspSxsIdentInitializeFromFile()) + goto exit; + + if (FspSxsIdentInitializeFromDirectory()) + goto exit; + +exit: return TRUE; } @@ -115,3 +194,21 @@ PWSTR FspSxsSuffix(VOID) InitOnceExecuteOnce(&FspSxsIdentInitOnce, FspSxsIdentInitialize, 0, 0); return FspSxsIdentBuf; } + +PWSTR FspSxsAppendSuffix(PWCHAR Buffer, SIZE_T Size, PWSTR Ident) +{ + PWSTR Suffix; + SIZE_T IdentSize, SuffixSize; + + Suffix = FspSxsSuffix(); + IdentSize = lstrlenW(Ident) * sizeof(WCHAR); + SuffixSize = lstrlenW(Suffix) * sizeof(WCHAR); + if (Size < IdentSize + SuffixSize + sizeof(WCHAR)) + return L""; + + memcpy(Buffer, Ident, IdentSize); + memcpy((PUINT8)Buffer + IdentSize, Suffix, SuffixSize); + *(PWCHAR)((PUINT8)Buffer + IdentSize + SuffixSize) = L'\0'; + + return Buffer; +}