sys: device extension reference count

This commit is contained in:
Bill Zissimopoulos 2015-11-30 00:35:28 -08:00
parent 7bd979a3fd
commit 7c3d69f63b
5 changed files with 314 additions and 159 deletions

View File

@ -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);
}

View File

@ -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;

View File

@ -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[];

View File

@ -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(

View File

@ -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)