ReactOS  0.4.15-dev-3723-g8d70159
shellpath.c
Go to the documentation of this file.
1 /*
2  * Path Functions
3  *
4  * Copyright 1998, 1999, 2000 Juergen Schmied
5  * Copyright 2004 Juan Lang
6  * Copyright 2018-2021 Katayama Hirofumi MZ
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  *
22  * NOTES:
23  *
24  * Many of these functions are in SHLWAPI.DLL also
25  *
26  */
27 
28 #define WIN32_NO_STATUS
29 #define _INC_WINDOWS
30 #define COBJMACROS
31 
32 #include <wine/config.h>
33 
34 #include <windef.h>
35 #include <winbase.h>
36 #include <shlobj.h>
37 #include <undocshell.h>
38 #include <shlwapi.h>
39 #include <sddl.h>
40 #include <strsafe.h>
41 #include <wine/debug.h>
42 #include <wine/unicode.h>
43 
44 #include <shlwapi_undoc.h>
45 #include <shellutils.h>
46 
47 #include <userenv.h>
48 
49 #include "pidl.h"
50 #include "shell32_main.h"
51 #include "shresdef.h"
52 
53 #undef _WIN32_WINNT
54 #define _WIN32_WINNT _WIN32_WINNT_WS03
55 
57 
58 static const BOOL is_win64 = sizeof(void *) > sizeof(int);
59 
60 #ifdef __REACTOS__
61 
62 /* FIXME: Remove this */
63 typedef enum _NT_PRODUCT_TYPE
64 {
65  NtProductWinNt = 1,
69 
70 /* FIXME: We cannot refresh the RtlGetNtProductType value before reboot. */
71 static BOOL
72 DoGetProductType(PNT_PRODUCT_TYPE ProductType)
73 {
74  HKEY hKey;
75  LONG error;
76  WCHAR szValue[9];
77  DWORD cbValue;
78  static DWORD s_dwProductType = 0;
79 
80  if (s_dwProductType != 0)
81  {
82  *ProductType = s_dwProductType;
83  return TRUE;
84  }
85 
86  *ProductType = NtProductServer;
87 
88  error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions", 0, KEY_READ, &hKey);
89  if (error)
90  return FALSE;
91 
92  cbValue = sizeof(szValue);
93  error = RegGetValueW(hKey, NULL, L"ProductType", RRF_RT_REG_SZ, NULL, (PVOID)szValue, &cbValue);
94  if (!error)
95  {
96  if (lstrcmpW(szValue, L"WinNT") == 0)
97  *ProductType = NtProductWinNt;
98  else if (lstrcmpW(szValue, L"LanmanNT") == 0)
99  *ProductType = NtProductLanManNt;
100  }
101 
102  s_dwProductType = *ProductType;
103 
104  RegCloseKey(hKey);
105  return TRUE;
106 }
107 
108 #endif // __REACTOS__
109 
110 /*
111  ########## Combining and Constructing paths ##########
112 */
113 
114 /* @implemented */
115 static BOOL WINAPI
116 PathSearchOnExtensionsW(LPWSTR pszPath, LPCWSTR *ppszDirs, BOOL bDoSearch, DWORD dwWhich)
117 {
118  if (*PathFindExtensionW(pszPath) != 0)
119  return FALSE;
120 
121  if (bDoSearch)
122  return PathFindOnPathExW(pszPath, ppszDirs, dwWhich);
123  else
124  return PathFileExistsDefExtW(pszPath, dwWhich);
125 }
126 
127 #if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
128 /* @implemented */
130 {
131  return PathIsUNCW(path) || (PathGetDriveNumberW(path) != -1 && path[2] == L'\\');
132 }
133 
134 /* @implemented */
136 {
138  DWORD cch;
139 
140  if (path == NULL)
141  return FALSE;
143  if (!cch || cch > _countof(path1))
144  return FALSE;
145  return (PathCombineW(path, path1, path) != NULL);
146 }
147 #endif
148 
149 /* NOTE: GetShortPathName fails if the pathname didn't exist.
150  GetShortPathNameAbsentW should set the short path name that even doesn't exist. */
151 static DWORD GetShortPathNameAbsentW(LPCWSTR pszLong, LPWSTR pszShort, DWORD cchShort)
152 {
153  FIXME("GetShortPathNameAbsentW(%ls, %p, %ld): stub\n", pszLong, pszShort, cchShort);
154  StringCchCopyW(pszShort, cchShort, pszLong);
155  return lstrlenW(pszShort);
156 }
157 
158 BOOL WINAPI IsLFNDriveW(LPCWSTR lpszPath);
159 
160 /* @unconfirmed */
162 {
163  WCHAR szRoot[MAX_PATH], szCopy[MAX_PATH], szCurDir[MAX_PATH];
164  LPWSTR pch;
165  LONG cch;
166  BOOL bCheckLFN;
167 
168  if (FAILED(StringCchCopyW(szCopy, _countof(szCopy), pszPath)))
169  return;
170 
171  FixSlashesAndColonW(szCopy);
172 
173  if (pszDir)
174  {
175  cch = GetCurrentDirectoryW(_countof(szCurDir), szCurDir);
177  pszDir = NULL;
178  }
179 
180  if (!GetFullPathNameW(szCopy, _countof(szRoot), szRoot, NULL))
181  goto Quit;
182 
183  if (PathIsUNCW(szRoot)) /* it begins with double backslash */
184  {
185  pch = StrChrW(&szRoot[2], L'\\');
186  if (pch)
187  {
188  pch = StrChrW(&pch[1], L'\\');
189  if (pch)
190  *pch = 0;
191  if (!PathAddBackslashW(szRoot))
192  goto Quit;
193  /* szRoot is like \\MyServer\MyShare\ */
194  bCheckLFN = TRUE;
195  }
196  else
197  {
198  bCheckLFN = FALSE;
199  }
200  }
201  else
202  {
203  if (!PathStripToRootW(szRoot) || !PathAddBackslashW(szRoot))
204  goto Quit;
205  /* szRoot is like X:\ */
206  bCheckLFN = TRUE;
207  }
208 
209  if (bCheckLFN && !IsLFNDriveW(szRoot)) /* not a long filename drive */
210  {
211  if (!GetFullPathNameW(szCopy, _countof(szRoot), szRoot, NULL))
212  goto Quit;
213  if (!GetShortPathNameW(szRoot, szCopy, _countof(szCopy)) &&
214  !GetShortPathNameAbsentW(szRoot, szCopy, _countof(szCopy)))
215  {
216  goto Quit;
217  }
218  }
219 
220  PathRemoveBackslashW(szCopy);
221  StringCchCopyW(pszPath, MAX_PATH, szCopy);
222 
223  if ((dwFlags & 1) == 0)
224  {
225  cch = lstrlenW(pszPath);
226  if (cch > 0 && pszPath[cch - 1] == L'.')
227  pszPath[cch - 1] = 0;
228  }
229 
230 Quit:
231  if (pszDir)
232  SetCurrentDirectoryW(szCurDir);
233 }
234 
235 /*************************************************************************
236  * PathAppend [SHELL32.36]
237  */
239  LPVOID lpszPath1,
240  LPCVOID lpszPath2)
241 {
242  if (SHELL_OsIsUnicode())
243  return PathAppendW(lpszPath1, lpszPath2);
244  return PathAppendA(lpszPath1, lpszPath2);
245 }
246 
247 /*************************************************************************
248  * PathGetExtensionA [internal]
249  *
250  * NOTES
251  * exported by ordinal
252  * return value points to the first char after the dot
253  */
255 {
256  TRACE("(%s)\n",lpszPath);
257 
258  lpszPath = PathFindExtensionA(lpszPath);
259  return (LPSTR)(*lpszPath?(lpszPath+1):lpszPath);
260 }
261 
262 /*************************************************************************
263  * PathGetExtensionW [internal]
264  */
266 {
267  TRACE("(%s)\n",debugstr_w(lpszPath));
268 
269  lpszPath = PathFindExtensionW(lpszPath);
270  return (LPWSTR)(*lpszPath?(lpszPath+1):lpszPath);
271 }
272 
273 /*************************************************************************
274  * SHPathGetExtension [SHELL32.158]
275  */
277 {
278  return PathGetExtensionW(lpszPath);
279 }
280 
281 /*************************************************************************
282  * PathRemoveFileSpec [SHELL32.35]
283  */
285 {
286  if (SHELL_OsIsUnicode())
287  return PathRemoveFileSpecW(lpszPath);
288  return PathRemoveFileSpecA(lpszPath);
289 }
290 
291 /*
292  Path Manipulations
293 */
294 
295 /*************************************************************************
296  * PathGetShortPathA [internal]
297  */
298 static void PathGetShortPathA(LPSTR pszPath)
299 {
300  CHAR path[MAX_PATH];
301 
302  TRACE("%s\n", pszPath);
303 
304  if (GetShortPathNameA(pszPath, path, MAX_PATH))
305  {
306  lstrcpyA(pszPath, path);
307  }
308 }
309 
310 /*************************************************************************
311  * PathGetShortPathW [internal]
312  */
313 static void PathGetShortPathW(LPWSTR pszPath)
314 {
316 
317  TRACE("%s\n", debugstr_w(pszPath));
318 
319  if (GetShortPathNameW(pszPath, path, MAX_PATH))
320  {
321  lstrcpyW(pszPath, path);
322  }
323 }
324 
325 /*************************************************************************
326  * PathGetShortPath [SHELL32.92]
327  */
329 {
330  if(SHELL_OsIsUnicode())
331  PathGetShortPathW(pszPath);
332  PathGetShortPathA(pszPath);
333 }
334 
335 /*
336  ########## Path Testing ##########
337 */
338 
339 /*************************************************************************
340  * PathIsRoot [SHELL32.29]
341  */
343 {
344  if (SHELL_OsIsUnicode())
345  return PathIsRootW(lpszPath);
346  return PathIsRootA(lpszPath);
347 }
348 
349 /*************************************************************************
350  * PathIsExeA [internal]
351  */
352 static BOOL PathIsExeA (LPCSTR lpszPath)
353 {
354  LPCSTR lpszExtension = PathGetExtensionA(lpszPath);
355  int i;
356  static const char * const lpszExtensions[] =
357  {"exe", "com", "pif", "cmd", "bat", "scf", "scr", NULL };
358 
359  TRACE("path=%s\n",lpszPath);
360 
361  for(i=0; lpszExtensions[i]; i++)
362  if (!lstrcmpiA(lpszExtension,lpszExtensions[i])) return TRUE;
363 
364  return FALSE;
365 }
366 
367 /*************************************************************************
368  * PathIsExeW [internal]
369  */
371 {
372  LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
373  int i;
374  static const WCHAR lpszExtensions[][4] =
375  {L"exe", L"com", L"pif", L"cmd", L"bat", L"scf", L"scr", L"" };
376 
377  TRACE("path=%s\n",debugstr_w(lpszPath));
378 
379  for(i=0; lpszExtensions[i][0]; i++)
380  if (!wcsicmp(lpszExtension,lpszExtensions[i])) return TRUE;
381 
382  return FALSE;
383 }
384 
385 /*************************************************************************
386  * PathIsExe [SHELL32.43]
387  */
389 {
390  if (SHELL_OsIsUnicode())
391  return PathIsExeW (path);
392  return PathIsExeA(path);
393 }
394 
395 /*************************************************************************
396  * PathFileExists [SHELL32.45]
397  */
399 {
400  if (SHELL_OsIsUnicode())
401  return PathFileExistsW (lpszPath);
402  return PathFileExistsA (lpszPath);
403 }
404 
405 /*************************************************************************
406  * IsLFNDriveA [SHELL32.41]
407  */
409 {
410  DWORD fnlen;
411 
412  if (!GetVolumeInformationA(lpszPath, NULL, 0, NULL, &fnlen, NULL, NULL, 0))
413  return FALSE;
414  return fnlen > 12;
415 }
416 
417 /*************************************************************************
418  * IsLFNDriveW [SHELL32.42]
419  */
421 {
422  DWORD fnlen;
423 
424  if (!GetVolumeInformationW(lpszPath, NULL, 0, NULL, &fnlen, NULL, NULL, 0))
425  return FALSE;
426  return fnlen > 12;
427 }
428 
429 /*************************************************************************
430  * IsLFNDrive [SHELL32.119]
431  */
433 {
434  if (SHELL_OsIsUnicode())
435  return IsLFNDriveW(lpszPath);
436  return IsLFNDriveA(lpszPath);
437 }
438 
439 /*
440  ########## Creating Something Unique ##########
441 */
442 /*************************************************************************
443  * PathMakeUniqueNameA [internal]
444  */
446  LPSTR lpszBuffer,
447  DWORD dwBuffSize,
448  LPCSTR lpszShortName,
449  LPCSTR lpszLongName,
450  LPCSTR lpszPathName)
451 {
452  FIXME("%p %u %s %s %s stub\n",
453  lpszBuffer, dwBuffSize, debugstr_a(lpszShortName),
454  debugstr_a(lpszLongName), debugstr_a(lpszPathName));
455  return TRUE;
456 }
457 
458 /*************************************************************************
459  * PathMakeUniqueNameW [internal]
460  */
462  LPWSTR lpszBuffer,
463  DWORD dwBuffSize,
464  LPCWSTR lpszShortName,
465  LPCWSTR lpszLongName,
466  LPCWSTR lpszPathName)
467 {
468  FIXME("%p %u %s %s %s stub\n",
469  lpszBuffer, dwBuffSize, debugstr_w(lpszShortName),
470  debugstr_w(lpszLongName), debugstr_w(lpszPathName));
471  return TRUE;
472 }
473 
474 /*************************************************************************
475  * PathMakeUniqueName [SHELL32.47]
476  */
478  LPVOID lpszBuffer,
479  DWORD dwBuffSize,
480  LPCVOID lpszShortName,
481  LPCVOID lpszLongName,
482  LPCVOID lpszPathName)
483 {
484  if (SHELL_OsIsUnicode())
485  return PathMakeUniqueNameW(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
486  return PathMakeUniqueNameA(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
487 }
488 
489 /*************************************************************************
490  * PathYetAnotherMakeUniqueName [SHELL32.75]
491  */
493 {
494  WCHAR pathW[MAX_PATH], retW[MAX_PATH];
495  const WCHAR *file, *ext;
496  int i = 2;
497 
498  TRACE("(%p, %s, %s, %s)\n", buffer, debugstr_w(path), debugstr_w(shortname), debugstr_w(longname));
499 
500  file = longname ? longname : shortname;
501  PathCombineW(pathW, path, file);
502  strcpyW(retW, pathW);
503  PathRemoveExtensionW(pathW);
504 
506 
507  /* now try to make it unique */
508  while (PathFileExistsW(retW))
509  {
510  sprintfW(retW, L"%s (%d)%s", pathW, i, ext);
511  i++;
512  }
513 
514  strcpyW(buffer, retW);
515  TRACE("ret - %s\n", debugstr_w(buffer));
516 
517  return TRUE;
518 }
519 
520 /*
521  ########## cleaning and resolving paths ##########
522  */
523 
524 /*************************************************************************
525  * PathCleanupSpec [SHELL32.171]
526  *
527  * lpszFile is changed in place.
528  */
529 int WINAPI PathCleanupSpec( LPCWSTR lpszPathW, LPWSTR lpszFileW )
530 {
531  int i = 0;
532  DWORD rc = 0;
533  int length = 0;
534 
535  if (SHELL_OsIsUnicode())
536  {
537  LPWSTR p = lpszFileW;
538 
539  TRACE("Cleanup %s\n",debugstr_w(lpszFileW));
540 
541  if (lpszPathW)
542  length = strlenW(lpszPathW);
543 
544  while (*p)
545  {
546  int gct = PathGetCharTypeW(*p);
547  if (gct == GCT_INVALID || gct == GCT_WILD || gct == GCT_SEPARATOR)
548  {
549  lpszFileW[i]='-';
550  rc |= PCS_REPLACEDCHAR;
551  }
552  else
553  lpszFileW[i]=*p;
554  i++;
555  p++;
556  if (length + i == MAX_PATH)
557  {
558  rc |= PCS_FATAL | PCS_PATHTOOLONG;
559  break;
560  }
561  }
562  lpszFileW[i]=0;
563  }
564  else
565  {
566  LPSTR lpszFileA = (LPSTR)lpszFileW;
567  LPCSTR lpszPathA = (LPCSTR)lpszPathW;
568  LPSTR p = lpszFileA;
569 
570  TRACE("Cleanup %s\n",debugstr_a(lpszFileA));
571 
572  if (lpszPathA)
573  length = strlen(lpszPathA);
574 
575  while (*p)
576  {
577  int gct = PathGetCharTypeA(*p);
578  if (gct == GCT_INVALID || gct == GCT_WILD || gct == GCT_SEPARATOR)
579  {
580  lpszFileA[i]='-';
581  rc |= PCS_REPLACEDCHAR;
582  }
583  else
584  lpszFileA[i]=*p;
585  i++;
586  p++;
587  if (length + i == MAX_PATH)
588  {
589  rc |= PCS_FATAL | PCS_PATHTOOLONG;
590  break;
591  }
592  }
593  lpszFileA[i]=0;
594  }
595  return rc;
596 }
597 
598 /*************************************************************************
599  * PathQualifyA [SHELL32]
600  */
602 {
604  TRACE("%s\n",pszPath);
607  SHUnicodeToAnsi(szPath, pszPath, MAX_PATH);
608 }
609 
610 /*************************************************************************
611  * PathQualifyW [SHELL32]
612  */
614 {
615  TRACE("%s\n",debugstr_w(pszPath));
616  PathQualifyExW(pszPath, NULL, 0);
617 }
618 
619 /*************************************************************************
620  * PathQualify [SHELL32.49]
621  */
623 {
624  if (SHELL_OsIsUnicode())
625  PathQualifyW(pszPath);
626  else
627  PathQualifyA(pszPath);
628 }
629 
631 {
632  BOOL ret = FALSE;
633  LPWSTR *dirsW = NULL;
634  DWORD iDir, cDirs, cbDirs;
635  WCHAR pathW[MAX_PATH];
636 
637  TRACE("PathResolveA(%s,%p,0x%08x)\n", debugstr_a(path), dirs, flags);
638 
639  if (dirs)
640  {
641  for (cDirs = 0; dirs[cDirs]; ++cDirs)
642  ;
643 
644  cbDirs = (cDirs + 1) * sizeof(LPWSTR);
645  dirsW = SHAlloc(cbDirs);
646  if (!dirsW)
647  goto Cleanup;
648 
649  ZeroMemory(dirsW, cbDirs);
650  for (iDir = 0; iDir < cDirs; ++iDir)
651  {
652  __SHCloneStrAtoW(&dirsW[iDir], dirs[iDir]);
653  if (dirsW[iDir] == NULL)
654  goto Cleanup;
655  }
656  }
657 
658  SHAnsiToUnicode(path, pathW, _countof(pathW));
659 
660  ret = PathResolveW(pathW, (LPCWSTR*)dirsW, flags);
661  if (ret)
662  SHUnicodeToAnsi(pathW, path, MAX_PATH);
663 
664 Cleanup:
665  if (dirsW)
666  {
667  for (iDir = 0; iDir < cDirs; ++iDir)
668  {
669  SHFree(dirsW[iDir]);
670  }
671  SHFree(dirsW);
672  }
673  return ret;
674 }
675 
677 {
679 
680  TRACE("PathResolveW(%s,%p,0x%08x)\n", debugstr_w(path), dirs, flags);
681 
682  if (flags & PRF_VERIFYEXISTS)
684 
686 
687  if (PathIsRootW(path))
688  {
689  if ((path[0] == L'\\' && path[1] == 0) ||
691  {
692  if (flags & PRF_FIRSTDIRDEF)
693  PathQualifyExW(path, dirs[0], 0);
694  else
695  PathQualifyExW(path, NULL, 0);
696  }
697 
698  if (flags & PRF_VERIFYEXISTS)
700  return TRUE;
701  }
702  else if (PathIsFileSpecW(path))
703  {
704  if ((flags & PRF_TRYPROGRAMEXTENSIONS) && PathSearchOnExtensionsW(path, dirs, TRUE, dwWhich))
705  return TRUE;
706 
707  if (PathFindOnPathW(path, dirs))
708  {
709 #if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
710  if (!(flags & PRF_REQUIREABSOLUTE))
711  return TRUE;
712 
713  if (!PathIsAbsoluteW(path))
715 #else
716  return TRUE;
717 #endif
718  }
719  }
720  else if (!PathIsURLW(path))
721  {
722  if (flags & PRF_FIRSTDIRDEF)
723  PathQualifyExW(path, *dirs, 1);
724  else
725  PathQualifyExW(path, NULL, 1);
726 
727  if (flags & PRF_VERIFYEXISTS)
728  {
730  PathSearchOnExtensionsW(path, dirs, FALSE, dwWhich))
731  {
732  return TRUE;
733  }
735  {
736  return FALSE;
737  }
738  }
739 
740 #if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
742  {
743  if (!PathIsAbsoluteW(path))
745  }
746 #endif
747  return TRUE;
748  }
749 
750  return FALSE;
751 }
752 
753 /*************************************************************************
754  * PathResolve [SHELL32.51]
755  */
757 {
758  if (SHELL_OsIsUnicode())
759  return PathResolveW(path, (LPCWSTR*)paths, flags);
760  else
761  return PathResolveA(path, (LPCSTR*)paths, flags);
762 }
763 
764 /*************************************************************************
765 * PathProcessCommandA
766 */
768  LPCSTR lpszPath,
769  LPSTR lpszBuff,
770  DWORD dwBuffSize,
771  DWORD dwFlags)
772 {
773  FIXME("%s %p 0x%04x 0x%04x stub\n",
774  lpszPath, lpszBuff, dwBuffSize, dwFlags);
775  if(!lpszPath) return -1;
776  if(lpszBuff) strcpy(lpszBuff, lpszPath);
777  return strlen(lpszPath);
778 }
779 
780 /*************************************************************************
781 * PathProcessCommandW
782 */
784  LPCWSTR lpszPath,
785  LPWSTR lpszBuff,
786  DWORD dwBuffSize,
787  DWORD dwFlags)
788 {
789  FIXME("(%s, %p, 0x%04x, 0x%04x) stub\n",
790  debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags);
791  if(!lpszPath) return -1;
792  if(lpszBuff) strcpyW(lpszBuff, lpszPath);
793  return strlenW(lpszPath);
794 }
795 
796 /*************************************************************************
797 * PathProcessCommand (SHELL32.653)
798 */
800  LPCVOID lpszPath,
801  LPVOID lpszBuff,
802  DWORD dwBuffSize,
803  DWORD dwFlags)
804 {
805  if (SHELL_OsIsUnicode())
806  return PathProcessCommandW(lpszPath, lpszBuff, dwBuffSize, dwFlags);
807  return PathProcessCommandA(lpszPath, lpszBuff, dwBuffSize, dwFlags);
808 }
809 
810 /*
811  ########## special ##########
812 */
813 
814 /* !! MISSING Win2k3-compatible paths from the list below; absent from Wine !! */
815 #ifndef __REACTOS__
816 static const WCHAR Application_DataW[] = L"Application Data";
817 static const WCHAR Local_Settings_Application_DataW[] = L"Local Settings\\Application Data";
818 static const WCHAR Local_Settings_HistoryW[] = L"Local Settings\\History";
819 static const WCHAR Local_Settings_Temporary_Internet_FilesW[] = L"Local Settings\\Temporary Internet Files";
820 static const WCHAR MusicW[] = L"Music";
821 static const WCHAR PicturesW[] = L"Pictures";
822 static const WCHAR Program_FilesW[] = L"Program Files";
823 static const WCHAR Program_Files_Common_FilesW[] = L"Program Files\\Common Files";
824 static const WCHAR Start_Menu_ProgramsW[] = L"Start Menu\\Programs";
825 static const WCHAR Start_Menu_Admin_ToolsW[] = L"Start Menu\\Programs\\Administrative Tools";
826 static const WCHAR Start_Menu_StartupW[] = L"Start Menu\\Programs\\StartUp";
827 #endif
828 
829 /* Long strings that are repeated many times: keep them here */
830 static const WCHAR szSHFolders[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
831 static const WCHAR szSHUserFolders[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
832 #ifndef __REACTOS__
833 static const WCHAR szKnownFolderDescriptions[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FolderDescriptions";
834 static const WCHAR szKnownFolderRedirections[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
835 #endif
836 
837 typedef enum _CSIDL_Type {
839 #ifdef __REACTOS__
840  CSIDL_Type_InMyDocuments,
841 #endif
849 } CSIDL_Type;
850 
851 /* Cannot use #if _WIN32_WINNT >= 0x0600 because _WIN32_WINNT == 0x0600 here. */
852 #ifndef __REACTOS__
853 #define CSIDL_CONTACTS 0x0043
854 #define CSIDL_DOWNLOADS 0x0047
855 #define CSIDL_LINKS 0x004d
856 #define CSIDL_APPDATA_LOCALLOW 0x004e
857 #define CSIDL_SAVED_GAMES 0x0062
858 #define CSIDL_SEARCHES 0x0063
859 #endif
860 
861 typedef struct
862 {
866  LPCWSTR szDefaultPath; /* fallback string or resource ID */
868 } CSIDL_DATA;
869 
870 static const CSIDL_DATA CSIDL_Data[] =
871 {
872  { /* 0x00 - CSIDL_DESKTOP */
873  &FOLDERID_Desktop,
875  L"Desktop",
877 #ifdef __REACTOS__
878  0
879 #else
881 #endif
882  },
883  { /* 0x01 - CSIDL_INTERNET */
884  &FOLDERID_InternetFolder,
886  NULL,
887  NULL
888  },
889  { /* 0x02 - CSIDL_PROGRAMS */
890  &FOLDERID_Programs,
892  L"Programs",
894 #ifdef __REACTOS__
895  0
896 #else
898 #endif
899  },
900  { /* 0x03 - CSIDL_CONTROLS (.CPL files) */
901  &FOLDERID_ControlPanelFolder,
903  NULL,
904  NULL,
906  },
907  { /* 0x04 - CSIDL_PRINTERS */
908  &FOLDERID_PrintersFolder,
910  NULL,
911  NULL,
913  },
914  { /* 0x05 - CSIDL_PERSONAL */
915  &FOLDERID_Documents,
917  L"Personal",
920  },
921  { /* 0x06 - CSIDL_FAVORITES */
922  &FOLDERID_Favorites,
924  L"Favorites",
927  },
928  { /* 0x07 - CSIDL_STARTUP */
929  &FOLDERID_Startup,
931  L"StartUp",
933  },
934  { /* 0x08 - CSIDL_RECENT */
935  &FOLDERID_Recent,
937  L"Recent",
940  },
941  { /* 0x09 - CSIDL_SENDTO */
942  &FOLDERID_SendTo,
944  L"SendTo",
946  },
947  { /* 0x0a - CSIDL_BITBUCKET - Recycle Bin */
948  &FOLDERID_RecycleBinFolder,
950  NULL,
951  NULL
952  },
953  { /* 0x0b - CSIDL_STARTMENU */
954  &FOLDERID_StartMenu,
956  L"Start Menu",
959  },
960  { /* 0x0c - CSIDL_MYDOCUMENTS */
961  &GUID_NULL,
962  CSIDL_Type_Disallowed, /* matches WinXP--can't get its path */
963  NULL,
964  NULL,
966  },
967  { /* 0x0d - CSIDL_MYMUSIC */
968  &FOLDERID_Music,
969 #ifdef __REACTOS__
970  CSIDL_Type_InMyDocuments,
971 #else
973 #endif
974  L"My Music",
977  },
978  { /* 0x0e - CSIDL_MYVIDEO */
979  &FOLDERID_Videos,
980 #ifdef __REACTOS__
981  CSIDL_Type_InMyDocuments,
982 #else
984 #endif
985  L"My Video",
988  },
989  { /* 0x0f - unassigned */
990  &GUID_NULL,
992  NULL,
993  NULL,
994  },
995  { /* 0x10 - CSIDL_DESKTOPDIRECTORY */
996  &FOLDERID_Desktop,
998  L"Desktop",
1000 #ifdef __REACTOS__
1001  0
1002 #else
1004 #endif
1005  },
1006  { /* 0x11 - CSIDL_DRIVES */
1007  &FOLDERID_ComputerFolder,
1009  NULL,
1010  NULL,
1012  },
1013  { /* 0x12 - CSIDL_NETWORK */
1014  &FOLDERID_NetworkFolder,
1016  NULL,
1017  NULL,
1019  },
1020  { /* 0x13 - CSIDL_NETHOOD */
1021  &FOLDERID_NetHood,
1023  L"NetHood",
1026  },
1027  { /* 0x14 - CSIDL_FONTS */
1028  &FOLDERID_Fonts,
1030  L"Fonts",
1031  L"Fonts",
1033  },
1034  { /* 0x15 - CSIDL_TEMPLATES */
1035  &FOLDERID_Templates,
1037  L"Templates",
1039  },
1040  { /* 0x16 - CSIDL_COMMON_STARTMENU */
1041  &FOLDERID_CommonStartMenu,
1043  L"Common Start Menu",
1046  },
1047  { /* 0x17 - CSIDL_COMMON_PROGRAMS */
1048  &FOLDERID_CommonPrograms,
1050  L"Common Programs",
1052 #ifdef __REACTOS__
1053  0
1054 #else
1056 #endif
1057  },
1058  { /* 0x18 - CSIDL_COMMON_STARTUP */
1059  &FOLDERID_CommonStartup,
1061  L"Common StartUp",
1063  },
1064  { /* 0x19 - CSIDL_COMMON_DESKTOPDIRECTORY */
1065  &FOLDERID_PublicDesktop,
1067  L"Common Desktop",
1069 #ifdef __REACTOS__
1070  0
1071 #else
1073 #endif
1074  },
1075  { /* 0x1a - CSIDL_APPDATA */
1076  &FOLDERID_RoamingAppData,
1078  L"AppData",
1080  },
1081  { /* 0x1b - CSIDL_PRINTHOOD */
1082  &FOLDERID_PrintHood,
1084  L"PrintHood",
1087  },
1088  { /* 0x1c - CSIDL_LOCAL_APPDATA */
1089  &FOLDERID_LocalAppData,
1091  L"Local AppData",
1093  },
1094  { /* 0x1d - CSIDL_ALTSTARTUP */
1095  &GUID_NULL,
1097  NULL,
1098  NULL
1099  },
1100  { /* 0x1e - CSIDL_COMMON_ALTSTARTUP */
1101  &GUID_NULL,
1103  NULL,
1104  NULL
1105  },
1106  { /* 0x1f - CSIDL_COMMON_FAVORITES */
1107  &FOLDERID_Favorites,
1109  L"Common Favorites",
1112  },
1113  { /* 0x20 - CSIDL_INTERNET_CACHE */
1114  &FOLDERID_InternetCache,
1116  L"Cache",
1118  },
1119  { /* 0x21 - CSIDL_COOKIES */
1120  &FOLDERID_Cookies,
1122  L"Cookies",
1124  },
1125  { /* 0x22 - CSIDL_HISTORY */
1126  &FOLDERID_History,
1128  L"History",
1130  },
1131  { /* 0x23 - CSIDL_COMMON_APPDATA */
1132  &FOLDERID_ProgramData,
1134  L"Common AppData",
1136  },
1137  { /* 0x24 - CSIDL_WINDOWS */
1138  &FOLDERID_Windows,
1140  NULL,
1141  NULL,
1143  },
1144  { /* 0x25 - CSIDL_SYSTEM */
1145  &FOLDERID_System,
1147  NULL,
1148  NULL,
1150  },
1151  { /* 0x26 - CSIDL_PROGRAM_FILES */
1152  &FOLDERID_ProgramFiles,
1154  L"ProgramFilesDir",
1156 #ifdef __REACTOS__
1157  0
1158 #else
1160 #endif
1161  },
1162  { /* 0x27 - CSIDL_MYPICTURES */
1163  &FOLDERID_Pictures,
1164 #ifdef __REACTOS__
1165  CSIDL_Type_InMyDocuments,
1166 #else
1168 #endif
1169  L"My Pictures",
1172  },
1173  { /* 0x28 - CSIDL_PROFILE */
1174  &FOLDERID_Profile,
1176  NULL,
1177  NULL
1178  },
1179  { /* 0x29 - CSIDL_SYSTEMX86 */
1180  &FOLDERID_SystemX86,
1182  NULL,
1183  NULL,
1185  },
1186  { /* 0x2a - CSIDL_PROGRAM_FILESX86 */
1187  &FOLDERID_ProgramFilesX86,
1189  L"ProgramFilesDir (x86)",
1190  L"Program Files (x86)",
1192  },
1193  { /* 0x2b - CSIDL_PROGRAM_FILES_COMMON */
1194  &FOLDERID_ProgramFilesCommon,
1196  L"CommonFilesDir",
1199  },
1200  { /* 0x2c - CSIDL_PROGRAM_FILES_COMMONX86 */
1201  &FOLDERID_ProgramFilesCommonX86,
1203  L"CommonFilesDir (x86)",
1204  L"Program Files (x86)\\Common Files",
1206  },
1207  { /* 0x2d - CSIDL_COMMON_TEMPLATES */
1208  &FOLDERID_CommonTemplates,
1210  L"Common Templates",
1212  },
1213  { /* 0x2e - CSIDL_COMMON_DOCUMENTS */
1214  &FOLDERID_PublicDocuments,
1216  L"Common Documents",
1219  },
1220  { /* 0x2f - CSIDL_COMMON_ADMINTOOLS */
1221  &FOLDERID_CommonAdminTools,
1223  L"Common Administrative Tools",
1225  },
1226  { /* 0x30 - CSIDL_ADMINTOOLS */
1227  &FOLDERID_AdminTools,
1229  L"Administrative Tools",
1231  },
1232  { /* 0x31 - CSIDL_CONNECTIONS */
1233  &FOLDERID_ConnectionsFolder,
1235  NULL,
1236  NULL,
1238  },
1239  { /* 0x32 - unassigned */
1240  &GUID_NULL,
1242  NULL,
1243  NULL
1244  },
1245  { /* 0x33 - unassigned */
1246  &GUID_NULL,
1248  NULL,
1249  NULL
1250  },
1251  { /* 0x34 - unassigned */
1252  &GUID_NULL,
1254  NULL,
1255  NULL
1256  },
1257  { /* 0x35 - CSIDL_COMMON_MUSIC */
1258  &FOLDERID_PublicMusic,
1260  L"CommonMusic",
1263  },
1264  { /* 0x36 - CSIDL_COMMON_PICTURES */
1265  &FOLDERID_PublicPictures,
1267  L"CommonPictures",
1270  },
1271  { /* 0x37 - CSIDL_COMMON_VIDEO */
1272  &FOLDERID_PublicVideos,
1274  L"CommonVideo",
1277  },
1278  { /* 0x38 - CSIDL_RESOURCES */
1279  &FOLDERID_ResourceDir,
1281  NULL,
1282  L"Resources"
1283  },
1284  { /* 0x39 - CSIDL_RESOURCES_LOCALIZED */
1285  &FOLDERID_LocalizedResourcesDir,
1287  NULL,
1288  NULL
1289  },
1290  { /* 0x3a - CSIDL_COMMON_OEM_LINKS */
1291  &FOLDERID_CommonOEMLinks,
1293  NULL,
1294  L"OEM Links"
1295  },
1296  { /* 0x3b - CSIDL_CDBURN_AREA */
1297  &FOLDERID_CDBurning,
1299  L"CD Burning",
1300  L"Local Settings\\Application Data\\Microsoft\\CD Burning"
1301  },
1302  { /* 0x3c unassigned */
1303  &GUID_NULL,
1305  NULL,
1306  NULL
1307  },
1308  { /* 0x3d - CSIDL_COMPUTERSNEARME */
1309  &GUID_NULL,
1310  CSIDL_Type_Disallowed, /* FIXME */
1311  NULL,
1312  NULL
1313  },
1314  { /* 0x3e - CSIDL_PROFILES */
1315  &GUID_NULL,
1316  CSIDL_Type_Disallowed, /* oddly, this matches WinXP */
1317  NULL,
1318  NULL
1319  },
1320 /* Cannot use #if _WIN32_WINNT >= 0x0600 because _WIN32_WINNT == 0x0600 here. */
1321 #ifndef __REACTOS__
1322  { /* 0x3f */
1323  &FOLDERID_AddNewPrograms,
1325  NULL,
1326  NULL
1327  },
1328  { /* 0x40 */
1329  &FOLDERID_AppUpdates,
1331  NULL,
1332  NULL
1333  },
1334  { /* 0x41 */
1335  &FOLDERID_ChangeRemovePrograms,
1337  NULL,
1338  NULL
1339  },
1340  { /* 0x42 */
1341  &FOLDERID_ConflictFolder,
1343  NULL,
1344  NULL
1345  },
1346  { /* 0x43 - CSIDL_CONTACTS */
1347  &FOLDERID_Contacts,
1349  NULL,
1350  L"Contacts"
1351  },
1352  { /* 0x44 */
1353  &FOLDERID_DeviceMetadataStore,
1354  CSIDL_Type_Disallowed, /* FIXME */
1355  NULL,
1356  NULL
1357  },
1358  { /* 0x45 */
1359  &GUID_NULL,
1361  NULL,
1362  L"Documents"
1363  },
1364  { /* 0x46 */
1365  &FOLDERID_DocumentsLibrary,
1366  CSIDL_Type_Disallowed, /* FIXME */
1367  NULL,
1368  NULL
1369  },
1370  { /* 0x47 - CSIDL_DOWNLOADS */
1371  &FOLDERID_Downloads,
1372 #ifdef __REACTOS__
1373  CSIDL_Type_InMyDocuments,
1374 #else
1376 #endif
1377  NULL,
1378  L"Downloads"
1379  },
1380  { /* 0x48 */
1381  &FOLDERID_Games,
1383  NULL,
1384  NULL
1385  },
1386  { /* 0x49 */
1387  &FOLDERID_GameTasks,
1388  CSIDL_Type_Disallowed, /* FIXME */
1389  NULL,
1390  NULL
1391  },
1392  { /* 0x4a */
1393  &FOLDERID_HomeGroup,
1395  NULL,
1396  NULL
1397  },
1398  { /* 0x4b */
1399  &FOLDERID_ImplicitAppShortcuts,
1400  CSIDL_Type_Disallowed, /* FIXME */
1401  NULL,
1402  NULL
1403  },
1404  { /* 0x4c */
1405  &FOLDERID_Libraries,
1406  CSIDL_Type_Disallowed, /* FIXME */
1407  NULL,
1408  NULL
1409  },
1410  { /* 0x4d - CSIDL_LINKS */
1411  &FOLDERID_Links,
1413  NULL,
1414  L"Links"
1415  },
1416  { /* 0x4e - CSIDL_APPDATA_LOCALLOW */
1417  &FOLDERID_LocalAppDataLow,
1419  NULL,
1420  L"AppData\\LocalLow"
1421  },
1422  { /* 0x4f */
1423  &FOLDERID_MusicLibrary,
1424  CSIDL_Type_Disallowed, /* FIXME */
1425  NULL,
1426  NULL
1427  },
1428  { /* 0x50 */
1429  &FOLDERID_OriginalImages,
1430  CSIDL_Type_Disallowed, /* FIXME */
1431  NULL,
1432  NULL
1433  },
1434  { /* 0x51 */
1435  &FOLDERID_PhotoAlbums,
1437  NULL,
1438  L"Pictures\\Slide Shows"
1439  },
1440  { /* 0x52 */
1441  &FOLDERID_PicturesLibrary,
1442  CSIDL_Type_Disallowed, /* FIXME */
1443  NULL,
1444  NULL
1445  },
1446  { /* 0x53 */
1447  &FOLDERID_Playlists,
1449  NULL,
1450  L"Music\\Playlists"
1451  },
1452  { /* 0x54 */
1453  &FOLDERID_ProgramFilesX64,
1455  NULL,
1456  NULL
1457  },
1458  { /* 0x55 */
1459  &FOLDERID_ProgramFilesCommonX64,
1461  NULL,
1462  NULL
1463  },
1464  { /* 0x56 */
1465  &FOLDERID_Public,
1466  CSIDL_Type_CurrVer, /* FIXME */
1467  NULL,
1468  L"Users\\Public"
1469  },
1470  { /* 0x57 */
1471  &FOLDERID_PublicDownloads,
1473  NULL,
1474  L"Downloads"
1475  },
1476  { /* 0x58 */
1477  &FOLDERID_PublicGameTasks,
1479  NULL,
1480  L"Microsoft\\Windows\\GameExplorer"
1481  },
1482  { /* 0x59 */
1483  &FOLDERID_PublicLibraries,
1485  NULL,
1486  L"Microsoft\\Windows\\Libraries"
1487  },
1488  { /* 0x5a */
1489  &FOLDERID_PublicRingtones,
1491  NULL,
1492  L"Microsoft\\Windows\\Ringtones"
1493  },
1494  { /* 0x5b */
1495  &FOLDERID_QuickLaunch,
1496  CSIDL_Type_Disallowed, /* FIXME */
1497  NULL,
1498  NULL
1499  },
1500  { /* 0x5c */
1501  &FOLDERID_RecordedTVLibrary,
1502  CSIDL_Type_Disallowed, /* FIXME */
1503  NULL,
1504  NULL
1505  },
1506  { /* 0x5d */
1507  &FOLDERID_Ringtones,
1508  CSIDL_Type_Disallowed, /* FIXME */
1509  NULL,
1510  NULL
1511  },
1512  { /* 0x5e */
1513  &FOLDERID_SampleMusic,
1515  NULL,
1516  L"Music\\Sample Music"
1517  },
1518  { /* 0x5f */
1519  &FOLDERID_SamplePictures,
1521  NULL,
1522  L"Pictures\\Sample Pictures"
1523  },
1524  { /* 0x60 */
1525  &FOLDERID_SamplePlaylists,
1527  NULL,
1528  L"Music\\Sample Playlists"
1529  },
1530  { /* 0x61 */
1531  &FOLDERID_SampleVideos,
1533  NULL,
1534  L"Videos\\Sample Videos"
1535  },
1536  { /* 0x62 - CSIDL_SAVED_GAMES */
1537  &FOLDERID_SavedGames,
1539  NULL,
1540  L"Saved Games"
1541  },
1542  { /* 0x63 - CSIDL_SEARCHES */
1543  &FOLDERID_SavedSearches,
1545  NULL,
1546  L"Searches"
1547  },
1548  { /* 0x64 */
1549  &FOLDERID_SEARCH_CSC,
1551  NULL,
1552  NULL
1553  },
1554  { /* 0x65 */
1555  &FOLDERID_SEARCH_MAPI,
1557  NULL,
1558  NULL
1559  },
1560  { /* 0x66 */
1561  &FOLDERID_SearchHome,
1563  NULL,
1564  NULL
1565  },
1566  { /* 0x67 */
1567  &FOLDERID_SidebarDefaultParts,
1568  CSIDL_Type_Disallowed, /* FIXME */
1569  NULL,
1570  NULL
1571  },
1572  { /* 0x68 */
1573  &FOLDERID_SidebarParts,
1574  CSIDL_Type_Disallowed, /* FIXME */
1575  NULL,
1576  NULL
1577  },
1578  { /* 0x69 */
1579  &FOLDERID_SyncManagerFolder,
1581  NULL,
1582  NULL
1583  },
1584  { /* 0x6a */
1585  &FOLDERID_SyncResultsFolder,
1587  NULL,
1588  NULL
1589  },
1590  { /* 0x6b */
1591  &FOLDERID_SyncSetupFolder,
1593  NULL,
1594  NULL
1595  },
1596  { /* 0x6c */
1597  &FOLDERID_UserPinned,
1598  CSIDL_Type_Disallowed, /* FIXME */
1599  NULL,
1600  NULL
1601  },
1602  { /* 0x6d */
1603  &FOLDERID_UserProfiles,
1605  L"Users",
1606  L"Users"
1607  },
1608  { /* 0x6e */
1609  &FOLDERID_UserProgramFiles,
1610  CSIDL_Type_Disallowed, /* FIXME */
1611  NULL,
1612  NULL
1613  },
1614  { /* 0x6f */
1615  &FOLDERID_UserProgramFilesCommon,
1616  CSIDL_Type_Disallowed, /* FIXME */
1617  NULL,
1618  NULL
1619  },
1620  { /* 0x70 */
1621  &FOLDERID_UsersFiles,
1623  NULL,
1624  NULL
1625  },
1626  { /* 0x71 */
1627  &FOLDERID_UsersLibraries,
1629  NULL,
1630  NULL
1631  },
1632  { /* 0x72 */
1633  &FOLDERID_VideosLibrary,
1634  CSIDL_Type_Disallowed, /* FIXME */
1635  NULL,
1636  NULL
1637  }
1638 #endif
1639 };
1640 
1641 #ifndef __REACTOS__
1642 static HRESULT _SHExpandEnvironmentStrings(LPCWSTR szSrc, LPWSTR szDest);
1643 #else
1644 static HRESULT _SHExpandEnvironmentStrings(HANDLE hToken, LPCWSTR szSrc, LPWSTR szDest, DWORD cchDest);
1645 #endif
1646 
1647 /* Gets the value named value from the registry key
1648  * rootKey\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
1649  * (or from rootKey\userPrefix\... if userPrefix is not NULL) into path, which
1650  * is assumed to be MAX_PATH WCHARs in length.
1651  * If it exists, expands the value and writes the expanded value to
1652  * rootKey\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
1653  * Returns successful error code if the value was retrieved from the registry,
1654  * and a failure otherwise.
1655  */
1656 #ifndef __REACTOS__
1657 static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, LPCWSTR userPrefix,
1658 #else
1659 static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, HANDLE hToken, LPCWSTR userPrefix,
1660 #endif
1662 {
1663  HRESULT hr;
1664  WCHAR shellFolderPath[MAX_PATH], userShellFolderPath[MAX_PATH];
1665  LPCWSTR pShellFolderPath, pUserShellFolderPath;
1666  HKEY userShellFolderKey, shellFolderKey;
1667  DWORD dwType, dwPathLen;
1668 
1669  TRACE("%p,%s,%s,%p\n",rootKey, debugstr_w(userPrefix), debugstr_w(value),
1670  path);
1671 
1672  if (userPrefix)
1673  {
1674  strcpyW(shellFolderPath, userPrefix);
1675  PathAddBackslashW(shellFolderPath);
1676  strcatW(shellFolderPath, szSHFolders);
1677  pShellFolderPath = shellFolderPath;
1678  strcpyW(userShellFolderPath, userPrefix);
1679  PathAddBackslashW(userShellFolderPath);
1680  strcatW(userShellFolderPath, szSHUserFolders);
1681  pUserShellFolderPath = userShellFolderPath;
1682  }
1683  else
1684  {
1685  pUserShellFolderPath = szSHUserFolders;
1686  pShellFolderPath = szSHFolders;
1687  }
1688 
1689  if (RegCreateKeyW(rootKey, pShellFolderPath, &shellFolderKey))
1690  {
1691  TRACE("Failed to create %s\n", debugstr_w(pShellFolderPath));
1692  return E_FAIL;
1693  }
1694  if (RegCreateKeyW(rootKey, pUserShellFolderPath, &userShellFolderKey))
1695  {
1696  TRACE("Failed to create %s\n",
1697  debugstr_w(pUserShellFolderPath));
1698  RegCloseKey(shellFolderKey);
1699  return E_FAIL;
1700  }
1701 
1702  dwPathLen = MAX_PATH * sizeof(WCHAR);
1703  if (!RegQueryValueExW(userShellFolderKey, value, NULL, &dwType,
1704  (LPBYTE)path, &dwPathLen) && (dwType == REG_EXPAND_SZ || dwType == REG_SZ))
1705  {
1706  LONG ret;
1707 
1708  path[dwPathLen / sizeof(WCHAR)] = '\0';
1709  if (dwType == REG_EXPAND_SZ && path[0] == '%')
1710  {
1711  WCHAR szTemp[MAX_PATH];
1712 
1713 #ifndef __REACTOS__
1715 #else
1716  hr = _SHExpandEnvironmentStrings(hToken, path, szTemp, _countof(szTemp));
1717  if (FAILED(hr))
1718  goto end;
1719 #endif
1720  lstrcpynW(path, szTemp, MAX_PATH);
1721  }
1722  ret = RegSetValueExW(shellFolderKey, value, 0, REG_SZ, (LPBYTE)path,
1723  (strlenW(path) + 1) * sizeof(WCHAR));
1724  if (ret != ERROR_SUCCESS)
1726  else
1727  hr = S_OK;
1728  }
1729  else
1730  hr = E_FAIL;
1731 #ifdef __REACTOS__
1732 end:
1733 #endif
1734  RegCloseKey(shellFolderKey);
1735  RegCloseKey(userShellFolderKey);
1736  TRACE("returning 0x%08x\n", hr);
1737  return hr;
1738 }
1739 
1741 {
1742  BOOL result;
1743  if (!hToken)
1744  {
1746  result = GetUserProfileDirectoryW(hToken, szPath, lpcchPath);
1747  CloseHandle(hToken);
1748  }
1749  else if ((INT) hToken == -1)
1750  {
1752  }
1753  else
1754  {
1755  result = GetUserProfileDirectoryW(hToken, szPath, lpcchPath);
1756  }
1757  TRACE("_SHGetUserProfileDirectoryW returning %S\n", szPath);
1758  return result;
1759 }
1760 
1761 /* Gets a 'semi-expanded' default value of the CSIDL with index folder into
1762  * pszPath, based on the entries in CSIDL_Data. By semi-expanded, I mean:
1763  * - The entry's szDefaultPath may be either a string value or an integer
1764  * resource identifier. In the latter case, the string value of the resource
1765  * is written.
1766  * - Depending on the entry's type, the path may begin with an (unexpanded)
1767  * environment variable name. The caller is responsible for expanding
1768  * environment strings if so desired.
1769  * The types that are prepended with environment variables are:
1770  * CSIDL_Type_User: %USERPROFILE%
1771  * CSIDL_Type_AllUsers: %ALLUSERSPROFILE%
1772  * CSIDL_Type_CurrVer: %SystemDrive%
1773  * (Others might make sense too, but as yet are unneeded.)
1774  */
1775 #ifndef __REACTOS__
1777 #else
1778 static HRESULT _SHGetDefaultValue(HANDLE hToken, BYTE folder, LPWSTR pszPath)
1779 #endif
1780 {
1781  HRESULT hr;
1782  WCHAR resourcePath[MAX_PATH];
1783 #ifdef __REACTOS__
1784  NT_PRODUCT_TYPE ProductType;
1785 #endif
1786 
1787  TRACE("0x%02x,%p\n", folder, pszPath);
1788 
1789  if (folder >= ARRAY_SIZE(CSIDL_Data))
1790  return E_INVALIDARG;
1791 
1792  if (!pszPath)
1793  return E_INVALIDARG;
1794 
1795 #ifdef __REACTOS__
1796  if (hToken != NULL && hToken != (HANDLE)-1)
1797  {
1798  FIXME("unsupported for user other than current or default\n");
1799  }
1800 #endif
1801 
1802  if (!is_win64)
1803  {
1804  BOOL is_wow64;
1805 
1806  switch (folder)
1807  {
1808  case CSIDL_PROGRAM_FILES:
1812  break;
1817  break;
1818  }
1819  }
1820 
1821  switch (CSIDL_Data[folder].type)
1822  {
1823  case CSIDL_Type_User:
1824  strcpyW(pszPath, L"%USERPROFILE%");
1825  break;
1826 #ifdef __REACTOS__
1827  case CSIDL_Type_InMyDocuments:
1828  strcpyW(pszPath, L"%USERPROFILE%");
1829  if (DoGetProductType(&ProductType) && ProductType == NtProductWinNt)
1830  {
1831  if (IS_INTRESOURCE(CSIDL_Data[CSIDL_MYDOCUMENTS].szDefaultPath))
1832  {
1833  WCHAR szItem[MAX_PATH];
1835  LOWORD(CSIDL_Data[CSIDL_MYDOCUMENTS].szDefaultPath),
1836  szItem, ARRAY_SIZE(szItem));
1837  PathAppendW(pszPath, szItem);
1838  }
1839  else
1840  {
1841  PathAppendW(pszPath, CSIDL_Data[CSIDL_MYDOCUMENTS].szDefaultPath);
1842  }
1843  }
1844  break;
1845 #endif
1846  case CSIDL_Type_AllUsers:
1847 #ifndef __REACTOS__
1848  strcpyW(pszPath, L"%PUBLIC%");
1849 #else
1850  strcpyW(pszPath, L"%ALLUSERSPROFILE%");
1851 #endif
1852  break;
1853  case CSIDL_Type_CurrVer:
1854  strcpyW(pszPath, L"%SystemDrive%");
1855  break;
1856  default:
1857  ; /* no corresponding env. var, do nothing */
1858  }
1859 
1860  hr = S_OK;
1861  if (CSIDL_Data[folder].szDefaultPath)
1862  {
1863  if (IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath))
1864  {
1866  LOWORD(CSIDL_Data[folder].szDefaultPath), resourcePath, MAX_PATH))
1867  {
1868  PathAppendW(pszPath, resourcePath);
1869  }
1870  else
1871  {
1872  ERR("(%d,%s), LoadString failed, missing translation?\n", folder,
1873  debugstr_w(pszPath));
1874  hr = E_FAIL;
1875  }
1876  }
1877  else
1878  {
1879  PathAppendW(pszPath, CSIDL_Data[folder].szDefaultPath);
1880  }
1881  }
1882  TRACE("returning 0x%08x\n", hr);
1883  return hr;
1884 }
1885 
1886 /* Gets the (unexpanded) value of the folder with index folder into pszPath.
1887  * The folder's type is assumed to be CSIDL_Type_CurrVer. Its default value
1888  * can be overridden in the HKLM\\Software\\Microsoft\\Windows\\CurrentVersion key.
1889  * If dwFlags has SHGFP_TYPE_DEFAULT set or if the value isn't overridden in
1890  * the registry, uses _SHGetDefaultValue to get the value.
1891  */
1893  LPWSTR pszPath)
1894 {
1895  HRESULT hr;
1896 
1897  TRACE("0x%08x,0x%02x,%p\n", dwFlags, folder, pszPath);
1898 
1899  if (folder >= ARRAY_SIZE(CSIDL_Data))
1900  return E_INVALIDARG;
1902  return E_INVALIDARG;
1903  if (!pszPath)
1904  return E_INVALIDARG;
1905 
1907 #ifndef __REACTOS__
1908  hr = _SHGetDefaultValue(folder, pszPath);
1909 #else
1910  hr = _SHGetDefaultValue(NULL, folder, pszPath);
1911 #endif
1912  else
1913  {
1914  HKEY hKey;
1915 
1916  if (RegCreateKeyW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion", &hKey))
1917  hr = E_FAIL;
1918  else
1919  {
1920  DWORD dwType, dwPathLen = MAX_PATH * sizeof(WCHAR);
1921 
1922  if (RegQueryValueExW(hKey, CSIDL_Data[folder].szValueName, NULL,
1923  &dwType, (LPBYTE)pszPath, &dwPathLen) ||
1924  (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
1925  {
1926 #ifndef __REACTOS__
1927  hr = _SHGetDefaultValue(folder, pszPath);
1928 #else
1929  hr = _SHGetDefaultValue(NULL, folder, pszPath);
1930 #endif
1931  dwType = REG_EXPAND_SZ;
1932  switch (folder)
1933  {
1936  /* these two should never be set on 32-bit setups */
1937  if (!is_win64)
1938  {
1939  BOOL is_wow64;
1941  if (!is_wow64) break;
1942  }
1943  /* fall through */
1944  default:
1945  RegSetValueExW(hKey, CSIDL_Data[folder].szValueName, 0, dwType,
1946  (LPBYTE)pszPath, (strlenW(pszPath)+1)*sizeof(WCHAR));
1947  }
1948  }
1949  else
1950  {
1951  pszPath[dwPathLen / sizeof(WCHAR)] = '\0';
1952  hr = S_OK;
1953  }
1954  RegCloseKey(hKey);
1955  }
1956  }
1957  TRACE("returning 0x%08x (output path is %s)\n", hr, debugstr_w(pszPath));
1958  return hr;
1959 }
1960 
1962 {
1963  char InfoBuffer[64];
1964  PTOKEN_USER UserInfo;
1965  DWORD InfoSize;
1966  LPWSTR SidStr;
1967 
1968  UserInfo = (PTOKEN_USER) InfoBuffer;
1969  if (! GetTokenInformation(Token, TokenUser, InfoBuffer, sizeof(InfoBuffer),
1970  &InfoSize))
1971  {
1973  return NULL;
1974  UserInfo = HeapAlloc(GetProcessHeap(), 0, InfoSize);
1975  if (UserInfo == NULL)
1976  return NULL;
1977  if (! GetTokenInformation(Token, TokenUser, UserInfo, InfoSize,
1978  &InfoSize))
1979  {
1980  HeapFree(GetProcessHeap(), 0, UserInfo);
1981  return NULL;
1982  }
1983  }
1984 
1985  if (! ConvertSidToStringSidW(UserInfo->User.Sid, &SidStr))
1986  SidStr = NULL;
1987 
1988  if (UserInfo != (PTOKEN_USER) InfoBuffer)
1989  HeapFree(GetProcessHeap(), 0, UserInfo);
1990 
1991  return SidStr;
1992 }
1993 
1994 /* Gets the user's path (unexpanded) for the CSIDL with index folder:
1995  * If SHGFP_TYPE_DEFAULT is set, calls _SHGetDefaultValue for it. Otherwise
1996  * calls _SHGetUserShellFolderPath for it. Where it looks depends on hToken:
1997  * - if hToken is -1, looks in HKEY_USERS\.Default
1998  * - otherwise looks first in HKEY_CURRENT_USER, followed by HKEY_LOCAL_MACHINE
1999  * if HKEY_CURRENT_USER doesn't contain any entries. If both fail, finally
2000  * calls _SHGetDefaultValue for it.
2001  */
2003  LPWSTR pszPath)
2004 {
2005  const WCHAR *szValueName;
2006  WCHAR buffer[40];
2007  HRESULT hr;
2008 
2009  TRACE("%p,0x%08x,0x%02x,%p\n", hToken, dwFlags, folder, pszPath);
2010 
2011  if (folder >= ARRAY_SIZE(CSIDL_Data))
2012  return E_INVALIDARG;
2013 #ifdef __REACTOS__
2015  CSIDL_Data[folder].type != CSIDL_Type_InMyDocuments)
2016 #else
2018 #endif
2019  {
2020  return E_INVALIDARG;
2021  }
2022  if (!pszPath)
2023  return E_INVALIDARG;
2024 
2026  {
2027 #ifndef __REACTOS__
2028  hr = _SHGetDefaultValue(folder, pszPath);
2029 #else
2030  hr = _SHGetDefaultValue(hToken, folder, pszPath);
2031 #endif
2032  }
2033  else
2034  {
2035  static const WCHAR DefaultW[] = L".Default";
2036  LPCWSTR userPrefix = NULL;
2037  HKEY hRootKey;
2038 
2039  if (hToken == (HANDLE)-1)
2040  {
2041  hRootKey = HKEY_USERS;
2042  userPrefix = DefaultW;
2043  }
2044  else if (hToken == NULL)
2045  hRootKey = HKEY_CURRENT_USER;
2046  else
2047  {
2048  hRootKey = HKEY_USERS;
2049  userPrefix = _GetUserSidStringFromToken(hToken);
2050  if (userPrefix == NULL)
2051  {
2052  hr = E_FAIL;
2053  goto error;
2054  }
2055  }
2056 
2057  /* For CSIDL_Type_User we also use the GUID if no szValueName is provided */
2058  szValueName = CSIDL_Data[folder].szValueName;
2059  if (!szValueName)
2060  {
2062  szValueName = &buffer[0];
2063  }
2064 
2065 #ifndef __REACTOS__
2066  hr = _SHGetUserShellFolderPath(hRootKey, userPrefix, szValueName, pszPath);
2067  if (FAILED(hr) && hRootKey != HKEY_LOCAL_MACHINE)
2068  hr = _SHGetUserShellFolderPath(HKEY_LOCAL_MACHINE, NULL, szValueName, pszPath);
2069  if (FAILED(hr))
2070  hr = _SHGetDefaultValue(folder, pszPath);
2071 #else
2072  hr = _SHGetUserShellFolderPath(hRootKey, hToken, userPrefix, szValueName, pszPath);
2073  if (FAILED(hr) && hRootKey != HKEY_LOCAL_MACHINE)
2074  hr = _SHGetUserShellFolderPath(HKEY_LOCAL_MACHINE, hToken, NULL, szValueName, pszPath);
2075  if (FAILED(hr))
2076  hr = _SHGetDefaultValue(hToken, folder, pszPath);
2077 #endif
2078  if (userPrefix != NULL && userPrefix != DefaultW)
2079  LocalFree((HLOCAL) userPrefix);
2080  }
2081 error:
2082  TRACE("returning 0x%08x (output path is %s)\n", hr, debugstr_w(pszPath));
2083  return hr;
2084 }
2085 
2086 /* Gets the (unexpanded) path for the CSIDL with index folder. If dwFlags has
2087  * SHGFP_TYPE_DEFAULT set, calls _SHGetDefaultValue. Otherwise calls
2088  * _SHGetUserShellFolderPath for it, looking only in HKEY_LOCAL_MACHINE.
2089  * If this fails, falls back to _SHGetDefaultValue.
2090  */
2092  LPWSTR pszPath)
2093 {
2094  HRESULT hr;
2095 
2096  TRACE("0x%08x,0x%02x,%p\n", dwFlags, folder, pszPath);
2097 
2098  if (folder >= ARRAY_SIZE(CSIDL_Data))
2099  return E_INVALIDARG;
2101  return E_INVALIDARG;
2102  if (!pszPath)
2103  return E_INVALIDARG;
2104 
2106 #ifndef __REACTOS__
2107  hr = _SHGetDefaultValue(folder, pszPath);
2108 #else
2109  hr = _SHGetDefaultValue(NULL, folder, pszPath);
2110 #endif
2111  else
2112  {
2113 #ifndef __REACTOS__
2115 #else
2117 #endif
2118  CSIDL_Data[folder].szValueName, pszPath);
2119  if (FAILED(hr))
2120 #ifndef __REACTOS__
2121  hr = _SHGetDefaultValue(folder, pszPath);
2122 #else
2123  hr = _SHGetDefaultValue(NULL, folder, pszPath);
2124 #endif
2125  }
2126  TRACE("returning 0x%08x (output path is %s)\n", hr, debugstr_w(pszPath));
2127  return hr;
2128 }
2129 
2130 #ifndef __REACTOS__
2132 {
2133  LONG lRet;
2134  DWORD disp;
2135 
2136  lRet = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList", 0, NULL, 0,
2137  KEY_ALL_ACCESS, NULL, pKey, &disp);
2138  return HRESULT_FROM_WIN32(lRet);
2139 }
2140 
2141 /* Reads the value named szValueName from the key profilesKey (assumed to be
2142  * opened by _SHOpenProfilesKey) into szValue, which is assumed to be MAX_PATH
2143  * WCHARs in length. If it doesn't exist, returns szDefault (and saves
2144  * szDefault to the registry).
2145  */
2146 static HRESULT _SHGetProfilesValue(HKEY profilesKey, LPCWSTR szValueName,
2147  LPWSTR szValue, LPCWSTR szDefault)
2148 {
2149  HRESULT hr;
2150  DWORD type, dwPathLen = MAX_PATH * sizeof(WCHAR);
2151  LONG lRet;
2152 
2153  TRACE("%p,%s,%p,%s\n", profilesKey, debugstr_w(szValueName), szValue,
2154  debugstr_w(szDefault));
2155  lRet = RegQueryValueExW(profilesKey, szValueName, NULL, &type,
2156  (LPBYTE)szValue, &dwPathLen);
2157  if (!lRet && (type == REG_SZ || type == REG_EXPAND_SZ) && dwPathLen
2158  && *szValue)
2159  {
2160  dwPathLen /= sizeof(WCHAR);
2161  szValue[dwPathLen] = '\0';
2162  hr = S_OK;
2163  }
2164  else
2165  {
2166  /* Missing or invalid value, set a default */
2167  lstrcpynW(szValue, szDefault, MAX_PATH);
2168  TRACE("Setting missing value %s to %s\n", debugstr_w(szValueName),
2169  debugstr_w(szValue));
2170  lRet = RegSetValueExW(profilesKey, szValueName, 0, REG_EXPAND_SZ,
2171  (LPBYTE)szValue,
2172  (strlenW(szValue) + 1) * sizeof(WCHAR));
2173  if (lRet)
2174  hr = HRESULT_FROM_WIN32(lRet);
2175  else
2176  hr = S_OK;
2177  }
2178  TRACE("returning 0x%08x (output value is %s)\n", hr, debugstr_w(szValue));
2179  return hr;
2180 }
2181 #endif
2182 
2183 /* Attempts to expand environment variables from szSrc into szDest, which is
2184  * assumed to be MAX_PATH characters in length. Before referring to the
2185  * environment, handles a few variables directly, because the environment
2186  * variables may not be set when this is called (as during Wine's installation
2187  * when default values are being written to the registry).
2188  * The directly handled environment variables, and their source, are:
2189  * - ALLUSERSPROFILE, USERPROFILE: reads from the registry
2190  * - SystemDrive: uses GetSystemDirectoryW and uses the drive portion of its
2191  * path
2192  * If one of the directly handled environment variables is expanded, only
2193  * expands a single variable, and only in the beginning of szSrc.
2194  */
2195 #ifndef __REACTOS__
2197 #else
2198 static HRESULT _SHExpandEnvironmentStrings(HANDLE hToken, LPCWSTR szSrc, LPWSTR szDest, DWORD cchDest)
2199 #endif
2200 {
2201  HRESULT hr;
2202 #ifndef __REACTOS__
2203  WCHAR szTemp[MAX_PATH], szProfilesPrefix[MAX_PATH] = { 0 };
2204  HKEY key = NULL;
2205 #else
2206  WCHAR szTemp[MAX_PATH];
2207 #endif
2208 
2209  TRACE("%s, %p\n", debugstr_w(szSrc), szDest);
2210 
2211  if (!szSrc || !szDest) return E_INVALIDARG;
2212 
2213  /* short-circuit if there's nothing to expand */
2214  if (szSrc[0] != '%')
2215  {
2216  strcpyW(szDest, szSrc);
2217  hr = S_OK;
2218  goto end;
2219  }
2220 #ifndef __REACTOS__
2221  /* Get the profile prefix, we'll probably be needing it */
2223  if (SUCCEEDED(hr))
2224  {
2225  WCHAR def_val[MAX_PATH];
2226 
2227  /* get the system drive */
2228  GetSystemDirectoryW(def_val, MAX_PATH);
2229  strcpyW( def_val + 3, L"Users" );
2230 
2231  hr = _SHGetProfilesValue(key, L"ProfilesDirectory", szProfilesPrefix, def_val );
2232  }
2233 #else
2234  hr = S_OK;
2235 #endif
2236 
2237  *szDest = 0;
2238  strcpyW(szTemp, szSrc);
2239  while (SUCCEEDED(hr) && szTemp[0] == '%')
2240  {
2241  if (!strncmpiW(szTemp, L"%ALLUSERSPROFILE%", ARRAY_SIZE(L"%ALLUSERSPROFILE%")-1))
2242  {
2243 #ifndef __REACTOS__
2245 
2246  strcpyW(szDest, szProfilesPrefix);
2247  hr = _SHGetProfilesValue(key, L"AllUsersProfile", szAllUsers, L"Public");
2248  PathAppendW(szDest, szAllUsers);
2249 #else
2250  DWORD cchSize = cchDest;
2251  if (!GetAllUsersProfileDirectoryW(szDest, &cchSize))
2252  goto fallback_expand;
2253 #endif
2254  PathAppendW(szDest, szTemp + ARRAY_SIZE(L"%ALLUSERSPROFILE%")-1);
2255  }
2256 #ifndef __REACTOS__
2257  else if (!strncmpiW(szTemp, L"%PUBLIC%", ARRAY_SIZE(L"%PUBLIC%")-1))
2258  {
2259  WCHAR szAllUsers[MAX_PATH], def_val[MAX_PATH];
2260 
2261  GetSystemDirectoryW(def_val, MAX_PATH);
2262  strcpyW( def_val + 3, L"Users\\Public" );
2263 
2264  hr = _SHGetProfilesValue(key, L"Public", szAllUsers, def_val);
2265  PathAppendW(szDest, szAllUsers);
2266  PathAppendW(szDest, szTemp + ARRAY_SIZE(L"%PUBLIC%")-1);
2267  }
2268 #endif
2269  else if (!strncmpiW(szTemp, L"%USERPROFILE%", ARRAY_SIZE(L"%USERPROFILE%")-1))
2270  {
2271 #ifndef __REACTOS__
2273  DWORD userLen = MAX_PATH;
2274 
2275  strcpyW(szDest, szProfilesPrefix);
2276  GetUserNameW(userName, &userLen);
2277  PathAppendW(szDest, userName);
2278 #else
2279  DWORD cchSize = cchDest;
2280  if (!_SHGetUserProfileDirectoryW(hToken, szDest, &cchSize))
2281  goto fallback_expand;
2282 #endif
2283  PathAppendW(szDest, szTemp + ARRAY_SIZE(L"%USERPROFILE%")-1);
2284  }
2285  else if (!strncmpiW(szTemp, L"%SystemDrive%", ARRAY_SIZE(L"%SystemDrive%")-1))
2286  {
2287 #ifndef __REACTOS__
2288  GetSystemDirectoryW(szDest, MAX_PATH);
2289 #else
2290  if (!GetSystemDirectoryW(szDest, cchDest))
2291  goto fallback_expand;
2292 #endif
2293  strcpyW(szDest + 3, szTemp + ARRAY_SIZE(L"%SystemDrive%")-1 + 1);
2294  }
2295  else
2296 #ifdef __REACTOS__
2297 fallback_expand:
2298 #endif
2299  {
2300 #ifndef __REACTOS__
2301  DWORD ret = ExpandEnvironmentStringsW(szTemp, szDest, MAX_PATH);
2302 #else
2303  DWORD ret = SHExpandEnvironmentStringsForUserW(hToken, szTemp, szDest, cchDest);
2304 #endif
2305 
2306 #ifndef __REACTOS__
2307  if (ret > MAX_PATH)
2308 #else
2309  if (ret > cchDest)
2310 #endif
2312  else if (ret == 0)
2314  else if (!strcmpW( szTemp, szDest )) break; /* nothing expanded */
2315  }
2316  if (SUCCEEDED(hr)) strcpyW(szTemp, szDest);
2317  }
2318 end:
2319 #ifndef __REACTOS__
2320  if (key)
2321  RegCloseKey(key);
2322 #endif
2323  TRACE("returning 0x%08x (input was %s, output is %s)\n", hr,
2324  debugstr_w(szSrc), debugstr_w(szDest));
2325  return hr;
2326 }
2327 
2328 /*************************************************************************
2329  * SHGetFolderPathW [SHELL32.@]
2330  *
2331  * Convert nFolder to path.
2332  *
2333  * RETURNS
2334  * Success: S_OK
2335  * Failure: standard HRESULT error codes.
2336  *
2337  * NOTES
2338  * Most values can be overridden in either
2339  * HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
2340  * or in the same location in HKLM.
2341  * The "Shell Folders" registry key was used in NT4 and earlier systems.
2342  * Beginning with Windows 2000, the "User Shell Folders" key is used, so
2343  * changes made to it are made to the former key too. This synchronization is
2344  * done on-demand: not until someone requests the value of one of these paths
2345  * (by calling one of the SHGet functions) is the value synchronized.
2346  * Furthermore, the HKCU paths take precedence over the HKLM paths.
2347  */
2349  HWND hwndOwner, /* [I] owner window */
2350  int nFolder, /* [I] CSIDL identifying the folder */
2351  HANDLE hToken, /* [I] access token */
2352  DWORD dwFlags, /* [I] which path to return */
2353  LPWSTR pszPath) /* [O] converted path */
2354 {
2355  HRESULT hr = SHGetFolderPathAndSubDirW(hwndOwner, nFolder, hToken, dwFlags, NULL, pszPath);
2358  return hr;
2359 }
2360 
2362  HWND hwndOwner, /* [I] owner window */
2363  int nFolder, /* [I] CSIDL identifying the folder */
2364  HANDLE hToken, /* [I] access token */
2365  DWORD dwFlags, /* [I] which path to return */
2366  LPCSTR pszSubPath, /* [I] sub directory of the specified folder */
2367  LPSTR pszPath) /* [O] converted path */
2368 {
2369  int length;
2370  HRESULT hr = S_OK;
2371  LPWSTR pszSubPathW = NULL;
2372  LPWSTR pszPathW = NULL;
2373 
2374  TRACE("%p,%#x,%p,%#x,%s,%p\n", hwndOwner, nFolder, hToken, dwFlags, debugstr_a(pszSubPath), pszPath);
2375 
2376  if(pszPath) {
2377  pszPathW = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
2378  if(!pszPathW) {
2380  goto cleanup;
2381  }
2382  }
2383  TRACE("%08x,%08x,%s\n",nFolder, dwFlags, debugstr_w(pszSubPathW));
2384 
2385  /* SHGetFolderPathAndSubDirW does not distinguish if pszSubPath isn't
2386  * set (null), or an empty string.therefore call it without the parameter set
2387  * if pszSubPath is an empty string
2388  */
2389  if (pszSubPath && pszSubPath[0]) {
2390  length = MultiByteToWideChar(CP_ACP, 0, pszSubPath, -1, NULL, 0);
2391  pszSubPathW = HeapAlloc(GetProcessHeap(), 0, length * sizeof(WCHAR));
2392  if(!pszSubPathW) {
2394  goto cleanup;
2395  }
2396  MultiByteToWideChar(CP_ACP, 0, pszSubPath, -1, pszSubPathW, length);
2397  }
2398 
2399  hr = SHGetFolderPathAndSubDirW(hwndOwner, nFolder, hToken, dwFlags, pszSubPathW, pszPathW);
2400 
2401  if (SUCCEEDED(hr) && pszPath)
2402  WideCharToMultiByte(CP_ACP, 0, pszPathW, -1, pszPath, MAX_PATH, NULL, NULL);
2403 
2404 cleanup:
2405  HeapFree(GetProcessHeap(), 0, pszPathW);
2406  HeapFree(GetProcessHeap(), 0, pszSubPathW);
2407  return hr;
2408 }
2409 
2410 /*************************************************************************
2411  * SHGetFolderPathAndSubDirW [SHELL32.@]
2412  */
2414  HWND hwndOwner, /* [I] owner window */
2415  int nFolder, /* [I] CSIDL identifying the folder */
2416  HANDLE hToken, /* [I] access token */
2417  DWORD dwFlags, /* [I] which path to return */
2418  LPCWSTR pszSubPath,/* [I] sub directory of the specified folder */
2419  LPWSTR pszPath) /* [O] converted path */
2420 {
2421  HRESULT hr;
2422  WCHAR szBuildPath[MAX_PATH], szTemp[MAX_PATH];
2424  CSIDL_Type type;
2425  int ret;
2426 
2427  TRACE("%p,%#x,%p,%#x,%s,%p\n", hwndOwner, nFolder, hToken, dwFlags, debugstr_w(pszSubPath), pszPath);
2428 
2429  /* Windows always NULL-terminates the resulting path regardless of success
2430  * or failure, so do so first
2431  */
2432  if (pszPath)
2433  *pszPath = '\0';
2434 
2435  if (folder >= ARRAY_SIZE(CSIDL_Data))
2436  return E_INVALIDARG;
2438  return E_INVALIDARG;
2439  szTemp[0] = 0;
2441  switch (type)
2442  {
2443  case CSIDL_Type_Disallowed:
2444  hr = E_INVALIDARG;
2445  break;
2447  hr = S_FALSE;
2448  break;
2450  GetWindowsDirectoryW(szTemp, MAX_PATH);
2451  if (CSIDL_Data[folder].szDefaultPath &&
2452  !IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath) &&
2453  *CSIDL_Data[folder].szDefaultPath)
2454  {
2455  PathAddBackslashW(szTemp);
2456  strcatW(szTemp, CSIDL_Data[folder].szDefaultPath);
2457  }
2458  hr = S_OK;
2459  break;
2460  case CSIDL_Type_SystemPath:
2461  GetSystemDirectoryW(szTemp, MAX_PATH);
2462  if (CSIDL_Data[folder].szDefaultPath &&
2463  !IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath) &&
2464  *CSIDL_Data[folder].szDefaultPath)
2465  {
2466  PathAddBackslashW(szTemp);
2467  strcatW(szTemp, CSIDL_Data[folder].szDefaultPath);
2468  }
2469  hr = S_OK;
2470  break;
2473  if (CSIDL_Data[folder].szDefaultPath &&
2474  !IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath) &&
2475  *CSIDL_Data[folder].szDefaultPath)
2476  {
2477  PathAddBackslashW(szTemp);
2478  strcatW(szTemp, CSIDL_Data[folder].szDefaultPath);
2479  }
2480  hr = S_OK;
2481  break;
2482  case CSIDL_Type_CurrVer:
2484  break;
2485  case CSIDL_Type_User:
2486 #ifdef __REACTOS__
2487  case CSIDL_Type_InMyDocuments:
2488 #endif
2489  hr = _SHGetUserProfilePath(hToken, dwFlags, folder, szTemp);
2490  break;
2491  case CSIDL_Type_AllUsers:
2493  break;
2494  default:
2495  FIXME("bogus type %d, please fix\n", type);
2496  hr = E_INVALIDARG;
2497  break;
2498  }
2499 
2500  /* Expand environment strings if necessary */
2501  if (*szTemp == '%')
2502 #ifndef __REACTOS__
2503  hr = _SHExpandEnvironmentStrings(szTemp, szBuildPath);
2504 #else
2505  hr = _SHExpandEnvironmentStrings(hToken, szTemp, szBuildPath, _countof(szBuildPath));
2506 #endif
2507  else
2508  strcpyW(szBuildPath, szTemp);
2509 
2510  if (FAILED(hr)) goto end;
2511 
2512  if(pszSubPath) {
2513  /* make sure the new path does not exceed the buffer length
2514  * and remember to backslash and terminate it */
2515  if(MAX_PATH < (lstrlenW(szBuildPath) + lstrlenW(pszSubPath) + 2)) {
2517  goto end;
2518  }
2519  PathAppendW(szBuildPath, pszSubPath);
2520  PathRemoveBackslashW(szBuildPath);
2521  }
2522  /* Copy the path if it's available before we might return */
2523  if (SUCCEEDED(hr) && pszPath)
2524  strcpyW(pszPath, szBuildPath);
2525 
2526  /* if we don't care about existing directories we are ready */
2527  if(nFolder & CSIDL_FLAG_DONT_VERIFY) goto end;
2528 
2529  if (PathFileExistsW(szBuildPath)) goto end;
2530 
2531  /* not existing but we are not allowed to create it. The return value
2532  * is verified against shell32 version 6.0.
2533  */
2534  if (!(nFolder & CSIDL_FLAG_CREATE))
2535  {
2537  goto end;
2538  }
2539 
2540  /* create directory/directories */
2541  ret = SHCreateDirectoryExW(hwndOwner, szBuildPath, NULL);
2542  if (ret && ret != ERROR_ALREADY_EXISTS)
2543  {
2544  ERR("Failed to create directory %s.\n", debugstr_w(szBuildPath));
2545  hr = E_FAIL;
2546  goto end;
2547  }
2548 
2549  TRACE("Created missing system directory %s\n", debugstr_w(szBuildPath));
2550 
2551 end:
2552 #ifdef __REACTOS__
2553  /* create desktop.ini for custom icon */
2554  if ((nFolder & CSIDL_FLAG_CREATE) &&
2555  CSIDL_Data[folder].nShell32IconIndex)
2556  {
2557  WCHAR szIconLocation[MAX_PATH];
2559 
2560  /* make the directory a read-only folder */
2561  dwAttributes = GetFileAttributesW(szBuildPath);
2563  SetFileAttributesW(szBuildPath, dwAttributes);
2564 
2565  /* build the desktop.ini file path */
2566  PathAppendW(szBuildPath, L"desktop.ini");
2567 
2568  /* build the icon location */
2569  StringCchPrintfW(szIconLocation, _countof(szIconLocation),
2570  L"%%SystemRoot%%\\system32\\shell32.dll,%d",
2571  CSIDL_Data[folder].nShell32IconIndex);
2572 
2573  /* write desktop.ini */
2574  WritePrivateProfileStringW(L".ShellClassInfo", L"IconResource", szIconLocation, szBuildPath);
2575 
2576  /* flush! */
2577  WritePrivateProfileStringW(NULL, NULL, NULL, szBuildPath);
2578 
2579  /* make the desktop.ini a system and hidden file */
2580  dwAttributes = GetFileAttributesW(szBuildPath);
2582  SetFileAttributesW(szBuildPath, dwAttributes);
2583  }
2584 #endif
2585 
2586  TRACE("returning 0x%08x (final path is %s)\n", hr, debugstr_w(szBuildPath));
2587  return hr;
2588 }
2589 
2590 /*************************************************************************
2591  * SHGetFolderPathA [SHELL32.@]
2592  *
2593  * See SHGetFolderPathW.
2594  */
2596  HWND hwndOwner,
2597  int nFolder,
2598  HANDLE hToken,
2599  DWORD dwFlags,
2600  LPSTR pszPath)
2601 {
2602  WCHAR szTemp[MAX_PATH];
2603  HRESULT hr;
2604 
2605  TRACE("%p,%d,%p,%#x,%p\n", hwndOwner, nFolder, hToken, dwFlags, pszPath);
2606 
2607  if (pszPath)
2608  *pszPath = '\0';
2609  hr = SHGetFolderPathW(hwndOwner, nFolder, hToken, dwFlags, szTemp);
2610  if (SUCCEEDED(hr) && pszPath)
2611  WideCharToMultiByte(CP_ACP, 0, szTemp, -1, pszPath, MAX_PATH, NULL,
2612  NULL);
2613 
2614  return hr;
2615 }
2616 
2617 /* For each folder in folders, if its value has not been set in the registry,
2618  * calls _SHGetUserProfilePath or _SHGetAllUsersProfilePath (depending on the
2619  * folder's type) to get the unexpanded value first.
2620  * Writes the unexpanded value to User Shell Folders, and queries it with
2621  * SHGetFolderPathW to force the creation of the directory if it doesn't
2622  * already exist. SHGetFolderPathW also returns the expanded value, which
2623  * this then writes to Shell Folders.
2624  */
2625 static HRESULT _SHRegisterFolders(HKEY hRootKey, HANDLE hToken,
2626  LPCWSTR szUserShellFolderPath, LPCWSTR szShellFolderPath, const UINT folders[],
2627  UINT foldersLen)
2628 {
2629  const WCHAR *szValueName;
2630  WCHAR buffer[40];
2631  UINT i;
2632  WCHAR path[MAX_PATH];
2633  HRESULT hr = S_OK;
2634  HKEY hUserKey = NULL, hKey = NULL;
2635  DWORD dwType, dwPathLen;
2636  LONG ret;
2637 
2638  TRACE("%p,%p,%s,%p,%u\n", hRootKey, hToken,
2639  debugstr_w(szUserShellFolderPath), folders, foldersLen);
2640 
2641  ret = RegCreateKeyW(hRootKey, szUserShellFolderPath, &hUserKey);
2642  if (ret)
2644  else
2645  {
2646  ret = RegCreateKeyW(hRootKey, szShellFolderPath, &hKey);
2647  if (ret)
2649  }
2650  for (i = 0; SUCCEEDED(hr) && i < foldersLen; i++)
2651  {
2652  dwPathLen = MAX_PATH * sizeof(WCHAR);
2653 
2654  /* For CSIDL_Type_User we also use the GUID if no szValueName is provided */
2655  szValueName = CSIDL_Data[folders[i]].szValueName;
2656 #ifdef __REACTOS__
2657  if (!szValueName &&
2658  (CSIDL_Data[folders[i]].type == CSIDL_Type_User ||
2659  CSIDL_Data[folders[i]].type == CSIDL_Type_InMyDocuments))
2660 #else
2661  if (!szValueName && CSIDL_Data[folders[i]].type == CSIDL_Type_User)
2662 #endif
2663  {
2664  StringFromGUID2( CSIDL_Data[folders[i]].id, buffer, 39 );
2665  szValueName = &buffer[0];
2666  }
2667 
2668  if (!RegQueryValueExW(hUserKey, szValueName, NULL,
2669  &dwType, (LPBYTE)path, &dwPathLen) &&
2670  (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
2671  {
2672  hr = SHGetFolderPathW(NULL, folders[i] | CSIDL_FLAG_CREATE,
2673  hToken, SHGFP_TYPE_CURRENT, path);
2674  }
2675  else
2676  {
2677  *path = '\0';
2678 #ifdef __REACTOS__
2679  if (CSIDL_Data[folders[i]].type == CSIDL_Type_User ||
2680  CSIDL_Data[folders[i]].type == CSIDL_Type_InMyDocuments)
2681 #else
2682  if (CSIDL_Data[folders[i]].type == CSIDL_Type_User)
2683 #endif
2684  _SHGetUserProfilePath(hToken, SHGFP_TYPE_CURRENT, folders[i],
2685  path);
2686  else if (CSIDL_Data[folders[i]].type == CSIDL_Type_AllUsers)
2688  else if (CSIDL_Data[folders[i]].type == CSIDL_Type_WindowsPath)
2689  {
2691  if (CSIDL_Data[folders[i]].szDefaultPath &&
2692  !IS_INTRESOURCE(CSIDL_Data[folders[i]].szDefaultPath))
2693  {
2695  strcatW(path, CSIDL_Data[folders[i]].szDefaultPath);
2696  }
2697  }
2698  else
2699  hr = E_FAIL;
2700  if (*path)
2701  {
2702  ret = RegSetValueExW(hUserKey, szValueName, 0, REG_EXPAND_SZ,
2703  (LPBYTE)path, (strlenW(path) + 1) * sizeof(WCHAR));
2704  if (ret)
2706  else
2707  {
2708  hr = SHGetFolderPathW(NULL, folders[i] | CSIDL_FLAG_CREATE,
2709  hToken, SHGFP_TYPE_CURRENT, path);
2710  ret = RegSetValueExW(hKey, szValueName, 0, REG_SZ,
2711  (LPBYTE)path, (strlenW(path) + 1) * sizeof(WCHAR));
2712  if (ret)
2714  }
2715  }
2716  }
2717  }
2718  if (hUserKey)
2719  RegCloseKey(hUserKey);
2720  if (hKey)
2721  RegCloseKey(hKey);
2722 
2723  TRACE("returning 0x%08x\n", hr);
2724  return hr;
2725 }
2726 
2728 {
2729  static const UINT folders[] = {
2733  CSIDL_APPDATA,
2734  CSIDL_STARTUP,
2735  CSIDL_RECENT,
2736  CSIDL_SENDTO,
2738  CSIDL_MYMUSIC,
2739  CSIDL_MYVIDEO,
2741  CSIDL_NETHOOD,
2746  CSIDL_COOKIES,
2747  CSIDL_HISTORY,
2749  CSIDL_FONTS,
2751 /* Cannot use #if _WIN32_WINNT >= 0x0600 because _WIN32_WINNT == 0x0600 here. */
2752 #ifndef __REACTOS__
2755  CSIDL_LINKS,
2759 #endif
2760  };
2761  WCHAR userShellFolderPath[MAX_PATH], shellFolderPath[MAX_PATH];
2762  LPCWSTR pUserShellFolderPath, pShellFolderPath;
2763  HRESULT hr = S_OK;
2764  HKEY hRootKey;
2765  HANDLE hToken;
2766 
2767  TRACE("%s\n", bDefault ? "TRUE" : "FALSE");
2768  if (bDefault)
2769  {
2770  hToken = (HANDLE)-1;
2771  hRootKey = HKEY_USERS;
2772  strcpyW(userShellFolderPath, L".Default");
2773  PathAddBackslashW(userShellFolderPath);
2774  strcatW(userShellFolderPath, szSHUserFolders);
2775  pUserShellFolderPath = userShellFolderPath;
2776  strcpyW(shellFolderPath, L".Default");
2777  PathAddBackslashW(shellFolderPath);
2778  strcatW(shellFolderPath, szSHFolders);
2779  pShellFolderPath = shellFolderPath;
2780  }
2781  else
2782  {
2783  hToken = NULL;
2784  hRootKey = HKEY_CURRENT_USER;
2785  pUserShellFolderPath = szSHUserFolders;
2786  pShellFolderPath = szSHFolders;
2787  }
2788 
2789  hr = _SHRegisterFolders(hRootKey, hToken, pUserShellFolderPath,
2790  pShellFolderPath, folders, ARRAY_SIZE(folders));
2791  TRACE("returning 0x%08x\n", hr);
2792  return hr;
2793 }
2794 
2796 {
2797  static const UINT folders[] = {
2810  };
2811  HRESULT hr;
2812 
2813  TRACE("\n");
2815  szSHFolders, folders, ARRAY_SIZE(folders));
2816  TRACE("returning 0x%08x\n", hr);
2817  return hr;
2818 }
2819 
2820 /* Register the default values in the registry, as some apps seem to depend
2821  * on their presence. The set registered was taken from Windows XP.
2822  */
2824 {
2825  HRESULT hr;
2826 
2828  if (SUCCEEDED(hr))
2830  if (SUCCEEDED(hr))
2832  return hr;
2833 }
2834 
2835 /*************************************************************************
2836  * SHGetSpecialFolderPathA [SHELL32.@]
2837  */
2839  HWND hwndOwner,
2840  LPSTR szPath,
2841  int nFolder,
2842  BOOL bCreate)
2843 {
2844  return SHGetFolderPathA(hwndOwner, nFolder + (bCreate ? CSIDL_FLAG_CREATE : 0), NULL, 0,
2845  szPath) == S_OK;
2846 }
2847 
2848 /*************************************************************************
2849  * SHGetSpecialFolderPathW
2850  */
2852  HWND hwndOwner,
2853  LPWSTR szPath,
2854  int nFolder,
2855  BOOL bCreate)
2856 {
2857  return SHGetFolderPathW(hwndOwner, nFolder + (bCreate ? CSIDL_FLAG_CREATE : 0), NULL, 0,
2858  szPath) == S_OK;
2859 }
2860 
2861 /*************************************************************************
2862  * SHGetFolderLocation [SHELL32.@]
2863  *
2864  * Gets the folder locations from the registry and creates a pidl.
2865  *
2866  * PARAMS
2867  * hwndOwner [I]
2868  * nFolder [I] CSIDL_xxxxx
2869  * hToken [I] token representing user, or NULL for current user, or -1 for
2870  * default user
2871  * dwReserved [I] must be zero
2872  * ppidl [O] PIDL of a special folder
2873  *
2874  * RETURNS
2875  * Success: S_OK
2876  * Failure: Standard OLE-defined error result, S_FALSE or E_INVALIDARG
2877  *
2878  * NOTES
2879  * Creates missing reg keys and directories.
2880  * Mostly forwards to SHGetFolderPathW, but a few values of nFolder return
2881  * virtual folders that are handled here.
2882  */
2884  HWND hwndOwner,
2885  int nFolder,
2886  HANDLE hToken,
2887  DWORD dwReserved,
2888  LPITEMIDLIST *ppidl)
2889 {
2891 
2892  TRACE("%p 0x%08x %p 0x%08x %p\n",
2893  hwndOwner, nFolder, hToken, dwReserved, ppidl);
2894 
2895  if (!ppidl)
2896  return E_INVALIDARG;
2897  if (dwReserved)
2898  return E_INVALIDARG;
2899 
2900  /* The virtual folders' locations are not user-dependent */
2901  *ppidl = NULL;
2902  switch (nFolder & CSIDL_FOLDER_MASK)
2903  {
2904  case CSIDL_DESKTOP:
2905  *ppidl = _ILCreateDesktop();
2906  break;
2907 
2908  case CSIDL_PERSONAL:
2909  *ppidl = _ILCreateMyDocuments();
2910  break;
2911 
2912  case CSIDL_INTERNET:
2913  *ppidl = _ILCreateIExplore();
2914  break;
2915 
2916  case CSIDL_CONTROLS:
2917  *ppidl = _ILCreateControlPanel();
2918  break;
2919 
2920  case CSIDL_PRINTERS:
2921  *ppidl = _ILCreatePrinters();
2922  break;
2923 
2924  case CSIDL_BITBUCKET:
2925  *ppidl = _ILCreateBitBucket();
2926  break;
2927 
2928  case CSIDL_DRIVES:
2929  *ppidl = _ILCreateMyComputer();
2930  break;
2931 
2932  case CSIDL_NETWORK:
2933  *ppidl = _ILCreateNetwork();
2934  break;
2935 
2936  default:
2937  {
2939 
2940  hr = SHGetFolderPathW(hwndOwner, nFolder, hToken,
2942  if (SUCCEEDED(hr))
2943  {
2944  DWORD attributes=0;
2945 
2946  TRACE("Value=%s\n", debugstr_w(szPath));
2947  hr = SHILCreateFromPathW(szPath, ppidl, &attributes);
2948  }
2950  {
2951  /* unlike SHGetFolderPath, SHGetFolderLocation in shell32
2952  * version 6.0 returns E_FAIL for nonexistent paths
2953  */
2954  hr = E_FAIL;
2955  }
2956  }
2957  }
2958  if(*ppidl)
2959  hr = S_OK;
2960 
2961  TRACE("-- (new pidl %p)\n",*ppidl);
2962  return hr;
2963 }
2964 
2965 /*************************************************************************
2966  * SHGetSpecialFolderLocation [SHELL32.@]
2967  *
2968  * NOTES
2969  * In NT5, SHGetSpecialFolderLocation needs the <winntdir>/Recent
2970  * directory.
2971  */
2973  HWND hwndOwner,
2974  INT nFolder,
2975  LPITEMIDLIST * ppidl)
2976 {
2978 
2979  TRACE("(%p,0x%x,%p)\n", hwndOwner,nFolder,ppidl);
2980 
2981  if (!ppidl)
2982  return E_INVALIDARG;
2983 
2984  hr = SHGetFolderLocation(hwndOwner, nFolder, NULL, 0, ppidl);
2985  return hr;
2986 }
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1965
#define HKEY_USERS
Definition: winreg.h:13
static HRESULT _SHRegisterCommonShellFolders(void)
Definition: shellpath.c:2795
BOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:794
static LONG PathProcessCommandA(LPCSTR lpszPath, LPSTR lpszBuff, DWORD dwBuffSize, DWORD dwFlags)
Definition: shellpath.c:767
#define IDI_SHELL_RECENT_DOCUMENTS
Definition: shresdef.h:544
#define CSIDL_COOKIES
Definition: shlobj.h:2044
BOOL WINAPI GetDefaultUserProfileDirectoryW(_Out_opt_ LPWSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1443
BOOL WINAPI PathAppendAW(LPVOID lpszPath1, LPCVOID lpszPath2)
Definition: shellpath.c:238
BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
Definition: path.c:629
Definition: pdh_main.c:93
#define IDS_STARTMENU
Definition: shresdef.h:92
BOOL WINAPI PathFileExistsAndAttributesW(LPCWSTR lpszPath, DWORD *dwAttr)
Definition: path.c:1831
#define WHICH_DEFAULT
#define CloseHandle
Definition: compat.h:598
LPCWSTR szDefaultPath
Definition: shellpath.c:866
LPITEMIDLIST _ILCreateDesktop(void)
Definition: pidl.c:1602
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
Definition: fci.c:115
static LONG PathProcessCommandW(LPCWSTR lpszPath, LPWSTR lpszBuff, DWORD dwBuffSize, DWORD dwFlags)
Definition: shellpath.c:783
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
#define ERROR_SUCCESS
Definition: deptool.c:10
int WINAPI lstrcmpiA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:42
#define CSIDL_MYVIDEO
Definition: shlobj.h:2026
static const WCHAR szKnownFolderRedirections[]
Definition: shellpath.c:834
#define WideCharToMultiByte
Definition: compat.h:111
HRESULT hr
Definition: shlfolder.c:183
#define error(str)
Definition: mkdosfs.c:1605
GLuint64EXT * result
Definition: glext.h:11304
static HRESULT _SHExpandEnvironmentStrings(LPCWSTR szSrc, LPWSTR szDest)
Definition: shellpath.c:2196
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
LPITEMIDLIST _ILCreatePrinters(void)
Definition: pidl.c:1650
int WINAPI PathCleanupSpec(LPCWSTR lpszPathW, LPWSTR lpszFileW)
Definition: shellpath.c:529
#define CSIDL_FLAG_DONT_VERIFY
Definition: shlobj.h:2073
BOOL WINAPI GetUserProfileDirectoryW(_In_ HANDLE hToken, _Out_opt_ LPWSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1792
#define CSIDL_COMMON_DESKTOPDIRECTORY
Definition: shlobj.h:2036
#define CSIDL_MYPICTURES
Definition: shlobj.h:2050
#define IDS_APPDATA
Definition: shresdef.h:98
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define IDI_SHELL_CONTROL_PANEL
Definition: shresdef.h:545
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
#define CSIDL_DESKTOP
Definition: shlobj.h:2012
#define CSIDL_COMMON_FAVORITES
Definition: shlobj.h:2042
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
static HRESULT _SHGetCurrentVersionPath(DWORD dwFlags, BYTE folder, LPWSTR pszPath)
Definition: shellpath.c:1892
#define CSIDL_CONTACTS
Definition: shellpath.c:853
#define PRF_FIRSTDIRDEF
Definition: PathResolve.cpp:32
#define CP_ACP
Definition: compat.h:109
#define PRF_DONTFINDLNK
Definition: PathResolve.cpp:33
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
LONG WINAPI PathProcessCommandAW(LPCVOID lpszPath, LPVOID lpszBuff, DWORD dwBuffSize, DWORD dwFlags)
Definition: shellpath.c:799
#define HKEY_CURRENT_USER
Definition: winreg.h:11
static HRESULT _SHRegisterFolders(HKEY hRootKey, HANDLE hToken, LPCWSTR szUserShellFolderPath, LPCWSTR szShellFolderPath, const UINT folders[], UINT foldersLen)
Definition: shellpath.c:2625
char CHAR
Definition: xmlstorage.h:175
#define IDS_COMMON_MUSIC
Definition: shresdef.h:109
#define IDI_SHELL_COMPUTER_FOLDER
Definition: shresdef.h:566
#define PRF_VERIFYEXISTS
Definition: PathResolve.cpp:29
BOOL WINAPI PathAppendA(LPSTR lpszPath, LPCSTR lpszAppend)
Definition: path.c:106
static BOOL PathMakeUniqueNameW(LPWSTR lpszBuffer, DWORD dwBuffSize, LPCWSTR lpszShortName, LPCWSTR lpszLongName, LPCWSTR lpszPathName)
Definition: shellpath.c:461
#define IDS_INTERNET_CACHE
Definition: shresdef.h:101
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID _Out_ PHANDLE Token
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:615
static const WCHAR Program_FilesW[]
Definition: shellpath.c:822
static const CSIDL_DATA CSIDL_Data[]
Definition: shellpath.c:870
#define CSIDL_COMMON_STARTUP
Definition: shlobj.h:2035
#define IDS_PERSONAL
Definition: shresdef.h:269
#define IDI_SHELL_FAVORITES
Definition: shresdef.h:567
#define IDS_FAVORITES
Definition: resource.h:31
_In_ int nFolder
Definition: shlobj.h:1444
enum _CSIDL_Type CSIDL_Type
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define RRF_RT_REG_SZ
Definition: driver.c:575
BOOL WINAPI PathFileExistsA(LPCSTR lpszPath)
Definition: path.c:1754
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
#define ZeroMemory
Definition: winbase.h:1664
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1105
UINT WINAPI PathGetCharTypeW(WCHAR ch)
Definition: path.c:3035
#define IDI_SHELL_MY_MOVIES
Definition: shresdef.h:652
GLuint buffer
Definition: glext.h:5915
#define CSIDL_BITBUCKET
Definition: shlobj.h:2022
#define CSIDL_HISTORY
Definition: shlobj.h:2045
#define CSIDL_PROGRAM_FILES
Definition: shlobj.h:2049
LPVOID WINAPI SHPathGetExtensionW(LPCWSTR lpszPath, DWORD void1, DWORD void2)
Definition: shellpath.c:276
#define CSIDL_COMMON_PICTURES
Definition: shlobj.h:2062
#define IDI_SHELL_PROGRAMS_FOLDER
Definition: shresdef.h:543
static __inline BOOL SHELL_OsIsUnicode(void)
Definition: shell32_main.h:130
#define strncmpiW(s1, s2, n)
Definition: unicode.h:40
static LPSTR
Definition: shellpath.c:88
BOOL WINAPI GetVolumeInformationA(IN LPCSTR lpRootPathName, IN LPSTR lpVolumeNameBuffer, IN DWORD nVolumeNameSize, OUT LPDWORD lpVolumeSerialNumber OPTIONAL, OUT LPDWORD lpMaximumComponentLength OPTIONAL, OUT LPDWORD lpFileSystemFlags OPTIONAL, OUT LPSTR lpFileSystemNameBuffer OPTIONAL, IN DWORD nFileSystemNameSize)
Definition: volume.c:32
char * LPSTR
Definition: xmlstorage.h:182
BOOL WINAPI ConvertSidToStringSidW(PSID Sid, LPWSTR *StringSid)
Definition: security.c:3382
#define PCS_FATAL
Definition: shlobj.h:331
#define CSIDL_FONTS
Definition: shlobj.h:2031
#define lstrlenW
Definition: compat.h:609
#define E_FAIL
Definition: ddrawi.h:102
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
int32_t INT
Definition: typedefs.h:58
BOOL WINAPI PathRemoveFileSpecA(LPSTR lpszPath)
Definition: path.c:586
WINE_DEFAULT_DEBUG_CHANNEL(shell)
#define CSIDL_INTERNET_CACHE
Definition: shlobj.h:2043
BOOL WINAPI IsLFNDriveAW(LPCVOID lpszPath)
Definition: shellpath.c:432
DWORD dwAttributes
Definition: vdmdbg.h:34
#define pch(ap)
Definition: match.c:418
#define PRF_TRYPROGRAMEXTENSIONS
Definition: PathResolve.cpp:31
#define CSIDL_COMMON_TEMPLATES
Definition: shlobj.h:2056
#define IDI_SHELL_PRINTERS_FOLDER
Definition: shresdef.h:561
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1091
#define lstrcpynW
Definition: compat.h:597
BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
Definition: url.c:2432
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2351
#define CSIDL_CONTROLS
Definition: shlobj.h:2015
BOOL WINAPI PathAppendW(LPWSTR lpszPath, LPCWSTR lpszAppend)
Definition: path.c:126
#define CSIDL_PROGRAM_FILESX86
Definition: shlobj.h:2053
static const WCHAR szSHUserFolders[]
Definition: shellpath.c:831
#define CSIDL_COMMON_PROGRAMS
Definition: shlobj.h:2034
static BOOL WINAPI PathIsAbsoluteW(LPCWSTR path)
Definition: shellpath.c:129
static const WCHAR MusicW[]
Definition: shellpath.c:820
#define CSIDL_MYDOCUMENTS
Definition: shlobj.h:2024
#define CSIDL_RECENT
Definition: shlobj.h:2020
VOID WINAPI FixSlashesAndColonW(LPWSTR lpwstr)
Definition: ordinal.c:4401
static const WCHAR Local_Settings_Application_DataW[]
Definition: shellpath.c:817
#define CSIDL_FOLDER_MASK
Definition: shlobj.h:2070
enum _NT_PRODUCT_TYPE * PNT_PRODUCT_TYPE
#define IDS_PRINTHOOD
Definition: shresdef.h:99
#define PCS_PATHTOOLONG
Definition: shlobj.h:335
BOOL WINAPI SHGetSpecialFolderPathA(HWND hwndOwner, LPSTR szPath, int nFolder, BOOL bCreate)
Definition: shellpath.c:2838
#define CSIDL_PRINTERS
Definition: shlobj.h:2016
#define L(x)
Definition: ntvdm.h:50
#define IDI_SHELL_DESKTOP
Definition: shresdef.h:558
#define CSIDL_DRIVES
Definition: shlobj.h:2028
#define GCT_WILD
Definition: shlwapi.h:778
unsigned char * LPBYTE
Definition: typedefs.h:53
#define FALSE
Definition: types.h:117
#define CSIDL_FAVORITES
Definition: shlobj.h:2018
BOOL WINAPI PathStripToRootW(LPWSTR lpszPath)
Definition: path.c:733
void WINAPI PathRemoveExtensionW(LPWSTR lpszPath)
Definition: path.c:823
BOOL _SHGetUserProfileDirectoryW(HANDLE hToken, LPWSTR szPath, LPDWORD lpcchPath)
Definition: shellpath.c:1740
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:90
LPWSTR WINAPI PathAddBackslashW(LPWSTR lpszPath)
Definition: path.c:294
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
BOOL WINAPI PathIsRootAW(LPCVOID lpszPath)
Definition: shellpath.c:342
if SUCCEEDED(hr)
#define GCT_INVALID
Definition: shlwapi.h:775
static HRESULT _SHRegisterUserShellFolders(BOOL bDefault)
Definition: shellpath.c:2727
BOOL WINAPI PathIsUNCServerShareW(LPCWSTR lpszPath)
Definition: path.c:2377
#define IDS_STARTUP
Definition: shresdef.h:89
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
#define debugstr_w
Definition: kernel32.h:32
#define IDS_PROGRAMS
Definition: resource.h:69
#define PRF_REQUIREABSOLUTE
Definition: PathResolve.cpp:36
#define FIXME(fmt,...)
Definition: debug.h:111
static void PathGetShortPathW(LPWSTR pszPath)
Definition: shellpath.c:313
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define S_FALSE
Definition: winerror.h:2357
BOOL WINAPI PathRemoveFileSpecAW(LPVOID lpszPath)
Definition: shellpath.c:284
#define E_INVALIDARG
Definition: ddrawi.h:101
BOOL WINAPI PathIsFileSpecW(LPCWSTR lpszPath)
Definition: path.c:2132
static const BOOL is_win64
Definition: shellpath.c:58
char ext[3]
Definition: mkdosfs.c:358
#define IDS_DESKTOPDIRECTORY
Definition: shresdef.h:95
#define IDI_SHELL_TSKBAR_STARTMENU
Definition: shresdef.h:563
#define CSIDL_SEARCHES
Definition: shellpath.c:858
#define CSIDL_COMMON_STARTMENU
Definition: shlobj.h:2033
#define IDI_SHELL_NETWORK
Definition: shresdef.h:538
BOOL WINAPI PathResolveW(LPWSTR path, LPCWSTR *dirs, DWORD flags)
Definition: shellpath.c:676
#define IDS_COMMON_VIDEO
Definition: shresdef.h:111
BOOL WINAPI IsLFNDriveW(LPCWSTR lpszPath)
Definition: shellpath.c:420
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c:1776
const char * LPCSTR
Definition: xmlstorage.h:183
LPITEMIDLIST _ILCreateMyComputer(void)
Definition: pidl.c:1613
struct CFFOLDER folder
Definition: fdi.c:102
LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
Definition: path.c:447
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static HRESULT _SHOpenProfilesKey(PHKEY pKey)
Definition: shellpath.c:2131
static const WCHAR Program_Files_Common_FilesW[]
Definition: shellpath.c:823
static const WCHAR path1[]
Definition: path.c:28
#define CSIDL_COMMON_ADMINTOOLS
Definition: shlobj.h:2058
static const WCHAR szKnownFolderDescriptions[]
Definition: shellpath.c:833
#define IDI_SHELL_FONTS_FOLDER
Definition: shresdef.h:562
BOOL WINAPI IsWow64Process(IN HANDLE hProcess, OUT PBOOL Wow64Process)
Definition: proc.c:1975
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4899
UINT WINAPI PathGetCharTypeA(UCHAR ch)
Definition: path.c:3025
BOOL WINAPI PathIsRootW(LPCWSTR lpszPath)
Definition: path.c:1641
#define IDI_SHELL_NETWORK_FOLDER
Definition: resource.h:5
#define IDS_TEMPLATES
Definition: shresdef.h:97
const KNOWNFOLDERID * id
Definition: shellpath.c:863
BOOL WINAPI GetUserNameW(LPWSTR lpszName, LPDWORD lpSize)
Definition: misc.c:291
#define TRACE(s)
Definition: solgame.cpp:4
static const WCHAR szAllUsers[]
Definition: msipriv.h:1138
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define TOKEN_QUERY
Definition: setypes.h:906
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4120
#define CSIDL_ADMINTOOLS
Definition: shlobj.h:2059
BOOL WINAPI PathMakeUniqueNameAW(LPVOID lpszBuffer, DWORD dwBuffSize, LPCVOID lpszShortName, LPCVOID lpszLongName, LPCVOID lpszPathName)
Definition: shellpath.c:477
__wchar_t WCHAR
Definition: xmlstorage.h:180
static HRESULT _SHGetUserProfilePath(HANDLE hToken, DWORD dwFlags, BYTE folder, LPWSTR pszPath)
Definition: shellpath.c:2002
#define debugstr_a
Definition: kernel32.h:31
HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST *ppidl)
Definition: shellpath.c:2972
LONG HRESULT
Definition: typedefs.h:79
#define _countof(array)
Definition: sndvol32.h:68
#define CSIDL_LOCAL_APPDATA
Definition: shlobj.h:2039
DWORD WINAPI GetShortPathNameW(IN LPCWSTR lpszLongPath, OUT LPWSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1832
static BOOL is_wow64
Definition: loader.c:55
#define CSIDL_SENDTO
Definition: shlobj.h:2021
DWORD WINAPI GetShortPathNameA(IN LPCSTR lpszLongPath, OUT LPSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1751
_In_ LPCSTR pszDir
Definition: shellapi.h:582
#define CSIDL_APPDATA
Definition: shlobj.h:2037
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
const char file[]
Definition: icontest.c:11
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
#define GCT_SEPARATOR
Definition: shlwapi.h:779
BOOL PathIsExeW(LPCWSTR lpszPath)
Definition: shellpath.c:370
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
DWORD WINAPI SHAnsiToUnicode(LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen)
Definition: string.c:2659
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath)
Definition: shellpath.c:408
#define IDS_COOKIES
Definition: shresdef.h:102
#define SetLastError(x)
Definition: compat.h:611
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
#define CSIDL_COMMON_VIDEO
Definition: shlobj.h:2063
GLbitfield flags
Definition: glext.h:7161
static void PathGetShortPathA(LPSTR pszPath)
Definition: shellpath.c:298
#define IDS_RECENT
Definition: shresdef.h:90
GLuint GLuint end
Definition: gl.h:1545
static HRESULT _SHGetDefaultValue(BYTE folder, LPWSTR pszPath)
Definition: shellpath.c:1776
#define wcsicmp
Definition: compat.h:15
static HANDLE
Definition: shellpath.c:88
int ret
static const WCHAR Start_Menu_ProgramsW[]
Definition: shellpath.c:824
static HRESULT _SHGetAllUsersProfilePath(DWORD dwFlags, BYTE folder, LPWSTR pszPath)
Definition: shellpath.c:2091
UINT WINAPI GetSystemWow64DirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2420
#define CSIDL_COMMON_APPDATA
Definition: shlobj.h:2046
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
static const WCHAR Start_Menu_StartupW[]
Definition: shellpath.c:826
VOID WINAPI PathQualifyW(LPWSTR pszPath)
Definition: shellpath.c:613
#define IDS_COMMON_PICTURES
Definition: shresdef.h:110
#define IDS_PROGRAM_FILES_COMMON
Definition: shresdef.h:106
INT WINAPI SHUnicodeToAnsi(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT iLen)
Definition: string.c:2783
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1199
#define GUID_NULL
Definition: ks.h:106
#define GetCurrentProcess()
Definition: compat.h:618
#define IDS_HISTORY
Definition: shresdef.h:103
BOOL WINAPI PathFileExistsAW(LPCVOID lpszPath)
Definition: shellpath.c:398
static const WCHAR Cleanup[]
Definition: register.c:80
#define E_NOT_SUFFICIENT_BUFFER
Definition: winerror.h:2345
static BOOL WINAPI PathSearchOnExtensionsW(LPWSTR pszPath, LPCWSTR *ppszDirs, BOOL bDoSearch, DWORD dwWhich)
Definition: shellpath.c:116
LPWSTR WINAPI PathRemoveBackslashW(LPWSTR lpszPath)
Definition: path.c:867
static VOID WINAPI PathQualifyExW(LPWSTR pszPath, LPCWSTR pszDir, DWORD dwFlags)
Definition: shellpath.c:161
unsigned char BYTE
Definition: xxhash.c:193
#define PCS_REPLACEDCHAR
Definition: shlobj.h:332
BOOL WINAPI WritePrivateProfileStringW(LPCWSTR section, LPCWSTR entry, LPCWSTR string, LPCWSTR filename)
Definition: profile.c:1453
GLsizei const GLuint * paths
Definition: glext.h:11717
#define CSIDL_PROGRAM_FILES_COMMONX86
Definition: shlobj.h:2055
#define CSIDL_STARTUP
Definition: shlobj.h:2019
#define CSIDL_PROGRAM_FILES_COMMON
Definition: shlobj.h:2054
#define CSIDL_COMMON_MUSIC
Definition: shlobj.h:2061
#define CSIDL_LINKS
Definition: shellpath.c:855
BOOL WINAPI PathIsRootA(LPCSTR lpszPath)
Definition: path.c:1601
FxRegKey * pKey
#define ERR(fmt,...)
Definition: debug.h:110
static const WCHAR Local_Settings_HistoryW[]
Definition: shellpath.c:818
BOOL WINAPI GetVolumeInformationW(IN LPCWSTR lpRootPathName, IN LPWSTR lpVolumeNameBuffer, IN DWORD nVolumeNameSize, OUT LPDWORD lpVolumeSerialNumber OPTIONAL, OUT LPDWORD lpMaximumComponentLength OPTIONAL, OUT LPDWORD lpFileSystemFlags OPTIONAL, OUT LPWSTR lpFileSystemNameBuffer OPTIONAL, IN DWORD nFileSystemNameSize)
Definition: volume.c:226
#define CSIDL_APPDATA_LOCALLOW
Definition: shellpath.c:856
BOOL WINAPI PathFileExistsDefExtW(LPWSTR lpszPath, DWORD dwWhich)
Definition: path.c:1117
LPITEMIDLIST _ILCreateNetwork(void)
Definition: pidl.c:1669
static __inline LPWSTR __SHCloneStrAtoW(WCHAR **target, const char *source)
Definition: shell32_main.h:160
#define S_OK
Definition: intsafe.h:52
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
#define shell32_hInstance
#define IDI_SHELL_MY_MUSIC
Definition: shresdef.h:651
_In_ int _In_ BOOL bCreate
Definition: shlobj.h:1444
_NT_PRODUCT_TYPE
#define IDI_SHELL_MY_DOCUMENTS
Definition: shresdef.h:649
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
#define lstrcpyW
Definition: compat.h:608
#define IDI_SHELL_SYSTEM_GEAR
Definition: shresdef.h:688
LPSTR WINAPI PathFindExtensionA(LPCSTR lpszPath)
Definition: path.c:422
BOOL WINAPI SHGetSpecialFolderPathW(HWND hwndOwner, LPWSTR szPath, int nFolder, BOOL bCreate)
Definition: shellpath.c:2851
BOOL WINAPI PathResolveAW(LPVOID path, LPCVOID *paths, DWORD flags)
Definition: shellpath.c:756
static BOOL PathIsExeA(LPCSTR lpszPath)
Definition: shellpath.c:352
#define CSIDL_DOWNLOADS
Definition: shellpath.c:854
BOOL WINAPI GetAllUsersProfileDirectoryW(_Out_opt_ LPWSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1310
HRESULT WINAPI SHGetFolderPathA(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPSTR pszPath)
Definition: shellpath.c:2595
#define WHICH_LNK
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
FxAutoRegKey hKey
LPCWSTR szPath
Definition: env.c:37
#define ARRAY_SIZE(a)
Definition: main.h:24
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
int WINAPI SHCreateDirectoryExW(HWND hWnd, LPCWSTR path, LPSECURITY_ATTRIBUTES sec)
Definition: shlfileop.cpp:892
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
static LPWSTR _GetUserSidStringFromToken(HANDLE Token)
Definition: shellpath.c:1961
#define CSIDL_PRINTHOOD
Definition: shlobj.h:2038
BOOL WINAPI SetCurrentDirectoryW(IN LPCWSTR lpPathName)
Definition: path.c:2248
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
INT nShell32IconIndex
Definition: shellpath.c:867
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
#define IDI_SHELL_NETWORK_CONNECTIONS
Definition: shresdef.h:608
#define sprintfW
Definition: unicode.h:58
WINE_UNICODE_INLINE WCHAR * strcatW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:242
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2312
#define CSIDL_COMMON_DOCUMENTS
Definition: shlobj.h:2057
static HRESULT _SHGetProfilesValue(HKEY profilesKey, LPCWSTR szValueName, LPWSTR szValue, LPCWSTR szDefault)
Definition: shellpath.c:2146
BOOL WINAPI PathResolveA(LPSTR path, LPCSTR *dirs, DWORD flags)
Definition: shellpath.c:630
VOID WINAPI PathUnquoteSpacesW(LPWSTR lpszPath)
Definition: path.c:1034
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define IDI_SHELL_MY_PICTURES
Definition: shresdef.h:650
LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:468
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:296
#define CSIDL_FLAG_CREATE
#define CSIDL_INTERNET
Definition: shlobj.h:2013
CSIDL_Type type
Definition: shellpath.c:864
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
BOOL WINAPI PathIsUNCServerW(LPCWSTR lpszPath)
Definition: path.c:2322
VOID WINAPI PathQualifyA(LPSTR pszPath)
Definition: shellpath.c:601
HRESULT WINAPI SHGetFolderPathAndSubDirA(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPCSTR pszSubPath, LPSTR pszPath)
Definition: shellpath.c:2361
#define MultiByteToWideChar
Definition: compat.h:110
#define IDS_MYVIDEO
Definition: shresdef.h:94
HRESULT WINAPI SHILCreateFromPathW(LPCWSTR path, LPITEMIDLIST *ppidl, DWORD *attributes)
Definition: pidl.c:392
int WINAPI PathGetDriveNumberW(const WCHAR *path)
Definition: path.c:553
static LPWSTR PathGetExtensionW(LPCWSTR lpszPath)
Definition: shellpath.c:265
#define IDS_PROGRAM_FILES
Definition: shresdef.h:104
#define CSIDL_SAVED_GAMES
Definition: shellpath.c:857
#define CSIDL_NETHOOD
Definition: shlobj.h:2030
static const WCHAR userName[]
Definition: wnet.c:2154
static const WCHAR szSHFolders[]
Definition: shellpath.c:830
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326
#define CSIDL_PERSONAL
Definition: shlobj.h:2017
CONST void * LPCVOID
Definition: windef.h:191
HRESULT WINAPI SHGetFolderPathW(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath)
Definition: shellpath.c:2348
#define CSIDL_STARTMENU
Definition: shlobj.h:2023
WINE_UNICODE_INLINE int strcmpW(const WCHAR *str1, const WCHAR *str2)
Definition: unicode.h:229
static DWORD GetShortPathNameAbsentW(LPCWSTR pszLong, LPWSTR pszShort, DWORD cchShort)
Definition: shellpath.c:151
LPCWSTR szValueName
Definition: shellpath.c:865
enum _NT_PRODUCT_TYPE NT_PRODUCT_TYPE
static const WCHAR Application_DataW[]
Definition: shellpath.c:816
uint32_t * LPDWORD
Definition: typedefs.h:59
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
static LPSTR PathGetExtensionA(LPCSTR lpszPath)
Definition: shellpath.c:254
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:413
static BOOL WINAPI PathMakeAbsoluteW(LPWSTR path)
Definition: shellpath.c:135
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
BOOL WINAPI PathIsExeAW(LPCVOID path)
Definition: shellpath.c:388
struct _TOKEN_USER * PTOKEN_USER
SID_AND_ATTRIBUTES User
Definition: setypes.h:988
char * cleanup(char *str)
Definition: wpickclick.c:99
HRESULT WINAPI SHGetFolderLocation(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwReserved, LPITEMIDLIST *ppidl)
Definition: shellpath.c:2883
#define IDS_ADMINTOOLS
Definition: shresdef.h:108
#define IDS_MYMUSIC
Definition: shresdef.h:93
LPITEMIDLIST _ILCreateIExplore(void)
Definition: pidl.c:1625
#define IDS_MYPICTURES
Definition: shresdef.h:105
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
BOOL WINAPI PathYetAnotherMakeUniqueName(LPWSTR buffer, LPCWSTR path, LPCWSTR shortname, LPCWSTR longname)
Definition: shellpath.c:492
#define IDS_NETHOOD
Definition: shresdef.h:96
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
static const WCHAR Local_Settings_Temporary_Internet_FilesW[]
Definition: shellpath.c:819
#define CSIDL_DESKTOPDIRECTORY
Definition: shlobj.h:2027
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
BOOL WINAPI PathIsUNCW(LPCWSTR lpszPath)
Definition: path.c:2265
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
LPITEMIDLIST _ILCreateMyDocuments(void)
Definition: pidl.c:1619
LPITEMIDLIST _ILCreateControlPanel(void)
Definition: pidl.c:1631
#define CSIDL_NETWORK
Definition: shlobj.h:2029
IN PCTCH IN DWORD cch
Definition: pager.h:36
HRESULT WINAPI SHGetFolderPathAndSubDirW(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPCWSTR pszSubPath, LPWSTR pszPath)
Definition: shellpath.c:2413
#define CSIDL_PROGRAMS
Definition: shlobj.h:2014
LPWSTR WINAPI PathCombineW(LPWSTR lpszDest, LPCWSTR lpszDir, LPCWSTR lpszFile)
Definition: path.c:194
#define CSIDL_TEMPLATES
Definition: shlobj.h:2032
BOOL WINAPI PathFindOnPathExW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs, DWORD dwWhich)
Definition: path.c:1350
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
static const WCHAR Start_Menu_Admin_ToolsW[]
Definition: shellpath.c:825
static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, LPCWSTR userPrefix, LPCWSTR value, LPWSTR path)
Definition: shellpath.c:1657
BOOL WINAPI PathFindOnPathW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs)
Definition: path.c:1402
#define LOWORD(l)
Definition: pedump.c:82
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:304
static BOOL PathMakeUniqueNameA(LPSTR lpszBuffer, DWORD dwBuffSize, LPCSTR lpszShortName, LPCSTR lpszLongName, LPCSTR lpszPathName)
Definition: shellpath.c:445
#define HeapFree(x, y, z)
Definition: compat.h:594
#define RegCloseKey(hKey)
Definition: registry.h:40
LPITEMIDLIST _ILCreateBitBucket(void)
Definition: pidl.c:1675
#define IDS_SENDTO
Definition: shresdef.h:91
#define IDS_LOCAL_APPDATA
Definition: shresdef.h:100
static const WCHAR PicturesW[]
Definition: shellpath.c:821
_CSIDL_Type
Definition: shellpath.c:837
VOID WINAPI PathQualifyAW(LPVOID pszPath)
Definition: shellpath.c:622
VOID WINAPI PathGetShortPathAW(LPVOID pszPath)
Definition: shellpath.c:328
Definition: path.c:41
#define ERROR_FILENAME_EXCED_RANGE
Definition: winerror.h:263
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define CSIDL_MYMUSIC
Definition: shlobj.h:2025
HRESULT SHELL_RegisterShellFolders(void)
Definition: shellpath.c:2823
Definition: fci.c:126
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define REG_SZ
Definition: layer.c:22