diff --git a/src/sys/device.c b/src/sys/device.c index f90a91fa..c56f97c9 100644 --- a/src/sys/device.c +++ b/src/sys/device.c @@ -22,6 +22,8 @@ static NTSTATUS FspFsvolDeviceInit(PDEVICE_OBJECT DeviceObject); static VOID FspFsvolDeviceFini(PDEVICE_OBJECT DeviceObject); BOOLEAN FspDeviceRetain(PDEVICE_OBJECT DeviceObject); VOID FspDeviceRelease(PDEVICE_OBJECT DeviceObject); +VOID FspFsctlDeviceVolumeCreated(PDEVICE_OBJECT DeviceObject); +VOID FspFsctlDeviceVolumeDeleted(PDEVICE_OBJECT DeviceObject); NTSTATUS FspDeviceCopyList( PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount); VOID FspDeviceDeleteList( @@ -38,6 +40,8 @@ VOID FspDeviceDeleteAll(VOID); #pragma alloc_text(PAGE, FspFsvrtDeviceFini) #pragma alloc_text(PAGE, FspFsvolDeviceInit) #pragma alloc_text(PAGE, FspFsvolDeviceFini) +#pragma alloc_text(PAGE, FspFsctlDeviceVolumeCreated) +#pragma alloc_text(PAGE, FspFsctlDeviceVolumeDeleted) #pragma alloc_text(PAGE, FspDeviceCopyList) #pragma alloc_text(PAGE, FspDeviceDeleteList) #pragma alloc_text(PAGE, FspDeviceDeleteAll) @@ -241,6 +245,30 @@ VOID FspDeviceRelease(PDEVICE_OBJECT DeviceObject) FspDeviceDelete(DeviceObject); } +VOID FspFsctlDeviceVolumeCreated(PDEVICE_OBJECT DeviceObject) +{ + PAGED_CODE(); + + ASSERT(FspFsctlDeviceExtensionKind == FspDeviceExtension(DeviceObject)->Kind); + ASSERT(ExIsResourceAcquiredExclusiveLite(&FspDeviceExtension(DeviceObject)->Resource)); + + ULONG FsvrtDeviceObjectCount = FspFsctlDeviceExtension(DeviceObject)->FsvrtDeviceObjectCount++; + if (0 == FsvrtDeviceObjectCount) + IoRegisterFileSystem(DeviceObject); +} + +VOID FspFsctlDeviceVolumeDeleted(PDEVICE_OBJECT DeviceObject) +{ + PAGED_CODE(); + + ASSERT(FspFsctlDeviceExtensionKind == FspDeviceExtension(DeviceObject)->Kind); + ASSERT(ExIsResourceAcquiredExclusiveLite(&FspDeviceExtension(DeviceObject)->Resource)); + + ULONG FsvrtDeviceObjectCount = --FspFsctlDeviceExtension(DeviceObject)->FsvrtDeviceObjectCount; + if (0 == FsvrtDeviceObjectCount) + IoUnregisterFileSystem(DeviceObject); +} + NTSTATUS FspDeviceCopyList( PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount) { @@ -250,7 +278,7 @@ NTSTATUS FspDeviceCopyList( ULONG DeviceObjectCount = 0; while (STATUS_BUFFER_TOO_SMALL == IoEnumerateDeviceObjectList(FspDriverObject, - DeviceObjects, DeviceObjectCount, &DeviceObjectCount)) + DeviceObjects, sizeof *DeviceObjects * DeviceObjectCount, &DeviceObjectCount)) { if (0 != DeviceObjects) ExFreePoolWithTag(DeviceObjects, FSP_TAG); diff --git a/src/sys/driver.c b/src/sys/driver.c index 965ee16d..ccaf13d6 100644 --- a/src/sys/driver.c +++ b/src/sys/driver.c @@ -116,10 +116,6 @@ NTSTATUS DriverEntry( #pragma prefast(suppress:28175, "We are a filesystem: ok to access FastIoDispatch") DriverObject->FastIoDispatch = &FspFastIoDispatch; - /* register our device objects as file systems */ - IoRegisterFileSystem(FspFsctlDiskDeviceObject); - IoRegisterFileSystem(FspFsctlNetDeviceObject); - #pragma prefast(suppress:28175, "We are in DriverEntry: ok to access DriverName") FSP_LEAVE("DriverName=\"%wZ\", RegistryPath=\"%wZ\"", &DriverObject->DriverName, RegistryPath); diff --git a/src/sys/driver.h b/src/sys/driver.h index d178899d..c563ab62 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -261,6 +261,7 @@ typedef struct typedef struct { FSP_DEVICE_EXTENSION Base; + ULONG FsvrtDeviceObjectCount; } FSP_FSCTL_DEVICE_EXTENSION; typedef struct { @@ -311,6 +312,8 @@ NTSTATUS FspDeviceCreate(UINT32 Kind, ULONG ExtraSize, VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject); BOOLEAN FspDeviceRetain(PDEVICE_OBJECT DeviceObject); VOID FspDeviceRelease(PDEVICE_OBJECT DeviceObject); +VOID FspFsctlDeviceVolumeCreated(PDEVICE_OBJECT DeviceObject); +VOID FspFsctlDeviceVolumeDeleted(PDEVICE_OBJECT DeviceObject); NTSTATUS FspDeviceCopyList( PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount); VOID FspDeviceDeleteList( diff --git a/src/sys/fsctl.c b/src/sys/fsctl.c index b9f61825..a430a931 100644 --- a/src/sys/fsctl.c +++ b/src/sys/fsctl.c @@ -133,7 +133,7 @@ static NTSTATUS FspFsctlCreateVolume( return STATUS_INSUFFICIENT_RESOURCES; RtlCopyMemory(SecurityDescriptorBuf, SecurityDescriptor, SecurityDescriptorSize); - /* create the virtual volume device */ + /* prepare the device name and SDDL */ PDEVICE_OBJECT FsvrtDeviceObject; UNICODE_STRING DeviceSddl; UNICODE_STRING DeviceName; @@ -145,21 +145,33 @@ 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 = FspDeviceCreateSecure(FspFsvrtDeviceExtensionKind, SecurityDescriptorSize, - &DeviceName, FILE_DEVICE_VIRTUAL_DISK, - &DeviceSddl, &FspFsvrtDeviceClassGuid, - &FsvrtDeviceObject); - if (NT_SUCCESS(Result)) + + /* create the virtual volume device */ + FSP_FSCTL_DEVICE_EXTENSION *FsctlDeviceExtension = FspFsctlDeviceExtension(DeviceObject); + ExAcquireResourceExclusiveLite(&FsctlDeviceExtension->Base.Resource, TRUE); + try { + Result = FspDeviceCreateSecure(FspFsvrtDeviceExtensionKind, SecurityDescriptorSize, + &DeviceName, FILE_DEVICE_VIRTUAL_DISK, + &DeviceSddl, &FspFsvrtDeviceClassGuid, + &FsvrtDeviceObject); + if (NT_SUCCESS(Result)) + { #pragma prefast(suppress:28175, "We are a filesystem: ok to access SectorSize") - FsvrtDeviceObject->SectorSize = Params.SectorSize; - FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject); - FsvrtDeviceExtension->FsctlDeviceObject = DeviceObject; - FsvrtDeviceExtension->VolumeParams = Params; - RtlCopyMemory(FsvrtDeviceExtension->SecurityDescriptorBuf, - SecurityDescriptorBuf, SecurityDescriptorSize); - ClearFlag(FsvrtDeviceObject->Flags, DO_DEVICE_INITIALIZING); - Irp->IoStatus.Information = DeviceName.Length + sizeof(WCHAR); + FsvrtDeviceObject->SectorSize = Params.SectorSize; + FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject); + FsvrtDeviceExtension->FsctlDeviceObject = DeviceObject; + FsvrtDeviceExtension->VolumeParams = Params; + RtlCopyMemory(FsvrtDeviceExtension->SecurityDescriptorBuf, + SecurityDescriptorBuf, SecurityDescriptorSize); + ClearFlag(FsvrtDeviceObject->Flags, DO_DEVICE_INITIALIZING); + Irp->IoStatus.Information = DeviceName.Length + sizeof(WCHAR); + FspFsctlDeviceVolumeCreated(DeviceObject); + } + } + finally + { + ExReleaseResourceLite(&FsctlDeviceExtension->Base.Resource); } /* free the temporary security descriptor */ @@ -292,12 +304,15 @@ static NTSTATUS FspFsvrtDeleteVolume( #pragma prefast(pop) /* release the file system device and virtual volume objects */ + PDEVICE_OBJECT FsctlDeviceObject = FsvrtDeviceExtension->FsctlDeviceObject; PDEVICE_OBJECT FsvolDeviceObject = FsvrtDeviceExtension->FsvolDeviceObject; FsvrtDeviceExtension->FsvolDeviceObject = 0; if (0 != FsvolDeviceObject) FspDeviceRelease(FsvolDeviceObject); FspDeviceRelease(DeviceObject); + FspFsctlDeviceVolumeDeleted(FsctlDeviceObject); + Result = STATUS_SUCCESS; exit:;