mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
sys: silo support
This commit is contained in:
parent
899cd5595d
commit
aa3beba928
@ -185,6 +185,7 @@
|
||||
<ClCompile Include="..\..\src\sys\read.c" />
|
||||
<ClCompile Include="..\..\src\sys\security.c" />
|
||||
<ClCompile Include="..\..\src\sys\shutdown.c" />
|
||||
<ClCompile Include="..\..\src\sys\silo.c" />
|
||||
<ClCompile Include="..\..\src\sys\statistics.c" />
|
||||
<ClCompile Include="..\..\src\sys\util.c" />
|
||||
<ClCompile Include="..\..\src\sys\volinfo.c" />
|
||||
|
@ -122,6 +122,9 @@
|
||||
<ClCompile Include="..\..\src\shared\ku\uuid5.c">
|
||||
<Filter>Source\shared\ku</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\sys\silo.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\sys\driver.h">
|
||||
|
@ -242,6 +242,22 @@ static NTSTATUS FspFsctlStartService(VOID)
|
||||
DWORD LastError;
|
||||
NTSTATUS Result;
|
||||
|
||||
/* Determine if we are running inside container.
|
||||
*
|
||||
* See https://github.com/microsoft/perfview/blob/V1.9.65/src/TraceEvent/TraceEventSession.cs#L525
|
||||
* See https://stackoverflow.com/a/50748300
|
||||
*/
|
||||
LastError = RegGetValueW(
|
||||
HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control",
|
||||
L"ContainerType",
|
||||
RRF_RT_REG_DWORD, 0,
|
||||
0, 0);
|
||||
if (ERROR_SUCCESS == LastError)
|
||||
{
|
||||
Result = STATUS_SUCCESS;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ScmHandle = OpenSCManagerW(0, 0, 0);
|
||||
if (0 == ScmHandle)
|
||||
{
|
||||
|
266
src/sys/driver.c
266
src/sys/driver.c
@ -21,26 +21,16 @@
|
||||
|
||||
#include <sys/driver.h>
|
||||
|
||||
/*
|
||||
* Define the following macro to include FspUnload.
|
||||
*
|
||||
* Note that this driver is no longer unloadable.
|
||||
* See the comments in DriverEntry as to why!
|
||||
*/
|
||||
//#define FSP_UNLOAD
|
||||
|
||||
DRIVER_INITIALIZE DriverEntry;
|
||||
static VOID FspDriverMultiVersionInitialize(VOID);
|
||||
#if defined(FSP_UNLOAD)
|
||||
DRIVER_UNLOAD FspUnload;
|
||||
#endif
|
||||
static NTSTATUS FspDriverInitializeDevices(VOID);
|
||||
static VOID FspDriverFinalizeDevices(VOID);
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(INIT, DriverEntry)
|
||||
#pragma alloc_text(INIT, FspDriverMultiVersionInitialize)
|
||||
#if defined(FSP_UNLOAD)
|
||||
#pragma alloc_text(PAGE, FspUnload)
|
||||
#endif
|
||||
#pragma alloc_text(PAGE, FspDriverInitializeDevices)
|
||||
#pragma alloc_text(PAGE, FspDriverFinalizeDevices)
|
||||
#endif
|
||||
|
||||
NTSTATUS DriverEntry(
|
||||
@ -49,9 +39,6 @@ NTSTATUS DriverEntry(
|
||||
FSP_ENTER_DRV();
|
||||
|
||||
/* setup the driver object */
|
||||
#if defined(FSP_UNLOAD)
|
||||
DriverObject->DriverUnload = FspUnload;
|
||||
#endif
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = FspCreate;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FspClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_READ] = FspRead;
|
||||
@ -133,94 +120,41 @@ NTSTATUS DriverEntry(
|
||||
#pragma prefast(suppress:28175, "We are a filesystem: ok to access FastIoDispatch")
|
||||
DriverObject->FastIoDispatch = &FspFastIoDispatch;
|
||||
|
||||
BOOLEAN InitDoneGRes = FALSE, InitDonePsBuf = FALSE;
|
||||
UNICODE_STRING DeviceSddl;
|
||||
UNICODE_STRING DeviceName;
|
||||
BOOLEAN InitDoneGRes = FALSE, InitDoneSilo = FALSE, InitDonePsBuf = FALSE,
|
||||
InitDoneDevices = FALSE;
|
||||
|
||||
FspDriverObject = DriverObject;
|
||||
FspDriverMultiVersionInitialize();
|
||||
|
||||
ExInitializeResourceLite(&FspDeviceGlobalResource);
|
||||
InitDoneGRes = TRUE;
|
||||
|
||||
FspDriverMultiVersionInitialize();
|
||||
Result = FspSiloInitialize(FspDriverInitializeDevices, FspDriverFinalizeDevices);
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
InitDoneSilo = TRUE;
|
||||
|
||||
Result = FspProcessBufferInitialize();
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
InitDonePsBuf = TRUE;
|
||||
|
||||
/* create the file system control device objects */
|
||||
RtlInitUnicodeString(&DeviceSddl, L"" FSP_FSCTL_DEVICE_SDDL);
|
||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\" FSP_FSCTL_DISK_DEVICE_NAME);
|
||||
Result = FspDeviceCreateSecure(FspFsctlDeviceExtensionKind, 0,
|
||||
&DeviceName, FILE_DEVICE_DISK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN,
|
||||
&DeviceSddl, &FspFsctlDeviceClassGuid,
|
||||
&FspFsctlDiskDeviceObject);
|
||||
Result = FspDriverInitializeDevices();
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\" FSP_FSCTL_NET_DEVICE_NAME);
|
||||
Result = FspDeviceCreateSecure(FspFsctlDeviceExtensionKind, 0,
|
||||
&DeviceName, FILE_DEVICE_NETWORK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN,
|
||||
&DeviceSddl, &FspFsctlDeviceClassGuid,
|
||||
&FspFsctlNetDeviceObject);
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
Result = FspDeviceCreate(FspFsmupDeviceExtensionKind, 0,
|
||||
FILE_DEVICE_NETWORK_FILE_SYSTEM, FILE_REMOTE_DEVICE,
|
||||
&FspFsmupDeviceObject);
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
|
||||
#if DBG
|
||||
/*
|
||||
* Fix GitHub issue #177. All credit for the investigation of this issue
|
||||
* and the suggested steps to reproduce and work around the problem goes
|
||||
* to GitHub user @thinkport.
|
||||
*
|
||||
* On debug builds set DO_LOW_PRIORITY_FILESYSTEM to place the file system
|
||||
* at the end of the file system list during IoRegisterFileSystem below.
|
||||
* This allows us to test the behavior of our Fsvrt devices when foreign
|
||||
* file systems attempt to use them for mounting.
|
||||
*/
|
||||
SetFlag(FspFsctlDiskDeviceObject->Flags, DO_LOW_PRIORITY_FILESYSTEM);
|
||||
#endif
|
||||
|
||||
Result = FspDeviceInitialize(FspFsctlDiskDeviceObject);
|
||||
ASSERT(STATUS_SUCCESS == Result);
|
||||
Result = FspDeviceInitialize(FspFsctlNetDeviceObject);
|
||||
ASSERT(STATUS_SUCCESS == Result);
|
||||
Result = FspDeviceInitialize(FspFsmupDeviceObject);
|
||||
ASSERT(STATUS_SUCCESS == Result);
|
||||
|
||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\" FSP_FSCTL_MUP_DEVICE_NAME);
|
||||
Result = FsRtlRegisterUncProviderEx(&FspMupHandle,
|
||||
&DeviceName, FspFsmupDeviceObject, 0);
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
|
||||
/*
|
||||
* Register our "disk" device as a file system. We do not register our "net" device
|
||||
* as a file system; we register with the MUP instead.
|
||||
*
|
||||
* Please note that the call below makes our driver unloadable. In fact the driver
|
||||
* remains unloadable even if we issue an IoUnregisterFileSystem() call immediately
|
||||
* after our IoRegisterFileSystem() call! Some system component appears to keep an
|
||||
* extra reference to our device somewhere.
|
||||
*/
|
||||
IoRegisterFileSystem(FspFsctlDiskDeviceObject);
|
||||
InitDoneDevices = TRUE;
|
||||
|
||||
Result = STATUS_SUCCESS;
|
||||
|
||||
exit:
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
if (0 != FspFsmupDeviceObject)
|
||||
FspDeviceDelete(FspFsmupDeviceObject);
|
||||
if (0 != FspFsctlNetDeviceObject)
|
||||
FspDeviceDelete(FspFsctlNetDeviceObject);
|
||||
if (0 != FspFsctlDiskDeviceObject)
|
||||
FspDeviceDelete(FspFsctlDiskDeviceObject);
|
||||
if (InitDoneDevices)
|
||||
FspDriverFinalizeDevices();
|
||||
if (InitDonePsBuf)
|
||||
FspProcessBufferFinalize();
|
||||
if (InitDoneSilo)
|
||||
FspSiloFinalize();
|
||||
if (InitDoneGRes)
|
||||
ExDeleteResourceLite(&FspDeviceGlobalResource);
|
||||
}
|
||||
@ -253,35 +187,157 @@ static VOID FspDriverMultiVersionInitialize(VOID)
|
||||
FspHasReparsePointCaseSensitivityFix = TRUE;
|
||||
}
|
||||
|
||||
#if defined(FSP_UNLOAD)
|
||||
VOID FspUnload(
|
||||
PDRIVER_OBJECT DriverObject)
|
||||
static NTSTATUS FspDriverInitializeDevices(VOID)
|
||||
{
|
||||
FSP_ENTER_VOID(PAGED_CODE());
|
||||
PAGED_CODE();
|
||||
|
||||
FsRtlDeregisterUncProvider(FspMupHandle);
|
||||
FSP_SILO_GLOBALS *Globals;
|
||||
UNICODE_STRING DeviceSddl;
|
||||
UNICODE_STRING DeviceName;
|
||||
GUID Guid;
|
||||
NTSTATUS Result;
|
||||
|
||||
FspFsctlDiskDeviceObject = 0;
|
||||
FspFsctlNetDeviceObject = 0;
|
||||
FspFsmupDeviceObject = 0;
|
||||
//FspDeviceDeleteAll();
|
||||
FspSiloGetGlobals(&Globals);
|
||||
ASSERT(0 != Globals);
|
||||
|
||||
ExDeleteResourceLite(&FspDeviceGlobalResource);
|
||||
FspDriverObject = 0;
|
||||
/* create the file system control device objects */
|
||||
RtlInitUnicodeString(&DeviceSddl, L"" FSP_FSCTL_DEVICE_SDDL);
|
||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\" FSP_FSCTL_DISK_DEVICE_NAME);
|
||||
Result = FspDeviceCreateSecure(FspFsctlDeviceExtensionKind, 0,
|
||||
&DeviceName, FILE_DEVICE_DISK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN,
|
||||
&DeviceSddl, &FspFsctlDeviceClassGuid,
|
||||
&Globals->FsctlDiskDeviceObject);
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\" FSP_FSCTL_NET_DEVICE_NAME);
|
||||
Result = FspDeviceCreateSecure(FspFsctlDeviceExtensionKind, 0,
|
||||
&DeviceName, FILE_DEVICE_NETWORK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN,
|
||||
&DeviceSddl, &FspFsctlDeviceClassGuid,
|
||||
&Globals->FsctlNetDeviceObject);
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
Result = FspDeviceCreate(FspFsmupDeviceExtensionKind, 0,
|
||||
FILE_DEVICE_NETWORK_FILE_SYSTEM, FILE_REMOTE_DEVICE,
|
||||
&Globals->FsmupDeviceObject);
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
|
||||
FspProcessBufferFinalize();
|
||||
|
||||
#pragma prefast(suppress:28175, "We are in DriverUnload: ok to access DriverName")
|
||||
FSP_LEAVE_VOID("DriverName=\"%wZ\"",
|
||||
&DriverObject->DriverName);
|
||||
}
|
||||
#if DBG
|
||||
/*
|
||||
* Fix GitHub issue #177. All credit for the investigation of this issue
|
||||
* and the suggested steps to reproduce and work around the problem goes
|
||||
* to GitHub user @thinkport.
|
||||
*
|
||||
* On debug builds set DO_LOW_PRIORITY_FILESYSTEM to place the file system
|
||||
* at the end of the file system list during IoRegisterFileSystem below.
|
||||
* This allows us to test the behavior of our Fsvrt devices when foreign
|
||||
* file systems attempt to use them for mounting.
|
||||
*/
|
||||
SetFlag(Globals->FsctlDiskDeviceObject->Flags, DO_LOW_PRIORITY_FILESYSTEM);
|
||||
#endif
|
||||
|
||||
Result = FspDeviceInitialize(Globals->FsctlDiskDeviceObject);
|
||||
ASSERT(STATUS_SUCCESS == Result);
|
||||
Result = FspDeviceInitialize(Globals->FsctlNetDeviceObject);
|
||||
ASSERT(STATUS_SUCCESS == Result);
|
||||
Result = FspDeviceInitialize(Globals->FsmupDeviceObject);
|
||||
ASSERT(STATUS_SUCCESS == Result);
|
||||
|
||||
FspSiloGetContainerId(&Guid);
|
||||
RtlInitEmptyUnicodeString(&DeviceName,
|
||||
Globals->FsmupDeviceNameBuf, sizeof Globals->FsmupDeviceNameBuf);
|
||||
Result = RtlUnicodeStringPrintf(&DeviceName,
|
||||
0 == ((PULONG)&Guid)[0] && 0 == ((PULONG)&Guid)[1] &&
|
||||
0 == ((PULONG)&Guid)[2] && 0 == ((PULONG)&Guid)[3] ?
|
||||
L"\\Device\\" FSP_FSCTL_MUP_DEVICE_NAME :
|
||||
L"\\Device\\" FSP_FSCTL_MUP_DEVICE_NAME "{%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));
|
||||
DeviceName.MaximumLength = DeviceName.Length;
|
||||
Result = FsRtlRegisterUncProviderEx(&Globals->MupHandle,
|
||||
&DeviceName, Globals->FsmupDeviceObject, 0);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
Globals->MupHandle = 0;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register our "disk" device as a file system. We do not register our "net" device
|
||||
* as a file system; we register with the MUP instead.
|
||||
*/
|
||||
IoRegisterFileSystem(Globals->FsctlDiskDeviceObject);
|
||||
|
||||
Result = STATUS_SUCCESS;
|
||||
|
||||
exit:
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
if (0 != Globals->MupHandle)
|
||||
{
|
||||
FsRtlDeregisterUncProvider(Globals->MupHandle);
|
||||
Globals->MupHandle = 0;
|
||||
}
|
||||
if (0 != Globals->FsmupDeviceObject)
|
||||
{
|
||||
FspDeviceDelete(Globals->FsmupDeviceObject);
|
||||
Globals->FsmupDeviceObject = 0;
|
||||
}
|
||||
if (0 != Globals->FsctlNetDeviceObject)
|
||||
{
|
||||
FspDeviceDelete(Globals->FsctlNetDeviceObject);
|
||||
Globals->FsctlNetDeviceObject = 0;
|
||||
}
|
||||
if (0 != Globals->FsctlDiskDeviceObject)
|
||||
{
|
||||
FspDeviceDelete(Globals->FsctlDiskDeviceObject);
|
||||
Globals->FsctlDiskDeviceObject = 0;
|
||||
}
|
||||
}
|
||||
|
||||
FspSiloDereferenceGlobals(Globals);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
static VOID FspDriverFinalizeDevices(VOID)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
FSP_SILO_GLOBALS *Globals;
|
||||
|
||||
FspSiloGetGlobals(&Globals);
|
||||
ASSERT(0 != Globals);
|
||||
|
||||
IoUnregisterFileSystem(Globals->FsctlDiskDeviceObject);
|
||||
|
||||
if (0 != Globals->MupHandle)
|
||||
{
|
||||
FsRtlDeregisterUncProvider(Globals->MupHandle);
|
||||
Globals->MupHandle = 0;
|
||||
}
|
||||
if (0 != Globals->FsmupDeviceObject)
|
||||
{
|
||||
FspDeviceDelete(Globals->FsmupDeviceObject);
|
||||
Globals->FsmupDeviceObject = 0;
|
||||
}
|
||||
if (0 != Globals->FsctlNetDeviceObject)
|
||||
{
|
||||
FspDeviceDelete(Globals->FsctlNetDeviceObject);
|
||||
Globals->FsctlNetDeviceObject = 0;
|
||||
}
|
||||
if (0 != Globals->FsctlDiskDeviceObject)
|
||||
{
|
||||
FspDeviceDelete(Globals->FsctlDiskDeviceObject);
|
||||
Globals->FsctlDiskDeviceObject = 0;
|
||||
}
|
||||
|
||||
FspSiloDereferenceGlobals(Globals);
|
||||
}
|
||||
|
||||
PDRIVER_OBJECT FspDriverObject;
|
||||
PDEVICE_OBJECT FspFsctlDiskDeviceObject;
|
||||
PDEVICE_OBJECT FspFsctlNetDeviceObject;
|
||||
PDEVICE_OBJECT FspFsmupDeviceObject;
|
||||
HANDLE FspMupHandle;
|
||||
FAST_IO_DISPATCH FspFastIoDispatch;
|
||||
CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
|
||||
|
||||
|
@ -652,6 +652,23 @@ VOID FspIrpHookReset(PIRP Irp);
|
||||
PVOID FspIrpHookContext(PVOID Context);
|
||||
NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
|
||||
|
||||
/* silos */
|
||||
typedef struct
|
||||
{
|
||||
PDEVICE_OBJECT FsctlDiskDeviceObject;
|
||||
PDEVICE_OBJECT FsctlNetDeviceObject;
|
||||
PDEVICE_OBJECT FsmupDeviceObject;
|
||||
HANDLE MupHandle;
|
||||
WCHAR FsmupDeviceNameBuf[64];
|
||||
} FSP_SILO_GLOBALS;
|
||||
typedef NTSTATUS (*FSP_SILO_INIT_CALLBACK)(VOID);
|
||||
typedef VOID (*FSP_SILO_FINI_CALLBACK)(VOID);
|
||||
NTSTATUS FspSiloGetGlobals(FSP_SILO_GLOBALS **PGlobals);
|
||||
VOID FspSiloDereferenceGlobals(FSP_SILO_GLOBALS *Globals);
|
||||
VOID FspSiloGetContainerId(GUID *ContainerId);
|
||||
NTSTATUS FspSiloInitialize(FSP_SILO_INIT_CALLBACK Init, FSP_SILO_FINI_CALLBACK Fini);
|
||||
VOID FspSiloFinalize(VOID);
|
||||
|
||||
/* process buffers */
|
||||
#define FspProcessBufferSizeMax (64 * 1024)
|
||||
NTSTATUS FspProcessBufferInitialize(VOID);
|
||||
@ -1069,6 +1086,7 @@ typedef struct
|
||||
KSPIN_LOCK SpinLock;
|
||||
LONG RefCount;
|
||||
UINT32 Kind;
|
||||
GUID SiloContainerId;
|
||||
} FSP_DEVICE_EXTENSION;
|
||||
typedef struct
|
||||
{
|
||||
@ -1695,10 +1713,6 @@ FSP_MV_CcCoherencyFlushAndPurgeCache(
|
||||
|
||||
/* extern */
|
||||
extern PDRIVER_OBJECT FspDriverObject;
|
||||
extern PDEVICE_OBJECT FspFsctlDiskDeviceObject;
|
||||
extern PDEVICE_OBJECT FspFsctlNetDeviceObject;
|
||||
extern PDEVICE_OBJECT FspFsmupDeviceObject;
|
||||
extern HANDLE FspMupHandle;
|
||||
extern FAST_IO_DISPATCH FspFastIoDispatch;
|
||||
extern CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
|
||||
extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[];
|
||||
|
325
src/sys/silo.c
Normal file
325
src/sys/silo.c
Normal file
@ -0,0 +1,325 @@
|
||||
/**
|
||||
* @file sys/silo.c
|
||||
*
|
||||
* @copyright 2015-2020 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>
|
||||
|
||||
NTSTATUS FspSiloInitialize(FSP_SILO_INIT_CALLBACK Init, FSP_SILO_FINI_CALLBACK Fini);
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(INIT, FspSiloInitialize)
|
||||
#endif
|
||||
|
||||
typedef PEJOB FSP_PESILO;
|
||||
typedef PVOID FSP_PSILO_MONITOR;
|
||||
|
||||
typedef NTSTATUS (NTAPI *FSP_SILO_MONITOR_CREATE_CALLBACK)(FSP_PESILO Silo);
|
||||
typedef VOID (NTAPI *FSP_SILO_MONITOR_TERMINATE_CALLBACK)(FSP_PESILO Silo);
|
||||
typedef VOID (NTAPI *FSP_SILO_CONTEXT_CLEANUP_CALLBACK)(PVOID SiloContext);
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4201) /* nameless struct/union */
|
||||
typedef struct _FSP_SILO_MONITOR_REGISTRATION
|
||||
{
|
||||
UCHAR Version;
|
||||
BOOLEAN MonitorHost;
|
||||
BOOLEAN MonitorExistingSilos;
|
||||
UCHAR Reserved[5];
|
||||
union
|
||||
{
|
||||
PUNICODE_STRING DriverObjectName;
|
||||
PUNICODE_STRING ComponentName;
|
||||
};
|
||||
FSP_SILO_MONITOR_CREATE_CALLBACK CreateCallback;
|
||||
FSP_SILO_MONITOR_TERMINATE_CALLBACK TerminateCallback;
|
||||
} FSP_SILO_MONITOR_REGISTRATION;
|
||||
#pragma warning(pop)
|
||||
|
||||
typedef NTSTATUS FSP_SILO_PsRegisterSiloMonitor(
|
||||
FSP_SILO_MONITOR_REGISTRATION *Registration,
|
||||
FSP_PSILO_MONITOR *ReturnedMonitor);
|
||||
typedef NTSTATUS FSP_SILO_PsStartSiloMonitor(
|
||||
FSP_PSILO_MONITOR Monitor);
|
||||
typedef VOID FSP_SILO_PsUnregisterSiloMonitor(
|
||||
FSP_PSILO_MONITOR Monitor);
|
||||
typedef ULONG FSP_SILO_PsGetSiloMonitorContextSlot(
|
||||
FSP_PSILO_MONITOR Monitor);
|
||||
typedef NTSTATUS FSP_SILO_PsCreateSiloContext(
|
||||
FSP_PESILO Silo,
|
||||
ULONG Size,
|
||||
POOL_TYPE PoolType,
|
||||
FSP_SILO_CONTEXT_CLEANUP_CALLBACK ContextCleanupCallback,
|
||||
PVOID *ReturnedSiloContext);
|
||||
typedef VOID FSP_SILO_PsDereferenceSiloContext(
|
||||
PVOID SiloContext);
|
||||
typedef NTSTATUS FSP_SILO_PsInsertSiloContext(
|
||||
FSP_PESILO Silo,
|
||||
ULONG ContextSlot,
|
||||
PVOID SiloContext);
|
||||
typedef NTSTATUS FSP_SILO_PsRemoveSiloContext(
|
||||
FSP_PESILO Silo,
|
||||
ULONG ContextSlot,
|
||||
PVOID *RemovedSiloContext);
|
||||
typedef NTSTATUS FSP_SILO_PsGetSiloContext(
|
||||
FSP_PESILO Silo,
|
||||
ULONG ContextSlot,
|
||||
PVOID *ReturnedSiloContext);
|
||||
typedef FSP_PESILO FSP_SILO_PsAttachSiloToCurrentThread(
|
||||
FSP_PESILO Silo);
|
||||
typedef VOID FSP_SILO_PsDetachSiloFromCurrentThread(
|
||||
FSP_PESILO PreviousSilo);
|
||||
typedef FSP_PESILO FSP_SILO_PsGetCurrentServerSilo(
|
||||
VOID);
|
||||
typedef GUID* FSP_SILO_PsGetSiloContainerId(
|
||||
FSP_PESILO Silo);
|
||||
|
||||
static FSP_SILO_PsRegisterSiloMonitor *FspSiloPsRegisterSiloMonitor;
|
||||
static FSP_SILO_PsStartSiloMonitor *FspSiloPsStartSiloMonitor;
|
||||
static FSP_SILO_PsUnregisterSiloMonitor *FspSiloPsUnregisterSiloMonitor;
|
||||
static FSP_SILO_PsGetSiloMonitorContextSlot *FspSiloPsGetSiloMonitorContextSlot;
|
||||
static FSP_SILO_PsCreateSiloContext *FspSiloPsCreateSiloContext;
|
||||
static FSP_SILO_PsDereferenceSiloContext *FspSiloPsDereferenceSiloContext;
|
||||
static FSP_SILO_PsInsertSiloContext *FspSiloPsInsertSiloContext;
|
||||
static FSP_SILO_PsRemoveSiloContext *FspSiloPsRemoveSiloContext;
|
||||
static FSP_SILO_PsGetSiloContext *FspSiloPsGetSiloContext;
|
||||
static FSP_SILO_PsAttachSiloToCurrentThread *FspSiloPsAttachSiloToCurrentThread;
|
||||
static FSP_SILO_PsDetachSiloFromCurrentThread *FspSiloPsDetachSiloFromCurrentThread;
|
||||
static FSP_SILO_PsGetCurrentServerSilo *FspSiloPsGetCurrentServerSilo;
|
||||
static FSP_SILO_PsGetSiloContainerId *FspSiloPsGetSiloContainerId;
|
||||
static FSP_PSILO_MONITOR FspSiloMonitor;
|
||||
static FSP_SILO_INIT_CALLBACK FspSiloInitCallback;
|
||||
static FSP_SILO_FINI_CALLBACK FspSiloFiniCallback;
|
||||
static BOOLEAN FspSiloInitDone = FALSE;
|
||||
|
||||
static FSP_SILO_GLOBALS FspSiloHostGlobals;
|
||||
|
||||
#define FSP_SILO_MONITOR_REGISTRATION_VERSION 1
|
||||
|
||||
#define LOAD(n) \
|
||||
{ \
|
||||
UNICODE_STRING Name; \
|
||||
RtlInitUnicodeString(&Name, L"" #n);\
|
||||
FspSilo ## n = \
|
||||
(FSP_SILO_ ## n *)(UINT_PTR)MmGetSystemRoutineAddress(&Name);\
|
||||
if (0 == FspSilo ## n) \
|
||||
Fail++; \
|
||||
}
|
||||
#define CALL(n) (FspSilo ## n)
|
||||
|
||||
NTSTATUS FspSiloGetGlobals(FSP_SILO_GLOBALS **PGlobals)
|
||||
{
|
||||
FSP_PESILO Silo;
|
||||
ULONG ContextSlot;
|
||||
FSP_SILO_GLOBALS *Globals;
|
||||
NTSTATUS Result;
|
||||
|
||||
if (!FspSiloInitDone ||
|
||||
0 == (Silo = CALL(PsGetCurrentServerSilo)()))
|
||||
{
|
||||
*PGlobals = &FspSiloHostGlobals;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ContextSlot = CALL(PsGetSiloMonitorContextSlot)(FspSiloMonitor);
|
||||
|
||||
Result = CALL(PsGetSiloContext)(Silo, ContextSlot, &Globals);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
*PGlobals = 0;
|
||||
return Result;
|
||||
}
|
||||
|
||||
*PGlobals = Globals;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID FspSiloDereferenceGlobals(FSP_SILO_GLOBALS *Globals)
|
||||
{
|
||||
if (&FspSiloHostGlobals == Globals)
|
||||
return;
|
||||
|
||||
CALL(PsDereferenceSiloContext)(Globals);
|
||||
}
|
||||
|
||||
VOID FspSiloGetContainerId(GUID *ContainerId)
|
||||
{
|
||||
FSP_PESILO Silo;
|
||||
GUID *Guid;
|
||||
|
||||
if (!FspSiloInitDone ||
|
||||
0 == (Silo = CALL(PsGetCurrentServerSilo)()) ||
|
||||
0 == (Guid = CALL(PsGetSiloContainerId)(Silo)))
|
||||
{
|
||||
RtlZeroMemory(ContainerId, sizeof *ContainerId);
|
||||
return;
|
||||
}
|
||||
|
||||
RtlCopyMemory(ContainerId, Guid, sizeof *ContainerId);
|
||||
}
|
||||
|
||||
static NTSTATUS NTAPI FspSiloMonitorCreateCallback(FSP_PESILO Silo)
|
||||
{
|
||||
ULONG ContextSlot;
|
||||
FSP_SILO_GLOBALS *Globals = 0;
|
||||
BOOLEAN Inserted = FALSE;
|
||||
NTSTATUS Result;
|
||||
|
||||
ASSERT(0 != Silo);
|
||||
|
||||
ContextSlot = CALL(PsGetSiloMonitorContextSlot)(FspSiloMonitor);
|
||||
|
||||
Result = CALL(PsCreateSiloContext)(Silo, sizeof(FSP_SILO_GLOBALS), NonPagedPoolNx, 0, &Globals);
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
RtlZeroMemory(Globals, sizeof(FSP_SILO_GLOBALS));
|
||||
|
||||
/* PsInsertSiloContext adds reference to Globals */
|
||||
Result = CALL(PsInsertSiloContext)(Silo, ContextSlot, Globals);
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
Inserted = TRUE;
|
||||
|
||||
if (0 != FspSiloInitCallback)
|
||||
{
|
||||
FSP_PESILO PreviousSilo = CALL(PsAttachSiloToCurrentThread)(Silo);
|
||||
Result = FspSiloInitCallback();
|
||||
CALL(PsDetachSiloFromCurrentThread)(PreviousSilo);
|
||||
}
|
||||
|
||||
exit:
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
if (Inserted)
|
||||
CALL(PsRemoveSiloContext)(Silo, ContextSlot, 0);
|
||||
}
|
||||
|
||||
if (0 != Globals)
|
||||
CALL(PsDereferenceSiloContext)(Globals);
|
||||
|
||||
/*
|
||||
* Ignore errors and return success. There are two reasons for this:
|
||||
*
|
||||
* - Returning an error will disallow container creation.
|
||||
* - In some cases returning an error will crash Windows with an
|
||||
* unexpected page fault in wcifs.sys.
|
||||
*/
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static VOID NTAPI FspSiloMonitorTerminateCallback(FSP_PESILO Silo)
|
||||
{
|
||||
ULONG ContextSlot;
|
||||
FSP_SILO_GLOBALS *Globals;
|
||||
NTSTATUS Result;
|
||||
|
||||
ASSERT(0 != Silo);
|
||||
|
||||
ContextSlot = CALL(PsGetSiloMonitorContextSlot)(FspSiloMonitor);
|
||||
|
||||
/* if we cannot get the Globals, it must mean that we failed in Create callback */
|
||||
Result = CALL(PsGetSiloContext)(Silo, ContextSlot, &Globals);
|
||||
if (!NT_SUCCESS(Result))
|
||||
return;
|
||||
CALL(PsDereferenceSiloContext)(Globals);
|
||||
Globals = 0;
|
||||
|
||||
if (0 != FspSiloFiniCallback)
|
||||
{
|
||||
FSP_PESILO PreviousSilo = CALL(PsAttachSiloToCurrentThread)(Silo);
|
||||
FspSiloFiniCallback();
|
||||
CALL(PsDetachSiloFromCurrentThread)(PreviousSilo);
|
||||
}
|
||||
|
||||
/* PsRemoveSiloContext removes reference to Globals (possibly freeing it) */
|
||||
CALL(PsRemoveSiloContext)(Silo, ContextSlot, 0);
|
||||
}
|
||||
|
||||
NTSTATUS FspSiloInitialize(FSP_SILO_INIT_CALLBACK Init, FSP_SILO_FINI_CALLBACK Fini)
|
||||
{
|
||||
NTSTATUS Result = STATUS_SUCCESS;
|
||||
|
||||
if (FspIsNtDdiVersionAvailable(NTDDI_WIN10_RS5))
|
||||
{
|
||||
ULONG Fail = 0;
|
||||
|
||||
LOAD(PsRegisterSiloMonitor);
|
||||
LOAD(PsStartSiloMonitor);
|
||||
LOAD(PsUnregisterSiloMonitor);
|
||||
LOAD(PsGetSiloMonitorContextSlot);
|
||||
LOAD(PsCreateSiloContext);
|
||||
LOAD(PsDereferenceSiloContext);
|
||||
LOAD(PsInsertSiloContext);
|
||||
LOAD(PsRemoveSiloContext);
|
||||
LOAD(PsGetSiloContext);
|
||||
LOAD(PsAttachSiloToCurrentThread);
|
||||
LOAD(PsDetachSiloFromCurrentThread);
|
||||
LOAD(PsGetCurrentServerSilo);
|
||||
LOAD(PsGetSiloContainerId);
|
||||
|
||||
if (0 == Fail)
|
||||
{
|
||||
FSP_SILO_MONITOR_REGISTRATION Registration =
|
||||
{
|
||||
.Version = FSP_SILO_MONITOR_REGISTRATION_VERSION,
|
||||
.MonitorHost = FALSE,
|
||||
.MonitorExistingSilos = TRUE,
|
||||
.DriverObjectName = 0,
|
||||
.CreateCallback = FspSiloMonitorCreateCallback,
|
||||
.TerminateCallback = FspSiloMonitorTerminateCallback,
|
||||
};
|
||||
FSP_PSILO_MONITOR Monitor = 0;
|
||||
UNICODE_STRING DriverName;
|
||||
|
||||
RtlInitUnicodeString(&DriverName, L"" DRIVER_NAME);
|
||||
Registration.DriverObjectName = &DriverName;
|
||||
Result = CALL(PsRegisterSiloMonitor)(&Registration, &Monitor);
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
|
||||
Result = CALL(PsStartSiloMonitor)(Monitor);
|
||||
if (!NT_SUCCESS(Result))
|
||||
goto exit;
|
||||
|
||||
FspSiloMonitor = Monitor;
|
||||
FspSiloInitCallback = Init;
|
||||
FspSiloFiniCallback = Fini;
|
||||
|
||||
FspSiloInitDone = TRUE;
|
||||
Result = STATUS_SUCCESS;
|
||||
|
||||
exit:
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
if (0 != Monitor)
|
||||
CALL(PsUnregisterSiloMonitor)(Monitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
VOID FspSiloFinalize(VOID)
|
||||
{
|
||||
if (!FspSiloInitDone)
|
||||
return;
|
||||
|
||||
CALL(PsUnregisterSiloMonitor)(FspSiloMonitor);
|
||||
}
|
@ -24,11 +24,13 @@
|
||||
NTSTATUS FspVolumeCreate(
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
static NTSTATUS FspVolumeCreateNoLock(
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
|
||||
FSP_SILO_GLOBALS *Globals);
|
||||
VOID FspVolumeDelete(
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
static VOID FspVolumeDeleteNoLock(
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
|
||||
FSP_SILO_GLOBALS *Globals);
|
||||
static WORKER_THREAD_ROUTINE FspVolumeDeleteDelayed;
|
||||
NTSTATUS FspVolumeMount(
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
@ -77,15 +79,25 @@ NTSTATUS FspVolumeCreate(
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
FSP_SILO_GLOBALS *Globals;
|
||||
NTSTATUS Result;
|
||||
|
||||
FspSiloGetGlobals(&Globals);
|
||||
ASSERT(0 != Globals);
|
||||
|
||||
FspDeviceGlobalLock();
|
||||
Result = FspVolumeCreateNoLock(FsctlDeviceObject, Irp, IrpSp);
|
||||
Result = FspVolumeCreateNoLock(FsctlDeviceObject, Irp, IrpSp,
|
||||
Globals);
|
||||
FspDeviceGlobalUnlock();
|
||||
|
||||
FspSiloDereferenceGlobals(Globals);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
static NTSTATUS FspVolumeCreateNoLock(
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
|
||||
FSP_SILO_GLOBALS *Globals)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
@ -302,18 +314,18 @@ static NTSTATUS FspVolumeCreateNoLock(
|
||||
/* do we need to register with fsmup? */
|
||||
if (0 == FsvrtDeviceObject)
|
||||
{
|
||||
Result = FspMupRegister(FspFsmupDeviceObject, FsvolDeviceObject);
|
||||
Result = FspMupRegister(Globals->FsmupDeviceObject, FsvolDeviceObject);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
FspDeviceDereference(FsvolDeviceObject);
|
||||
return Result;
|
||||
}
|
||||
|
||||
RtlInitUnicodeString(&FsmupDeviceName, L"\\Device\\" FSP_FSCTL_MUP_DEVICE_NAME);
|
||||
RtlInitUnicodeString(&FsmupDeviceName, Globals->FsmupDeviceNameBuf);
|
||||
Result = IoCreateSymbolicLink(&FsvolDeviceExtension->VolumeName, &FsmupDeviceName);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
FspMupUnregister(FspFsmupDeviceObject, FsvolDeviceObject);
|
||||
FspMupUnregister(Globals->FsmupDeviceObject, FsvolDeviceObject);
|
||||
FspDeviceDereference(FsvolDeviceObject);
|
||||
return Result;
|
||||
}
|
||||
@ -331,6 +343,7 @@ VOID FspVolumeDelete(
|
||||
{
|
||||
// !PAGED_CODE();
|
||||
|
||||
FSP_SILO_GLOBALS *Globals;
|
||||
PDEVICE_OBJECT FsvolDeviceObject = IrpSp->FileObject->FsContext2;
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||
PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject;
|
||||
@ -350,10 +363,16 @@ VOID FspVolumeDelete(
|
||||
|
||||
FspDeviceReference(FsvolDeviceObject);
|
||||
|
||||
FspSiloGetGlobals(&Globals);
|
||||
ASSERT(0 != Globals);
|
||||
|
||||
FspDeviceGlobalLock();
|
||||
FspVolumeDeleteNoLock(FsctlDeviceObject, Irp, IrpSp);
|
||||
FspVolumeDeleteNoLock(FsctlDeviceObject, Irp, IrpSp,
|
||||
Globals);
|
||||
FspDeviceGlobalUnlock();
|
||||
|
||||
FspSiloDereferenceGlobals(Globals);
|
||||
|
||||
/*
|
||||
* Call MmForceSectionClosed on active files to ensure that Mm removes them from Standby List.
|
||||
*/
|
||||
@ -370,7 +389,8 @@ VOID FspVolumeDelete(
|
||||
}
|
||||
|
||||
static VOID FspVolumeDeleteNoLock(
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp,
|
||||
FSP_SILO_GLOBALS *Globals)
|
||||
{
|
||||
// !PAGED_CODE();
|
||||
|
||||
@ -445,7 +465,7 @@ static VOID FspVolumeDeleteNoLock(
|
||||
else
|
||||
{
|
||||
IoDeleteSymbolicLink(&FsvolDeviceExtension->VolumeName);
|
||||
FspMupUnregister(FspFsmupDeviceObject, FsvolDeviceObject);
|
||||
FspMupUnregister(Globals->FsmupDeviceObject, FsvolDeviceObject);
|
||||
}
|
||||
|
||||
/* release the volume device object */
|
||||
|
Loading…
x
Reference in New Issue
Block a user