sys: FspUnload, FspSxsIdent

This commit is contained in:
Bill Zissimopoulos 2022-08-05 17:41:12 +01:00
parent 62a6bbab66
commit 005d3e4fb0
6 changed files with 177 additions and 6 deletions

View File

@ -260,6 +260,7 @@
<ClCompile Include="..\..\src\sys\shutdown.c" /> <ClCompile Include="..\..\src\sys\shutdown.c" />
<ClCompile Include="..\..\src\sys\silo.c" /> <ClCompile Include="..\..\src\sys\silo.c" />
<ClCompile Include="..\..\src\sys\statistics.c" /> <ClCompile Include="..\..\src\sys\statistics.c" />
<ClCompile Include="..\..\src\sys\sxs.c" />
<ClCompile Include="..\..\src\sys\trace.c" /> <ClCompile Include="..\..\src\sys\trace.c" />
<ClCompile Include="..\..\src\sys\util.c" /> <ClCompile Include="..\..\src\sys\util.c" />
<ClCompile Include="..\..\src\sys\volinfo.c" /> <ClCompile Include="..\..\src\sys\volinfo.c" />

View File

@ -134,6 +134,9 @@
<ClCompile Include="..\..\src\shared\ku\mountmgr.c"> <ClCompile Include="..\..\src\shared\ku\mountmgr.c">
<Filter>Source\shared\ku</Filter> <Filter>Source\shared\ku</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\sys\sxs.c">
<Filter>Source</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\src\sys\driver.h"> <ClInclude Include="..\..\src\sys\driver.h">

View File

