diff --git a/build/VStudio/testing/winfsp-tests.vcxproj b/build/VStudio/testing/winfsp-tests.vcxproj
index 5e494520..55cd2848 100644
--- a/build/VStudio/testing/winfsp-tests.vcxproj
+++ b/build/VStudio/testing/winfsp-tests.vcxproj
@@ -186,6 +186,7 @@
+
diff --git a/build/VStudio/testing/winfsp-tests.vcxproj.filters b/build/VStudio/testing/winfsp-tests.vcxproj.filters
index dd1e6352..d4443b26 100644
--- a/build/VStudio/testing/winfsp-tests.vcxproj.filters
+++ b/build/VStudio/testing/winfsp-tests.vcxproj.filters
@@ -70,6 +70,9 @@
Source
+
+ Source
+
diff --git a/tst/winfsp-tests/hooks.c b/tst/winfsp-tests/hooks.c
new file mode 100644
index 00000000..0e692509
--- /dev/null
+++ b/tst/winfsp-tests/hooks.c
@@ -0,0 +1,194 @@
+/**
+ * @file hooks.c
+ *
+ * @copyright 2015-2016 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 "winfsp-tests.h"
+
+#undef CreateFileW
+#undef CloseHandle
+#undef DeleteFileW
+
+#define FILENAMEBUF_SIZE 1024
+
+static VOID PrepareFileName(PCWSTR FileName, PWSTR FileNameBuf)
+{
+ static WCHAR DevicePrefix[] =
+ L"\\\\?\\GLOBALROOT\\Device\\Volume{01234567-0123-0123-0101-010101010101}";
+ static WCHAR MemfsSharePrefix[] =
+ L"\\\\memfs\\share";
+ static const int TogglePercent = 25;
+ PWSTR P, EndP;
+ size_t L1, L2, L3;
+
+ wcscpy_s(FileNameBuf, FILENAMEBUF_SIZE, FileName);
+
+ if (OptCaseRandomize)
+ {
+ if (L'\\' == FileNameBuf[0] && L'\\' == FileNameBuf[1] &&
+ L'?' == FileNameBuf[2] && L'\\' == FileNameBuf[3] &&
+ testalpha(FileNameBuf[4]) && L':' == FileNameBuf[5] && L'\\' == FileNameBuf[6])
+ P = FileNameBuf + 6;
+ else if (0 == wcsncmp(FileNameBuf, DevicePrefix, wcschr(DevicePrefix, L'{') - DevicePrefix))
+ P = FileNameBuf + wcslen(DevicePrefix);
+ else if (L'\\' == FileNameBuf[0] && L'\\' == FileNameBuf[1])
+ P = FileNameBuf + 2;
+ else if (testalpha(FileNameBuf[0]) && L':' == FileNameBuf[1] && L'\\' == FileNameBuf[2])
+ P = FileNameBuf + 2;
+ else
+ ABORT("unknown filename format");
+
+ for (EndP = P + wcslen(P); EndP > P; P++)
+ if (testalpha(*P) && myrand() <= (TogglePercent) * 0x7fff / 100)
+ *P = togglealpha(*P);
+ }
+
+ if (OptMountPoint && memfs_running)
+ {
+ if (L'\\' == FileNameBuf[0] && L'\\' == FileNameBuf[1] &&
+ L'?' == FileNameBuf[2] && L'\\' == FileNameBuf[3] &&
+ testalpha(FileNameBuf[4]) && L':' == FileNameBuf[5] && L'\\' == FileNameBuf[6])
+ ABORT("--mountpoint not supported with NTFS");
+ 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])
+ ABORT("--mountpoint not supported with NTFS");
+ else
+ ABORT("unknown filename format");
+
+ L1 = wcslen(P) + 1;
+ L2 = wcslen(OptMountPoint);
+ memmove(FileNameBuf + FILENAMEBUF_SIZE - L1, P, L1 * sizeof(WCHAR));
+ memmove(FileNameBuf, OptMountPoint, L2 * sizeof(WCHAR));
+ memmove(FileNameBuf + L2, FileNameBuf + FILENAMEBUF_SIZE - 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("unknown filename format");
+
+ L1 = wcslen(P) + 1;
+ L2 = wcslen(OptShareComputer);
+ L3 = wcslen(OptShareName);
+ memmove(FileNameBuf + FILENAMEBUF_SIZE - L1, P, L1 * sizeof(WCHAR));
+ memmove(FileNameBuf, OptShareComputer, L2 * sizeof(WCHAR));
+ memmove(FileNameBuf + L2, OptShareName, L3 * sizeof(WCHAR));
+ memmove(FileNameBuf + L2 + L3, FileNameBuf + FILENAMEBUF_SIZE - L1, L1 * sizeof(WCHAR));
+ }
+}
+
+HANDLE HookCreateFileW(
+ LPCWSTR lpFileName,
+ DWORD dwDesiredAccess,
+ DWORD dwShareMode,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+ DWORD dwCreationDisposition,
+ DWORD dwFlagsAndAttributes,
+ HANDLE hTemplateFile)
+{
+ WCHAR FileNameBuf[FILENAMEBUF_SIZE];
+ TOKEN_PRIVILEGES Privileges;
+
+ PrepareFileName(lpFileName, FileNameBuf);
+
+ if (OptNoTraverseToken)
+ {
+ Privileges.PrivilegeCount = 1;
+ Privileges.Privileges[0].Attributes = 0;
+ Privileges.Privileges[0].Luid = OptNoTraverseLuid;
+ if (!AdjustTokenPrivileges(OptNoTraverseToken, FALSE, &Privileges, 0, 0, 0))
+ ABORT("cannot disable traverse privilege");
+ }
+
+ HANDLE h;
+ if (!OptResilient)
+ h = CreateFileW(
+ FileNameBuf,
+ dwDesiredAccess,
+ dwShareMode,
+ lpSecurityAttributes,
+ dwCreationDisposition,
+ dwFlagsAndAttributes,
+ hTemplateFile);
+ else
+ h = ResilientCreateFileW(
+ FileNameBuf,
+ dwDesiredAccess,
+ dwShareMode,
+ lpSecurityAttributes,
+ dwCreationDisposition,
+ dwFlagsAndAttributes,
+ hTemplateFile);
+ DWORD LastError = GetLastError();
+
+ if (OptNoTraverseToken)
+ {
+ Privileges.PrivilegeCount = 1;
+ Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+ Privileges.Privileges[0].Luid = OptNoTraverseLuid;
+ if (!AdjustTokenPrivileges(OptNoTraverseToken, FALSE, &Privileges, 0, 0, 0))
+ ABORT("cannot enable traverse privilege");
+ }
+
+#if 0
+ FspDebugLog("CreateFileW(\"%S\", %#lx, %#lx, %p, %#lx, %#lx, %p) = %p[%#lx]\n",
+ FileNameBuf,
+ dwDesiredAccess,
+ dwShareMode,
+ lpSecurityAttributes,
+ dwCreationDisposition,
+ dwFlagsAndAttributes,
+ hTemplateFile,
+ h, INVALID_HANDLE_VALUE != h ? 0 : LastError);
+#endif
+
+ SetLastError(LastError);
+ return h;
+}
+
+BOOL HookCloseHandle(
+ HANDLE hObject)
+{
+ if (!OptResilient)
+ return CloseHandle(hObject);
+ else
+ return ResilientCloseHandle(hObject);
+}
+
+BOOL HookDeleteFileW(
+ LPCWSTR lpFileName)
+{
+ if (!OptResilient)
+ return DeleteFileW(lpFileName);
+ else
+ return ResilientDeleteFileW(lpFileName);
+}
diff --git a/tst/winfsp-tests/winfsp-tests.c b/tst/winfsp-tests/winfsp-tests.c
index 33cc4cee..68d44207 100644
--- a/tst/winfsp-tests/winfsp-tests.c
+++ b/tst/winfsp-tests/winfsp-tests.c
@@ -23,12 +23,9 @@
#include "winfsp-tests.h"
-#define ABORT(s)\
- do\
- {\
- tlib_printf("ABORT: %s: %s\n", __func__, s);\
- abort();\
- } while (0,0)
+#undef CreateFileW
+#undef CloseHandle
+#undef DeleteFileW
int NtfsTests = 0;
int WinFspDiskTests = 1;
@@ -69,11 +66,8 @@ int mywcscmp(PWSTR a, int alen, PWSTR b, int blen)
return res;
}
-#define testalpha(c) ('a' <= ((c) | 0x20) && ((c) | 0x20) <= 'z')
-#define togglealpha(c) ((c) ^ 0x20)
-#undef CreateFileW
static unsigned myrandseed = 1;
-static int myrand(void)
+int myrand(void)
{
/*
* This mimics MSVCRT rand(); we need our own version
@@ -83,172 +77,6 @@ static int myrand(void)
myrandseed = myrandseed * 214013 + 2531011;
return (myrandseed >> 16) & RAND_MAX;
}
-HANDLE HookCreateFileW(
- LPCWSTR lpFileName,
- DWORD dwDesiredAccess,
- DWORD dwShareMode,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes,
- DWORD dwCreationDisposition,
- DWORD dwFlagsAndAttributes,
- HANDLE hTemplateFile)
-{
- static WCHAR DevicePrefix[] =
- L"\\\\?\\GLOBALROOT\\Device\\Volume{01234567-0123-0123-0101-010101010101}";
- static WCHAR MemfsSharePrefix[] =
- L"\\\\memfs\\share";
- static const TogglePercent = 25;
- WCHAR FileNameBuf[1024];
- TOKEN_PRIVILEGES Privileges;
- PWSTR P, EndP;
- size_t L1, L2;
-
- wcscpy_s(FileNameBuf, sizeof FileNameBuf / sizeof(WCHAR), lpFileName);
-
- if (OptCaseRandomize)
- {
- if (L'\\' == FileNameBuf[0] && L'\\' == FileNameBuf[1] &&
- L'?' == FileNameBuf[2] && L'\\' == FileNameBuf[3] &&
- testalpha(FileNameBuf[4]) && L':' == FileNameBuf[5] && L'\\' == FileNameBuf[6])
- P = FileNameBuf + 7;
- else if (0 == wcsncmp(FileNameBuf, DevicePrefix, wcschr(DevicePrefix, L'{') - DevicePrefix))
- P = FileNameBuf + wcslen(DevicePrefix);
- else if (L'\\' == FileNameBuf[0] && L'\\' == FileNameBuf[1])
- P = FileNameBuf + 2;
- else if (testalpha(FileNameBuf[0]) && L':' == FileNameBuf[1] && L'\\' == FileNameBuf[2])
- P = FileNameBuf + 3;
- else
- ABORT("unknown filename format");
-
- for (EndP = P + wcslen(P); EndP > P; P++)
- if (testalpha(*P) && myrand() <= (TogglePercent) * 0x7fff / 100)
- *P = togglealpha(*P);
- }
-
- if (OptMountPoint && memfs_running)
- {
- if (L'\\' == FileNameBuf[0] && L'\\' == FileNameBuf[1] &&
- L'?' == FileNameBuf[2] && L'\\' == FileNameBuf[3] &&
- testalpha(FileNameBuf[4]) && L':' == FileNameBuf[5] && L'\\' == FileNameBuf[6])
- ABORT("--mountpoint not supported with NTFS");
- 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])
- ABORT("--mountpoint not supported with NTFS");
- else
- ABORT("unknown filename format");
-
- 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("unknown filename format");
-
- 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)
- {
- Privileges.PrivilegeCount = 1;
- Privileges.Privileges[0].Attributes = 0;
- Privileges.Privileges[0].Luid = OptNoTraverseLuid;
- if (!AdjustTokenPrivileges(OptNoTraverseToken, FALSE, &Privileges, 0, 0, 0))
- ABORT("cannot disable traverse privilege");
- }
-
- HANDLE h;
- if (!OptResilient)
- h = CreateFileW(
- FileNameBuf,
- dwDesiredAccess,
- dwShareMode,
- lpSecurityAttributes,
- dwCreationDisposition,
- dwFlagsAndAttributes,
- hTemplateFile);
- else
- h = ResilientCreateFileW(
- FileNameBuf,
- dwDesiredAccess,
- dwShareMode,
- lpSecurityAttributes,
- dwCreationDisposition,
- dwFlagsAndAttributes,
- hTemplateFile);
- DWORD LastError = GetLastError();
-
- if (OptNoTraverseToken)
- {
- Privileges.PrivilegeCount = 1;
- Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- Privileges.Privileges[0].Luid = OptNoTraverseLuid;
- if (!AdjustTokenPrivileges(OptNoTraverseToken, FALSE, &Privileges, 0, 0, 0))
- ABORT("cannot enable traverse privilege");
- }
-
-#if 0
- FspDebugLog("CreateFileW(\"%S\", %#lx, %#lx, %p, %#lx, %#lx, %p) = %p[%#lx]\n",
- FileNameBuf,
- dwDesiredAccess,
- dwShareMode,
- lpSecurityAttributes,
- dwCreationDisposition,
- dwFlagsAndAttributes,
- hTemplateFile,
- h, INVALID_HANDLE_VALUE != h ? 0 : LastError);
-#endif
-
- SetLastError(LastError);
- return h;
-}
-
-#undef CloseHandle
-BOOL HookCloseHandle(
- HANDLE hObject)
-{
- if (!OptResilient)
- return CloseHandle(hObject);
- else
- return ResilientCloseHandle(hObject);
-}
-
-#undef DeleteFileW
-BOOL HookDeleteFileW(
- LPCWSTR lpFileName)
-{
- if (!OptResilient)
- return DeleteFileW(lpFileName);
- else
- return ResilientDeleteFileW(lpFileName);
-}
static VOID DisableBackupRestorePrivileges(VOID)
{
diff --git a/tst/winfsp-tests/winfsp-tests.h b/tst/winfsp-tests/winfsp-tests.h
index d94c6c97..c215e6c9 100644
--- a/tst/winfsp-tests/winfsp-tests.h
+++ b/tst/winfsp-tests/winfsp-tests.h
@@ -17,12 +17,16 @@
#include
-void *memfs_start_ex(ULONG Flags, ULONG FileInfoTimeout);
-void *memfs_start(ULONG Flags);
-void memfs_stop(void *data);
-PWSTR memfs_volumename(void *data);
+#define ABORT(s)\
+ do\
+ {\
+ void tlib_printf(const char *fmt, ...);\
+ tlib_printf("ABORT: %s: %s\n", __func__, s);\
+ abort();\
+ } while (0,0)
-int mywcscmp(PWSTR a, int alen, PWSTR b, int blen);
+#define testalpha(c) ('a' <= ((c) | 0x20) && ((c) | 0x20) <= 'z')
+#define togglealpha(c) ((c) ^ 0x20)
#define CreateFileW HookCreateFileW
#define CloseHandle HookCloseHandle
@@ -58,6 +62,14 @@ typedef struct
BOOLEAN Disposition;
} MY_FILE_DISPOSITION_INFO;
+void *memfs_start_ex(ULONG Flags, ULONG FileInfoTimeout);
+void *memfs_start(ULONG Flags);
+void memfs_stop(void *data);
+PWSTR memfs_volumename(void *data);
+
+int mywcscmp(PWSTR a, int alen, PWSTR b, int blen);
+int myrand(void);
+
extern int NtfsTests;
extern int WinFspDiskTests;
extern int WinFspNetTests;