sys: FspFsextProvider: load provider driver

This commit is contained in:
Bill Zissimopoulos 2019-06-18 20:28:59 -07:00
parent f4496786e5
commit 4ae03629f7
4 changed files with 76 additions and 6 deletions

View File

@ -329,7 +329,7 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject)
if (0 != FsvolDeviceExtension->VolumeParams.FsextControlCode) if (0 != FsvolDeviceExtension->VolumeParams.FsextControlCode)
{ {
FSP_FSEXT_PROVIDER *Provider = FspFsextProvider( FSP_FSEXT_PROVIDER *Provider = FspFsextProvider(
FsvolDeviceExtension->VolumeParams.FsextControlCode); FsvolDeviceExtension->VolumeParams.FsextControlCode, &Result);
if (0 != Provider) if (0 != Provider)
{ {
Result = Provider->DeviceInit(DeviceObject, &FsvolDeviceExtension->VolumeParams); Result = Provider->DeviceInit(DeviceObject, &FsvolDeviceExtension->VolumeParams);
@ -337,6 +337,11 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject)
return Result; return Result;
FsvolDeviceExtension->InitDoneFsext = 1; FsvolDeviceExtension->InitDoneFsext = 1;
} }
else
{
ASSERT(!NT_SUCCESS(Result));
return Result;
}
} }
/* is there a virtual disk? */ /* is there a virtual disk? */
@ -519,7 +524,7 @@ static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject)
if (FsvolDeviceExtension->InitDoneFsext) if (FsvolDeviceExtension->InitDoneFsext)
{ {
FSP_FSEXT_PROVIDER *Provider = FspFsextProvider( FSP_FSEXT_PROVIDER *Provider = FspFsextProvider(
FsvolDeviceExtension->VolumeParams.FsextControlCode); FsvolDeviceExtension->VolumeParams.FsextControlCode, 0);
if (0 != Provider) if (0 != Provider)
Provider->DeviceFini(DeviceObject); Provider->DeviceFini(DeviceObject);
} }
@ -573,7 +578,7 @@ static VOID FspFsvolDeviceExpirationRoutine(PVOID Context)
if (0 != FsvolDeviceExtension->VolumeParams.FsextControlCode) if (0 != FsvolDeviceExtension->VolumeParams.FsextControlCode)
{ {
FSP_FSEXT_PROVIDER *Provider = FspFsextProvider( FSP_FSEXT_PROVIDER *Provider = FspFsextProvider(
FsvolDeviceExtension->VolumeParams.FsextControlCode); FsvolDeviceExtension->VolumeParams.FsextControlCode, 0);
if (0 != Provider) if (0 != Provider)
Provider->DeviceExpirationRoutine(DeviceObject, InterruptTime); Provider->DeviceExpirationRoutine(DeviceObject, InterruptTime);
} }

View File

@ -37,6 +37,12 @@
#define DRIVER_NAME FSP_FSCTL_DRIVER_NAME #define DRIVER_NAME FSP_FSCTL_DRIVER_NAME
#if _WIN64
#define FSP_REGKEY "\\Registry\\Machine\\Software\\WOW6432Node\\WinFsp"
#else
#define FSP_REGKEY "\\Registry\\Machine\\Software\\WinFsp"
#endif
/* IoCreateDeviceSecure default SDDL's */ /* IoCreateDeviceSecure default SDDL's */
#define FSP_FSCTL_DEVICE_SDDL "D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GR;;;WD)" #define FSP_FSCTL_DEVICE_SDDL "D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GR;;;WD)"
/* System:GENERIC_ALL, Administrators:GENERIC_ALL, World:GENERIC_READ */ /* System:GENERIC_ALL, Administrators:GENERIC_ALL, World:GENERIC_READ */
@ -1182,7 +1188,7 @@ VOID FspDeviceGlobalUnlock(VOID)
// STATUS_VOLUME_DISMOUNTED : STATUS_DEVICE_NOT_CONNECTED) // STATUS_VOLUME_DISMOUNTED : STATUS_DEVICE_NOT_CONNECTED)
/* fsext */ /* fsext */
FSP_FSEXT_PROVIDER *FspFsextProvider(UINT32 ControlCode); FSP_FSEXT_PROVIDER *FspFsextProvider(UINT32 ControlCode, PNTSTATUS PLoadResult);
/* process buffers conditional usage */ /* process buffers conditional usage */
static inline static inline

View File

