|
| 1 | +/* |
| 2 | + * PROJECT: ReactOS API tests |
| 3 | + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) |
| 4 | + * PURPOSE: Tests for PathProcessCommand |
| 5 | + * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ ([email protected]) |
| 6 | + */ |
| 7 | + |
| 8 | +#include "shelltest.h" |
| 9 | +#include <stdio.h> |
| 10 | + |
| 11 | +#define ok_wstri(x, y) \ |
| 12 | + ok(_wcsicmp(x, y) == 0, "Wrong string. Expected '%S', got '%S'\n", y, x) |
| 13 | + |
| 14 | +typedef LONG (WINAPI *FN_PathProcessCommand)(LPCWSTR, LPWSTR, INT, DWORD); |
| 15 | + |
| 16 | +static FN_PathProcessCommand s_PathProcessCommand = NULL; |
| 17 | + |
| 18 | +static void |
| 19 | +Test_PathProcessCommand(void) |
| 20 | +{ |
| 21 | + WCHAR buffer[MAX_PATH], szCalcExe[MAX_PATH]; |
| 22 | + LONG result; |
| 23 | + FILE *fout; |
| 24 | + WCHAR szCurDir[MAX_PATH]; |
| 25 | + WCHAR szFull1[MAX_PATH], szFull2[MAX_PATH], szFull3[MAX_PATH], szFull4[MAX_PATH]; |
| 26 | + WCHAR szFull5[MAX_PATH]; |
| 27 | + |
| 28 | + fout = _wfopen(L"_Test.exe", L"wb"); |
| 29 | + fclose(fout); |
| 30 | + fout = _wfopen(L"test with spaces.exe", L"wb"); |
| 31 | + fclose(fout); |
| 32 | + |
| 33 | + GetFullPathNameW(L".", _countof(szCurDir), szCurDir, NULL); |
| 34 | + GetShortPathNameW(szCurDir, szCurDir, _countof(szCurDir)); |
| 35 | + |
| 36 | + lstrcpynW(szFull1, szCurDir, _countof(szFull1)); |
| 37 | + lstrcpynW(szFull2, szCurDir, _countof(szFull2)); |
| 38 | + lstrcpynW(szFull4, szCurDir, _countof(szFull4)); |
| 39 | + lstrcpynW(szFull5, szCurDir, _countof(szFull5)); |
| 40 | + |
| 41 | + lstrcatW(szFull1, L"\\_Test.exe"); |
| 42 | + lstrcatW(szFull2, L"\\test with spaces.exe"); |
| 43 | + wsprintfW(szFull3, L"\"%s\"", szFull2); |
| 44 | + lstrcatW(szFull4, L"\\_Test.exe arg1 arg2"); |
| 45 | + lstrcatW(szFull5, L"\\_TestDir.exe"); |
| 46 | + |
| 47 | + CreateDirectoryW(L"_TestDir.exe", NULL); |
| 48 | + |
| 49 | + // Test case 1: Basic functionality (no flags) |
| 50 | + lstrcpynW(buffer, L"<>", _countof(buffer)); |
| 51 | + result = s_PathProcessCommand(L"_Test", buffer, _countof(buffer), 0); |
| 52 | + ok_int(result, lstrlenW(szFull1) + 1); |
| 53 | + ok_wstri(buffer, szFull1); |
| 54 | + |
| 55 | + // Test case 2: Quoted path |
| 56 | + lstrcpynW(buffer, L"<>", _countof(buffer)); |
| 57 | + result = s_PathProcessCommand(L"\"test with spaces\"", buffer, _countof(buffer), 0); |
| 58 | + ok_int(result, lstrlenW(szFull2) + 1); |
| 59 | + ok_wstri(buffer, szFull2); |
| 60 | + |
| 61 | + // Test case 3: Add quotes flag |
| 62 | + lstrcpynW(buffer, L"<>", _countof(buffer)); |
| 63 | + result = s_PathProcessCommand(L"test with spaces", buffer, _countof(buffer), PPCF_ADDQUOTES); |
| 64 | + ok_int(result, lstrlenW(szFull3) + 1); |
| 65 | + ok_wstri(buffer, szFull3); |
| 66 | + |
| 67 | + // Test case 4: Add arguments flag |
| 68 | + lstrcpynW(buffer, L"<>", _countof(buffer)); |
| 69 | + result = s_PathProcessCommand(L"_Test arg1 arg2", buffer, _countof(buffer), PPCF_ADDARGUMENTS); |
| 70 | + ok_int(result, lstrlenW(szFull4) + 1); |
| 71 | + ok_wstri(buffer, szFull4); |
| 72 | + |
| 73 | + // calc.exe |
| 74 | + GetSystemDirectoryW(szCalcExe, _countof(szCalcExe)); |
| 75 | + PathAppendW(szCalcExe, L"calc.exe"); |
| 76 | + |
| 77 | + // Test case 5: Longest possible flag |
| 78 | + lstrcpynW(buffer, L"<>", _countof(buffer)); |
| 79 | + result = s_PathProcessCommand(szCalcExe, buffer, _countof(buffer), PPCF_LONGESTPOSSIBLE); |
| 80 | + ok_int(result, lstrlenW(szCalcExe) + 1); |
| 81 | + ok_wstri(buffer, szCalcExe); |
| 82 | + |
| 83 | + // Test case 6: Buffer too small |
| 84 | + lstrcpynW(buffer, L"<>", _countof(buffer)); |
| 85 | + result = s_PathProcessCommand(L"_Test.exe", buffer, 5, 0); |
| 86 | + ok_int(result, -1); |
| 87 | + ok_wstri(buffer, L"<>"); |
| 88 | + |
| 89 | + // Test case 7: Null input path |
| 90 | + lstrcpynW(buffer, L"<>", _countof(buffer)); |
| 91 | + result = s_PathProcessCommand(NULL, buffer, _countof(buffer), 0); |
| 92 | + ok_int(result, -1); |
| 93 | + ok_wstri(buffer, L"<>"); |
| 94 | + |
| 95 | + // Test case 8: Relative path resolution |
| 96 | + lstrcpynW(buffer, L"<>", _countof(buffer)); |
| 97 | + result = s_PathProcessCommand(L"_Test.exe", buffer, _countof(buffer), PPCF_FORCEQUALIFY); |
| 98 | + ok_int(result, lstrlenW(szFull1) + 1); |
| 99 | + ok_wstri(buffer, szFull1); |
| 100 | + |
| 101 | + // Test case 9: No directories |
| 102 | + lstrcpynW(buffer, L"<>", _countof(buffer)); |
| 103 | + result = s_PathProcessCommand(L"_TestDir.exe", buffer, _countof(buffer), PPCF_NODIRECTORIES); |
| 104 | + ok_int(result, -1); |
| 105 | + ok_wstri(buffer, L"<>"); |
| 106 | + |
| 107 | + // Test case 10: With directories |
| 108 | + lstrcpynW(buffer, L"<>", _countof(buffer)); |
| 109 | + result = s_PathProcessCommand(L"_TestDir.exe", buffer, _countof(buffer), 0); |
| 110 | + ok_int(result, lstrlenW(szFull5) + 1); |
| 111 | + ok_wstri(buffer, szFull5); |
| 112 | + |
| 113 | + RemoveDirectoryW(L"_TestDir.exe"); |
| 114 | + DeleteFileW(L"_Test.exe"); |
| 115 | + DeleteFileW(L"test with spaces.exe"); |
| 116 | +} |
| 117 | + |
| 118 | +START_TEST(PathProcessCommand) |
| 119 | +{ |
| 120 | + WCHAR szCurDir[MAX_PATH], szTempDir[MAX_PATH]; |
| 121 | + |
| 122 | + s_PathProcessCommand = (FN_PathProcessCommand) |
| 123 | + GetProcAddress(GetModuleHandleW(L"shell32"), "PathProcessCommand"); |
| 124 | + if (!s_PathProcessCommand) |
| 125 | + { |
| 126 | + s_PathProcessCommand = (FN_PathProcessCommand) |
| 127 | + GetProcAddress(GetModuleHandleW(L"shell32"), MAKEINTRESOURCEA(653)); |
| 128 | + } |
| 129 | + if (!s_PathProcessCommand) |
| 130 | + { |
| 131 | + skip("PathProcessCommand not found\n"); |
| 132 | + return; |
| 133 | + } |
| 134 | + |
| 135 | + GetCurrentDirectoryW(_countof(szCurDir), szCurDir); |
| 136 | + GetEnvironmentVariableW(L"TEMP", szTempDir, _countof(szTempDir)); |
| 137 | + SetCurrentDirectoryW(szTempDir); |
| 138 | + |
| 139 | + SetEnvironmentVariableW(L"PATH", szTempDir); |
| 140 | + |
| 141 | + Test_PathProcessCommand(); |
| 142 | + |
| 143 | + SetCurrentDirectoryW(szCurDir); |
| 144 | +} |
0 commit comments