Reactos
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 (katayama.hirofumi.mz@gmail.com)
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
14typedef LONG (WINAPI *FN_PathProcessCommand)(LPCWSTR, LPWSTR, INT, DWORD);
15
16static FN_PathProcessCommand s_PathProcessCommand = NULL;
17
18static void
19Test_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
118START_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}