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

View File

@ -37,6 +37,12 @@
#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 */
#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 */
@ -1182,7 +1188,7 @@ VOID FspDeviceGlobalUnlock(VOID)
// STATUS_VOLUME_DISMOUNTED : STATUS_DEVICE_NOT_CONNECTED)
/* fsext */
FSP_FSEXT_PROVIDER *FspFsextProvider(UINT32 ControlCode);
FSP_FSEXT_PROVIDER *FspFsextProvider(UINT32 ControlCode, PNTSTATUS PLoadResult);
/* process buffers conditional usage */
static inline

View File

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

View File

@ -25,7 +25,7 @@
static KSPIN_LOCK FsextSpinLock = 0;
FSP_FSEXT_PROVIDER *FsextProvider;
FSP_FSEXT_PROVIDER *FspFsextProvider(UINT32 ControlCode)
FSP_FSEXT_PROVIDER *FspFsextProvider(UINT32 ControlCode, PNTSTATUS PLoadResult)
{
FSP_FSEXT_PROVIDER *Provider;
KIRQL Irql;
@ -34,6 +34,61 @@ FSP_FSEXT_PROVIDER *FspFsextProvider(UINT32 ControlCode)
Provider = FsextProvider;
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;
}
@ -43,14 +98,18 @@ NTSTATUS FspFsextProviderRegister(FSP_FSEXT_PROVIDER *Provider)
KIRQL Irql;
KeAcquireSpinLock(&FsextSpinLock, &Irql);
if (0 != FsextProvider)
{
Result = STATUS_TOO_LATE;
goto exit;
}
Provider->DeviceExtensionOffset = FIELD_OFFSET(FSP_FSVOL_DEVICE_EXTENSION, FsextData);
FsextProvider = Provider;
Result = STATUS_SUCCESS;
exit:
KeReleaseSpinLock(&FsextSpinLock, Irql);