mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 08:53:01 -05:00
sys: check and remove volume prefix when mounted as a network file system
This commit is contained in:
parent
e8eccef80a
commit
e2e96322f3
@ -169,12 +169,13 @@ static NTSTATUS FspFsvolCreate(
|
|||||||
|
|
||||||
/* check for trailing backslash */
|
/* check for trailing backslash */
|
||||||
if (sizeof(WCHAR) * 2/* not empty or root */ <= FileName.Length &&
|
if (sizeof(WCHAR) * 2/* not empty or root */ <= FileName.Length &&
|
||||||
L'\\' == FileName.Buffer[FileName.Length / 2 - 1])
|
L'\\' == FileName.Buffer[FileName.Length / sizeof(WCHAR) - 1])
|
||||||
{
|
{
|
||||||
FileName.Length -= sizeof(WCHAR);
|
FileName.Length -= sizeof(WCHAR);
|
||||||
HasTrailingBackslash = TRUE;
|
HasTrailingBackslash = TRUE;
|
||||||
|
|
||||||
if (sizeof(WCHAR) * 2 <= FileName.Length && L'\\' == FileName.Buffer[FileName.Length / 2 - 1])
|
if (sizeof(WCHAR) * 2 <= FileName.Length &&
|
||||||
|
L'\\' == FileName.Buffer[FileName.Length / sizeof(WCHAR) - 1])
|
||||||
return STATUS_OBJECT_NAME_INVALID;
|
return STATUS_OBJECT_NAME_INVALID;
|
||||||
}
|
}
|
||||||
if (HasTrailingBackslash && !FlagOn(CreateOptions, FILE_DIRECTORY_FILE))
|
if (HasTrailingBackslash && !FlagOn(CreateOptions, FILE_DIRECTORY_FILE))
|
||||||
@ -260,6 +261,23 @@ static NTSTATUS FspFsvolCreate(
|
|||||||
Result = RtlAppendUnicodeStringToString(&FileNode->FileName, &FileName);
|
Result = RtlAppendUnicodeStringToString(&FileNode->FileName, &FileName);
|
||||||
ASSERT(NT_SUCCESS(Result));
|
ASSERT(NT_SUCCESS(Result));
|
||||||
|
|
||||||
|
/* check and remove any volume prefix */
|
||||||
|
if (0 < FsvolDeviceExtension->VolumePrefix.Length)
|
||||||
|
{
|
||||||
|
if (FileNode->FileName.Length <= FsvolDeviceExtension->VolumePrefix.Length ||
|
||||||
|
!RtlEqualMemory(FileNode->FileName.Buffer, FsvolDeviceExtension->VolumePrefix.Buffer,
|
||||||
|
FsvolDeviceExtension->VolumePrefix.Length) ||
|
||||||
|
'\\' != FileNode->FileName.Buffer[FsvolDeviceExtension->VolumePrefix.Length / sizeof(WCHAR)])
|
||||||
|
{
|
||||||
|
FspFileNodeDereference(FileNode);
|
||||||
|
return STATUS_OBJECT_PATH_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileNode->FileName.Length -= FsvolDeviceExtension->VolumePrefix.Length;
|
||||||
|
FileNode->FileName.MaximumLength -= FsvolDeviceExtension->VolumePrefix.Length;
|
||||||
|
FileNode->FileName.Buffer += FsvolDeviceExtension->VolumePrefix.Length / sizeof(WCHAR);
|
||||||
|
}
|
||||||
|
|
||||||
Result = FspFileDescCreate(&FileDesc);
|
Result = FspFileDescCreate(&FileDesc);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
|
@ -451,6 +451,7 @@ typedef struct
|
|||||||
FSP_DELAYED_WORK_ITEM DeleteVolumeDelayedWorkItem;
|
FSP_DELAYED_WORK_ITEM DeleteVolumeDelayedWorkItem;
|
||||||
ERESOURCE DeleteResource;
|
ERESOURCE DeleteResource;
|
||||||
FSP_FSCTL_VOLUME_PARAMS VolumeParams;
|
FSP_FSCTL_VOLUME_PARAMS VolumeParams;
|
||||||
|
UNICODE_STRING VolumePrefix;
|
||||||
FSP_IOQ *Ioq;
|
FSP_IOQ *Ioq;
|
||||||
KSPIN_LOCK ExpirationLock;
|
KSPIN_LOCK ExpirationLock;
|
||||||
WORK_QUEUE_ITEM ExpirationWorkItem;
|
WORK_QUEUE_ITEM ExpirationWorkItem;
|
||||||
|
@ -102,7 +102,7 @@ NTSTATUS FspVolumeCreate(
|
|||||||
VolumeParams.IrpCapacity = FspFsctlIrpCapacityDefault;
|
VolumeParams.IrpCapacity = FspFsctlIrpCapacityDefault;
|
||||||
if (FILE_DEVICE_NETWORK_FILE_SYSTEM == FsctlDeviceObject->DeviceType)
|
if (FILE_DEVICE_NETWORK_FILE_SYSTEM == FsctlDeviceObject->DeviceType)
|
||||||
{
|
{
|
||||||
VolumeParams.Prefix[sizeof VolumeParams.Prefix / 2 - 1] = L'\0';
|
VolumeParams.Prefix[sizeof VolumeParams.Prefix / sizeof(WCHAR) - 1] = L'\0';
|
||||||
for (; L'\0' != VolumeParams.Prefix[PrefixLength]; PrefixLength++)
|
for (; L'\0' != VolumeParams.Prefix[PrefixLength]; PrefixLength++)
|
||||||
;
|
;
|
||||||
for (; 0 < PrefixLength && L'\\' == VolumeParams.Prefix[PrefixLength - 1]; PrefixLength--)
|
for (; 0 < PrefixLength && L'\\' == VolumeParams.Prefix[PrefixLength - 1]; PrefixLength--)
|
||||||
@ -155,6 +155,9 @@ NTSTATUS FspVolumeCreate(
|
|||||||
FsvolDeviceExtension->FsctlDeviceObject = FsctlDeviceObject;
|
FsvolDeviceExtension->FsctlDeviceObject = FsctlDeviceObject;
|
||||||
FsvolDeviceExtension->FsvrtDeviceObject = FsvrtDeviceObject;
|
FsvolDeviceExtension->FsvrtDeviceObject = FsvrtDeviceObject;
|
||||||
FsvolDeviceExtension->VolumeParams = VolumeParams;
|
FsvolDeviceExtension->VolumeParams = VolumeParams;
|
||||||
|
if (FILE_DEVICE_NETWORK_FILE_SYSTEM == FsctlDeviceObject->DeviceType)
|
||||||
|
RtlInitUnicodeString(&FsvolDeviceExtension->VolumePrefix,
|
||||||
|
FsvolDeviceExtension->VolumeParams.Prefix);
|
||||||
RtlInitEmptyUnicodeString(&FsvolDeviceExtension->VolumeName,
|
RtlInitEmptyUnicodeString(&FsvolDeviceExtension->VolumeName,
|
||||||
FsvolDeviceExtension->VolumeNameBuf, sizeof FsvolDeviceExtension->VolumeNameBuf);
|
FsvolDeviceExtension->VolumeNameBuf, sizeof FsvolDeviceExtension->VolumeNameBuf);
|
||||||
RtlCopyUnicodeString(&FsvolDeviceExtension->VolumeName, &VolumeName);
|
RtlCopyUnicodeString(&FsvolDeviceExtension->VolumeName, &VolumeName);
|
||||||
@ -424,7 +427,6 @@ NTSTATUS FspVolumeRedirQueryPathEx(
|
|||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject);
|
||||||
UNICODE_STRING Prefix;
|
|
||||||
|
|
||||||
/* acquire our DeleteResource */
|
/* acquire our DeleteResource */
|
||||||
ExAcquireResourceExclusiveLite(&FsvolDeviceExtension->DeleteResource, TRUE);
|
ExAcquireResourceExclusiveLite(&FsvolDeviceExtension->DeleteResource, TRUE);
|
||||||
@ -432,13 +434,14 @@ NTSTATUS FspVolumeRedirQueryPathEx(
|
|||||||
Result = STATUS_BAD_NETWORK_PATH;
|
Result = STATUS_BAD_NETWORK_PATH;
|
||||||
if (!FspIoqStopped(FsvolDeviceExtension->Ioq))
|
if (!FspIoqStopped(FsvolDeviceExtension->Ioq))
|
||||||
{
|
{
|
||||||
RtlInitUnicodeString(&Prefix, FsvolDeviceExtension->VolumeParams.Prefix);
|
if (0 < FsvolDeviceExtension->VolumePrefix.Length &&
|
||||||
if (Prefix.Length <= QueryPathRequest->PathName.Length &&
|
QueryPathRequest->PathName.Length >= FsvolDeviceExtension->VolumePrefix.Length &&
|
||||||
RtlEqualMemory(Prefix.Buffer, QueryPathRequest->PathName.Buffer, Prefix.Length) &&
|
RtlEqualMemory(QueryPathRequest->PathName.Buffer,
|
||||||
(Prefix.Length == QueryPathRequest->PathName.Length ||
|
FsvolDeviceExtension->VolumePrefix.Buffer, FsvolDeviceExtension->VolumePrefix.Length) &&
|
||||||
'\\' == QueryPathRequest->PathName.Buffer[Prefix.Length / 2]))
|
(QueryPathRequest->PathName.Length == FsvolDeviceExtension->VolumePrefix.Length ||
|
||||||
|
'\\' == QueryPathRequest->PathName.Buffer[FsvolDeviceExtension->VolumePrefix.Length / sizeof(WCHAR)]))
|
||||||
{
|
{
|
||||||
QueryPathResponse->LengthAccepted = Prefix.Length;
|
QueryPathResponse->LengthAccepted = FsvolDeviceExtension->VolumePrefix.Length;
|
||||||
|
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
@ -107,7 +107,7 @@ void create_test(void)
|
|||||||
{
|
{
|
||||||
if (WinFspDiskTests)
|
if (WinFspDiskTests)
|
||||||
create_dotest(MemfsDisk, 0);
|
create_dotest(MemfsDisk, 0);
|
||||||
if (0 && WinFspNetTests)
|
if (WinFspNetTests)
|
||||||
create_dotest(MemfsNet, L"\\\\memfs\\share");
|
create_dotest(MemfsNet, L"\\\\memfs\\share");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,7 +211,7 @@ void create_sd_test(void)
|
|||||||
{
|
{
|
||||||
if (WinFspDiskTests)
|
if (WinFspDiskTests)
|
||||||
create_sd_dotest(MemfsDisk, 0);
|
create_sd_dotest(MemfsDisk, 0);
|
||||||
if (0 && WinFspNetTests)
|
if (WinFspNetTests)
|
||||||
create_sd_dotest(MemfsNet, L"\\\\memfs\\share");
|
create_sd_dotest(MemfsNet, L"\\\\memfs\\share");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,7 +279,7 @@ void create_share_test(void)
|
|||||||
{
|
{
|
||||||
if (WinFspDiskTests)
|
if (WinFspDiskTests)
|
||||||
create_share_dotest(MemfsDisk, 0);
|
create_share_dotest(MemfsDisk, 0);
|
||||||
if (0 && WinFspNetTests)
|
if (WinFspNetTests)
|
||||||
create_share_dotest(MemfsNet, L"\\\\memfs\\share");
|
create_share_dotest(MemfsNet, L"\\\\memfs\\share");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ static unsigned __stdcall mount_volume_cancel_dotest_thread(void *FilePath)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mount_volume_cancel_dotest(PWSTR DeviceName)
|
void mount_volume_cancel_dotest(PWSTR DeviceName, PWSTR Prefix)
|
||||||
{
|
{
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
BOOL Success;
|
BOOL Success;
|
||||||
@ -107,11 +107,12 @@ void mount_volume_cancel_dotest(PWSTR DeviceName)
|
|||||||
ASSERT(0 == wcsncmp(L"\\Device\\Volume{", VolumeName, 15));
|
ASSERT(0 == wcsncmp(L"\\Device\\Volume{", VolumeName, 15));
|
||||||
ASSERT(INVALID_HANDLE_VALUE != VolumeHandle);
|
ASSERT(INVALID_HANDLE_VALUE != VolumeHandle);
|
||||||
|
|
||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"\\\\?\\GLOBALROOT%s\\file0", VolumeName);
|
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0",
|
||||||
|
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : VolumeName);
|
||||||
Thread = (HANDLE)_beginthreadex(0, 0, mount_volume_cancel_dotest_thread, FilePath, 0, 0);
|
Thread = (HANDLE)_beginthreadex(0, 0, mount_volume_cancel_dotest_thread, FilePath, 0, 0);
|
||||||
ASSERT(0 != Thread);
|
ASSERT(0 != Thread);
|
||||||
|
|
||||||
Sleep(1000); /* give some time to the thread to execute */
|
Sleep(0 == Prefix ? 1000 : 5000); /* give some time to the thread to execute */
|
||||||
|
|
||||||
Success = CloseHandle(VolumeHandle);
|
Success = CloseHandle(VolumeHandle);
|
||||||
ASSERT(Success);
|
ASSERT(Success);
|
||||||
@ -126,9 +127,9 @@ void mount_volume_cancel_dotest(PWSTR DeviceName)
|
|||||||
void mount_volume_cancel_test(void)
|
void mount_volume_cancel_test(void)
|
||||||
{
|
{
|
||||||
if (WinFspDiskTests)
|
if (WinFspDiskTests)
|
||||||
mount_volume_cancel_dotest(L"WinFsp.Disk");
|
mount_volume_cancel_dotest(L"WinFsp.Disk", 0);
|
||||||
if (WinFspNetTests)
|
if (WinFspNetTests)
|
||||||
mount_volume_cancel_dotest(L"WinFsp.Net");
|
mount_volume_cancel_dotest(L"WinFsp.Net", L"\\\\winfsp-tests\\share");
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned __stdcall mount_volume_transact_dotest_thread(void *FilePath)
|
static unsigned __stdcall mount_volume_transact_dotest_thread(void *FilePath)
|
||||||
@ -210,9 +211,7 @@ void mount_volume_transact_dotest(PWSTR DeviceName, PWSTR Prefix)
|
|||||||
ASSERT(!Request->Req.Create.CaseSensitive);
|
ASSERT(!Request->Req.Create.CaseSensitive);
|
||||||
ASSERT(0 == Request->FileName.Offset);
|
ASSERT(0 == Request->FileName.Offset);
|
||||||
ASSERT((wcslen((PVOID)Request->Buffer) + 1) * sizeof(WCHAR) == Request->FileName.Size);
|
ASSERT((wcslen((PVOID)Request->Buffer) + 1) * sizeof(WCHAR) == Request->FileName.Size);
|
||||||
ASSERT(
|
ASSERT(0 == wcscmp((PVOID)Request->Buffer, L"\\file0"));
|
||||||
0 == wcscmp((PVOID)Request->Buffer, L"\\file0") ||
|
|
||||||
0 == wcscmp((PVOID)Request->Buffer, FilePath + 1));
|
|
||||||
|
|
||||||
ASSERT(FspFsctlTransactCanProduceResponse(Response, ResponseBufEnd));
|
ASSERT(FspFsctlTransactCanProduceResponse(Response, ResponseBufEnd));
|
||||||
|
|
||||||
@ -250,11 +249,8 @@ void mount_volume_transact_test(void)
|
|||||||
if (WinFspDiskTests)
|
if (WinFspDiskTests)
|
||||||
mount_volume_transact_dotest(L"WinFsp.Disk", 0);
|
mount_volume_transact_dotest(L"WinFsp.Disk", 0);
|
||||||
if (WinFspNetTests)
|
if (WinFspNetTests)
|
||||||
{
|
|
||||||
mount_volume_transact_dotest(L"WinFsp.Net", 0);
|
|
||||||
mount_volume_transact_dotest(L"WinFsp.Net", L"\\\\winfsp-tests\\share");
|
mount_volume_transact_dotest(L"WinFsp.Net", L"\\\\winfsp-tests\\share");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void mount_tests(void)
|
void mount_tests(void)
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,7 @@ static unsigned __stdcall timeout_pending_dotest_thread2(void *FilePath)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void timeout_pending_dotest(PWSTR DeviceName)
|
void timeout_pending_dotest(PWSTR DeviceName, PWSTR Prefix)
|
||||||
{
|
{
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
BOOL Success;
|
BOOL Success;
|
||||||
@ -45,6 +45,7 @@ void timeout_pending_dotest(PWSTR DeviceName)
|
|||||||
HANDLE Thread;
|
HANDLE Thread;
|
||||||
DWORD ExitCode;
|
DWORD ExitCode;
|
||||||
|
|
||||||
|
VolumeParams.TransactTimeout = 10000; /* allow for longer transact timeout to handle MUP redir */
|
||||||
VolumeParams.IrpTimeout = FspFsctlIrpTimeoutDebug;
|
VolumeParams.IrpTimeout = FspFsctlIrpTimeoutDebug;
|
||||||
VolumeParams.SectorSize = 16384;
|
VolumeParams.SectorSize = 16384;
|
||||||
VolumeParams.SerialNumber = 0x12345678;
|
VolumeParams.SerialNumber = 0x12345678;
|
||||||
@ -55,7 +56,8 @@ void timeout_pending_dotest(PWSTR DeviceName)
|
|||||||
ASSERT(0 == wcsncmp(L"\\Device\\Volume{", VolumeName, 15));
|
ASSERT(0 == wcsncmp(L"\\Device\\Volume{", VolumeName, 15));
|
||||||
ASSERT(INVALID_HANDLE_VALUE != VolumeHandle);
|
ASSERT(INVALID_HANDLE_VALUE != VolumeHandle);
|
||||||
|
|
||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"\\\\?\\GLOBALROOT%s\\file0", VolumeName);
|
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0",
|
||||||
|
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : VolumeName);
|
||||||
Thread = (HANDLE)_beginthreadex(0, 0, timeout_pending_dotest_thread, FilePath, 0, 0);
|
Thread = (HANDLE)_beginthreadex(0, 0, timeout_pending_dotest_thread, FilePath, 0, 0);
|
||||||
ASSERT(0 != Thread);
|
ASSERT(0 != Thread);
|
||||||
|
|
||||||
@ -126,9 +128,9 @@ void timeout_pending_dotest(PWSTR DeviceName)
|
|||||||
void timeout_pending_test(void)
|
void timeout_pending_test(void)
|
||||||
{
|
{
|
||||||
if (WinFspDiskTests)
|
if (WinFspDiskTests)
|
||||||
timeout_pending_dotest(L"WinFsp.Disk");
|
timeout_pending_dotest(L"WinFsp.Disk", 0);
|
||||||
if (WinFspNetTests)
|
if (WinFspNetTests)
|
||||||
timeout_pending_dotest(L"WinFsp.Net");
|
timeout_pending_dotest(L"WinFsp.Net", L"\\\\winfsp-tests\\share");
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned __stdcall timeout_transact_dotest_thread(void *FilePath)
|
static unsigned __stdcall timeout_transact_dotest_thread(void *FilePath)
|
||||||
@ -144,7 +146,7 @@ static unsigned __stdcall timeout_transact_dotest_thread(void *FilePath)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void timeout_transact_dotest(PWSTR DeviceName)
|
void timeout_transact_dotest(PWSTR DeviceName, PWSTR Prefix)
|
||||||
{
|
{
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
BOOL Success;
|
BOOL Success;
|
||||||
@ -155,7 +157,7 @@ void timeout_transact_dotest(PWSTR DeviceName)
|
|||||||
HANDLE Thread;
|
HANDLE Thread;
|
||||||
DWORD ExitCode;
|
DWORD ExitCode;
|
||||||
|
|
||||||
VolumeParams.TransactTimeout = 1000;
|
VolumeParams.TransactTimeout = 0 != Prefix ? 1000 : 5000;
|
||||||
VolumeParams.SectorSize = 16384;
|
VolumeParams.SectorSize = 16384;
|
||||||
VolumeParams.SerialNumber = 0x12345678;
|
VolumeParams.SerialNumber = 0x12345678;
|
||||||
wcscpy_s(VolumeParams.Prefix, sizeof VolumeParams.Prefix / sizeof(WCHAR), L"\\winfsp-tests\\share");
|
wcscpy_s(VolumeParams.Prefix, sizeof VolumeParams.Prefix / sizeof(WCHAR), L"\\winfsp-tests\\share");
|
||||||
@ -181,7 +183,8 @@ void timeout_transact_dotest(PWSTR DeviceName)
|
|||||||
ASSERT(STATUS_SUCCESS == Result);
|
ASSERT(STATUS_SUCCESS == Result);
|
||||||
ASSERT(0 == RequestBufSize);
|
ASSERT(0 == RequestBufSize);
|
||||||
|
|
||||||
StringCbPrintfW(FilePath, sizeof FilePath, L"\\\\?\\GLOBALROOT%s\\file0", VolumeName);
|
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\file0",
|
||||||
|
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : VolumeName);
|
||||||
Thread = (HANDLE)_beginthreadex(0, 0, timeout_transact_dotest_thread, FilePath, 0, 0);
|
Thread = (HANDLE)_beginthreadex(0, 0, timeout_transact_dotest_thread, FilePath, 0, 0);
|
||||||
ASSERT(0 != Thread);
|
ASSERT(0 != Thread);
|
||||||
|
|
||||||
@ -232,9 +235,9 @@ void timeout_transact_dotest(PWSTR DeviceName)
|
|||||||
void timeout_transact_test(void)
|
void timeout_transact_test(void)
|
||||||
{
|
{
|
||||||
if (WinFspDiskTests)
|
if (WinFspDiskTests)
|
||||||
timeout_transact_dotest(L"WinFsp.Disk");
|
timeout_transact_dotest(L"WinFsp.Disk", 0);
|
||||||
if (WinFspNetTests)
|
if (WinFspNetTests)
|
||||||
timeout_transact_dotest(L"WinFsp.Net");
|
timeout_transact_dotest(L"WinFsp.Net", L"\\\\winfsp-tests\\share");
|
||||||
}
|
}
|
||||||
|
|
||||||
void timeout_tests(void)
|
void timeout_tests(void)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user