mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 03:28:38 -05:00 
			
		
		
		
	sys: FspFsextProvider: load provider driver
This commit is contained in:
		| @@ -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); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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); | ||||||
|                 } |                 } | ||||||
|   | |||||||
| @@ -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); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user