ReactOS  0.4.12-dev-418-g3df31a8
shellpath.c
Go to the documentation of this file.
1 /*
2  * Unit tests for shell32 SHGet{Special}Folder{Path|Location} functions.
3  *
4  * Copyright 2004 Juan Lang
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  * This is a test program for the SHGet{Special}Folder{Path|Location} functions
20  * of shell32, that get either a filesystem path or a LPITEMIDLIST (shell
21  * namespace) path for a given folder (CSIDL value).
22  */
23 
24 #define COBJMACROS
25 
26 #include <stdarg.h>
27 #include <stdio.h>
28 #include "windef.h"
29 #include "winbase.h"
30 #include "shlguid.h"
31 #include "shlobj.h"
32 #include "shlwapi.h"
33 #include "knownfolders.h"
34 #include "shellapi.h"
35 #include "wine/test.h"
36 
37 #include "initguid.h"
38 
39 /* CSIDL_MYDOCUMENTS is now the same as CSIDL_PERSONAL, but what we want
40  * here is its original value.
41  */
42 #define OLD_CSIDL_MYDOCUMENTS 0x000c
43 
44 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
45 
46 #ifndef ARRAY_SIZE
47 #define ARRAY_SIZE(x) ( sizeof(x) / sizeof((x)[0]) )
48 #endif
49 
50 /* from pidl.h, not included here: */
51 #ifndef PT_CPL /* Guess, Win7 uses this for CSIDL_CONTROLS */
52 #define PT_CPL 0x01 /* no path */
53 #endif
54 #ifndef PT_GUID
55 #define PT_GUID 0x1f /* no path */
56 #endif
57 #ifndef PT_DRIVE
58 #define PT_DRIVE 0x23 /* has path */
59 #endif
60 #ifndef PT_DRIVE2
61 #define PT_DRIVE2 0x25 /* has path */
62 #endif
63 #ifndef PT_SHELLEXT
64 #define PT_SHELLEXT 0x2e /* no path */
65 #endif
66 #ifndef PT_FOLDER
67 #define PT_FOLDER 0x31 /* has path */
68 #endif
69 #ifndef PT_FOLDERW
70 #define PT_FOLDERW 0x35 /* has path */
71 #endif
72 #ifndef PT_WORKGRP
73 #define PT_WORKGRP 0x41 /* no path */
74 #endif
75 #ifndef PT_YAGUID
76 #define PT_YAGUID 0x70 /* no path */
77 #endif
78 /* FIXME: this is used for history/favorites folders; what's a better name? */
79 #ifndef PT_IESPECIAL2
80 #define PT_IESPECIAL2 0xb1 /* has path */
81 #endif
82 
83 static GUID CLSID_CommonDocuments = { 0x0000000c, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x1a } };
84 
86  int folder;
87  int numTypes;
88  const BYTE *types;
89 };
90 
91 static HRESULT (WINAPI *pDllGetVersion)(DLLVERSIONINFO *);
92 static HRESULT (WINAPI *pSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR);
93 static HRESULT (WINAPI *pSHGetFolderLocation)(HWND, int, HANDLE, DWORD,
94  LPITEMIDLIST *);
95 static BOOL (WINAPI *pSHGetSpecialFolderPathA)(HWND, LPSTR, int, BOOL);
96 static HRESULT (WINAPI *pSHGetSpecialFolderLocation)(HWND, int, LPITEMIDLIST *);
97 static LPITEMIDLIST (WINAPI *pILFindLastID)(LPCITEMIDLIST);
98 static int (WINAPI *pSHFileOperationA)(LPSHFILEOPSTRUCTA);
99 static HRESULT (WINAPI *pSHGetMalloc)(LPMALLOC *);
100 static UINT (WINAPI *pGetSystemWow64DirectoryA)(LPSTR,UINT);
101 static HRESULT (WINAPI *pSHGetKnownFolderPath)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR *);
102 static HRESULT (WINAPI *pSHSetKnownFolderPath)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR);
103 static HRESULT (WINAPI *pSHGetFolderPathEx)(REFKNOWNFOLDERID, DWORD, HANDLE, LPWSTR, DWORD);
104 static BOOL (WINAPI *pPathYetAnotherMakeUniqueName)(PWSTR, PCWSTR, PCWSTR, PCWSTR);
105 static HRESULT (WINAPI *pSHGetKnownFolderIDList)(REFKNOWNFOLDERID, DWORD, HANDLE, PIDLIST_ABSOLUTE*);
106 
109 static const BYTE guidType[] = { PT_GUID };
111 static const BYTE folderType[] = { PT_FOLDER, PT_FOLDERW };
112 static const BYTE favoritesType[] = { PT_FOLDER, PT_FOLDERW, 0, PT_IESPECIAL2 /* Win98 */ };
114 static const BYTE personalType[] = { PT_FOLDER, PT_GUID, PT_DRIVE, 0xff /* Win9x */,
115  PT_IESPECIAL2 /* Win98 */, 0 /* Vista */, PT_SHELLEXT /* win8 */ };
116 /* FIXME: don't know the type of 0x71 returned by Vista/2008 for printers */
117 static const BYTE printersType[] = { PT_YAGUID, PT_SHELLEXT, 0x71 };
118 static const BYTE ieSpecialType[] = { PT_IESPECIAL2 };
119 static const BYTE shellExtType[] = { PT_SHELLEXT };
120 static const BYTE workgroupType[] = { PT_WORKGRP };
121 #define DECLARE_TYPE(x, y) { x, sizeof(y) / sizeof(y[0]), y }
122 static const struct shellExpectedValues requiredShellValues[] = {
130 /* FIXME: the following fails in Wine, returns type PT_FOLDER
131  DECLARE_TYPE(CSIDL_HISTORY, ieSpecialType),
132  */
145 };
146 static const struct shellExpectedValues optionalShellValues[] = {
147 /* FIXME: the following only semi-succeed; they return NULL PIDLs on XP.. hmm.
148  DECLARE_TYPE(CSIDL_ALTSTARTUP, folderType),
149  DECLARE_TYPE(CSIDL_COMMON_ALTSTARTUP, folderType),
150  DECLARE_TYPE(CSIDL_COMMON_OEM_LINKS, folderType),
151  */
152 /* Windows NT-only: */
160 /* first appearing in shell32 version 4.71: */
162 /* first appearing in shell32 version 4.72: */
164 /* first appearing in shell32 version 5.0: */
179 /* first appearing in shell32 6.0: */
187 };
188 #undef DECLARE_TYPE
189 
190 static void loadShell32(void)
191 {
192  HMODULE hShell32 = GetModuleHandleA("shell32");
193 
194 #define GET_PROC(func) \
195  p ## func = (void*)GetProcAddress(hShell32, #func); \
196  if(!p ## func) \
197  trace("GetProcAddress(%s) failed\n", #func);
198 
201  GET_PROC(SHGetFolderPathEx)
203  GET_PROC(SHGetKnownFolderPath)
204  GET_PROC(SHSetKnownFolderPath)
208  if (!pILFindLastID)
209  pILFindLastID = (void *)GetProcAddress(hShell32, (LPCSTR)16);
213  GET_PROC(SHGetKnownFolderIDList)
214 
215  ok(pSHGetMalloc != NULL, "shell32 is missing SHGetMalloc\n");
216  if (pSHGetMalloc)
217  {
218  HRESULT hr = pSHGetMalloc(&pMalloc);
219 
220  ok(hr == S_OK, "SHGetMalloc failed: 0x%08x\n", hr);
221  ok(pMalloc != NULL, "SHGetMalloc returned a NULL IMalloc\n");
222  }
223 
224  if (pDllGetVersion)
225  {
226  shellVersion.cbSize = sizeof(shellVersion);
227  pDllGetVersion(&shellVersion);
228  trace("shell32 version is %d.%d\n",
229  shellVersion.dwMajorVersion, shellVersion.dwMinorVersion);
230  }
231 #undef GET_PROC
232 }
233 
234 #ifndef CSIDL_PROFILES
235 #define CSIDL_PROFILES 0x003e
236 #endif
237 
238 /* A couple utility printing functions */
239 static const char *getFolderName(int folder)
240 {
241  static char unknown[32];
242 
243 #define CSIDL_TO_STR(x) case x: return#x;
244  switch (folder)
245  {
304 #undef CSIDL_TO_STR
305  default:
306  sprintf(unknown, "unknown (0x%04x)", folder);
307  return unknown;
308  }
309 }
310 
311 static void test_parameters(void)
312 {
313  LPITEMIDLIST pidl = NULL;
314  char path[MAX_PATH];
315  HRESULT hr;
316 
317  if (pSHGetFolderLocation)
318  {
319  /* check a bogus CSIDL: */
320  pidl = NULL;
321  hr = pSHGetFolderLocation(NULL, 0xeeee, NULL, 0, &pidl);
322  ok(hr == E_INVALIDARG, "got 0x%08x, expected E_INVALIDARG\n", hr);
323  if (hr == S_OK) IMalloc_Free(pMalloc, pidl);
324 
325  /* check a bogus user token: */
326  pidl = NULL;
327  hr = pSHGetFolderLocation(NULL, CSIDL_FAVORITES, (HANDLE)2, 0, &pidl);
328  ok(hr == E_FAIL || hr == E_HANDLE, "got 0x%08x, expected E_FAIL or E_HANDLE\n", hr);
329  if (hr == S_OK) IMalloc_Free(pMalloc, pidl);
330 
331  /* a NULL pidl pointer crashes, so don't test it */
332  }
333 
334  if (pSHGetSpecialFolderLocation)
335  {
336  if (0)
337  /* crashes */
339 
340  hr = pSHGetSpecialFolderLocation(NULL, 0xeeee, &pidl);
341  ok(hr == E_INVALIDARG, "got returned 0x%08x\n", hr);
342  }
343 
344  if (pSHGetFolderPathA)
345  {
346  /* expect 2's a bogus handle, especially since we didn't open it */
347  hr = pSHGetFolderPathA(NULL, CSIDL_DESKTOP, (HANDLE)2, SHGFP_TYPE_DEFAULT, path);
348  ok(hr == E_FAIL || hr == E_HANDLE || /* Vista and 2k8 */
349  broken(hr == S_OK), /* W2k and Me */ "got 0x%08x, expected E_FAIL\n", hr);
350 
351  hr = pSHGetFolderPathA(NULL, 0xeeee, NULL, SHGFP_TYPE_DEFAULT, path);
352  ok(hr == E_INVALIDARG, "got 0x%08x, expected E_INVALIDARG\n", hr);
353  }
354 
355  if (pSHGetSpecialFolderPathA)
356  {
357  BOOL ret;
358 
359  if (0)
360  pSHGetSpecialFolderPathA(NULL, NULL, CSIDL_BITBUCKET, FALSE);
361 
362  /* odd but true: calling with a NULL path still succeeds if it's a real
363  * dir (on some windows platform). on winME it generates exception.
364  */
365  ret = pSHGetSpecialFolderPathA(NULL, path, CSIDL_PROGRAMS, FALSE);
366  ok(ret, "got %d\n", ret);
367 
368  ret = pSHGetSpecialFolderPathA(NULL, path, 0xeeee, FALSE);
369  ok(!ret, "got %d\n", ret);
370  }
371 }
372 
373 /* Returns the folder's PIDL type, or 0xff if one can't be found. */
375 {
376  LPITEMIDLIST pidl;
377  HRESULT hr;
378  BYTE ret = 0xff;
379 
380  /* treat absence of function as success */
381  if (!pSHGetFolderLocation) return TRUE;
382 
383  pidl = NULL;
384  hr = pSHGetFolderLocation(NULL, folder, NULL, 0, &pidl);
385  if (hr == S_OK)
386  {
387  if (pidl)
388  {
389  LPITEMIDLIST pidlLast = pILFindLastID(pidl);
390 
391  ok(pidlLast != NULL, "%s: ILFindLastID failed\n",
393  if (pidlLast)
394  ret = pidlLast->mkid.abID[0];
395  IMalloc_Free(pMalloc, pidl);
396  }
397  }
398  return ret;
399 }
400 
401 /* Returns the folder's PIDL type, or 0xff if one can't be found. */
403 {
404  LPITEMIDLIST pidl;
405  HRESULT hr;
406  BYTE ret = 0xff;
407 
408  /* treat absence of function as success */
409  if (!pSHGetSpecialFolderLocation) return TRUE;
410 
411  pidl = NULL;
412  hr = pSHGetSpecialFolderLocation(NULL, folder, &pidl);
413  if (hr == S_OK)
414  {
415  if (pidl)
416  {
417  LPITEMIDLIST pidlLast = pILFindLastID(pidl);
418 
419  ok(pidlLast != NULL,
420  "%s: ILFindLastID failed\n", getFolderName(folder));
421  if (pidlLast)
422  ret = pidlLast->mkid.abID[0];
423  IMalloc_Free(pMalloc, pidl);
424  }
425  }
426  return ret;
427 }
428 
430 {
431  char path[MAX_PATH];
432  HRESULT hr;
433 
434  if (!pSHGetFolderPathA) return;
435 
436  hr = pSHGetFolderPathA(NULL, folder, NULL, SHGFP_TYPE_CURRENT, path);
437  ok(hr == S_OK || optional,
438  "SHGetFolderPathA(NULL, %s, NULL, SHGFP_TYPE_CURRENT, path) failed: 0x%08x\n", getFolderName(folder), hr);
439 }
440 
442 {
443  char path[MAX_PATH];
444  BOOL ret;
445 
446  if (!pSHGetSpecialFolderPathA) return;
447 
448  ret = pSHGetSpecialFolderPathA(NULL, path, folder, FALSE);
449  if (ret && winetest_interactive)
450  printf("%s: %s\n", getFolderName(folder), path);
451  ok(ret || optional,
452  "SHGetSpecialFolderPathA(NULL, path, %s, FALSE) failed\n",
454 }
455 
456 static void test_ShellValues(const struct shellExpectedValues testEntries[],
457  int numEntries, BOOL optional)
458 {
459  int i;
460 
461  for (i = 0; i < numEntries; i++)
462  {
463  BYTE type;
464  int j;
465  BOOL foundTypeMatch = FALSE;
466 
467  if (pSHGetFolderLocation)
468  {
469  type = testSHGetFolderLocation(testEntries[i].folder);
470  for (j = 0; !foundTypeMatch && j < testEntries[i].numTypes; j++)
471  if (testEntries[i].types[j] == type)
472  foundTypeMatch = TRUE;
473  ok(foundTypeMatch || optional || broken(type == 0xff) /* Win9x */,
474  "%s has unexpected type %d (0x%02x)\n",
475  getFolderName(testEntries[i].folder), type, type);
476  }
478  for (j = 0, foundTypeMatch = FALSE; !foundTypeMatch &&
479  j < testEntries[i].numTypes; j++)
480  if (testEntries[i].types[j] == type)
481  foundTypeMatch = TRUE;
482  ok(foundTypeMatch || optional || broken(type == 0xff) /* Win9x */,
483  "%s has unexpected type %d (0x%02x)\n",
484  getFolderName(testEntries[i].folder), type, type);
485  switch (type)
486  {
487  case PT_FOLDER:
488  case PT_DRIVE:
489  case PT_DRIVE2:
490  case PT_IESPECIAL2:
491  test_SHGetFolderPath(optional, testEntries[i].folder);
493  break;
494  }
495  }
496 }
497 
498 /* Attempts to verify that the folder path corresponding to the folder CSIDL
499  * value has the same value as the environment variable with name envVar.
500  * Doesn't mind if SHGetSpecialFolderPath fails for folder or if envVar isn't
501  * set in this environment; different OS and shell version behave differently.
502  * However, if both are present, fails if envVar's value is not the same
503  * (byte-for-byte) as what SHGetSpecialFolderPath returns.
504  */
505 static void matchSpecialFolderPathToEnv(int folder, const char *envVar)
506 {
507  char path[MAX_PATH];
508 
509  if (!pSHGetSpecialFolderPathA) return;
510 
511  if (pSHGetSpecialFolderPathA(NULL, path, folder, FALSE))
512  {
513  char *envVal = getenv(envVar);
514 
515  ok(!envVal || !lstrcmpiA(envVal, path),
516  "%%%s%% does not match SHGetSpecialFolderPath:\n"
517  "%%%s%% is %s\nSHGetSpecialFolderPath returns %s\n",
518  envVar, envVar, envVal, path);
519  }
520 }
521 
522 /* Attempts to match the GUID returned by SHGetFolderLocation for folder with
523  * GUID. Assumes the type of the returned PIDL is in fact a GUID, but doesn't
524  * fail if it isn't--that check should already have been done.
525  * Fails if the returned PIDL is a GUID whose value does not match guid.
526  */
527 static void matchGUID(int folder, const GUID *guid, const GUID *guid_alt)
528 {
529  LPITEMIDLIST pidl;
530  HRESULT hr;
531 
532  if (!pSHGetFolderLocation) return;
533  if (!guid) return;
534 
535  pidl = NULL;
536  hr = pSHGetFolderLocation(NULL, folder, NULL, 0, &pidl);
537  if (hr == S_OK)
538  {
539  LPITEMIDLIST pidlLast = pILFindLastID(pidl);
540 
541  if (pidlLast && (pidlLast->mkid.abID[0] == PT_SHELLEXT ||
542  pidlLast->mkid.abID[0] == PT_GUID))
543  {
544  GUID *shellGuid = (GUID *)(pidlLast->mkid.abID + 2);
545 
546  if (!guid_alt)
547  ok(IsEqualIID(shellGuid, guid),
548  "%s: got GUID %s, expected %s\n", getFolderName(folder),
549  wine_dbgstr_guid(shellGuid), wine_dbgstr_guid(guid));
550  else
551  ok(IsEqualIID(shellGuid, guid) ||
552  IsEqualIID(shellGuid, guid_alt),
553  "%s: got GUID %s, expected %s or %s\n", getFolderName(folder),
554  wine_dbgstr_guid(shellGuid), wine_dbgstr_guid(guid), wine_dbgstr_guid(guid_alt));
555  }
556  IMalloc_Free(pMalloc, pidl);
557  }
558 }
559 
560 /* Checks the PIDL type of all the known values. */
561 static void test_PidlTypes(void)
562 {
563  /* Desktop */
566 
569 }
570 
571 /* FIXME: Should be in shobjidl.idl */
572 DEFINE_GUID(CLSID_NetworkExplorerFolder, 0xF02C1A0D, 0xBE21, 0x4350, 0x88, 0xB0, 0x73, 0x67, 0xFC, 0x96, 0xEF, 0x3C);
573 DEFINE_GUID(_CLSID_Documents, 0xA8CDFF1C, 0x4878, 0x43be, 0xB5, 0xFD, 0xF8, 0x09, 0x1C, 0x1C, 0x60, 0xD0);
574 
575 /* Verifies various shell virtual folders have the correct well-known GUIDs. */
576 static void test_GUIDs(void)
577 {
578  matchGUID(CSIDL_BITBUCKET, &CLSID_RecycleBin, NULL);
579  matchGUID(CSIDL_CONTROLS, &CLSID_ControlPanel, NULL);
580  matchGUID(CSIDL_DRIVES, &CLSID_MyComputer, NULL);
581  matchGUID(CSIDL_INTERNET, &CLSID_Internet, NULL);
582  matchGUID(CSIDL_NETWORK, &CLSID_NetworkPlaces, &CLSID_NetworkExplorerFolder); /* Vista and higher */
583  matchGUID(CSIDL_PERSONAL, &CLSID_MyDocuments, &_CLSID_Documents /* win8 */);
585  matchGUID(CSIDL_PRINTERS, &CLSID_Printers, NULL);
586 }
587 
588 /* Verifies various shell paths match the environment variables to which they
589  * correspond.
590  */
591 static void test_EnvVars(void)
592 {
599  /* this is only set on Wine, but can't hurt to verify it: */
601 }
602 
603 /* Loosely based on PathRemoveBackslashA from dlls/shlwapi/path.c */
604 static BOOL myPathIsRootA(LPCSTR lpszPath)
605 {
606  if (lpszPath && *lpszPath &&
607  lpszPath[1] == ':' && lpszPath[2] == '\\' && lpszPath[3] == '\0')
608  return TRUE; /* X:\ */
609  return FALSE;
610 }
612 {
613  LPSTR szTemp = NULL;
614 
615  if(lpszPath)
616  {
617  szTemp = CharPrevA(lpszPath, lpszPath + strlen(lpszPath));
618  if (!myPathIsRootA(lpszPath) && *szTemp == '\\')
619  *szTemp = '\0';
620  }
621  return szTemp;
622 }
623 
624 /* Verifies the shell path for CSIDL_WINDOWS matches the return from
625  * GetWindowsDirectory. If SHGetSpecialFolderPath fails, no harm, no foul--not
626  * every shell32 version supports CSIDL_WINDOWS.
627  */
628 static void testWinDir(void)
629 {
630  char windowsShellPath[MAX_PATH], windowsDir[MAX_PATH] = { 0 };
631 
632  if (!pSHGetSpecialFolderPathA) return;
633 
634  if (pSHGetSpecialFolderPathA(NULL, windowsShellPath, CSIDL_WINDOWS, FALSE))
635  {
636  myPathRemoveBackslashA(windowsShellPath);
637  GetWindowsDirectoryA(windowsDir, sizeof(windowsDir));
638  myPathRemoveBackslashA(windowsDir);
639  ok(!lstrcmpiA(windowsDir, windowsShellPath),
640  "GetWindowsDirectory returns %s SHGetSpecialFolderPath returns %s\n",
641  windowsDir, windowsShellPath);
642  }
643 }
644 
645 /* Verifies the shell path for CSIDL_SYSTEM matches the return from
646  * GetSystemDirectory. If SHGetSpecialFolderPath fails, no harm,
647  * no foul--not every shell32 version supports CSIDL_SYSTEM.
648  */
649 static void testSystemDir(void)
650 {
651  char systemShellPath[MAX_PATH], systemDir[MAX_PATH], systemDirx86[MAX_PATH];
652 
653  if (!pSHGetSpecialFolderPathA) return;
654 
655  GetSystemDirectoryA(systemDir, sizeof(systemDir));
656  myPathRemoveBackslashA(systemDir);
657  if (pSHGetSpecialFolderPathA(NULL, systemShellPath, CSIDL_SYSTEM, FALSE))
658  {
659  myPathRemoveBackslashA(systemShellPath);
660  ok(!lstrcmpiA(systemDir, systemShellPath),
661  "GetSystemDirectory returns %s SHGetSpecialFolderPath returns %s\n",
662  systemDir, systemShellPath);
663  }
664 
665  if (!pGetSystemWow64DirectoryA || !pGetSystemWow64DirectoryA(systemDirx86, sizeof(systemDirx86)))
666  GetSystemDirectoryA(systemDirx86, sizeof(systemDirx86));
667  myPathRemoveBackslashA(systemDirx86);
668  if (pSHGetSpecialFolderPathA(NULL, systemShellPath, CSIDL_SYSTEMX86, FALSE))
669  {
670  myPathRemoveBackslashA(systemShellPath);
671  ok(!lstrcmpiA(systemDirx86, systemShellPath) || broken(!lstrcmpiA(systemDir, systemShellPath)),
672  "GetSystemDirectory returns %s SHGetSpecialFolderPath returns %s\n",
673  systemDir, systemShellPath);
674  }
675 }
676 
677 /* Globals used by subprocesses */
678 static int myARGC;
679 static char **myARGV;
680 static char base[MAX_PATH];
681 static char selfname[MAX_PATH];
682 
683 static BOOL init(void)
684 {
686  if (!GetCurrentDirectoryA(sizeof(base), base)) return FALSE;
687  strcpy(selfname, myARGV[0]);
688  return TRUE;
689 }
690 
691 static void doChild(const char *arg)
692 {
693  char path[MAX_PATH];
694  HRESULT hr;
695 
696  if (arg[0] == '1')
697  {
698  LPITEMIDLIST pidl;
699  char *p;
700 
701  /* test what happens when CSIDL_FAVORITES is set to a nonexistent directory */
702 
703  /* test some failure cases first: */
704  hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES, NULL, SHGFP_TYPE_CURRENT, path);
706  "SHGetFolderPath returned 0x%08x, expected 0x80070002\n", hr);
707 
708  pidl = NULL;
709  hr = pSHGetFolderLocation(NULL, CSIDL_FAVORITES, NULL, 0, &pidl);
711  "SHGetFolderLocation returned 0x%08x\n", hr);
712  if (hr == S_OK && pidl) IMalloc_Free(pMalloc, pidl);
713 
714  ok(!pSHGetSpecialFolderPathA(NULL, path, CSIDL_FAVORITES, FALSE),
715  "SHGetSpecialFolderPath succeeded, expected failure\n");
716 
717  pidl = NULL;
718  hr = pSHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidl);
720  "SHGetFolderLocation returned 0x%08x\n", hr);
721 
722  if (hr == S_OK && pidl) IMalloc_Free(pMalloc, pidl);
723 
724  /* now test success: */
725  hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES | CSIDL_FLAG_CREATE, NULL,
727  ok (hr == S_OK, "got 0x%08x\n", hr);
728  if (hr == S_OK)
729  {
730  BOOL ret;
731 
732  trace("CSIDL_FAVORITES was changed to %s\n", path);
734  ok(!ret, "expected failure with ERROR_ALREADY_EXISTS\n");
735  if (!ret)
737  "got %d, expected ERROR_ALREADY_EXISTS\n", GetLastError());
738 
739  p = path + strlen(path);
740  strcpy(p, "\\desktop.ini");
741  DeleteFileA(path);
742  *p = 0;
745  ok( ret, "failed to remove %s error %u\n", path, GetLastError() );
746  }
747  }
748  else if (arg[0] == '2')
749  {
750  /* make sure SHGetFolderPath still succeeds when the
751  original value of CSIDL_FAVORITES is restored. */
752  hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES | CSIDL_FLAG_CREATE, NULL,
754  ok(hr == S_OK, "SHGetFolderPath failed: 0x%08x\n", hr);
755  }
756 }
757 
758 /* Tests the return values from the various shell functions both with and
759  * without the use of the CSIDL_FLAG_CREATE flag. This flag only appeared in
760  * version 5 of the shell, so don't test unless it's at least version 5.
761  * The test reads a value from the registry, modifies it, calls
762  * SHGetFolderPath once with the CSIDL_FLAG_CREATE flag, and immediately
763  * afterward without it. Then it restores the registry and deletes the folder
764  * that was created.
765  * One oddity with respect to restoration: shell32 caches somehow, so it needs
766  * to be reloaded in order to see the correct (restored) value.
767  * Some APIs unrelated to the ones under test may fail, but I expect they're
768  * covered by other unit tests; I just print out something about failure to
769  * help trace what's going on.
770  */
771 static void test_NonExistentPath(void)
772 {
773  static const char userShellFolders[] =
774  "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
775  char originalPath[MAX_PATH], modifiedPath[MAX_PATH];
776  HKEY key;
777 
778  if (!pSHGetFolderPathA) return;
779  if (!pSHGetFolderLocation) return;
780  if (!pSHGetSpecialFolderPathA) return;
781  if (!pSHGetSpecialFolderLocation) return;
782  if (!pSHFileOperationA) return;
783  if (shellVersion.dwMajorVersion < 5) return;
784 
785  if (!RegOpenKeyExA(HKEY_CURRENT_USER, userShellFolders, 0, KEY_ALL_ACCESS,
786  &key))
787  {
788  DWORD len, type;
789 
790  len = sizeof(originalPath);
791  if (!RegQueryValueExA(key, "Favorites", NULL, &type,
792  (LPBYTE)&originalPath, &len))
793  {
794  size_t len = strlen(originalPath);
795 
796  memcpy(modifiedPath, originalPath, len);
797  modifiedPath[len++] = '2';
798  modifiedPath[len++] = '\0';
799  trace("Changing CSIDL_FAVORITES to %s\n", modifiedPath);
800  if (!RegSetValueExA(key, "Favorites", 0, type,
801  (LPBYTE)modifiedPath, len))
802  {
803  char buffer[MAX_PATH+20];
806 
807  sprintf(buffer, "%s tests/shellpath.c 1", selfname);
808  memset(&startup, 0, sizeof(startup));
809  startup.cb = sizeof(startup);
810  startup.dwFlags = STARTF_USESHOWWINDOW;
811  startup.wShowWindow = SW_SHOWNORMAL;
813  &startup, &info);
814  winetest_wait_child_process( info.hProcess );
815 
816  /* restore original values: */
817  trace("Restoring CSIDL_FAVORITES to %s\n", originalPath);
818  RegSetValueExA(key, "Favorites", 0, type, (LPBYTE) originalPath,
819  strlen(originalPath) + 1);
820  RegFlushKey(key);
821 
822  sprintf(buffer, "%s tests/shellpath.c 2", selfname);
823  memset(&startup, 0, sizeof(startup));
824  startup.cb = sizeof(startup);
825  startup.dwFlags = STARTF_USESHOWWINDOW;
826  startup.wShowWindow = SW_SHOWNORMAL;
828  &startup, &info);
829  ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0,
830  "child process termination\n");
831  }
832  }
833  else skip("RegQueryValueExA(key, Favorites, ...) failed\n");
834  if (key)
835  RegCloseKey(key);
836  }
837  else skip("RegOpenKeyExA(HKEY_CURRENT_USER, %s, ...) failed\n", userShellFolders);
838 }
839 
840 static void test_SHGetFolderPathEx(void)
841 {
842  HRESULT hr;
844  DWORD len;
845 
846  if (!pSHGetKnownFolderPath || !pSHGetFolderPathEx)
847  {
848  win_skip("SHGetKnownFolderPath or SHGetFolderPathEx not available\n");
849  return;
850  }
851 
852 if (0) { /* crashes */
853  hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, NULL);
854  ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
855 }
856  /* non-existent folder id */
857  path = (void *)0xdeadbeef;
858  hr = pSHGetKnownFolderPath(&IID_IOleObject, 0, NULL, &path);
859  ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
860  ok(path == NULL, "got %p\n", path);
861 
862  path = NULL;
863  hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, KF_FLAG_DEFAULT_PATH, NULL, &path);
864  ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
865  ok(path != NULL, "expected path != NULL\n");
867 
868  path = NULL;
869  hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &path);
870  ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
871  ok(path != NULL, "expected path != NULL\n");
872 
873  hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, MAX_PATH);
874  ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
875  ok(!lstrcmpiW(path, buffer), "expected equal paths\n");
876  len = lstrlenW(buffer);
878 
879  hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, 0);
880  ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
881 
882 if (0) { /* crashes */
883  hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, NULL, len + 1);
884  ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
885 
886  hr = pSHGetFolderPathEx(NULL, 0, NULL, buffer, MAX_PATH);
887  ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
888 }
889  hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, len);
890  ok(hr == E_NOT_SUFFICIENT_BUFFER, "expected E_NOT_SUFFICIENT_BUFFER, got 0x%08x\n", hr);
891 
892  hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, len + 1);
893  ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
894 }
895 
896 /* Standard CSIDL values (and their flags) uses only two less-significant bytes */
897 #define NO_CSIDL 0x10000
898 #define WINE_ATTRIBUTES_OPTIONAL 0x20000
899 #define KNOWN_FOLDER(id, csidl, name, category, parent1, parent2, relative_path, parsing_name, attributes, definitionFlags) \
900  { &id, # id, csidl, # csidl, name, category, {&parent1, &parent2}, relative_path, parsing_name, attributes, definitionFlags, __LINE__ }
901 
902 /* non-published known folders test */
903 static const GUID _FOLDERID_CryptoKeys = {0xB88F4DAA, 0xE7BD, 0x49A9, {0xB7, 0x4D, 0x02, 0x88, 0x5A, 0x5D, 0xC7, 0x65} };
904 static const GUID _FOLDERID_DpapiKeys = {0x10C07CD0, 0xEF91, 0x4567, {0xB8, 0x50, 0x44, 0x8B, 0x77, 0xCB, 0x37, 0xF9} };
905 static const GUID _FOLDERID_SystemCertificates = {0x54EED2E0, 0xE7CA, 0x4FDB, {0x91, 0x48, 0x0F, 0x42, 0x47, 0x29, 0x1C, 0xFA} };
906 static const GUID _FOLDERID_CredentialManager = {0x915221FB, 0x9EFE, 0x4BDA, {0x8F, 0xD7, 0xF7, 0x8D, 0xCA, 0x77, 0x4F, 0x87} };
907 
910  const char *sFolderId;
911  const int csidl;
912  const char *sCsidl;
913  const char *sName;
914  const KF_CATEGORY category;
916  const char *sRelativePath;
917  const char *sParsingName;
920  const int line;
921 };
922 
923 /* Note: content of parsing name may vary between Windows versions.
924  * As a base, values from 6.0 (Vista) were used. Some entries may contain
925  * alternative values. In that case, Windows version where the value was
926  * found is noted.
927  *
928  * The list of values for parsing name was encoded as a number of null-
929  * terminated strings placed one by one (separated by null byte only).
930  * End of list is marked by two consecutive null bytes.
931  */
932 static const struct knownFolderDef known_folders[] = {
933  KNOWN_FOLDER(FOLDERID_AddNewPrograms,
934  NO_CSIDL,
935  "AddNewProgramsFolder",
936  KF_CATEGORY_VIRTUAL,
938  NULL,
939  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{15eae92e-f17a-4431-9f28-805e482dafd4}\0"
940  "shell:::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{15eae92e-f17a-4431-9f28-805e482dafd4}\0\0" /* 6.1 */,
941  0,
942  0),
943  KNOWN_FOLDER(FOLDERID_AdminTools,
945  "Administrative Tools",
946  KF_CATEGORY_PERUSER,
947  FOLDERID_Programs, GUID_NULL,
948  "Administrative Tools",
949  NULL,
952  KNOWN_FOLDER(FOLDERID_AppUpdates,
953  NO_CSIDL,
954  "AppUpdatesFolder",
955  KF_CATEGORY_VIRTUAL,
957  NULL,
958  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{7b81be6a-ce2b-4676-a29e-eb907a5126c5}\\::{d450a8a1-9568-45c7-9c0e-b4f9fb4537bd}\0"
959  "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{7b81be6a-ce2b-4676-a29e-eb907a5126c5}\\::{d450a8a1-9568-45c7-9c0e-b4f9fb4537bd}\0\0" /* 6.1 */,
960  0,
961  0),
962  KNOWN_FOLDER(FOLDERID_CDBurning,
964  "CD Burning",
965  KF_CATEGORY_PERUSER,
966  FOLDERID_LocalAppData, GUID_NULL,
967  "Microsoft\\Windows\\Burn\\Burn",
968  NULL,
971  KNOWN_FOLDER(FOLDERID_ChangeRemovePrograms,
972  NO_CSIDL,
973  "ChangeRemoveProgramsFolder",
974  KF_CATEGORY_VIRTUAL,
976  NULL,
977  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{7b81be6a-ce2b-4676-a29e-eb907a5126c5}\0"
978  "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{7b81be6a-ce2b-4676-a29e-eb907a5126c5}\0\0" /* 6.1 */,
979  0,
980  0),
981  KNOWN_FOLDER(FOLDERID_CommonAdminTools,
983  "Common Administrative Tools",
984  KF_CATEGORY_COMMON,
985  FOLDERID_CommonPrograms, GUID_NULL,
986  "Administrative Tools",
987  NULL,
990  KNOWN_FOLDER(FOLDERID_CommonOEMLinks,
992  "OEM Links",
993  KF_CATEGORY_COMMON,
994  FOLDERID_ProgramData, GUID_NULL,
995  "OEM Links",
996  NULL,
997  0,
998  0),
999  KNOWN_FOLDER(FOLDERID_CommonPrograms,
1001  "Common Programs",
1002  KF_CATEGORY_COMMON,
1003  FOLDERID_CommonStartMenu, GUID_NULL,
1004  "Programs",
1005  NULL,
1007  KFDF_PRECREATE),
1008  KNOWN_FOLDER(FOLDERID_CommonStartMenu,
1010  "Common Start Menu",
1011  KF_CATEGORY_COMMON,
1012  FOLDERID_ProgramData, GUID_NULL,
1013  "Microsoft\\Windows\\Start Menu\0",
1014  NULL,
1016  KFDF_PRECREATE),
1017  KNOWN_FOLDER(FOLDERID_CommonStartup,
1019  "Common Startup",
1020  KF_CATEGORY_COMMON,
1021  FOLDERID_CommonPrograms, GUID_NULL,
1022  "StartUp",
1023  NULL,
1025  KFDF_PRECREATE),
1026  KNOWN_FOLDER(FOLDERID_CommonTemplates,
1028  "Common Templates",
1029  KF_CATEGORY_COMMON,
1030  FOLDERID_ProgramData, GUID_NULL,
1031  "Microsoft\\Windows\\Templates\0",
1032  NULL,
1033  0,
1034  0),
1035  KNOWN_FOLDER(FOLDERID_ComputerFolder,
1036  CSIDL_DRIVES,
1037  "MyComputerFolder",
1038  KF_CATEGORY_VIRTUAL,
1040  NULL,
1041  "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\0\0",
1042  0,
1043  0),
1044  KNOWN_FOLDER(FOLDERID_ConflictFolder,
1045  NO_CSIDL,
1046  "ConflictFolder",
1047  KF_CATEGORY_VIRTUAL,
1049  NULL,
1050  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\\::{E413D040-6788-4C22-957E-175D1C513A34},\0"
1051  "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\\::{E413D040-6788-4C22-957E-175D1C513A34},\0\0" /* 6.1 */,
1052  0,
1053  0),
1054  KNOWN_FOLDER(FOLDERID_ConnectionsFolder,
1056  "ConnectionsFolder",
1057  KF_CATEGORY_VIRTUAL,
1059  NULL,
1060  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{7007ACC7-3202-11D1-AAD2-00805FC1270E}\0"
1061  "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{7007ACC7-3202-11D1-AAD2-00805FC1270E}\0\0" /* 6.1 */,
1062  0,
1063  0),
1064  KNOWN_FOLDER(FOLDERID_Contacts,
1065  NO_CSIDL,
1066  "Contacts",
1067  KF_CATEGORY_PERUSER,
1068  FOLDERID_Profile, GUID_NULL,
1069  "Contacts",
1070  "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{56784854-C6CB-462B-8169-88E350ACB882}\0\0",
1073  KNOWN_FOLDER(FOLDERID_ControlPanelFolder,
1075  "ControlPanelFolder",
1076  KF_CATEGORY_VIRTUAL,
1078  NULL,
1079  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\0"
1080  "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\0\0" /* 6.1 */,
1081  0,
1082  0),
1083  KNOWN_FOLDER(FOLDERID_Cookies,
1084  CSIDL_COOKIES,
1085  "Cookies",
1086  KF_CATEGORY_PERUSER,
1087  FOLDERID_RoamingAppData, FOLDERID_LocalAppData,
1088  "Microsoft\\Windows\\Cookies\0Microsoft\\Windows\\INetCookies\0" /* win8 */,
1089  NULL,
1090  0,
1091  0),
1092  KNOWN_FOLDER(FOLDERID_Desktop,
1093  CSIDL_DESKTOP,
1094  "Desktop",
1095  KF_CATEGORY_PERUSER,
1096  FOLDERID_Profile, GUID_NULL,
1097  "Desktop",
1098  NULL,
1101  KNOWN_FOLDER(FOLDERID_DeviceMetadataStore,
1102  NO_CSIDL,
1103  "Device Metadata Store",
1104  KF_CATEGORY_COMMON,
1105  FOLDERID_ProgramData, GUID_NULL,
1106  "Microsoft\\Windows\\DeviceMetadataStore\0",
1107  NULL,
1108  0,
1109  0),
1110  KNOWN_FOLDER(FOLDERID_Documents,
1112  "Personal",
1113  KF_CATEGORY_PERUSER,
1114  FOLDERID_Profile, GUID_NULL,
1115  "Documents\0",
1116  "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{FDD39AD0-238F-46AF-ADB4-6C85480369C7}\0shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{A8CDFF1C-4878-43be-B5FD-F8091C1C60D0}\0\0", /* win8 */
1119  KNOWN_FOLDER(FOLDERID_DocumentsLibrary,
1120  NO_CSIDL,
1121  "DocumentsLibrary",
1122  KF_CATEGORY_PERUSER,
1123  FOLDERID_Libraries, GUID_NULL,
1124  "Documents.library-ms\0",
1125  "::{031E4825-7B94-4dc3-B131-E946B44C8DD5}\\{7b0db17d-9cd2-4a93-9733-46cc89022e7c}\0\0",
1126  0,
1128  KNOWN_FOLDER(FOLDERID_Downloads,
1129  NO_CSIDL,
1130  "Downloads",
1131  KF_CATEGORY_PERUSER,
1132  FOLDERID_Profile, GUID_NULL,
1133  "Downloads\0",
1134  "(null)\0shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{374DE290-123F-4565-9164-39C4925E467B}\0\0", /* win8 */
1137  KNOWN_FOLDER(FOLDERID_Favorites,
1139  "Favorites",
1140  KF_CATEGORY_PERUSER,
1141  FOLDERID_Profile, GUID_NULL,
1142  "Favorites\0",
1143  NULL,
1146  KNOWN_FOLDER(FOLDERID_Fonts,
1147  CSIDL_FONTS,
1148  "Fonts",
1149  KF_CATEGORY_FIXED,
1150  FOLDERID_Windows, GUID_NULL,
1151  NULL,
1152  NULL,
1153  0,
1154  0),
1155  KNOWN_FOLDER(FOLDERID_Games,
1156  NO_CSIDL,
1157  "Games",
1158  KF_CATEGORY_VIRTUAL,
1160  NULL,
1161  "::{ED228FDF-9EA8-4870-83b1-96b02CFE0D52}\0\0",
1162  0,
1163  0),
1164  KNOWN_FOLDER(FOLDERID_GameTasks,
1165  NO_CSIDL,
1166  "GameTasks",
1167  KF_CATEGORY_PERUSER,
1168  FOLDERID_LocalAppData, GUID_NULL,
1169  "Microsoft\\Windows\\GameExplorer\0",
1170  NULL,
1171  0,
1173  KNOWN_FOLDER(FOLDERID_History,
1174  CSIDL_HISTORY,
1175  "History",
1176  KF_CATEGORY_PERUSER,
1177  FOLDERID_LocalAppData, GUID_NULL,
1178  "Microsoft\\Windows\\History\0",
1179  NULL,
1180  0,
1182  KNOWN_FOLDER(FOLDERID_HomeGroup,
1183  NO_CSIDL,
1184  "HomeGroupFolder",
1185  KF_CATEGORY_VIRTUAL,
1187  NULL,
1188  "::{B4FB3F98-C1EA-428d-A78A-D1F5659CBA93}\0\0",
1189  0,
1190  0),
1191  KNOWN_FOLDER(FOLDERID_ImplicitAppShortcuts,
1192  NO_CSIDL,
1193  "ImplicitAppShortcuts",
1194  KF_CATEGORY_PERUSER,
1195  FOLDERID_UserPinned, GUID_NULL,
1196  "ImplicitAppShortcuts\0",
1197  NULL,
1198  0,
1199  KFDF_PRECREATE),
1200  KNOWN_FOLDER(FOLDERID_InternetCache,
1202  "Cache",
1203  KF_CATEGORY_PERUSER,
1204  FOLDERID_LocalAppData, GUID_NULL,
1205  "Microsoft\\Windows\\Temporary Internet Files\0Microsoft\\Windows\\INetCache\0\0", /* win8 */
1206  NULL,
1207  0,
1209  KNOWN_FOLDER(FOLDERID_InternetFolder,
1211  "InternetFolder",
1212  KF_CATEGORY_VIRTUAL,
1214  NULL,
1215  "::{871C5380-42A0-1069-A2EA-08002B30309D}\0\0",
1216  0,
1217  0),
1218  KNOWN_FOLDER(FOLDERID_Libraries,
1219  NO_CSIDL,
1220  "Libraries",
1221  KF_CATEGORY_PERUSER,
1222  FOLDERID_RoamingAppData, GUID_NULL,
1223  "Microsoft\\Windows\\Libraries\0",
1224  NULL,
1225  0,
1227  KNOWN_FOLDER(FOLDERID_Links,
1228  NO_CSIDL,
1229  "Links",
1230  KF_CATEGORY_PERUSER,
1231  FOLDERID_Profile, GUID_NULL,
1232  "Links\0",
1233  "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{bfb9d5e0-c6a9-404c-b2b2-ae6db6af4968}\0\0",
1236  KNOWN_FOLDER(FOLDERID_LocalAppData,
1238  "Local AppData",
1239  KF_CATEGORY_PERUSER,
1240  FOLDERID_Profile, GUID_NULL,
1241  "AppData\\Local\0",
1242  NULL,
1243  0,
1245  KNOWN_FOLDER(FOLDERID_LocalAppDataLow,
1246  NO_CSIDL,
1247  "LocalAppDataLow",
1248  KF_CATEGORY_PERUSER,
1249  FOLDERID_Profile, GUID_NULL,
1250  "AppData\\LocalLow\0",
1251  NULL,
1254  KNOWN_FOLDER(FOLDERID_LocalizedResourcesDir,
1256  "LocalizedResourcesDir",
1257  KF_CATEGORY_FIXED,
1259  NULL,
1260  NULL,
1261  0,
1262  0),
1263  KNOWN_FOLDER(FOLDERID_Music,
1264  CSIDL_MYMUSIC,
1265  "My Music",
1266  KF_CATEGORY_PERUSER,
1267  FOLDERID_Profile, GUID_NULL,
1268  "Music\0",
1269  "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{4BD8D571-6D19-48D3-BE97-422220080E43}\0shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{1CF1260C-4DD0-4EBB-811F-33C572699FDE}\0\0", /* win8 */
1272  KNOWN_FOLDER(FOLDERID_MusicLibrary,
1273  NO_CSIDL,
1274  "MusicLibrary",
1275  KF_CATEGORY_PERUSER,
1276  FOLDERID_Libraries, GUID_NULL,
1277  "Music.library-ms\0",
1278  "::{031E4825-7B94-4dc3-B131-E946B44C8DD5}\\{2112AB0A-C86A-4ffe-A368-0DE96E47012E}\0\0",
1279  0,
1281  KNOWN_FOLDER(FOLDERID_NetHood,
1282  CSIDL_NETHOOD,
1283  "NetHood",
1284  KF_CATEGORY_PERUSER,
1285  FOLDERID_RoamingAppData, GUID_NULL,
1286  "Microsoft\\Windows\\Network Shortcuts\0",
1287  NULL,
1288  0,
1289  0),
1290  KNOWN_FOLDER(FOLDERID_NetworkFolder,
1291  CSIDL_NETWORK,
1292  "NetworkPlacesFolder",
1293  KF_CATEGORY_VIRTUAL,
1295  NULL,
1296  "::{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}\0\0",
1297  0,
1298  0),
1299  KNOWN_FOLDER(FOLDERID_OriginalImages,
1300  NO_CSIDL,
1301  "Original Images",
1302  KF_CATEGORY_PERUSER,
1303  FOLDERID_LocalAppData, GUID_NULL,
1304  "Microsoft\\Windows Photo Gallery\\Original Images\0",
1305  NULL,
1306  0,
1307  0),
1308  KNOWN_FOLDER(FOLDERID_PhotoAlbums,
1309  NO_CSIDL,
1310  "PhotoAlbums",
1311  KF_CATEGORY_PERUSER,
1312  FOLDERID_Pictures, GUID_NULL,
1313  "Slide Shows\0",
1314  NULL,
1316  0),
1317  KNOWN_FOLDER(FOLDERID_Pictures,
1319  "My Pictures",
1320  KF_CATEGORY_PERUSER,
1321  FOLDERID_Profile, GUID_NULL,
1322  "Pictures\0",
1323  "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{33E28130-4E1E-4676-835A-98395C3BC3BB}\0shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{3ADD1653-EB32-4CB0-BBD7-DFA0ABB5ACCA}\0\0", /* win8 */
1326  KNOWN_FOLDER(FOLDERID_PicturesLibrary,
1327  NO_CSIDL,
1328  "PicturesLibrary",
1329  KF_CATEGORY_PERUSER,
1330  FOLDERID_Libraries, GUID_NULL,
1331  "Pictures.library-ms\0",
1332  "::{031E4825-7B94-4dc3-B131-E946B44C8DD5}\\{A990AE9F-A03B-4e80-94BC-9912D7504104}\0\0",
1333  0,
1335  KNOWN_FOLDER(FOLDERID_Playlists,
1336  NO_CSIDL,
1337  "Playlists",
1338  KF_CATEGORY_PERUSER,
1339  FOLDERID_Music, GUID_NULL,
1340  "Playlists\0",
1341  NULL,
1343  0),
1344  KNOWN_FOLDER(FOLDERID_PrintersFolder,
1346  "PrintersFolder",
1347  KF_CATEGORY_VIRTUAL,
1349  NULL,
1350  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{2227A280-3AEA-1069-A2DE-08002B30309D}\0\0",
1351  0,
1352  0),
1353  KNOWN_FOLDER(FOLDERID_PrintHood,
1355  "PrintHood",
1356  KF_CATEGORY_PERUSER,
1357  FOLDERID_RoamingAppData, GUID_NULL,
1358  "Microsoft\\Windows\\Printer Shortcuts\0",
1359  NULL,
1360  0,
1361  0),
1362  KNOWN_FOLDER(FOLDERID_Profile,
1363  CSIDL_PROFILE,
1364  "Profile",
1365  KF_CATEGORY_FIXED,
1367  NULL,
1368  NULL,
1369  0,
1370  0),
1371  KNOWN_FOLDER(FOLDERID_ProgramData,
1373  "Common AppData",
1374  KF_CATEGORY_FIXED,
1376  NULL,
1377  NULL,
1378  0,
1379  0),
1380  KNOWN_FOLDER(FOLDERID_ProgramFiles,
1382  "ProgramFiles",
1383  KF_CATEGORY_FIXED,
1385  NULL,
1386  NULL,
1389  ),
1390  KNOWN_FOLDER(FOLDERID_ProgramFilesCommon,
1392  "ProgramFilesCommon",
1393  KF_CATEGORY_FIXED,
1395  NULL,
1396  NULL,
1397  0,
1398  0),
1399  KNOWN_FOLDER(FOLDERID_ProgramFilesCommonX64,
1400  NO_CSIDL,
1401  "ProgramFilesCommonX64",
1402  KF_CATEGORY_FIXED,
1404  NULL,
1405  NULL,
1406  0,
1407  0),
1408  KNOWN_FOLDER(FOLDERID_ProgramFilesCommonX86,
1409  NO_CSIDL,
1410  "ProgramFilesCommonX86",
1411  KF_CATEGORY_FIXED,
1413  NULL,
1414  NULL,
1415  0,
1416  0),
1417  KNOWN_FOLDER(FOLDERID_ProgramFilesX64,
1418  NO_CSIDL,
1419  "ProgramFilesX64",
1420  KF_CATEGORY_FIXED,
1422  NULL,
1423  NULL,
1424  0,
1425  0),
1426  KNOWN_FOLDER(FOLDERID_ProgramFilesX86,
1428  "ProgramFilesX86",
1429  KF_CATEGORY_FIXED,
1431  NULL,
1432  NULL,
1434  KFDF_PRECREATE),
1435  KNOWN_FOLDER(FOLDERID_Programs,
1437  "Programs",
1438  KF_CATEGORY_PERUSER,
1439  FOLDERID_StartMenu, GUID_NULL,
1440  "Programs\0",
1441  NULL,
1443  KFDF_PRECREATE),
1444  KNOWN_FOLDER(FOLDERID_Public,
1445  NO_CSIDL,
1446  "Public",
1447  KF_CATEGORY_FIXED,
1449  NULL,
1450  "::{4336a54d-038b-4685-ab02-99bb52d3fb8b}\0"
1451  "(null)\0\0" /* 6.1 */,
1453  KFDF_PRECREATE),
1454  KNOWN_FOLDER(FOLDERID_PublicDesktop,
1456  "Common Desktop",
1457  KF_CATEGORY_COMMON,
1458  FOLDERID_Public, GUID_NULL,
1459  "Desktop\0",
1460  NULL,
1462  KFDF_PRECREATE),
1463  KNOWN_FOLDER(FOLDERID_PublicDocuments,
1465  "Common Documents",
1466  KF_CATEGORY_COMMON,
1467  FOLDERID_Public, GUID_NULL,
1468  "Documents\0",
1469  NULL,
1471  KFDF_PRECREATE),
1472  KNOWN_FOLDER(FOLDERID_PublicDownloads,
1473  NO_CSIDL,
1474  "CommonDownloads",
1475  KF_CATEGORY_COMMON,
1476  FOLDERID_Public, GUID_NULL,
1477  "Downloads\0",
1478  NULL,
1480  KFDF_PRECREATE),
1481  KNOWN_FOLDER(FOLDERID_PublicGameTasks,
1482  NO_CSIDL,
1483  "PublicGameTasks",
1484  KF_CATEGORY_COMMON,
1485  FOLDERID_ProgramData, GUID_NULL,
1486  "Microsoft\\Windows\\GameExplorer\0",
1487  NULL,
1488  0,
1490  KNOWN_FOLDER(FOLDERID_PublicLibraries,
1491  NO_CSIDL,
1492  "PublicLibraries",
1493  KF_CATEGORY_COMMON,
1494  FOLDERID_Public, GUID_NULL,
1495  "Libraries\0",
1496  NULL,
1498  KFDF_PRECREATE),
1499  KNOWN_FOLDER(FOLDERID_PublicMusic,
1501  "CommonMusic",
1502  KF_CATEGORY_COMMON,
1503  FOLDERID_Public, GUID_NULL,
1504  "Music\0",
1505  NULL,
1507  KFDF_PRECREATE),
1508  KNOWN_FOLDER(FOLDERID_PublicPictures,
1510  "CommonPictures",
1511  KF_CATEGORY_COMMON,
1512  FOLDERID_Public, GUID_NULL,
1513  "Pictures\0",
1514  NULL,
1516  KFDF_PRECREATE),
1517  KNOWN_FOLDER(FOLDERID_PublicRingtones,
1518  NO_CSIDL,
1519  "CommonRingtones",
1520  KF_CATEGORY_COMMON,
1521  FOLDERID_ProgramData, GUID_NULL,
1522  "Microsoft\\Windows\\Ringtones\0",
1523  NULL,
1524  0,
1525  KFDF_PRECREATE),
1526  KNOWN_FOLDER(FOLDERID_PublicVideos,
1528  "CommonVideo",
1529  KF_CATEGORY_COMMON,
1530  FOLDERID_Public, GUID_NULL,
1531  "Videos\0",
1532  NULL,
1534  KFDF_PRECREATE),
1535  KNOWN_FOLDER(FOLDERID_QuickLaunch,
1536  NO_CSIDL,
1537  "Quick Launch",
1538  KF_CATEGORY_PERUSER,
1539  FOLDERID_RoamingAppData, GUID_NULL,
1540  "Microsoft\\Internet Explorer\\Quick Launch\0",
1541  NULL,
1542  0,
1543  0),
1544  KNOWN_FOLDER(FOLDERID_Recent,
1545  CSIDL_RECENT,
1546  "Recent",
1547  KF_CATEGORY_PERUSER,
1548  FOLDERID_RoamingAppData, GUID_NULL,
1549  "Microsoft\\Windows\\Recent\0",
1550  NULL,
1552  KFDF_PRECREATE),
1553  KNOWN_FOLDER(FOLDERID_RecordedTVLibrary,
1554  NO_CSIDL,
1555  "RecordedTVLibrary",
1556  KF_CATEGORY_COMMON,
1557  FOLDERID_PublicLibraries, GUID_NULL,
1558  "RecordedTV.library-ms\0",
1559  NULL,
1560  0,
1562  KNOWN_FOLDER(FOLDERID_RecycleBinFolder,
1564  "RecycleBinFolder",
1565  KF_CATEGORY_VIRTUAL,
1567  NULL,
1568  "::{645FF040-5081-101B-9F08-00AA002F954E}\0\0",
1569  0,
1570  0),
1571  KNOWN_FOLDER(FOLDERID_ResourceDir,
1573  "ResourceDir",
1574  KF_CATEGORY_FIXED,
1576  NULL,
1577  NULL,
1578  0,
1579  0),
1580  KNOWN_FOLDER(FOLDERID_Ringtones,
1581  NO_CSIDL,
1582  "Ringtones",
1583  KF_CATEGORY_PERUSER,
1584  FOLDERID_LocalAppData, GUID_NULL,
1585  "Microsoft\\Windows\\Ringtones\0",
1586  NULL,
1587  0,
1588  KFDF_PRECREATE),
1589  KNOWN_FOLDER(FOLDERID_RoamingAppData,
1590  CSIDL_APPDATA,
1591  "AppData",
1592  KF_CATEGORY_PERUSER,
1593  FOLDERID_Profile, GUID_NULL,
1594  "AppData\\Roaming\0",
1595  NULL,
1596  0,
1597  0),
1598  KNOWN_FOLDER(FOLDERID_SampleMusic,
1600  "SampleMusic",
1601  KF_CATEGORY_COMMON,
1602  FOLDERID_PublicMusic, GUID_NULL,
1603  "Sample Music\0",
1604  NULL,
1606  KFDF_PRECREATE),
1607  KNOWN_FOLDER(FOLDERID_SamplePictures,
1609  "SamplePictures",
1610  KF_CATEGORY_COMMON,
1611  FOLDERID_PublicPictures, GUID_NULL,
1612  "Sample Pictures\0",
1613  NULL,
1615  KFDF_PRECREATE),
1616  KNOWN_FOLDER(FOLDERID_SamplePlaylists,
1617  NO_CSIDL,
1618  "SamplePlaylists",
1619  KF_CATEGORY_COMMON,
1620  FOLDERID_PublicMusic, GUID_NULL,
1621  "Sample Playlists\0",
1622  NULL,
1624  0),
1625  KNOWN_FOLDER(FOLDERID_SampleVideos,
1627  "SampleVideos",
1628  KF_CATEGORY_COMMON,
1629  FOLDERID_PublicVideos, GUID_NULL,
1630  "Sample Videos\0",
1631  NULL,
1633  KFDF_PRECREATE),
1634  KNOWN_FOLDER(FOLDERID_SavedGames,
1635  NO_CSIDL,
1636  "SavedGames",
1637  KF_CATEGORY_PERUSER,
1638  FOLDERID_Profile, GUID_NULL,
1639  "Saved Games\0",
1640  "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{4C5C32FF-BB9D-43b0-B5B4-2D72E54EAAA4}\0\0",
1643  KNOWN_FOLDER(FOLDERID_SavedSearches,
1644  NO_CSIDL,
1645  "Searches",
1646  KF_CATEGORY_PERUSER,
1647  FOLDERID_Profile, GUID_NULL,
1648  "Searches\0",
1649  "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{7d1d3a04-debb-4115-95cf-2f29da2920da}\0\0",
1652  KNOWN_FOLDER(FOLDERID_SEARCH_CSC,
1653  NO_CSIDL,
1654  "CSCFolder",
1655  KF_CATEGORY_VIRTUAL,
1657  NULL,
1658  "shell:::{BD7A2E7B-21CB-41b2-A086-B309680C6B7E}\\*\0\0",
1659  0,
1660  0),
1661  KNOWN_FOLDER(FOLDERID_SearchHome,
1662  NO_CSIDL,
1663  "SearchHomeFolder",
1664  KF_CATEGORY_VIRTUAL,
1666  NULL,
1667  "::{9343812e-1c37-4a49-a12e-4b2d810d956b}\0\0",
1668  0,
1669  0),
1670  KNOWN_FOLDER(FOLDERID_SEARCH_MAPI,
1671  NO_CSIDL,
1672  "MAPIFolder",
1673  KF_CATEGORY_VIRTUAL,
1675  NULL,
1676  "shell:::{89D83576-6BD1-4C86-9454-BEB04E94C819}\\*\0\0",
1677  0,
1678  0),
1679  KNOWN_FOLDER(FOLDERID_SendTo,
1680  CSIDL_SENDTO,
1681  "SendTo",
1682  KF_CATEGORY_PERUSER,
1683  FOLDERID_RoamingAppData, GUID_NULL,
1684  "Microsoft\\Windows\\SendTo\0",
1685  NULL,
1686  0,
1687  0),
1688  KNOWN_FOLDER(FOLDERID_SidebarDefaultParts,
1689  NO_CSIDL,
1690  "Default Gadgets",
1691  KF_CATEGORY_COMMON,
1692  FOLDERID_ProgramFiles, GUID_NULL,
1693  "Windows Sidebar\\Gadgets\0",
1694  NULL,
1695  0,
1696  0),
1697  KNOWN_FOLDER(FOLDERID_SidebarParts,
1698  NO_CSIDL,
1699  "Gadgets",
1700  KF_CATEGORY_PERUSER,
1701  FOLDERID_LocalAppData, GUID_NULL,
1702  "Microsoft\\Windows Sidebar\\Gadgets\0",
1703  NULL,
1704  0,
1705  0),
1706  KNOWN_FOLDER(FOLDERID_StartMenu,
1708  "Start Menu",
1709  KF_CATEGORY_PERUSER,
1710  FOLDERID_RoamingAppData, GUID_NULL,
1711  "Microsoft\\Windows\\Start Menu\0",
1712  NULL,
1714  KFDF_PRECREATE),
1715  KNOWN_FOLDER(FOLDERID_Startup,
1716  CSIDL_STARTUP,
1717  "Startup",
1718  KF_CATEGORY_PERUSER,
1719  FOLDERID_Programs, GUID_NULL,
1720  "StartUp\0",
1721  NULL,
1723  KFDF_PRECREATE),
1724  KNOWN_FOLDER(FOLDERID_SyncManagerFolder,
1725  NO_CSIDL,
1726  "SyncCenterFolder",
1727  KF_CATEGORY_VIRTUAL,
1729  NULL,
1730  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\0"
1731  "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\0\0" /* 6.1 */,
1732  0,
1733  0),
1734  KNOWN_FOLDER(FOLDERID_SyncResultsFolder,
1735  NO_CSIDL,
1736  "SyncResultsFolder",
1737  KF_CATEGORY_VIRTUAL,
1739  NULL,
1740  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\\::{BC48B32F-5910-47F5-8570-5074A8A5636A},\0"
1741  "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\\::{BC48B32F-5910-47F5-8570-5074A8A5636A},\0\0",
1742  0,
1743  0),
1744  KNOWN_FOLDER(FOLDERID_SyncSetupFolder,
1745  NO_CSIDL,
1746  "SyncSetupFolder",
1747  KF_CATEGORY_VIRTUAL,
1749  NULL,
1750  "::{21EC2020-3AEA-1069-A2DD-08002B30309D}\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\\::{F1390A9A-A3F4-4E5D-9C5F-98F3BD8D935C},\0"
1751  "::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{9C73F5E5-7AE7-4E32-A8E8-8D23B85255BF}\\::{F1390A9A-A3F4-4E5D-9C5F-98F3BD8D935C},\0\0" /* 6.1 */,
1752  0,
1753  0),
1754  KNOWN_FOLDER(FOLDERID_System,
1755  CSIDL_SYSTEM,
1756  "System",
1757  KF_CATEGORY_FIXED,
1759  NULL,
1760  NULL,
1761  0,
1762  0),
1763  KNOWN_FOLDER(FOLDERID_SystemX86,
1765  "SystemX86",
1766  KF_CATEGORY_FIXED,
1768  NULL,
1769  NULL,
1770  0,
1771  0),
1772  KNOWN_FOLDER(FOLDERID_Templates,
1774  "Templates",
1775  KF_CATEGORY_PERUSER,
1776  FOLDERID_RoamingAppData, GUID_NULL,
1777  "Microsoft\\Windows\\Templates\0",
1778  NULL,
1779  0,
1780  0),
1781  KNOWN_FOLDER(FOLDERID_UserPinned,
1782  NO_CSIDL,
1783  "User Pinned",
1784  KF_CATEGORY_PERUSER,
1785  FOLDERID_QuickLaunch, GUID_NULL,
1786  "User Pinned\0",
1787  NULL,
1789  KFDF_PRECREATE),
1790  KNOWN_FOLDER(FOLDERID_UserProfiles,
1791  NO_CSIDL,
1792  "UserProfiles",
1793  KF_CATEGORY_FIXED,
1795  NULL,
1796  NULL,
1798  KFDF_PRECREATE),
1799  KNOWN_FOLDER(FOLDERID_UserProgramFiles,
1800  NO_CSIDL,
1801  "UserProgramFiles",
1802  KF_CATEGORY_PERUSER,
1803  FOLDERID_LocalAppData, GUID_NULL,
1804  "Programs\0",
1805  NULL,
1806  0,
1807  0),
1808  KNOWN_FOLDER(FOLDERID_UserProgramFilesCommon,
1809  NO_CSIDL,
1810  "UserProgramFilesCommon",
1811  KF_CATEGORY_PERUSER,
1812  FOLDERID_UserProgramFiles, GUID_NULL,
1813  "Common\0",
1814  NULL,
1815  0,
1816  0),
1817  KNOWN_FOLDER(FOLDERID_UsersFiles,
1818  NO_CSIDL,
1819  "UsersFilesFolder",
1820  KF_CATEGORY_VIRTUAL,
1822  NULL,
1823  "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\0\0",
1824  0,
1825  0),
1826  KNOWN_FOLDER(FOLDERID_UsersLibraries,
1827  NO_CSIDL,
1828  "UsersLibrariesFolder",
1829  KF_CATEGORY_VIRTUAL,
1831  NULL,
1832  "::{031E4825-7B94-4dc3-B131-E946B44C8DD5}\0\0",
1833  0,
1834  0),
1835  KNOWN_FOLDER(FOLDERID_Videos,
1836  CSIDL_MYVIDEO,
1837  "My Video",
1838  KF_CATEGORY_PERUSER,
1839  FOLDERID_Profile, GUID_NULL,
1840  "Videos\0",
1841  "::{59031a47-3f72-44a7-89c5-5595fe6b30ee}\\{18989B1D-99B5-455B-841C-AB7C74E4DDFC}\0shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{A0953C92-50DC-43BF-BE83-3742FED03C9C}\0\0", /* win8 */
1844  KNOWN_FOLDER(FOLDERID_VideosLibrary,
1845  NO_CSIDL,
1846  "VideosLibrary",
1847  KF_CATEGORY_PERUSER,
1848  FOLDERID_Libraries, GUID_NULL,
1849  "Videos.library-ms\0",
1850  "::{031E4825-7B94-4dc3-B131-E946B44C8DD5}\\{491E922F-5643-4af4-A7EB-4E7A138D8174}\0\0",
1851  0,
1853  KNOWN_FOLDER(FOLDERID_Windows,
1854  CSIDL_WINDOWS,
1855  "Windows",
1856  KF_CATEGORY_FIXED,
1858  NULL,
1859  NULL,
1860  0,
1861  0),
1863  NO_CSIDL,
1864  "CredentialManager",
1865  KF_CATEGORY_FIXED,
1867  NULL,
1868  NULL,
1869  0,
1870  0),
1872  NO_CSIDL,
1873  "CryptoKeys",
1874  KF_CATEGORY_FIXED,
1876  NULL,
1877  NULL,
1878  0,
1879  0),
1881  NO_CSIDL,
1882  "DpapiKeys",
1883  KF_CATEGORY_FIXED,
1885  NULL,
1886  NULL,
1887  0,
1888  0),
1890  NO_CSIDL,
1891  "SystemCertificates",
1892  KF_CATEGORY_FIXED,
1894  NULL,
1895  NULL,
1896  0,
1897  0),
1898  { 0 }
1899 };
1900 #undef KNOWN_FOLDER
1902 
1903 static BOOL is_in_strarray(const WCHAR *needle, const char *hay)
1904 {
1905  WCHAR wstr[MAX_PATH];
1906 
1907  if(!needle && !hay)
1908  return TRUE;
1909 
1910  while(hay && *hay)
1911  {
1912  DWORD ret;
1913 
1914  if(strcmp(hay, "(null)") == 0 && !needle)
1915  return TRUE;
1916 
1917  ret = MultiByteToWideChar(CP_ACP, 0, hay, -1, wstr, ARRAY_SIZE(wstr));
1918  if(ret == 0)
1919  {
1920  ok(0, "Failed to convert string\n");
1921  return FALSE;
1922  }
1923 
1924  if(lstrcmpW(wstr, needle) == 0)
1925  return TRUE;
1926 
1927  hay += strlen(hay) + 1;
1928  }
1929 
1930  return FALSE;
1931 }
1932 
1934 {
1935  HRESULT hr;
1936  const struct knownFolderDef *known_folder = &known_folders[0];
1937  int csidl, expectedCsidl, ret;
1939  IKnownFolder *folder;
1940  WCHAR sName[1024];
1941  BOOL *current_known_folder_found = &known_folder_found[0];
1942  BOOL found = FALSE;
1943 
1944  while(known_folder->folderId != NULL)
1945  {
1946  if(IsEqualGUID(known_folder->folderId, folderId))
1947  {
1948  *current_known_folder_found = TRUE;
1949  found = TRUE;
1950  /* verify CSIDL */
1951  if(!(known_folder->csidl & NO_CSIDL))
1952  {
1953  /* mask off winetest flags */
1954  expectedCsidl = known_folder->csidl & 0xFFFF;
1955 
1956  hr = IKnownFolderManager_FolderIdToCsidl(mgr, folderId, &csidl);
1957  ok_(__FILE__, known_folder->line)(hr == S_OK, "cannot retrieve CSIDL for folder %s\n", known_folder->sFolderId);
1958 
1959  ok_(__FILE__, known_folder->line)(csidl == expectedCsidl, "invalid CSIDL retrieved for folder %s. %d (%s) expected, but %d found\n", known_folder->sFolderId, expectedCsidl, known_folder->sCsidl, csidl);
1960  }
1961 
1962  hr = IKnownFolderManager_GetFolder(mgr, folderId, &folder);
1963  ok_(__FILE__, known_folder->line)(hr == S_OK, "cannot get known folder for %s\n", known_folder->sFolderId);
1964  if(SUCCEEDED(hr))
1965  {
1966  hr = IKnownFolder_GetFolderDefinition(folder, &kfd);
1967  ok_(__FILE__, known_folder->line)(hr == S_OK, "cannot get known folder definition for %s\n", known_folder->sFolderId);
1968  if(SUCCEEDED(hr))
1969  {
1970  ret = MultiByteToWideChar(CP_ACP, 0, known_folder->sName, -1, sName, ARRAY_SIZE(sName));
1971  ok_(__FILE__, known_folder->line)(ret != 0, "cannot convert known folder name \"%s\" to wide characters\n", known_folder->sName);
1972 
1973  ok_(__FILE__, known_folder->line)(lstrcmpW(kfd.pszName, sName)==0, "invalid known folder name returned for %s: %s expected, but %s retrieved\n", known_folder->sFolderId, wine_dbgstr_w(sName), wine_dbgstr_w(kfd.pszName));
1974 
1975  ok_(__FILE__, known_folder->line)(kfd.category == known_folder->category, "invalid known folder category for %s: %d expected, but %d retrieved\n", known_folder->sFolderId, known_folder->category, kfd.category);
1976 
1977  ok_(__FILE__, known_folder->line)(IsEqualGUID(known_folder->fidParents[0], &kfd.fidParent) ||
1978  IsEqualGUID(known_folder->fidParents[1], &kfd.fidParent),
1979  "invalid known folder parent for %s: %s retrieved\n",
1980  known_folder->sFolderId, wine_dbgstr_guid(&kfd.fidParent));
1981 
1982  ok_(__FILE__, known_folder->line)(is_in_strarray(kfd.pszRelativePath, known_folder->sRelativePath), "invalid known folder relative path returned for %s: %s expected, but %s retrieved\n", known_folder->sFolderId, known_folder->sRelativePath, wine_dbgstr_w(kfd.pszRelativePath));
1983 
1984  ok_(__FILE__, known_folder->line)(is_in_strarray(kfd.pszParsingName, known_folder->sParsingName), "invalid known folder parsing name returned for %s: %s retrieved\n", known_folder->sFolderId, wine_dbgstr_w(kfd.pszParsingName));
1985 
1986  ok_(__FILE__, known_folder->line)(known_folder->attributes == kfd.dwAttributes ||
1987  (known_folder->csidl & WINE_ATTRIBUTES_OPTIONAL && kfd.dwAttributes == 0),
1988  "invalid known folder attributes for %s: 0x%08x expected, but 0x%08x retrieved\n", known_folder->sFolderId, known_folder->attributes, kfd.dwAttributes);
1989 
1990  ok_(__FILE__, known_folder->line)(!(kfd.kfdFlags & (~known_folder->definitionFlags)), "invalid known folder flags for %s: 0x%08x expected, but 0x%08x retrieved\n", known_folder->sFolderId, known_folder->definitionFlags, kfd.kfdFlags);
1991 
1993  }
1994 
1995  IKnownFolder_Release(folder);
1996  }
1997 
1998  break;
1999  }
2000  known_folder++;
2001  current_known_folder_found++;
2002  }
2003 
2004  if(!found)
2005  {
2006  trace("unknown known folder found: %s\n", wine_dbgstr_guid(folderId));
2007 
2008  hr = IKnownFolderManager_GetFolder(mgr, folderId, &folder);
2009  ok(hr == S_OK, "cannot get known folder for %s\n", wine_dbgstr_guid(folderId));
2010  if(SUCCEEDED(hr))
2011  {
2012  hr = IKnownFolder_GetFolderDefinition(folder, &kfd);
2013  todo_wine
2014  ok(hr == S_OK, "cannot get known folder definition for %s\n", wine_dbgstr_guid(folderId));
2015  if(SUCCEEDED(hr))
2016  {
2017  trace(" category: %d\n", kfd.category);
2018  trace(" name: %s\n", wine_dbgstr_w(kfd.pszName));
2019  trace(" description: %s\n", wine_dbgstr_w(kfd.pszDescription));
2020  trace(" parent: %s\n", wine_dbgstr_guid(&kfd.fidParent));
2021  trace(" relative path: %s\n", wine_dbgstr_w(kfd.pszRelativePath));
2022  trace(" parsing name: %s\n", wine_dbgstr_w(kfd.pszParsingName));
2023  trace(" tooltip: %s\n", wine_dbgstr_w(kfd.pszTooltip));
2024  trace(" localized name: %s\n", wine_dbgstr_w(kfd.pszLocalizedName));
2025  trace(" icon: %s\n", wine_dbgstr_w(kfd.pszIcon));
2026  trace(" security: %s\n", wine_dbgstr_w(kfd.pszSecurity));
2027  trace(" attributes: 0x%08x\n", kfd.dwAttributes);
2028  trace(" flags: 0x%08x\n", kfd.kfdFlags);
2029  trace(" type: %s\n", wine_dbgstr_guid(&kfd.ftidType));
2031  }
2032 
2033  IKnownFolder_Release(folder);
2034  }
2035  }
2036 }
2037 #undef NO_CSIDL
2038 
2039 static void test_knownFolders(void)
2040 {
2041  static const WCHAR sWindows[] = {'W','i','n','d','o','w','s',0};
2042  static const WCHAR sWindows2[] = {'w','i','n','d','o','w','s',0};
2043  static const WCHAR sExample[] = {'E','x','a','m','p','l','e',0};
2044  static const WCHAR sExample2[] = {'E','x','a','m','p','l','e','2',0};
2045  static const WCHAR sSubFolder[] = {'S','u','b','F','o','l','d','e','r',0};
2046  static const WCHAR sNoSuch[] = {'N','o','S','u','c','h',0};
2047  static const WCHAR sBackslash[] = {'\\',0};
2048  static const KNOWNFOLDERID newFolderId = {0x01234567, 0x89AB, 0xCDEF, {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x01} };
2049  static const KNOWNFOLDERID subFolderId = {0xFEDCBA98, 0x7654, 0x3210, {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF} };
2050  HRESULT hr;
2051  IKnownFolderManager *mgr = NULL;
2052  IKnownFolder *folder = NULL, *subFolder = NULL;
2053  KNOWNFOLDERID folderId, *folders;
2054  KF_CATEGORY cat = 0;
2055  KNOWNFOLDER_DEFINITION kfDefinition, kfSubDefinition;
2056  int csidl, i;
2057  UINT nCount = 0;
2058  LPWSTR folderPath, errorMsg;
2059  KF_REDIRECTION_CAPABILITIES redirectionCapabilities = 1;
2060  WCHAR sWinDir[MAX_PATH], sExamplePath[MAX_PATH], sExample2Path[MAX_PATH], sSubFolderPath[MAX_PATH], sSubFolder2Path[MAX_PATH];
2061  BOOL bRes;
2063 
2064  GetWindowsDirectoryW( sWinDir, MAX_PATH );
2065 
2066  GetTempPathW(ARRAY_SIZE(sExamplePath), sExamplePath);
2067  lstrcatW(sExamplePath, sExample);
2068 
2069  GetTempPathW(ARRAY_SIZE(sExample2Path), sExample2Path);
2070  lstrcatW(sExample2Path, sExample2);
2071 
2072  lstrcpyW(sSubFolderPath, sExamplePath);
2073  lstrcatW(sSubFolderPath, sBackslash);
2074  lstrcatW(sSubFolderPath, sSubFolder);
2075 
2076  lstrcpyW(sSubFolder2Path, sExample2Path);
2077  lstrcatW(sSubFolder2Path, sBackslash);
2078  lstrcatW(sSubFolder2Path, sSubFolder);
2079 
2080  CoInitialize(NULL);
2081 
2082  hr = CoCreateInstance(&CLSID_KnownFolderManager, NULL, CLSCTX_INPROC_SERVER,
2083  &IID_IKnownFolderManager, (LPVOID*)&mgr);
2084  if(hr == REGDB_E_CLASSNOTREG)
2085  win_skip("IKnownFolderManager unavailable\n");
2086  else
2087  {
2088  IUnknown *unk;
2089 
2090  ok(hr == S_OK, "failed to create KnownFolderManager instance: 0x%08x\n", hr);
2091 
2092  hr = IKnownFolderManager_QueryInterface(mgr, &IID_IMarshal, (void**)&unk);
2093  ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
2094 
2095  hr = IKnownFolderManager_FolderIdFromCsidl(mgr, CSIDL_WINDOWS, &folderId);
2096  ok(hr == S_OK, "failed to convert CSIDL to KNOWNFOLDERID: 0x%08x\n", hr);
2097  ok(IsEqualGUID(&folderId, &FOLDERID_Windows)==TRUE, "invalid KNOWNFOLDERID returned\n");
2098 
2099  hr = IKnownFolderManager_FolderIdToCsidl(mgr, &FOLDERID_Windows, &csidl);
2100  ok(hr == S_OK, "failed to convert CSIDL to KNOWNFOLDERID: 0x%08x\n", hr);
2101  ok(csidl == CSIDL_WINDOWS, "invalid CSIDL returned\n");
2102 
2103  hr = IKnownFolderManager_GetFolder(mgr, &FOLDERID_Windows, &folder);
2104  ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
2105  if(SUCCEEDED(hr))
2106  {
2107  hr = IKnownFolder_QueryInterface(folder, &IID_IMarshal, (void**)&unk);
2108  ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
2109 
2110  hr = IKnownFolder_GetCategory(folder, &cat);
2111  ok(hr == S_OK, "failed to get folder category: 0x%08x\n", hr);
2112  ok(cat==KF_CATEGORY_FIXED, "invalid folder category: %d\n", cat);
2113 
2114  hr = IKnownFolder_GetId(folder, &folderId);
2115  ok(hr == S_OK, "failed to get folder id: 0x%08x\n", hr);
2116  ok(IsEqualGUID(&folderId, &FOLDERID_Windows)==TRUE, "invalid KNOWNFOLDERID returned\n");
2117 
2118  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2119  ok(hr == S_OK, "failed to get path from known folder: 0x%08x\n", hr);
2120  ok(lstrcmpiW(sWinDir, folderPath)==0, "invalid path returned: \"%s\", expected: \"%s\"\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sWinDir));
2121  CoTaskMemFree(folderPath);
2122 
2123  hr = IKnownFolder_GetRedirectionCapabilities(folder, &redirectionCapabilities);
2124  ok(hr == S_OK, "failed to get redirection capabilities: 0x%08x\n", hr);
2125  todo_wine
2126  ok(redirectionCapabilities==0, "invalid redirection capabilities returned: %d\n", redirectionCapabilities);
2127 
2128  hr = IKnownFolder_SetPath(folder, 0, sWinDir);
2129  todo_wine
2130  ok(hr == E_INVALIDARG, "unexpected value from SetPath: 0x%08x\n", hr);
2131 
2132  hr = IKnownFolder_GetFolderDefinition(folder, &kfDefinition);
2133  ok(hr == S_OK, "failed to get folder definition: 0x%08x\n", hr);
2134  if(SUCCEEDED(hr))
2135  {
2136  ok(kfDefinition.category==KF_CATEGORY_FIXED, "invalid folder category: 0x%08x\n", kfDefinition.category);
2137  ok(lstrcmpW(kfDefinition.pszName, sWindows)==0, "invalid folder name: %s\n", wine_dbgstr_w(kfDefinition.pszName));
2138  ok(kfDefinition.dwAttributes==0, "invalid folder attributes: %d\n", kfDefinition.dwAttributes);
2139  FreeKnownFolderDefinitionFields(&kfDefinition);
2140  }
2141 
2142  hr = IKnownFolder_Release(folder);
2143  ok(hr == S_OK, "failed to release KnownFolder instance: 0x%08x\n", hr);
2144  }
2145 
2146  hr = IKnownFolderManager_GetFolderByName(mgr, sWindows, &folder);
2147  ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
2148  if(SUCCEEDED(hr))
2149  {
2150  hr = IKnownFolder_GetId(folder, &folderId);
2151  ok(hr == S_OK, "failed to get folder id: 0x%08x\n", hr);
2152  ok(IsEqualGUID(&folderId, &FOLDERID_Windows)==TRUE, "invalid KNOWNFOLDERID returned\n");
2153 
2154  hr = IKnownFolder_Release(folder);
2155  ok(hr == S_OK, "failed to release KnownFolder instance: 0x%08x\n", hr);
2156  }
2157 
2158  hr = IKnownFolderManager_GetFolderByName(mgr, sWindows2, &folder);
2159  ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
2160  if(SUCCEEDED(hr))
2161  {
2162  hr = IKnownFolder_GetId(folder, &folderId);
2163  ok(hr == S_OK, "failed to get folder id: 0x%08x\n", hr);
2164  ok(IsEqualGUID(&folderId, &FOLDERID_Windows)==TRUE, "invalid KNOWNFOLDERID returned\n");
2165 
2166  hr = IKnownFolder_Release(folder);
2167  ok(hr == S_OK, "failed to release KnownFolder instance: 0x%08x\n", hr);
2168  }
2169 
2170  folder = (IKnownFolder *)0xdeadbeef;
2171  hr = IKnownFolderManager_GetFolderByName(mgr, sNoSuch, &folder);
2172  ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
2173  ok(folder == NULL, "got %p\n", folder);
2174 
2175  for(i=0; i < ARRAY_SIZE(known_folder_found); ++i)
2177 
2178  hr = IKnownFolderManager_GetFolderIds(mgr, &folders, &nCount);
2179  ok(hr == S_OK, "failed to get known folders: 0x%08x\n", hr);
2180  for(i=0;i<nCount;++i)
2181  check_known_folder(mgr, &folders[i]);
2182 
2183  for(i=0; i < ARRAY_SIZE(known_folder_found); ++i)
2184  if(!known_folder_found[i])
2185  trace("Known folder %s not found on current platform\n", known_folders[i].sFolderId);
2186 
2187  CoTaskMemFree(folders);
2188 
2189  /* test of registering new known folders */
2190  bRes = CreateDirectoryW(sExamplePath, NULL);
2191  ok(bRes, "cannot create example directory: %s\n", wine_dbgstr_w(sExamplePath));
2192  bRes = CreateDirectoryW(sExample2Path, NULL);
2193  ok(bRes, "cannot create example directory: %s\n", wine_dbgstr_w(sExample2Path));
2194  bRes = CreateDirectoryW(sSubFolderPath, NULL);
2195  ok(bRes, "cannot create example directory: %s\n", wine_dbgstr_w(sSubFolderPath));
2196 
2197  ZeroMemory(&kfDefinition, sizeof(kfDefinition));
2198  kfDefinition.category = KF_CATEGORY_PERUSER;
2199  kfDefinition.pszName = CoTaskMemAlloc(sizeof(sExample));
2200  lstrcpyW(kfDefinition.pszName, sExample);
2201  kfDefinition.pszDescription = CoTaskMemAlloc(sizeof(sExample));
2202  lstrcpyW(kfDefinition.pszDescription, sExample);
2203  kfDefinition.pszRelativePath = CoTaskMemAlloc(sizeof(sExamplePath));
2204  lstrcpyW(kfDefinition.pszRelativePath, sExamplePath);
2205 
2206  hr = IKnownFolderManager_RegisterFolder(mgr, &newFolderId, &kfDefinition);
2208  win_skip("No permissions required to register custom known folder\n");
2209  else
2210  {
2211  ok(hr == S_OK, "failed to register known folder: 0x%08x\n", hr);
2212  if(SUCCEEDED(hr))
2213  {
2214  hr = IKnownFolderManager_GetFolder(mgr, &newFolderId, &folder);
2215  ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
2216  if(SUCCEEDED(hr))
2217  {
2218  hr = IKnownFolder_GetCategory(folder, &cat);
2219  ok(hr == S_OK, "failed to get folder category: hr=0x%0x\n", hr);
2220  ok(cat == KF_CATEGORY_PERUSER, "invalid category returned: %d, while %d (KF_CATEGORY_PERUSER) expected\n", cat, KF_CATEGORY_PERUSER);
2221 
2222  hr = IKnownFolder_GetId(folder, &folderId);
2223  ok(hr == S_OK, "failed to get folder id: 0x%08x\n", hr);
2224  ok(IsEqualGUID(&folderId, &newFolderId)==TRUE, "invalid KNOWNFOLDERID returned\n");
2225 
2226  /* current path should be Temp\Example */
2227  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2228  ok(hr == S_OK, "failed to get path from known folder: 0x%08x\n", hr);
2229  ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
2230  CoTaskMemFree(folderPath);
2231 
2232  /* register sub-folder and mark it as child of Example folder */
2233  ZeroMemory(&kfSubDefinition, sizeof(kfSubDefinition));
2234  kfSubDefinition.category = KF_CATEGORY_PERUSER;
2235  kfSubDefinition.pszName = CoTaskMemAlloc(sizeof(sSubFolder));
2236  lstrcpyW(kfSubDefinition.pszName, sSubFolder);
2237  kfSubDefinition.pszDescription = CoTaskMemAlloc(sizeof(sSubFolder));
2238  lstrcpyW(kfSubDefinition.pszDescription, sSubFolder);
2239  kfSubDefinition.pszRelativePath = CoTaskMemAlloc(sizeof(sSubFolder));
2240  lstrcpyW(kfSubDefinition.pszRelativePath, sSubFolder);
2241  kfSubDefinition.fidParent = newFolderId;
2242 
2243  hr = IKnownFolderManager_RegisterFolder(mgr, &subFolderId, &kfSubDefinition);
2244  ok(hr == S_OK, "failed to register known folder: 0x%08x\n", hr);
2245  if(SUCCEEDED(hr))
2246  {
2247 
2248  hr = IKnownFolderManager_GetFolder(mgr, &subFolderId, &subFolder);
2249  ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
2250  if(SUCCEEDED(hr))
2251  {
2252  /* check sub folder path */
2253  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2254  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2255  ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
2256  CoTaskMemFree(folderPath);
2257 
2258 
2259  /* try to redirect Example to Temp\Example2 */
2260  hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, 0, sExample2Path, 0, NULL, &errorMsg);
2261  ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
2262 
2263  /* verify */
2264  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2265  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2266  ok(lstrcmpiW(folderPath, sExample2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExample2Path));
2267  CoTaskMemFree(folderPath);
2268 
2269  /* verify sub folder - it should fail now, as we redirected its parent folder, but we have no sub folder in new location */
2270  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2271  ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "unexpected value from GetPath(): 0x%08x\n", hr);
2272  ok(folderPath==NULL, "invalid known folder path retrieved: \"%s\" when NULL pointer was expected\n", wine_dbgstr_w(folderPath));
2273  CoTaskMemFree(folderPath);
2274 
2275 
2276  /* set Example path to original. Using SetPath() is valid here, as it also uses redirection internally */
2277  hr = IKnownFolder_SetPath(folder, 0, sExamplePath);
2278  ok(hr == S_OK, "SetPath() failed: 0x%08x\n", hr);
2279 
2280  /* verify */
2281  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2282  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2283  ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
2284  CoTaskMemFree(folderPath);
2285 
2286 
2287  /* create sub folder in Temp\Example2 */
2288  bRes = CreateDirectoryW(sSubFolder2Path, NULL);
2289  ok(bRes, "cannot create example directory: %s\n", wine_dbgstr_w(sSubFolder2Path));
2290 
2291  /* again perform that same redirection */
2292  hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, 0, sExample2Path, 0, NULL, &errorMsg);
2293  ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
2294 
2295  /* verify sub folder. It should succeed now, as the required sub folder exists */
2296  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2297  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2298  ok(lstrcmpiW(folderPath, sSubFolder2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolder2Path));
2299  CoTaskMemFree(folderPath);
2300 
2301  /* remove newly created directory */
2302  RemoveDirectoryW(sSubFolder2Path);
2303 
2304  /* verify subfolder. It still succeeds, so Windows does not check folder presence each time */
2305  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2306  todo_wine
2307  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2308  todo_wine
2309  ok(lstrcmpiW(folderPath, sSubFolder2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolder2Path));
2310  CoTaskMemFree(folderPath);
2311 
2312 
2313  /* set Example path to original */
2314  hr = IKnownFolder_SetPath(folder, 0, sExamplePath);
2315  ok(hr == S_OK, "SetPath() failed: 0x%08x\n", hr);
2316 
2317  /* verify */
2318  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2319  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2320  ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
2321  CoTaskMemFree(folderPath);
2322 
2323  /* verify sub folder */
2324  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2325  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2326  ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
2327  CoTaskMemFree(folderPath);
2328 
2329 
2330  /* create sub folder in Temp\Example2 */
2331  bRes = CreateDirectoryW(sSubFolder2Path, NULL);
2332  ok(bRes, "cannot create example directory: %s\n", wine_dbgstr_w(sSubFolder2Path));
2333 
2334  /* do that same redirection, but try to exclude sub-folder */
2335  hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, 0, sExample2Path, 1, &subFolderId, &errorMsg);
2336  ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
2337 
2338  /* verify */
2339  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2340  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2341  ok(lstrcmpiW(folderPath, sExample2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExample2Path));
2342  CoTaskMemFree(folderPath);
2343 
2344  /* verify sub folder. Unexpectedly, this path was also changed. So, exclusion seems to be ignored (Windows bug)? This test however will let us know, if this behavior is changed */
2345  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2346  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2347  ok(lstrcmpiW(folderPath, sSubFolder2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolder2Path));
2348  CoTaskMemFree(folderPath);
2349 
2350  /* remove newly created directory */
2351  RemoveDirectoryW(sSubFolder2Path);
2352 
2353 
2354  /* set Example path to original */
2355  hr = IKnownFolder_SetPath(folder, 0, sExamplePath);
2356  ok(hr == S_OK, "SetPath() failed: 0x%08x\n", hr);
2357 
2358  /* verify */
2359  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2360  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2361  ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
2362  CoTaskMemFree(folderPath);
2363 
2364  /* verify sub folder */
2365  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2366  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2367  ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
2368  CoTaskMemFree(folderPath);
2369 
2370 
2371  /* do that same redirection again, but set it to copy content. It should also copy the sub folder, so checking it would succeed now */
2372  hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, KF_REDIRECT_COPY_CONTENTS, sExample2Path, 0, NULL, &errorMsg);
2373  ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
2374 
2375  /* verify */
2376  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2377  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2378  ok(lstrcmpiW(folderPath, sExample2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExample2Path));
2379  CoTaskMemFree(folderPath);
2380 
2381  /* verify sub folder */
2382  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2383  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2384  ok(lstrcmpiW(folderPath, sSubFolder2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolder2Path));
2385  CoTaskMemFree(folderPath);
2386 
2387  /* remove copied directory */
2388  RemoveDirectoryW(sSubFolder2Path);
2389 
2390 
2391  /* set Example path to original */
2392  hr = IKnownFolder_SetPath(folder, 0, sExamplePath);
2393  ok(hr == S_OK, "SetPath() failed: 0x%08x\n", hr);
2394 
2395  /* verify */
2396  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2397  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2398  ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
2399  CoTaskMemFree(folderPath);
2400 
2401  /* verify sub folder */
2402  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2403  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2404  ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
2405  CoTaskMemFree(folderPath);
2406 
2407 
2408  /* redirect again, set it to copy content and remove originals */
2409  hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, KF_REDIRECT_COPY_CONTENTS | KF_REDIRECT_DEL_SOURCE_CONTENTS, sExample2Path, 0, NULL, &errorMsg);
2410  ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
2411 
2412  /* verify */
2413  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2414  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2415  ok(lstrcmpiW(folderPath, sExample2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExample2Path));
2416  CoTaskMemFree(folderPath);
2417 
2418  /* verify sub folder */
2419  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2420  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2421  ok(lstrcmpiW(folderPath, sSubFolder2Path)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolder2Path));
2422  CoTaskMemFree(folderPath);
2423 
2424  /* check if original directory was really removed */
2425  dwAttributes = GetFileAttributesW(sExamplePath);
2426  ok(dwAttributes==INVALID_FILE_ATTRIBUTES, "directory should not exist, but has attributes: 0x%08x\n", dwAttributes );
2427 
2428 
2429  /* redirect (with copy) to original path */
2430  hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, KF_REDIRECT_COPY_CONTENTS, sExamplePath, 0, NULL, &errorMsg);
2431  ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
2432 
2433  /* verify */
2434  hr = IKnownFolder_GetPath(folder, 0, &folderPath);
2435  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2436  ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
2437  CoTaskMemFree(folderPath);
2438 
2439  /* verify sub folder */
2440  hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
2441  ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
2442  ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
2443  CoTaskMemFree(folderPath);
2444 
2445  /* check shell utility functions */
2446  if(!pSHGetKnownFolderPath || !pSHSetKnownFolderPath)
2447  todo_wine
2448  win_skip("cannot get SHGet/SetKnownFolderPath routines\n");
2449  else
2450  {
2451  /* try to get current known folder path */
2452  hr = pSHGetKnownFolderPath(&newFolderId, 0, NULL, &folderPath);
2453  todo_wine
2454  ok(hr==S_OK, "cannot get known folder path: hr=0x%0x\n", hr);
2455  todo_wine
2456  ok(lstrcmpW(folderPath, sExamplePath)==0, "invalid path returned: %s\n", wine_dbgstr_w(folderPath));
2457 
2458  /* set it to new value */
2459  hr = pSHSetKnownFolderPath(&newFolderId, 0, NULL, sExample2Path);
2460  todo_wine
2461  ok(hr==S_OK, "cannot set known folder path: hr=0x%0x\n", hr);
2462 
2463  /* check if it changed */
2464  hr = pSHGetKnownFolderPath(&newFolderId, 0, NULL, &folderPath);
2465  todo_wine
2466  ok(hr==S_OK, "cannot get known folder path: hr=0x%0x\n", hr);
2467  todo_wine
2468  ok(lstrcmpW(folderPath, sExample2Path)==0, "invalid path returned: %s\n", wine_dbgstr_w(folderPath));
2469 
2470  /* set it back */
2471  hr = pSHSetKnownFolderPath(&newFolderId, 0, NULL, sExamplePath);
2472  todo_wine
2473  ok(hr==S_OK, "cannot set known folder path: hr=0x%0x\n", hr);
2474  }
2475 
2476  IKnownFolder_Release(subFolder);
2477  }
2478 
2479  hr = IKnownFolderManager_UnregisterFolder(mgr, &subFolderId);
2480  ok(hr == S_OK, "failed to unregister folder: 0x%08x\n", hr);
2481  }
2482 
2483  FreeKnownFolderDefinitionFields(&kfSubDefinition);
2484 
2485  hr = IKnownFolder_Release(folder);
2486  ok(hr == S_OK, "failed to release KnownFolder instance: 0x%08x\n", hr);
2487 
2488  /* update the folder */
2489  CoTaskMemFree(kfDefinition.pszName);
2490  kfDefinition.pszName = CoTaskMemAlloc(sizeof(sExample2));
2491  lstrcpyW(kfDefinition.pszName, sExample2);
2492  hr = IKnownFolderManager_RegisterFolder(mgr, &newFolderId, &kfDefinition);
2493  ok(hr == S_OK, "failed to re-register known folder: 0x%08x\n", hr);
2494 
2495  hr = IKnownFolderManager_GetFolder(mgr, &newFolderId, &folder);
2496  ok(hr == S_OK, "failed to get known folder: 0x%08x\n", hr);
2497 
2498  hr = IKnownFolder_GetFolderDefinition(folder, &kfSubDefinition);
2499  ok(hr == S_OK, "failed to get folder definition: 0x%08x\n", hr);
2500  ok(!memcmp(kfDefinition.pszName, kfSubDefinition.pszName, sizeof(sExample2)),
2501  "Got wrong updated name: %s\n", wine_dbgstr_w(kfSubDefinition.pszName));
2502 
2503  FreeKnownFolderDefinitionFields(&kfSubDefinition);
2504 
2505  hr = IKnownFolder_Release(folder);
2506  ok(hr == S_OK, "failed to release KnownFolder instance: 0x%08x\n", hr);
2507  }
2508 
2509  hr = IKnownFolderManager_UnregisterFolder(mgr, &newFolderId);
2510  ok(hr == S_OK, "failed to unregister folder: 0x%08x\n", hr);
2511  }
2512  }
2513  FreeKnownFolderDefinitionFields(&kfDefinition);
2514 
2515  RemoveDirectoryW(sSubFolder2Path);
2516  RemoveDirectoryW(sSubFolderPath);
2517  RemoveDirectoryW(sExamplePath);
2518  RemoveDirectoryW(sExample2Path);
2519 
2520  hr = IKnownFolderManager_Release(mgr);
2521  ok(hr == S_OK, "failed to release KnownFolderManager instance: 0x%08x\n", hr);
2522  }
2523  CoUninitialize();
2524 }
2525 
2526 
2527 static void test_DoEnvironmentSubst(void)
2528 {
2529  WCHAR expectedW[MAX_PATH];
2530  WCHAR bufferW[MAX_PATH];
2531  CHAR expectedA[MAX_PATH];
2532  CHAR bufferA[MAX_PATH];
2533  DWORD res;
2534  DWORD res2;
2535  DWORD len;
2536  INT i;
2537  static const WCHAR does_not_existW[] = {'%','D','O','E','S','_','N','O','T','_','E','X','I','S','T','%',0};
2538  static const CHAR does_not_existA[] = "%DOES_NOT_EXIST%";
2539  static const CHAR *names[] = {
2540  /* interactive apps and services (works on all windows versions) */
2541  "%ALLUSERSPROFILE%", "%APPDATA%", "%LOCALAPPDATA%",
2542  "%NUMBER_OF_PROCESSORS%", "%OS%", "%PROCESSOR_ARCHITECTURE%",
2543  "%PROCESSOR_IDENTIFIER%", "%PROCESSOR_LEVEL%", "%PROCESSOR_REVISION%",
2544  "%ProgramFiles%", "%SystemDrive%",
2545  "%SystemRoot%", "%USERPROFILE%", "%windir%",
2546  /* todo_wine: "%COMPUTERNAME%", "%ProgramData%", "%PUBLIC%", */
2547 
2548  /* replace more than one var is allowed */
2549  "%HOMEDRIVE%%HOMEPATH%",
2550  "%OS% %windir%"}; /* always the last entry in the table */
2551 
2552  for (i = 0; i < (sizeof(names)/sizeof(LPSTR)); i++)
2553  {
2554  memset(bufferA, '#', MAX_PATH - 1);
2555  bufferA[MAX_PATH - 1] = 0;
2556  lstrcpyA(bufferA, names[i]);
2557  MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
2558 
2559  res2 = ExpandEnvironmentStringsA(names[i], expectedA, MAX_PATH);
2560  res = DoEnvironmentSubstA(bufferA, MAX_PATH);
2561 
2562  /* is the space for the terminating 0 included? */
2563  if (!i && HIWORD(res) && (LOWORD(res) == (lstrlenA(bufferA))))
2564  {
2565  win_skip("DoEnvironmentSubstA/W are broken on NT 4\n");
2566  return;
2567  }
2568  ok(HIWORD(res) && (LOWORD(res) == res2),
2569  "%d: got %d/%d (expected TRUE/%d)\n", i, HIWORD(res), LOWORD(res), res2);
2570  ok(!lstrcmpA(bufferA, expectedA),
2571  "%d: got %s (expected %s)\n", i, bufferA, expectedA);
2572 
2573  res2 = ExpandEnvironmentStringsW(bufferW, expectedW, MAX_PATH);
2574  res = DoEnvironmentSubstW(bufferW, MAX_PATH);
2575  ok(HIWORD(res) && (LOWORD(res) == res2),
2576  "%d: got %d/%d (expected TRUE/%d)\n", i, HIWORD(res), LOWORD(res), res2);
2577  ok(!lstrcmpW(bufferW, expectedW),
2578  "%d: got %s (expected %s)\n", i, wine_dbgstr_w(bufferW), wine_dbgstr_w(expectedW));
2579  }
2580 
2581  i--; /* reuse data in the last table entry */
2582  len = LOWORD(res); /* needed length */
2583 
2584  /* one character extra is fine */
2585  memset(bufferA, '#', MAX_PATH - 1);
2586  bufferA[len + 2] = 0;
2587  lstrcpyA(bufferA, names[i]);
2588  MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
2589 
2590  res2 = ExpandEnvironmentStringsA(bufferA, expectedA, MAX_PATH);
2591  res = DoEnvironmentSubstA(bufferA, len + 1);
2592  ok(HIWORD(res) && (LOWORD(res) == res2),
2593  "+1: got %d/%d (expected TRUE/%d)\n", HIWORD(res), LOWORD(res), res2);
2594  ok(!lstrcmpA(bufferA, expectedA),
2595  "+1: got %s (expected %s)\n", bufferA, expectedA);
2596 
2597  res2 = ExpandEnvironmentStringsW(bufferW, expectedW, MAX_PATH);
2598  res = DoEnvironmentSubstW(bufferW, len + 1);
2599  ok(HIWORD(res) && (LOWORD(res) == res2),
2600  "+1: got %d/%d (expected TRUE/%d)\n", HIWORD(res), LOWORD(res), res2);
2601  ok(!lstrcmpW(bufferW, expectedW),
2602  "+1: got %s (expected %s)\n", wine_dbgstr_w(bufferW), wine_dbgstr_w(expectedW));
2603 
2604 
2605  /* minimal buffer length (result string and terminating 0) */
2606  memset(bufferA, '#', MAX_PATH - 1);
2607  bufferA[len + 2] = 0;
2608  lstrcpyA(bufferA, names[i]);
2609  MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
2610 
2611  /* ANSI version failed without an extra byte, as documented on msdn */
2612  res = DoEnvironmentSubstA(bufferA, len);
2613  ok(!HIWORD(res) && (LOWORD(res) == len),
2614  " 0: got %d/%d (expected FALSE/%d)\n", HIWORD(res), LOWORD(res), len);
2615  ok(!lstrcmpA(bufferA, names[i]),
2616  " 0: got %s (expected %s)\n", bufferA, names[i]);
2617 
2618  /* DoEnvironmentSubstW works as expected */
2619  res2 = ExpandEnvironmentStringsW(bufferW, expectedW, MAX_PATH);
2620  res = DoEnvironmentSubstW(bufferW, len);
2621  ok(HIWORD(res) && (LOWORD(res) == res2),
2622  " 0: got %d/%d (expected TRUE/%d)\n", HIWORD(res), LOWORD(res), res2);
2623  ok(!lstrcmpW(bufferW, expectedW),
2624  " 0: got %s (expected %s)\n", wine_dbgstr_w(bufferW), wine_dbgstr_w(expectedW));
2625 
2626 
2627  /* Buffer too small */
2628  /* result: FALSE / provided buffer length / the buffer is untouched */
2629  memset(bufferA, '#', MAX_PATH - 1);
2630  bufferA[len + 2] = 0;
2631  lstrcpyA(bufferA, names[i]);
2632  MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
2633 
2634  res = DoEnvironmentSubstA(bufferA, len - 1);
2635  ok(!HIWORD(res) && (LOWORD(res) == (len - 1)),
2636  "-1: got %d/%d (expected FALSE/%d)\n", HIWORD(res), LOWORD(res), len - 1);
2637  ok(!lstrcmpA(bufferA, names[i]),
2638  "-1: got %s (expected %s)\n", bufferA, names[i]);
2639 
2640  lstrcpyW(expectedW, bufferW);
2641  res = DoEnvironmentSubstW(bufferW, len - 1);
2642  ok(!HIWORD(res) && (LOWORD(res) == (len - 1)),
2643  "-1: got %d/%d (expected FALSE/%d)\n", HIWORD(res), LOWORD(res), len - 1);
2644  ok(!lstrcmpW(bufferW, expectedW),
2645  "-1: got %s (expected %s)\n", wine_dbgstr_w(bufferW), wine_dbgstr_w(expectedW));
2646 
2647 
2648  /* unknown variable */
2649  /* result: TRUE / string length including terminating 0 / the buffer is untouched */
2650  memset(bufferA, '#', MAX_PATH - 1);
2651  bufferA[MAX_PATH - 1] = 0;
2652  lstrcpyA(bufferA, does_not_existA);
2653  MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
2654 
2655  res2 = lstrlenA(does_not_existA) + 1;
2656  res = DoEnvironmentSubstA(bufferA, MAX_PATH);
2657  ok(HIWORD(res) && (LOWORD(res) == res2),
2658  "%d: got %d/%d (expected TRUE/%d)\n", i, HIWORD(res), LOWORD(res), res2);
2659  ok(!lstrcmpA(bufferA, does_not_existA),
2660  "%d: got %s (expected %s)\n", i, bufferA, does_not_existA);
2661 
2662  res = DoEnvironmentSubstW(bufferW, MAX_PATH);
2663  ok(HIWORD(res) && (LOWORD(res) == res2),
2664  "%d: got %d/%d (expected TRUE/%d)\n", i, HIWORD(res), LOWORD(res), res2);
2665  ok(!lstrcmpW(bufferW, does_not_existW),
2666  "%d: got %s (expected %s)\n", i, wine_dbgstr_w(bufferW), wine_dbgstr_w(does_not_existW));
2667 
2668 
2669  if (0)
2670  {
2671  /* NULL crashes on windows */
2674  }
2675 }
2676 
2678 {
2679  static const WCHAR shortW[] = {'f','i','l','e','.','t','s','t',0};
2680  static const WCHAR short2W[] = {'f','i','l','e',' ','(','2',')','.','t','s','t',0};
2681  static const WCHAR tmpW[] = {'t','m','p',0};
2682  static const WCHAR longW[] = {'n','a','m','e',0};
2683  static const WCHAR long2W[] = {'n','a','m','e',' ','(','2',')',0};
2684  WCHAR nameW[MAX_PATH], buffW[MAX_PATH], pathW[MAX_PATH];
2685  HANDLE file;
2686  BOOL ret;
2687 
2688  if (!pPathYetAnotherMakeUniqueName)
2689  {
2690  win_skip("PathYetAnotherMakeUniqueName() is not available.\n");
2691  return;
2692  }
2693 
2694 if (0)
2695 {
2696  /* crashes on Windows */
2697  ret = pPathYetAnotherMakeUniqueName(NULL, NULL, NULL, NULL);
2698  ok(!ret, "got %d\n", ret);
2699 
2700  ret = pPathYetAnotherMakeUniqueName(nameW, NULL, NULL, NULL);
2701  ok(!ret, "got %d\n", ret);
2702 }
2703 
2704  GetTempPathW(ARRAY_SIZE(pathW), pathW);
2705 
2706  /* Using short name only first */
2707  nameW[0] = 0;
2708  ret = pPathYetAnotherMakeUniqueName(nameW, pathW, shortW, NULL);
2709  ok(ret, "got %d\n", ret);
2710  lstrcpyW(buffW, pathW);
2711  lstrcatW(buffW, shortW);
2712  ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
2713 
2714  /* now create a file with this name and get next name */
2716  ok(file != NULL, "got %p\n", file);
2717 
2718  nameW[0] = 0;
2719  ret = pPathYetAnotherMakeUniqueName(nameW, pathW, shortW, NULL);
2720  ok(ret, "got %d\n", ret);
2721  lstrcpyW(buffW, pathW);
2722  lstrcatW(buffW, short2W);
2723  ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
2724 
2725  CloseHandle(file);
2726 
2727  /* Using short and long */
2728  nameW[0] = 0;
2729  ret = pPathYetAnotherMakeUniqueName(nameW, pathW, tmpW, longW);
2730  ok(ret, "got %d\n", ret);
2731  lstrcpyW(buffW, pathW);
2732  lstrcatW(buffW, longW);
2733  ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
2734 
2736  ok(file != NULL, "got %p\n", file);
2737 
2738  nameW[0] = 0;
2739  ret = pPathYetAnotherMakeUniqueName(nameW, pathW, tmpW, longW);
2740  ok(ret, "got %d\n", ret);
2741  lstrcpyW(buffW, pathW);
2742  lstrcatW(buffW, long2W);
2743  ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
2744 
2745  CloseHandle(file);
2746 
2747  /* Using long only */
2748  nameW[0] = 0;
2749  ret = pPathYetAnotherMakeUniqueName(nameW, pathW, NULL, longW);
2750  ok(ret, "got %d\n", ret);
2751  lstrcpyW(buffW, pathW);
2752  lstrcatW(buffW, longW);
2753  ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
2754 }
2755 
2757 {
2758  PIDLIST_ABSOLUTE pidl;
2759  HRESULT hr;
2760 
2761  if (!pSHGetKnownFolderIDList)
2762  {
2763  win_skip("SHGetKnownFolderIDList is not available.\n");
2764  return;
2765  }
2766 
2767  hr = pSHGetKnownFolderIDList(NULL, 0, NULL, NULL);
2768  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2769 
2770 if (0) { /* crashes on native */
2771  pidl = (void*)0xdeadbeef;
2772  hr = pSHGetKnownFolderIDList(NULL, 0, NULL, &pidl);
2773 }
2774  /* not a known folder */
2775  pidl = (void*)0xdeadbeef;
2776  hr = pSHGetKnownFolderIDList(&IID_IUnknown, 0, NULL, &pidl);
2777  ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
2778  ok(pidl == NULL, "got %p\n", pidl);
2779 
2780  hr = pSHGetKnownFolderIDList(&FOLDERID_Desktop, 0, NULL, NULL);
2781  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2782 
2783  pidl = (void*)0xdeadbeef;
2784  hr = pSHGetKnownFolderIDList(&FOLDERID_Desktop, 0, NULL, &pidl);
2785  ok(hr == S_OK, "SHGetKnownFolderIDList failed: 0x%08x\n", hr);
2786  ok(ILIsEmpty(pidl), "pidl should be empty.\n");
2787  ok(pidl->mkid.cb == 0, "get wrong value: %d\n", pidl->mkid.cb);
2788  ILFree(pidl);
2789 
2790  pidl = (void*)0xdeadbeef;
2791  hr = pSHGetKnownFolderIDList(&FOLDERID_Desktop, KF_FLAG_NO_ALIAS, NULL, &pidl);
2792  ok(hr == S_OK, "SHGetKnownFolderIDList failed: 0x%08x\n", hr);
2793  todo_wine ok(!ILIsEmpty(pidl), "pidl should not be empty.\n");
2794  todo_wine ok(pidl->mkid.cb == 20, "get wrong value: %d\n", pidl->mkid.cb);
2795  ILFree(pidl);
2796 
2797  pidl = (void*)0xdeadbeef;
2798  hr = pSHGetKnownFolderIDList(&FOLDERID_Documents, 0, NULL, &pidl);
2799  ok(hr == S_OK, "SHGetKnownFolderIDList failed: 0x%08x\n", hr);
2800  ok(!ILIsEmpty(pidl), "pidl should not be empty.\n");
2801  ok(pidl->mkid.cb == 20, "get wrong value: %d\n", pidl->mkid.cb);
2802  ILFree(pidl);
2803 
2804  pidl = (void*)0xdeadbeef;
2805  hr = pSHGetKnownFolderIDList(&FOLDERID_Documents, KF_FLAG_NO_ALIAS, NULL, &pidl);
2806  ok(hr == S_OK, "SHGetKnownFolderIDList failed: 0x%08x\n", hr);
2807  ok(!ILIsEmpty(pidl), "pidl should not be empty.\n");
2808  ok(pidl->mkid.cb == 20, "get wrong value: %d\n", pidl->mkid.cb);
2809  ILFree(pidl);
2810 }
2811 
2812 START_TEST(shellpath)
2813 {
2814  if (!init()) return;
2815 
2816  loadShell32();
2817  pGetSystemWow64DirectoryA = (void *)GetProcAddress( GetModuleHandleA("kernel32.dll"),
2818  "GetSystemWow64DirectoryA" );
2819  if (myARGC >= 3)
2820  doChild(myARGV[2]);
2821  else
2822  {
2823  /* Report missing functions once */
2824  if (!pSHGetFolderLocation)
2825  win_skip("SHGetFolderLocation is not available\n");
2826 
2827  /* first test various combinations of parameters: */
2828  test_parameters();
2829 
2830  /* check known values: */
2831  test_PidlTypes();
2832  test_GUIDs();
2833  test_EnvVars();
2834  testWinDir();
2835  testSystemDir();
2842  }
2843 }
static void test_PidlTypes(void)
Definition: shellpath.c:561
static int myARGC
Definition: shellpath.c:678
static void check_known_folder(IKnownFolderManager *mgr, KNOWNFOLDERID *folderId)
Definition: shellpath.c:1933
#define PT_DRIVE
Definition: shellpath.c:58
static char ** myARGV
Definition: shellpath.c:679
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
static BYTE testSHGetFolderLocation(int folder)
Definition: shellpath.c:374
static void test_SHGetKnownFolderIDList(void)
Definition: shellpath.c:2756
struct _SHFILEOPSTRUCTA * LPSHFILEOPSTRUCTA
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4041
#define CSIDL_COOKIES
Definition: shlobj.h:2020
#define trace(...)
Definition: kmt_test.h:217
#define PT_FOLDER
Definition: shellpath.c:67
static void doChild(const char *arg)
Definition: shellpath.c:691
KF_DEFINITION_FLAGS kfdFlags
Definition: shobjidl.idl:3906
#define KNOWN_FOLDER(id, csidl, name, category, parent1, parent2, relative_path, parsing_name, attributes, definitionFlags)
Definition: shellpath.c:899
#define TRUE
Definition: types.h:120
static const GUID _FOLDERID_CredentialManager
Definition: shellpath.c:906
#define CloseHandle
Definition: compat.h:398
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:925
#define E_NOINTERFACE
Definition: winerror.h:2364
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
Definition: fci.c:115
static const struct shellExpectedValues optionalShellValues[]
Definition: shellpath.c:146
const char * sCsidl
Definition: shellpath.c:912
#define E_HANDLE
Definition: winerror.h:2850
KNOWNFOLDERID * REFKNOWNFOLDERID
Definition: shtypes.idl:147
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:422
int WINAPI lstrcmpiA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:42
#define CSIDL_MYVIDEO
Definition: shlobj.h:2002
static void test_ShellValues(const struct shellExpectedValues testEntries[], int numEntries, BOOL optional)
Definition: shellpath.c:456
static const BYTE folderOrSpecialType[]
Definition: shellpath.c:113
#define CSIDL_COMMON_DESKTOPDIRECTORY
Definition: shlobj.h:2012
#define CSIDL_MYPICTURES
Definition: shlobj.h:2026
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
interface IMalloc * LPMALLOC
Definition: objfwd.h:12
#define CSIDL_DESKTOP
Definition: shlobj.h:1988
#define CSIDL_COMMON_FAVORITES
Definition: shlobj.h:2018
__wchar_t WCHAR
Definition: xmlstorage.h:180
GLsizei const GLchar ** path
Definition: glext.h:7234
START_TEST(shellpath)
Definition: shellpath.c:2812
uint16_t * PWSTR
Definition: typedefs.h:54
#define CP_ACP
Definition: compat.h:99
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
#define HKEY_CURRENT_USER
Definition: winreg.h:11
char CHAR
Definition: xmlstorage.h:175
static const BYTE favoritesType[]
Definition: shellpath.c:112
const DWORD attributes
Definition: shellpath.c:918
static void test_GUIDs(void)
Definition: shellpath.c:576
#define PT_YAGUID
Definition: shellpath.c:76
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
BOOL known_folder_found[ARRAY_SIZE(known_folders) -1]
Definition: shellpath.c:1901
#define CSIDL_COMMON_STARTUP
Definition: shlobj.h:2011
UINT WINAPI GetSystemDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2282
HANDLE HWND
Definition: compat.h:13
HRESULT WINAPI SHGetMalloc(LPMALLOC *lpmal)
Definition: shellole.c:290
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3346
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define PT_SHELLEXT
Definition: shellpath.c:64
const char * wine_dbgstr_guid(const GUID *guid)
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1635
GLuint buffer
Definition: glext.h:5915
int startup(int argc, const char *argv[])
Definition: startup.c:430
#define PT_WORKGRP
Definition: shellpath.c:73
#define CSIDL_BITBUCKET
Definition: shlobj.h:1998
#define PT_CPL
Definition: shellpath.c:52
#define CSIDL_HISTORY
Definition: shlobj.h:2021
#define CSIDL_PROGRAM_FILES
Definition: shlobj.h:2025
#define CSIDL_COMMON_PICTURES
Definition: shlobj.h:2038
int winetest_interactive
DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
#define CSIDL_PROFILE
Definition: shlobj.h:2027
static LPSTR
Definition: shellpath.c:92
#define CSIDL_COMMON_OEM_LINKS
Definition: shlobj.h:2042
LONG WINAPI RegFlushKey(HKEY hKey)
Definition: reg.c:2988
char * LPSTR
Definition: xmlstorage.h:182
#define CSIDL_FONTS
Definition: shlobj.h:2007
#define lstrlenW
Definition: compat.h:407
#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
Definition: ntifs_ex.h:384
#define E_FAIL
Definition: ddrawi.h:102
static void test_knownFolders(void)
Definition: shellpath.c:2039
int32_t INT
Definition: typedefs.h:56
#define CSIDL_INTERNET_CACHE
Definition: shlobj.h:2019
WORD cb
Definition: shtypes.idl:27
DWORD dwAttributes
Definition: vdmdbg.h:34
#define CSIDL_COMMON_TEMPLATES
Definition: shlobj.h:2032
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2351
#define CSIDL_CONTROLS
Definition: shlobj.h:1991
#define CSIDL_PROGRAM_FILESX86
Definition: shlobj.h:2029
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
#define CSIDL_COMMON_PROGRAMS
Definition: shlobj.h:2010
struct _test_info info[]
Definition: SetCursorPos.c:19
#define CSIDL_MYDOCUMENTS
Definition: shlobj.h:2000
static void test_SHGetSpecialFolderPath(BOOL optional, int folder)
Definition: shellpath.c:441
#define CSIDL_RECENT
Definition: shlobj.h:1996
#define sprintf(buf, format,...)
Definition: sprintf.c:55
GLuint GLuint * names
Definition: glext.h:11545
static void test_DoEnvironmentSubst(void)
Definition: shellpath.c:2527
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
static BOOL is_in_strarray(const WCHAR *needle, const char *hay)
Definition: shellpath.c:1903
static void test_SHGetFolderPath(BOOL optional, int folder)
Definition: shellpath.c:429
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 const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
STDAPI DllGetVersion(DLLVERSIONINFO *info)
Definition: browseui.cpp:207
#define CSIDL_CONNECTIONS
Definition: shlobj.h:2036
BOOL WINAPI SHGetSpecialFolderPathA(HWND hwndOwner, LPSTR szPath, int nFolder, BOOL bCreate)
Definition: shellpath.c:2553
#define CSIDL_PRINTERS
Definition: shlobj.h:1992
const GUID * guid
#define CSIDL_DRIVES
Definition: shlobj.h:2004
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
static void test_PathYetAnotherMakeUniqueName(void)
Definition: shellpath.c:2677
#define DECLARE_TYPE(x, y)
Definition: shellpath.c:121
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2079
#define CSIDL_FAVORITES
Definition: shlobj.h:1994
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
const int line
Definition: shellpath.c:920
static const BYTE ieSpecialType[]
Definition: shellpath.c:118
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:802
#define GENERIC_WRITE
Definition: nt_native.h:90
static BYTE testSHGetSpecialFolderLocation(int folder)
Definition: shellpath.c:402
#define OLD_CSIDL_MYDOCUMENTS
Definition: shellpath.c:42
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: CString.cpp:62
static GUID CLSID_CommonDocuments
Definition: shellpath.c:83
enum tagKF_DEFINITION_FLAGS KF_DEFINITION_FLAGS
#define E_INVALIDARG
Definition: ddrawi.h:101
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
smooth NULL
Definition: ftsmooth.c:416
#define PT_DRIVE2
Definition: shellpath.c:61
static const BYTE guidType[]
Definition: shellpath.c:109
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
Definition: pidl.c:189
DWORD WINAPI ExpandEnvironmentStringsA(IN LPCSTR lpSrc, IN LPSTR lpDst, IN DWORD nSize)
Definition: environ.c:399
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
const BYTE * types
Definition: shellpath.c:88
BOOL WINAPI SetFileAttributesA(LPCSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:926
#define CSIDL_COMMON_STARTMENU
Definition: shlobj.h:2009
static const BYTE personalType[]
Definition: shellpath.c:114
#define CSIDL_WINDOWS
Definition: shlobj.h:2023
#define CSIDL_CDBURN_AREA
Definition: shlobj.h:2043
const char * LPCSTR
Definition: xmlstorage.h:183
#define STARTF_USESHOWWINDOW
Definition: winbase.h:472
struct CFFOLDER folder
Definition: fdi.c:110
const KF_DEFINITION_FLAGS definitionFlags
Definition: shellpath.c:919
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define CSIDL_PROFILES
Definition: shellpath.c:235
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
const char * sName
Definition: shellpath.c:913
static LPWSTR
Definition: shellpath.c:103
static const struct shellExpectedValues requiredShellValues[]
Definition: shellpath.c:122
Definition: msg.h:41
static const BYTE workgroupType[]
Definition: shellpath.c:120
static void test_parameters(void)
Definition: shellpath.c:311
const GUID IID_IOleObject
static UINT
Definition: shellpath.c:100
const char * sParsingName
Definition: shellpath.c:917
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 const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define ok(value,...)
Definition: CComObject.cpp:34
static const WCHAR nameW[]
Definition: main.c:46
static const BYTE shellExtType[]
Definition: shellpath.c:119
#define CSIDL_COMMON_ALTSTARTUP
Definition: shlobj.h:2017
#define CSIDL_COMMON_ADMINTOOLS
Definition: shlobj.h:2034
static void loadShell32(void)
Definition: shellpath.c:190
unsigned int BOOL
Definition: ntddk_ex.h:94
#define WAIT_OBJECT_0
Definition: winbase.h:387
DWORD WINAPI DoEnvironmentSubstW(LPWSTR pszString, UINT cchString)
Definition: shellord.c:1539
#define PT_GUID
Definition: shellpath.c:55
Definition: cmds.c:130
#define CSIDL_ADMINTOOLS
Definition: shlobj.h:2035
#define PT_IESPECIAL2
Definition: shellpath.c:80
HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST *ppidl)
Definition: shellpath.c:2687
LONG HRESULT
Definition: typedefs.h:77
static LPITEMIDLIST *static BOOL
Definition: shellpath.c:95
const GUID IID_IUnknown
#define CSIDL_LOCAL_APPDATA
Definition: shlobj.h:2015
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4772
#define CSIDL_SENDTO
Definition: shlobj.h:1997
#define CSIDL_APPDATA
Definition: shlobj.h:2013
#define MAX_PATH
Definition: compat.h:26
const char file[]
Definition: icontest.c:11
unsigned int UINT
Definition: ndis.h:50
static PCWSTR
Definition: shellpath.c:104
#define FILE_FLAG_DELETE_ON_CLOSE
Definition: disk.h:42
static const GUID _FOLDERID_SystemCertificates
Definition: shellpath.c:905
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define GET_PROC(func)
static const BYTE folderType[]
Definition: shellpath.c:111
unsigned long DWORD
Definition: ntddk_ex.h:95
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
Definition: id3.c:18
static const GUID _FOLDERID_DpapiKeys
Definition: shellpath.c:904
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
int winetest_get_mainargs(char ***pargv)
#define CSIDL_COMMON_VIDEO
Definition: shlobj.h:2039
const int csidl
Definition: shellpath.c:911
DWORD WINAPI DoEnvironmentSubstA(LPSTR pszString, UINT cchString)
Definition: shellord.c:1494
static HANDLE
Definition: shellpath.c:92
static const BYTE printersType[]
Definition: shellpath.c:117
int ret
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
static const WCHAR L[]
Definition: oid.c:1087
#define todo_wine
Definition: test.h:154
#define CSIDL_RESOURCES_LOCALIZED
Definition: shlobj.h:2041
#define CSIDL_COMMON_APPDATA
Definition: shlobj.h:2022
static const GUID _FOLDERID_CryptoKeys
Definition: shellpath.c:903
static const char * getFolderName(int folder)
Definition: shellpath.c:239
HKEY key
Definition: reg.c:42
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:819
unsigned char BYTE
Definition: mem.h:68
#define GUID_NULL
Definition: ks.h:106
#define NO_CSIDL
Definition: shellpath.c:897
static const WCHAR shortW[]
Definition: tokenize.c:73
static LPMALLOC pMalloc
Definition: shellpath.c:108
#define E_NOT_SUFFICIENT_BUFFER
Definition: winerror.h:2345
#define WINAPI
Definition: msvc.h:20
LPSTR WINAPI CharPrevA(_In_ LPCSTR, _In_ LPCSTR)
#define broken(x)
Definition: _sntprintf.h:21
#define CSIDL_PROGRAM_FILES_COMMONX86
Definition: shlobj.h:2031
#define CSIDL_STARTUP
Definition: shlobj.h:1995
void winetest_wait_child_process(HANDLE process)
#define CSIDL_PROGRAM_FILES_COMMON
Definition: shlobj.h:2030
#define CSIDL_COMMON_MUSIC
Definition: shlobj.h:2037
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3237
const KF_CATEGORY category
Definition: shellpath.c:914
const KNOWNFOLDERID * fidParents[2]
Definition: shellpath.c:915
#define CSIDL_TO_STR(x)
#define S_OK
Definition: intsafe.h:59
#define CREATE_ALWAYS
Definition: disk.h:72
#define CSIDL_RESOURCES
Definition: shlobj.h:2040
#define SW_SHOWNORMAL
Definition: winuser.h:764
#define REGDB_E_CLASSNOTREG
Definition: winerror.h:2696
#define ARRAY_SIZE(x)
Definition: shellpath.c:47
static WCHAR does_not_existW[]
Definition: localmon.c:78
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define lstrcpyW
Definition: compat.h:406
static void testWinDir(void)
Definition: shellpath.c:628
static BOOL init(void)
Definition: shellpath.c:683
const char * sFolderId
Definition: shellpath.c:910
HRESULT WINAPI SHGetFolderPathA(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPSTR pszPath)
Definition: shellpath.c:2326
static char selfname[MAX_PATH]
Definition: shellpath.c:681
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:1994
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define CSIDL_PRINTHOOD
Definition: shlobj.h:2014
static void matchGUID(int folder, const GUID *guid, const GUID *guid_alt)
Definition: shellpath.c:527
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2145
#define skip(...)
Definition: CString.cpp:57
Definition: services.c:325
UINT WINAPI GetWindowsDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2336
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
#define PT_FOLDERW
Definition: shellpath.c:70
#define CSIDL_COMMON_DOCUMENTS
Definition: shlobj.h:2033
static PWSTR *static PWSTR
Definition: shellpath.c:102
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4024
#define CSIDL_FLAG_CREATE
#define CSIDL_INTERNET
Definition: shlobj.h:1989
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
#define MultiByteToWideChar
Definition: compat.h:100
#define CreateFileW
Definition: compat.h:400
#define CSIDL_NETHOOD
Definition: shlobj.h:2006
int WINAPI SHFileOperationA(LPSHFILEOPSTRUCTA lpFileOp)
Definition: shlfileop.cpp:999
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1900
#define CSIDL_PERSONAL
Definition: shlobj.h:1993
static int
Definition: shellpath.c:92
static BOOL myPathIsRootA(LPCSTR lpszPath)
Definition: shellpath.c:604
#define CSIDL_STARTMENU
Definition: shlobj.h:1999
static const BYTE controlPanelType[]
Definition: shellpath.c:110
#define CSIDL_ALTSTARTUP
Definition: shlobj.h:2016
GLuint res
Definition: glext.h:9613
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define CSIDL_COMPUTERSNEARME
Definition: shlobj.h:2044
#define HIWORD(l)
Definition: typedefs.h:246
static PIDLIST_ABSOLUTE *static DLLVERSIONINFO shellVersion
Definition: shellpath.c:107
static BOOL ILIsEmpty(_In_opt_ LPCITEMIDLIST pidl)
Definition: shlobj.h:2295
static void test_SHGetFolderPathEx(void)
Definition: shellpath.c:840
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
static void test_NonExistentPath(void)
Definition: shellpath.c:771
static const WCHAR longW[]
Definition: tokenize.c:63
pointer_default(unique)] interface IFileDialogCustomize enum tagKF_REDIRECTION_CAPABILITIES KF_REDIRECTION_CAPABILITIES
static LPITEMIDLIST *static LPITEMIDLIST(WINAPI *pILFindLastID)(LPCITEMIDLIST)
#define GetProcAddress(x, y)
Definition: compat.h:410
HRESULT WINAPI SHGetFolderLocation(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwReserved, LPITEMIDLIST *ppidl)
Definition: shellpath.c:2598
SHITEMID mkid
Definition: shtypes.idl:34
BOOL WINAPI PathYetAnotherMakeUniqueName(LPWSTR buffer, LPCWSTR path, LPCWSTR shortname, LPCWSTR longname)
Definition: shellpath.c:319
#define CSIDL_SYSTEM
Definition: shlobj.h:2024
#define CSIDL_DESKTOPDIRECTORY
Definition: shlobj.h:2003
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4831
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
static DWORD
Definition: shellpath.c:92
#define CSIDL_NETWORK
Definition: shlobj.h:2005
static void testSystemDir(void)
Definition: shellpath.c:649
const KNOWNFOLDERID * folderId
Definition: shellpath.c:909
#define CSIDL_PROGRAMS
Definition: shlobj.h:1990
#define CSIDL_TEMPLATES
Definition: shlobj.h:2008
#define memset(x, y, z)
Definition: compat.h:39
const char * sRelativePath
Definition: shellpath.c:916
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
static void matchSpecialFolderPathToEnv(int folder, const char *envVar)
Definition: shellpath.c:505
#define win_skip
Definition: test.h:141
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:406
#define LOWORD(l)
Definition: pedump.c:82
static HMODULE hShell32
Definition: string.c:34
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:90
#define CSIDL_SYSTEMX86
Definition: shlobj.h:2028
#define WINE_ATTRIBUTES_OPTIONAL
Definition: shellpath.c:898
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static LPSTR myPathRemoveBackslashA(LPSTR lpszPath)
Definition: shellpath.c:611
#define ok_(x1, x2)
Definition: CString.cpp:56
Definition: path.c:42
#define printf
Definition: config.h:203
static void FreeKnownFolderDefinitionFields(KNOWNFOLDER_DEFINITION *pKFD)") cpp_quote("
Definition: shobjidl.idl:4025
#define CSIDL_MYMUSIC
Definition: shlobj.h:2001
static const struct knownFolderDef known_folders[]
Definition: shellpath.c:932
Definition: fci.c:126
static HRESULT(WINAPI *pDllGetVersion)(DLLVERSIONINFO *)
static void test_EnvVars(void)
Definition: shellpath.c:591