mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 17:03:12 -05:00
sys: device extension reference count
This commit is contained in:
parent
7bd979a3fd
commit
7c3d69f63b
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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user