From aa75d412acfcd39cc6f577777ba74edcf47a6f62 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Mon, 23 May 2016 22:23:47 -0700 Subject: [PATCH] sys: IRP_MJ_QUERY_VOLUME_INFORMATION: FileFsDeviceInformation: always return FILE_DEVICE_DISK to avoid problem with GetFileType failures --- src/sys/volinfo.c | 10 +++++++++- src/sys/volume.c | 3 ++- tools/run-tests.bat | 38 ++++++++++++++++++++++++++---------- tst/winfsp-tests/info-test.c | 16 +++++++++++++++ 4 files changed, 55 insertions(+), 12 deletions(-) diff --git a/src/sys/volinfo.c b/src/sys/volinfo.c index ac15c240..3a7456bc 100644 --- a/src/sys/volinfo.c +++ b/src/sys/volinfo.c @@ -117,7 +117,15 @@ static NTSTATUS FspFsvolQueryFsDeviceInformation( PFILE_FS_DEVICE_INFORMATION Info = (PFILE_FS_DEVICE_INFORMATION)*PBuffer; - Info->DeviceType = FsvolDeviceObject->DeviceType; + /* + * The following value MUST be FILE_DEVICE_DISK or GetFileType fails, + * which has all sorts of interesting consequences (like cmd.exe failing + * to redirect to a file when under a network file system). + * + * See also (which explicitly says to use FILE_DEVICE_DISK for our case): + * https://msdn.microsoft.com/en-us/library/cc232109.aspx + */ + Info->DeviceType = FILE_DEVICE_DISK; Info->Characteristics = FsvolDeviceObject->Characteristics; *PBuffer += sizeof(FILE_FS_DEVICE_INFORMATION); diff --git a/src/sys/volume.c b/src/sys/volume.c index 39f056d2..e7de54cf 100644 --- a/src/sys/volume.c +++ b/src/sys/volume.c @@ -188,7 +188,8 @@ static NTSTATUS FspVolumeCreateNoLock( /* create the volume (and virtual disk) device(s) */ Result = FspDeviceCreate(FspFsvolDeviceExtensionKind, 0, - FsctlDeviceObject->DeviceType, 0, + FsctlDeviceObject->DeviceType, + FILE_DEVICE_DISK_FILE_SYSTEM == FsctlDeviceObject->DeviceType ? 0 : FILE_REMOTE_DEVICE, &FsvolDeviceObject); if (!NT_SUCCESS(Result)) return Result; diff --git a/tools/run-tests.bat b/tools/run-tests.bat index 08aaba85..413a4446 100644 --- a/tools/run-tests.bat +++ b/tools/run-tests.bat @@ -12,12 +12,16 @@ cd build\VStudio if not exist build\%Configuration% echo === No tests found >&2 & goto fail cd build\%Configuration% -launchctl-x64 start memfs64 test \memfs64\test M: >nul -launchctl-x64 start memfs32 test \memfs32\test N: >nul +launchctl-x64 start memfs64 testdsk "" M: >nul +launchctl-x64 start memfs64 testnet \memfs64\test N: >nul +launchctl-x64 start memfs32 testdsk "" O: >nul +launchctl-x64 start memfs32 testnet \memfs32\test P: >nul rem Cannot use timeout under cygwin/mintty: "Input redirection is not supported" waitfor 7BF47D72F6664550B03248ECFE77C7DD /t 3 2>nul cd M: >nul 2>nul || (echo === Unable to find drive M: >&2 & goto fail) cd N: >nul 2>nul || (echo === Unable to find drive N: >&2 & goto fail) +cd O: >nul 2>nul || (echo === Unable to find drive O: >&2 & goto fail) +cd P: >nul 2>nul || (echo === Unable to find drive P: >&2 & goto fail) set testpass=0 set testfail=0 @@ -52,8 +56,10 @@ for %%f in (winfsp-tests-x64 winfsp-tests-x86 :fsx-memfs-x64 :fsx-memfs-x86 :win echo: ) -launchctl-x64 stop memfs64 test >nul -launchctl-x64 stop memfs32 test >nul +launchctl-x64 stop memfs64 testdsk >nul +launchctl-x64 stop memfs64 testnet >nul +launchctl-x64 stop memfs32 testdsk >nul +launchctl-x64 stop memfs32 testnet >nul set /a total=testpass+testfail echo === Total: %testpass%/%total% @@ -66,13 +72,19 @@ exit /b 1 :fsx-memfs-x64 M: -"%ProjRoot%\ext\test\fstools\src\fsx\fsx.exe" -N 1000 test xxxxxx +"%ProjRoot%\ext\test\fstools\src\fsx\fsx.exe" -N 5000 test xxxxxx +if errorlevel 1 goto fail +N: +"%ProjRoot%\ext\test\fstools\src\fsx\fsx.exe" -N 5000 test xxxxxx if errorlevel 1 goto fail exit /b 0 :fsx-memfs-x86 -N: -"%ProjRoot%\ext\test\fstools\src\fsx\fsx.exe" -N 1000 test xxxxxx +O: +"%ProjRoot%\ext\test\fstools\src\fsx\fsx.exe" -N 5000 test xxxxxx +if errorlevel 1 goto fail +P: +"%ProjRoot%\ext\test\fstools\src\fsx\fsx.exe" -N 5000 test xxxxxx if errorlevel 1 goto fail exit /b 0 @@ -80,10 +92,16 @@ exit /b 0 M: call "%ProjRoot%\ext\test\winfstest\run-winfstest.bat" base if errorlevel 1 goto fail -exit /b 0 - -:winfstest-memfs-x86 N: call "%ProjRoot%\ext\test\winfstest\run-winfstest.bat" base if errorlevel 1 goto fail exit /b 0 + +:winfstest-memfs-x86 +O: +call "%ProjRoot%\ext\test\winfstest\run-winfstest.bat" base +if errorlevel 1 goto fail +P: +call "%ProjRoot%\ext\test\winfstest\run-winfstest.bat" base +if errorlevel 1 goto fail +exit /b 0 diff --git a/tst/winfsp-tests/info-test.c b/tst/winfsp-tests/info-test.c index 9ba0e7d5..6113002b 100644 --- a/tst/winfsp-tests/info-test.c +++ b/tst/winfsp-tests/info-test.c @@ -508,6 +508,7 @@ void getvolinfo_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout) ULARGE_INTEGER CallerFreeBytes; ULARGE_INTEGER TotalBytes; ULARGE_INTEGER FreeBytes; + HANDLE Handle; StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); @@ -532,6 +533,21 @@ void getvolinfo_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout) Success = GetDiskFreeSpaceExW(FilePath, &CallerFreeBytes, &TotalBytes, &FreeBytes); ASSERT(Success); +#if 0 + UINT DriveType = GetDriveTypeW(FilePath); + ASSERT( + ((0 == Prefix || L'\\' != Prefix[0]) && DRIVE_FIXED == DriveType) || + ((0 != Prefix && L'\\' == Prefix[0]) && DRIVE_REMOTE == DriveType)); +#endif + + Handle = CreateFileW(FilePath, + 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, 0); + ASSERT(INVALID_HANDLE_VALUE != Handle); + DWORD FileType = GetFileType(Handle); + ASSERT(FILE_TYPE_DISK == FileType); + CloseHandle(Handle); + memfs_stop(memfs); }