mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-31 03:58:38 -05:00 
			
		
		
		
	sys: device extension reference count
This commit is contained in:
		
							
								
								
									
										315
									
								
								src/sys/device.c
									
									
									
									
									
								
							
							
						
						
									
										315
									
								
								src/sys/device.c
									
									
									
									
									
								
							| @@ -6,40 +6,249 @@ | |||||||
|  |  | ||||||
| #include <sys/driver.h> | #include <sys/driver.h> | ||||||
|  |  | ||||||
| NTSTATUS FspDeviceCreateList( | NTSTATUS FspDeviceCreateSecure(UINT32 Kind, ULONG ExtraSize, | ||||||
|     PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount); |     PUNICODE_STRING DeviceName, DEVICE_TYPE DeviceType, | ||||||
|  |     PUNICODE_STRING DeviceSddl, LPCGUID DeviceClassGuid, | ||||||
|  |     PDEVICE_OBJECT *PDeviceObject); | ||||||
|  | NTSTATUS FspDeviceCreate(UINT32 Kind, ULONG ExtraSize, | ||||||
|  |     DEVICE_TYPE DeviceType, | ||||||
|  |     PDEVICE_OBJECT *PDeviceObject); | ||||||
|  | VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject); | ||||||
|  | static NTSTATUS FspFsctlDeviceInit(PDEVICE_OBJECT DeviceObject); | ||||||
|  | static VOID FspFsctlDeviceFini(PDEVICE_OBJECT DeviceObject); | ||||||
|  | static NTSTATUS FspFsvrtDeviceInit(PDEVICE_OBJECT DeviceObject); | ||||||
|  | static VOID FspFsvrtDeviceFini(PDEVICE_OBJECT DeviceObject); | ||||||
|  | static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject); | ||||||
|  | static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject); | ||||||
|  | BOOLEAN FspDeviceRetain(PDEVICE_OBJECT DeviceObject); | ||||||
|  | VOID FspDeviceRelease(PDEVICE_OBJECT DeviceObject); | ||||||
|  | NTSTATUS FspDeviceCopyList( | ||||||
|  |     PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount); | ||||||
| VOID FspDeviceDeleteList( | VOID FspDeviceDeleteList( | ||||||
|     PDEVICE_OBJECT *DeviceObjects, ULONG DeviceObjectCount); |     PDEVICE_OBJECT *DeviceObjects, ULONG DeviceObjectCount); | ||||||
| NTSTATUS FspDeviceOwned( | NTSTATUS FspDeviceOwned(PDEVICE_OBJECT DeviceObject); | ||||||
|     PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT DeviceObject); | VOID FspDeviceDeleteAll(VOID); | ||||||
| VOID FspDeviceInitExtension(PDEVICE_OBJECT DeviceObject, UINT8 Kind); |  | ||||||
| static VOID FspFsctlDeviceDeleteObject(PDEVICE_OBJECT DeviceObject); |  | ||||||
| static VOID FspFsvrtDeviceDeleteObject(PDEVICE_OBJECT DeviceObject); |  | ||||||
| static VOID FspFsvolDeviceDeleteObject(PDEVICE_OBJECT DeviceObject); |  | ||||||
| VOID FspDeviceDeleteObject(PDEVICE_OBJECT DeviceObject); |  | ||||||
| VOID FspDeviceDeleteObjects(PDRIVER_OBJECT DriverObject); |  | ||||||
|  |  | ||||||
| #ifdef ALLOC_PRAGMA | #ifdef ALLOC_PRAGMA | ||||||
| #pragma alloc_text(PAGE, FspDeviceCreateList) | #pragma alloc_text(PAGE, FspDeviceCreateSecure) | ||||||
|  | #pragma alloc_text(PAGE, FspDeviceCreate) | ||||||
|  | #pragma alloc_text(PAGE, FspDeviceDelete) | ||||||
|  | #pragma alloc_text(PAGE, FspFsctlDeviceInit) | ||||||
|  | #pragma alloc_text(PAGE, FspFsctlDeviceFini) | ||||||
|  | #pragma alloc_text(PAGE, FspFsvrtDeviceInit) | ||||||
|  | #pragma alloc_text(PAGE, FspFsvrtDeviceFini) | ||||||
|  | #pragma alloc_text(PAGE, FspFsvolDeviceInit) | ||||||
|  | #pragma alloc_text(PAGE, FspFsvolDeviceFini) | ||||||
|  | #pragma alloc_text(PAGE, FspDeviceCopyList) | ||||||
| #pragma alloc_text(PAGE, FspDeviceDeleteList) | #pragma alloc_text(PAGE, FspDeviceDeleteList) | ||||||
| #pragma alloc_text(PAGE, FspDeviceOwned) | #pragma alloc_text(PAGE, FspDeviceOwned) | ||||||
| #pragma alloc_text(PAGE, FspDeviceInitExtension) | #pragma alloc_text(PAGE, FspDeviceDeleteAll) | ||||||
| #pragma alloc_text(PAGE, FspFsctlDeviceDeleteObject) |  | ||||||
| #pragma alloc_text(PAGE, FspFsvrtDeviceDeleteObject) |  | ||||||
| #pragma alloc_text(PAGE, FspFsvolDeviceDeleteObject) |  | ||||||
| #pragma alloc_text(PAGE, FspDeviceDeleteObject) |  | ||||||
| #pragma alloc_text(PAGE, FspDeviceDeleteObjects) |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| NTSTATUS FspDeviceCreateList( | NTSTATUS FspDeviceCreateSecure(UINT32 Kind, ULONG ExtraSize, | ||||||
|     PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount) |     PUNICODE_STRING DeviceName, DEVICE_TYPE DeviceType, | ||||||
|  |     PUNICODE_STRING DeviceSddl, LPCGUID DeviceClassGuid, | ||||||
|  |     PDEVICE_OBJECT *PDeviceObject) | ||||||
|  | { | ||||||
|  |     PAGED_CODE(); | ||||||
|  |  | ||||||
|  |     NTSTATUS Result; | ||||||
|  |     ULONG DeviceExtensionSize; | ||||||
|  |     PDEVICE_OBJECT DeviceObject; | ||||||
|  |     FSP_DEVICE_EXTENSION *DeviceExtension; | ||||||
|  |  | ||||||
|  |     switch (Kind) | ||||||
|  |     { | ||||||
|  |     case FspFsvolDeviceExtensionKind: | ||||||
|  |         DeviceExtensionSize = sizeof(FSP_FSVOL_DEVICE_EXTENSION); | ||||||
|  |         break; | ||||||
|  |     case FspFsvrtDeviceExtensionKind: | ||||||
|  |         DeviceExtensionSize = sizeof(FSP_FSVRT_DEVICE_EXTENSION); | ||||||
|  |         break; | ||||||
|  |     case FspFsctlDeviceExtensionKind: | ||||||
|  |         DeviceExtensionSize = sizeof(FSP_FSCTL_DEVICE_EXTENSION); | ||||||
|  |         break; | ||||||
|  |     default: | ||||||
|  |         ASSERT(0); | ||||||
|  |         return STATUS_INVALID_PARAMETER; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (0 != DeviceSddl) | ||||||
|  |         Result = IoCreateDeviceSecure(FspDriverObject, | ||||||
|  |             DeviceExtensionSize + ExtraSize, DeviceName, DeviceType, | ||||||
|  |             FILE_DEVICE_SECURE_OPEN, FALSE, | ||||||
|  |             DeviceSddl, DeviceClassGuid, | ||||||
|  |             &DeviceObject); | ||||||
|  |     else | ||||||
|  |         Result = IoCreateDevice(FspDriverObject, | ||||||
|  |             DeviceExtensionSize + ExtraSize, DeviceName, DeviceType, | ||||||
|  |             0, FALSE, | ||||||
|  |             &DeviceObject); | ||||||
|  |     if (!NT_SUCCESS(Result)) | ||||||
|  |         return Result; | ||||||
|  |  | ||||||
|  |     DeviceExtension = FspDeviceExtension(DeviceObject); | ||||||
|  |     KeInitializeSpinLock(&DeviceExtension->SpinLock); | ||||||
|  |     DeviceExtension->RefCount = 1; | ||||||
|  |     ExInitializeResourceLite(&DeviceExtension->Resource); | ||||||
|  |     DeviceExtension->Kind = Kind; | ||||||
|  |  | ||||||
|  |     switch (Kind) | ||||||
|  |     { | ||||||
|  |     case FspFsvolDeviceExtensionKind: | ||||||
|  |         Result = FspFsvolDeviceInit(DeviceObject); | ||||||
|  |         break; | ||||||
|  |     case FspFsvrtDeviceExtensionKind: | ||||||
|  |         Result = FspFsvrtDeviceInit(DeviceObject); | ||||||
|  |         break; | ||||||
|  |     case FspFsctlDeviceExtensionKind: | ||||||
|  |         Result = FspFsctlDeviceInit(DeviceObject); | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (!NT_SUCCESS(Result)) | ||||||
|  |     { | ||||||
|  |         ExDeleteResourceLite(&DeviceExtension->Resource); | ||||||
|  |         IoDeleteDevice(DeviceObject); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |         *PDeviceObject = DeviceObject; | ||||||
|  |  | ||||||
|  |     return Result; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | NTSTATUS FspDeviceCreate(UINT32 Kind, ULONG ExtraSize, | ||||||
|  |     DEVICE_TYPE DeviceType, | ||||||
|  |     PDEVICE_OBJECT *PDeviceObject) | ||||||
|  | { | ||||||
|  |     PAGED_CODE(); | ||||||
|  |  | ||||||
|  |     return FspDeviceCreateSecure(Kind, ExtraSize, 0, DeviceType, 0, 0, PDeviceObject); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject) | ||||||
|  | { | ||||||
|  |     PAGED_CODE(); | ||||||
|  |  | ||||||
|  |     FSP_DEVICE_EXTENSION *DeviceExtension = FspDeviceExtension(DeviceObject); | ||||||
|  |  | ||||||
|  |     switch (DeviceExtension->Kind) | ||||||
|  |     { | ||||||
|  |     case FspFsvolDeviceExtensionKind: | ||||||
|  |         FspFsvolDeviceFini(DeviceObject); | ||||||
|  |         break; | ||||||
|  |     case FspFsvrtDeviceExtensionKind: | ||||||
|  |         FspFsvrtDeviceFini(DeviceObject); | ||||||
|  |         break; | ||||||
|  |     case FspFsctlDeviceExtensionKind: | ||||||
|  |         FspFsctlDeviceFini(DeviceObject); | ||||||
|  |         break; | ||||||
|  |     default: | ||||||
|  |         ASSERT(0); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ExDeleteResourceLite(&DeviceExtension->Resource); | ||||||
|  |     IoDeleteDevice(DeviceObject); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static NTSTATUS FspFsctlDeviceInit(PDEVICE_OBJECT DeviceObject) | ||||||
|  | { | ||||||
|  |     PAGED_CODE(); | ||||||
|  |  | ||||||
|  |     return STATUS_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static VOID FspFsctlDeviceFini(PDEVICE_OBJECT DeviceObject) | ||||||
|  | { | ||||||
|  |     PAGED_CODE(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static NTSTATUS FspFsvrtDeviceInit(PDEVICE_OBJECT DeviceObject) | ||||||
|  | { | ||||||
|  |     PAGED_CODE(); | ||||||
|  |  | ||||||
|  |     FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(DeviceObject); | ||||||
|  |  | ||||||
|  |     FspIoqInitialize(&FsvrtDeviceExtension->Ioq); | ||||||
|  |  | ||||||
|  |     FsvrtDeviceExtension->SwapVpb = ExAllocatePoolWithTag(NonPagedPool, | ||||||
|  |         sizeof *FsvrtDeviceExtension->SwapVpb, FSP_TAG); | ||||||
|  |     if (0 == FsvrtDeviceExtension->SwapVpb) | ||||||
|  |         return STATUS_INSUFFICIENT_RESOURCES; | ||||||
|  |     RtlZeroMemory(FsvrtDeviceExtension->SwapVpb, sizeof *FsvrtDeviceExtension->SwapVpb); | ||||||
|  |  | ||||||
|  |     return STATUS_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static VOID FspFsvrtDeviceFini(PDEVICE_OBJECT DeviceObject) | ||||||
|  | { | ||||||
|  |     PAGED_CODE(); | ||||||
|  |  | ||||||
|  |     FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(DeviceObject); | ||||||
|  |  | ||||||
|  |     if (0 != FsvrtDeviceExtension->SwapVpb) | ||||||
|  |         ExFreePoolWithTag(FsvrtDeviceExtension->SwapVpb, FSP_TAG); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject) | ||||||
|  | { | ||||||
|  |     PAGED_CODE(); | ||||||
|  |  | ||||||
|  |     return STATUS_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject) | ||||||
|  | { | ||||||
|  |     PAGED_CODE(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | BOOLEAN FspDeviceRetain(PDEVICE_OBJECT DeviceObject) | ||||||
|  | { | ||||||
|  |     // !PAGED_CODE(); | ||||||
|  |  | ||||||
|  |     BOOLEAN Result; | ||||||
|  |     FSP_DEVICE_EXTENSION *DeviceExtension; | ||||||
|  |     KIRQL Irql; | ||||||
|  |  | ||||||
|  |     DeviceExtension = FspDeviceExtension(DeviceObject); | ||||||
|  |     KeAcquireSpinLock(&DeviceExtension->SpinLock, &Irql); | ||||||
|  |     Result = 0 != DeviceExtension->RefCount; | ||||||
|  |     if (!Result) | ||||||
|  |         DeviceExtension->RefCount++; | ||||||
|  |     KeReleaseSpinLock(&DeviceExtension->SpinLock, Irql); | ||||||
|  |  | ||||||
|  |     return Result; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | VOID FspDeviceRelease(PDEVICE_OBJECT DeviceObject) | ||||||
|  | { | ||||||
|  |     // !PAGED_CODE(); | ||||||
|  |  | ||||||
|  |     BOOLEAN Result; | ||||||
|  |     FSP_DEVICE_EXTENSION *DeviceExtension; | ||||||
|  |     KIRQL Irql; | ||||||
|  |  | ||||||
|  |     DeviceExtension = FspDeviceExtension(DeviceObject); | ||||||
|  |     KeAcquireSpinLock(&DeviceExtension->SpinLock, &Irql); | ||||||
|  |     if (0 != DeviceExtension->RefCount) | ||||||
|  |         DeviceExtension->RefCount--; | ||||||
|  |     Result = 0 != DeviceExtension->RefCount; | ||||||
|  |     KeReleaseSpinLock(&DeviceExtension->SpinLock, Irql); | ||||||
|  |  | ||||||
|  |     if (!Result) | ||||||
|  |         FspDeviceDelete(DeviceObject); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | NTSTATUS FspDeviceCopyList( | ||||||
|  |     PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount) | ||||||
| { | { | ||||||
|     PAGED_CODE(); |     PAGED_CODE(); | ||||||
|  |  | ||||||
|     PDEVICE_OBJECT *DeviceObjects = 0; |     PDEVICE_OBJECT *DeviceObjects = 0; | ||||||
|     ULONG DeviceObjectCount = 0; |     ULONG DeviceObjectCount = 0; | ||||||
|  |  | ||||||
|     while (STATUS_BUFFER_TOO_SMALL == IoEnumerateDeviceObjectList(DriverObject, |     while (STATUS_BUFFER_TOO_SMALL == IoEnumerateDeviceObjectList(FspDriverObject, | ||||||
|         DeviceObjects, DeviceObjectCount, &DeviceObjectCount)) |         DeviceObjects, DeviceObjectCount, &DeviceObjectCount)) | ||||||
|     { |     { | ||||||
|         if (0 != DeviceObjects) |         if (0 != DeviceObjects) | ||||||
| @@ -68,8 +277,7 @@ VOID FspDeviceDeleteList( | |||||||
|     ExFreePoolWithTag(DeviceObjects, FSP_TAG); |     ExFreePoolWithTag(DeviceObjects, FSP_TAG); | ||||||
| } | } | ||||||
|  |  | ||||||
| NTSTATUS FspDeviceOwned( | NTSTATUS FspDeviceOwned(PDEVICE_OBJECT DeviceObject) | ||||||
|     PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT DeviceObject) |  | ||||||
| { | { | ||||||
|     PAGED_CODE(); |     PAGED_CODE(); | ||||||
|  |  | ||||||
| @@ -77,7 +285,7 @@ NTSTATUS FspDeviceOwned( | |||||||
|     PDEVICE_OBJECT *DeviceObjects = 0; |     PDEVICE_OBJECT *DeviceObjects = 0; | ||||||
|     ULONG DeviceObjectCount = 0; |     ULONG DeviceObjectCount = 0; | ||||||
|  |  | ||||||
|     Result = FspDeviceCreateList(DriverObject, &DeviceObjects, &DeviceObjectCount); |     Result = FspDeviceCopyList(&DeviceObjects, &DeviceObjectCount); | ||||||
|     if (!NT_SUCCESS(Result)) |     if (!NT_SUCCESS(Result)) | ||||||
|         return Result; |         return Result; | ||||||
|  |  | ||||||
| @@ -93,62 +301,7 @@ NTSTATUS FspDeviceOwned( | |||||||
|     return Result; |     return Result; | ||||||
| } | } | ||||||
|  |  | ||||||
| VOID FspDeviceInitExtension(PDEVICE_OBJECT DeviceObject, UINT8 Kind) | VOID FspDeviceDeleteAll(VOID) | ||||||
| { |  | ||||||
|     PAGED_CODE(); |  | ||||||
|  |  | ||||||
|     FSP_DEVICE_EXTENSION *DeviceExtension = FspDeviceExtension(DeviceObject); |  | ||||||
|  |  | ||||||
|     DeviceExtension->Kind = Kind; |  | ||||||
|     ExInitializeResourceLite(&DeviceExtension->Resource); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static VOID FspFsctlDeviceDeleteObject(PDEVICE_OBJECT DeviceObject) |  | ||||||
| { |  | ||||||
|     PAGED_CODE(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static VOID FspFsvrtDeviceDeleteObject(PDEVICE_OBJECT DeviceObject) |  | ||||||
| { |  | ||||||
|     PAGED_CODE(); |  | ||||||
|  |  | ||||||
|     FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(DeviceObject); |  | ||||||
|  |  | ||||||
|     if (0 != FsvrtDeviceExtension->SwapVpb) |  | ||||||
|         ExFreePoolWithTag(FsvrtDeviceExtension->SwapVpb, FSP_TAG); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static VOID FspFsvolDeviceDeleteObject(PDEVICE_OBJECT DeviceObject) |  | ||||||
| { |  | ||||||
|     PAGED_CODE(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| VOID FspDeviceDeleteObject(PDEVICE_OBJECT DeviceObject) |  | ||||||
| { |  | ||||||
|     PAGED_CODE(); |  | ||||||
|  |  | ||||||
|     switch (FspDeviceExtension(DeviceObject)->Kind) |  | ||||||
|     { |  | ||||||
|     case FspFsvolDeviceExtensionKind: |  | ||||||
|         FspFsvolDeviceDeleteObject(DeviceObject); |  | ||||||
|         break; |  | ||||||
|     case FspFsvrtDeviceExtensionKind: |  | ||||||
|         FspFsvrtDeviceDeleteObject(DeviceObject); |  | ||||||
|         break; |  | ||||||
|     case FspFsctlDeviceExtensionKind: |  | ||||||
|         FspFsctlDeviceDeleteObject(DeviceObject); |  | ||||||
|         break; |  | ||||||
|     default: |  | ||||||
|         ASSERT(0); |  | ||||||
|         break; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     ExDeleteResourceLite(&FspDeviceExtension(DeviceObject)->Resource); |  | ||||||
|  |  | ||||||
|     IoDeleteDevice(DeviceObject); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| VOID FspDeviceDeleteObjects(PDRIVER_OBJECT DriverObject) |  | ||||||
| { | { | ||||||
|     PAGED_CODE(); |     PAGED_CODE(); | ||||||
|  |  | ||||||
| @@ -156,12 +309,12 @@ VOID FspDeviceDeleteObjects(PDRIVER_OBJECT DriverObject) | |||||||
|     PDEVICE_OBJECT *DeviceObjects = 0; |     PDEVICE_OBJECT *DeviceObjects = 0; | ||||||
|     ULONG DeviceObjectCount = 0; |     ULONG DeviceObjectCount = 0; | ||||||
|  |  | ||||||
|     Result = FspDeviceCreateList(DriverObject, &DeviceObjects, &DeviceObjectCount); |     Result = FspDeviceCopyList(&DeviceObjects, &DeviceObjectCount); | ||||||
|     if (!NT_SUCCESS(Result)) |     if (!NT_SUCCESS(Result)) | ||||||
|         return; |         return; | ||||||
|  |  | ||||||
|     for (ULONG i = 0; DeviceObjectCount > i; i++) |     for (ULONG i = 0; DeviceObjectCount > i; i++) | ||||||
|         FspDeviceDeleteObject(DeviceObjects[i]); |         FspDeviceDelete(DeviceObjects[i]); | ||||||
|  |  | ||||||
|     FspDeviceDeleteList(DeviceObjects, DeviceObjectCount); |     FspDeviceDeleteList(DeviceObjects, DeviceObjectCount); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -19,28 +19,26 @@ NTSTATUS DriverEntry( | |||||||
| { | { | ||||||
|     FSP_ENTER(); |     FSP_ENTER(); | ||||||
|  |  | ||||||
|  |     FspDriverObject = DriverObject; | ||||||
|  |  | ||||||
|     /* create the file system control device objects */ |     /* create the file system control device objects */ | ||||||
|     UNICODE_STRING DeviceSddl; |     UNICODE_STRING DeviceSddl; | ||||||
|     UNICODE_STRING DeviceName; |     UNICODE_STRING DeviceName; | ||||||
|     RtlInitUnicodeString(&DeviceSddl, L"" FSP_FSCTL_DEVICE_SDDL); |     RtlInitUnicodeString(&DeviceSddl, L"" FSP_FSCTL_DEVICE_SDDL); | ||||||
|     RtlInitUnicodeString(&DeviceName, L"\\Device\\" FSP_FSCTL_DISK_DEVICE_NAME); |     RtlInitUnicodeString(&DeviceName, L"\\Device\\" FSP_FSCTL_DISK_DEVICE_NAME); | ||||||
|     Result = IoCreateDeviceSecure(DriverObject, |     Result = FspDeviceCreateSecure(FspFsctlDeviceExtensionKind, 0, | ||||||
|         sizeof(FSP_FSCTL_DEVICE_EXTENSION), &DeviceName, FILE_DEVICE_DISK_FILE_SYSTEM, |         &DeviceName, FILE_DEVICE_DISK_FILE_SYSTEM, | ||||||
|         FILE_DEVICE_SECURE_OPEN, FALSE, |  | ||||||
|         &DeviceSddl, &FspFsctlDeviceClassGuid, |         &DeviceSddl, &FspFsctlDeviceClassGuid, | ||||||
|         &FspFsctlDiskDeviceObject); |         &FspFsctlDiskDeviceObject); | ||||||
|     if (!NT_SUCCESS(Result)) |     if (!NT_SUCCESS(Result)) | ||||||
|         FSP_RETURN(); |         FSP_RETURN(); | ||||||
|     RtlInitUnicodeString(&DeviceName, L"\\Device\\" FSP_FSCTL_NET_DEVICE_NAME); |     RtlInitUnicodeString(&DeviceName, L"\\Device\\" FSP_FSCTL_NET_DEVICE_NAME); | ||||||
|     Result = IoCreateDeviceSecure(DriverObject, |     Result = FspDeviceCreateSecure(FspFsctlDeviceExtensionKind, 0, | ||||||
|         sizeof(FSP_FSCTL_DEVICE_EXTENSION), &DeviceName, FILE_DEVICE_NETWORK_FILE_SYSTEM, |         &DeviceName, FILE_DEVICE_NETWORK_FILE_SYSTEM, | ||||||
|         FILE_DEVICE_SECURE_OPEN, FALSE, |  | ||||||
|         &DeviceSddl, &FspFsctlDeviceClassGuid, |         &DeviceSddl, &FspFsctlDeviceClassGuid, | ||||||
|         &FspFsctlNetDeviceObject); |         &FspFsctlNetDeviceObject); | ||||||
|     if (!NT_SUCCESS(Result)) |     if (!NT_SUCCESS(Result)) | ||||||
|         FSP_RETURN(IoDeleteDevice(FspFsctlDiskDeviceObject)); |         FSP_RETURN(FspDeviceDelete(FspFsctlDiskDeviceObject)); | ||||||
|     FspDeviceInitExtension(FspFsctlDiskDeviceObject, FspFsctlDeviceExtensionKind); |  | ||||||
|     FspDeviceInitExtension(FspFsctlNetDeviceObject, FspFsctlDeviceExtensionKind); |  | ||||||
|  |  | ||||||
|     /* setup the driver object */ |     /* setup the driver object */ | ||||||
|     DriverObject->DriverUnload = FspUnload; |     DriverObject->DriverUnload = FspUnload; | ||||||
| @@ -134,12 +132,15 @@ VOID FspUnload( | |||||||
|  |  | ||||||
|     FspFsctlDiskDeviceObject = 0; |     FspFsctlDiskDeviceObject = 0; | ||||||
|     FspFsctlNetDeviceObject = 0; |     FspFsctlNetDeviceObject = 0; | ||||||
|     FspDeviceDeleteObjects(DriverObject); |     FspDeviceDeleteAll(); | ||||||
|  |  | ||||||
|  |     FspDriverObject = 0; | ||||||
|  |  | ||||||
| #pragma prefast(suppress:28175, "We are in DriverUnload: ok to access DriverName") | #pragma prefast(suppress:28175, "We are in DriverUnload: ok to access DriverName") | ||||||
|     FSP_LEAVE_VOID("DriverName=\"%wZ\"", |     FSP_LEAVE_VOID("DriverName=\"%wZ\"", | ||||||
|         &DriverObject->DriverName); |         &DriverObject->DriverName); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | PDRIVER_OBJECT FspDriverObject; | ||||||
| PDEVICE_OBJECT FspFsctlDiskDeviceObject; | PDEVICE_OBJECT FspFsctlDiskDeviceObject; | ||||||
| PDEVICE_OBJECT FspFsctlNetDeviceObject; | PDEVICE_OBJECT FspFsctlNetDeviceObject; | ||||||
|   | |||||||
| @@ -80,13 +80,21 @@ | |||||||
|     FSP_LEAVE_(FSP_DEBUGLOG_(fmt, " = %s", __VA_ARGS__, NtStatusSym(Result))); return Result |     FSP_LEAVE_(FSP_DEBUGLOG_(fmt, " = %s", __VA_ARGS__, NtStatusSym(Result))); return Result | ||||||
| #define FSP_ENTER_MJ(...)               \ | #define FSP_ENTER_MJ(...)               \ | ||||||
|     NTSTATUS Result = STATUS_SUCCESS;   \ |     NTSTATUS Result = STATUS_SUCCESS;   \ | ||||||
|     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); (VOID)IrpSp;\ |     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);\ | ||||||
|     FSP_ENTER_(__VA_ARGS__) |     FSP_ENTER_(__VA_ARGS__);            \ | ||||||
|  |     do                                  \ | ||||||
|  |     {                                   \ | ||||||
|  |         if (!FspDeviceRetain(IrpSp->DeviceObject))\ | ||||||
|  |         {                               \ | ||||||
|  |             Result = STATUS_CANCELLED;  \ | ||||||
|  |             goto fsp_leave_label;       \ | ||||||
|  |         }                               \ | ||||||
|  |     } while (0,0) | ||||||
| #define FSP_LEAVE_MJ(fmt, ...)          \ | #define FSP_LEAVE_MJ(fmt, ...)          \ | ||||||
|     FSP_LEAVE_(                         \ |     FSP_LEAVE_(                         \ | ||||||
|         FSP_DEBUGLOG_("%p, %c%c, %s%s, " fmt, " = %s[%lld]",\ |         FSP_DEBUGLOG_("%p, %s%c, %s%s, " fmt, " = %s[%lld]",\ | ||||||
|             Irp,                        \ |             Irp,                        \ | ||||||
|             FspDeviceExtension(IrpSp->DeviceObject)->Kind,\ |             (const char *)&FspDeviceExtension(IrpSp->DeviceObject)->Kind,\ | ||||||
|             Irp->RequestorMode == KernelMode ? 'K' : 'U',\ |             Irp->RequestorMode == KernelMode ? 'K' : 'U',\ | ||||||
|             IrpMajorFunctionSym(IrpSp->MajorFunction),\ |             IrpMajorFunctionSym(IrpSp->MajorFunction),\ | ||||||
|             IrpMinorFunctionSym(IrpSp->MajorFunction, IrpSp->MajorFunction),\ |             IrpMinorFunctionSym(IrpSp->MajorFunction, IrpSp->MajorFunction),\ | ||||||
| @@ -121,9 +129,9 @@ | |||||||
|     FSP_ENTER_NOCRIT_(__VA_ARGS__) |     FSP_ENTER_NOCRIT_(__VA_ARGS__) | ||||||
| #define FSP_LEAVE_IOC(fmt, ...)         \ | #define FSP_LEAVE_IOC(fmt, ...)         \ | ||||||
|     FSP_LEAVE_NOCRIT_(                  \ |     FSP_LEAVE_NOCRIT_(                  \ | ||||||
|         FSP_DEBUGLOG_NOCRIT_("%p, %c%c, %s%s, " fmt, " = %s[%lld]",\ |         FSP_DEBUGLOG_NOCRIT_("%p, %s%c, %s%s, " fmt, " = %s[%lld]",\ | ||||||
|             Irp,                        \ |             Irp,                        \ | ||||||
|             FspDeviceExtension(IrpSp->DeviceObject)->Kind,\ |             (const char *)&FspDeviceExtension(IrpSp->DeviceObject)->Kind,\ | ||||||
|             Irp->RequestorMode == KernelMode ? 'K' : 'U',\ |             Irp->RequestorMode == KernelMode ? 'K' : 'U',\ | ||||||
|             IrpMajorFunctionSym(IrpSp->MajorFunction),\ |             IrpMajorFunctionSym(IrpSp->MajorFunction),\ | ||||||
|             IrpMinorFunctionSym(IrpSp->MajorFunction, IrpSp->MajorFunction),\ |             IrpMinorFunctionSym(IrpSp->MajorFunction, IrpSp->MajorFunction),\ | ||||||
| @@ -235,17 +243,19 @@ PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, ULONG millis); | |||||||
| BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp); | BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp); | ||||||
| PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint); | PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint); | ||||||
|  |  | ||||||
| /* device extensions */ | /* device management */ | ||||||
| enum | enum | ||||||
| { | { | ||||||
|     FspFsctlDeviceExtensionKind = 'C',  /* file system control device (e.g. \Device\WinFsp.Disk) */ |     FspFsctlDeviceExtensionKind = '\0ltC',  /* file system control device (e.g. \Device\WinFsp.Disk) */ | ||||||
|     FspFsvrtDeviceExtensionKind = 'V',  /* virtual volume device (e.g. \Device\Volume{GUID}) */ |     FspFsvrtDeviceExtensionKind = '\0trV',  /* virtual volume device (e.g. \Device\Volume{GUID}) */ | ||||||
|     FspFsvolDeviceExtensionKind = 'F',  /* file system volume device (unnamed) */ |     FspFsvolDeviceExtensionKind = '\0loV',  /* file system volume device (unnamed) */ | ||||||
| }; | }; | ||||||
| typedef struct | typedef struct | ||||||
| { | { | ||||||
|     UINT8 Kind; |     KSPIN_LOCK SpinLock; | ||||||
|  |     LONG RefCount; | ||||||
|     ERESOURCE Resource; |     ERESOURCE Resource; | ||||||
|  |     UINT32 Kind; | ||||||
| } FSP_DEVICE_EXTENSION; | } FSP_DEVICE_EXTENSION; | ||||||
| typedef struct | typedef struct | ||||||
| { | { | ||||||
| @@ -255,6 +265,7 @@ typedef struct | |||||||
| { | { | ||||||
|     FSP_DEVICE_EXTENSION Base; |     FSP_DEVICE_EXTENSION Base; | ||||||
|     PDEVICE_OBJECT FsctlDeviceObject; |     PDEVICE_OBJECT FsctlDeviceObject; | ||||||
|  |     PDEVICE_OBJECT FsvolDeviceObject; | ||||||
|     FSP_FSCTL_VOLUME_PARAMS VolumeParams; |     FSP_FSCTL_VOLUME_PARAMS VolumeParams; | ||||||
|     FSP_IOQ Ioq; |     FSP_IOQ Ioq; | ||||||
|     PVPB SwapVpb; |     PVPB SwapVpb; | ||||||
| @@ -288,15 +299,22 @@ FSP_FSVOL_DEVICE_EXTENSION *FspFsvolDeviceExtension(PDEVICE_OBJECT DeviceObject) | |||||||
|     ASSERT(FspFsvolDeviceExtensionKind == ((FSP_DEVICE_EXTENSION *)DeviceObject->DeviceExtension)->Kind); |     ASSERT(FspFsvolDeviceExtensionKind == ((FSP_DEVICE_EXTENSION *)DeviceObject->DeviceExtension)->Kind); | ||||||
|     return DeviceObject->DeviceExtension; |     return DeviceObject->DeviceExtension; | ||||||
| } | } | ||||||
| NTSTATUS FspDeviceCreateList( | NTSTATUS FspDeviceCreateSecure(UINT32 Kind, ULONG ExtraSize, | ||||||
|     PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount); |     PUNICODE_STRING DeviceName, DEVICE_TYPE DeviceType, | ||||||
|  |     PUNICODE_STRING DeviceSddl, LPCGUID DeviceClassGuid, | ||||||
|  |     PDEVICE_OBJECT *PDeviceObject); | ||||||
|  | NTSTATUS FspDeviceCreate(UINT32 Kind, ULONG ExtraSize, | ||||||
|  |     DEVICE_TYPE DeviceType, | ||||||
|  |     PDEVICE_OBJECT *PDeviceObject); | ||||||
|  | VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject); | ||||||
|  | BOOLEAN FspDeviceRetain(PDEVICE_OBJECT DeviceObject); | ||||||
|  | VOID FspDeviceRelease(PDEVICE_OBJECT DeviceObject); | ||||||
|  | NTSTATUS FspDeviceCopyList( | ||||||
|  |     PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount); | ||||||
| VOID FspDeviceDeleteList( | VOID FspDeviceDeleteList( | ||||||
|     PDEVICE_OBJECT *DeviceObjects, ULONG DeviceObjectCount); |     PDEVICE_OBJECT *DeviceObjects, ULONG DeviceObjectCount); | ||||||
| NTSTATUS FspDeviceOwned( | NTSTATUS FspDeviceOwned(PDEVICE_OBJECT DeviceObject); | ||||||
|     PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT DeviceObject); | VOID FspDeviceDeleteAll(VOID); | ||||||
| VOID FspDeviceInitExtension(PDEVICE_OBJECT DeviceObject, UINT8 Kind); |  | ||||||
| VOID FspDeviceDeleteObject(PDEVICE_OBJECT DeviceObject); |  | ||||||
| VOID FspDeviceDeleteObjects(PDRIVER_OBJECT DriverObject); |  | ||||||
|  |  | ||||||
| /* I/O processing */ | /* I/O processing */ | ||||||
| VOID FspIopCompleteRequest(PIRP Irp, NTSTATUS Result); | VOID FspIopCompleteRequest(PIRP Irp, NTSTATUS Result); | ||||||
| @@ -317,6 +335,7 @@ const char *IoctlCodeSym(ULONG ControlCode); | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| /* extern */ | /* extern */ | ||||||
|  | extern PDRIVER_OBJECT FspDriverObject; | ||||||
| extern PDEVICE_OBJECT FspFsctlDiskDeviceObject; | extern PDEVICE_OBJECT FspFsctlDiskDeviceObject; | ||||||
| extern PDEVICE_OBJECT FspFsctlNetDeviceObject; | extern PDEVICE_OBJECT FspFsctlNetDeviceObject; | ||||||
| extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[]; | extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[]; | ||||||
|   | |||||||
| @@ -56,32 +56,20 @@ static NTSTATUS FspFsctlCreateVolume( | |||||||
|  |  | ||||||
|     NTSTATUS Result; |     NTSTATUS Result; | ||||||
|     PVOID SecurityDescriptorBuf = 0; |     PVOID SecurityDescriptorBuf = 0; | ||||||
|     PVPB SwapVpb = 0; |     FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension; | ||||||
|  |  | ||||||
|     /* create volume guid */ |     /* create volume guid */ | ||||||
|     GUID Guid; |     GUID Guid; | ||||||
|     Result = FspCreateGuid(&Guid); |     Result = FspCreateGuid(&Guid); | ||||||
|     if (!NT_SUCCESS(Result)) |     if (!NT_SUCCESS(Result)) | ||||||
|         goto exit; |         return Result; | ||||||
|  |  | ||||||
|     /* copy the security descriptor from the system buffer to a temporary one */ |     /* copy the security descriptor from the system buffer to a temporary one */ | ||||||
|     SecurityDescriptorBuf = ExAllocatePoolWithTag(PagedPool, SecurityDescriptorSize, FSP_TAG); |     SecurityDescriptorBuf = ExAllocatePoolWithTag(PagedPool, SecurityDescriptorSize, FSP_TAG); | ||||||
|     if (0 == SecurityDescriptorBuf) |     if (0 == SecurityDescriptorBuf) | ||||||
|     { |         return STATUS_INSUFFICIENT_RESOURCES; | ||||||
|         Result = STATUS_INSUFFICIENT_RESOURCES; |  | ||||||
|         goto exit; |  | ||||||
|     } |  | ||||||
|     RtlCopyMemory(SecurityDescriptorBuf, SecurityDescriptor, SecurityDescriptorSize); |     RtlCopyMemory(SecurityDescriptorBuf, SecurityDescriptor, SecurityDescriptorSize); | ||||||
|  |  | ||||||
|     /* preallocate swap VPB */ |  | ||||||
|     SwapVpb = ExAllocatePoolWithTag(NonPagedPool, sizeof *SwapVpb, FSP_TAG); |  | ||||||
|     if (0 == SwapVpb) |  | ||||||
|     { |  | ||||||
|         Result = STATUS_INSUFFICIENT_RESOURCES; |  | ||||||
|         goto exit; |  | ||||||
|     } |  | ||||||
|     RtlZeroMemory(SwapVpb, sizeof *SwapVpb); |  | ||||||
|  |  | ||||||
|     /* create the virtual volume device */ |     /* create the virtual volume device */ | ||||||
|     PDEVICE_OBJECT FsvrtDeviceObject; |     PDEVICE_OBJECT FsvrtDeviceObject; | ||||||
|     UNICODE_STRING DeviceSddl; |     UNICODE_STRING DeviceSddl; | ||||||
| @@ -94,33 +82,24 @@ static NTSTATUS FspFsctlCreateVolume( | |||||||
|         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]); | ||||||
|     ASSERT(NT_SUCCESS(Result)); |     ASSERT(NT_SUCCESS(Result)); | ||||||
|     Result = IoCreateDeviceSecure(DeviceObject->DriverObject, |     Result = FspDeviceCreateSecure(FspFsvrtDeviceExtensionKind, SecurityDescriptorSize, | ||||||
|         sizeof(FSP_FSVRT_DEVICE_EXTENSION) + SecurityDescriptorSize, &DeviceName, FILE_DEVICE_VIRTUAL_DISK, |         &DeviceName, FILE_DEVICE_VIRTUAL_DISK, | ||||||
|         FILE_DEVICE_SECURE_OPEN, FALSE, |         &DeviceSddl, &FspFsvrtDeviceClassGuid, | ||||||
|         &DeviceSddl, 0, |  | ||||||
|         &FsvrtDeviceObject); |         &FsvrtDeviceObject); | ||||||
|     if (NT_SUCCESS(Result)) |     if (NT_SUCCESS(Result)) | ||||||
|     { |     { | ||||||
|         FspDeviceInitExtension(FsvrtDeviceObject, FspFsvrtDeviceExtensionKind); |         FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject); | ||||||
|         FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject); |  | ||||||
|         FsvrtDeviceExtension->FsctlDeviceObject = DeviceObject; |         FsvrtDeviceExtension->FsctlDeviceObject = DeviceObject; | ||||||
|         FsvrtDeviceExtension->VolumeParams = *Params; |         FsvrtDeviceExtension->VolumeParams = *Params; | ||||||
|         FspIoqInitialize(&FsvrtDeviceExtension->Ioq); |         RtlCopyMemory(FsvrtDeviceExtension->SecurityDescriptorBuf, | ||||||
|         FsvrtDeviceExtension->SwapVpb = SwapVpb; |  | ||||||
|         RtlCopyMemory(FspFsvrtDeviceExtension(FsvrtDeviceObject)->SecurityDescriptorBuf, |  | ||||||
|             SecurityDescriptorBuf, SecurityDescriptorSize); |             SecurityDescriptorBuf, SecurityDescriptorSize); | ||||||
|         ClearFlag(FsvrtDeviceObject->Flags, DO_DEVICE_INITIALIZING); |         ClearFlag(FsvrtDeviceObject->Flags, DO_DEVICE_INITIALIZING); | ||||||
|         Irp->IoStatus.Information = DeviceName.Length + 1; |         Irp->IoStatus.Information = DeviceName.Length + 1; | ||||||
|         SwapVpb = 0; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
| exit: |  | ||||||
|     /* free the temporary security descriptor */ |     /* free the temporary security descriptor */ | ||||||
|     if (0 != SecurityDescriptorBuf) |     if (0 != SecurityDescriptorBuf) | ||||||
|         ExFreePoolWithTag(SecurityDescriptorBuf, FSP_TAG); |         ExFreePoolWithTag(SecurityDescriptorBuf, FSP_TAG); | ||||||
|     /* free swap VPB if we failed */ |  | ||||||
|     if (0 != SwapVpb) |  | ||||||
|         ExFreePoolWithTag(SwapVpb, FSP_TAG); |  | ||||||
|  |  | ||||||
|     return Result; |     return Result; | ||||||
| } | } | ||||||
| @@ -132,12 +111,14 @@ static NTSTATUS FspFsctlMountVolume( | |||||||
|  |  | ||||||
|     NTSTATUS Result; |     NTSTATUS Result; | ||||||
|     FSP_FSCTL_DEVICE_EXTENSION *FsctlDeviceExtension = FspFsctlDeviceExtension(DeviceObject); |     FSP_FSCTL_DEVICE_EXTENSION *FsctlDeviceExtension = FspFsctlDeviceExtension(DeviceObject); | ||||||
|  |     FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension; | ||||||
|  |     FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension; | ||||||
|     PVPB Vpb = IrpSp->Parameters.MountVolume.Vpb; |     PVPB Vpb = IrpSp->Parameters.MountVolume.Vpb; | ||||||
|     PDEVICE_OBJECT FsvrtDeviceObject = Vpb->RealDevice; |     PDEVICE_OBJECT FsvrtDeviceObject = Vpb->RealDevice; | ||||||
|     PDEVICE_OBJECT FsvolDeviceObject; |     PDEVICE_OBJECT FsvolDeviceObject; | ||||||
|  |  | ||||||
|     /* check the passed in volume object; it must be one of our own */ |     /* check the passed in volume object; it must be one of our own */ | ||||||
|     Result = FspDeviceOwned(DeviceObject->DriverObject, FsvrtDeviceObject); |     Result = FspDeviceOwned(FsvrtDeviceObject); | ||||||
|     if (!NT_SUCCESS(Result)) |     if (!NT_SUCCESS(Result)) | ||||||
|     { |     { | ||||||
|         if (STATUS_NO_SUCH_DEVICE == Result) |         if (STATUS_NO_SUCH_DEVICE == Result) | ||||||
| @@ -151,18 +132,17 @@ static NTSTATUS FspFsctlMountVolume( | |||||||
|     ExAcquireResourceExclusiveLite(&FsctlDeviceExtension->Base.Resource, TRUE); |     ExAcquireResourceExclusiveLite(&FsctlDeviceExtension->Base.Resource, TRUE); | ||||||
|  |  | ||||||
|     /* create the file system device object */ |     /* create the file system device object */ | ||||||
|     Result = IoCreateDevice(DeviceObject->DriverObject, |     Result = FspDeviceCreate(FspFsvolDeviceExtensionKind, 0, | ||||||
|         sizeof(FSP_FSVOL_DEVICE_EXTENSION), 0, DeviceObject->DeviceType, |         DeviceObject->DeviceType, | ||||||
|         0, FALSE, |  | ||||||
|         &FsvolDeviceObject); |         &FsvolDeviceObject); | ||||||
|     if (NT_SUCCESS(Result)) |     if (NT_SUCCESS(Result)) | ||||||
|     { |     { | ||||||
|  |         FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject); | ||||||
|  |         FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); | ||||||
| #pragma prefast(suppress:28175, "We are a filesystem: ok to access SectorSize") | #pragma prefast(suppress:28175, "We are a filesystem: ok to access SectorSize") | ||||||
|         FsvolDeviceObject->SectorSize = |         FsvolDeviceObject->SectorSize = FsvrtDeviceExtension->VolumeParams.SectorSize; | ||||||
|             FspFsvrtDeviceExtension(FsvrtDeviceObject)->VolumeParams.SectorSize; |  | ||||||
|         FspDeviceInitExtension(FsvolDeviceObject, FspFsvolDeviceExtensionKind); |  | ||||||
|         FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); |  | ||||||
|         FsvolDeviceExtension->FsvrtDeviceObject = FsvrtDeviceObject; |         FsvolDeviceExtension->FsvrtDeviceObject = FsvrtDeviceObject; | ||||||
|  |         FsvrtDeviceExtension->FsvolDeviceObject = FsvolDeviceObject; | ||||||
|         ClearFlag(FsvolDeviceObject->Flags, DO_DEVICE_INITIALIZING); |         ClearFlag(FsvolDeviceObject->Flags, DO_DEVICE_INITIALIZING); | ||||||
|         Vpb->DeviceObject = FsvolDeviceObject; |         Vpb->DeviceObject = FsvolDeviceObject; | ||||||
|         Irp->IoStatus.Information = 0; |         Irp->IoStatus.Information = 0; | ||||||
| @@ -183,6 +163,8 @@ static NTSTATUS FspFsvrtDeleteVolume( | |||||||
|         FspFsvrtDeviceExtension(DeviceObject); |         FspFsvrtDeviceExtension(DeviceObject); | ||||||
|     FSP_FSCTL_DEVICE_EXTENSION *FsctlDeviceExtension = |     FSP_FSCTL_DEVICE_EXTENSION *FsctlDeviceExtension = | ||||||
|         FspFsctlDeviceExtension(FsvrtDeviceExtension->FsctlDeviceObject); |         FspFsctlDeviceExtension(FsvrtDeviceExtension->FsctlDeviceObject); | ||||||
|  |     PVPB OldVpb; | ||||||
|  |     KIRQL Irql; | ||||||
|  |  | ||||||
|     /* access check */ |     /* access check */ | ||||||
|     Result = FspSecuritySubjectContextAccessCheck( |     Result = FspSecuritySubjectContextAccessCheck( | ||||||
| @@ -196,8 +178,8 @@ static NTSTATUS FspFsvrtDeleteVolume( | |||||||
|     FspIoqStop(&FsvrtDeviceExtension->Ioq); |     FspIoqStop(&FsvrtDeviceExtension->Ioq); | ||||||
|  |  | ||||||
|     /* swap the preallocated VPB */ |     /* swap the preallocated VPB */ | ||||||
|     PVPB OldVpb; | #pragma prefast(push) | ||||||
|     KIRQL Irql; | #pragma prefast(disable:28175, "We are a filesystem: ok to access Vpb") | ||||||
|     IoAcquireVpbSpinLock(&Irql); |     IoAcquireVpbSpinLock(&Irql); | ||||||
|     OldVpb = DeviceObject->Vpb; |     OldVpb = DeviceObject->Vpb; | ||||||
|     if (0 != OldVpb) |     if (0 != OldVpb) | ||||||
| @@ -211,21 +193,17 @@ static NTSTATUS FspFsvrtDeleteVolume( | |||||||
|         FsvrtDeviceExtension->SwapVpb = 0; |         FsvrtDeviceExtension->SwapVpb = 0; | ||||||
|     } |     } | ||||||
|     IoReleaseVpbSpinLock(Irql); |     IoReleaseVpbSpinLock(Irql); | ||||||
|  | #pragma prefast(pop) | ||||||
|  |  | ||||||
|     /* delete the file system device object */ |     /* release the file system device and virtual volume objects */ | ||||||
|     if (0 != OldVpb && 0 != OldVpb->DeviceObject && |     PDEVICE_OBJECT FsvolDeviceObject = FsvrtDeviceExtension->FsvolDeviceObject; | ||||||
|         FspDeviceOwned(DeviceObject->DriverObject, OldVpb->DeviceObject)) |     FsvrtDeviceExtension->FsvolDeviceObject = 0; | ||||||
|     { |     FspDeviceRelease(FsvolDeviceObject); | ||||||
|         ASSERT(FspFsvolDeviceExtensionKind == FspDeviceExtension(OldVpb->DeviceObject)->Kind); |     FspDeviceRelease(DeviceObject); | ||||||
|         FspDeviceDeleteObject(OldVpb->DeviceObject); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /* delete the virtual volume device */ |  | ||||||
|     FspDeviceDeleteObject(DeviceObject); |  | ||||||
|  |  | ||||||
|     ExReleaseResourceLite(&FsctlDeviceExtension->Base.Resource); |     ExReleaseResourceLite(&FsctlDeviceExtension->Base.Resource); | ||||||
|  |  | ||||||
|     return STATUS_INVALID_DEVICE_REQUEST; |     return STATUS_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
| static NTSTATUS FspFsvrtTransact( | static NTSTATUS FspFsvrtTransact( | ||||||
|   | |||||||
| @@ -24,10 +24,14 @@ VOID FspIopCompleteRequest(PIRP Irp, NTSTATUS Result) | |||||||
|         Irp->Tail.Overlay.DriverContext[0] = 0; |         Irp->Tail.Overlay.DriverContext[0] = 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     PDEVICE_OBJECT DeviceObject = IoGetCurrentIrpStackLocation(Irp)->DeviceObject; | ||||||
|  |  | ||||||
|     if (!NT_SUCCESS(Result)) |     if (!NT_SUCCESS(Result)) | ||||||
|         Irp->IoStatus.Information = 0; |         Irp->IoStatus.Information = 0; | ||||||
|     Irp->IoStatus.Status = Result; |     Irp->IoStatus.Status = Result; | ||||||
|     IoCompleteRequest(Irp, FSP_IO_INCREMENT); |     IoCompleteRequest(Irp, FSP_IO_INCREMENT); | ||||||
|  |  | ||||||
|  |     FspDeviceRelease(DeviceObject); | ||||||
| } | } | ||||||
|  |  | ||||||
| VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response) | VOID FspIopDispatchComplete(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user