summaryrefslogtreecommitdiffstats
path: root/winpr/libwinpr/path/test
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--winpr/libwinpr/path/test/CMakeLists.txt48
-rw-r--r--winpr/libwinpr/path/test/TestPathAllocCanonicalize.c12
-rw-r--r--winpr/libwinpr/path/test/TestPathAllocCombine.c98
-rw-r--r--winpr/libwinpr/path/test/TestPathCchAddBackslash.c100
-rw-r--r--winpr/libwinpr/path/test/TestPathCchAddBackslashEx.c103
-rw-r--r--winpr/libwinpr/path/test/TestPathCchAddExtension.c140
-rw-r--r--winpr/libwinpr/path/test/TestPathCchAppend.c151
-rw-r--r--winpr/libwinpr/path/test/TestPathCchAppendEx.c12
-rw-r--r--winpr/libwinpr/path/test/TestPathCchCanonicalize.c12
-rw-r--r--winpr/libwinpr/path/test/TestPathCchCanonicalizeEx.c12
-rw-r--r--winpr/libwinpr/path/test/TestPathCchCombine.c12
-rw-r--r--winpr/libwinpr/path/test/TestPathCchCombineEx.c12
-rw-r--r--winpr/libwinpr/path/test/TestPathCchFindExtension.c116
-rw-r--r--winpr/libwinpr/path/test/TestPathCchIsRoot.c12
-rw-r--r--winpr/libwinpr/path/test/TestPathCchRemoveBackslash.c12
-rw-r--r--winpr/libwinpr/path/test/TestPathCchRemoveBackslashEx.c12
-rw-r--r--winpr/libwinpr/path/test/TestPathCchRemoveExtension.c12
-rw-r--r--winpr/libwinpr/path/test/TestPathCchRemoveFileSpec.c12
-rw-r--r--winpr/libwinpr/path/test/TestPathCchRenameExtension.c12
-rw-r--r--winpr/libwinpr/path/test/TestPathCchSkipRoot.c12
-rw-r--r--winpr/libwinpr/path/test/TestPathCchStripPrefix.c128
-rw-r--r--winpr/libwinpr/path/test/TestPathCchStripToRoot.c12
-rw-r--r--winpr/libwinpr/path/test/TestPathIsUNCEx.c52
-rw-r--r--winpr/libwinpr/path/test/TestPathMakePath.c83
-rw-r--r--winpr/libwinpr/path/test/TestPathShell.c58
25 files changed, 1245 insertions, 0 deletions
diff --git a/winpr/libwinpr/path/test/CMakeLists.txt b/winpr/libwinpr/path/test/CMakeLists.txt
new file mode 100644
index 0000000..974907e
--- /dev/null
+++ b/winpr/libwinpr/path/test/CMakeLists.txt
@@ -0,0 +1,48 @@
+
+set(MODULE_NAME "TestPath")
+set(MODULE_PREFIX "TEST_PATH")
+
+set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
+
+set(${MODULE_PREFIX}_TESTS
+ TestPathCchAddBackslash.c
+ TestPathCchRemoveBackslash.c
+ TestPathCchAddBackslashEx.c
+ TestPathCchRemoveBackslashEx.c
+ TestPathCchAddExtension.c
+ TestPathCchAppend.c
+ TestPathCchAppendEx.c
+ TestPathCchCanonicalize.c
+ TestPathCchCanonicalizeEx.c
+ TestPathAllocCanonicalize.c
+ TestPathCchCombine.c
+ TestPathCchCombineEx.c
+ TestPathAllocCombine.c
+ TestPathCchFindExtension.c
+ TestPathCchRenameExtension.c
+ TestPathCchRemoveExtension.c
+ TestPathCchIsRoot.c
+ TestPathIsUNCEx.c
+ TestPathCchSkipRoot.c
+ TestPathCchStripToRoot.c
+ TestPathCchStripPrefix.c
+ TestPathCchRemoveFileSpec.c
+ TestPathShell.c
+ TestPathMakePath.c)
+
+create_test_sourcelist(${MODULE_PREFIX}_SRCS
+ ${${MODULE_PREFIX}_DRIVER}
+ ${${MODULE_PREFIX}_TESTS})
+
+add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
+
+target_link_libraries(${MODULE_NAME} winpr)
+
+set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
+
+foreach(test ${${MODULE_PREFIX}_TESTS})
+ get_filename_component(TestName ${test} NAME_WE)
+ add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
+endforeach()
+
+set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test")
diff --git a/winpr/libwinpr/path/test/TestPathAllocCanonicalize.c b/winpr/libwinpr/path/test/TestPathAllocCanonicalize.c
new file mode 100644
index 0000000..d04fff1
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathAllocCanonicalize.c
@@ -0,0 +1,12 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+int TestPathAllocCanonicalize(int argc, char* argv[])
+{
+ printf("Warning: %s is not implemented!\n", __func__);
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathAllocCombine.c b/winpr/libwinpr/path/test/TestPathAllocCombine.c
new file mode 100644
index 0000000..4630df0
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathAllocCombine.c
@@ -0,0 +1,98 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+static const TCHAR testBasePathBackslash[] = _T("C:\\Program Files\\");
+static const TCHAR testBasePathNoBackslash[] = _T("C:\\Program Files");
+static const TCHAR testMorePathBackslash[] = _T("\\Microsoft Visual Studio 11.0");
+static const TCHAR testMorePathNoBackslash[] = _T("Microsoft Visual Studio 11.0");
+static const TCHAR testPathOut[] = _T("C:\\Program Files\\Microsoft Visual Studio 11.0");
+static const TCHAR testPathOutMorePathBackslash[] = _T("C:\\Microsoft Visual Studio 11.0");
+
+int TestPathAllocCombine(int argc, char* argv[])
+{
+ HRESULT status = 0;
+ LPTSTR PathOut = NULL;
+
+ WINPR_UNUSED(argc);
+ WINPR_UNUSED(argv);
+
+ /* Base Path: Backslash, More Path: No Backslash */
+
+ status = PathAllocCombine(testBasePathBackslash, testMorePathNoBackslash, 0, &PathOut);
+
+ if (status != S_OK)
+ {
+ _tprintf(_T("PathAllocCombine status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ if (_tcscmp(PathOut, testPathOut) != 0)
+ {
+ _tprintf(_T("Path Mismatch 1: Actual: %s, Expected: %s\n"), PathOut, testPathOut);
+ return -1;
+ }
+
+ free(PathOut);
+
+ /* Base Path: Backslash, More Path: Backslash */
+
+ status = PathAllocCombine(testBasePathBackslash, testMorePathBackslash, 0, &PathOut);
+
+ if (status != S_OK)
+ {
+ _tprintf(_T("PathAllocCombine status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ if (_tcscmp(PathOut, testPathOutMorePathBackslash) != 0)
+ {
+ _tprintf(_T("Path Mismatch 2: Actual: %s, Expected: %s\n"), PathOut,
+ testPathOutMorePathBackslash);
+ return -1;
+ }
+
+ free(PathOut);
+
+ /* Base Path: No Backslash, More Path: Backslash */
+
+ status = PathAllocCombine(testBasePathNoBackslash, testMorePathBackslash, 0, &PathOut);
+
+ if (status != S_OK)
+ {
+ _tprintf(_T("PathAllocCombine status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ if (_tcscmp(PathOut, testPathOutMorePathBackslash) != 0)
+ {
+ _tprintf(_T("Path Mismatch 3: Actual: %s, Expected: %s\n"), PathOut,
+ testPathOutMorePathBackslash);
+ return -1;
+ }
+
+ free(PathOut);
+
+ /* Base Path: No Backslash, More Path: No Backslash */
+
+ status = PathAllocCombine(testBasePathNoBackslash, testMorePathNoBackslash, 0, &PathOut);
+
+ if (status != S_OK)
+ {
+ _tprintf(_T("PathAllocCombine status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ if (_tcscmp(PathOut, testPathOut) != 0)
+ {
+ _tprintf(_T("Path Mismatch 4: Actual: %s, Expected: %s\n"), PathOut, testPathOut);
+ return -1;
+ }
+
+ free(PathOut);
+
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathCchAddBackslash.c b/winpr/libwinpr/path/test/TestPathCchAddBackslash.c
new file mode 100644
index 0000000..0a414e2
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathCchAddBackslash.c
@@ -0,0 +1,100 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+static const TCHAR testPathBackslash[] = _T("C:\\Program Files\\");
+static const TCHAR testPathNoBackslash[] = _T("C:\\Program Files");
+
+int TestPathCchAddBackslash(int argc, char* argv[])
+{
+ HRESULT status = 0;
+ TCHAR Path[PATHCCH_MAX_CCH];
+
+ WINPR_UNUSED(argc);
+ WINPR_UNUSED(argv);
+
+ /**
+ * PathCchAddBackslash returns S_OK if the function was successful,
+ * S_FALSE if the path string already ends in a backslash,
+ * or an error code otherwise.
+ */
+
+ _tcscpy(Path, testPathNoBackslash);
+
+ /* Add a backslash to a path without a trailing backslash, expect S_OK */
+
+ status = PathCchAddBackslash(Path, PATHCCH_MAX_CCH);
+
+ if (status != S_OK)
+ {
+ _tprintf(_T("PathCchAddBackslash status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ if (_tcscmp(Path, testPathBackslash) != 0)
+ {
+ _tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathBackslash);
+ return -1;
+ }
+
+ /* Add a backslash to a path with a trailing backslash, expect S_FALSE */
+
+ _tcscpy(Path, testPathBackslash);
+
+ status = PathCchAddBackslash(Path, PATHCCH_MAX_CCH);
+
+ if (status != S_FALSE)
+ {
+ _tprintf(_T("PathCchAddBackslash status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ if (_tcscmp(Path, testPathBackslash) != 0)
+ {
+ _tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathBackslash);
+ return -1;
+ }
+
+ /* Use NULL PSTR, expect FAILED(status) */
+
+ status = PathCchAddBackslash(NULL, PATHCCH_MAX_CCH);
+
+ if (SUCCEEDED(status))
+ {
+ _tprintf(_T("PathCchAddBackslash unexpectedly succeded with null buffer. Status: 0x%08") _T(
+ PRIX32) _T("\n"),
+ status);
+ return -1;
+ }
+
+ /* Use insufficient size value, expect FAILED(status) */
+
+ _tcscpy(Path, _T("C:\\tmp"));
+
+ status = PathCchAddBackslash(Path, 7);
+
+ if (SUCCEEDED(status))
+ {
+ _tprintf(_T("PathCchAddBackslash unexpectedly succeded with insufficient buffer size. ")
+ _T("Status: 0x%08") _T(PRIX32) _T("\n"),
+ status);
+ return -1;
+ }
+
+ /* Use minimum required size value, expect S_OK */
+
+ _tcscpy(Path, _T("C:\\tmp"));
+
+ status = PathCchAddBackslash(Path, 8);
+
+ if (status != S_OK)
+ {
+ _tprintf(_T("PathCchAddBackslash failed with status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathCchAddBackslashEx.c b/winpr/libwinpr/path/test/TestPathCchAddBackslashEx.c
new file mode 100644
index 0000000..4a84200
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathCchAddBackslashEx.c
@@ -0,0 +1,103 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+static const TCHAR testPathBackslash[] = _T("C:\\Program Files\\");
+static const TCHAR testPathNoBackslash[] = _T("C:\\Program Files");
+
+int TestPathCchAddBackslashEx(int argc, char* argv[])
+{
+ HRESULT status = 0;
+ LPTSTR pszEnd = NULL;
+ size_t cchRemaining = 0;
+ TCHAR Path[PATHCCH_MAX_CCH];
+
+ WINPR_UNUSED(argc);
+ WINPR_UNUSED(argv);
+
+ /**
+ * PathCchAddBackslashEx returns S_OK if the function was successful,
+ * S_FALSE if the path string already ends in a backslash,
+ * or an error code otherwise.
+ */
+
+ _tcscpy(Path, testPathNoBackslash);
+
+ /* Add a backslash to a path without a trailing backslash, expect S_OK */
+
+ status = PathCchAddBackslashEx(Path, sizeof(Path) / sizeof(TCHAR), &pszEnd, &cchRemaining);
+
+ if (status != S_OK)
+ {
+ _tprintf(_T("PathCchAddBackslash status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ if (_tcscmp(Path, testPathBackslash) != 0)
+ {
+ _tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathBackslash);
+ return -1;
+ }
+
+ /* Add a backslash to a path with a trailing backslash, expect S_FALSE */
+
+ _tcscpy(Path, testPathBackslash);
+
+ status = PathCchAddBackslashEx(Path, sizeof(Path) / sizeof(TCHAR), &pszEnd, &cchRemaining);
+
+ if (status != S_FALSE)
+ {
+ _tprintf(_T("PathCchAddBackslash status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ if (_tcscmp(Path, testPathBackslash) != 0)
+ {
+ _tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathBackslash);
+ return -1;
+ }
+
+ /* Use NULL PSTR, expect FAILED(status) */
+
+ status = PathCchAddBackslashEx(NULL, PATHCCH_MAX_CCH, NULL, NULL);
+
+ if (SUCCEEDED(status))
+ {
+ _tprintf(
+ _T("PathCchAddBackslashEx unexpectedly succeded with null buffer. Status: 0x%08") _T(
+ PRIX32) _T("\n"),
+ status);
+ return -1;
+ }
+
+ /* Use insufficient size value, expect FAILED(status) */
+
+ _tcscpy(Path, _T("C:\\tmp"));
+
+ status = PathCchAddBackslashEx(Path, 7, NULL, NULL);
+
+ if (SUCCEEDED(status))
+ {
+ _tprintf(_T("PathCchAddBackslashEx unexpectedly succeded with insufficient buffer size. ")
+ _T("Status: 0x%08") _T(PRIX32) _T("\n"),
+ status);
+ return -1;
+ }
+
+ /* Use minimum required size value, expect S_OK */
+
+ _tcscpy(Path, _T("C:\\tmp"));
+
+ status = PathCchAddBackslashEx(Path, 8, NULL, NULL);
+
+ if (status != S_OK)
+ {
+ _tprintf(_T("PathCchAddBackslashEx failed with status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathCchAddExtension.c b/winpr/libwinpr/path/test/TestPathCchAddExtension.c
new file mode 100644
index 0000000..71f5ddf
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathCchAddExtension.c
@@ -0,0 +1,140 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+static const TCHAR testExtDot[] = _T(".exe");
+static const TCHAR testExtNoDot[] = _T("exe");
+static const TCHAR testPathNoExtension[] = _T("C:\\Windows\\System32\\cmd");
+static const TCHAR testPathExtension[] = _T("C:\\Windows\\System32\\cmd.exe");
+
+int TestPathCchAddExtension(int argc, char* argv[])
+{
+ HRESULT status = 0;
+ TCHAR Path[PATHCCH_MAX_CCH];
+
+ WINPR_UNUSED(argc);
+ WINPR_UNUSED(argv);
+
+ /* Path: no extension, Extension: dot */
+
+ _tcscpy(Path, testPathNoExtension);
+
+ status = PathCchAddExtension(Path, PATHCCH_MAX_CCH, testExtDot);
+
+ if (status != S_OK)
+ {
+ _tprintf(_T("PathCchAddExtension status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ if (_tcscmp(Path, testPathExtension) != 0)
+ {
+ _tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathExtension);
+ return -1;
+ }
+
+ /* Path: no extension, Extension: no dot */
+
+ _tcscpy(Path, testPathNoExtension);
+
+ status = PathCchAddExtension(Path, PATHCCH_MAX_CCH, testExtNoDot);
+
+ if (status != S_OK)
+ {
+ _tprintf(_T("PathCchAddExtension status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ if (_tcscmp(Path, testPathExtension) != 0)
+ {
+ _tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathExtension);
+ return -1;
+ }
+
+ /* Path: extension, Extension: dot */
+
+ _tcscpy(Path, testPathExtension);
+
+ status = PathCchAddExtension(Path, PATHCCH_MAX_CCH, testExtDot);
+
+ if (status != S_FALSE)
+ {
+ _tprintf(_T("PathCchAddExtension status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ if (_tcscmp(Path, testPathExtension) != 0)
+ {
+ _tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathExtension);
+ return -1;
+ }
+
+ /* Path: extension, Extension: no dot */
+
+ _tcscpy(Path, testPathExtension);
+
+ status = PathCchAddExtension(Path, PATHCCH_MAX_CCH, testExtDot);
+
+ if (status != S_FALSE)
+ {
+ _tprintf(_T("PathCchAddExtension status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ if (_tcscmp(Path, testPathExtension) != 0)
+ {
+ _tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathExtension);
+ return -1;
+ }
+
+ /* Path: NULL */
+
+ status = PathCchAddExtension(NULL, PATHCCH_MAX_CCH, testExtDot);
+ if (status != E_INVALIDARG)
+ {
+ _tprintf(_T("PathCchAddExtension with null buffer returned status: 0x%08") _T(
+ PRIX32) _T(" (expected E_INVALIDARG)\n"),
+ status);
+ return -1;
+ }
+
+ /* Extension: NULL */
+
+ status = PathCchAddExtension(Path, PATHCCH_MAX_CCH, NULL);
+ if (status != E_INVALIDARG)
+ {
+ _tprintf(_T("PathCchAddExtension with null extension returned status: 0x%08") _T(
+ PRIX32) _T(" (expected E_INVALIDARG)\n"),
+ status);
+ return -1;
+ }
+
+ /* Insufficient Buffer size */
+
+ _tcscpy(Path, _T("C:\\456789"));
+ status = PathCchAddExtension(Path, 9 + 4, _T(".jpg"));
+ if (SUCCEEDED(status))
+ {
+ _tprintf(_T("PathCchAddExtension with insufficient buffer unexpectedly succeeded with ")
+ _T("status: 0x%08") _T(PRIX32) _T("\n"),
+ status);
+ return -1;
+ }
+
+ /* Minimum required buffer size */
+
+ _tcscpy(Path, _T("C:\\456789"));
+ status = PathCchAddExtension(Path, 9 + 4 + 1, _T(".jpg"));
+ if (FAILED(status))
+ {
+ _tprintf(_T("PathCchAddExtension with sufficient buffer unexpectedly failed with status: ")
+ _T("0x%08") _T(PRIX32) _T("\n"),
+ status);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathCchAppend.c b/winpr/libwinpr/path/test/TestPathCchAppend.c
new file mode 100644
index 0000000..93524ca
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathCchAppend.c
@@ -0,0 +1,151 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+static const TCHAR testBasePathBackslash[] = _T("C:\\Program Files\\");
+static const TCHAR testBasePathNoBackslash[] = _T("C:\\Program Files");
+static const TCHAR testMorePathBackslash[] = _T("\\Microsoft Visual Studio 11.0");
+static const TCHAR testMorePathNoBackslash[] = _T("Microsoft Visual Studio 11.0");
+static const TCHAR testPathOut[] = _T("C:\\Program Files\\Microsoft Visual Studio 11.0");
+
+int TestPathCchAppend(int argc, char* argv[])
+{
+ HRESULT status = 0;
+ TCHAR Path[PATHCCH_MAX_CCH];
+
+ WINPR_UNUSED(argc);
+ WINPR_UNUSED(argv);
+
+ /* Base Path: Backslash, More Path: No Backslash */
+
+ _tcscpy(Path, testBasePathBackslash);
+
+ status = PathCchAppend(Path, PATHCCH_MAX_CCH, testMorePathNoBackslash);
+
+ if (status != S_OK)
+ {
+ _tprintf(_T("PathCchAppend status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ if (_tcscmp(Path, testPathOut) != 0)
+ {
+ _tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathOut);
+ return -1;
+ }
+
+ /* Base Path: Backslash, More Path: Backslash */
+
+ _tcscpy(Path, testBasePathBackslash);
+
+ status = PathCchAppend(Path, PATHCCH_MAX_CCH, testMorePathBackslash);
+
+ if (status != S_OK)
+ {
+ _tprintf(_T("PathCchAppend status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ if (_tcscmp(Path, testPathOut) != 0)
+ {
+ _tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathOut);
+ return -1;
+ }
+
+ /* Base Path: No Backslash, More Path: Backslash */
+
+ _tcscpy(Path, testBasePathNoBackslash);
+
+ status = PathCchAppend(Path, PATHCCH_MAX_CCH, testMorePathBackslash);
+
+ if (status != S_OK)
+ {
+ _tprintf(_T("PathCchAppend status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ if (_tcscmp(Path, testPathOut) != 0)
+ {
+ _tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathOut);
+ return -1;
+ }
+
+ /* Base Path: No Backslash, More Path: No Backslash */
+
+ _tcscpy(Path, testBasePathNoBackslash);
+
+ status = PathCchAppend(Path, PATHCCH_MAX_CCH, testMorePathNoBackslash);
+
+ if (status != S_OK)
+ {
+ _tprintf(_T("PathCchAppend status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ if (_tcscmp(Path, testPathOut) != 0)
+ {
+ _tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path, testPathOut);
+ return -1;
+ }
+
+ /* According to msdn a NULL Path is an invalid argument */
+ status = PathCchAppend(NULL, PATHCCH_MAX_CCH, testMorePathNoBackslash);
+ if (status != E_INVALIDARG)
+ {
+ _tprintf(_T("PathCchAppend with NULL path unexpectedly returned status: 0x%08") _T(
+ PRIX32) _T("\n"),
+ status);
+ return -1;
+ }
+
+ /* According to msdn a NULL pszMore is an invalid argument (although optional !?) */
+ _tcscpy(Path, testBasePathNoBackslash);
+ status = PathCchAppend(Path, PATHCCH_MAX_CCH, NULL);
+ if (status != E_INVALIDARG)
+ {
+ _tprintf(_T("PathCchAppend with NULL pszMore unexpectedly returned status: 0x%08") _T(
+ PRIX32) _T("\n"),
+ status);
+ return -1;
+ }
+
+ /* According to msdn cchPath must be > 0 and <= PATHCCH_MAX_CCH */
+ _tcscpy(Path, testBasePathNoBackslash);
+ status = PathCchAppend(Path, 0, testMorePathNoBackslash);
+ if (status != E_INVALIDARG)
+ {
+ _tprintf(_T("PathCchAppend with cchPath value 0 unexpectedly returned status: 0x%08") _T(
+ PRIX32) _T("\n"),
+ status);
+ return -1;
+ }
+ _tcscpy(Path, testBasePathNoBackslash);
+ status = PathCchAppend(Path, PATHCCH_MAX_CCH + 1, testMorePathNoBackslash);
+ if (status != E_INVALIDARG)
+ {
+ _tprintf(_T("PathCchAppend with cchPath value > PATHCCH_MAX_CCH unexpectedly returned ")
+ _T("status: 0x%08") _T(PRIX32) _T("\n"),
+ status);
+ return -1;
+ }
+
+ /* Resulting file must not exceed PATHCCH_MAX_CCH */
+
+ for (size_t i = 0; i < PATHCCH_MAX_CCH - 1; i++)
+ Path[i] = _T('X');
+
+ Path[PATHCCH_MAX_CCH - 1] = 0;
+
+ status = PathCchAppend(Path, PATHCCH_MAX_CCH, _T("\\This cannot be appended to Path"));
+ if (SUCCEEDED(status))
+ {
+ _tprintf(_T("PathCchAppend unexepectedly succeeded with status: 0x%08") _T(PRIX32) _T("\n"),
+ status);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathCchAppendEx.c b/winpr/libwinpr/path/test/TestPathCchAppendEx.c
new file mode 100644
index 0000000..b6d83f5
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathCchAppendEx.c
@@ -0,0 +1,12 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+int TestPathCchAppendEx(int argc, char* argv[])
+{
+ printf("Warning: %s is not implemented!\n", __func__);
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathCchCanonicalize.c b/winpr/libwinpr/path/test/TestPathCchCanonicalize.c
new file mode 100644
index 0000000..a7fa4ce
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathCchCanonicalize.c
@@ -0,0 +1,12 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+int TestPathCchCanonicalize(int argc, char* argv[])
+{
+ printf("Warning: %s is not implemented!\n", __func__);
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathCchCanonicalizeEx.c b/winpr/libwinpr/path/test/TestPathCchCanonicalizeEx.c
new file mode 100644
index 0000000..2d670eb
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathCchCanonicalizeEx.c
@@ -0,0 +1,12 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+int TestPathCchCanonicalizeEx(int argc, char* argv[])
+{
+ printf("Warning: %s is not implemented!\n", __func__);
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathCchCombine.c b/winpr/libwinpr/path/test/TestPathCchCombine.c
new file mode 100644
index 0000000..4b6f4e4
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathCchCombine.c
@@ -0,0 +1,12 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+int TestPathCchCombine(int argc, char* argv[])
+{
+ printf("Warning: %s is not implemented!\n", __func__);
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathCchCombineEx.c b/winpr/libwinpr/path/test/TestPathCchCombineEx.c
new file mode 100644
index 0000000..89b794f
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathCchCombineEx.c
@@ -0,0 +1,12 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+int TestPathCchCombineEx(int argc, char* argv[])
+{
+ printf("Warning: %s is not implemented!\n", __func__);
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathCchFindExtension.c b/winpr/libwinpr/path/test/TestPathCchFindExtension.c
new file mode 100644
index 0000000..f4b4151
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathCchFindExtension.c
@@ -0,0 +1,116 @@
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+static const char testPathExtension[] = "C:\\Windows\\System32\\cmd.exe";
+
+int TestPathCchFindExtension(int argc, char* argv[])
+{
+ PCSTR pszExt = NULL;
+ PCSTR pszTmp = NULL;
+ HRESULT hr = 0;
+
+ WINPR_UNUSED(argc);
+ WINPR_UNUSED(argv);
+
+ /* Test invalid args */
+
+ hr = PathCchFindExtensionA(NULL, sizeof(testPathExtension), &pszExt);
+ if (SUCCEEDED(hr))
+ {
+ printf(
+ "PathCchFindExtensionA unexpectedly succeeded with pszPath = NULL. result: 0x%08" PRIX32
+ "\n",
+ hr);
+ return -1;
+ }
+
+ hr = PathCchFindExtensionA(testPathExtension, 0, &pszExt);
+ if (SUCCEEDED(hr))
+ {
+ printf("PathCchFindExtensionA unexpectedly succeeded with cchPath = 0. result: 0x%08" PRIX32
+ "\n",
+ hr);
+ return -1;
+ }
+
+ hr = PathCchFindExtensionA(testPathExtension, sizeof(testPathExtension), NULL);
+ if (SUCCEEDED(hr))
+ {
+ printf(
+ "PathCchFindExtensionA unexpectedly succeeded with ppszExt = NULL. result: 0x%08" PRIX32
+ "\n",
+ hr);
+ return -1;
+ }
+
+ /* Test missing null-termination of pszPath */
+
+ hr = PathCchFindExtensionA("c:\\45.789", 9, &pszExt); /* nb: correct would be 10 */
+ if (SUCCEEDED(hr))
+ {
+ printf("PathCchFindExtensionA unexpectedly succeeded with unterminated pszPath. result: "
+ "0x%08" PRIX32 "\n",
+ hr);
+ return -1;
+ }
+
+ /* Test passing of an empty terminated string (must succeed) */
+
+ pszExt = NULL;
+ pszTmp = "";
+ hr = PathCchFindExtensionA(pszTmp, 1, &pszExt);
+ if (hr != S_OK)
+ {
+ printf("PathCchFindExtensionA failed with an empty terminated string. result: 0x%08" PRIX32
+ "\n",
+ hr);
+ return -1;
+ }
+ /* pszExt must point to the strings terminating 0 now */
+ if (pszExt != pszTmp)
+ {
+ printf("PathCchFindExtensionA failed with an empty terminated string: pszExt pointer "
+ "mismatch\n");
+ return -1;
+ }
+
+ /* Test a path without file extension (must succeed) */
+
+ pszExt = NULL;
+ pszTmp = "c:\\4.678\\";
+ hr = PathCchFindExtensionA(pszTmp, 10, &pszExt);
+ if (hr != S_OK)
+ {
+ printf("PathCchFindExtensionA failed with a directory path. result: 0x%08" PRIX32 "\n", hr);
+ return -1;
+ }
+ /* The extension must not have been found and pszExt must point to the
+ * strings terminating NULL now */
+ if (pszExt != &pszTmp[9])
+ {
+ printf("PathCchFindExtensionA failed with a directory path: pszExt pointer mismatch\n");
+ return -1;
+ }
+
+ /* Non-special tests */
+
+ pszExt = NULL;
+ if (PathCchFindExtensionA(testPathExtension, sizeof(testPathExtension), &pszExt) != S_OK)
+ {
+ printf("PathCchFindExtensionA failure: expected S_OK\n");
+ return -1;
+ }
+
+ if (!pszExt || strcmp(pszExt, ".exe"))
+ {
+ printf("PathCchFindExtensionA failure: unexpected extension\n");
+ return -1;
+ }
+
+ printf("Extension: %s\n", pszExt);
+
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathCchIsRoot.c b/winpr/libwinpr/path/test/TestPathCchIsRoot.c
new file mode 100644
index 0000000..1ffda37
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathCchIsRoot.c
@@ -0,0 +1,12 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+int TestPathCchIsRoot(int argc, char* argv[])
+{
+ printf("Warning: %s is not implemented!\n", __func__);
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathCchRemoveBackslash.c b/winpr/libwinpr/path/test/TestPathCchRemoveBackslash.c
new file mode 100644
index 0000000..f23e72b
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathCchRemoveBackslash.c
@@ -0,0 +1,12 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+int TestPathCchRemoveBackslash(int argc, char* argv[])
+{
+ printf("Warning: %s is not implemented!\n", __func__);
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathCchRemoveBackslashEx.c b/winpr/libwinpr/path/test/TestPathCchRemoveBackslashEx.c
new file mode 100644
index 0000000..80eb1aa
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathCchRemoveBackslashEx.c
@@ -0,0 +1,12 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+int TestPathCchRemoveBackslashEx(int argc, char* argv[])
+{
+ printf("Warning: %s is not implemented!\n", __func__);
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathCchRemoveExtension.c b/winpr/libwinpr/path/test/TestPathCchRemoveExtension.c
new file mode 100644
index 0000000..bd315cb
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathCchRemoveExtension.c
@@ -0,0 +1,12 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+int TestPathCchRemoveExtension(int argc, char* argv[])
+{
+ printf("Warning: %s is not implemented!\n", __func__);
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathCchRemoveFileSpec.c b/winpr/libwinpr/path/test/TestPathCchRemoveFileSpec.c
new file mode 100644
index 0000000..686e367
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathCchRemoveFileSpec.c
@@ -0,0 +1,12 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+int TestPathCchRemoveFileSpec(int argc, char* argv[])
+{
+ printf("Warning: %s is not implemented!\n", __func__);
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathCchRenameExtension.c b/winpr/libwinpr/path/test/TestPathCchRenameExtension.c
new file mode 100644
index 0000000..cf021b1
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathCchRenameExtension.c
@@ -0,0 +1,12 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+int TestPathCchRenameExtension(int argc, char* argv[])
+{
+ printf("Warning: %s is not implemented!\n", __func__);
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathCchSkipRoot.c b/winpr/libwinpr/path/test/TestPathCchSkipRoot.c
new file mode 100644
index 0000000..dca5ad9
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathCchSkipRoot.c
@@ -0,0 +1,12 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+int TestPathCchSkipRoot(int argc, char* argv[])
+{
+ printf("Warning: %s is not implemented!\n", __func__);
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathCchStripPrefix.c b/winpr/libwinpr/path/test/TestPathCchStripPrefix.c
new file mode 100644
index 0000000..aaec4bc
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathCchStripPrefix.c
@@ -0,0 +1,128 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+/**
+ * Naming Files, Paths, and Namespaces:
+ * http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247/
+ */
+
+static const TCHAR testPathPrefixFileNamespace[] = _T("\\\\?\\C:\\Program Files\\");
+static const TCHAR testPathNoPrefixFileNamespace[] = _T("C:\\Program Files\\");
+static const TCHAR testPathPrefixFileNamespaceMinimum[] = _T("\\\\?\\C:");
+static const TCHAR testPathNoPrefixFileNamespaceMinimum[] = _T("C:");
+
+static const TCHAR testPathPrefixDeviceNamespace[] = _T("\\\\?\\GLOBALROOT");
+
+int TestPathCchStripPrefix(int argc, char* argv[])
+{
+ HRESULT status = 0;
+ TCHAR Path[PATHCCH_MAX_CCH];
+
+ WINPR_UNUSED(argc);
+ WINPR_UNUSED(argv);
+
+ /**
+ * PathCchStripPrefix returns S_OK if the prefix was removed, S_FALSE if
+ * the path did not have a prefix to remove, or an HRESULT failure code.
+ */
+
+ /* Path with prefix (File Namespace) */
+
+ _tcscpy(Path, testPathPrefixFileNamespace);
+
+ status = PathCchStripPrefix(Path, sizeof(testPathPrefixFileNamespace) / sizeof(TCHAR));
+
+ if (status != S_OK)
+ {
+ _tprintf(_T("PathCchStripPrefix status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ if (_tcscmp(Path, testPathNoPrefixFileNamespace) != 0)
+ {
+ _tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path,
+ testPathNoPrefixFileNamespace);
+ return -1;
+ }
+
+ /* Path with prefix (Device Namespace) */
+
+ _tcscpy(Path, testPathPrefixDeviceNamespace);
+
+ status = PathCchStripPrefix(Path, sizeof(testPathPrefixDeviceNamespace) / sizeof(TCHAR));
+
+ if (status != S_FALSE)
+ {
+ _tprintf(_T("PathCchStripPrefix status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ if (_tcscmp(Path, testPathPrefixDeviceNamespace) != 0)
+ {
+ _tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path,
+ testPathPrefixDeviceNamespace);
+ return -1;
+ }
+
+ /* NULL Path */
+ status = PathCchStripPrefix(NULL, PATHCCH_MAX_CCH);
+ if (status != E_INVALIDARG)
+ {
+ _tprintf(
+ _T("PathCchStripPrefix with null path unexpectedly succeeded with status 0x%08") _T(
+ PRIX32) _T("\n"),
+ status);
+ return -1;
+ }
+
+ /* Invalid cchPath values: 0, 1, 2, 3 and > PATHCCH_MAX_CCH */
+ for (int i = 0; i < 5; i++)
+ {
+ _tcscpy(Path, testPathPrefixFileNamespace);
+ if (i == 4)
+ i = PATHCCH_MAX_CCH + 1;
+ status = PathCchStripPrefix(Path, i);
+ if (status != E_INVALIDARG)
+ {
+ _tprintf(_T("PathCchStripPrefix with invalid cchPath value %d unexpectedly succeeded ")
+ _T("with status 0x%08") _T(PRIX32) _T("\n"),
+ i, status);
+ return -1;
+ }
+ }
+
+ /* Minimum Path that would get successfully stripped on windows */
+ _tcscpy(Path, testPathPrefixFileNamespaceMinimum);
+ size_t i = sizeof(testPathPrefixFileNamespaceMinimum) / sizeof(TCHAR);
+ i = i - 1; /* include testing of a non-null terminated string */
+ status = PathCchStripPrefix(Path, i);
+ if (status != S_OK)
+ {
+ _tprintf(_T("PathCchStripPrefix with minimum valid strippable path length unexpectedly ")
+ _T("returned status 0x%08") _T(PRIX32) _T("\n"),
+ status);
+ return -1;
+ }
+ if (_tcscmp(Path, testPathNoPrefixFileNamespaceMinimum))
+ {
+ _tprintf(_T("Path Mismatch: Actual: %s, Expected: %s\n"), Path,
+ testPathNoPrefixFileNamespaceMinimum);
+ return -1;
+ }
+
+ /* Invalid drive letter symbol */
+ _tcscpy(Path, _T("\\\\?\\5:"));
+ status = PathCchStripPrefix(Path, 6);
+ if (status == S_OK)
+ {
+ _tprintf(
+ _T("PathCchStripPrefix with invalid drive letter symbol unexpectedly succeeded\n"));
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathCchStripToRoot.c b/winpr/libwinpr/path/test/TestPathCchStripToRoot.c
new file mode 100644
index 0000000..3b96e5c
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathCchStripToRoot.c
@@ -0,0 +1,12 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+int TestPathCchStripToRoot(int argc, char* argv[])
+{
+ printf("Warning: %s is not implemented!\n", __func__);
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathIsUNCEx.c b/winpr/libwinpr/path/test/TestPathIsUNCEx.c
new file mode 100644
index 0000000..4fdf4f7
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathIsUNCEx.c
@@ -0,0 +1,52 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+static const TCHAR testServer[] = _T("server\\share\\path\\file");
+static const TCHAR testPathUNC[] = _T("\\\\server\\share\\path\\file");
+static const TCHAR testPathNotUNC[] = _T("C:\\share\\path\\file");
+
+int TestPathIsUNCEx(int argc, char* argv[])
+{
+ BOOL status = 0;
+ LPCTSTR Server = NULL;
+ TCHAR Path[PATHCCH_MAX_CCH];
+
+ WINPR_UNUSED(argc);
+ WINPR_UNUSED(argv);
+
+ /* Path is UNC */
+
+ _tcscpy(Path, testPathUNC);
+
+ status = PathIsUNCEx(Path, &Server);
+
+ if (!status)
+ {
+ _tprintf(_T("PathIsUNCEx status: 0x%d\n"), status);
+ return -1;
+ }
+
+ if (_tcscmp(Server, testServer) != 0)
+ {
+ _tprintf(_T("Server Name Mismatch: Actual: %s, Expected: %s\n"), Server, testServer);
+ return -1;
+ }
+
+ /* Path is not UNC */
+
+ _tcscpy(Path, testPathNotUNC);
+
+ status = PathIsUNCEx(Path, &Server);
+
+ if (status)
+ {
+ _tprintf(_T("PathIsUNCEx status: 0x%08") _T(PRIX32) _T("\n"), status);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathMakePath.c b/winpr/libwinpr/path/test/TestPathMakePath.c
new file mode 100644
index 0000000..488cab3
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathMakePath.c
@@ -0,0 +1,83 @@
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <winpr/crt.h>
+#include <winpr/file.h>
+#include <winpr/path.h>
+
+int TestPathMakePath(int argc, char* argv[])
+{
+ size_t baseLen = 0;
+ BOOL success = 0;
+ char tmp[64] = { 0 };
+ char* path = NULL;
+ char* cur = NULL;
+ char delim = PathGetSeparatorA(0);
+ char* base = GetKnownPath(KNOWN_PATH_TEMP);
+
+ WINPR_UNUSED(argc);
+ WINPR_UNUSED(argv);
+
+ if (!base)
+ {
+ fprintf(stderr, "Failed to get temporary directory!\n");
+ return -1;
+ }
+
+ baseLen = strlen(base);
+ srand(time(NULL));
+
+ for (int x = 0; x < 5; x++)
+ {
+ sprintf_s(tmp, ARRAYSIZE(tmp), "%08X", rand());
+ path = GetCombinedPath(base, tmp);
+ free(base);
+
+ if (!path)
+ {
+ fprintf(stderr, "GetCombinedPath failed!\n");
+ return -1;
+ }
+
+ base = path;
+ }
+
+ printf("Creating path %s\n", path);
+ success = winpr_PathMakePath(path, NULL);
+
+ if (!success)
+ {
+ fprintf(stderr, "MakePath failed!\n");
+ free(path);
+ return -1;
+ }
+
+ success = winpr_PathFileExists(path);
+
+ if (!success)
+ {
+ fprintf(stderr, "MakePath lied about success!\n");
+ free(path);
+ return -1;
+ }
+
+ while (strlen(path) > baseLen)
+ {
+ if (!winpr_RemoveDirectory(path))
+ {
+ fprintf(stderr, "winpr_RemoveDirectory %s failed!\n", path);
+ free(path);
+ return -1;
+ }
+
+ cur = strrchr(path, delim);
+
+ if (cur)
+ *cur = '\0';
+ }
+
+ free(path);
+ printf("%s success!\n", __func__);
+ return 0;
+}
diff --git a/winpr/libwinpr/path/test/TestPathShell.c b/winpr/libwinpr/path/test/TestPathShell.c
new file mode 100644
index 0000000..1925fea
--- /dev/null
+++ b/winpr/libwinpr/path/test/TestPathShell.c
@@ -0,0 +1,58 @@
+
+#include <stdio.h>
+#include <winpr/crt.h>
+#include <winpr/path.h>
+#include <winpr/tchar.h>
+#include <winpr/winpr.h>
+
+int TestPathShell(int argc, char* argv[])
+{
+ const int paths[] = { KNOWN_PATH_HOME, KNOWN_PATH_TEMP,
+ KNOWN_PATH_XDG_DATA_HOME, KNOWN_PATH_XDG_CONFIG_HOME,
+ KNOWN_PATH_XDG_CACHE_HOME, KNOWN_PATH_XDG_RUNTIME_DIR,
+ KNOWN_PATH_XDG_CONFIG_HOME };
+ const char* names[] = { "KNOWN_PATH_HOME", "KNOWN_PATH_TEMP",
+ "KNOWN_PATH_XDG_DATA_HOME", "KNOWN_PATH_XDG_CONFIG_HOME",
+ "KNOWN_PATH_XDG_CACHE_HOME", "KNOWN_PATH_XDG_RUNTIME_DIR",
+ "KNOWN_PATH_XDG_CONFIG_HOME" };
+ int rc = 0;
+
+ WINPR_UNUSED(argc);
+ WINPR_UNUSED(argv);
+
+ for (size_t x = 0; x < sizeof(paths) / sizeof(paths[0]); x++)
+ {
+ const int id = paths[x];
+ const char* name = names[x];
+ {
+ char* path = GetKnownPath(id);
+
+ if (!path)
+ {
+ fprintf(stderr, "GetKnownPath(%d) failed\n", id);
+ rc = -1;
+ }
+ else
+ {
+ printf("%s Path: %s\n", name, path);
+ }
+ free(path);
+ }
+ {
+ char* path = GetKnownSubPath(id, "freerdp");
+
+ if (!path)
+ {
+ fprintf(stderr, "GetKnownSubPath(%d) failed\n", id);
+ rc = -1;
+ }
+ else
+ {
+ printf("%s SubPath: %s\n", name, path);
+ }
+ free(path);
+ }
+ }
+
+ return rc;
+}