diff --git a/build/VStudio/winfsp_sys.vcxproj b/build/VStudio/winfsp_sys.vcxproj
index 6fcfd949..3f23fcfd 100644
--- a/build/VStudio/winfsp_sys.vcxproj
+++ b/build/VStudio/winfsp_sys.vcxproj
@@ -173,6 +173,7 @@
+
diff --git a/build/VStudio/winfsp_sys.vcxproj.filters b/build/VStudio/winfsp_sys.vcxproj.filters
index eb0c4f04..3bad7aa5 100644
--- a/build/VStudio/winfsp_sys.vcxproj.filters
+++ b/build/VStudio/winfsp_sys.vcxproj.filters
@@ -101,6 +101,9 @@
Source
+
+ Source
+
diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h
index 05012ee7..0be90c8b 100644
--- a/inc/winfsp/fsctl.h
+++ b/inc/winfsp/fsctl.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 =
diff --git a/src/sys/create.c b/src/sys/create.c
index 51a5bbcb..5ffd55c3 100644
--- a/src/sys/create.c
+++ b/src/sys/create.c
@@ -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;
}
diff --git a/src/sys/debug.c b/src/sys/debug.c
index b8fd16da..de02b586 100644
--- a/src/sys/debug.c
+++ b/src/sys/debug.c
@@ -281,6 +281,8 @@ const char *DeviceExtensionKindSym(UINT32 Kind)
{
case FspFsctlDeviceExtensionKind:
return "Ctl";
+ case FspFsmupDeviceExtensionKind:
+ return "Mup";
case FspFsvrtDeviceExtensionKind:
return "Vrt";
case FspFsvolDeviceExtensionKind:
diff --git a/src/sys/devctl.c b/src/sys/devctl.c
index 7ff68c76..a076ec63 100644
--- a/src/sys/devctl.c
+++ b/src/sys/devctl.c
@@ -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(
diff --git a/src/sys/device.c b/src/sys/device.c
index 489d967d..68f3b3a5 100644
--- a/src/sys/device.c
+++ b/src/sys/device.c
@@ -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)
{
diff --git a/src/sys/driver.c b/src/sys/driver.c
index 31ffe1d9..9151cfab 100644
--- a/src/sys/driver.c
+++ b/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;
diff --git a/src/sys/driver.h b/src/sys/driver.h
index afb5f5e3..91519f2a 100644
--- a/src/sys/driver.h
+++ b/src/sys/driver.h
@@ -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[];
diff --git a/src/sys/mup.c b/src/sys/mup.c
new file mode 100644
index 00000000..ecc8431c
--- /dev/null
+++ b/src/sys/mup.c
@@ -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
+
+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;
+}
diff --git a/src/sys/shutdown.c b/src/sys/shutdown.c
index 576014e8..0cbd3485 100644
--- a/src/sys/shutdown.c
+++ b/src/sys/shutdown.c
@@ -17,45 +17,18 @@
#include
-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", "");
}
diff --git a/src/sys/volume.c b/src/sys/volume.c
index 4c0b30a7..4be4ec45 100644
--- a/src/sys/volume.c
+++ b/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)
{