@ -113,7 +113,7 @@ static NTSTATUS FspFsctlFileSystemControl(
FsvolDeviceExtension->VolumeParams.FsextControlCode) FsvolDeviceExtension->VolumeParams.FsextControlCode)
{ {
FSP_FSEXT_PROVIDER *Provider = FspFsextProvider( FSP_FSEXT_PROVIDER *Provider = FspFsextProvider(
FsvolDeviceExtension->VolumeParams.FsextControlCode); FsvolDeviceExtension->VolumeParams.FsextControlCode, 0);
if (0 != Provider) if (0 != Provider)
Result = Provider->DeviceTransact(FsvolDeviceObject, Irp); Result = Provider->DeviceTransact(FsvolDeviceObject, Irp);
} }

View File

@ -25,7 +25,7 @@
static KSPIN_LOCK FsextSpinLock = 0; static KSPIN_LOCK FsextSpinLock = 0;
FSP_FSEXT_PROVIDER *FsextProvider; FSP_FSEXT_PROVIDER *FsextProvider;
FSP_FSEXT_PROVIDER *FspFsextProvider(UINT32 ControlCode) FSP_FSEXT_PROVIDER *FspFsextProvider(UINT32 ControlCode, PNTSTATUS PLoadResult)
{ {
FSP_FSEXT_PROVIDER *Provider; FSP_FSEXT_PROVIDER *Provider;
KIRQL Irql; KIRQL Irql;
@ -34,6 +34,61 @@ FSP_FSEXT_PROVIDER *FspFsextProvider(UINT32 ControlCode)
Provider = FsextProvider; Provider = FsextProvider;
KeReleaseSpinLock(&FsextSpinLock, Irql); KeReleaseSpinLock(&FsextSpinLock, Irql);
if (0 != PLoadResult)
{
if (0 == Provider)
{
WCHAR Buf[64 + 256];
UNICODE_STRING Path;
UNICODE_STRING Name;
union
{
KEY_VALUE_PARTIAL_INFORMATION V;
UINT8 B[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + 256];
} Value;
ULONG Length;
NTSTATUS Result;
RtlInitUnicodeString(&Path, L"" FSP_REGKEY "\\Fsext");
RtlInitEmptyUnicodeString(&Name, Buf, sizeof Buf);
Result = RtlUnicodeStringPrintf(&Name, L"%08x", ControlCode);
ASSERT(NT_SUCCESS(Result));
Length = sizeof Value;
Result = FspRegistryGetValue(&Path, &Name, &Value.V, &Length);
if (STATUS_SUCCESS != Result/*!NT_SUCCESS*/)
{
if (STATUS_BUFFER_OVERFLOW == Result)
Result = STATUS_BUFFER_TOO_SMALL;
*PLoadResult = Result;
return 0;
}
if (REG_SZ != Value.V.Type)
{
*PLoadResult = STATUS_OBJECT_NAME_NOT_FOUND;
return 0;
}
RtlInitEmptyUnicodeString(&Path, Buf, sizeof Buf);
Result = RtlUnicodeStringPrintf(&Path,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\%s", Value.V.Data);
ASSERT(NT_SUCCESS(Result));
Result = ZwLoadDriver(&Path);
if (!NT_SUCCESS(Result) && STATUS_IMAGE_ALREADY_LOADED != Result)
{
*PLoadResult = Result;
return 0;
}
KeAcquireSpinLock(&FsextSpinLock, &Irql);
Provider = FsextProvider;
KeReleaseSpinLock(&FsextSpinLock, Irql);
}
*PLoadResult = 0 != Provider ? STATUS_SUCCESS : STATUS_OBJECT_NAME_NOT_FOUND;
}
return Provider; return Provider;
} }
@ -43,14 +98,18 @@ NTSTATUS FspFsextProviderRegister(FSP_FSEXT_PROVIDER *Provider)
KIRQL Irql; KIRQL Irql;
KeAcquireSpinLock(&FsextSpinLock, &Irql); KeAcquireSpinLock(&FsextSpinLock, &Irql);
if (0 != FsextProvider) if (0 != FsextProvider)
{ {
Result = STATUS_TOO_LATE; Result = STATUS_TOO_LATE;
goto exit; goto exit;
} }
Provider->DeviceExtensionOffset = FIELD_OFFSET(FSP_FSVOL_DEVICE_EXTENSION, FsextData); Provider->DeviceExtensionOffset = FIELD_OFFSET(FSP_FSVOL_DEVICE_EXTENSION, FsextData);
FsextProvider = Provider; FsextProvider = Provider;
Result = STATUS_SUCCESS; Result = STATUS_SUCCESS;
exit: exit:
KeReleaseSpinLock(&FsextSpinLock, Irql); KeReleaseSpinLock(&FsextSpinLock, Irql);