diff --git a/build/VStudio/testing/winfsp-tests.vcxproj b/build/VStudio/testing/winfsp-tests.vcxproj index 1d51effe..a54d0da1 100644 --- a/build/VStudio/testing/winfsp-tests.vcxproj +++ b/build/VStudio/testing/winfsp-tests.vcxproj @@ -107,7 +107,7 @@ Console true - ntdll.lib;%(AdditionalDependencies) + ntdll.lib;netapi32.lib;%(AdditionalDependencies) @@ -124,7 +124,7 @@ Console true - ntdll.lib;%(AdditionalDependencies) + ntdll.lib;netapi32.lib;%(AdditionalDependencies) @@ -145,7 +145,7 @@ true true true - ntdll.lib;%(AdditionalDependencies) + ntdll.lib;netapi32.lib;%(AdditionalDependencies) @@ -166,7 +166,7 @@ true true true - ntdll.lib;%(AdditionalDependencies) + ntdll.lib;netapi32.lib;%(AdditionalDependencies) diff --git a/tst/winfsp-tests/dirctl-test.c b/tst/winfsp-tests/dirctl-test.c index 3c4df4b0..ae350b5d 100644 --- a/tst/winfsp-tests/dirctl-test.c +++ b/tst/winfsp-tests/dirctl-test.c @@ -372,6 +372,9 @@ static void querydir_buffer_overflow_dotest(ULONG Flags, PWSTR Prefix, ULONG Fil void querydir_buffer_overflow_test(void) { + if (OptShareName) + return; + if (NtfsTests) { WCHAR DirBuf[MAX_PATH] = L"\\\\?\\"; diff --git a/tst/winfsp-tests/info-test.c b/tst/winfsp-tests/info-test.c index 1ef9d4f4..12c3bbaf 100644 --- a/tst/winfsp-tests/info-test.c +++ b/tst/winfsp-tests/info-test.c @@ -67,6 +67,10 @@ void getfileinfo_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout) Success = GetFileInformationByHandleEx(Handle, FileNameInfo, PNameInfo, sizeof *PNameInfo); ASSERT(!Success); ASSERT(ERROR_MORE_DATA == GetLastError()); + if (OptSharePrefixLength) + { + PNameInfo->FileNameLength -= OptSharePrefixLength; + } if (-1 == Flags) ASSERT(PNameInfo->FileNameLength == wcslen(FilePath + 6) * sizeof(WCHAR)); else if (0 == Prefix) @@ -77,6 +81,13 @@ void getfileinfo_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout) Success = GetFileInformationByHandleEx(Handle, FileNameInfo, PNameInfo, sizeof NameInfoBuf); ASSERT(Success); + if (OptSharePrefixLength) + { + memmove(PNameInfo->FileName, + PNameInfo->FileName + OptSharePrefixLength / sizeof(WCHAR), + PNameInfo->FileNameLength - OptSharePrefixLength); + PNameInfo->FileNameLength -= OptSharePrefixLength; + } if (-1 == Flags) ASSERT(PNameInfo->FileNameLength == wcslen(FilePath + 6) * sizeof(WCHAR)); else if (0 == Prefix) @@ -177,11 +188,25 @@ void getfileinfo_name_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout) Result = GetFinalPathNameByHandleW( Handle, FinalPath, MAX_PATH - 1, VOLUME_NAME_NONE | FILE_NAME_OPENED); ASSERT(0 != Result && Result < MAX_PATH); - ASSERT(0 == wcscmp(OrigPath, FinalPath)); /* don't use mywcscmp */ + if (OptSharePrefixLength) + { + memmove(FinalPath, + FinalPath + OptSharePrefixLength / sizeof(WCHAR), + (wcslen(FinalPath) + 1) * sizeof(WCHAR) - OptSharePrefixLength); + ASSERT(0 == _wcsicmp(OrigPath, FinalPath)); /* use wcsicmp when going through share (?) */ + } + else + ASSERT(0 == wcscmp(OrigPath, FinalPath)); /* don't use mywcscmp */ Result = GetFinalPathNameByHandleW( Handle, FinalPath, MAX_PATH - 1, VOLUME_NAME_NONE | FILE_NAME_NORMALIZED); ASSERT(0 != Result && Result < MAX_PATH); + if (OptSharePrefixLength) + { + memmove(FinalPath, + FinalPath + OptSharePrefixLength / sizeof(WCHAR), + (wcslen(FinalPath) + 1) * sizeof(WCHAR) - OptSharePrefixLength); + } ASSERT(0 == wcscmp(OrigPath, FinalPath)); /* don't use mywcscmp */ CloseHandle(Handle); @@ -707,6 +732,10 @@ static void rename_flipflop_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTime void rename_flipflop_test(void) { + if (OptShareName) + /* this test fails with shares */ + return; + if (NtfsTests) { WCHAR DirBuf[MAX_PATH] = L"\\\\?\\"; diff --git a/tst/winfsp-tests/memfs-test.c b/tst/winfsp-tests/memfs-test.c index 3c2714a9..193cea2e 100644 --- a/tst/winfsp-tests/memfs-test.c +++ b/tst/winfsp-tests/memfs-test.c @@ -10,7 +10,10 @@ int memfs_running; void *memfs_start_ex(ULONG Flags, ULONG FileInfoTimeout) { if (-1 == Flags) + { + memfs_running = 1; return 0; + } MEMFS *Memfs; NTSTATUS Result; @@ -47,11 +50,11 @@ void *memfs_start(ULONG Flags) void memfs_stop(void *data) { + memfs_running = 0; + if (0 == data) return; - memfs_running = 0; - MEMFS *Memfs = data; MemfsStop(Memfs); diff --git a/tst/winfsp-tests/reparse-test.c b/tst/winfsp-tests/reparse-test.c index 3d6beaaa..2f9d0825 100644 --- a/tst/winfsp-tests/reparse-test.c +++ b/tst/winfsp-tests/reparse-test.c @@ -236,6 +236,13 @@ static void reparse_symlink_dotest0(ULONG Flags, PWSTR Prefix, Success = GetFileInformationByHandleEx(Handle, FileNameInfo, PNameInfo, sizeof NameInfoBuf); ASSERT(Success); + if (OptSharePrefixLength) + { + memmove(PNameInfo->FileName, + PNameInfo->FileName + OptSharePrefixLength / sizeof(WCHAR), + PNameInfo->FileNameLength - OptSharePrefixLength); + PNameInfo->FileNameLength -= OptSharePrefixLength; + } if (-1 == Flags) ASSERT(PNameInfo->FileNameLength == wcslen(FilePath + 6) * sizeof(WCHAR)); else if (0 == Prefix) @@ -278,7 +285,12 @@ static void reparse_symlink_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTime StringCbPrintfW(LinkPath, sizeof LinkPath, L"%s%s\\link0", Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs)); - reparse_symlink_dotest0(Flags, Prefix, FilePath, LinkPath, FilePath); + if (OptShareName) + StringCbPrintfW(TargetPath, sizeof TargetPath, L"%s%s%s\\file0", + OptShareComputer, OptShareName, -1 == Flags ? Prefix + 6 : L""); + + reparse_symlink_dotest0(Flags, Prefix, FilePath, LinkPath, + OptShareName ? TargetPath : FilePath); StringCbPrintfW(TargetPath, sizeof TargetPath, L"%s\\file0", -1 == Flags ? Prefix + 6 : L""); @@ -393,6 +405,13 @@ static BOOL my_namecheck_fn(ULONG Flags, PWSTR Prefix, void *memfs, PWSTR FileNa if (GetFileInformationByHandleEx(Handle, FileNameInfo, PNameInfo, sizeof NameInfoBuf)) { + if (OptSharePrefixLength) + { + memmove(PNameInfo->FileName, + PNameInfo->FileName + OptSharePrefixLength / sizeof(WCHAR), + PNameInfo->FileNameLength - OptSharePrefixLength); + PNameInfo->FileNameLength -= OptSharePrefixLength; + } if (-1 == Flags) ASSERT(PNameInfo->FileNameLength == wcslen(ExpectedPath + 6) * sizeof(WCHAR)); else if (0 == Prefix) diff --git a/tst/winfsp-tests/stream-tests.c b/tst/winfsp-tests/stream-tests.c index 748a8922..64f568c8 100644 --- a/tst/winfsp-tests/stream-tests.c +++ b/tst/winfsp-tests/stream-tests.c @@ -859,6 +859,10 @@ static void stream_getfileinfo_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoT Success = GetFileInformationByHandleEx(Handle, FileNameInfo, PNameInfo, sizeof *PNameInfo); ASSERT(!Success); ASSERT(ERROR_MORE_DATA == GetLastError()); + if (OptSharePrefixLength) + { + PNameInfo->FileNameLength -= OptSharePrefixLength; + } if (-1 == Flags) ASSERT(PNameInfo->FileNameLength == wcslen(FilePath + 6) * sizeof(WCHAR)); else if (0 == Prefix) @@ -869,6 +873,13 @@ static void stream_getfileinfo_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoT Success = GetFileInformationByHandleEx(Handle, FileNameInfo, PNameInfo, sizeof NameInfoBuf); ASSERT(Success); + if (OptSharePrefixLength) + { + memmove(PNameInfo->FileName, + PNameInfo->FileName + OptSharePrefixLength / sizeof(WCHAR), + PNameInfo->FileNameLength - OptSharePrefixLength); + PNameInfo->FileNameLength -= OptSharePrefixLength; + } if (-1 == Flags) ASSERT(PNameInfo->FileNameLength == wcslen(FilePath + 6) * sizeof(WCHAR)); else if (0 == Prefix) @@ -946,6 +957,10 @@ static void stream_getfileinfo_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoT Success = GetFileInformationByHandleEx(Handle, FileNameInfo, PNameInfo, sizeof *PNameInfo); ASSERT(!Success); ASSERT(ERROR_MORE_DATA == GetLastError()); + if (OptSharePrefixLength) + { + PNameInfo->FileNameLength -= OptSharePrefixLength; + } if (-1 == Flags) ASSERT(PNameInfo->FileNameLength == wcslen(FilePath + 6) * sizeof(WCHAR)); else if (0 == Prefix) @@ -956,6 +971,13 @@ static void stream_getfileinfo_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoT Success = GetFileInformationByHandleEx(Handle, FileNameInfo, PNameInfo, sizeof NameInfoBuf); ASSERT(Success); + if (OptSharePrefixLength) + { + memmove(PNameInfo->FileName, + PNameInfo->FileName + OptSharePrefixLength / sizeof(WCHAR), + PNameInfo->FileNameLength - OptSharePrefixLength); + PNameInfo->FileNameLength -= OptSharePrefixLength; + } if (-1 == Flags) ASSERT(PNameInfo->FileNameLength == wcslen(FilePath + 6) * sizeof(WCHAR)); else if (0 == Prefix) @@ -1438,6 +1460,10 @@ static void stream_rename_flipflop_dotest(ULONG Flags, PWSTR Prefix, ULONG FileI static void stream_rename_flipflop_test(void) { + if (OptShareName) + /* this test fails with shares */ + return; + if (NtfsTests) { WCHAR DirBuf[MAX_PATH] = L"\\\\?\\"; diff --git a/tst/winfsp-tests/winfsp-tests.c b/tst/winfsp-tests/winfsp-tests.c index cfaa0120..cf934b2b 100644 --- a/tst/winfsp-tests/winfsp-tests.c +++ b/tst/winfsp-tests/winfsp-tests.c @@ -1,3 +1,6 @@ +#include +#include +#include #include #include @@ -17,9 +20,14 @@ int WinFspNetTests = 1; BOOLEAN OptCaseInsensitive = FALSE; BOOLEAN OptCaseRandomize = FALSE; WCHAR OptMountPointBuf[MAX_PATH], *OptMountPoint; +WCHAR OptShareNameBuf[MAX_PATH], *OptShareName, *OptShareTarget; + WCHAR OptShareComputer[] = L"\\\\localhost\\"; + ULONG OptSharePrefixLength; /* only counts single leading slash: \localhost\target\path */ HANDLE OptNoTraverseToken = 0; LUID OptNoTraverseLuid; +static void exiting(void); + int mywcscmp(PWSTR a, int alen, PWSTR b, int blen) { int len, res; @@ -98,35 +106,55 @@ HANDLE HookCreateFileW( *P = togglealpha(*P); } - if (OptMountPoint && memfs_running) + if (OptMountPoint && !OptShareName && memfs_running) { if (L'\\' == FileNameBuf[0] && L'\\' == FileNameBuf[1] && L'?' == FileNameBuf[2] && L'\\' == FileNameBuf[3] && testalpha(FileNameBuf[4]) && L':' == FileNameBuf[5] && L'\\' == FileNameBuf[6]) ; else if (0 == wcsncmp(FileNameBuf, DevicePrefix, wcschr(DevicePrefix, L'{') - DevicePrefix)) - { P = FileNameBuf + wcslen(DevicePrefix); - L1 = wcslen(P) + 1; - L2 = wcslen(OptMountPoint); - memmove(FileNameBuf + 1024 - L1, P, L1 * sizeof(WCHAR)); - memmove(FileNameBuf, OptMountPoint, L2 * sizeof(WCHAR)); - memmove(FileNameBuf + L2, P, L1 * sizeof(WCHAR)); - } else if (0 == mywcscmp( FileNameBuf, (int)wcslen(MemfsSharePrefix), MemfsSharePrefix, (int)wcslen(MemfsSharePrefix))) - { P = FileNameBuf + wcslen(MemfsSharePrefix); - L1 = wcslen(P) + 1; - L2 = wcslen(OptMountPoint); - memmove(FileNameBuf + 1024 - L1, P, L1 * sizeof(WCHAR)); - memmove(FileNameBuf, OptMountPoint, L2 * sizeof(WCHAR)); - memmove(FileNameBuf + L2, P, L1 * sizeof(WCHAR)); - } else if (testalpha(FileNameBuf[0]) && L':' == FileNameBuf[1] && L'\\' == FileNameBuf[2]) ; else ABORT(); + + L1 = wcslen(P) + 1; + L2 = wcslen(OptMountPoint); + memmove(FileNameBuf + 1024 - L1, P, L1 * sizeof(WCHAR)); + memmove(FileNameBuf, OptMountPoint, L2 * sizeof(WCHAR)); + memmove(FileNameBuf + L2, FileNameBuf + 1024 - L1, L1 * sizeof(WCHAR)); + } + + if (OptShareName && memfs_running) + { + if (L'\\' == FileNameBuf[0] && L'\\' == FileNameBuf[1] && + L'?' == FileNameBuf[2] && L'\\' == FileNameBuf[3] && + testalpha(FileNameBuf[4]) && L':' == FileNameBuf[5] && L'\\' == FileNameBuf[6]) + /* NTFS testing can only been done when the whole drive is being shared */ + P = FileNameBuf + 6; + else if (0 == wcsncmp(FileNameBuf, DevicePrefix, wcschr(DevicePrefix, L'{') - DevicePrefix)) + P = FileNameBuf + wcslen(DevicePrefix); + else if (0 == mywcscmp( + FileNameBuf, (int)wcslen(MemfsSharePrefix), MemfsSharePrefix, (int)wcslen(MemfsSharePrefix))) + P = FileNameBuf + wcslen(MemfsSharePrefix); + else if (testalpha(FileNameBuf[0]) && L':' == FileNameBuf[1] && L'\\' == FileNameBuf[2]) + /* NTFS testing can only been done when the whole drive is being shared */ + P = FileNameBuf + 2; + else + ABORT(); + + L1 = wcslen(P) + 1; + L2 = wcslen(OptShareName); + memmove(FileNameBuf + 1024 - L1, P, L1 * sizeof(WCHAR)); + memmove(FileNameBuf, OptShareComputer, sizeof OptShareComputer - sizeof(WCHAR)); + memmove(FileNameBuf + (sizeof OptShareComputer - sizeof(WCHAR)) / sizeof(WCHAR), + OptShareName, L2 * sizeof(WCHAR)); + memmove(FileNameBuf + (sizeof OptShareComputer - sizeof(WCHAR)) / sizeof(WCHAR) + L2, + FileNameBuf + 1024 - L1, L1 * sizeof(WCHAR)); } if (OptNoTraverseToken) @@ -199,6 +227,36 @@ static VOID DisableBackupRestorePrivileges(VOID) CloseHandle(Token); } +static VOID AddNetworkShare(VOID) +{ + SHARE_INFO_2 ShareInfo = { 0 }; + NET_API_STATUS NetStatus; + + ShareInfo.shi2_netname = OptShareName; + ShareInfo.shi2_type = STYPE_DISKTREE; + ShareInfo.shi2_permissions = ACCESS_ALL; + ShareInfo.shi2_max_uses = -1; + ShareInfo.shi2_path = OptShareTarget; + + NetShareDel(0, OptShareName, 0); + NetStatus = NetShareAdd(0, 2, (PBYTE)&ShareInfo, 0); + if (NERR_Success != NetStatus) + ABORT(); +} + +static void abort_handler(int sig) +{ + DWORD Error = GetLastError(); + exiting(); + SetLastError(Error); +} + +LONG WINAPI UnhandledExceptionHandler(struct _EXCEPTION_POINTERS *ExceptionInfo) +{ + exiting(); + return EXCEPTION_EXECUTE_HANDLER; +} + #define rmarg(argv, argc, argi) \ argc--,\ memmove(argv + argi, argv + argi + 1, (argc - argi) * sizeof(char *)),\ @@ -223,6 +281,10 @@ int main(int argc, char *argv[]) TESTSUITE(reparse_tests); TESTSUITE(stream_tests); + atexit(exiting); + signal(SIGABRT, abort_handler); + SetUnhandledExceptionFilter(UnhandledExceptionHandler); + for (int argi = 1; argc > argi; argi++) { const char *a = argv[argi]; @@ -254,6 +316,25 @@ int main(int argc, char *argv[]) WinFspNetTests = 0; } } + else if (0 == strncmp("--share=", a, sizeof "--share=" - 1)) + { + if (0 != MultiByteToWideChar(CP_UTF8, 0, + a + sizeof "--share=" - 1, -1, OptShareNameBuf, MAX_PATH)) + { + OptShareTarget = wcschr(OptShareNameBuf, L'='); + if (OptShareTarget) + { + *OptShareTarget++ = L'\0'; + OptShareName = OptShareNameBuf; + rmarg(argv, argc, argi); + + OptSharePrefixLength = (ULONG) + (sizeof OptShareComputer - 2 * sizeof(WCHAR) + (wcslen(OptShareName) * sizeof(WCHAR))); + + WinFspNetTests = 0; + } + } + } else if (0 == strcmp("--no-traverse", a)) { if (LookupPrivilegeValueW(0, SE_CHANGE_NOTIFY_NAME, &OptNoTraverseLuid) && @@ -267,8 +348,18 @@ int main(int argc, char *argv[]) DisableBackupRestorePrivileges(); + if (OptShareName) + AddNetworkShare(); + myrandseed = (unsigned)time(0); tlib_run_tests(argc, argv); return 0; } + +static void exiting(void) +{ + OutputDebugStringA("winfsp-tests: exiting\n"); + if (OptShareName) + NetShareDel(0, OptShareName, 0); +} diff --git a/tst/winfsp-tests/winfsp-tests.h b/tst/winfsp-tests/winfsp-tests.h index 95ffdf3e..c1d9da30 100644 --- a/tst/winfsp-tests/winfsp-tests.h +++ b/tst/winfsp-tests/winfsp-tests.h @@ -24,6 +24,9 @@ extern int WinFspNetTests; extern BOOLEAN OptCaseInsensitive; extern BOOLEAN OptCaseRandomize; extern WCHAR OptMountPointBuf[], *OptMountPoint; +extern WCHAR OptShareNameBuf[], *OptShareName, *OptShareTarget; + extern WCHAR OptShareComputer[]; + extern ULONG OptSharePrefixLength; extern HANDLE OptNoTraverseToken; extern LUID OptNoTraverseLuid;