mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
sys: fsmup device
- This commit introduces the fsmup device, which is a major change in how network file systems are handled. Previously every network file system's fsvol device was directly registered with the MUP. Now there is a single fsmup device that is registered with the MUP; network file systems' fsvol devices register with fsmup instead. The fsmup device maintains a prefix table which it uses to demultiplex and forward requests to the appropriate fsvol device. - This device change was necessatitated to fix issue #87.
This commit is contained in:
parent
670a38d549
commit
a4629b8f8b
@ -173,6 +173,7 @@
|
|||||||
<ClCompile Include="..\..\src\sys\ioq.c" />
|
<ClCompile Include="..\..\src\sys\ioq.c" />
|
||||||
<ClCompile Include="..\..\src\sys\lockctl.c" />
|
<ClCompile Include="..\..\src\sys\lockctl.c" />
|
||||||
<ClCompile Include="..\..\src\sys\meta.c" />
|
<ClCompile Include="..\..\src\sys\meta.c" />
|
||||||
|
<ClCompile Include="..\..\src\sys\mup.c" />
|
||||||
<ClCompile Include="..\..\src\sys\name.c" />
|
<ClCompile Include="..\..\src\sys\name.c" />
|
||||||
<ClCompile Include="..\..\src\sys\psbuffer.c" />
|
<ClCompile Include="..\..\src\sys\psbuffer.c" />
|
||||||
<ClCompile Include="..\..\src\sys\read.c" />
|
<ClCompile Include="..\..\src\sys\read.c" />
|
||||||
|
@ -101,6 +101,9 @@
|
|||||||
<ClCompile Include="..\..\src\sys\psbuffer.c">
|
<ClCompile Include="..\..\src\sys\psbuffer.c">
|
||||||
<Filter>Source</Filter>
|
<Filter>Source</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\sys\mup.c">
|
||||||
|
<Filter>Source</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\src\sys\driver.h">
|
<ClInclude Include="..\..\src\sys\driver.h">
|
||||||
|
@ -34,6 +34,7 @@ extern "C" {
|
|||||||
#define FSP_FSCTL_DRIVER_NAME "WinFsp"
|
#define FSP_FSCTL_DRIVER_NAME "WinFsp"
|
||||||
#define FSP_FSCTL_DISK_DEVICE_NAME "WinFsp.Disk"
|
#define FSP_FSCTL_DISK_DEVICE_NAME "WinFsp.Disk"
|
||||||
#define FSP_FSCTL_NET_DEVICE_NAME "WinFsp.Net"
|
#define FSP_FSCTL_NET_DEVICE_NAME "WinFsp.Net"
|
||||||
|
#define FSP_FSCTL_MUP_DEVICE_NAME "WinFsp.Mup"
|
||||||
|
|
||||||
// {6F9D25FA-6DEE-4A9D-80F5-E98E14F35E54}
|
// {6F9D25FA-6DEE-4A9D-80F5-E98E14F35E54}
|
||||||
extern const __declspec(selectany) GUID FspFsctlDeviceClassGuid =
|
extern const __declspec(selectany) GUID FspFsctlDeviceClassGuid =
|
||||||
|
@ -164,6 +164,8 @@ static NTSTATUS FspFsvolCreateNoLock(
|
|||||||
#pragma prefast(disable:28175, "We are a filesystem: ok to access Vpb")
|
#pragma prefast(disable:28175, "We are a filesystem: ok to access Vpb")
|
||||||
FileObject->Vpb = FsvolDeviceExtension->FsvrtDeviceObject->Vpb;
|
FileObject->Vpb = FsvolDeviceExtension->FsvrtDeviceObject->Vpb;
|
||||||
|
|
||||||
|
FileObject->FsContext2 = FsvolDeviceObject;
|
||||||
|
|
||||||
Irp->IoStatus.Information = FILE_OPENED;
|
Irp->IoStatus.Information = FILE_OPENED;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -281,6 +281,8 @@ const char *DeviceExtensionKindSym(UINT32 Kind)
|
|||||||
{
|
{
|
||||||
case FspFsctlDeviceExtensionKind:
|
case FspFsctlDeviceExtensionKind:
|
||||||
return "Ctl";
|
return "Ctl";
|
||||||
|
case FspFsmupDeviceExtensionKind:
|
||||||
|
return "Mup";
|
||||||
case FspFsvrtDeviceExtensionKind:
|
case FspFsvrtDeviceExtensionKind:
|
||||||
return "Vrt";
|
return "Vrt";
|
||||||
case FspFsvolDeviceExtensionKind:
|
case FspFsvolDeviceExtensionKind:
|
||||||
|
@ -33,15 +33,7 @@ static NTSTATUS FspFsvolDeviceControl(
|
|||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
NTSTATUS Result = STATUS_INVALID_DEVICE_REQUEST;
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
|
|
||||||
{
|
|
||||||
case IOCTL_REDIR_QUERY_PATH_EX :
|
|
||||||
Result = FspVolumeRedirQueryPathEx(DeviceObject, Irp, IrpSp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FspFsvolDeviceControlComplete(
|
NTSTATUS FspFsvolDeviceControlComplete(
|
||||||
|
@ -63,6 +63,8 @@ VOID FspFsvolDeviceGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_I
|
|||||||
BOOLEAN FspFsvolDeviceTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
BOOLEAN FspFsvolDeviceTryGetVolumeInfo(PDEVICE_OBJECT DeviceObject, FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||||
VOID FspFsvolDeviceSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
VOID FspFsvolDeviceSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||||
VOID FspFsvolDeviceInvalidateVolumeInfo(PDEVICE_OBJECT DeviceObject);
|
VOID FspFsvolDeviceInvalidateVolumeInfo(PDEVICE_OBJECT DeviceObject);
|
||||||
|
static NTSTATUS FspFsmupDeviceInit(PDEVICE_OBJECT DeviceObject);
|
||||||
|
static VOID FspFsmupDeviceFini(PDEVICE_OBJECT DeviceObject);
|
||||||
NTSTATUS FspDeviceCopyList(
|
NTSTATUS FspDeviceCopyList(
|
||||||
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount);
|
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount);
|
||||||
VOID FspDeviceDeleteList(
|
VOID FspDeviceDeleteList(
|
||||||
@ -94,6 +96,8 @@ VOID FspDeviceDeleteAll(VOID);
|
|||||||
#pragma alloc_text(PAGE, FspFsvolDeviceCompareContextByName)
|
#pragma alloc_text(PAGE, FspFsvolDeviceCompareContextByName)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceAllocateContextByName)
|
#pragma alloc_text(PAGE, FspFsvolDeviceAllocateContextByName)
|
||||||
#pragma alloc_text(PAGE, FspFsvolDeviceFreeContextByName)
|
#pragma alloc_text(PAGE, FspFsvolDeviceFreeContextByName)
|
||||||
|
#pragma alloc_text(PAGE, FspFsmupDeviceInit)
|
||||||
|
#pragma alloc_text(PAGE, FspFsmupDeviceFini)
|
||||||
#pragma alloc_text(PAGE, FspDeviceCopyList)
|
#pragma alloc_text(PAGE, FspDeviceCopyList)
|
||||||
#pragma alloc_text(PAGE, FspDeviceDeleteList)
|
#pragma alloc_text(PAGE, FspDeviceDeleteList)
|
||||||
#pragma alloc_text(PAGE, FspDeviceDeleteAll)
|
#pragma alloc_text(PAGE, FspDeviceDeleteAll)
|
||||||
@ -118,6 +122,9 @@ NTSTATUS FspDeviceCreateSecure(UINT32 Kind, ULONG ExtraSize,
|
|||||||
case FspFsvolDeviceExtensionKind:
|
case FspFsvolDeviceExtensionKind:
|
||||||
DeviceExtensionSize = sizeof(FSP_FSVOL_DEVICE_EXTENSION);
|
DeviceExtensionSize = sizeof(FSP_FSVOL_DEVICE_EXTENSION);
|
||||||
break;
|
break;
|
||||||
|
case FspFsmupDeviceExtensionKind:
|
||||||
|
DeviceExtensionSize = sizeof(FSP_FSMUP_DEVICE_EXTENSION);
|
||||||
|
break;
|
||||||
case FspFsvrtDeviceExtensionKind:
|
case FspFsvrtDeviceExtensionKind:
|
||||||
case FspFsctlDeviceExtensionKind:
|
case FspFsctlDeviceExtensionKind:
|
||||||
DeviceExtensionSize = sizeof(FSP_DEVICE_EXTENSION);
|
DeviceExtensionSize = sizeof(FSP_DEVICE_EXTENSION);
|
||||||
@ -173,6 +180,9 @@ NTSTATUS FspDeviceInitialize(PDEVICE_OBJECT DeviceObject)
|
|||||||
case FspFsvolDeviceExtensionKind:
|
case FspFsvolDeviceExtensionKind:
|
||||||
Result = FspFsvolDeviceInit(DeviceObject);
|
Result = FspFsvolDeviceInit(DeviceObject);
|
||||||
break;
|
break;
|
||||||
|
case FspFsmupDeviceExtensionKind:
|
||||||
|
Result = FspFsmupDeviceInit(DeviceObject);
|
||||||
|
break;
|
||||||
case FspFsvrtDeviceExtensionKind:
|
case FspFsvrtDeviceExtensionKind:
|
||||||
case FspFsctlDeviceExtensionKind:
|
case FspFsctlDeviceExtensionKind:
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
@ -199,6 +209,9 @@ VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject)
|
|||||||
case FspFsvolDeviceExtensionKind:
|
case FspFsvolDeviceExtensionKind:
|
||||||
FspFsvolDeviceFini(DeviceObject);
|
FspFsvolDeviceFini(DeviceObject);
|
||||||
break;
|
break;
|
||||||
|
case FspFsmupDeviceExtensionKind:
|
||||||
|
FspFsmupDeviceFini(DeviceObject);
|
||||||
|
break;
|
||||||
case FspFsvrtDeviceExtensionKind:
|
case FspFsvrtDeviceExtensionKind:
|
||||||
case FspFsctlDeviceExtensionKind:
|
case FspFsctlDeviceExtensionKind:
|
||||||
break;
|
break;
|
||||||
@ -876,6 +889,37 @@ VOID FspFsvolDeviceInvalidateVolumeInfo(PDEVICE_OBJECT DeviceObject)
|
|||||||
KeReleaseSpinLock(&FsvolDeviceExtension->InfoSpinLock, Irql);
|
KeReleaseSpinLock(&FsvolDeviceExtension->InfoSpinLock, Irql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspFsmupDeviceInit(PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
FSP_FSMUP_DEVICE_EXTENSION *FsmupDeviceExtension = FspFsmupDeviceExtension(DeviceObject);
|
||||||
|
|
||||||
|
/* initialize our prefix table */
|
||||||
|
ExInitializeResourceLite(&FsmupDeviceExtension->PrefixTableResource);
|
||||||
|
RtlInitializeUnicodePrefix(&FsmupDeviceExtension->PrefixTable);
|
||||||
|
FsmupDeviceExtension->InitDonePfxTab = 1;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID FspFsmupDeviceFini(PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
FSP_FSMUP_DEVICE_EXTENSION *FsmupDeviceExtension = FspFsmupDeviceExtension(DeviceObject);
|
||||||
|
|
||||||
|
if (FsmupDeviceExtension->InitDonePfxTab)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Normally we would have to finalize our prefix table. This is not necessary as all
|
||||||
|
* prefixes will be gone if this code ever gets reached.
|
||||||
|
*/
|
||||||
|
ASSERT(0 == RtlNextUnicodePrefix(&FsmupDeviceExtension->PrefixTable, TRUE));
|
||||||
|
ExDeleteResourceLite(&FsmupDeviceExtension->PrefixTableResource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS FspDeviceCopyList(
|
NTSTATUS FspDeviceCopyList(
|
||||||
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount)
|
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount)
|
||||||
{
|
{
|
||||||
|
111
src/sys/driver.c
111
src/sys/driver.c
@ -44,45 +44,6 @@ NTSTATUS DriverEntry(
|
|||||||
{
|
{
|
||||||
FSP_ENTER_DRV();
|
FSP_ENTER_DRV();
|
||||||
|
|
||||||
FspDriverMultiVersionInitialize();
|
|
||||||
|
|
||||||
Result = FspProcessBufferInitialize();
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
FSP_RETURN();
|
|
||||||
|
|
||||||
FspDriverObject = DriverObject;
|
|
||||||
ExInitializeResourceLite(&FspDeviceGlobalResource);
|
|
||||||
|
|
||||||
/* 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 = FspDeviceCreateSecure(FspFsctlDeviceExtensionKind, 0,
|
|
||||||
&DeviceName, FILE_DEVICE_DISK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN,
|
|
||||||
&DeviceSddl, &FspFsctlDeviceClassGuid,
|
|
||||||
&FspFsctlDiskDeviceObject);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
{
|
|
||||||
FspProcessBufferFinalize();
|
|
||||||
FSP_RETURN();
|
|
||||||
}
|
|
||||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\" FSP_FSCTL_NET_DEVICE_NAME);
|
|
||||||
Result = FspDeviceCreateSecure(FspFsctlDeviceExtensionKind, 0,
|
|
||||||
&DeviceName, FILE_DEVICE_NETWORK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN,
|
|
||||||
&DeviceSddl, &FspFsctlDeviceClassGuid,
|
|
||||||
&FspFsctlNetDeviceObject);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
{
|
|
||||||
FspDeviceDelete(FspFsctlDiskDeviceObject);
|
|
||||||
FspProcessBufferFinalize();
|
|
||||||
FSP_RETURN();
|
|
||||||
}
|
|
||||||
Result = FspDeviceInitialize(FspFsctlDiskDeviceObject);
|
|
||||||
ASSERT(STATUS_SUCCESS == Result);
|
|
||||||
Result = FspDeviceInitialize(FspFsctlNetDeviceObject);
|
|
||||||
ASSERT(STATUS_SUCCESS == Result);
|
|
||||||
|
|
||||||
/* setup the driver object */
|
/* setup the driver object */
|
||||||
#if defined(FSP_UNLOAD)
|
#if defined(FSP_UNLOAD)
|
||||||
DriverObject->DriverUnload = FspUnload;
|
DriverObject->DriverUnload = FspUnload;
|
||||||
@ -127,7 +88,6 @@ NTSTATUS DriverEntry(
|
|||||||
FspIopCompleteFunction[IRP_MJ_DIRECTORY_CONTROL] = FspFsvolDirectoryControlComplete;
|
FspIopCompleteFunction[IRP_MJ_DIRECTORY_CONTROL] = FspFsvolDirectoryControlComplete;
|
||||||
FspIopCompleteFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FspFsvolFileSystemControlComplete;
|
FspIopCompleteFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FspFsvolFileSystemControlComplete;
|
||||||
FspIopCompleteFunction[IRP_MJ_DEVICE_CONTROL] = FspFsvolDeviceControlComplete;
|
FspIopCompleteFunction[IRP_MJ_DEVICE_CONTROL] = FspFsvolDeviceControlComplete;
|
||||||
FspIopCompleteFunction[IRP_MJ_SHUTDOWN] = FspFsvolShutdownComplete;
|
|
||||||
FspIopCompleteFunction[IRP_MJ_LOCK_CONTROL] = FspFsvolLockControlComplete;
|
FspIopCompleteFunction[IRP_MJ_LOCK_CONTROL] = FspFsvolLockControlComplete;
|
||||||
FspIopCompleteFunction[IRP_MJ_CLEANUP] = FspFsvolCleanupComplete;
|
FspIopCompleteFunction[IRP_MJ_CLEANUP] = FspFsvolCleanupComplete;
|
||||||
FspIopCompleteFunction[IRP_MJ_QUERY_SECURITY] = FspFsvolQuerySecurityComplete;
|
FspIopCompleteFunction[IRP_MJ_QUERY_SECURITY] = FspFsvolQuerySecurityComplete;
|
||||||
@ -169,9 +129,58 @@ NTSTATUS DriverEntry(
|
|||||||
#pragma prefast(suppress:28175, "We are a filesystem: ok to access FastIoDispatch")
|
#pragma prefast(suppress:28175, "We are a filesystem: ok to access FastIoDispatch")
|
||||||
DriverObject->FastIoDispatch = &FspFastIoDispatch;
|
DriverObject->FastIoDispatch = &FspFastIoDispatch;
|
||||||
|
|
||||||
|
BOOLEAN InitDoneGRes = FALSE, InitDonePsBuf = FALSE;
|
||||||
|
UNICODE_STRING DeviceSddl;
|
||||||
|
UNICODE_STRING DeviceName;
|
||||||
|
|
||||||
|
FspDriverObject = DriverObject;
|
||||||
|
ExInitializeResourceLite(&FspDeviceGlobalResource);
|
||||||
|
InitDoneGRes = TRUE;
|
||||||
|
|
||||||
|
FspDriverMultiVersionInitialize();
|
||||||
|
|
||||||
|
Result = FspProcessBufferInitialize();
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
InitDonePsBuf = TRUE;
|
||||||
|
|
||||||
|
/* create the file system control device objects */
|
||||||
|
RtlInitUnicodeString(&DeviceSddl, L"" FSP_FSCTL_DEVICE_SDDL);
|
||||||
|
RtlInitUnicodeString(&DeviceName, L"\\Device\\" FSP_FSCTL_DISK_DEVICE_NAME);
|
||||||
|
Result = FspDeviceCreateSecure(FspFsctlDeviceExtensionKind, 0,
|
||||||
|
&DeviceName, FILE_DEVICE_DISK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN,
|
||||||
|
&DeviceSddl, &FspFsctlDeviceClassGuid,
|
||||||
|
&FspFsctlDiskDeviceObject);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
RtlInitUnicodeString(&DeviceName, L"\\Device\\" FSP_FSCTL_NET_DEVICE_NAME);
|
||||||
|
Result = FspDeviceCreateSecure(FspFsctlDeviceExtensionKind, 0,
|
||||||
|
&DeviceName, FILE_DEVICE_NETWORK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN,
|
||||||
|
&DeviceSddl, &FspFsctlDeviceClassGuid,
|
||||||
|
&FspFsctlNetDeviceObject);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
Result = FspDeviceCreate(FspFsmupDeviceExtensionKind, 0,
|
||||||
|
FILE_DEVICE_NETWORK_FILE_SYSTEM, FILE_REMOTE_DEVICE,
|
||||||
|
&FspFsmupDeviceObject);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
Result = FspDeviceInitialize(FspFsctlDiskDeviceObject);
|
||||||
|
ASSERT(STATUS_SUCCESS == Result);
|
||||||
|
Result = FspDeviceInitialize(FspFsctlNetDeviceObject);
|
||||||
|
ASSERT(STATUS_SUCCESS == Result);
|
||||||
|
Result = FspDeviceInitialize(FspFsmupDeviceObject);
|
||||||
|
ASSERT(STATUS_SUCCESS == Result);
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&DeviceName, L"\\Device\\" FSP_FSCTL_MUP_DEVICE_NAME);
|
||||||
|
Result = FsRtlRegisterUncProviderEx(&FspMupHandle,
|
||||||
|
&DeviceName, FspFsmupDeviceObject, 0);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register our "disk" device as a file system. We do not register our "net" device
|
* Register our "disk" device as a file system. We do not register our "net" device
|
||||||
* as a file system, but we register with the MUP instead at a later time.
|
* as a file system; we register with the MUP instead.
|
||||||
*
|
*
|
||||||
* Please note that the call below makes our driver unloadable. In fact the driver
|
* Please note that the call below makes our driver unloadable. In fact the driver
|
||||||
* remains unloadable even if we issue an IoUnregisterFileSystem() call immediately
|
* remains unloadable even if we issue an IoUnregisterFileSystem() call immediately
|
||||||
@ -180,6 +189,23 @@ NTSTATUS DriverEntry(
|
|||||||
*/
|
*/
|
||||||
IoRegisterFileSystem(FspFsctlDiskDeviceObject);
|
IoRegisterFileSystem(FspFsctlDiskDeviceObject);
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
if (0 != FspFsmupDeviceObject)
|
||||||
|
FspDeviceDelete(FspFsmupDeviceObject);
|
||||||
|
if (0 != FspFsctlNetDeviceObject)
|
||||||
|
FspDeviceDelete(FspFsctlNetDeviceObject);
|
||||||
|
if (0 != FspFsctlDiskDeviceObject)
|
||||||
|
FspDeviceDelete(FspFsctlDiskDeviceObject);
|
||||||
|
if (InitDonePsBuf)
|
||||||
|
FspProcessBufferFinalize();
|
||||||
|
if (InitDoneGRes)
|
||||||
|
ExDeleteResourceLite(&FspDeviceGlobalResource);
|
||||||
|
}
|
||||||
|
|
||||||
#pragma prefast(suppress:28175, "We are in DriverEntry: ok to access DriverName")
|
#pragma prefast(suppress:28175, "We are in DriverEntry: ok to access DriverName")
|
||||||
FSP_LEAVE_DRV("DriverName=\"%wZ\", RegistryPath=\"%wZ\"",
|
FSP_LEAVE_DRV("DriverName=\"%wZ\", RegistryPath=\"%wZ\"",
|
||||||
&DriverObject->DriverName, RegistryPath);
|
&DriverObject->DriverName, RegistryPath);
|
||||||
@ -213,6 +239,7 @@ VOID FspUnload(
|
|||||||
|
|
||||||
FspFsctlDiskDeviceObject = 0;
|
FspFsctlDiskDeviceObject = 0;
|
||||||
FspFsctlNetDeviceObject = 0;
|
FspFsctlNetDeviceObject = 0;
|
||||||
|
FspFsmupDeviceObject = 0;
|
||||||
//FspDeviceDeleteAll();
|
//FspDeviceDeleteAll();
|
||||||
|
|
||||||
ExDeleteResourceLite(&FspDeviceGlobalResource);
|
ExDeleteResourceLite(&FspDeviceGlobalResource);
|
||||||
@ -229,6 +256,8 @@ VOID FspUnload(
|
|||||||
PDRIVER_OBJECT FspDriverObject;
|
PDRIVER_OBJECT FspDriverObject;
|
||||||
PDEVICE_OBJECT FspFsctlDiskDeviceObject;
|
PDEVICE_OBJECT FspFsctlDiskDeviceObject;
|
||||||
PDEVICE_OBJECT FspFsctlNetDeviceObject;
|
PDEVICE_OBJECT FspFsctlNetDeviceObject;
|
||||||
|
PDEVICE_OBJECT FspFsmupDeviceObject;
|
||||||
|
HANDLE FspMupHandle;
|
||||||
FAST_IO_DISPATCH FspFastIoDispatch;
|
FAST_IO_DISPATCH FspFastIoDispatch;
|
||||||
CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
|
CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
|
||||||
|
|
||||||
|
@ -180,6 +180,8 @@ VOID FspDebugLogIrp(const char *func, PIRP Irp, NTSTATUS Result);
|
|||||||
#define FSP_LEAVE_DRV(fmt, ...) \
|
#define FSP_LEAVE_DRV(fmt, ...) \
|
||||||
FSP_LEAVE_(FSP_DEBUGLOG_(fmt, " = %s", __VA_ARGS__, NtStatusSym(Result))); return Result
|
FSP_LEAVE_(FSP_DEBUGLOG_(fmt, " = %s", __VA_ARGS__, NtStatusSym(Result))); return Result
|
||||||
#define FSP_ENTER_MJ(...) \
|
#define FSP_ENTER_MJ(...) \
|
||||||
|
if (FspFsmupDeviceExtensionKind == FspDeviceExtension(DeviceObject)->Kind)\
|
||||||
|
return FspMupHandleIrp(DeviceObject, Irp);\
|
||||||
NTSTATUS Result = STATUS_SUCCESS; \
|
NTSTATUS Result = STATUS_SUCCESS; \
|
||||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);\
|
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);\
|
||||||
BOOLEAN fsp_device_deref = FALSE; \
|
BOOLEAN fsp_device_deref = FALSE; \
|
||||||
@ -328,7 +330,6 @@ FSP_IOPREP_DISPATCH FspFsvolSetInformationPrepare;
|
|||||||
FSP_IOCMPL_DISPATCH FspFsvolSetInformationComplete;
|
FSP_IOCMPL_DISPATCH FspFsvolSetInformationComplete;
|
||||||
FSP_IOCMPL_DISPATCH FspFsvolSetSecurityComplete;
|
FSP_IOCMPL_DISPATCH FspFsvolSetSecurityComplete;
|
||||||
FSP_IOCMPL_DISPATCH FspFsvolSetVolumeInformationComplete;
|
FSP_IOCMPL_DISPATCH FspFsvolSetVolumeInformationComplete;
|
||||||
FSP_IOCMPL_DISPATCH FspFsvolShutdownComplete;
|
|
||||||
FSP_IOPREP_DISPATCH FspFsvolWritePrepare;
|
FSP_IOPREP_DISPATCH FspFsvolWritePrepare;
|
||||||
FSP_IOCMPL_DISPATCH FspFsvolWriteComplete;
|
FSP_IOCMPL_DISPATCH FspFsvolWriteComplete;
|
||||||
|
|
||||||
@ -1007,6 +1008,7 @@ typedef struct
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
FspFsctlDeviceExtensionKind = '\0ltC', /* file system control device (e.g. \Device\WinFsp.Disk) */
|
FspFsctlDeviceExtensionKind = '\0ltC', /* file system control device (e.g. \Device\WinFsp.Disk) */
|
||||||
|
FspFsmupDeviceExtensionKind = '\0puM', /* our own MUP device (linked to \Device\WinFsp.Mup) */
|
||||||
FspFsvrtDeviceExtensionKind = '\0trV', /* virtual volume device (e.g. \Device\Volume{GUID}) */
|
FspFsvrtDeviceExtensionKind = '\0trV', /* virtual volume device (e.g. \Device\Volume{GUID}) */
|
||||||
FspFsvolDeviceExtensionKind = '\0loV', /* file system volume device (unnamed) */
|
FspFsvolDeviceExtensionKind = '\0loV', /* file system volume device (unnamed) */
|
||||||
};
|
};
|
||||||
@ -1023,11 +1025,12 @@ typedef struct
|
|||||||
InitDoneCtxTab:1, InitDoneTimer:1, InitDoneInfo:1, InitDoneNotify:1, InitDoneStat:1;
|
InitDoneCtxTab:1, InitDoneTimer:1, InitDoneInfo:1, InitDoneNotify:1, InitDoneStat:1;
|
||||||
PDEVICE_OBJECT FsctlDeviceObject;
|
PDEVICE_OBJECT FsctlDeviceObject;
|
||||||
PDEVICE_OBJECT FsvrtDeviceObject;
|
PDEVICE_OBJECT FsvrtDeviceObject;
|
||||||
HANDLE MupHandle;
|
PDEVICE_OBJECT FsvolDeviceObject;
|
||||||
PVPB SwapVpb;
|
PVPB SwapVpb;
|
||||||
FSP_DELAYED_WORK_ITEM DeleteVolumeDelayedWorkItem;
|
FSP_DELAYED_WORK_ITEM DeleteVolumeDelayedWorkItem;
|
||||||
FSP_FSCTL_VOLUME_PARAMS VolumeParams;
|
FSP_FSCTL_VOLUME_PARAMS VolumeParams;
|
||||||
UNICODE_STRING VolumePrefix;
|
UNICODE_STRING VolumePrefix;
|
||||||
|
UNICODE_PREFIX_TABLE_ENTRY VolumePrefixEntry;
|
||||||
FSP_IOQ *Ioq;
|
FSP_IOQ *Ioq;
|
||||||
FSP_META_CACHE *SecurityCache;
|
FSP_META_CACHE *SecurityCache;
|
||||||
FSP_META_CACHE *DirInfoCache;
|
FSP_META_CACHE *DirInfoCache;
|
||||||
@ -1049,6 +1052,13 @@ typedef struct
|
|||||||
LIST_ENTRY NotifyList;
|
LIST_ENTRY NotifyList;
|
||||||
FSP_STATISTICS *Statistics;
|
FSP_STATISTICS *Statistics;
|
||||||
} FSP_FSVOL_DEVICE_EXTENSION;
|
} FSP_FSVOL_DEVICE_EXTENSION;
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
FSP_DEVICE_EXTENSION Base;
|
||||||
|
UINT32 InitDonePfxTab:1;
|
||||||
|
ERESOURCE PrefixTableResource;
|
||||||
|
UNICODE_PREFIX_TABLE PrefixTable;
|
||||||
|
} FSP_FSMUP_DEVICE_EXTENSION;
|
||||||
static inline
|
static inline
|
||||||
FSP_DEVICE_EXTENSION *FspDeviceExtension(PDEVICE_OBJECT DeviceObject)
|
FSP_DEVICE_EXTENSION *FspDeviceExtension(PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
@ -1060,6 +1070,12 @@ FSP_FSVOL_DEVICE_EXTENSION *FspFsvolDeviceExtension(PDEVICE_OBJECT DeviceObject)
|
|||||||
ASSERT(FspFsvolDeviceExtensionKind == ((FSP_DEVICE_EXTENSION *)DeviceObject->DeviceExtension)->Kind);
|
ASSERT(FspFsvolDeviceExtensionKind == ((FSP_DEVICE_EXTENSION *)DeviceObject->DeviceExtension)->Kind);
|
||||||
return DeviceObject->DeviceExtension;
|
return DeviceObject->DeviceExtension;
|
||||||
}
|
}
|
||||||
|
static inline
|
||||||
|
FSP_FSMUP_DEVICE_EXTENSION *FspFsmupDeviceExtension(PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
ASSERT(FspFsmupDeviceExtensionKind == ((FSP_DEVICE_EXTENSION *)DeviceObject->DeviceExtension)->Kind);
|
||||||
|
return DeviceObject->DeviceExtension;
|
||||||
|
}
|
||||||
NTSTATUS FspDeviceCreateSecure(UINT32 Kind, ULONG ExtraSize,
|
NTSTATUS FspDeviceCreateSecure(UINT32 Kind, ULONG ExtraSize,
|
||||||
PUNICODE_STRING DeviceName, DEVICE_TYPE DeviceType, ULONG DeviceCharacteristics,
|
PUNICODE_STRING DeviceName, DEVICE_TYPE DeviceType, ULONG DeviceCharacteristics,
|
||||||
PUNICODE_STRING DeviceSddl, LPCGUID DeviceClassGuid,
|
PUNICODE_STRING DeviceSddl, LPCGUID DeviceClassGuid,
|
||||||
@ -1156,6 +1172,14 @@ BOOLEAN FspQueryDirectoryIrpShouldUseProcessBuffer(PIRP Irp, SIZE_T BufferSize)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* fsmup */
|
||||||
|
BOOLEAN FspMupRegister(
|
||||||
|
PDEVICE_OBJECT FsmupDeviceObject, PDEVICE_OBJECT FsvolDeviceObject);
|
||||||
|
VOID FspMupUnregister(
|
||||||
|
PDEVICE_OBJECT FsmupDeviceObject, PDEVICE_OBJECT FsvolDeviceObject);
|
||||||
|
NTSTATUS FspMupHandleIrp(
|
||||||
|
PDEVICE_OBJECT FsmupDeviceObject, PIRP Irp);
|
||||||
|
|
||||||
/* volume management */
|
/* volume management */
|
||||||
#define FspVolumeTransactEarlyTimeout (1 * 10000ULL)
|
#define FspVolumeTransactEarlyTimeout (1 * 10000ULL)
|
||||||
NTSTATUS FspVolumeCreate(
|
NTSTATUS FspVolumeCreate(
|
||||||
@ -1164,8 +1188,6 @@ VOID FspVolumeDelete(
|
|||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeMount(
|
NTSTATUS FspVolumeMount(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeRedirQueryPathEx(
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
|
||||||
NTSTATUS FspVolumeGetName(
|
NTSTATUS FspVolumeGetName(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeGetNameList(
|
NTSTATUS FspVolumeGetNameList(
|
||||||
@ -1559,6 +1581,8 @@ FSP_MV_CcCoherencyFlushAndPurgeCache(
|
|||||||
extern PDRIVER_OBJECT FspDriverObject;
|
extern PDRIVER_OBJECT FspDriverObject;
|
||||||
extern PDEVICE_OBJECT FspFsctlDiskDeviceObject;
|
extern PDEVICE_OBJECT FspFsctlDiskDeviceObject;
|
||||||
extern PDEVICE_OBJECT FspFsctlNetDeviceObject;
|
extern PDEVICE_OBJECT FspFsctlNetDeviceObject;
|
||||||
|
extern PDEVICE_OBJECT FspFsmupDeviceObject;
|
||||||
|
extern HANDLE FspMupHandle;
|
||||||
extern FAST_IO_DISPATCH FspFastIoDispatch;
|
extern FAST_IO_DISPATCH FspFastIoDispatch;
|
||||||
extern CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
|
extern CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
|
||||||
extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[];
|
extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[];
|
||||||
|
266
src/sys/mup.c
Normal file
266
src/sys/mup.c
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
/**
|
||||||
|
* @file sys/mup.c
|
||||||
|
*
|
||||||
|
* @copyright 2015-2018 Bill Zissimopoulos
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* This file is part of WinFsp.
|
||||||
|
*
|
||||||
|
* You can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
* General Public License version 3 as published by the Free Software
|
||||||
|
* Foundation.
|
||||||
|
*
|
||||||
|
* Licensees holding a valid commercial license may use this file in
|
||||||
|
* accordance with the commercial license agreement provided with the
|
||||||
|
* software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/driver.h>
|
||||||
|
|
||||||
|
BOOLEAN FspMupRegister(
|
||||||
|
PDEVICE_OBJECT FsmupDeviceObject, PDEVICE_OBJECT FsvolDeviceObject);
|
||||||
|
VOID FspMupUnregister(
|
||||||
|
PDEVICE_OBJECT FsmupDeviceObject, PDEVICE_OBJECT FsvolDeviceObject);
|
||||||
|
NTSTATUS FspMupHandleIrp(
|
||||||
|
PDEVICE_OBJECT FsmupDeviceObject, PIRP Irp);
|
||||||
|
static NTSTATUS FspMupRedirQueryPathEx(
|
||||||
|
PDEVICE_OBJECT FsmupDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
|
|
||||||
|
#ifdef ALLOC_PRAGMA
|
||||||
|
#pragma alloc_text(PAGE, FspMupRegister)
|
||||||
|
#pragma alloc_text(PAGE, FspMupUnregister)
|
||||||
|
#pragma alloc_text(PAGE, FspMupHandleIrp)
|
||||||
|
#pragma alloc_text(PAGE, FspMupRedirQueryPathEx)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BOOLEAN FspMupRegister(
|
||||||
|
PDEVICE_OBJECT FsmupDeviceObject, PDEVICE_OBJECT FsvolDeviceObject)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
BOOLEAN Result;
|
||||||
|
FSP_FSMUP_DEVICE_EXTENSION *FsmupDeviceExtension = FspFsmupDeviceExtension(FsmupDeviceObject);
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
|
|
||||||
|
ExAcquireResourceExclusiveLite(&FsmupDeviceExtension->PrefixTableResource, TRUE);
|
||||||
|
Result = RtlInsertUnicodePrefix(&FsmupDeviceExtension->PrefixTable,
|
||||||
|
&FsvolDeviceExtension->VolumePrefix, &FsvolDeviceExtension->VolumePrefixEntry);
|
||||||
|
if (Result)
|
||||||
|
FspDeviceReference(FsvolDeviceObject);
|
||||||
|
ExReleaseResourceLite(&FsmupDeviceExtension->PrefixTableResource);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID FspMupUnregister(
|
||||||
|
PDEVICE_OBJECT FsmupDeviceObject, PDEVICE_OBJECT FsvolDeviceObject)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
FSP_FSMUP_DEVICE_EXTENSION *FsmupDeviceExtension = FspFsmupDeviceExtension(FsmupDeviceObject);
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
|
|
||||||
|
ExAcquireResourceExclusiveLite(&FsmupDeviceExtension->PrefixTableResource, TRUE);
|
||||||
|
RtlRemoveUnicodePrefix(&FsmupDeviceExtension->PrefixTable,
|
||||||
|
&FsvolDeviceExtension->VolumePrefixEntry);
|
||||||
|
FspDeviceDereference(FsvolDeviceObject);
|
||||||
|
ExReleaseResourceLite(&FsmupDeviceExtension->PrefixTableResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspMupHandleIrp(
|
||||||
|
PDEVICE_OBJECT FsmupDeviceObject, PIRP Irp)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
FSP_FSMUP_DEVICE_EXTENSION *FsmupDeviceExtension = FspFsmupDeviceExtension(FsmupDeviceObject);
|
||||||
|
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||||
|
PDEVICE_OBJECT FsvolDeviceObject = 0;
|
||||||
|
PUNICODE_PREFIX_TABLE_ENTRY Entry;
|
||||||
|
BOOLEAN DeviceDeref = FALSE;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
FsRtlEnterFileSystem();
|
||||||
|
|
||||||
|
switch (IrpSp->MajorFunction)
|
||||||
|
{
|
||||||
|
case IRP_MJ_CREATE:
|
||||||
|
/*
|
||||||
|
* A CREATE request with an empty file name indicates that the fsmup device
|
||||||
|
* is being opened. Check for this case and handle it.
|
||||||
|
*/
|
||||||
|
if (0 == FileObject->FileName.Length)
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
Irp->IoStatus.Information = FILE_OPENED;
|
||||||
|
IoCompleteRequest(Irp, FSP_IO_INCREMENT);
|
||||||
|
Result = Irp->IoStatus.Status;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Every other CREATE request must be forwarded to the appropriate fsvol device.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (0 != FileObject->RelatedFileObject)
|
||||||
|
FileObject = FileObject->RelatedFileObject;
|
||||||
|
|
||||||
|
ExAcquireResourceExclusiveLite(&FsmupDeviceExtension->PrefixTableResource, TRUE);
|
||||||
|
Entry = RtlFindUnicodePrefix(&FsmupDeviceExtension->PrefixTable,
|
||||||
|
&FileObject->FileName, 0);
|
||||||
|
if (0 != Entry)
|
||||||
|
{
|
||||||
|
FsvolDeviceObject = CONTAINING_RECORD(Entry,
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION, VolumePrefixEntry)->FsvolDeviceObject;
|
||||||
|
FspDeviceReference(FsvolDeviceObject);
|
||||||
|
DeviceDeref = TRUE;
|
||||||
|
}
|
||||||
|
ExReleaseResourceLite(&FsmupDeviceExtension->PrefixTableResource);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MJ_DEVICE_CONTROL:
|
||||||
|
/*
|
||||||
|
* A DEVICE_CONTROL request with IOCTL_REDIR_QUERY_PATH_EX must be handled
|
||||||
|
* by the fsmup device. Check for this case and handle it.
|
||||||
|
*/
|
||||||
|
if (IOCTL_REDIR_QUERY_PATH_EX == IrpSp->Parameters.DeviceIoControl.IoControlCode)
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Status = FspMupRedirQueryPathEx(FsmupDeviceObject, Irp, IrpSp);
|
||||||
|
IoCompleteRequest(Irp, FSP_IO_INCREMENT);
|
||||||
|
Result = Irp->IoStatus.Status;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Every other DEVICE_CONTROL request must be forwarded to the appropriate fsvol device.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* fall through! */
|
||||||
|
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
* Every other request must be forwarded to the appropriate fsvol device. If there is no
|
||||||
|
* fsvol device, then we must return the appropriate status code (see below).
|
||||||
|
*
|
||||||
|
* Please note that since we allow the fsmup device to be opened, we must also handle
|
||||||
|
* CLEANUP and CLOSE requests for it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (0 != FileObject)
|
||||||
|
{
|
||||||
|
if (FspFileNodeIsValid(FileObject->FsContext))
|
||||||
|
FsvolDeviceObject = ((FSP_FILE_NODE *)FileObject->FsContext)->FsvolDeviceObject;
|
||||||
|
else if (0 != FileObject->FsContext2 &&
|
||||||
|
3 == ((PDEVICE_OBJECT)FileObject->FsContext2)->Type &&
|
||||||
|
0 != ((PDEVICE_OBJECT)FileObject->FsContext2)->DeviceExtension &&
|
||||||
|
FspFsvolDeviceExtensionKind == FspDeviceExtension((PDEVICE_OBJECT)FileObject->FsContext2)->Kind)
|
||||||
|
FsvolDeviceObject = (PDEVICE_OBJECT)FileObject->FsContext2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == FsvolDeviceObject)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We were not able to find an fsvol device to forward this IRP to. We will complete
|
||||||
|
* the IRP with an appropriate status code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
switch (IrpSp->MajorFunction)
|
||||||
|
{
|
||||||
|
case IRP_MJ_CLEANUP:
|
||||||
|
case IRP_MJ_CLOSE:
|
||||||
|
/*
|
||||||
|
* CLEANUP and CLOSE requests ignore their status code (except for STATUS_PENDING).
|
||||||
|
* So return STATUS_SUCCESS. This works regardless of whether this is a legitimate
|
||||||
|
* fsmup request or an erroneous CLOSE request that we should not have seen.
|
||||||
|
*/
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
case IRP_MJ_QUERY_INFORMATION:
|
||||||
|
case IRP_MJ_SET_INFORMATION:
|
||||||
|
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
IoCompleteRequest(Irp, FSP_IO_INCREMENT);
|
||||||
|
Result = Irp->IoStatus.Status;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(FspFsvolDeviceExtensionKind == FspDeviceExtension(FsvolDeviceObject)->Kind);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Forward the IRP to the appropriate fsvol device. The fsvol device will take care
|
||||||
|
* to complete the IRP, etc.
|
||||||
|
*/
|
||||||
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
|
Result = IoCallDriver(FsvolDeviceObject, Irp);
|
||||||
|
|
||||||
|
if (DeviceDeref)
|
||||||
|
FspDeviceDereference(FsvolDeviceObject);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
FsRtlExitFileSystem();
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspMupRedirQueryPathEx(
|
||||||
|
PDEVICE_OBJECT FsmupDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
ASSERT(IRP_MJ_DEVICE_CONTROL == IrpSp->MajorFunction);
|
||||||
|
ASSERT(IOCTL_REDIR_QUERY_PATH_EX == IrpSp->Parameters.DeviceIoControl.IoControlCode);
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
|
if (KernelMode != Irp->RequestorMode)
|
||||||
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
|
||||||
|
/* check parameters */
|
||||||
|
ULONG InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||||
|
ULONG OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||||
|
QUERY_PATH_REQUEST_EX *QueryPathRequest = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
||||||
|
QUERY_PATH_RESPONSE *QueryPathResponse = Irp->UserBuffer;
|
||||||
|
if (sizeof(QUERY_PATH_REQUEST_EX) > InputBufferLength ||
|
||||||
|
0 == QueryPathRequest || 0 == QueryPathResponse)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
if (sizeof(QUERY_PATH_RESPONSE) > OutputBufferLength)
|
||||||
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
FSP_FSMUP_DEVICE_EXTENSION *FsmupDeviceExtension = FspFsmupDeviceExtension(FsmupDeviceObject);
|
||||||
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension;
|
||||||
|
PUNICODE_PREFIX_TABLE_ENTRY Entry;
|
||||||
|
PDEVICE_OBJECT FsvolDeviceObject = 0;
|
||||||
|
|
||||||
|
Result = STATUS_BAD_NETWORK_PATH;
|
||||||
|
ExAcquireResourceExclusiveLite(&FsmupDeviceExtension->PrefixTableResource, TRUE);
|
||||||
|
Entry = RtlFindUnicodePrefix(&FsmupDeviceExtension->PrefixTable,
|
||||||
|
&QueryPathRequest->PathName, 0);
|
||||||
|
if (0 != Entry)
|
||||||
|
{
|
||||||
|
FsvolDeviceExtension = CONTAINING_RECORD(Entry, FSP_FSVOL_DEVICE_EXTENSION, VolumePrefixEntry);
|
||||||
|
FsvolDeviceObject = FsvolDeviceExtension->FsvolDeviceObject;
|
||||||
|
if (!FspIoqStopped(FsvolDeviceExtension->Ioq))
|
||||||
|
{
|
||||||
|
if (0 < FsvolDeviceExtension->VolumePrefix.Length &&
|
||||||
|
FspFsvolDeviceVolumePrefixInString(FsvolDeviceObject, &QueryPathRequest->PathName) &&
|
||||||
|
(QueryPathRequest->PathName.Length == FsvolDeviceExtension->VolumePrefix.Length ||
|
||||||
|
'\\' == QueryPathRequest->PathName.Buffer[FsvolDeviceExtension->VolumePrefix.Length / sizeof(WCHAR)]))
|
||||||
|
{
|
||||||
|
QueryPathResponse->LengthAccepted = FsvolDeviceExtension->VolumePrefix.Length;
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ExReleaseResourceLite(&FsmupDeviceExtension->PrefixTableResource);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
@ -17,45 +17,18 @@
|
|||||||
|
|
||||||
#include <sys/driver.h>
|
#include <sys/driver.h>
|
||||||
|
|
||||||
static NTSTATUS FspFsvolShutdown(
|
|
||||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
|
||||||
FSP_DRIVER_DISPATCH FspShutdown;
|
FSP_DRIVER_DISPATCH FspShutdown;
|
||||||
FSP_IOCMPL_DISPATCH FspFsvolShutdownComplete;
|
|
||||||
|
|
||||||
#ifdef ALLOC_PRAGMA
|
#ifdef ALLOC_PRAGMA
|
||||||
#pragma alloc_text(PAGE, FspFsvolShutdown)
|
|
||||||
#pragma alloc_text(PAGE, FspFsvolShutdownComplete)
|
|
||||||
#pragma alloc_text(PAGE, FspShutdown)
|
#pragma alloc_text(PAGE, FspShutdown)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static NTSTATUS FspFsvolShutdown(
|
|
||||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS FspFsvolShutdownComplete(
|
|
||||||
PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Response)
|
|
||||||
{
|
|
||||||
FSP_ENTER_IOC(PAGED_CODE());
|
|
||||||
|
|
||||||
FSP_LEAVE_IOC("%s", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS FspShutdown(
|
NTSTATUS FspShutdown(
|
||||||
PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
{
|
{
|
||||||
FSP_ENTER_MJ(PAGED_CODE());
|
FSP_ENTER_MJ(PAGED_CODE());
|
||||||
|
|
||||||
switch (FspDeviceExtension(DeviceObject)->Kind)
|
|
||||||
{
|
|
||||||
case FspFsvolDeviceExtensionKind:
|
|
||||||
FSP_RETURN(Result = FspFsvolShutdown(DeviceObject, Irp, IrpSp));
|
|
||||||
default:
|
|
||||||
FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST);
|
FSP_RETURN(Result = STATUS_INVALID_DEVICE_REQUEST);
|
||||||
}
|
|
||||||
|
|
||||||
FSP_LEAVE_MJ("%s", "");
|
FSP_LEAVE_MJ("%s", "");
|
||||||
}
|
}
|
||||||
|
102
src/sys/volume.c
102
src/sys/volume.c
@ -21,7 +21,6 @@ NTSTATUS FspVolumeCreate(
|
|||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
static NTSTATUS FspVolumeCreateNoLock(
|
static NTSTATUS FspVolumeCreateNoLock(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
static WORKER_THREAD_ROUTINE FspVolumeCreateRegisterMup;
|
|
||||||
VOID FspVolumeDelete(
|
VOID FspVolumeDelete(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
static VOID FspVolumeDeleteNoLock(
|
static VOID FspVolumeDeleteNoLock(
|
||||||
@ -31,8 +30,6 @@ NTSTATUS FspVolumeMount(
|
|||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
static NTSTATUS FspVolumeMountNoLock(
|
static NTSTATUS FspVolumeMountNoLock(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeRedirQueryPathEx(
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
|
||||||
NTSTATUS FspVolumeGetName(
|
NTSTATUS FspVolumeGetName(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
NTSTATUS FspVolumeGetNameList(
|
NTSTATUS FspVolumeGetNameList(
|
||||||
@ -49,13 +46,11 @@ NTSTATUS FspVolumeWork(
|
|||||||
#ifdef ALLOC_PRAGMA
|
#ifdef ALLOC_PRAGMA
|
||||||
#pragma alloc_text(PAGE, FspVolumeCreate)
|
#pragma alloc_text(PAGE, FspVolumeCreate)
|
||||||
#pragma alloc_text(PAGE, FspVolumeCreateNoLock)
|
#pragma alloc_text(PAGE, FspVolumeCreateNoLock)
|
||||||
#pragma alloc_text(PAGE, FspVolumeCreateRegisterMup)
|
|
||||||
// ! #pragma alloc_text(PAGE, FspVolumeDelete)
|
// ! #pragma alloc_text(PAGE, FspVolumeDelete)
|
||||||
// ! #pragma alloc_text(PAGE, FspVolumeDeleteNoLock)
|
// ! #pragma alloc_text(PAGE, FspVolumeDeleteNoLock)
|
||||||
// ! #pragma alloc_text(PAGE, FspVolumeDeleteDelayed)
|
// ! #pragma alloc_text(PAGE, FspVolumeDeleteDelayed)
|
||||||
// ! #pragma alloc_text(PAGE, FspVolumeMount)
|
// ! #pragma alloc_text(PAGE, FspVolumeMount)
|
||||||
// ! #pragma alloc_text(PAGE, FspVolumeMountNoLock)
|
// ! #pragma alloc_text(PAGE, FspVolumeMountNoLock)
|
||||||
#pragma alloc_text(PAGE, FspVolumeRedirQueryPathEx)
|
|
||||||
#pragma alloc_text(PAGE, FspVolumeGetName)
|
#pragma alloc_text(PAGE, FspVolumeGetName)
|
||||||
#pragma alloc_text(PAGE, FspVolumeGetNameList)
|
#pragma alloc_text(PAGE, FspVolumeGetNameList)
|
||||||
#pragma alloc_text(PAGE, FspVolumeGetNameListNoLock)
|
#pragma alloc_text(PAGE, FspVolumeGetNameListNoLock)
|
||||||
@ -67,13 +62,6 @@ NTSTATUS FspVolumeWork(
|
|||||||
#define PREFIXW L"" FSP_FSCTL_VOLUME_PARAMS_PREFIX
|
#define PREFIXW L"" FSP_FSCTL_VOLUME_PARAMS_PREFIX
|
||||||
#define PREFIXW_SIZE (sizeof PREFIXW - sizeof(WCHAR))
|
#define PREFIXW_SIZE (sizeof PREFIXW - sizeof(WCHAR))
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject;
|
|
||||||
NTSTATUS Result;
|
|
||||||
FSP_SYNCHRONOUS_WORK_ITEM SynchronousWorkItem;
|
|
||||||
} FSP_CREATE_VOLUME_REGISTER_MUP_WORK_ITEM;
|
|
||||||
|
|
||||||
NTSTATUS FspVolumeCreate(
|
NTSTATUS FspVolumeCreate(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
@ -106,11 +94,11 @@ static NTSTATUS FspVolumeCreateNoLock(
|
|||||||
GUID Guid;
|
GUID Guid;
|
||||||
UNICODE_STRING DeviceSddl;
|
UNICODE_STRING DeviceSddl;
|
||||||
UNICODE_STRING VolumeName;
|
UNICODE_STRING VolumeName;
|
||||||
|
UNICODE_STRING FsmupDeviceName;
|
||||||
WCHAR VolumeNameBuf[FSP_FSCTL_VOLUME_NAME_SIZE / sizeof(WCHAR)];
|
WCHAR VolumeNameBuf[FSP_FSCTL_VOLUME_NAME_SIZE / sizeof(WCHAR)];
|
||||||
PDEVICE_OBJECT FsvolDeviceObject;
|
PDEVICE_OBJECT FsvolDeviceObject;
|
||||||
PDEVICE_OBJECT FsvrtDeviceObject;
|
PDEVICE_OBJECT FsvrtDeviceObject;
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension;
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension;
|
||||||
FSP_CREATE_VOLUME_REGISTER_MUP_WORK_ITEM RegisterMupWorkItem;
|
|
||||||
|
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
if (PREFIXW_SIZE + sizeof(FSP_FSCTL_VOLUME_PARAMS) * sizeof(WCHAR) > FileObject->FileName.Length)
|
if (PREFIXW_SIZE + sizeof(FSP_FSCTL_VOLUME_PARAMS) * sizeof(WCHAR) > FileObject->FileName.Length)
|
||||||
@ -225,6 +213,7 @@ static NTSTATUS FspVolumeCreateNoLock(
|
|||||||
FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
FsvolDeviceExtension->FsctlDeviceObject = FsctlDeviceObject;
|
FsvolDeviceExtension->FsctlDeviceObject = FsctlDeviceObject;
|
||||||
FsvolDeviceExtension->FsvrtDeviceObject = FsvrtDeviceObject;
|
FsvolDeviceExtension->FsvrtDeviceObject = FsvrtDeviceObject;
|
||||||
|
FsvolDeviceExtension->FsvolDeviceObject = FsvolDeviceObject;
|
||||||
FsvolDeviceExtension->VolumeParams = VolumeParams;
|
FsvolDeviceExtension->VolumeParams = VolumeParams;
|
||||||
if (FILE_DEVICE_NETWORK_FILE_SYSTEM == FsctlDeviceObject->DeviceType)
|
if (FILE_DEVICE_NETWORK_FILE_SYSTEM == FsctlDeviceObject->DeviceType)
|
||||||
RtlInitUnicodeString(&FsvolDeviceExtension->VolumePrefix,
|
RtlInitUnicodeString(&FsvolDeviceExtension->VolumePrefix,
|
||||||
@ -245,24 +234,20 @@ static NTSTATUS FspVolumeCreateNoLock(
|
|||||||
FspDeviceDereference(FsvolDeviceObject);
|
FspDeviceDereference(FsvolDeviceObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do we need to register with MUP? */
|
/* do we need to register with fsmup? */
|
||||||
if (0 == FsvrtDeviceObject)
|
if (0 == FsvrtDeviceObject)
|
||||||
{
|
{
|
||||||
/*
|
if (!FspMupRegister(FspFsmupDeviceObject, FsvolDeviceObject))
|
||||||
* Turns out we cannot call FsRtlRegisterUncProviderEx when the PreviousMode
|
{
|
||||||
* is UserMode! So we need to somehow switch to KernelMode prior to issuing
|
FspDeviceDereference(FsvolDeviceObject);
|
||||||
* the FsRtlRegisterUncProviderEx call. There seems to be no straightforward
|
return STATUS_OBJECT_NAME_COLLISION;
|
||||||
* way to switch the PreviousMode (no ExSetPreviousMode). So we do it indirectly
|
}
|
||||||
* by executing a synchronous work item (FspExecuteSynchronousWorkItem).
|
|
||||||
*/
|
RtlInitUnicodeString(&FsmupDeviceName, L"\\Device\\" FSP_FSCTL_MUP_DEVICE_NAME);
|
||||||
RtlZeroMemory(&RegisterMupWorkItem, sizeof RegisterMupWorkItem);
|
Result = IoCreateSymbolicLink(&FsvolDeviceExtension->VolumeName, &FsmupDeviceName);
|
||||||
RegisterMupWorkItem.FsvolDeviceObject = FsvolDeviceObject;
|
|
||||||
FspInitializeSynchronousWorkItem(&RegisterMupWorkItem.SynchronousWorkItem,
|
|
||||||
FspVolumeCreateRegisterMup, &RegisterMupWorkItem);
|
|
||||||
FspExecuteSynchronousWorkItem(&RegisterMupWorkItem.SynchronousWorkItem);
|
|
||||||
Result = RegisterMupWorkItem.Result;
|
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
|
FspMupUnregister(FspFsmupDeviceObject, FsvolDeviceObject);
|
||||||
FspDeviceDereference(FsvolDeviceObject);
|
FspDeviceDereference(FsvolDeviceObject);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@ -275,18 +260,6 @@ static NTSTATUS FspVolumeCreateNoLock(
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID FspVolumeCreateRegisterMup(PVOID Context)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
FSP_CREATE_VOLUME_REGISTER_MUP_WORK_ITEM *RegisterMupWorkItem = Context;
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject = RegisterMupWorkItem->FsvolDeviceObject;
|
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
|
||||||
|
|
||||||
RegisterMupWorkItem->Result = FsRtlRegisterUncProviderEx(&FsvolDeviceExtension->MupHandle,
|
|
||||||
&FsvolDeviceExtension->VolumeName, FsvolDeviceObject, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID FspVolumeDelete(
|
VOID FspVolumeDelete(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
@ -333,7 +306,7 @@ static VOID FspVolumeDeleteNoLock(
|
|||||||
/* stop the I/O queue */
|
/* stop the I/O queue */
|
||||||
FspIoqStop(FsvolDeviceExtension->Ioq);
|
FspIoqStop(FsvolDeviceExtension->Ioq);
|
||||||
|
|
||||||
/* do we have a virtual disk device or a MUP handle? */
|
/* do we have a virtual disk device or are we registered with fsmup? */
|
||||||
if (0 != FsvolDeviceExtension->FsvrtDeviceObject)
|
if (0 != FsvolDeviceExtension->FsvrtDeviceObject)
|
||||||
{
|
{
|
||||||
PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject;
|
PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject;
|
||||||
@ -391,10 +364,10 @@ static VOID FspVolumeDeleteNoLock(
|
|||||||
FspQueueDelayedWorkItem(&FsvolDeviceExtension->DeleteVolumeDelayedWorkItem, Delay);
|
FspQueueDelayedWorkItem(&FsvolDeviceExtension->DeleteVolumeDelayedWorkItem, Delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (0 != FsvolDeviceExtension->MupHandle)
|
else
|
||||||
{
|
{
|
||||||
FsRtlDeregisterUncProvider(FsvolDeviceExtension->MupHandle);
|
IoDeleteSymbolicLink(&FsvolDeviceExtension->VolumeName);
|
||||||
FsvolDeviceExtension->MupHandle = 0;
|
FspMupUnregister(FspFsmupDeviceObject, FsvolDeviceObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* release the volume device object */
|
/* release the volume device object */
|
||||||
@ -515,49 +488,6 @@ static NTSTATUS FspVolumeMountNoLock(
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FspVolumeRedirQueryPathEx(
|
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
ASSERT(IRP_MJ_DEVICE_CONTROL == IrpSp->MajorFunction);
|
|
||||||
ASSERT(IOCTL_REDIR_QUERY_PATH_EX == IrpSp->Parameters.DeviceIoControl.IoControlCode);
|
|
||||||
|
|
||||||
if (KernelMode != Irp->RequestorMode)
|
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
|
||||||
|
|
||||||
/* check parameters */
|
|
||||||
ULONG InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
|
||||||
ULONG OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
|
||||||
QUERY_PATH_REQUEST_EX *QueryPathRequest = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
|
|
||||||
QUERY_PATH_RESPONSE *QueryPathResponse = Irp->UserBuffer;
|
|
||||||
if (sizeof(QUERY_PATH_REQUEST_EX) > InputBufferLength ||
|
|
||||||
0 == QueryPathRequest || 0 == QueryPathResponse)
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
if (sizeof(QUERY_PATH_RESPONSE) > OutputBufferLength)
|
|
||||||
return STATUS_BUFFER_TOO_SMALL;
|
|
||||||
|
|
||||||
NTSTATUS Result;
|
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
|
||||||
|
|
||||||
Result = STATUS_BAD_NETWORK_PATH;
|
|
||||||
if (!FspIoqStopped(FsvolDeviceExtension->Ioq))
|
|
||||||
{
|
|
||||||
if (0 < FsvolDeviceExtension->VolumePrefix.Length &&
|
|
||||||
FspFsvolDeviceVolumePrefixInString(FsvolDeviceObject, &QueryPathRequest->PathName) &&
|
|
||||||
(QueryPathRequest->PathName.Length == FsvolDeviceExtension->VolumePrefix.Length ||
|
|
||||||
'\\' == QueryPathRequest->PathName.Buffer[FsvolDeviceExtension->VolumePrefix.Length / sizeof(WCHAR)]))
|
|
||||||
{
|
|
||||||
QueryPathResponse->LengthAccepted = FsvolDeviceExtension->VolumePrefix.Length;
|
|
||||||
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
Result = STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS FspVolumeGetName(
|
NTSTATUS FspVolumeGetName(
|
||||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user