@ -93,7 +93,7 @@ static BOOL WINAPI FspSxsIdentInitialize(
if (0 == Size) if (0 == Size)
goto exit; goto exit;
FspSxsIdentBuf[0] = L'-'; FspSxsIdentBuf[0] = L'+';
memcpy(FspSxsIdentBuf + 1, WBuffer, Size * sizeof(WCHAR)); memcpy(FspSxsIdentBuf + 1, WBuffer, Size * sizeof(WCHAR));
FspSxsIdentBuf[1 + Size] = L'\0'; FspSxsIdentBuf[1 + Size] = L'\0';

View File

@ -21,13 +21,24 @@
#include <sys/driver.h> #include <sys/driver.h>
/*
* Define the following macro to include FspUnload and make the driver unloadable.
*/
#define FSP_UNLOAD
DRIVER_INITIALIZE DriverEntry; DRIVER_INITIALIZE DriverEntry;
#if defined(FSP_UNLOAD)
DRIVER_UNLOAD FspUnload;
#endif
static VOID FspDriverMultiVersionInitialize(VOID); static VOID FspDriverMultiVersionInitialize(VOID);
static NTSTATUS FspDriverInitializeDevices(VOID); static NTSTATUS FspDriverInitializeDevices(VOID);
static VOID FspDriverFinalizeDevices(VOID); static VOID FspDriverFinalizeDevices(VOID);
#ifdef ALLOC_PRAGMA #ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry) #pragma alloc_text(INIT, DriverEntry)
#if defined(FSP_UNLOAD)
#pragma alloc_text(PAGE, FspUnload)
#endif
#pragma alloc_text(INIT, FspDriverMultiVersionInitialize) #pragma alloc_text(INIT, FspDriverMultiVersionInitialize)
#pragma alloc_text(PAGE, FspDriverInitializeDevices) #pragma alloc_text(PAGE, FspDriverInitializeDevices)
#pragma alloc_text(PAGE, FspDriverFinalizeDevices) #pragma alloc_text(PAGE, FspDriverFinalizeDevices)
@ -40,7 +51,12 @@ NTSTATUS DriverEntry(
FSP_TRACE_INIT(); FSP_TRACE_INIT();
FspSxsIdentInitialize(&DriverObject->DriverName);
/* setup the driver object */ /* setup the driver object */
#if defined(FSP_UNLOAD)
DriverObject->DriverUnload = FspUnload;
#endif
DriverObject->MajorFunction[IRP_MJ_CREATE] = FspCreate; DriverObject->MajorFunction[IRP_MJ_CREATE] = FspCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FspClose; DriverObject->MajorFunction[IRP_MJ_CLOSE] = FspClose;
DriverObject->MajorFunction[IRP_MJ_READ] = FspRead; DriverObject->MajorFunction[IRP_MJ_READ] = FspRead;
@ -172,6 +188,26 @@ exit:
&DriverObject->DriverName, RegistryPath); &DriverObject->DriverName, RegistryPath);
} }
#if defined(FSP_UNLOAD)
VOID FspUnload(
PDRIVER_OBJECT DriverObject)
{
FSP_ENTER_VOID(PAGED_CODE());
FspDeviceFinalizeAllTimers();
FspProcessBufferFinalize();
FspSiloFinalize();
FSP_TRACE_FINI();
#pragma prefast(suppress:28175, "We are in DriverUnload: ok to access DriverName")
FSP_LEAVE_VOID("DriverName=\"%wZ\"",
&DriverObject->DriverName);
}
#endif
static VOID FspDriverMultiVersionInitialize(VOID) static VOID FspDriverMultiVersionInitialize(VOID)
{ {
FspProcessorCount = KeQueryActiveProcessorCount(0); FspProcessorCount = KeQueryActiveProcessorCount(0);
@ -202,6 +238,8 @@ static NTSTATUS FspDriverInitializeDevices(VOID)
FSP_SILO_GLOBALS *Globals; FSP_SILO_GLOBALS *Globals;
UNICODE_STRING DeviceSddl; UNICODE_STRING DeviceSddl;
UNICODE_STRING DeviceName; UNICODE_STRING DeviceName;
WCHAR DeviceNameBuf[128];
UNICODE_STRING SymlinkName;
GUID Guid; GUID Guid;
NTSTATUS Result; NTSTATUS Result;
@ -210,20 +248,46 @@ static NTSTATUS FspDriverInitializeDevices(VOID)
/* create the file system control device objects */ /* create the file system control device objects */
RtlInitUnicodeString(&DeviceSddl, L"" FSP_FSCTL_DEVICE_SDDL); RtlInitUnicodeString(&DeviceSddl, L"" FSP_FSCTL_DEVICE_SDDL);
RtlInitUnicodeString(&DeviceName, L"\\Device\\" FSP_FSCTL_DISK_DEVICE_NAME); RtlInitEmptyUnicodeString(&DeviceName, DeviceNameBuf, sizeof DeviceNameBuf);
Result = RtlUnicodeStringPrintf(&DeviceName,
L"\\Device\\" FSP_FSCTL_DISK_DEVICE_NAME "%wZ",
FspSxsSuffix());
ASSERT(NT_SUCCESS(Result));
Result = FspDeviceCreateSecure(FspFsctlDeviceExtensionKind, 0, Result = FspDeviceCreateSecure(FspFsctlDeviceExtensionKind, 0,
&DeviceName, FILE_DEVICE_DISK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN, &DeviceName, FILE_DEVICE_DISK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN,
&DeviceSddl, &FspFsctlDeviceClassGuid, &DeviceSddl, &FspFsctlDeviceClassGuid,
&Globals->FsctlDiskDeviceObject); &Globals->FsctlDiskDeviceObject);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
RtlInitUnicodeString(&DeviceName, L"\\Device\\" FSP_FSCTL_NET_DEVICE_NAME); if (0 != FspSxsIdent()->Length)
{
/* \Device\WinFsp.Disk SxS symlink */
RtlInitUnicodeString(&SymlinkName, L"\\Device\\" FSP_FSCTL_DISK_DEVICE_NAME);
Result = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
if (!NT_SUCCESS(Result))
goto exit;
Globals->InitDoneSymlinkDisk = 1;
}
RtlInitEmptyUnicodeString(&DeviceName, DeviceNameBuf, sizeof DeviceNameBuf);
Result = RtlUnicodeStringPrintf(&DeviceName,
L"\\Device\\" FSP_FSCTL_NET_DEVICE_NAME "%wZ",
FspSxsSuffix());
ASSERT(NT_SUCCESS(Result));
Result = FspDeviceCreateSecure(FspFsctlDeviceExtensionKind, 0, Result = FspDeviceCreateSecure(FspFsctlDeviceExtensionKind, 0,
&DeviceName, FILE_DEVICE_NETWORK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN, &DeviceName, FILE_DEVICE_NETWORK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN,
&DeviceSddl, &FspFsctlDeviceClassGuid, &DeviceSddl, &FspFsctlDeviceClassGuid,
&Globals->FsctlNetDeviceObject); &Globals->FsctlNetDeviceObject);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
if (0 != FspSxsIdent()->Length)
{
/* \Device\WinFsp.Net SxS symlink */
RtlInitUnicodeString(&SymlinkName, L"\\Device\\" FSP_FSCTL_NET_DEVICE_NAME);
Result = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
if (!NT_SUCCESS(Result))
goto exit;
Globals->InitDoneSymlinkNet = 1;
}
Result = FspDeviceCreate(FspFsmupDeviceExtensionKind, 0, Result = FspDeviceCreate(FspFsmupDeviceExtensionKind, 0,
FILE_DEVICE_NETWORK_FILE_SYSTEM, FILE_REMOTE_DEVICE, FILE_DEVICE_NETWORK_FILE_SYSTEM, FILE_REMOTE_DEVICE,
&Globals->FsmupDeviceObject); &Globals->FsmupDeviceObject);
@ -257,8 +321,9 @@ static NTSTATUS FspDriverInitializeDevices(VOID)
Result = RtlUnicodeStringPrintf(&DeviceName, Result = RtlUnicodeStringPrintf(&DeviceName,
0 == ((PULONG)&Guid)[0] && 0 == ((PULONG)&Guid)[1] && 0 == ((PULONG)&Guid)[0] && 0 == ((PULONG)&Guid)[1] &&
0 == ((PULONG)&Guid)[2] && 0 == ((PULONG)&Guid)[3] ? 0 == ((PULONG)&Guid)[2] && 0 == ((PULONG)&Guid)[3] ?
L"\\Device\\" FSP_FSCTL_MUP_DEVICE_NAME : L"\\Device\\" FSP_FSCTL_MUP_DEVICE_NAME "%wZ":
L"\\Device\\" FSP_FSCTL_MUP_DEVICE_NAME "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", L"\\Device\\" FSP_FSCTL_MUP_DEVICE_NAME "%wZ{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
FspSxsSuffix(),
Guid.Data1, Guid.Data2, Guid.Data3, Guid.Data1, Guid.Data2, Guid.Data3,
Guid.Data4[0], Guid.Data4[1], Guid.Data4[2], Guid.Data4[3], Guid.Data4[0], Guid.Data4[1], Guid.Data4[2], Guid.Data4[3],
Guid.Data4[4], Guid.Data4[5], Guid.Data4[6], Guid.Data4[7]); Guid.Data4[4], Guid.Data4[5], Guid.Data4[6], Guid.Data4[7]);
@ -293,11 +358,23 @@ exit:
FspDeviceDelete(Globals->FsmupDeviceObject); FspDeviceDelete(Globals->FsmupDeviceObject);
Globals->FsmupDeviceObject = 0; Globals->FsmupDeviceObject = 0;
} }
if (Globals->InitDoneSymlinkNet)
{
RtlInitUnicodeString(&SymlinkName, L"\\Device\\" FSP_FSCTL_NET_DEVICE_NAME);
IoDeleteSymbolicLink(&SymlinkName);
Globals->InitDoneSymlinkNet = 0;
}
if (0 != Globals->FsctlNetDeviceObject) if (0 != Globals->FsctlNetDeviceObject)
{ {
FspDeviceDelete(Globals->FsctlNetDeviceObject); FspDeviceDelete(Globals->FsctlNetDeviceObject);
Globals->FsctlNetDeviceObject = 0; Globals->FsctlNetDeviceObject = 0;
} }
if (Globals->InitDoneSymlinkDisk)
{
RtlInitUnicodeString(&SymlinkName, L"\\Device\\" FSP_FSCTL_DISK_DEVICE_NAME);
IoDeleteSymbolicLink(&SymlinkName);
Globals->InitDoneSymlinkDisk = 0;
}
if (0 != Globals->FsctlDiskDeviceObject) if (0 != Globals->FsctlDiskDeviceObject)
{ {
FspDeviceDelete(Globals->FsctlDiskDeviceObject); FspDeviceDelete(Globals->FsctlDiskDeviceObject);
@ -315,6 +392,7 @@ static VOID FspDriverFinalizeDevices(VOID)
PAGED_CODE(); PAGED_CODE();
FSP_SILO_GLOBALS *Globals; FSP_SILO_GLOBALS *Globals;
UNICODE_STRING SymlinkName;
FspSiloGetGlobals(&Globals); FspSiloGetGlobals(&Globals);
ASSERT(0 != Globals); ASSERT(0 != Globals);
@ -331,11 +409,23 @@ static VOID FspDriverFinalizeDevices(VOID)
FspDeviceDelete(Globals->FsmupDeviceObject); FspDeviceDelete(Globals->FsmupDeviceObject);
Globals->FsmupDeviceObject = 0; Globals->FsmupDeviceObject = 0;
} }
if (Globals->InitDoneSymlinkNet)
{
RtlInitUnicodeString(&SymlinkName, L"\\Device\\" FSP_FSCTL_NET_DEVICE_NAME);
IoDeleteSymbolicLink(&SymlinkName);
Globals->InitDoneSymlinkNet = 0;
}
if (0 != Globals->FsctlNetDeviceObject) if (0 != Globals->FsctlNetDeviceObject)
{ {
FspDeviceDelete(Globals->FsctlNetDeviceObject); FspDeviceDelete(Globals->FsctlNetDeviceObject);
Globals->FsctlNetDeviceObject = 0; Globals->FsctlNetDeviceObject = 0;
} }
if (Globals->InitDoneSymlinkDisk)
{
RtlInitUnicodeString(&SymlinkName, L"\\Device\\" FSP_FSCTL_DISK_DEVICE_NAME);
IoDeleteSymbolicLink(&SymlinkName);
Globals->InitDoneSymlinkDisk = 0;
}
if (0 != Globals->FsctlDiskDeviceObject) if (0 != Globals->FsctlDiskDeviceObject)
{ {
FspDeviceDelete(Globals->FsctlDiskDeviceObject); FspDeviceDelete(Globals->FsctlDiskDeviceObject);

View File

@ -739,6 +739,11 @@ LONG FspCompareUnicodeString(
PCUNICODE_STRING String2, PCUNICODE_STRING String2,
BOOLEAN CaseInsensitive); BOOLEAN CaseInsensitive);
/* SxS */
VOID FspSxsIdentInitialize(PUNICODE_STRING DriverName);
PUNICODE_STRING FspSxsIdent(VOID);
PUNICODE_STRING FspSxsSuffix(VOID);
/* silos */ /* silos */
typedef struct typedef struct
{ {
@ -746,7 +751,8 @@ typedef struct
PDEVICE_OBJECT FsctlNetDeviceObject; PDEVICE_OBJECT FsctlNetDeviceObject;
PDEVICE_OBJECT FsmupDeviceObject; PDEVICE_OBJECT FsmupDeviceObject;
HANDLE MupHandle; HANDLE MupHandle;
WCHAR FsmupDeviceNameBuf[64]; WCHAR FsmupDeviceNameBuf[128];
UINT32 InitDoneSymlinkDisk:1, InitDoneSymlinkNet:1;
} FSP_SILO_GLOBALS; } FSP_SILO_GLOBALS;
typedef NTSTATUS (*FSP_SILO_INIT_CALLBACK)(VOID); typedef NTSTATUS (*FSP_SILO_INIT_CALLBACK)(VOID);
typedef VOID (*FSP_SILO_FINI_CALLBACK)(VOID); typedef VOID (*FSP_SILO_FINI_CALLBACK)(VOID);

71
src/sys/sxs.c Normal file
View File

@ -0,0 +1,71 @@
/**
* @file sys/sxs.c
*
* @copyright 2015-2022 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#include <sys/driver.h>
VOID FspSxsIdentInitialize(PUNICODE_STRING DriverName);
PUNICODE_STRING FspSxsIdent(VOID);
PUNICODE_STRING FspSxsSuffix(VOID);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, FspSxsIdentInitialize)
#endif
static WCHAR FspSxsIdentBuf[32 + 1] = L"";
static UNICODE_STRING FspSxsIdentStr = { 0, sizeof FspSxsIdentBuf - 1, FspSxsIdentBuf + 1 };
static UNICODE_STRING FspSxsSuffixStr = { 0, sizeof FspSxsIdentBuf, FspSxsIdentBuf };
VOID FspSxsIdentInitialize(PUNICODE_STRING DriverName)
{
PWCHAR Ident = 0;
USHORT Length;
for (PWCHAR P = DriverName->Buffer + DriverName->Length / sizeof(WCHAR) - 1; DriverName->Buffer <= P; P--)
{
if (L'\\' == *P)
break;
if (L'+' == *P)
{
Ident = P;
break;
}
}
if (0 == Ident)
return;
Length = (USHORT)(((PUINT8)DriverName->Buffer + DriverName->Length) - (PUINT8)Ident);
if (Length > sizeof FspSxsIdentBuf)
Length = sizeof FspSxsIdentBuf;
RtlCopyMemory(FspSxsIdentBuf, Ident, Length);
FspSxsIdentStr.Length = Length - sizeof(WCHAR);
FspSxsSuffixStr.Length = Length;
}
PUNICODE_STRING FspSxsIdent(VOID)
{
return &FspSxsIdentStr;
}
PUNICODE_STRING FspSxsSuffix(VOID)
{
return &FspSxsSuffixStr;
}