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