mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -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\lockctl.c" />
|
||||
<ClCompile Include="..\..\src\sys\meta.c" />
|
||||
<ClCompile Include="..\..\src\sys\mup.c" />
|
||||
<ClCompile Include="..\..\src\sys\name.c" />
|
||||
<ClCompile Include="..\..\src\sys\psbuffer.c" />
|
||||
<ClCompile Include="..\..\src\sys\read.c" />
|
||||
|
@ -101,6 +101,9 @@
|
||||
<ClCompile Include="..\..\src\sys\psbuffer.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\sys\mup.c">
|
||||
<Filter>Source</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\sys\driver.h">
|
||||
|
@ -34,6 +34,7 @@ extern "C" {
|
||||
#define FSP_FSCTL_DRIVER_NAME "WinFsp"
|
||||
#define FSP_FSCTL_DISK_DEVICE_NAME "WinFsp.Disk"
|
||||
#define FSP_FSCTL_NET_DEVICE_NAME "WinFsp.Net"
|
||||
#define FSP_FSCTL_MUP_DEVICE_NAME "WinFsp.Mup"
|
||||
|
||||
// {6F9D25FA-6DEE-4A9D-80F5-E98E14F35E54}
|
||||
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")
|
||||
FileObject->Vpb = FsvolDeviceExtension->FsvrtDeviceObject->Vpb;
|
||||
|
||||
FileObject->FsContext2 = FsvolDeviceObject;
|
||||
|
||||
Irp->IoStatus.Information = FILE_OPENED;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -281,6 +281,8 @@ const char *DeviceExtensionKindSym(UINT32 Kind)
|
||||
{
|
||||
case FspFsctlDeviceExtensionKind:
|
||||
return "Ctl";
|
||||
case FspFsmupDeviceExtensionKind:
|
||||
return "Mup";
|
||||
case FspFsvrtDeviceExtensionKind:
|
||||
return "Vrt";
|
||||
case FspFsvolDeviceExtensionKind:
|
||||
|
@ -33,15 +33,7 @@ static NTSTATUS FspFsvolDeviceControl(
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
NTSTATUS Result = STATUS_INVALID_DEVICE_REQUEST;
|
||||
switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
|
||||
{
|
||||
case IOCTL_REDIR_QUERY_PATH_EX :
|
||||
Result = FspVolumeRedirQueryPathEx(DeviceObject, Irp, IrpSp);
|
||||
break;
|
||||
}
|
||||
|
||||
return Result;
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
|
||||
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);
|
||||
VOID FspFsvolDeviceSetVolumeInfo(PDEVICE_OBJECT DeviceObject, const FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||
VOID FspFsvolDeviceInvalidateVolumeInfo(PDEVICE_OBJECT DeviceObject);
|
||||
static NTSTATUS FspFsmupDeviceInit(PDEVICE_OBJECT DeviceObject);
|
||||
static VOID FspFsmupDeviceFini(PDEVICE_OBJECT DeviceObject);
|
||||
NTSTATUS FspDeviceCopyList(
|
||||
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount);
|
||||
VOID FspDeviceDeleteList(
|
||||
@ -94,6 +96,8 @@ VOID FspDeviceDeleteAll(VOID);
|
||||
#pragma alloc_text(PAGE, FspFsvolDeviceCompareContextByName)
|
||||
#pragma alloc_text(PAGE, FspFsvolDeviceAllocateContextByName)
|
||||
#pragma alloc_text(PAGE, FspFsvolDeviceFreeContextByName)
|
||||
#pragma alloc_text(PAGE, FspFsmupDeviceInit)
|
||||
#pragma alloc_text(PAGE, FspFsmupDeviceFini)
|
||||
#pragma alloc_text(PAGE, FspDeviceCopyList)
|
||||
#pragma alloc_text(PAGE, FspDeviceDeleteList)
|
||||
#pragma alloc_text(PAGE, FspDeviceDeleteAll)
|
||||
@ -118,6 +122,9 @@ NTSTATUS FspDeviceCreateSecure(UINT32 Kind, ULONG ExtraSize,
|
||||
case FspFsvolDeviceExtensionKind:
|
||||
DeviceExtensionSize = sizeof(FSP_FSVOL_DEVICE_EXTENSION);
|
||||
break;
|
||||
case FspFsmupDeviceExtensionKind:
|
||||
DeviceExtensionSize = sizeof(FSP_FSMUP_DEVICE_EXTENSION);
|
||||
break;
|
||||
case FspFsvrtDeviceExtensionKind:
|
||||
case FspFsctlDeviceExtensionKind:
|
||||
DeviceExtensionSize = sizeof(FSP_DEVICE_EXTENSION);
|
||||
@ -173,6 +180,9 @@ NTSTATUS FspDeviceInitialize(PDEVICE_OBJECT DeviceObject)
|
||||
case FspFsvolDeviceExtensionKind:
|
||||
Result = FspFsvolDeviceInit(DeviceObject);
|
||||
break;
|
||||
case FspFsmupDeviceExtensionKind:
|
||||
Result = FspFsmupDeviceInit(DeviceObject);
|
||||
break;
|
||||
case FspFsvrtDeviceExtensionKind:
|
||||
case FspFsctlDeviceExtensionKind:
|
||||
Result = STATUS_SUCCESS;
|
||||
@ -199,6 +209,9 @@ VOID FspDeviceDelete(PDEVICE_OBJECT DeviceObject)
|
||||
case FspFsvolDeviceExtensionKind:
|
||||
FspFsvolDeviceFini(DeviceObject);
|
||||
break;
|
||||
case FspFsmupDeviceExtensionKind:
|
||||
FspFsmupDeviceFini(DeviceObject);
|
||||
break;
|
||||
case FspFsvrtDeviceExtensionKind:
|
||||
case FspFsctlDeviceExtensionKind:
|
||||
break;
|
||||
@ -876,6 +889,37 @@ VOID FspFsvolDeviceInvalidateVolumeInfo(PDEVICE_OBJECT DeviceObject)
|
||||
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(
|
||||
PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount)
|
||||
{
|
||||
|
111
src/sys/driver.c
111
src/sys/driver.c
@ -44,45 +44,6 @@ NTSTATUS DriverEntry(
|
||||
{
|
||||
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 */
|
||||
#if defined(FSP_UNLOAD)
|
||||
DriverObject->DriverUnload = FspUnload;
|
||||
@ -127,7 +88,6 @@ NTSTATUS DriverEntry(
|
||||
FspIopCompleteFunction[IRP_MJ_DIRECTORY_CONTROL] = FspFsvolDirectoryControlComplete;
|
||||
FspIopCompleteFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FspFsvolFileSystemControlComplete;
|
||||
FspIopCompleteFunction[IRP_MJ_DEVICE_CONTROL] = FspFsvolDeviceControlComplete;
|
||||
FspIopCompleteFunction[IRP_MJ_SHUTDOWN] = FspFsvolShutdownComplete;
|
||||
FspIopCompleteFunction[IRP_MJ_LOCK_CONTROL] = FspFsvolLockControlComplete;
|
||||
FspIopCompleteFunction[IRP_MJ_CLEANUP] = FspFsvolCleanupComplete;
|
||||
FspIopCompleteFunction[IRP_MJ_QUERY_SECURITY] = FspFsvolQuerySecurityComplete;
|
||||
@ -169,9 +129,58 @@ NTSTATUS DriverEntry(
|
||||
#pragma prefast(suppress:28175, "We are a filesystem: ok to access FastIoDispatch")
|
||||
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
|
||||
* 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
|
||||
* remains unloadable even if we issue an IoUnregisterFileSystem() call immediately
|
||||
@ -180,6 +189,23 @@ NTSTATUS DriverEntry(
|
||||
*/
|
||||
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")
|
||||
FSP_LEAVE_DRV("DriverName=\"%wZ\", RegistryPath=\"%wZ\"",
|
||||
&DriverObject->DriverName, RegistryPath);
|
||||
@ -213,6 +239,7 @@ VOID FspUnload(
|
||||
|
||||
FspFsctlDiskDeviceObject = 0;
|
||||
FspFsctlNetDeviceObject = 0;
|
||||
FspFsmupDeviceObject = 0;
|
||||
//FspDeviceDeleteAll();
|
||||
|
||||
ExDeleteResourceLite(&FspDeviceGlobalResource);
|
||||
@ -229,6 +256,8 @@ VOID FspUnload(
|
||||
PDRIVER_OBJECT FspDriverObject;
|
||||
PDEVICE_OBJECT FspFsctlDiskDeviceObject;
|
||||
PDEVICE_OBJECT FspFsctlNetDeviceObject;
|
||||
PDEVICE_OBJECT FspFsmupDeviceObject;
|
||||
HANDLE FspMupHandle;
|
||||
FAST_IO_DISPATCH FspFastIoDispatch;
|
||||
CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
|
||||
|
||||
|
@ -180,6 +180,8 @@ VOID FspDebugLogIrp(const char *func, PIRP Irp, NTSTATUS Result);
|
||||
#define FSP_LEAVE_DRV(fmt, ...) \
|
||||
FSP_LEAVE_(FSP_DEBUGLOG_(fmt, " = %s", __VA_ARGS__, NtStatusSym(Result))); return Result
|
||||
#define FSP_ENTER_MJ(...) \
|
||||
if (FspFsmupDeviceExtensionKind == FspDeviceExtension(DeviceObject)->Kind)\
|
||||
return FspMupHandleIrp(DeviceObject, Irp);\
|
||||
NTSTATUS Result = STATUS_SUCCESS; \
|
||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);\
|
||||
BOOLEAN fsp_device_deref = FALSE; \
|
||||
@ -328,7 +330,6 @@ FSP_IOPREP_DISPATCH FspFsvolSetInformationPrepare;
|
||||
FSP_IOCMPL_DISPATCH FspFsvolSetInformationComplete;
|
||||
FSP_IOCMPL_DISPATCH FspFsvolSetSecurityComplete;
|
||||
FSP_IOCMPL_DISPATCH FspFsvolSetVolumeInformationComplete;
|
||||
FSP_IOCMPL_DISPATCH FspFsvolShutdownComplete;
|
||||
FSP_IOPREP_DISPATCH FspFsvolWritePrepare;
|
||||
FSP_IOCMPL_DISPATCH FspFsvolWriteComplete;
|
||||
|
||||
@ -1007,6 +1008,7 @@ typedef struct
|
||||
enum
|
||||
{
|
||||
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}) */
|
||||
FspFsvolDeviceExtensionKind = '\0loV', /* file system volume device (unnamed) */
|
||||
};
|
||||
@ -1023,11 +1025,12 @@ typedef struct
|
||||
InitDoneCtxTab:1, InitDoneTimer:1, InitDoneInfo:1, InitDoneNotify:1, InitDoneStat:1;
|
||||
PDEVICE_OBJECT FsctlDeviceObject;
|
||||
PDEVICE_OBJECT FsvrtDeviceObject;
|
||||
HANDLE MupHandle;
|
||||
PDEVICE_OBJECT FsvolDeviceObject;
|
||||
PVPB SwapVpb;
|
||||
FSP_DELAYED_WORK_ITEM DeleteVolumeDelayedWorkItem;
|
||||
FSP_FSCTL_VOLUME_PARAMS VolumeParams;
|
||||
UNICODE_STRING VolumePrefix;
|
||||
UNICODE_PREFIX_TABLE_ENTRY VolumePrefixEntry;
|
||||
FSP_IOQ *Ioq;
|
||||
FSP_META_CACHE *SecurityCache;
|
||||
FSP_META_CACHE *DirInfoCache;
|
||||
@ -1049,6 +1052,13 @@ typedef struct
|
||||
LIST_ENTRY NotifyList;
|
||||
FSP_STATISTICS *Statistics;
|
||||
} 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
|
||||
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);
|
||||
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,
|
||||
PUNICODE_STRING DeviceName, DEVICE_TYPE DeviceType, ULONG DeviceCharacteristics,
|
||||
PUNICODE_STRING DeviceSddl, LPCGUID DeviceClassGuid,
|
||||
@ -1156,6 +1172,14 @@ BOOLEAN FspQueryDirectoryIrpShouldUseProcessBuffer(PIRP Irp, SIZE_T BufferSize)
|
||||
}
|
||||
#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 */
|
||||
#define FspVolumeTransactEarlyTimeout (1 * 10000ULL)
|
||||
NTSTATUS FspVolumeCreate(
|
||||
@ -1164,8 +1188,6 @@ VOID FspVolumeDelete(
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
NTSTATUS FspVolumeMount(
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
NTSTATUS FspVolumeRedirQueryPathEx(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
NTSTATUS FspVolumeGetName(
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
NTSTATUS FspVolumeGetNameList(
|
||||
@ -1559,6 +1581,8 @@ FSP_MV_CcCoherencyFlushAndPurgeCache(
|
||||
extern PDRIVER_OBJECT FspDriverObject;
|
||||
extern PDEVICE_OBJECT FspFsctlDiskDeviceObject;
|
||||
extern PDEVICE_OBJECT FspFsctlNetDeviceObject;
|
||||
extern PDEVICE_OBJECT FspFsmupDeviceObject;
|
||||
extern HANDLE FspMupHandle;
|
||||
extern FAST_IO_DISPATCH FspFastIoDispatch;
|
||||
extern CACHE_MANAGER_CALLBACKS FspCacheManagerCallbacks;
|
||||
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>
|
||||
|
||||
static NTSTATUS FspFsvolShutdown(
|
||||
PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
FSP_DRIVER_DISPATCH FspShutdown;
|
||||
FSP_IOCMPL_DISPATCH FspFsvolShutdownComplete;
|
||||
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(PAGE, FspFsvolShutdown)
|
||||
#pragma alloc_text(PAGE, FspFsvolShutdownComplete)
|
||||
#pragma alloc_text(PAGE, FspShutdown)
|
||||
#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(
|
||||
PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
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", "");
|
||||
}
|
||||
|
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);
|
||||
static NTSTATUS FspVolumeCreateNoLock(
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
static WORKER_THREAD_ROUTINE FspVolumeCreateRegisterMup;
|
||||
VOID FspVolumeDelete(
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
static VOID FspVolumeDeleteNoLock(
|
||||
@ -31,8 +30,6 @@ NTSTATUS FspVolumeMount(
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
static NTSTATUS FspVolumeMountNoLock(
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
NTSTATUS FspVolumeRedirQueryPathEx(
|
||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
NTSTATUS FspVolumeGetName(
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||
NTSTATUS FspVolumeGetNameList(
|
||||
@ -49,13 +46,11 @@ NTSTATUS FspVolumeWork(
|
||||
#ifdef ALLOC_PRAGMA
|
||||
#pragma alloc_text(PAGE, FspVolumeCreate)
|
||||
#pragma alloc_text(PAGE, FspVolumeCreateNoLock)
|
||||
#pragma alloc_text(PAGE, FspVolumeCreateRegisterMup)
|
||||
// ! #pragma alloc_text(PAGE, FspVolumeDelete)
|
||||
// ! #pragma alloc_text(PAGE, FspVolumeDeleteNoLock)
|
||||
// ! #pragma alloc_text(PAGE, FspVolumeDeleteDelayed)
|
||||
// ! #pragma alloc_text(PAGE, FspVolumeMount)
|
||||
// ! #pragma alloc_text(PAGE, FspVolumeMountNoLock)
|
||||
#pragma alloc_text(PAGE, FspVolumeRedirQueryPathEx)
|
||||
#pragma alloc_text(PAGE, FspVolumeGetName)
|
||||
#pragma alloc_text(PAGE, FspVolumeGetNameList)
|
||||
#pragma alloc_text(PAGE, FspVolumeGetNameListNoLock)
|
||||
@ -67,13 +62,6 @@ NTSTATUS FspVolumeWork(
|
||||
#define PREFIXW L"" FSP_FSCTL_VOLUME_PARAMS_PREFIX
|
||||
#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(
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||
{
|
||||
@ -106,11 +94,11 @@ static NTSTATUS FspVolumeCreateNoLock(
|
||||
GUID Guid;
|
||||
UNICODE_STRING DeviceSddl;
|
||||
UNICODE_STRING VolumeName;
|
||||
UNICODE_STRING FsmupDeviceName;
|
||||
WCHAR VolumeNameBuf[FSP_FSCTL_VOLUME_NAME_SIZE / sizeof(WCHAR)];
|
||||
PDEVICE_OBJECT FsvolDeviceObject;
|
||||
PDEVICE_OBJECT FsvrtDeviceObject;
|
||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension;
|
||||
FSP_CREATE_VOLUME_REGISTER_MUP_WORK_ITEM RegisterMupWorkItem;
|
||||
|
||||
/* check parameters */
|
||||
if (PREFIXW_SIZE + sizeof(FSP_FSCTL_VOLUME_PARAMS) * sizeof(WCHAR) > FileObject->FileName.Length)
|
||||
@ -225,6 +213,7 @@ static NTSTATUS FspVolumeCreateNoLock(
|
||||
FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||
FsvolDeviceExtension->FsctlDeviceObject = FsctlDeviceObject;
|
||||
FsvolDeviceExtension->FsvrtDeviceObject = FsvrtDeviceObject;
|
||||
FsvolDeviceExtension->FsvolDeviceObject = FsvolDeviceObject;
|
||||
FsvolDeviceExtension->VolumeParams = VolumeParams;
|
||||
if (FILE_DEVICE_NETWORK_FILE_SYSTEM == FsctlDeviceObject->DeviceType)
|
||||
RtlInitUnicodeString(&FsvolDeviceExtension->VolumePrefix,
|
||||
@ -245,24 +234,20 @@ static NTSTATUS FspVolumeCreateNoLock(
|
||||
FspDeviceDereference(FsvolDeviceObject);
|
||||
}
|
||||
|
||||
/* do we need to register with MUP? */
|
||||
/* do we need to register with fsmup? */
|
||||
if (0 == FsvrtDeviceObject)
|
||||
{
|
||||
/*
|
||||
* Turns out we cannot call FsRtlRegisterUncProviderEx when the PreviousMode
|
||||
* is UserMode! So we need to somehow switch to KernelMode prior to issuing
|
||||
* the FsRtlRegisterUncProviderEx call. There seems to be no straightforward
|
||||
* way to switch the PreviousMode (no ExSetPreviousMode). So we do it indirectly
|
||||
* by executing a synchronous work item (FspExecuteSynchronousWorkItem).
|
||||
*/
|
||||
RtlZeroMemory(&RegisterMupWorkItem, sizeof RegisterMupWorkItem);
|
||||
RegisterMupWorkItem.FsvolDeviceObject = FsvolDeviceObject;
|
||||
FspInitializeSynchronousWorkItem(&RegisterMupWorkItem.SynchronousWorkItem,
|
||||
FspVolumeCreateRegisterMup, &RegisterMupWorkItem);
|
||||
FspExecuteSynchronousWorkItem(&RegisterMupWorkItem.SynchronousWorkItem);
|
||||
Result = RegisterMupWorkItem.Result;
|
||||
if (!FspMupRegister(FspFsmupDeviceObject, FsvolDeviceObject))
|
||||
{
|
||||
FspDeviceDereference(FsvolDeviceObject);
|
||||
return STATUS_OBJECT_NAME_COLLISION;
|
||||
}
|
||||
|
||||
RtlInitUnicodeString(&FsmupDeviceName, L"\\Device\\" FSP_FSCTL_MUP_DEVICE_NAME);
|
||||
Result = IoCreateSymbolicLink(&FsvolDeviceExtension->VolumeName, &FsmupDeviceName);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
FspMupUnregister(FspFsmupDeviceObject, FsvolDeviceObject);
|
||||
FspDeviceDereference(FsvolDeviceObject);
|
||||
return Result;
|
||||
}
|
||||
@ -275,18 +260,6 @@ static NTSTATUS FspVolumeCreateNoLock(
|
||||
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(
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||
{
|
||||
@ -333,7 +306,7 @@ static VOID FspVolumeDeleteNoLock(
|
||||
/* stop the I/O queue */
|
||||
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)
|
||||
{
|
||||
PDEVICE_OBJECT FsvrtDeviceObject = FsvolDeviceExtension->FsvrtDeviceObject;
|
||||
@ -391,10 +364,10 @@ static VOID FspVolumeDeleteNoLock(
|
||||
FspQueueDelayedWorkItem(&FsvolDeviceExtension->DeleteVolumeDelayedWorkItem, Delay);
|
||||
}
|
||||
}
|
||||
else if (0 != FsvolDeviceExtension->MupHandle)
|
||||
else
|
||||
{
|
||||
FsRtlDeregisterUncProvider(FsvolDeviceExtension->MupHandle);
|
||||
FsvolDeviceExtension->MupHandle = 0;
|
||||
IoDeleteSymbolicLink(&FsvolDeviceExtension->VolumeName);
|
||||
FspMupUnregister(FspFsmupDeviceObject, FsvolDeviceObject);
|
||||
}
|
||||
|
||||
/* release the volume device object */
|
||||
@ -515,49 +488,6 @@ static NTSTATUS FspVolumeMountNoLock(
|
||||
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(
|
||||
PDEVICE_OBJECT FsctlDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user