ReactOS  0.4.15-dev-3163-gf17c2c0
ACListISF.cpp
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS api tests
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: Test for ACListISF objects
5  * COPYRIGHT: Copyright 2016 Mark Jansen <mark.jansen@reactos.org>
6  * Copyright 2021 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
7  */
8 
9 #define _UNICODE
10 #define UNICODE
11 #include <apitest.h>
12 #include <shlobj.h>
13 #include <atlbase.h>
14 #include <tchar.h> //
15 #include <atlcom.h> // These 3 includes only exist here to make gcc happy about (unused) templates..
16 #include <atlwin.h> //
17 
18 // Yes, gcc at it again, let's validate everything found inside unused templates!
20 
21 #include <stdio.h>
22 #include <shellutils.h>
23 #include <shlwapi.h>
24 #include <strsafe.h>
25 
26 static bool g_ShowHidden;
28 #define WINVER_VISTA 0x0600
29 
30 
31 #define ok_hr(status, expected) ok_hex(status, expected)
32 
33 // We do not want our results to originate from the helper functions, so have them originate from the calls to them
34 #define test_at_end (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : test_at_end_imp
35 #define test_ExpectDrives (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : test_ExpectDrives_imp
36 #define test_ExpectFolders (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : test_ExpectFolders_imp
37 #define winetest_ok_hr(expression, expected) \
38  do { \
39  int _value = (expression); \
40  winetest_ok(_value == (expected), "Wrong value for '%s', expected: " #expected " (0x%x), got: 0x%x\n", \
41  #expression, (int)(expected), _value); \
42  } while (0)
43 
44 static void test_at_end_imp(CComPtr<IEnumString>& EnumStr)
45 {
46  CComHeapPtr<OLECHAR> Result;
47  ULONG Fetched = 12345;
48  HRESULT hr = EnumStr->Next(1, &Result, &Fetched);
49  winetest_ok(hr == S_FALSE, "Expected hr to be S_FALSE, was 0x%lx\n", hr);
50  winetest_ok(Fetched == 0u, "Expected Fetched to be 0, was: %lu\n", Fetched);
51  if (Fetched == 1u)
52  winetest_ok(0, "Expected there not to be a result, got: %s\n", wine_dbgstr_w(Result));
53 }
54 
55 static bool GetDisplayname(CComPtr<IShellFolder>& spDrives, CComHeapPtr<ITEMIDLIST>& pidl, CComHeapPtr<WCHAR>& DisplayName)
56 {
57  STRRET StrRet;
58  HRESULT hr;
59  winetest_ok_hr(hr = spDrives->GetDisplayNameOf(pidl, SHGDN_INFOLDER | SHGDN_FORPARSING | SHGDN_FORADDRESSBAR, &StrRet), S_OK);
60  if (!SUCCEEDED(hr))
61  return false;
62 
63  winetest_ok_hr(hr = StrRetToStrW(&StrRet, NULL, &DisplayName), S_OK);
64  if (!SUCCEEDED(hr))
65  return false;
66  return true;
67 }
68 
70 {
71  None = 0,
73  CheckLast = 2,
76 };
77 
78 // wtf c++
80 {
81  return static_cast<ExpectOptions>(static_cast<int>(left) | static_cast<int>(right));
82 }
83 
84 
85 static void
86 test_ExpectFolders_imp(CComPtr<IEnumString>& EnumStr, LPITEMIDLIST pidlTarget, const WCHAR* Root, ExpectOptions options)
87 {
88  CComPtr<IShellFolder> spDesktop;
89  HRESULT hr = SHGetDesktopFolder(&spDesktop);
90 
91  CComPtr<IShellFolder> spTarget;
92  if (pidlTarget)
93  {
94  winetest_ok_hr(hr = spDesktop->BindToObject(pidlTarget, NULL, IID_PPV_ARG(IShellFolder, &spTarget)), S_OK);
95  if (!SUCCEEDED(hr))
96  return;
97  }
98  else
99  {
100  spTarget = spDesktop;
101  }
102 
103  SHCONTF EnumFlags = SHCONTF_FOLDERS | SHCONTF_INIT_ON_FIRST_NEXT;
104  if (g_ShowHidden && !(options & IgnoreHidden))
105  EnumFlags |= SHCONTF_INCLUDEHIDDEN;
106  if (!(options & IgnoreFiles))
107  EnumFlags |= SHCONTF_NONFOLDERS;
108 
109  CComPtr<IEnumIDList> spEnumIDList;
110  winetest_ok_hr(hr = spTarget->EnumObjects(NULL, EnumFlags, &spEnumIDList), S_OK);
111  if (!SUCCEEDED(hr))
112  return;
113 
114  WCHAR Buffer[512];
115  CComHeapPtr<ITEMIDLIST> pidl;
116  INT Count = 0;
117  while (spEnumIDList->Next(1, &pidl, NULL) == S_OK)
118  {
119  CComHeapPtr<WCHAR> DisplayName;
120  if (!GetDisplayname(spTarget, pidl, DisplayName))
121  break;
122 
123  CComHeapPtr<OLECHAR> Result;
124  ULONG Fetched;
125  hr = EnumStr->Next(1, &Result, &Fetched);
127 
128  if (hr != S_OK)
129  break;
130 
131  StringCchPrintfW(Buffer, _ARRAYSIZE(Buffer), L"%s%s", (options & IgnoreRoot) ? L"" : Root, (WCHAR*)DisplayName);
132 
133  winetest_ok(!wcscmp(Buffer, Result), "Expected %s, got %s\n", wine_dbgstr_w(Buffer), wine_dbgstr_w(Result));
134 
135  pidl.Free();
136  Count++;
137  }
138  if (options & CheckLast)
139  {
140  test_at_end_imp(EnumStr);
141  }
142 }
143 
144 static void
145 test_ExpectDrives_imp(CComPtr<IEnumString>& EnumStr, CComHeapPtr<ITEMIDLIST>& pidlTarget)
146 {
147  test_ExpectFolders_imp(EnumStr, pidlTarget, NULL, IgnoreRoot | CheckLast);
148 }
149 
150 static void
152 {
153  CComPtr<IEnumString> EnumStr;
154  HRESULT hr = CoCreateInstance(CLSID_ACListISF, NULL, CLSCTX_ALL, IID_PPV_ARG(IEnumString, &EnumStr));
155  ok_hr(hr, S_OK);
156  if (!SUCCEEDED(hr))
157  {
158  skip("CoCreateInstance failed\n");
159  return;
160  }
161 
162  CComPtr<IACList2> ACList;
163  ok_hr(hr = EnumStr->QueryInterface(IID_IACList2, (void**)&ACList), S_OK);
164  if (!SUCCEEDED(hr))
165  {
166  skip("QueryInterface failed\n");
167  return;
168  }
169 
170  ok_hr(hr = ACList->SetOptions(ACLO_NONE), S_OK);
171  test_at_end(EnumStr);
172 
173 
176  Buffer[3] = '\0';
177 
178  CComHeapPtr<ITEMIDLIST> pidlDiskRoot;
179  ok_hr(hr = SHParseDisplayName(Buffer, NULL, &pidlDiskRoot, NULL, NULL), S_OK);
180  if (!SUCCEEDED(hr))
181  {
182  skip("SHParseDisplayName failed\n");
183  return;
184  }
185 
186  ok_hr(hr = ACList->Expand(Buffer), S_OK);
187  test_ExpectFolders(EnumStr, pidlDiskRoot, Buffer, CheckLast | IgnoreHidden);
188 
189  ok_hr(hr = EnumStr->Reset(), S_OK);
190  ok_hr(hr = ACList->Expand(Buffer), S_OK);
191  ok_hr(hr = ACList->SetOptions(ACLO_NONE), S_OK);
192  test_ExpectFolders(EnumStr, pidlDiskRoot, Buffer, CheckLast);
193 }
194 
195 static void
197 {
198  CComPtr<IEnumString> EnumStr;
199  HRESULT hr = CoCreateInstance(CLSID_ACListISF, NULL, CLSCTX_ALL, IID_PPV_ARG(IEnumString, &EnumStr));
200  ok_hr(hr, S_OK);
201  if (!SUCCEEDED(hr))
202  {
203  skip("CoCreateInstance failed\n");
204  return;
205  }
206 
207  CComPtr<IACList2> ACList;
208  ok_hr(hr = EnumStr->QueryInterface(IID_IACList2, (void**)&ACList), S_OK);
209  if (!SUCCEEDED(hr))
210  {
211  skip("QueryInterface failed\n");
212  return;
213  }
214 
215  CComPtr<ICurrentWorkingDirectory> CurrentWorkingDir;
216  ok_hr(hr = EnumStr->QueryInterface(IID_ICurrentWorkingDirectory, (void**)&CurrentWorkingDir), S_OK);
217  if (!SUCCEEDED(hr))
218  {
219  skip("QueryInterface failed\n");
220  return;
221  }
222 
223  ok_hr(hr = ACList->SetOptions(ACLO_CURRENTDIR), S_OK);
224  test_at_end(EnumStr);
225 
226 
227  WCHAR Buffer[MAX_PATH] = { 1, 1, 1, 1, 1, 0 }, Buffer2[MAX_PATH];
229  ok_hr(hr = CurrentWorkingDir->GetDirectory(Buffer, _ARRAYSIZE(Buffer)), E_NOTIMPL);
230  else
231  ok_hr(hr = CurrentWorkingDir->GetDirectory(Buffer, _ARRAYSIZE(Buffer)), E_UNEXPECTED);
232  ok(!wcscmp(L"\x1\x1\x1\x1\x1", Buffer), "Expected %s, got %s\n", wine_dbgstr_w(L"\x1\x1\x1\x1\x1"), wine_dbgstr_w(Buffer));
233 
234  GetSystemWindowsDirectoryW(Buffer2, _ARRAYSIZE(Buffer2));
235  // Windows 2k3 does not parse it without the trailing '\\'
236  Buffer2[3] = '\0';
237  CComHeapPtr<ITEMIDLIST> pidlDiskRoot;
238  ok_hr(hr = SHParseDisplayName(Buffer2, NULL, &pidlDiskRoot, NULL, NULL), S_OK);
239  if (!SUCCEEDED(hr))
240  return;
241 
242  ok_hr(hr = CurrentWorkingDir->SetDirectory(Buffer2), S_OK);
243  test_at_end(EnumStr);
244 
245  Buffer[0] = '\0';
247  {
248  ok_hr(hr = CurrentWorkingDir->GetDirectory(Buffer, _ARRAYSIZE(Buffer)), E_NOTIMPL);
249  }
250  else
251  {
252  ok_hr(hr = CurrentWorkingDir->GetDirectory(Buffer, _ARRAYSIZE(Buffer)), S_OK);
253  ok(!wcscmp(Buffer2, Buffer), "Expected %s, got %s\n", wine_dbgstr_w(Buffer2), wine_dbgstr_w(Buffer));
254  }
255 
256  Buffer2[2] = '\0';
257  ok_hr(hr = CurrentWorkingDir->SetDirectory(Buffer2), S_OK);
258  test_at_end(EnumStr);
259 
260  Buffer[0] = '\0';
261  Buffer2[2] = '\\';
263  {
264  ok_hr(hr = CurrentWorkingDir->GetDirectory(Buffer, _ARRAYSIZE(Buffer)), E_NOTIMPL);
265  }
266  else
267  {
268  ok_hr(hr = CurrentWorkingDir->GetDirectory(Buffer, _ARRAYSIZE(Buffer)), S_OK);
269  ok(!wcscmp(Buffer2, Buffer), "Expected %s, got %s\n", wine_dbgstr_w(Buffer2), wine_dbgstr_w(Buffer));
270  }
271 
272  ok_hr(hr = ACList->Expand(Buffer2), S_OK);
273  // The first set of results are absolute paths, without hidden files?!
274  test_ExpectFolders(EnumStr, pidlDiskRoot, Buffer2, IgnoreHidden);
275  test_ExpectFolders(EnumStr, pidlDiskRoot, Buffer2, IgnoreHidden | IgnoreRoot | CheckLast);
276 
277  WCHAR szDir[MAX_PATH], szPath[MAX_PATH];
278  Buffer2[2] = 0;
279  StringCbCopyW(szDir, sizeof(szDir), Buffer2);
280 
281  StringCbCopyW(szPath, sizeof(szPath), szDir);
282  StringCbCatW(szPath, sizeof(szPath), L"\\BROWSEUI-1");
284 
285  StringCbCopyW(szPath, sizeof(szPath), szDir);
286  StringCbCatW(szPath, sizeof(szPath), L"\\BROWSEUI-1\\TEST1");
288 
289  StringCbCopyW(szPath, sizeof(szPath), szDir);
290  StringCbCatW(szPath, sizeof(szPath), L"\\BROWSEUI-1\\TEST2");
292 
293  StringCbCopyW(szPath, sizeof(szPath), szDir);
294  StringCbCatW(szPath, sizeof(szPath), L"\\BROWSEUI-2");
296 
297  StringCbCopyW(szPath, sizeof(szPath), szDir);
298  StringCbCatW(szPath, sizeof(szPath), L"\\BROWSEUI-2\\tes1");
300 
301  StringCbCopyW(szPath, sizeof(szPath), szDir);
302  StringCbCatW(szPath, sizeof(szPath), L"\\BROWSEUI-2\\tes2");
304 
305  ULONG cGot;
306  LPWSTR psz = NULL;
307  EnumStr->Reset();
308 
309  StringCbCopyW(szPath, sizeof(szPath), szDir);
310  StringCbCatW(szPath, sizeof(szPath), L"\\BROWSEUI-1\\");
311  ok_hr(hr = ACList->Expand(szPath), S_OK);
312 
313  hr = EnumStr->Next(1, &psz, &cGot);
314  ok_hr(hr, S_OK);
315  StringCbCopyW(szPath, sizeof(szPath), szDir);
316  StringCbCatW(szPath, sizeof(szPath), L"\\BROWSEUI-1\\TEST1");
317  ok_wstr(szPath, psz);
318  CoTaskMemFree(psz);
319 
320  hr = EnumStr->Next(1, &psz, &cGot);
321  ok_hr(hr, S_OK);
322  StringCbCopyW(szPath, sizeof(szPath), szDir);
323  StringCbCatW(szPath, sizeof(szPath), L"\\BROWSEUI-1\\TEST2");
324  ok_wstr(szPath, psz);
325  CoTaskMemFree(psz);
326 
327  StringCbCopyW(szPath, sizeof(szPath), szDir);
328  StringCbCatW(szPath, sizeof(szPath), L"\\BROWSEUI-2\\");
329  ok_hr(hr = CurrentWorkingDir->SetDirectory(szPath), S_OK);
330 
331  hr = EnumStr->Next(1, &psz, &cGot);
332  ok_hr(hr, S_OK);
333  ok_wstr(psz, L"tes1");
334  CoTaskMemFree(psz);
335 
336  hr = EnumStr->Next(1, &psz, &cGot);
337  ok_hr(hr, S_OK);
338  ok_wstr(psz, L"tes2");
339  CoTaskMemFree(psz);
340 
341  StringCbCopyW(szPath, sizeof(szPath), szDir);
342  StringCbCatW(szPath, sizeof(szPath), L"\\BROWSEUI-2");
343  ok_hr(hr = CurrentWorkingDir->SetDirectory(szPath), S_OK);
344 
345  EnumStr->Reset();
346 
347  hr = EnumStr->Next(1, &psz, &cGot);
348  ok_hr(hr, S_OK);
349  ok_wstr(psz, L"tes1");
350  CoTaskMemFree(psz);
351 
352  hr = EnumStr->Next(1, &psz, &cGot);
353  ok_hr(hr, S_OK);
354  ok_wstr(psz, L"tes2");
355  CoTaskMemFree(psz);
356 
357  StringCbCopyW(szPath, sizeof(szPath), szDir);
358  StringCbCatW(szPath, sizeof(szPath), L"\\BROWSEUI-1\\TEST1");
360 
361  StringCbCopyW(szPath, sizeof(szPath), szDir);
362  StringCbCatW(szPath, sizeof(szPath), L"\\BROWSEUI-1\\TEST2");
364 
365  StringCbCopyW(szPath, sizeof(szPath), szDir);
366  StringCbCatW(szPath, sizeof(szPath), L"\\BROWSEUI-1");
368 
369  StringCbCopyW(szPath, sizeof(szPath), szDir);
370  StringCbCatW(szPath, sizeof(szPath), L"\\BROWSEUI-2\\tes1");
372 
373  StringCbCopyW(szPath, sizeof(szPath), szDir);
374  StringCbCatW(szPath, sizeof(szPath), L"\\BROWSEUI-2\\tes2");
376 
377  StringCbCopyW(szPath, sizeof(szPath), szDir);
378  StringCbCatW(szPath, sizeof(szPath), L"\\BROWSEUI-2");
380 }
381 
382 static void
384 {
385  CComPtr<IEnumString> EnumStr;
386  HRESULT hr = CoCreateInstance(CLSID_ACListISF, NULL, CLSCTX_ALL, IID_PPV_ARG(IEnumString, &EnumStr));
387  ok_hr(hr, S_OK);
388  if (!SUCCEEDED(hr))
389  {
390  skip("CoCreateInstance failed\n");
391  return;
392  }
393 
394  CComPtr<IACList2> ACList;
395  ok_hr(hr = EnumStr->QueryInterface(IID_IACList2, (void**)&ACList), S_OK);
396  if (!SUCCEEDED(hr))
397  {
398  skip("QueryInterface failed\n");
399  return;
400  }
401 
402  CComPtr<ICurrentWorkingDirectory> CurrentWorkingDir;
403  ok_hr(hr = EnumStr->QueryInterface(IID_ICurrentWorkingDirectory, (void**)&CurrentWorkingDir), S_OK);
404  if (!SUCCEEDED(hr))
405  {
406  skip("QueryInterface failed\n");
407  return;
408  }
409 
410  ok_hr(hr = ACList->SetOptions(ACLO_CURRENTDIR), S_OK);
411  test_at_end(EnumStr);
412 
413  CreateDirectoryW(L"C:\\BROWSEUI-1", NULL);
414  CreateDirectoryW(L"C:\\BROWSEUI-1\\TEST1", NULL);
415  CreateDirectoryW(L"C:\\BROWSEUI-1\\TEST2", NULL);
416  CreateDirectoryW(L"C:\\BROWSEUI-1\\TEST1\\TEST3", NULL);
417  CreateDirectoryW(L"C:\\BROWSEUI-2", NULL);
418  CreateDirectoryW(L"C:\\BROWSEUI-2\\TEST1", NULL);
419  CreateDirectoryW(L"C:\\BROWSEUI-2\\TEST2", NULL);
420  CreateDirectoryW(L"C:\\BROWSEUI-2\\TEST1\\TEST4", NULL);
421 
422  ok_hr(hr = CurrentWorkingDir->SetDirectory(L"C:\\BROWSEUI-1\\TEST1"), S_OK);
423  test_at_end(EnumStr);
424 
425  ok_hr(hr = ACList->Expand(L"C:\\BROWSEUI-2\\TEST1\\"), S_OK);
426 
427  LPWSTR psz;
428  ULONG cGot;
429 
430  hr = EnumStr->Next(1, &psz, &cGot);
431  ok_hr(hr, S_OK);
432  ok_wstr(psz, L"C:\\BROWSEUI-2\\TEST1\\TEST4");
433  CoTaskMemFree(psz);
434 
435  hr = EnumStr->Next(1, &psz, &cGot);
436  ok_hr(hr, S_OK);
437  ok_wstr(psz, L"TEST3");
438  CoTaskMemFree(psz);
439 
440  test_at_end(EnumStr);
441 
442  ok_hr(hr = ACList->Expand(L"C:\\BROWSEUI-1\\TEST1\\"), S_OK);
443 
444  hr = EnumStr->Next(1, &psz, &cGot);
445  ok_hr(hr, S_OK);
446  ok_wstr(psz, L"C:\\BROWSEUI-1\\TEST1\\TEST3");
447  CoTaskMemFree(psz);
448 
449  hr = EnumStr->Next(1, &psz, &cGot);
450  ok_hr(hr, S_OK);
451  ok_wstr(psz, L"TEST3");
452  CoTaskMemFree(psz);
453 
454  test_at_end(EnumStr);
455 
456  ok_hr(hr = CurrentWorkingDir->SetDirectory(L"C:\\BROWSEUI-2\\TEST1"), S_OK);
457  test_at_end(EnumStr);
458 
459  ok_hr(hr = ACList->Expand(L"..\\TEST1\\"), S_OK);
460 
461  hr = EnumStr->Next(1, &psz, &cGot);
462  ok_hr(hr, S_OK);
463  ok_wstr(psz, L"..\\TEST1\\TEST4");
464  CoTaskMemFree(psz);
465 
466  hr = EnumStr->Next(1, &psz, &cGot);
467  ok_hr(hr, S_OK);
468  ok_wstr(psz, L"TEST4");
469  CoTaskMemFree(psz);
470 
471  test_at_end(EnumStr);
472 
473  ok_hr(hr = ACList->Expand(L"\\BROWSEUI-2\\TEST1\\"), S_OK);
474 
475  hr = EnumStr->Next(1, &psz, &cGot);
476  ok_hr(hr, S_OK);
477  ok_wstr(psz, L"\\BROWSEUI-2\\TEST1\\TEST4");
478  CoTaskMemFree(psz);
479 
480  hr = EnumStr->Next(1, &psz, &cGot);
481  ok_hr(hr, S_OK);
482  ok_wstr(psz, L"TEST4");
483  CoTaskMemFree(psz);
484 
485  test_at_end(EnumStr);
486 
487  RemoveDirectoryW(L"C:\\BROWSEUI-1\\TEST1\\TEST3");
488  RemoveDirectoryW(L"C:\\BROWSEUI-1\\TEST1");
489  RemoveDirectoryW(L"C:\\BROWSEUI-1\\TEST2");
490  RemoveDirectoryW(L"C:\\BROWSEUI-1");
491  RemoveDirectoryW(L"C:\\BROWSEUI-2\\TEST1\\TEST4");
492  RemoveDirectoryW(L"C:\\BROWSEUI-2\\TEST1");
493  RemoveDirectoryW(L"C:\\BROWSEUI-2\\TEST2");
494  RemoveDirectoryW(L"C:\\BROWSEUI-2");
495 }
496 
497 static void
499 {
500  CComPtr<IACList2> ACList;
501  HRESULT hr = CoCreateInstance(CLSID_ACListISF, NULL, CLSCTX_ALL, IID_PPV_ARG(IACList2, &ACList));
502  ok_hr(hr, S_OK);
503  if (!SUCCEEDED(hr))
504  {
505  skip("CoCreateInstance failed\n");
506  return;
507  }
508 
509  // Check the default
510  DWORD CurrentOption = 0xdeadbeef;
511  ok_hr(ACList->GetOptions(&CurrentOption), S_OK);
512  ok(CurrentOption == (ACLO_CURRENTDIR|ACLO_MYCOMPUTER), "Expected the default to be %x, was %lx\n",
513  (ACLO_CURRENTDIR|ACLO_MYCOMPUTER), CurrentOption);
514 
515 
516  CComPtr<IEnumString> EnumStr;
517  ok_hr(hr = ACList->QueryInterface(IID_IEnumString, (void**)&EnumStr), S_OK);
518  if (!SUCCEEDED(hr))
519  {
520  skip("QueryInterface failed\n");
521  return;
522  }
523 
524  CComPtr<IPersistFolder> PersistFolder;
525  ok_hr(hr = EnumStr->QueryInterface(IID_IPersistFolder, (void**)&PersistFolder), S_OK);
526  if (!SUCCEEDED(hr))
527  {
528  skip("QueryInterface failed\n");
529  return;
530  }
531 
532  CComHeapPtr<ITEMIDLIST> pidlMyComputer;
533  ok_hr(hr = SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &pidlMyComputer), S_OK);
534  if (!SUCCEEDED(hr))
535  {
536  skip("SHGetSpecialFolderLocation failed\n");
537  return;
538  }
539 
540  hr = EnumStr->Reset();
542  ok_hr(hr, S_FALSE);
543  else
544  ok_hr(hr, S_OK);
545  test_ExpectDrives(EnumStr, pidlMyComputer);
546 
547  ok_hr(hr = ACList->SetOptions(ACLO_MYCOMPUTER), S_OK);
548  ok_hr(EnumStr->Reset(), S_OK);
549  test_ExpectDrives(EnumStr, pidlMyComputer);
550 
553  // Windows 2k3 does not parse it without the trailing '\\'
554  Buffer[3] = '\0';
555  CComHeapPtr<ITEMIDLIST> pidlDiskRoot;
556  ok_hr(hr = SHParseDisplayName(Buffer, NULL, &pidlDiskRoot, NULL, NULL), S_OK);
557  if (!SUCCEEDED(hr))
558  return;
559  Buffer[2] = '\0';
560 
561  ok_hr(hr = ACList->Expand(Buffer), S_OK);
562  test_ExpectFolders(EnumStr, pidlDiskRoot, Buffer, None);
563  test_ExpectDrives(EnumStr, pidlMyComputer);
564 
565  ok_hr(hr = ACList->Expand(Buffer), S_OK);
566  ok_hr(EnumStr->Reset(), S_OK);
567  // Pre vista does not remove the expanded data from the enumeration, it changes it to relative paths???
569  test_ExpectFolders(EnumStr, pidlDiskRoot, Buffer, IgnoreRoot);
570  test_ExpectDrives(EnumStr, pidlMyComputer);
571 
572  ok_hr(EnumStr->Reset(), S_OK);
573  ok_hr(hr = ACList->Expand(Buffer), S_OK);
574  test_ExpectFolders(EnumStr, pidlDiskRoot, Buffer, None);
575  test_ExpectDrives(EnumStr, pidlMyComputer);
576 }
577 
578 static void
580 {
581  CComPtr<IEnumString> EnumStr;
582  HRESULT hr = CoCreateInstance(CLSID_ACListISF, NULL, CLSCTX_ALL, IID_PPV_ARG(IEnumString, &EnumStr));
583  ok_hr(hr, S_OK);
584  if (!SUCCEEDED(hr))
585  {
586  skip("CoCreateInstance failed\n");
587  return;
588  }
589 
590  CComPtr<IACList2> ACList;
591  ok_hr(hr = EnumStr->QueryInterface(IID_IACList2, (void**)&ACList), S_OK);
592  if (!SUCCEEDED(hr))
593  {
594  skip("QueryInterface failed\n");
595  return;
596  }
597 
598  ok_hr(hr = ACList->SetOptions(ACLO_DESKTOP), S_OK);
600 }
601 
602 static void
604 {
605  CComPtr<IEnumString> EnumStr;
606  HRESULT hr = CoCreateInstance(CLSID_ACListISF, NULL, CLSCTX_ALL, IID_PPV_ARG(IEnumString, &EnumStr));
607  ok_hr(hr, S_OK);
608  if (!SUCCEEDED(hr))
609  {
610  skip("CoCreateInstance failed\n");
611  return;
612  }
613 
614  CComPtr<IACList2> ACList;
615  ok_hr(hr = EnumStr->QueryInterface(IID_IACList2, (void**)&ACList), S_OK);
616  if (!SUCCEEDED(hr))
617  {
618  skip("QueryInterface failed\n");
619  return;
620  }
621 
622  CComHeapPtr<ITEMIDLIST> pidlFavorites;
624  if (!SUCCEEDED(hr))
625  {
626  skip("SHGetSpecialFolderLocation failed\n");
627  return;
628  }
629 
630  ok_hr(hr = ACList->SetOptions(ACLO_FAVORITES), S_OK);
631  test_ExpectFolders(EnumStr, pidlFavorites, NULL, IgnoreRoot | CheckLast | IgnoreHidden);
632 }
633 
634 static void
636 {
637  CComPtr<IEnumString> EnumStr;
638  HRESULT hr = CoCreateInstance(CLSID_ACListISF, NULL, CLSCTX_ALL, IID_PPV_ARG(IEnumString, &EnumStr));
639  ok_hr(hr, S_OK);
640  if (!SUCCEEDED(hr))
641  {
642  skip("CoCreateInstance failed\n");
643  return;
644  }
645 
646  CComPtr<IACList2> ACList;
647  ok_hr(hr = EnumStr->QueryInterface(IID_IACList2, (void**)&ACList), S_OK);
648  if (!SUCCEEDED(hr))
649  {
650  skip("QueryInterface failed\n");
651  return;
652  }
653 
656  // Windows 2k3 does not parse it without the trailing '\\'
657  Buffer[3] = '\0';
658  CComHeapPtr<ITEMIDLIST> pidlDiskRoot;
659  ok_hr(hr = SHParseDisplayName(Buffer, NULL, &pidlDiskRoot, NULL, NULL), S_OK);
660  if (!SUCCEEDED(hr))
661  {
662  skip("SHParseDisplayName failed\n");
663  return;
664  }
665 
666  ok_hr(hr = ACList->SetOptions(ACLO_FILESYSONLY), S_OK);
667  test_at_end(EnumStr);
668 
669  ok_hr(hr = ACList->Expand(Buffer), S_OK);
670  test_ExpectFolders(EnumStr, pidlDiskRoot, Buffer, CheckLast | IgnoreHidden);
671 }
672 
673 static void
675 {
676  CComPtr<IEnumString> EnumStr;
677  HRESULT hr = CoCreateInstance(CLSID_ACListISF, NULL, CLSCTX_ALL, IID_PPV_ARG(IEnumString, &EnumStr));
678  ok_hr(hr, S_OK);
679  if (!SUCCEEDED(hr))
680  {
681  skip("CoCreateInstance failed\n");
682  return;
683  }
684 
685  CComPtr<IACList2> ACList;
686  ok_hr(hr = EnumStr->QueryInterface(IID_IACList2, (void**)&ACList), S_OK);
687  if (!SUCCEEDED(hr))
688  {
689  skip("QueryInterface failed\n");
690  return;
691  }
692 
695  // Windows 2k3 does not parse it without the trailing '\\'
696  Buffer[3] = '\0';
697  CComHeapPtr<ITEMIDLIST> pidlDiskRoot;
698  ok_hr(hr = SHParseDisplayName(Buffer, NULL, &pidlDiskRoot, NULL, NULL), S_OK);
699  if (!SUCCEEDED(hr))
700  return;
701 
702  ok_hr(hr = ACList->SetOptions(ACLO_FILESYSDIRS), S_OK);
703  test_at_end(EnumStr);
704 
705  ok_hr(hr = ACList->Expand(Buffer), S_OK);
706  test_ExpectFolders(EnumStr, pidlDiskRoot, Buffer, CheckLast | IgnoreFiles | IgnoreHidden);
707 }
708 
709 static void GetEnvStatus()
710 {
711  RTL_OSVERSIONINFOEXW rtlinfo = {0};
712  void (__stdcall* pRtlGetVersion)(RTL_OSVERSIONINFOEXW*);
713  pRtlGetVersion = (void (__stdcall*)(RTL_OSVERSIONINFOEXW*))GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion");
714 
715  rtlinfo.dwOSVersionInfoSize = sizeof(rtlinfo);
716  pRtlGetVersion(&rtlinfo);
717  g_WinVersion = (rtlinfo.dwMajorVersion << 8) | rtlinfo.dwMinorVersion;
718 
719  SHELLFLAGSTATE sfs = {0};
721  g_ShowHidden = !!sfs.fShowAllObjects;
722  trace("Show hidden folders: %s\n", g_ShowHidden ? "yes" : "no");
723 }
724 
725 struct CCoInit
726 {
729  HRESULT hres;
730 };
731 
732 START_TEST(ACListISF)
733 {
734  GetEnvStatus();
735  CCoInit init;
736  ok_hr(init.hres, S_OK);
737  if (!SUCCEEDED(init.hres))
738  {
739  skip("CoInitialize failed\n");
740  return;
741  }
742 
751 }
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define ok_hr(status, expected)
Definition: ACListISF.cpp:31
static void test_ACListISF_MYCOMPUTER()
Definition: ACListISF.cpp:498
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
#define ACLO_FILESYSONLY
Definition: shlobj.h:744
#define ACLO_NONE
Definition: shlobj.h:739
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:269
UINT WINAPI GetSystemWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2396
static bool GetDisplayname(CComPtr< IShellFolder > &spDrives, CComHeapPtr< ITEMIDLIST > &pidl, CComHeapPtr< WCHAR > &DisplayName)
Definition: ACListISF.cpp:55
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
static void GetEnvStatus()
Definition: ACListISF.cpp:709
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
#define test_ExpectFolders
Definition: ACListISF.cpp:36
const GUID IID_IEnumString
static void test_ACListISF_FILESYSDIRS()
Definition: ACListISF.cpp:674
HRESULT hr
Definition: shlfolder.c:183
ExpectOptions operator|(const ExpectOptions &left, const ExpectOptions &right)
Definition: ACListISF.cpp:79
HRESULT hres
Definition: ACPPage.cpp:82
ULONG DbgPrint(PCH Format,...)
static void test_ACListISF_NONE()
Definition: ACListISF.cpp:151
ULONG dwMinorVersion
Definition: rtltypes.h:271
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: atltest.h:87
return static_cast< int >(global)
static void test_ACListISF_FILESYSONLY()
Definition: ACListISF.cpp:635
#define _ARRAYSIZE(A)
Definition: ntbasedef.h:701
#define ACLO_FILESYSDIRS
Definition: shlobj.h:745
static void test_ACListISF_DESKTOP()
Definition: ACListISF.cpp:579
#define IID_PPV_ARG(Itype, ppType)
int32_t INT
Definition: typedefs.h:58
static int init
Definition: wintirpc.c:33
STRSAFEAPI StringCbCatW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:342
#define test_at_end
Definition: ACListISF.cpp:34
static void test_ExpectDrives_imp(CComPtr< IEnumString > &EnumStr, CComHeapPtr< ITEMIDLIST > &pidlTarget)
Definition: ACListISF.cpp:145
ULONG dwMajorVersion
Definition: rtltypes.h:270
#define CSIDL_DRIVES
Definition: shlobj.h:2028
#define ACLO_CURRENTDIR
Definition: shlobj.h:740
#define CSIDL_FAVORITES
Definition: shlobj.h:2018
#define test_ExpectDrives
Definition: ACListISF.cpp:35
if SUCCEEDED(hr)
#define StrRet
Definition: shellclasses.h:871
CHAR * PCH
Definition: ntbasedef.h:391
#define S_FALSE
Definition: winerror.h:2357
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
Definition: bufpool.h:45
static void test_ACListISF_FAVORITES()
Definition: ACListISF.cpp:603
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
#define SSF_SHOWALLOBJECTS
Definition: shlobj.h:1527
root entry for file system trees
Definition: entries.h:148
int Count
Definition: noreturn.cpp:7
#define ACLO_MYCOMPUTER
Definition: shlobj.h:741
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
#define trace
Definition: atltest.h:70
__wchar_t WCHAR
Definition: xmlstorage.h:180
void __winetest_cdecl winetest_ok(int condition, const char *msg,...)
static void test_at_end_imp(CComPtr< IEnumString > &EnumStr)
Definition: ACListISF.cpp:44
HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST *ppidl)
Definition: shellpath.c:3069
LONG HRESULT
Definition: typedefs.h:79
#define MAX_PATH
Definition: compat.h:34
static void test_ACListISF_CURRENTDIR()
Definition: ACListISF.cpp:196
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint left
Definition: glext.h:7726
#define __stdcall
Definition: typedefs.h:25
GLdouble GLdouble right
Definition: glext.h:10859
#define ACLO_DESKTOP
Definition: shlobj.h:742
static void test_ACListISF_CURRENTDIR2()
Definition: ACListISF.cpp:383
static const WCHAR L[]
Definition: oid.c:1250
#define ok_wstr(x, y)
Definition: atltest.h:130
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
#define WINVER_VISTA
Definition: ACListISF.cpp:28
START_TEST(ACListISF)
Definition: ACListISF.cpp:732
static void test_ExpectFolders_imp(CComPtr< IEnumString > &EnumStr, LPITEMIDLIST pidlTarget, const WCHAR *Root, ExpectOptions options)
Definition: ACListISF.cpp:86
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
#define winetest_ok_hr(expression, expected)
Definition: ACListISF.cpp:37
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define ACLO_FAVORITES
Definition: shlobj.h:743
#define S_OK
Definition: intsafe.h:52
LPCWSTR szPath
Definition: env.c:37
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
#define ok(value,...)
Definition: atltest.h:57
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
#define E_NOTIMPL
Definition: ddrawi.h:99
HRESULT WINAPI SHParseDisplayName(LPCWSTR pszName, IBindCtx *pbc, LPITEMIDLIST *ppidl, SFGAOF sfgaoIn, SFGAOF *psfgaoOut)
Definition: pidl.c:1381
ExpectOptions
Definition: ACListISF.cpp:69
static bool g_ShowHidden
Definition: ACListISF.cpp:26
#define NULL
Definition: types.h:112
VOID WINAPI SHGetSettings(LPSHELLFLAGSTATE lpsfs, DWORD dwMask)
Definition: shellord.c:221
#define E_UNEXPECTED
Definition: winerror.h:2456
#define skip(...)
Definition: atltest.h:64
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
unsigned int ULONG
Definition: retypes.h:1
static DWORD g_WinVersion
Definition: ACListISF.cpp:27
#define GetProcAddress(x, y)
Definition: compat.h:612
WCHAR * LPWSTR
Definition: xmlstorage.h:184
nsresult QueryInterface(nsIIDRef riid, void **result)
STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:166
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
static SHCONTF
Definition: ordinal.c:61
HRESULT WINAPI StrRetToStrW(LPSTRRET lpStrRet, const ITEMIDLIST *pidl, LPWSTR *ppszName)
Definition: string.c:1623