1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for SHExplorerParseCmdLine
5 * PROGRAMMERS: Thomas Faber <thomas.faber@reactos.org>
6 * Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
7 */
8
9 #include <apitest.h>
10
11 //#define UNICODE
12 #include <strsafe.h>
13 #include <shlobj.h>
14 #include <browseui_undoc.h>
15
16 // Macro parameters are only expanded in the second nesting...
17 #define _WIDEN(x) L##x
18 #define WIDEN(x) _WIDEN(x)
19
20 #define TEST_FILENAMEA "SHExplorerParseCmdLine.test"
21 #define TEST_FILENAMEW WIDEN(TEST_FILENAMEA)
22
23 #define TEST_PATHA "C:\\SHExplorerParseCmdLine.test"
24 #define TEST_PATHW WIDEN(TEST_PATHA)
25
26 typedef UINT_PTR (WINAPI *SHExplorerParseCmdLine_Type)(PEXPLORER_CMDLINE_PARSE_RESULTS);
27 static SHExplorerParseCmdLine_Type pSHExplorerParseCmdLine;
28
29 #define PIDL_IS_UNTOUCHED -1
30 #define PIDL_IS_NULL -2
31 #define PIDL_IS_PATH -3
32 #define PIDL_IS_EMPTY -4
33 #define PIDL_PATH_EQUALS_PATH -5
34
35 #define InvalidPointer ((PVOID)0x5555555555555555ULL)
36
37 static
ReplaceSubstr(_Out_ PWCHAR OutputStr,_In_ DWORD OutputLen,_In_ PCWSTR InputStr,_In_ PCWSTR ReplaceStr,_In_ PCWSTR ReplaceWith)38 DWORD ReplaceSubstr(
39 _Out_ PWCHAR OutputStr,
40 _In_ DWORD OutputLen,
41 _In_ PCWSTR InputStr,
42 _In_ PCWSTR ReplaceStr,
43 _In_ PCWSTR ReplaceWith)
44 {
45 DWORD result = 0;
46 PCWSTR pos;
47 PCWSTR pwc;
48
49 if (!OutputLen)
50 return result;
51
52 OutputStr[0] = 0;
53 pos = InputStr;
54 pwc = wcsstr(pos, ReplaceStr);
55 while (pwc)
56 {
57 if (StringCchCatNW(OutputStr, OutputLen, pos, pwc - pos) == STRSAFE_E_INSUFFICIENT_BUFFER)
58 break;
59 if (StringCchCatW(OutputStr, OutputLen, ReplaceWith) == STRSAFE_E_INSUFFICIENT_BUFFER)
60 break;
61 result++;
62 pos = pwc + wcslen(ReplaceStr);
63 pwc = wcsstr(pos, ReplaceStr);
64 }
65 StringCchCatW(OutputStr, OutputLen, pos);
66 return result;
67 }
68
69 static
70 VOID
TestCommandLine(_In_ ULONG TestLine,_In_ UINT_PTR ExpectedRet,_In_ INT ExpectedCsidl,_In_ DWORD ExpectedFlags,_In_ PCWSTR ExpectedFileName,_In_ PCWSTR PidlPath,_In_ PCWSTR pclsid,_Out_opt_ PUINT PWriteEnd)71 TestCommandLine(
72 _In_ ULONG TestLine,
73 _In_ UINT_PTR ExpectedRet,
74 _In_ INT ExpectedCsidl,
75 _In_ DWORD ExpectedFlags,
76 _In_ PCWSTR ExpectedFileName,
77 _In_ PCWSTR PidlPath,
78 _In_ PCWSTR pclsid,
79 _Out_opt_ PUINT PWriteEnd)
80 {
81 EXPLORER_CMDLINE_PARSE_RESULTS Info;
82 UINT_PTR Ret;
83 ULONG i;
84 PDWORD InfoWords = (PDWORD) &Info;
85
86 FillMemory(&Info, sizeof(Info), 0x55);
87 Info.dwFlags = 0x00000000;
88 Ret = pSHExplorerParseCmdLine(&Info);
89
90 // Special case for empty cmdline: Ret is the PIDL for the selected folder.
91 if (ExpectedRet == -1)
92 {
93 ok(Ret == (UINT_PTR)Info.pidlPath, "Line %lu: Ret = %p, expected %p\n", TestLine, (PVOID)Ret, Info.pidlPath);
94 }
95 else
96 {
97 ok(Ret == ExpectedRet, "Line %lu: Ret = 0x%Ix, expected 0x%Ix\n", TestLine, Ret, ExpectedRet);
98 }
99
100 if (ExpectedFileName == NULL)
101 {
102 ok(Info.strPath == InvalidPointer, "Line %lu: strPath = %p\n", TestLine, Info.strPath);
103 }
104 else
105 {
106 ok(Info.strPath != InvalidPointer, "Line %lu: strPath = InvalidPointer\n", TestLine);
107 ok(Info.strPath != NULL, "Line %lu: strPath = NULL\n", TestLine);
108 if (Info.strPath != NULL && Info.strPath != InvalidPointer)
109 {
110 ok(!wcscmp(Info.strPath, ExpectedFileName), "Line %lu: strPath = %ls, expected %ls\n", TestLine, Info.strPath, ExpectedFileName);
111 LocalFree(Info.strPath);
112 }
113 }
114
115 ok(Info.dwFlags == ExpectedFlags, "Line %lu: dwFlags = %08lx, expected %08lx\n", TestLine, Info.dwFlags, ExpectedFlags);
116
117 if (ExpectedCsidl == PIDL_IS_UNTOUCHED)
118 {
119 ok(Info.pidlPath == InvalidPointer, "Line %lu: pidlPath = %p\n", TestLine, Info.pidlPath);
120 }
121 else if (ExpectedCsidl == PIDL_IS_NULL)
122 {
123 ok(Info.pidlPath == NULL, "Line %lu: pidlPath = %p\n", TestLine, Info.pidlPath);
124 }
125 else
126 {
127 PIDLIST_ABSOLUTE ExpectedPidl;
128 HRESULT hr;
129
130 ok(Info.pidlPath != InvalidPointer, "Line %lu: pidlPath = InvalidPointer\n", TestLine);
131 ok(Info.pidlPath != NULL, "Line %lu: pidlPath = NULL\n", TestLine);
132 if (Info.pidlPath != NULL && Info.pidlPath != InvalidPointer)
133 {
134 WCHAR pidlPathName[MAX_PATH] = L"";
135 WCHAR pidlPathTest[MAX_PATH] = L"";
136 WCHAR rootDir[MAX_PATH] = L"";
137 WCHAR curDir[MAX_PATH] = L"";
138 WCHAR replaceName[MAX_PATH];
139
140 GetFullPathNameW(L"\\", _countof(rootDir), rootDir, NULL);
141
142 GetCurrentDirectoryW(_countof(curDir), curDir);
143 if (wcslen(curDir) != 0 && curDir[wcslen(curDir) - 1] != L'\\')
144 StringCchCatW(curDir, _countof(curDir), L"\\");
145
146 if (PidlPath)
147 {
148 StringCchCopyW(pidlPathTest, _countof(pidlPathTest), PidlPath);
149
150 if (wcsstr(pidlPathTest, L"::ROOT::") != NULL && wcslen(rootDir) > 0)
151 {
152 if (ReplaceSubstr(replaceName, _countof(replaceName), pidlPathTest, L"::ROOT::", rootDir))
153 StringCchCopyW(pidlPathTest, _countof(pidlPathTest), replaceName);
154 }
155
156 if (wcsstr(pidlPathTest, L"::CURDIR::") != NULL && wcslen(curDir) > 0)
157 {
158 if (ReplaceSubstr(replaceName, _countof(replaceName), pidlPathTest, L"::CURDIR::", curDir))
159 StringCchCopyW(pidlPathTest, _countof(pidlPathTest), replaceName);
160 }
161 }
162
163 SHGetPathFromIDListW(Info.pidlPath, pidlPathName);
164
165 if (ExpectedCsidl == PIDL_PATH_EQUALS_PATH)
166 {
167 ok(_wcsicmp(pidlPathName, pidlPathTest) == 0, "Line %lu: Path from pidl does not match; pidlPathName=%S\n", TestLine, pidlPathName);
168 }
169 else if (ExpectedCsidl == PIDL_IS_EMPTY)
170 {
171 ok(wcslen(pidlPathName) == 0, "Line %lu: Unexpected non-empty path from pidl; pidlPathName=%S\n", TestLine, pidlPathName);
172 }
173 else
174 {
175 if (ExpectedCsidl == PIDL_IS_PATH)
176 {
177 ExpectedPidl = SHSimpleIDListFromPath(pidlPathTest);
178 hr = ExpectedPidl == NULL ? E_FAIL : S_OK;
179 ok(ExpectedPidl != NULL, "Line %lu: SHSimpleIDListFromPath(%S) failed. pidlPathName=%S\n", TestLine, pidlPathTest, pidlPathName);
180 if (SUCCEEDED(hr))
181 {
182 ok(ILIsEqual(Info.pidlPath, ExpectedPidl), "Line %lu: Unexpected pidlPath value %p; pidlPathName=%S pidlPathTest=%S\n", TestLine, Info.pidlPath, pidlPathName, pidlPathTest);
183 ILFree(ExpectedPidl);
184 }
185 }
186 else
187 {
188 hr = SHGetFolderLocation(NULL, ExpectedCsidl, NULL, 0, &ExpectedPidl);
189 ok(hr == S_OK, "Line %lu: SHGetFolderLocation returned %08lx\n", TestLine, hr);
190 if (SUCCEEDED(hr))
191 {
192 BOOL eq = ILIsEqual(Info.pidlPath, ExpectedPidl);
193 ILFree(ExpectedPidl);
194
195 ok(eq, "Line %lu: Unexpected pidlPath value %p; pidlPathName=%S CSIDL=%d\n", TestLine, Info.pidlPath, pidlPathName, ExpectedCsidl);
196 }
197 }
198 }
199
200 ILFree(Info.pidlPath);
201 }
202 }
203
204 for (i = 0; i < sizeof(Info) / sizeof(DWORD); i++)
205 {
206 switch (i * sizeof(DWORD))
207 {
208 case FIELD_OFFSET(EXPLORER_CMDLINE_PARSE_RESULTS, strPath):
209 case FIELD_OFFSET(EXPLORER_CMDLINE_PARSE_RESULTS, pidlPath):
210 case FIELD_OFFSET(EXPLORER_CMDLINE_PARSE_RESULTS, dwFlags):
211 // TODO: 'case FIELD_OFFSET(EXPLORER_CMDLINE_PARSE_RESULTS, nCmdShow):'?
212 case FIELD_OFFSET(EXPLORER_CMDLINE_PARSE_RESULTS, pidlRoot):
213 // TODO: 'case FIELD_OFFSET(EXPLORER_CMDLINE_PARSE_RESULTS, clsid):'?
214 case FIELD_OFFSET(EXPLORER_CMDLINE_PARSE_RESULTS, guidInproc) + (0 * sizeof(DWORD)):
215 case FIELD_OFFSET(EXPLORER_CMDLINE_PARSE_RESULTS, guidInproc) + (1 * sizeof(DWORD)):
216 case FIELD_OFFSET(EXPLORER_CMDLINE_PARSE_RESULTS, guidInproc) + (2 * sizeof(DWORD)):
217 case FIELD_OFFSET(EXPLORER_CMDLINE_PARSE_RESULTS, guidInproc) + (3 * sizeof(DWORD)):
218 #ifdef _WIN64
219 case FIELD_OFFSET(EXPLORER_CMDLINE_PARSE_RESULTS, strPath) + sizeof(DWORD):
220 case FIELD_OFFSET(EXPLORER_CMDLINE_PARSE_RESULTS, pidlPath) + sizeof(DWORD):
221 case FIELD_OFFSET(EXPLORER_CMDLINE_PARSE_RESULTS, pidlRoot) + sizeof(DWORD):
222 #endif
223 break;
224 default:
225 ok(InfoWords[i] == 0x55555555, "Line %lu: Word 0x%02lx has been set to 0x%08lx\n", TestLine, i * sizeof(DWORD), InfoWords[i]);
226 }
227 }
228
229 {
230 LPOLESTR psz;
231 BYTE ab[sizeof(CLSID)];
232
233 StringFromCLSID(&Info.clsid, &psz);
234 if (pclsid == NULL)
235 {
236 FillMemory(ab, sizeof(ab), 0x55);
237 ok(memcmp(ab, &Info.clsid, sizeof(ab)) == 0, "Line %lu: CLSID was %ls.\n", TestLine, psz);
238 }
239 else
240 {
241 ok(lstrcmpiW(psz, pclsid) == 0, "Line %lu: CLSID was %ls.\n", TestLine, psz);
242 }
243 CoTaskMemFree(psz);
244 }
245
246 if (PWriteEnd)
247 {
248 PBYTE data = (PBYTE)&Info;
249
250 *PWriteEnd = 0;
251
252 for (i = sizeof(Info); i > 0; i--)
253 {
254 if (data[i - 1] != 0x55)
255 {
256 *PWriteEnd = i;
257 break;
258 }
259 }
260 }
261 }
262
START_TEST(SHExplorerParseCmdLine)263 START_TEST(SHExplorerParseCmdLine)
264 {
265 static struct
266 {
267 INT TestLine;
268 PCWSTR CommandLine;
269 UINT_PTR ExpectedRet;
270 INT ExpectedCsidl;
271 DWORD ExpectedFlags;
272 PCWSTR ExpectedFileName;
273 PCWSTR PidlPath;
274 PCWSTR pclsid;
275 } Tests [] =
276 {
277 { __LINE__, L"", -1, CSIDL_MYDOCUMENTS, 0x00000009 },
278 { __LINE__, L"/e", TRUE, PIDL_IS_UNTOUCHED, 0x00000008 },
279 { __LINE__, L"/n", TRUE, PIDL_IS_UNTOUCHED, 0x00004001 },
280 { __LINE__, L"/x", TRUE, PIDL_IS_NULL, 0x02000000, L"/x" },
281 { __LINE__, L"-e", TRUE, PIDL_IS_NULL, 0x02000000, L"-e" },
282 { __LINE__, L"C:\\", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\" },
283 { __LINE__, L"/e,C:\\", TRUE, PIDL_IS_PATH, 0x00000208, NULL, L"C:\\" },
284 { __LINE__, L"/select,C:\\", TRUE, PIDL_IS_PATH, 0x00000240, NULL, L"C:\\" },
285 { __LINE__, L"/e,::{20d04fe0-3aea-1069-a2d8-08002b30309d}", TRUE, PIDL_IS_PATH, 0x00000208, NULL, L"::{20d04fe0-3aea-1069-a2d8-08002b30309d}" },
286 { __LINE__, L"::{645ff040-5081-101b-9f08-00aa002f954e}", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"::{645ff040-5081-101b-9f08-00aa002f954e}" },
287 { __LINE__, L"/select,::{450d8fba-ad25-11d0-98a8-0800361b1103}", TRUE, PIDL_IS_PATH, 0x00000240, NULL, L"::{450d8fba-ad25-11d0-98a8-0800361b1103}" },
288 { __LINE__, L"=", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"::{20d04fe0-3aea-1069-a2d8-08002b30309d}" },
289 // { __LINE__, L".", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\Documents and Settings\\gigaherz\\Desktop" },
290 // { __LINE__, L"..", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\Documents and Settings\\gigaherz" },
291 { __LINE__, L"wrongpath", TRUE, PIDL_IS_NULL, 0x02000000, L"wrongpath"},
292 { __LINE__, L"%wrongdir%", TRUE, PIDL_IS_NULL, 0x02000000, L"%wrongdir%"},
293 { __LINE__, L"%programfiles#", TRUE, PIDL_IS_NULL, 0x02000000, L"%programfiles#"},
294 { __LINE__, L",", TRUE, PIDL_IS_EMPTY, 0x00000200},
295 { __LINE__, L"\\", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"::ROOT::" }, // disk letter depends on current directory
296 { __LINE__, L"c:\\", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\" },
297 { __LINE__, L"c:", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\" },
298 { __LINE__, L"c", TRUE, PIDL_IS_NULL, 0x02000000, L"c"},
299 { __LINE__, L"c:\\Program Files", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\Program Files" },
300 { __LINE__, L"c:\\Program Files\\", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\Program Files" },
301 { __LINE__, L"c:\\Program Files/", TRUE, PIDL_IS_NULL, 0x02000000, L"c:\\Program Files/"},
302 { __LINE__, L"c:/Program Files/", TRUE, PIDL_IS_NULL, 0x02000000, L"c:/Program Files/"},
303 { __LINE__, L"fonts", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"::CURDIR::fonts" }, // this would not fail if we are in Windows directory
304 { __LINE__, L"winsxs", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"::CURDIR::winsxs" },
305 { __LINE__, L"system32", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"::CURDIR::system32" },
306 { __LINE__, L"drivers", TRUE, PIDL_IS_NULL, 0x02000000, L"drivers" }, // this would fail since we are not in system32 directory
307 { __LINE__, L"spool", TRUE, PIDL_IS_NULL, 0x02000000, L"spool" },
308 // { __LINE__, L"wbem", TRUE, PIDL_IS_NULL, 0x02000000, L"wbem" },
309 { __LINE__, TEST_PATHW, TRUE, PIDL_IS_PATH, 0x00000200, NULL, TEST_PATHW },
310 { __LINE__, L"\"c:\\\"\"program files\"", TRUE, PIDL_IS_NULL, 0x02000000, L"c:\\\"program files"},
311 { __LINE__, L"\"c:\\\"program files", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\Program Files" },
312 { __LINE__, L"\"c:\\ \"program files", TRUE, PIDL_IS_NULL, 0x02000000, L"c:\\ program files"},
313 { __LINE__, L"\"c:\\\" program files", TRUE, PIDL_IS_NULL, 0x02000000, L"c:\\ program files"},
314 { __LINE__, L"\"c:\\\", \"c:\\program files\"", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\Program Files" },
315 { __LINE__, L"c:\\,c:\\program files", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\Program Files" },
316 { __LINE__, L"/root", FALSE, PIDL_IS_UNTOUCHED, 0x00000000 },
317 { __LINE__, L"\"/root\"", FALSE, PIDL_IS_UNTOUCHED, 0x00000000 },
318 { __LINE__, L"/root,", TRUE, PIDL_IS_UNTOUCHED, 0x00000000 },
319 { __LINE__, L"/root,c", TRUE, PIDL_IS_UNTOUCHED, 0x00000000 },
320 { __LINE__, L"/root,\"\"", TRUE, PIDL_IS_UNTOUCHED, 0x00000000 },
321 { __LINE__, L"/root,wrong", TRUE, PIDL_IS_UNTOUCHED, 0x00000000 },
322 { __LINE__, L"/root,0", TRUE, PIDL_IS_UNTOUCHED, 0x00000000 },
323 { __LINE__, L"/root,c:\\", TRUE, PIDL_PATH_EQUALS_PATH, 0x00000000, NULL, L"c:\\" },
324 { __LINE__, L"/root,\"c:\\\"", TRUE, PIDL_PATH_EQUALS_PATH, 0x00000000, NULL, L"c:\\" },
325 { __LINE__, L"/root \"c:\\\"", TRUE, PIDL_IS_NULL, 0x02000000, L"/root c:\\"},
326 { __LINE__, L"/root,\"c:\\\"\"program files\"", TRUE, PIDL_IS_UNTOUCHED, 0x00000000 },
327 { __LINE__, L"/root,\"c:\\\"program files", TRUE, PIDL_PATH_EQUALS_PATH, 0x00000000, NULL, L"c:\\Program Files" },
328 { __LINE__, L"/root,c:\\,c:\\Program Files", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\Program Files" },
329 { __LINE__, L"/root,c:\\,Program Files", TRUE, PIDL_IS_NULL, 0x02000000, L"Program Files"},
330 { __LINE__, L"/root,\"c:\\\"", TRUE, PIDL_PATH_EQUALS_PATH, 0x00000000, NULL, L"c:\\" },
331 { __LINE__, L"c:\\Program Files,/root,c:\\", TRUE, PIDL_PATH_EQUALS_PATH, 0x00000200, NULL, L"c:\\" },
332 // { __LINE__, L"a:\\,/root,c:\\", TRUE, PIDL_PATH_EQUALS_PATH, 0x00000200, NULL, L"c:\\" },
333 // { __LINE__, L"a:\\,/root,c", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"A:\\" },
334 { __LINE__, L"c:\\,/root,c", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\" },
335 { __LINE__, L"/select", TRUE, PIDL_IS_UNTOUCHED, 0x00000040 },
336 { __LINE__, L"/select,", TRUE, CSIDL_DRIVES, 0x00000240 },
337 { __LINE__, L"/select,c", TRUE, PIDL_IS_NULL, 0x02000040, L"c"},
338 { __LINE__, L"/select,0", TRUE, PIDL_IS_NULL, 0x02000040, L"0"},
339 { __LINE__, L"/select,c:\\", TRUE, PIDL_IS_PATH, 0x00000240, NULL, L"C:\\" },
340 { __LINE__, L"c:\\,/select", TRUE, PIDL_IS_PATH, 0x00000240, NULL, L"C:\\" },
341 { __LINE__, L"/select," TEST_PATHW, TRUE, PIDL_IS_PATH, 0x00000240, NULL, TEST_PATHW },
342 { __LINE__, L"/select,c:\\Program Files,c:\\Documents and settings", TRUE, PIDL_IS_PATH, 0x00000240, NULL, L"C:\\Documents and Settings" },
343 { __LINE__, L"c:\\,/select," TEST_FILENAMEW, TRUE, PIDL_IS_NULL, 0x02000240, TEST_FILENAMEW },
344 { __LINE__, L"c:\\,/select," TEST_PATHW, TRUE, PIDL_IS_PATH, 0x00000240, NULL, TEST_PATHW },
345 // { __LINE__, L"a:\\,/select," TEST_PATHW, TRUE, PIDL_IS_PATH, 0x00000240, NULL, TEST_PATHW },
346 { __LINE__, L"z:\\,/select," TEST_PATHW, TRUE, PIDL_IS_PATH, 0x02000240, L"z:\\", TEST_PATHW },
347 { __LINE__, L"select,c:\\ ", TRUE, PIDL_IS_PATH, 0x02000200, L"select", L"C:\\" },
348 { __LINE__, L"/select c:\\ ", TRUE, PIDL_IS_NULL, 0x02000000, L"/select c:\\"},
349 // { __LINE__, L"a:\\,/select,c:\\", TRUE, PIDL_IS_PATH, 0x00000240, NULL, L"C:\\" },
350 { __LINE__, L"a:\\,/select,c", TRUE, PIDL_IS_NULL, 0x02000040, L"c"},
351 { __LINE__, L"c:\\,/select,c", TRUE, PIDL_IS_NULL, 0x02000240, L"c"},
352 { __LINE__, L"/e", TRUE, PIDL_IS_UNTOUCHED, 0x00000008 },
353 { __LINE__, L"/e,", TRUE, CSIDL_DRIVES, 0x00000208 },
354 { __LINE__, L"/e,\"", TRUE, CSIDL_DRIVES, 0x00000208 },
355 { __LINE__, L"/e,\"\"", TRUE, CSIDL_DRIVES, 0x00000208 },
356 { __LINE__, L"/e,c:\\", TRUE, PIDL_IS_PATH, 0x00000208, NULL, L"C:\\" },
357 { __LINE__, L"c:\\,/e", TRUE, PIDL_IS_PATH, 0x00000208, NULL, L"C:\\" },
358 { __LINE__, L"/e,c", TRUE, PIDL_IS_NULL, 0x02000008, L"c"},
359 { __LINE__, L"/root,c:\\,/select," TEST_FILENAMEW, TRUE, PIDL_IS_NULL, 0x02000040, TEST_FILENAMEW },
360 { __LINE__, L"/select," TEST_FILENAMEW L",/root,c:\\", TRUE, PIDL_PATH_EQUALS_PATH, 0x02000040, TEST_FILENAMEW, L"c:\\" },
361 { __LINE__, L"/root,c:\\,/select," TEST_PATHW, TRUE, PIDL_IS_PATH, 0x00000240, NULL, TEST_PATHW },
362 { __LINE__, L"/select," TEST_PATHW L",/root,c:\\", TRUE, PIDL_PATH_EQUALS_PATH, 0x00000240, NULL, L"c:\\" },
363 { __LINE__, L"/e,/select," TEST_FILENAMEW L",/root,c:\\", TRUE, PIDL_PATH_EQUALS_PATH, 0x02000048, TEST_FILENAMEW, L"c:\\" },
364 { __LINE__, L"/e,/root,c:\\,/select," TEST_FILENAMEW, TRUE, PIDL_IS_NULL, 0x02000048, TEST_FILENAMEW },
365 { __LINE__, L"/e,/root,c:\\", TRUE, PIDL_PATH_EQUALS_PATH, 0x00000008, NULL, L"c:\\" },
366 { __LINE__, L"/e,c:\\,/select," TEST_FILENAMEW, TRUE, PIDL_IS_NULL, 0x02000248, TEST_FILENAMEW },
367 { __LINE__, L"c:\\,/e,/select," TEST_FILENAMEW, TRUE, PIDL_IS_NULL, 0x02000248, TEST_FILENAMEW },
368 { __LINE__, L"c:\\,/select," TEST_FILENAMEW L",/e", TRUE, PIDL_IS_NULL, 0x02000248, TEST_FILENAMEW },
369 { __LINE__, L"http:\\\\www.reactos.org", TRUE, PIDL_IS_NULL, 0x02000000, L"http:\\\\www.reactos.org"},
370 { __LINE__, L"/e,http:\\\\www.reactos.org", TRUE, PIDL_IS_NULL, 0x02000008, L"http:\\\\www.reactos.org"},
371 { __LINE__, L"/root,c:\\,http:\\\\www.reactos.org", TRUE, PIDL_IS_NULL, 0x02000000, L"http:\\\\www.reactos.org"},
372 { __LINE__, L"/separate ", TRUE, PIDL_IS_UNTOUCHED, 0x00020000 },
373 { __LINE__, L"/separate,c:\\ program files", TRUE, PIDL_IS_NULL, 0x02020000, L"c:\\ program files"},
374 { __LINE__, L"/separate, c:\\program files", TRUE, PIDL_IS_PATH, 0x00020200, NULL, L"C:\\Program Files" },
375 { __LINE__, L"/separate, c:\\program files ,/e", TRUE, PIDL_IS_PATH, 0x00020208, NULL, L"C:\\Program Files" },
376 { __LINE__, L"/separate, c:\\program files ,\\e", TRUE, PIDL_IS_NULL, 0x02020200, L"\\e"},
377 { __LINE__, L"c:\\Documents and settings,/separate,/n,/e,/root,c:\\,/select,c:\\Program files,", TRUE, CSIDL_DRIVES, 0x00024249 },
378 { __LINE__, L"c:\\Documents and settings,/separate,/n,/e,/root,{450D8FBA-AD25-11D0-98A8-0800361B1103, 0},test,/select,c:\\Program files,", TRUE, CSIDL_DRIVES, 0x02024249, L"test" },
379 { __LINE__, L"c:\\Documents and settings,/inproc,/noui,/s,/separate,/n,/e,/root,{450D8FBA-AD25-11D0-98A8-0800361B1103, 0},test,/select,c:\\Program files,", FALSE, PIDL_PATH_EQUALS_PATH, 0x00000200, NULL, L"C:\\Documents and Settings" },
380 { __LINE__, L"=", TRUE, CSIDL_DRIVES, 0x00000200 },
381 { __LINE__, L"=c:\\", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\" },
382 { __LINE__, L"=" TEST_PATHW, TRUE, PIDL_IS_PATH, 0x00000200, NULL, TEST_PATHW },
383 { __LINE__, L"/root,=", TRUE, CSIDL_DRIVES, 0x00000200 },
384 { __LINE__, L"/root=c:\\", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\" },
385 { __LINE__, L"/root=c:\\Program files", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\Program Files" },
386 { __LINE__, L"/root=\"c:\\Program files\"", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\Program Files" },
387 { __LINE__, L"/root=\"\"c:\\Program files\"\"", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\Program Files" },
388 { __LINE__, L"c:\\=/root=\"c:\\Program files\"", TRUE, PIDL_PATH_EQUALS_PATH, 0x00000000, NULL, L"C:\\Program Files" },
389 { __LINE__, L"/select=c:\\", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\" },
390 { __LINE__, L"/select=c:\\Program files", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\Program Files" },
391 { __LINE__, L"=,/select,c:\\", TRUE, PIDL_IS_PATH, 0x00000240, NULL, L"C:\\" },
392 { __LINE__, L"/select,c:\\,=", TRUE, CSIDL_DRIVES, 0x00000240 },
393 { __LINE__, L"c:\\=/select=c:\\windows\\system32", TRUE, PIDL_IS_PATH, 0x00000240, NULL, L"C:\\WINDOWS\\system32" },
394 { __LINE__, L"/select=c:\\windows\\system32", TRUE, PIDL_IS_PATH, 0x00000200, NULL, L"C:\\WINDOWS\\system32" },
395 { __LINE__, L"=/select=c:\\windows\\system32", TRUE, PIDL_IS_PATH, 0x00000240, NULL, L"C:\\WINDOWS\\system32" },
396 { __LINE__, L"/e,=", TRUE, CSIDL_DRIVES, 0x00000208 },
397 { __LINE__, L"/e=", TRUE, CSIDL_DRIVES, 0x00000200 },
398 { __LINE__, L"/e=\"", TRUE, CSIDL_DRIVES, 0x00000200 },
399 { __LINE__, L"/e=\"\"", TRUE, CSIDL_DRIVES, 0x00000200 },
400 { __LINE__, L"=\"=\"", TRUE, PIDL_IS_NULL, 0x02000000, L"="},
401 { __LINE__, L"==\"=\"", TRUE, PIDL_IS_NULL, 0x02000200, L"="},
402 { __LINE__, L"===\"=\"", TRUE, PIDL_IS_NULL, 0x02000200, L"="},
403 { __LINE__, L"=\"=\"", TRUE, PIDL_IS_NULL, 0x02000000, L"="},
404 { __LINE__, L"==\"==\"", TRUE, PIDL_IS_NULL, 0x02000200, L"=="},
405 { __LINE__, L"===\"===\"", TRUE, PIDL_IS_NULL, 0x02000200, L"==="},
406 { __LINE__, L"=\"=a\"", TRUE, PIDL_IS_NULL, 0x02000000, L"=a"},
407 { __LINE__, L"==\"=a=\"", TRUE, PIDL_IS_NULL, 0x02000200, L"=a="},
408 { __LINE__, L"===\"=a=a=\"", TRUE, PIDL_IS_NULL, 0x02000200, L"=a=a="},
409 { __LINE__, L"=\"=a\"==", TRUE, CSIDL_DRIVES, 0x02000200, L"=a" },
410 { __LINE__, L"==\"=a=\"=", TRUE, CSIDL_DRIVES, 0x02000200, L"=a=" },
411 { __LINE__, L"===\"=a=a=\"===", TRUE, CSIDL_DRIVES, 0x02000200, L"=a=a=" },
412 { __LINE__, L"=,=,=,\"=a=a=\",=,=,=", TRUE, CSIDL_DRIVES, 0x02000200, L"=a=a=" },
413 { __LINE__, L"\"", TRUE, CSIDL_DRIVES, 0x00000200 },
414 { __LINE__, L"\"\"", TRUE, CSIDL_DRIVES, 0x00000200 },
415 { __LINE__, L"\"\"\"", TRUE, PIDL_IS_NULL, 0x02000000, L"\""},
416 { __LINE__, L"\"\"\"\"", TRUE, PIDL_IS_NULL, 0x02000000, L"\""},
417 { __LINE__, L"\"\"\"\"\"", TRUE, PIDL_IS_NULL, 0x02000000, L"\"\""},
418 { __LINE__, L"/s", TRUE, PIDL_IS_UNTOUCHED, 0x00000002 },
419 { __LINE__, L"/noui", TRUE, PIDL_IS_UNTOUCHED, 0x00001000 },
420 { __LINE__, L"/idlist", TRUE, PIDL_IS_UNTOUCHED, 0x00000000},
421 { __LINE__, L"-embedding", TRUE, PIDL_IS_UNTOUCHED, 0x00000080 },
422 { __LINE__, L"/inproc", FALSE, PIDL_IS_UNTOUCHED, 0x00000000 },
423 { __LINE__, L"/inproc,1", FALSE, PIDL_IS_UNTOUCHED, 0x00000000 },
424 { __LINE__, L"/inproc,a", FALSE, PIDL_IS_UNTOUCHED, 0x00000000 },
425 { __LINE__, L"/inproc,c:\\", FALSE, PIDL_IS_UNTOUCHED, 0x00000000 },
426 { __LINE__, L"/inproc,\"c:\\\"", FALSE, PIDL_IS_UNTOUCHED, 0x00000000 },
427 { __LINE__, L"/inproc,{20d04fe0-3aea-1069-a2d8-08002b30309d}", TRUE, PIDL_IS_UNTOUCHED, 0x00000400 },
428 { __LINE__, L"shell:::{450D8FBA-AD25-11D0-98A8-0800361B1103}", TRUE, CSIDL_MYDOCUMENTS, 0x00000200 },
429 { __LINE__, L"::{450d8fba-ad25-11d0-98a8-0800361b1103}", TRUE, CSIDL_MYDOCUMENTS, 0x00000200 },
430 };
431 const int TestCount = sizeof(Tests) / sizeof(Tests[0]);
432 PWSTR CommandLine;
433 WCHAR OriginalCommandLine[1024];
434 int i;
435 UINT maxWrite = 0;
436 FILE * ff;
437 WCHAR winDir[MAX_PATH];
438
439 HMODULE browseui = LoadLibraryA("browseui.dll");
440 pSHExplorerParseCmdLine = (SHExplorerParseCmdLine_Type)GetProcAddress(browseui, MAKEINTRESOURCEA(107));
441 if (!pSHExplorerParseCmdLine)
442 {
443 skip("SHExplorerParseCmdLine not found, as on NT6+\n");
444 return;
445 }
446
447 CommandLine = GetCommandLineW();
448 StringCbCopyW(OriginalCommandLine, sizeof(OriginalCommandLine), CommandLine);
449
450 ff = fopen(TEST_PATHA, "wb");
451 fclose(ff);
452
453 GetWindowsDirectoryW(winDir, _countof(winDir));
454 SetCurrentDirectoryW(winDir);
455
456 for (i = 0; i < TestCount; i++)
457 {
458 UINT cWrite;
459
460 wcscpy(CommandLine, L"browseui_apitest.exe ");
461 wcscat(CommandLine, Tests[i].CommandLine);
462 trace("Command line (%d): %ls\n", Tests[i].TestLine, CommandLine);
463 TestCommandLine(Tests[i].TestLine,
464 Tests[i].ExpectedRet,
465 Tests[i].ExpectedCsidl,
466 Tests[i].ExpectedFlags,
467 Tests[i].ExpectedFileName,
468 Tests[i].PidlPath,
469 Tests[i].pclsid,
470 &cWrite);
471
472 if (cWrite > maxWrite)
473 maxWrite = cWrite;
474 }
475
476 trace("Writes reached the byte right before 0x%08x\n", maxWrite);
477
478 wcscpy(CommandLine, OriginalCommandLine);
479
480 remove(TEST_PATHA);
481 }
482