ReactOS  0.4.15-dev-440-g5f37b68
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-2020 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 
54 
55 static const BOOL is_win64 = sizeof(void *) > sizeof(int);
56 
57 #ifdef __REACTOS__
58 /* FIXME: Remove this */
59 typedef enum _NT_PRODUCT_TYPE
60 {
61  NtProductWinNt = 1,
65 
66 /* FIXME: We cannot refresh the RtlGetNtProductType value before reboot. */
67 static BOOL
68 DoGetProductType(PNT_PRODUCT_TYPE ProductType)
69 {
70  static const WCHAR ProductOptions[] = L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions";
71  HKEY hKey;
72  LONG error;
73  WCHAR szValue[9];
74  DWORD cbValue;
75  static DWORD s_dwProductType = 0;
76 
77  if (s_dwProductType != 0)
78  {
79  *ProductType = s_dwProductType;
80  return TRUE;
81  }
82 
83  *ProductType = NtProductServer;
84 
85  error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, ProductOptions, 0, KEY_READ, &hKey);
86  if (error)
87  return FALSE;
88 
89  cbValue = sizeof(szValue);
90  error = RegGetValueW(hKey, NULL, L"ProductType", RRF_RT_REG_SZ, NULL, (PVOID)szValue, &cbValue);
91  if (!error)
92  {
93  if (lstrcmpW(szValue, L"WinNT") == 0)
94  *ProductType = NtProductWinNt;
95  else if (lstrcmpW(szValue, L"LanmanNT") == 0)
96  *ProductType = NtProductLanManNt;
97  }
98 
99  s_dwProductType = *ProductType;
100 
101  RegCloseKey(hKey);
102  return TRUE;
103 }
104 #endif
105 /*
106  ########## Combining and Constructing paths ##########
107 */
108 
109 /*************************************************************************
110  * PathAppend [SHELL32.36]
111  */
113  LPVOID lpszPath1,
114  LPCVOID lpszPath2)
115 {
116  if (SHELL_OsIsUnicode())
117  return PathAppendW(lpszPath1, lpszPath2);
118  return PathAppendA(lpszPath1, lpszPath2);
119 }
120 
121 /*************************************************************************
122  * PathGetExtensionA [internal]
123  *
124  * NOTES
125  * exported by ordinal
126  * return value points to the first char after the dot
127  */
129 {
130  TRACE("(%s)\n",lpszPath);
131 
132  lpszPath = PathFindExtensionA(lpszPath);
133  return (LPSTR)(*lpszPath?(lpszPath+1):lpszPath);
134 }
135 
136 /*************************************************************************
137  * PathGetExtensionW [internal]
138  */
140 {
141  TRACE("(%s)\n",debugstr_w(lpszPath));
142 
143  lpszPath = PathFindExtensionW(lpszPath);
144  return (LPWSTR)(*lpszPath?(lpszPath+1):lpszPath);
145 }
146 
147 /*************************************************************************
148  * SHPathGetExtension [SHELL32.158]
149  */
151 {
152  return PathGetExtensionW(lpszPath);
153 }
154 
155 /*************************************************************************
156  * PathRemoveFileSpec [SHELL32.35]
157  */
159 {
160  if (SHELL_OsIsUnicode())
161  return PathRemoveFileSpecW(lpszPath);
162  return PathRemoveFileSpecA(lpszPath);
163 }
164 
165 /*
166  Path Manipulations
167 */
168 
169 /*************************************************************************
170  * PathGetShortPathA [internal]
171  */
172 static void PathGetShortPathA(LPSTR pszPath)
173 {
174  CHAR path[MAX_PATH];
175 
176  TRACE("%s\n", pszPath);
177 
178  if (GetShortPathNameA(pszPath, path, MAX_PATH))
179  {
180  lstrcpyA(pszPath, path);
181  }
182 }
183 
184 /*************************************************************************
185  * PathGetShortPathW [internal]
186  */
187 static void PathGetShortPathW(LPWSTR pszPath)
188 {
190 
191  TRACE("%s\n", debugstr_w(pszPath));
192 
193  if (GetShortPathNameW(pszPath, path, MAX_PATH))
194  {
195  lstrcpyW(pszPath, path);
196  }
197 }
198 
199 /*************************************************************************
200  * PathGetShortPath [SHELL32.92]
201  */
203 {
204  if(SHELL_OsIsUnicode())
205  PathGetShortPathW(pszPath);
206  PathGetShortPathA(pszPath);
207 }
208 
209 /*
210  ########## Path Testing ##########
211 */
212 
213 /*************************************************************************
214  * PathIsRoot [SHELL32.29]
215  */
217 {
218  if (SHELL_OsIsUnicode())
219  return PathIsRootW(lpszPath);
220  return PathIsRootA(lpszPath);
221 }
222 
223 /*************************************************************************
224  * PathIsExeA [internal]
225  */
226 static BOOL PathIsExeA (LPCSTR lpszPath)
227 {
228  LPCSTR lpszExtension = PathGetExtensionA(lpszPath);
229  int i;
230  static const char * const lpszExtensions[] =
231  {"exe", "com", "pif", "cmd", "bat", "scf", "scr", NULL };
232 
233  TRACE("path=%s\n",lpszPath);
234 
235  for(i=0; lpszExtensions[i]; i++)
236  if (!lstrcmpiA(lpszExtension,lpszExtensions[i])) return TRUE;
237 
238  return FALSE;
239 }
240 
241 /*************************************************************************
242  * PathIsExeW [internal]
243  */
245 {
246  LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
247  int i;
248  static const WCHAR lpszExtensions[][4] =
249  {{'e','x','e','\0'}, {'c','o','m','\0'}, {'p','i','f','\0'},
250  {'c','m','d','\0'}, {'b','a','t','\0'}, {'s','c','f','\0'},
251  {'s','c','r','\0'}, {'\0'} };
252 
253  TRACE("path=%s\n",debugstr_w(lpszPath));
254 
255  for(i=0; lpszExtensions[i][0]; i++)
256  if (!strcmpiW(lpszExtension,lpszExtensions[i])) return TRUE;
257 
258  return FALSE;
259 }
260 
261 /*************************************************************************
262  * PathIsExe [SHELL32.43]
263  */
265 {
266  if (SHELL_OsIsUnicode())
267  return PathIsExeW (path);
268  return PathIsExeA(path);
269 }
270 
271 /*************************************************************************
272  * PathFileExists [SHELL32.45]
273  */
275 {
276  if (SHELL_OsIsUnicode())
277  return PathFileExistsW (lpszPath);
278  return PathFileExistsA (lpszPath);
279 }
280 
281 /*************************************************************************
282  * IsLFNDriveA [SHELL32.41]
283  */
285 {
286  DWORD fnlen;
287 
288  if (!GetVolumeInformationA(lpszPath, NULL, 0, NULL, &fnlen, NULL, NULL, 0))
289  return FALSE;
290  return fnlen > 12;
291 }
292 
293 /*************************************************************************
294  * IsLFNDriveW [SHELL32.42]
295  */
297 {
298  DWORD fnlen;
299 
300  if (!GetVolumeInformationW(lpszPath, NULL, 0, NULL, &fnlen, NULL, NULL, 0))
301  return FALSE;
302  return fnlen > 12;
303 }
304 
305 /*************************************************************************
306  * IsLFNDrive [SHELL32.119]
307  */
309 {
310  if (SHELL_OsIsUnicode())
311  return IsLFNDriveW(lpszPath);
312  return IsLFNDriveA(lpszPath);
313 }
314 
315 /*
316  ########## Creating Something Unique ##########
317 */
318 /*************************************************************************
319  * PathMakeUniqueNameA [internal]
320  */
322  LPSTR lpszBuffer,
323  DWORD dwBuffSize,
324  LPCSTR lpszShortName,
325  LPCSTR lpszLongName,
326  LPCSTR lpszPathName)
327 {
328  FIXME("%p %u %s %s %s stub\n",
329  lpszBuffer, dwBuffSize, debugstr_a(lpszShortName),
330  debugstr_a(lpszLongName), debugstr_a(lpszPathName));
331  return TRUE;
332 }
333 
334 /*************************************************************************
335  * PathMakeUniqueNameW [internal]
336  */
338  LPWSTR lpszBuffer,
339  DWORD dwBuffSize,
340  LPCWSTR lpszShortName,
341  LPCWSTR lpszLongName,
342  LPCWSTR lpszPathName)
343 {
344  FIXME("%p %u %s %s %s stub\n",
345  lpszBuffer, dwBuffSize, debugstr_w(lpszShortName),
346  debugstr_w(lpszLongName), debugstr_w(lpszPathName));
347  return TRUE;
348 }
349 
350 /*************************************************************************
351  * PathMakeUniqueName [SHELL32.47]
352  */
354  LPVOID lpszBuffer,
355  DWORD dwBuffSize,
356  LPCVOID lpszShortName,
357  LPCVOID lpszLongName,
358  LPCVOID lpszPathName)
359 {
360  if (SHELL_OsIsUnicode())
361  return PathMakeUniqueNameW(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
362  return PathMakeUniqueNameA(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
363 }
364 
365 /*************************************************************************
366  * PathYetAnotherMakeUniqueName [SHELL32.75]
367  */
369 {
370  WCHAR pathW[MAX_PATH], retW[MAX_PATH];
371  const WCHAR *file, *ext;
372  int i = 2;
373 
374  TRACE("(%p, %s, %s, %s)\n", buffer, debugstr_w(path), debugstr_w(shortname), debugstr_w(longname));
375 
376  file = longname ? longname : shortname;
377  PathCombineW(pathW, path, file);
378  strcpyW(retW, pathW);
379  PathRemoveExtensionW(pathW);
380 
382 
383  /* now try to make it unique */
384  while (PathFileExistsW(retW))
385  {
386  static const WCHAR fmtW[] = {'%','s',' ','(','%','d',')','%','s',0};
387 
388  sprintfW(retW, fmtW, pathW, i, ext);
389  i++;
390  }
391 
392  strcpyW(buffer, retW);
393  TRACE("ret - %s\n", debugstr_w(buffer));
394 
395  return TRUE;
396 }
397 
398 /*
399  ########## cleaning and resolving paths ##########
400  */
401 
402 /*************************************************************************
403  * PathCleanupSpec [SHELL32.171]
404  *
405  * lpszFile is changed in place.
406  */
407 int WINAPI PathCleanupSpec( LPCWSTR lpszPathW, LPWSTR lpszFileW )
408 {
409  int i = 0;
410  DWORD rc = 0;
411  int length = 0;
412 
413  if (SHELL_OsIsUnicode())
414  {
415  LPWSTR p = lpszFileW;
416 
417  TRACE("Cleanup %s\n",debugstr_w(lpszFileW));
418 
419  if (lpszPathW)
420  length = strlenW(lpszPathW);
421 
422  while (*p)
423  {
424  int gct = PathGetCharTypeW(*p);
425  if (gct == GCT_INVALID || gct == GCT_WILD || gct == GCT_SEPARATOR)
426  {
427  lpszFileW[i]='-';
428  rc |= PCS_REPLACEDCHAR;
429  }
430  else
431  lpszFileW[i]=*p;
432  i++;
433  p++;
434  if (length + i == MAX_PATH)
435  {
436  rc |= PCS_FATAL | PCS_PATHTOOLONG;
437  break;
438  }
439  }
440  lpszFileW[i]=0;
441  }
442  else
443  {
444  LPSTR lpszFileA = (LPSTR)lpszFileW;
445  LPCSTR lpszPathA = (LPCSTR)lpszPathW;
446  LPSTR p = lpszFileA;
447 
448  TRACE("Cleanup %s\n",debugstr_a(lpszFileA));
449 
450  if (lpszPathA)
451  length = strlen(lpszPathA);
452 
453  while (*p)
454  {
455  int gct = PathGetCharTypeA(*p);
456  if (gct == GCT_INVALID || gct == GCT_WILD || gct == GCT_SEPARATOR)
457  {
458  lpszFileA[i]='-';
459  rc |= PCS_REPLACEDCHAR;
460  }
461  else
462  lpszFileA[i]=*p;
463  i++;
464  p++;
465  if (length + i == MAX_PATH)
466  {
467  rc |= PCS_FATAL | PCS_PATHTOOLONG;
468  break;
469  }
470  }
471  lpszFileA[i]=0;
472  }
473  return rc;
474 }
475 
476 /*************************************************************************
477  * PathQualifyA [SHELL32]
478  */
479 static BOOL PathQualifyA(LPCSTR pszPath)
480 {
481  FIXME("%s\n",pszPath);
482  return FALSE;
483 }
484 
485 /*************************************************************************
486  * PathQualifyW [SHELL32]
487  */
488 static BOOL PathQualifyW(LPCWSTR pszPath)
489 {
490  FIXME("%s\n",debugstr_w(pszPath));
491  return FALSE;
492 }
493 
494 /*************************************************************************
495  * PathQualify [SHELL32.49]
496  */
498 {
499  if (SHELL_OsIsUnicode())
500  return PathQualifyW(pszPath);
501  return PathQualifyA(pszPath);
502 }
503 
505 {
506  FIXME("(%s,%p,0x%08x),stub!\n", debugstr_a(path), paths, flags);
507  return FALSE;
508 }
509 
511 {
512  FIXME("(%s,%p,0x%08x),stub!\n", debugstr_w(path), paths, flags);
513  return FALSE;
514 }
515 
516 /*************************************************************************
517  * PathResolve [SHELL32.51]
518  */
520 {
521  if (SHELL_OsIsUnicode())
522  return PathResolveW(path, (LPCWSTR*)paths, flags);
523  else
524  return PathResolveA(path, (LPCSTR*)paths, flags);
525 }
526 
527 /*************************************************************************
528 * PathProcessCommandA
529 */
531  LPCSTR lpszPath,
532  LPSTR lpszBuff,
533  DWORD dwBuffSize,
534  DWORD dwFlags)
535 {
536  FIXME("%s %p 0x%04x 0x%04x stub\n",
537  lpszPath, lpszBuff, dwBuffSize, dwFlags);
538  if(!lpszPath) return -1;
539  if(lpszBuff) strcpy(lpszBuff, lpszPath);
540  return strlen(lpszPath);
541 }
542 
543 /*************************************************************************
544 * PathProcessCommandW
545 */
547  LPCWSTR lpszPath,
548  LPWSTR lpszBuff,
549  DWORD dwBuffSize,
550  DWORD dwFlags)
551 {
552  FIXME("(%s, %p, 0x%04x, 0x%04x) stub\n",
553  debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags);
554  if(!lpszPath) return -1;
555  if(lpszBuff) strcpyW(lpszBuff, lpszPath);
556  return strlenW(lpszPath);
557 }
558 
559 /*************************************************************************
560 * PathProcessCommand (SHELL32.653)
561 */
563  LPCVOID lpszPath,
564  LPVOID lpszBuff,
565  DWORD dwBuffSize,
566  DWORD dwFlags)
567 {
568  if (SHELL_OsIsUnicode())
569  return PathProcessCommandW(lpszPath, lpszBuff, dwBuffSize, dwFlags);
570  return PathProcessCommandA(lpszPath, lpszBuff, dwBuffSize, dwFlags);
571 }
572 
573 /*
574  ########## special ##########
575 */
576 
577 static const WCHAR szCurrentVersion[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0'};
578 static const WCHAR Administrative_ToolsW[] = {'A','d','m','i','n','i','s','t','r','a','t','i','v','e',' ','T','o','o','l','s','\0'};
579 static const WCHAR AppDataW[] = {'A','p','p','D','a','t','a','\0'};
580 #ifndef __REACTOS__
581 static const WCHAR AppData_LocalLowW[] = {'A','p','p','D','a','t','a','\\','L','o','c','a','l','L','o','w','\0'};
582 static const WCHAR Application_DataW[] = {'A','p','p','l','i','c','a','t','i','o','n',' ','D','a','t','a','\0'};
583 #endif
584 static const WCHAR CacheW[] = {'C','a','c','h','e','\0'};
585 static const WCHAR CD_BurningW[] = {'C','D',' ','B','u','r','n','i','n','g','\0'};
586 static const WCHAR Common_Administrative_ToolsW[] = {'C','o','m','m','o','n',' ','A','d','m','i','n','i','s','t','r','a','t','i','v','e',' ','T','o','o','l','s','\0'};
587 static const WCHAR Common_AppDataW[] = {'C','o','m','m','o','n',' ','A','p','p','D','a','t','a','\0'};
588 static const WCHAR Common_DesktopW[] = {'C','o','m','m','o','n',' ','D','e','s','k','t','o','p','\0'};
589 static const WCHAR Common_DocumentsW[] = {'C','o','m','m','o','n',' ','D','o','c','u','m','e','n','t','s','\0'};
590 static const WCHAR Common_FavoritesW[] = {'C','o','m','m','o','n',' ','F','a','v','o','r','i','t','e','s','\0'};
591 static const WCHAR CommonFilesDirW[] = {'C','o','m','m','o','n','F','i','l','e','s','D','i','r','\0'};
592 static const WCHAR CommonFilesDirX86W[] = {'C','o','m','m','o','n','F','i','l','e','s','D','i','r',' ','(','x','8','6',')','\0'};
593 static const WCHAR CommonMusicW[] = {'C','o','m','m','o','n','M','u','s','i','c','\0'};
594 static const WCHAR CommonPicturesW[] = {'C','o','m','m','o','n','P','i','c','t','u','r','e','s','\0'};
595 static const WCHAR Common_ProgramsW[] = {'C','o','m','m','o','n',' ','P','r','o','g','r','a','m','s','\0'};
596 static const WCHAR Common_StartUpW[] = {'C','o','m','m','o','n',' ','S','t','a','r','t','U','p','\0'};
597 static const WCHAR Common_Start_MenuW[] = {'C','o','m','m','o','n',' ','S','t','a','r','t',' ','M','e','n','u','\0'};
598 static const WCHAR Common_TemplatesW[] = {'C','o','m','m','o','n',' ','T','e','m','p','l','a','t','e','s','\0'};
599 static const WCHAR CommonVideoW[] = {'C','o','m','m','o','n','V','i','d','e','o','\0'};
600 #ifndef __REACTOS__
601 static const WCHAR ContactsW[] = {'C','o','n','t','a','c','t','s','\0'};
602 #endif
603 static const WCHAR CookiesW[] = {'C','o','o','k','i','e','s','\0'};
604 static const WCHAR DesktopW[] = {'D','e','s','k','t','o','p','\0'};
605 #ifndef __REACTOS__
606 static const WCHAR DocumentsW[] = {'D','o','c','u','m','e','n','t','s','\0'};
607 static const WCHAR DownloadsW[] = {'D','o','w','n','l','o','a','d','s','\0'};
608 #endif
609 static const WCHAR FavoritesW[] = {'F','a','v','o','r','i','t','e','s','\0'};
610 static const WCHAR FontsW[] = {'F','o','n','t','s','\0'};
611 static const WCHAR HistoryW[] = {'H','i','s','t','o','r','y','\0'};
612 #ifndef __REACTOS__
613 static const WCHAR LinksW[] = {'L','i','n','k','s','\0'};
614 #endif
615 static const WCHAR Local_AppDataW[] = {'L','o','c','a','l',' ','A','p','p','D','a','t','a','\0'};
616 #ifndef __REACTOS__
617 static const WCHAR Local_Settings_Application_DataW[] = {'L','o','c','a','l',' ','S','e','t','t','i','n','g','s','\\','A','p','p','l','i','c','a','t','i','o','n',' ','D','a','t','a','\0'};
618 #endif
619 static const WCHAR Local_Settings_CD_BurningW[] = {'L','o','c','a','l',' ','S','e','t','t','i','n','g','s','\\','A','p','p','l','i','c','a','t','i','o','n',' ','D','a','t','a','\\','M','i','c','r','o','s','o','f','t','\\','C','D',' ','B','u','r','n','i','n','g','\0'};
620 #ifndef __REACTOS__
621 static const WCHAR Local_Settings_HistoryW[] = {'L','o','c','a','l',' ','S','e','t','t','i','n','g','s','\\','H','i','s','t','o','r','y','\0'};
622 static const WCHAR Local_Settings_Temporary_Internet_FilesW[] = {'L','o','c','a','l',' ','S','e','t','t','i','n','g','s','\\','T','e','m','p','o','r','a','r','y',' ','I','n','t','e','r','n','e','t',' ','F','i','l','e','s','\0'};
623 static const WCHAR Microsoft_Windows_GameExplorerW[] = {'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','G','a','m','e','E','x','p','l','o','r','e','r','\0'};
624 static const WCHAR Microsoft_Windows_LibrariesW[] = {'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','L','i','b','r','a','r','i','e','s','\0'};
625 static const WCHAR Microsoft_Windows_RingtonesW[] = {'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','R','i','n','g','t','o','n','e','s','\0'};
626 static const WCHAR MusicW[] = {'M','u','s','i','c','\0'};
627 static const WCHAR Music_PlaylistsW[] = {'M','u','s','i','c','\\','P','l','a','y','l','i','s','t','s','\0'};
628 static const WCHAR Music_Sample_MusicW[] = {'M','u','s','i','c','\\','S','a','m','p','l','e',' ','M','u','s','i','c','\0'};
629 static const WCHAR Music_Sample_PlaylistsW[] = {'M','u','s','i','c','\\','S','a','m','p','l','e',' ','P','l','a','y','l','i','s','t','s','\0'};
630 #endif
631 static const WCHAR My_MusicW[] = {'M','y',' ','M','u','s','i','c','\0'};
632 static const WCHAR My_PicturesW[] = {'M','y',' ','P','i','c','t','u','r','e','s','\0'};
633 static const WCHAR My_VideoW[] = {'M','y',' ','V','i','d','e','o','\0'};
634 static const WCHAR NetHoodW[] = {'N','e','t','H','o','o','d','\0'};
635 static const WCHAR OEM_LinksW[] = {'O','E','M',' ','L','i','n','k','s','\0'};
636 static const WCHAR PersonalW[] = {'P','e','r','s','o','n','a','l','\0'};
637 #ifndef __REACTOS__
638 static const WCHAR PicturesW[] = {'P','i','c','t','u','r','e','s','\0'};
639 static const WCHAR Pictures_Sample_PicturesW[] = {'P','i','c','t','u','r','e','s','\\','S','a','m','p','l','e',' ','P','i','c','t','u','r','e','s','\0'};
640 static const WCHAR Pictures_Slide_ShowsW[] = {'P','i','c','t','u','r','e','s','\\','S','l','i','d','e',' ','S','h','o','w','s','\0'};
641 #endif
642 static const WCHAR PrintHoodW[] = {'P','r','i','n','t','H','o','o','d','\0'};
643 #ifndef __REACTOS__
644 static const WCHAR Program_FilesW[] = {'P','r','o','g','r','a','m',' ','F','i','l','e','s','\0'};
645 static const WCHAR Program_Files_Common_FilesW[] = {'P','r','o','g','r','a','m',' ','F','i','l','e','s','\\','C','o','m','m','o','n',' ','F','i','l','e','s','\0'};
646 #endif
647 static const WCHAR Program_Files_x86W[] = {'P','r','o','g','r','a','m',' ','F','i','l','e','s',' ','(','x','8','6',')','\0'};
648 static const WCHAR Program_Files_x86_Common_FilesW[] = {'P','r','o','g','r','a','m',' ','F','i','l','e','s',' ','(','x','8','6',')','\\','C','o','m','m','o','n',' ','F','i','l','e','s','\0'};
649 static const WCHAR ProgramFilesDirW[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r','\0'};
650 static const WCHAR ProgramFilesDirX86W[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r',' ','(','x','8','6',')','\0'};
651 static const WCHAR ProgramsW[] = {'P','r','o','g','r','a','m','s','\0'};
652 #ifndef __REACTOS__
653 static const WCHAR PublicW[] = {'P','u','b','l','i','c',0};
654 #endif
655 static const WCHAR RecentW[] = {'R','e','c','e','n','t','\0'};
656 static const WCHAR ResourcesW[] = {'R','e','s','o','u','r','c','e','s','\0'};
657 #ifndef __REACTOS__
658 static const WCHAR Saved_GamesW[] = {'S','a','v','e','d',' ','G','a','m','e','s','\0'};
659 static const WCHAR SearchesW[] = {'S','e','a','r','c','h','e','s','\0'};
660 #endif
661 static const WCHAR SendToW[] = {'S','e','n','d','T','o','\0'};
662 static const WCHAR StartUpW[] = {'S','t','a','r','t','U','p','\0'};
663 static const WCHAR Start_MenuW[] = {'S','t','a','r','t',' ','M','e','n','u','\0'};
664 #ifndef __REACTOS__
665 static const WCHAR Start_Menu_ProgramsW[] = {'S','t','a','r','t',' ','M','e','n','u','\\','P','r','o','g','r','a','m','s','\0'};
666 static const WCHAR Start_Menu_Admin_ToolsW[] = {'S','t','a','r','t',' ','M','e','n','u','\\','P','r','o','g','r','a','m','s','\\','A','d','m','i','n','i','s','t','r','a','t','i','v','e',' ','T','o','o','l','s','\0'};
667 static const WCHAR Start_Menu_StartupW[] = {'S','t','a','r','t',' ','M','e','n','u','\\','P','r','o','g','r','a','m','s','\\','S','t','a','r','t','U','p','\0'};
668 #endif
669 static const WCHAR TemplatesW[] = {'T','e','m','p','l','a','t','e','s','\0'};
670 #ifndef __REACTOS__
671 static const WCHAR UsersW[] = {'U','s','e','r','s','\0'};
672 static const WCHAR UsersPublicW[] = {'U','s','e','r','s','\\','P','u','b','l','i','c','\0'};
673 static const WCHAR VideosW[] = {'V','i','d','e','o','s','\0'};
674 static const WCHAR Videos_Sample_VideosW[] = {'V','i','d','e','o','s','\\','S','a','m','p','l','e',' ','V','i','d','e','o','s','\0'};
675 #endif
676 static const WCHAR DefaultW[] = {'.','D','e','f','a','u','l','t','\0'};
677 static const WCHAR AllUsersProfileW[] = {'%','A','L','L','U','S','E','R','S','P','R','O','F','I','L','E','%','\0'};
678 #ifndef __REACTOS__
679 static const WCHAR PublicProfileW[] = {'%','P','U','B','L','I','C','%',0};
680 #endif
681 static const WCHAR UserProfileW[] = {'%','U','S','E','R','P','R','O','F','I','L','E','%','\0'};
682 static const WCHAR SystemDriveW[] = {'%','S','y','s','t','e','m','D','r','i','v','e','%','\0'};
683 #ifndef __REACTOS__
684 static const WCHAR ProfileListW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ','N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','P','r','o','f','i','l','e','L','i','s','t',0};
685 static const WCHAR ProfilesDirectoryW[] = {'P','r','o','f','i','l','e','s','D','i','r','e','c','t','o','r','y',0};
686 static const WCHAR AllUsersProfileValueW[] = {'A','l','l','U','s','e','r','s','P','r','o','f','i','l','e','\0'};
687 #endif
688 static const WCHAR szSHFolders[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','E','x','p','l','o','r','e','r','\\','S','h','e','l','l',' ','F','o','l','d','e','r','s','\0'};
689 static const WCHAR szSHUserFolders[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','E','x','p','l','o','r','e','r','\\','U','s','e','r',' ','S','h','e','l','l',' ','F','o','l','d','e','r','s','\0'};
690 static const WCHAR szDefaultProfileDirW[] = {'u','s','e','r','s',0};
691 #ifndef __REACTOS__
692 static const WCHAR szKnownFolderDescriptions[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','E','x','p','l','o','r','e','r','\\','F','o','l','d','e','r','D','e','s','c','r','i','p','t','i','o','n','s','\0'};
693 static const WCHAR szKnownFolderRedirections[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','E','x','p','l','o','r','e','r','\\','U','s','e','r',' ','S','h','e','l','l',' ','F','o','l','d','e','r','s',0};
694 #endif
695 static const WCHAR AllUsersW[] = {'P','u','b','l','i','c',0};
696 
697 typedef enum _CSIDL_Type {
699 #ifdef __REACTOS__
700  CSIDL_Type_InMyDocuments,
701 #endif
709 } CSIDL_Type;
710 
711 /* Cannot use #if _WIN32_WINNT >= 0x0600 because _WIN32_WINNT == 0x0600 here. */
712 #ifndef __REACTOS__
713 #define CSIDL_CONTACTS 0x0043
714 #define CSIDL_DOWNLOADS 0x0047
715 #define CSIDL_LINKS 0x004d
716 #define CSIDL_APPDATA_LOCALLOW 0x004e
717 #define CSIDL_SAVED_GAMES 0x0062
718 #define CSIDL_SEARCHES 0x0063
719 #endif
720 
721 typedef struct
722 {
726  LPCWSTR szDefaultPath; /* fallback string or resource ID */
728 } CSIDL_DATA;
729 
730 static const CSIDL_DATA CSIDL_Data[] =
731 {
732  { /* 0x00 - CSIDL_DESKTOP */
733  &FOLDERID_Desktop,
735  DesktopW,
737 #ifdef __REACTOS__
738  0
739 #else
741 #endif
742  },
743  { /* 0x01 - CSIDL_INTERNET */
744  &FOLDERID_InternetFolder,
746  NULL,
747  NULL
748  },
749  { /* 0x02 - CSIDL_PROGRAMS */
750  &FOLDERID_Programs,
752  ProgramsW,
754 #ifdef __REACTOS__
755  0
756 #else
758 #endif
759  },
760  { /* 0x03 - CSIDL_CONTROLS (.CPL files) */
761  &FOLDERID_ControlPanelFolder,
763  NULL,
764  NULL,
766  },
767  { /* 0x04 - CSIDL_PRINTERS */
768  &FOLDERID_PrintersFolder,
770  NULL,
771  NULL,
773  },
774  { /* 0x05 - CSIDL_PERSONAL */
775  &FOLDERID_Documents,
777  PersonalW,
780  },
781  { /* 0x06 - CSIDL_FAVORITES */
782  &FOLDERID_Favorites,
784  FavoritesW,
787  },
788  { /* 0x07 - CSIDL_STARTUP */
789  &FOLDERID_Startup,
791  StartUpW,
793  },
794  { /* 0x08 - CSIDL_RECENT */
795  &FOLDERID_Recent,
797  RecentW,
800  },
801  { /* 0x09 - CSIDL_SENDTO */
802  &FOLDERID_SendTo,
804  SendToW,
806  },
807  { /* 0x0a - CSIDL_BITBUCKET - Recycle Bin */
808  &FOLDERID_RecycleBinFolder,
810  NULL,
811  NULL
812  },
813  { /* 0x0b - CSIDL_STARTMENU */
814  &FOLDERID_StartMenu,
816  Start_MenuW,
819  },
820  { /* 0x0c - CSIDL_MYDOCUMENTS */
821  &GUID_NULL,
822  CSIDL_Type_Disallowed, /* matches WinXP--can't get its path */
823  NULL,
824  NULL,
826  },
827  { /* 0x0d - CSIDL_MYMUSIC */
828  &FOLDERID_Music,
829 #ifdef __REACTOS__
830  CSIDL_Type_InMyDocuments,
831 #else
833 #endif
834  My_MusicW,
837  },
838  { /* 0x0e - CSIDL_MYVIDEO */
839  &FOLDERID_Videos,
840 #ifdef __REACTOS__
841  CSIDL_Type_InMyDocuments,
842 #else
844 #endif
845  My_VideoW,
848  },
849  { /* 0x0f - unassigned */
850  &GUID_NULL,
852  NULL,
853  NULL,
854  },
855  { /* 0x10 - CSIDL_DESKTOPDIRECTORY */
856  &FOLDERID_Desktop,
858  DesktopW,
860 #ifdef __REACTOS__
861  0
862 #else
864 #endif
865  },
866  { /* 0x11 - CSIDL_DRIVES */
867  &FOLDERID_ComputerFolder,
869  NULL,
870  NULL,
872  },
873  { /* 0x12 - CSIDL_NETWORK */
874  &FOLDERID_NetworkFolder,
876  NULL,
877  NULL,
879  },
880  { /* 0x13 - CSIDL_NETHOOD */
881  &FOLDERID_NetHood,
883  NetHoodW,
886  },
887  { /* 0x14 - CSIDL_FONTS */
888  &FOLDERID_Fonts,
890  FontsW,
891  FontsW,
893  },
894  { /* 0x15 - CSIDL_TEMPLATES */
895  &FOLDERID_Templates,
897  TemplatesW,
899  },
900  { /* 0x16 - CSIDL_COMMON_STARTMENU */
901  &FOLDERID_CommonStartMenu,
906  },
907  { /* 0x17 - CSIDL_COMMON_PROGRAMS */
908  &FOLDERID_CommonPrograms,
912 #ifdef __REACTOS__
913  0
914 #else
916 #endif
917  },
918  { /* 0x18 - CSIDL_COMMON_STARTUP */
919  &FOLDERID_CommonStartup,
923  },
924  { /* 0x19 - CSIDL_COMMON_DESKTOPDIRECTORY */
925  &FOLDERID_PublicDesktop,
929 #ifdef __REACTOS__
930  0
931 #else
933 #endif
934  },
935  { /* 0x1a - CSIDL_APPDATA */
936  &FOLDERID_RoamingAppData,
938  AppDataW,
940  },
941  { /* 0x1b - CSIDL_PRINTHOOD */
942  &FOLDERID_PrintHood,
944  PrintHoodW,
947  },
948  { /* 0x1c - CSIDL_LOCAL_APPDATA */
949  &FOLDERID_LocalAppData,
953  },
954  { /* 0x1d - CSIDL_ALTSTARTUP */
955  &GUID_NULL,
957  NULL,
958  NULL
959  },
960  { /* 0x1e - CSIDL_COMMON_ALTSTARTUP */
961  &GUID_NULL,
963  NULL,
964  NULL
965  },
966  { /* 0x1f - CSIDL_COMMON_FAVORITES */
967  &FOLDERID_Favorites,
972  },
973  { /* 0x20 - CSIDL_INTERNET_CACHE */
974  &FOLDERID_InternetCache,
976  CacheW,
978  },
979  { /* 0x21 - CSIDL_COOKIES */
980  &FOLDERID_Cookies,
982  CookiesW,
984  },
985  { /* 0x22 - CSIDL_HISTORY */
986  &FOLDERID_History,
988  HistoryW,
990  },
991  { /* 0x23 - CSIDL_COMMON_APPDATA */
992  &FOLDERID_ProgramData,
996  },
997  { /* 0x24 - CSIDL_WINDOWS */
998  &FOLDERID_Windows,
1000  NULL,
1001  NULL,
1003  },
1004  { /* 0x25 - CSIDL_SYSTEM */
1005  &FOLDERID_System,
1007  NULL,
1008  NULL,
1010  },
1011  { /* 0x26 - CSIDL_PROGRAM_FILES */
1012  &FOLDERID_ProgramFiles,
1016 #ifdef __REACTOS__
1017  0
1018 #else
1020 #endif
1021  },
1022  { /* 0x27 - CSIDL_MYPICTURES */
1023  &FOLDERID_Pictures,
1024 #ifdef __REACTOS__
1025  CSIDL_Type_InMyDocuments,
1026 #else
1028 #endif
1029  My_PicturesW,
1032  },
1033  { /* 0x28 - CSIDL_PROFILE */
1034  &FOLDERID_Profile,
1036  NULL,
1037  NULL
1038  },
1039  { /* 0x29 - CSIDL_SYSTEMX86 */
1040  &FOLDERID_SystemX86,
1042  NULL,
1043  NULL,
1045  },
1046  { /* 0x2a - CSIDL_PROGRAM_FILESX86 */
1047  &FOLDERID_ProgramFilesX86,
1052  },
1053  { /* 0x2b - CSIDL_PROGRAM_FILES_COMMON */
1054  &FOLDERID_ProgramFilesCommon,
1059  },
1060  { /* 0x2c - CSIDL_PROGRAM_FILES_COMMONX86 */
1061  &FOLDERID_ProgramFilesCommonX86,
1066  },
1067  { /* 0x2d - CSIDL_COMMON_TEMPLATES */
1068  &FOLDERID_CommonTemplates,
1072  },
1073  { /* 0x2e - CSIDL_COMMON_DOCUMENTS */
1074  &FOLDERID_PublicDocuments,
1079  },
1080  { /* 0x2f - CSIDL_COMMON_ADMINTOOLS */
1081  &FOLDERID_CommonAdminTools,
1085  },
1086  { /* 0x30 - CSIDL_ADMINTOOLS */
1087  &FOLDERID_AdminTools,
1091  },
1092  { /* 0x31 - CSIDL_CONNECTIONS */
1093  &FOLDERID_ConnectionsFolder,
1095  NULL,
1096  NULL,
1098  },
1099  { /* 0x32 - unassigned */
1100  &GUID_NULL,
1102  NULL,
1103  NULL
1104  },
1105  { /* 0x33 - unassigned */
1106  &GUID_NULL,
1108  NULL,
1109  NULL
1110  },
1111  { /* 0x34 - unassigned */
1112  &GUID_NULL,
1114  NULL,
1115  NULL
1116  },
1117  { /* 0x35 - CSIDL_COMMON_MUSIC */
1118  &FOLDERID_PublicMusic,
1120  CommonMusicW,
1123  },
1124  { /* 0x36 - CSIDL_COMMON_PICTURES */
1125  &FOLDERID_PublicPictures,
1130  },
1131  { /* 0x37 - CSIDL_COMMON_VIDEO */
1132  &FOLDERID_PublicVideos,
1134  CommonVideoW,
1137  },
1138  { /* 0x38 - CSIDL_RESOURCES */
1139  &FOLDERID_ResourceDir,
1141  NULL,
1142  ResourcesW
1143  },
1144  { /* 0x39 - CSIDL_RESOURCES_LOCALIZED */
1145  &FOLDERID_LocalizedResourcesDir,
1147  NULL,
1148  NULL
1149  },
1150  { /* 0x3a - CSIDL_COMMON_OEM_LINKS */
1151  &FOLDERID_CommonOEMLinks,
1153  NULL,
1154  OEM_LinksW
1155  },
1156  { /* 0x3b - CSIDL_CDBURN_AREA */
1157  &FOLDERID_CDBurning,
1159  CD_BurningW,
1161  },
1162  { /* 0x3c unassigned */
1163  &GUID_NULL,
1165  NULL,
1166  NULL
1167  },
1168  { /* 0x3d - CSIDL_COMPUTERSNEARME */
1169  &GUID_NULL,
1170  CSIDL_Type_Disallowed, /* FIXME */
1171  NULL,
1172  NULL
1173  },
1174  { /* 0x3e - CSIDL_PROFILES */
1175  &GUID_NULL,
1176  CSIDL_Type_Disallowed, /* oddly, this matches WinXP */
1177  NULL,
1178  NULL
1179  },
1180 /* Cannot use #if _WIN32_WINNT >= 0x0600 because _WIN32_WINNT == 0x0600 here. */
1181 #ifndef __REACTOS__
1182  { /* 0x3f */
1183  &FOLDERID_AddNewPrograms,
1185  NULL,
1186  NULL
1187  },
1188  { /* 0x40 */
1189  &FOLDERID_AppUpdates,
1191  NULL,
1192  NULL
1193  },
1194  { /* 0x41 */
1195  &FOLDERID_ChangeRemovePrograms,
1197  NULL,
1198  NULL
1199  },
1200  { /* 0x42 */
1201  &FOLDERID_ConflictFolder,
1203  NULL,
1204  NULL
1205  },
1206  { /* 0x43 - CSIDL_CONTACTS */
1207  &FOLDERID_Contacts,
1209  NULL,
1210  ContactsW
1211  },
1212  { /* 0x44 */
1213  &FOLDERID_DeviceMetadataStore,
1214  CSIDL_Type_Disallowed, /* FIXME */
1215  NULL,
1216  NULL
1217  },
1218  { /* 0x45 */
1219  &GUID_NULL,
1221  NULL,
1222  DocumentsW
1223  },
1224  { /* 0x46 */
1225  &FOLDERID_DocumentsLibrary,
1226  CSIDL_Type_Disallowed, /* FIXME */
1227  NULL,
1228  NULL
1229  },
1230  { /* 0x47 - CSIDL_DOWNLOADS */
1231  &FOLDERID_Downloads,
1232 #ifdef __REACTOS__
1233  CSIDL_Type_InMyDocuments,
1234 #else
1236 #endif
1237  NULL,
1238  DownloadsW
1239  },
1240  { /* 0x48 */
1241  &FOLDERID_Games,
1243  NULL,
1244  NULL
1245  },
1246  { /* 0x49 */
1247  &FOLDERID_GameTasks,
1248  CSIDL_Type_Disallowed, /* FIXME */
1249  NULL,
1250  NULL
1251  },
1252  { /* 0x4a */
1253  &FOLDERID_HomeGroup,
1255  NULL,
1256  NULL
1257  },
1258  { /* 0x4b */
1259  &FOLDERID_ImplicitAppShortcuts,
1260  CSIDL_Type_Disallowed, /* FIXME */
1261  NULL,
1262  NULL
1263  },
1264  { /* 0x4c */
1265  &FOLDERID_Libraries,
1266  CSIDL_Type_Disallowed, /* FIXME */
1267  NULL,
1268  NULL
1269  },
1270  { /* 0x4d - CSIDL_LINKS */
1271  &FOLDERID_Links,
1273  NULL,
1274  LinksW
1275  },
1276  { /* 0x4e - CSIDL_APPDATA_LOCALLOW */
1277  &FOLDERID_LocalAppDataLow,
1279  NULL,
1281  },
1282  { /* 0x4f */
1283  &FOLDERID_MusicLibrary,
1284  CSIDL_Type_Disallowed, /* FIXME */
1285  NULL,
1286  NULL
1287  },
1288  { /* 0x50 */
1289  &FOLDERID_OriginalImages,
1290  CSIDL_Type_Disallowed, /* FIXME */
1291  NULL,
1292  NULL
1293  },
1294  { /* 0x51 */
1295  &FOLDERID_PhotoAlbums,
1297  NULL,
1299  },
1300  { /* 0x52 */
1301  &FOLDERID_PicturesLibrary,
1302  CSIDL_Type_Disallowed, /* FIXME */
1303  NULL,
1304  NULL
1305  },
1306  { /* 0x53 */
1307  &FOLDERID_Playlists,
1309  NULL,
1311  },
1312  { /* 0x54 */
1313  &FOLDERID_ProgramFilesX64,
1315  NULL,
1316  NULL
1317  },
1318  { /* 0x55 */
1319  &FOLDERID_ProgramFilesCommonX64,
1321  NULL,
1322  NULL
1323  },
1324  { /* 0x56 */
1325  &FOLDERID_Public,
1326  CSIDL_Type_CurrVer, /* FIXME */
1327  NULL,
1328  UsersPublicW
1329  },
1330  { /* 0x57 */
1331  &FOLDERID_PublicDownloads,
1333  NULL,
1334  DownloadsW
1335  },
1336  { /* 0x58 */
1337  &FOLDERID_PublicGameTasks,
1339  NULL,
1341  },
1342  { /* 0x59 */
1343  &FOLDERID_PublicLibraries,
1345  NULL,
1347  },
1348  { /* 0x5a */
1349  &FOLDERID_PublicRingtones,
1351  NULL,
1353  },
1354  { /* 0x5b */
1355  &FOLDERID_QuickLaunch,
1356  CSIDL_Type_Disallowed, /* FIXME */
1357  NULL,
1358  NULL
1359  },
1360  { /* 0x5c */
1361  &FOLDERID_RecordedTVLibrary,
1362  CSIDL_Type_Disallowed, /* FIXME */
1363  NULL,
1364  NULL
1365  },
1366  { /* 0x5d */
1367  &FOLDERID_Ringtones,
1368  CSIDL_Type_Disallowed, /* FIXME */
1369  NULL,
1370  NULL
1371  },
1372  { /* 0x5e */
1373  &FOLDERID_SampleMusic,
1375  NULL,
1377  },
1378  { /* 0x5f */
1379  &FOLDERID_SamplePictures,
1381  NULL,
1383  },
1384  { /* 0x60 */
1385  &FOLDERID_SamplePlaylists,
1387  NULL,
1389  },
1390  { /* 0x61 */
1391  &FOLDERID_SampleVideos,
1393  NULL,
1395  },
1396  { /* 0x62 - CSIDL_SAVED_GAMES */
1397  &FOLDERID_SavedGames,
1399  NULL,
1400  Saved_GamesW
1401  },
1402  { /* 0x63 - CSIDL_SEARCHES */
1403  &FOLDERID_SavedSearches,
1405  NULL,
1406  SearchesW
1407  },
1408  { /* 0x64 */
1409  &FOLDERID_SEARCH_CSC,
1411  NULL,
1412  NULL
1413  },
1414  { /* 0x65 */
1415  &FOLDERID_SEARCH_MAPI,
1417  NULL,
1418  NULL
1419  },
1420  { /* 0x66 */
1421  &FOLDERID_SearchHome,
1423  NULL,
1424  NULL
1425  },
1426  { /* 0x67 */
1427  &FOLDERID_SidebarDefaultParts,
1428  CSIDL_Type_Disallowed, /* FIXME */
1429  NULL,
1430  NULL
1431  },
1432  { /* 0x68 */
1433  &FOLDERID_SidebarParts,
1434  CSIDL_Type_Disallowed, /* FIXME */
1435  NULL,
1436  NULL
1437  },
1438  { /* 0x69 */
1439  &FOLDERID_SyncManagerFolder,
1441  NULL,
1442  NULL
1443  },
1444  { /* 0x6a */
1445  &FOLDERID_SyncResultsFolder,
1447  NULL,
1448  NULL
1449  },
1450  { /* 0x6b */
1451  &FOLDERID_SyncSetupFolder,
1453  NULL,
1454  NULL
1455  },
1456  { /* 0x6c */
1457  &FOLDERID_UserPinned,
1458  CSIDL_Type_Disallowed, /* FIXME */
1459  NULL,
1460  NULL
1461  },
1462  { /* 0x6d */
1463  &FOLDERID_UserProfiles,
1465  UsersW,
1466  UsersW
1467  },
1468  { /* 0x6e */
1469  &FOLDERID_UserProgramFiles,
1470  CSIDL_Type_Disallowed, /* FIXME */
1471  NULL,
1472  NULL
1473  },
1474  { /* 0x6f */
1475  &FOLDERID_UserProgramFilesCommon,
1476  CSIDL_Type_Disallowed, /* FIXME */
1477  NULL,
1478  NULL
1479  },
1480  { /* 0x70 */
1481  &FOLDERID_UsersFiles,
1483  NULL,
1484  NULL
1485  },
1486  { /* 0x71 */
1487  &FOLDERID_UsersLibraries,
1489  NULL,
1490  NULL
1491  },
1492  { /* 0x72 */
1493  &FOLDERID_VideosLibrary,
1494  CSIDL_Type_Disallowed, /* FIXME */
1495  NULL,
1496  NULL
1497  }
1498 #endif
1499 };
1500 
1501 #ifndef __REACTOS__
1502 static HRESULT _SHExpandEnvironmentStrings(LPCWSTR szSrc, LPWSTR szDest);
1503 #else
1504 static HRESULT _SHExpandEnvironmentStrings(HANDLE hToken, LPCWSTR szSrc, LPWSTR szDest, DWORD cchDest);
1505 #endif
1506 
1507 /* Gets the value named value from the registry key
1508  * rootKey\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
1509  * (or from rootKey\userPrefix\... if userPrefix is not NULL) into path, which
1510  * is assumed to be MAX_PATH WCHARs in length.
1511  * If it exists, expands the value and writes the expanded value to
1512  * rootKey\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
1513  * Returns successful error code if the value was retrieved from the registry,
1514  * and a failure otherwise.
1515  */
1516 #ifndef __REACTOS__
1517 static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, LPCWSTR userPrefix,
1518 #else
1519 static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, HANDLE hToken, LPCWSTR userPrefix,
1520 #endif
1522 {
1523  HRESULT hr;
1524  WCHAR shellFolderPath[MAX_PATH], userShellFolderPath[MAX_PATH];
1525  LPCWSTR pShellFolderPath, pUserShellFolderPath;
1526  HKEY userShellFolderKey, shellFolderKey;
1527  DWORD dwType, dwPathLen;
1528 
1529  TRACE("%p,%s,%s,%p\n",rootKey, debugstr_w(userPrefix), debugstr_w(value),
1530  path);
1531 
1532  if (userPrefix)
1533  {
1534  strcpyW(shellFolderPath, userPrefix);
1535  PathAddBackslashW(shellFolderPath);
1536  strcatW(shellFolderPath, szSHFolders);
1537  pShellFolderPath = shellFolderPath;
1538  strcpyW(userShellFolderPath, userPrefix);
1539  PathAddBackslashW(userShellFolderPath);
1540  strcatW(userShellFolderPath, szSHUserFolders);
1541  pUserShellFolderPath = userShellFolderPath;
1542  }
1543  else
1544  {
1545  pUserShellFolderPath = szSHUserFolders;
1546  pShellFolderPath = szSHFolders;
1547  }
1548 
1549  if (RegCreateKeyW(rootKey, pShellFolderPath, &shellFolderKey))
1550  {
1551  TRACE("Failed to create %s\n", debugstr_w(pShellFolderPath));
1552  return E_FAIL;
1553  }
1554  if (RegCreateKeyW(rootKey, pUserShellFolderPath, &userShellFolderKey))
1555  {
1556  TRACE("Failed to create %s\n",
1557  debugstr_w(pUserShellFolderPath));
1558  RegCloseKey(shellFolderKey);
1559  return E_FAIL;
1560  }
1561 
1562  dwPathLen = MAX_PATH * sizeof(WCHAR);
1563  if (!RegQueryValueExW(userShellFolderKey, value, NULL, &dwType,
1564  (LPBYTE)path, &dwPathLen) && (dwType == REG_EXPAND_SZ || dwType == REG_SZ))
1565  {
1566  LONG ret;
1567 
1568  path[dwPathLen / sizeof(WCHAR)] = '\0';
1569  if (dwType == REG_EXPAND_SZ && path[0] == '%')
1570  {
1571  WCHAR szTemp[MAX_PATH];
1572 
1573 #ifndef __REACTOS__
1575 #else
1576  hr = _SHExpandEnvironmentStrings(hToken, path, szTemp, _countof(szTemp));
1577  if (FAILED(hr))
1578  goto end;
1579 #endif
1580  lstrcpynW(path, szTemp, MAX_PATH);
1581  }
1582  ret = RegSetValueExW(shellFolderKey, value, 0, REG_SZ, (LPBYTE)path,
1583  (strlenW(path) + 1) * sizeof(WCHAR));
1584  if (ret != ERROR_SUCCESS)
1586  else
1587  hr = S_OK;
1588  }
1589  else
1590  hr = E_FAIL;
1591 #ifdef __REACTOS__
1592 end:
1593 #endif
1594  RegCloseKey(shellFolderKey);
1595  RegCloseKey(userShellFolderKey);
1596  TRACE("returning 0x%08x\n", hr);
1597  return hr;
1598 }
1599 
1601 {
1602  BOOL result;
1603  if (!hToken)
1604  {
1606  result = GetUserProfileDirectoryW(hToken, szPath, lpcchPath);
1607  CloseHandle(hToken);
1608  }
1609  else if ((INT) hToken == -1)
1610  {
1612  }
1613  else
1614  {
1615  result = GetUserProfileDirectoryW(hToken, szPath, lpcchPath);
1616  }
1617  TRACE("_SHGetUserProfileDirectoryW returning %S\n", szPath);
1618  return result;
1619 }
1620 
1621 /* Gets a 'semi-expanded' default value of the CSIDL with index folder into
1622  * pszPath, based on the entries in CSIDL_Data. By semi-expanded, I mean:
1623  * - The entry's szDefaultPath may be either a string value or an integer
1624  * resource identifier. In the latter case, the string value of the resource
1625  * is written.
1626  * - Depending on the entry's type, the path may begin with an (unexpanded)
1627  * environment variable name. The caller is responsible for expanding
1628  * environment strings if so desired.
1629  * The types that are prepended with environment variables are:
1630  * CSIDL_Type_User: %USERPROFILE%
1631  * CSIDL_Type_AllUsers: %ALLUSERSPROFILE%
1632  * CSIDL_Type_CurrVer: %SystemDrive%
1633  * (Others might make sense too, but as yet are unneeded.)
1634  */
1635 #ifndef __REACTOS__
1637 #else
1638 static HRESULT _SHGetDefaultValue(HANDLE hToken, BYTE folder, LPWSTR pszPath)
1639 #endif
1640 {
1641  HRESULT hr;
1642  WCHAR resourcePath[MAX_PATH];
1643 #ifdef __REACTOS__
1644  NT_PRODUCT_TYPE ProductType;
1645 #endif
1646 
1647  TRACE("0x%02x,%p\n", folder, pszPath);
1648 
1649  if (folder >= ARRAY_SIZE(CSIDL_Data))
1650  return E_INVALIDARG;
1651 
1652  if (!pszPath)
1653  return E_INVALIDARG;
1654 
1655 #ifdef __REACTOS__
1656  if (hToken != NULL && hToken != (HANDLE)-1)
1657  {
1658  FIXME("unsupported for user other than current or default\n");
1659  }
1660 #endif
1661 
1662  if (!is_win64)
1663  {
1664  BOOL is_wow64;
1665 
1666  switch (folder)
1667  {
1668  case CSIDL_PROGRAM_FILES:
1672  break;
1677  break;
1678  }
1679  }
1680 
1681  switch (CSIDL_Data[folder].type)
1682  {
1683  case CSIDL_Type_User:
1684  strcpyW(pszPath, UserProfileW);
1685  break;
1686 #ifdef __REACTOS__
1687  case CSIDL_Type_InMyDocuments:
1688  strcpyW(pszPath, UserProfileW);
1689  if (DoGetProductType(&ProductType) && ProductType == NtProductWinNt)
1690  {
1691  if (IS_INTRESOURCE(CSIDL_Data[CSIDL_MYDOCUMENTS].szDefaultPath))
1692  {
1693  WCHAR szItem[MAX_PATH];
1695  LOWORD(CSIDL_Data[CSIDL_MYDOCUMENTS].szDefaultPath),
1696  szItem, ARRAY_SIZE(szItem));
1697  PathAppendW(pszPath, szItem);
1698  }
1699  else
1700  {
1701  PathAppendW(pszPath, CSIDL_Data[CSIDL_MYDOCUMENTS].szDefaultPath);
1702  }
1703  }
1704  break;
1705 #endif
1706  case CSIDL_Type_AllUsers:
1707 #ifndef __REACTOS__
1708  strcpyW(pszPath, PublicProfileW);
1709 #else
1710  strcpyW(pszPath, AllUsersProfileW);
1711 #endif
1712  break;
1713  case CSIDL_Type_CurrVer:
1714  strcpyW(pszPath, SystemDriveW);
1715  break;
1716  default:
1717  ; /* no corresponding env. var, do nothing */
1718  }
1719 
1720  hr = S_OK;
1721  if (CSIDL_Data[folder].szDefaultPath)
1722  {
1723  if (IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath))
1724  {
1726  LOWORD(CSIDL_Data[folder].szDefaultPath), resourcePath, MAX_PATH))
1727  {
1728  PathAppendW(pszPath, resourcePath);
1729  }
1730  else
1731  {
1732  ERR("(%d,%s), LoadString failed, missing translation?\n", folder,
1733  debugstr_w(pszPath));
1734  hr = E_FAIL;
1735  }
1736  }
1737  else
1738  {
1739  PathAppendW(pszPath, CSIDL_Data[folder].szDefaultPath);
1740  }
1741  }
1742  TRACE("returning 0x%08x\n", hr);
1743  return hr;
1744 }
1745 
1746 /* Gets the (unexpanded) value of the folder with index folder into pszPath.
1747  * The folder's type is assumed to be CSIDL_Type_CurrVer. Its default value
1748  * can be overridden in the HKLM\\szCurrentVersion key.
1749  * If dwFlags has SHGFP_TYPE_DEFAULT set or if the value isn't overridden in
1750  * the registry, uses _SHGetDefaultValue to get the value.
1751  */
1753  LPWSTR pszPath)
1754 {
1755  HRESULT hr;
1756 
1757  TRACE("0x%08x,0x%02x,%p\n", dwFlags, folder, pszPath);
1758 
1759  if (folder >= ARRAY_SIZE(CSIDL_Data))
1760  return E_INVALIDARG;
1762  return E_INVALIDARG;
1763  if (!pszPath)
1764  return E_INVALIDARG;
1765 
1767 #ifndef __REACTOS__
1768  hr = _SHGetDefaultValue(folder, pszPath);
1769 #else
1770  hr = _SHGetDefaultValue(NULL, folder, pszPath);
1771 #endif
1772  else
1773  {
1774  HKEY hKey;
1775 
1777  hr = E_FAIL;
1778  else
1779  {
1780  DWORD dwType, dwPathLen = MAX_PATH * sizeof(WCHAR);
1781 
1782  if (RegQueryValueExW(hKey, CSIDL_Data[folder].szValueName, NULL,
1783  &dwType, (LPBYTE)pszPath, &dwPathLen) ||
1784  (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
1785  {
1786 #ifndef __REACTOS__
1787  hr = _SHGetDefaultValue(folder, pszPath);
1788 #else
1789  hr = _SHGetDefaultValue(NULL, folder, pszPath);
1790 #endif
1791  dwType = REG_EXPAND_SZ;
1792  switch (folder)
1793  {
1796  /* these two should never be set on 32-bit setups */
1797  if (!is_win64)
1798  {
1799  BOOL is_wow64;
1801  if (!is_wow64) break;
1802  }
1803  /* fall through */
1804  default:
1805  RegSetValueExW(hKey, CSIDL_Data[folder].szValueName, 0, dwType,
1806  (LPBYTE)pszPath, (strlenW(pszPath)+1)*sizeof(WCHAR));
1807  }
1808  }
1809  else
1810  {
1811  pszPath[dwPathLen / sizeof(WCHAR)] = '\0';
1812  hr = S_OK;
1813  }
1814  RegCloseKey(hKey);
1815  }
1816  }
1817  TRACE("returning 0x%08x (output path is %s)\n", hr, debugstr_w(pszPath));
1818  return hr;
1819 }
1820 
1822 {
1823  char InfoBuffer[64];
1824  PTOKEN_USER UserInfo;
1825  DWORD InfoSize;
1826  LPWSTR SidStr;
1827 
1828  UserInfo = (PTOKEN_USER) InfoBuffer;
1829  if (! GetTokenInformation(Token, TokenUser, InfoBuffer, sizeof(InfoBuffer),
1830  &InfoSize))
1831  {
1833  return NULL;
1834  UserInfo = HeapAlloc(GetProcessHeap(), 0, InfoSize);
1835  if (UserInfo == NULL)
1836  return NULL;
1837  if (! GetTokenInformation(Token, TokenUser, UserInfo, InfoSize,
1838  &InfoSize))
1839  {
1840  HeapFree(GetProcessHeap(), 0, UserInfo);
1841  return NULL;
1842  }
1843  }
1844 
1845  if (! ConvertSidToStringSidW(UserInfo->User.Sid, &SidStr))
1846  SidStr = NULL;
1847 
1848  if (UserInfo != (PTOKEN_USER) InfoBuffer)
1849  HeapFree(GetProcessHeap(), 0, UserInfo);
1850 
1851  return SidStr;
1852 }
1853 
1854 /* Gets the user's path (unexpanded) for the CSIDL with index folder:
1855  * If SHGFP_TYPE_DEFAULT is set, calls _SHGetDefaultValue for it. Otherwise
1856  * calls _SHGetUserShellFolderPath for it. Where it looks depends on hToken:
1857  * - if hToken is -1, looks in HKEY_USERS\.Default
1858  * - otherwise looks first in HKEY_CURRENT_USER, followed by HKEY_LOCAL_MACHINE
1859  * if HKEY_CURRENT_USER doesn't contain any entries. If both fail, finally
1860  * calls _SHGetDefaultValue for it.
1861  */
1863  LPWSTR pszPath)
1864 {
1865  const WCHAR *szValueName;
1866  WCHAR buffer[40];
1867  HRESULT hr;
1868 
1869  TRACE("%p,0x%08x,0x%02x,%p\n", hToken, dwFlags, folder, pszPath);
1870 
1871  if (folder >= ARRAY_SIZE(CSIDL_Data))
1872  return E_INVALIDARG;
1873 #ifdef __REACTOS__
1875  CSIDL_Data[folder].type != CSIDL_Type_InMyDocuments)
1876 #else
1878 #endif
1879  {
1880  return E_INVALIDARG;
1881  }
1882  if (!pszPath)
1883  return E_INVALIDARG;
1884 
1886  {
1887 #ifndef __REACTOS__
1888  hr = _SHGetDefaultValue(folder, pszPath);
1889 #else
1890  hr = _SHGetDefaultValue(hToken, folder, pszPath);
1891 #endif
1892  }
1893  else
1894  {
1895  LPCWSTR userPrefix = NULL;
1896  HKEY hRootKey;
1897 
1898  if (hToken == (HANDLE)-1)
1899  {
1900  hRootKey = HKEY_USERS;
1901  userPrefix = DefaultW;
1902  }
1903  else if (hToken == NULL)
1904  hRootKey = HKEY_CURRENT_USER;
1905  else
1906  {
1907  hRootKey = HKEY_USERS;
1908  userPrefix = _GetUserSidStringFromToken(hToken);
1909  if (userPrefix == NULL)
1910  {
1911  hr = E_FAIL;
1912  goto error;
1913  }
1914  }
1915 
1916  /* For CSIDL_Type_User we also use the GUID if no szValueName is provided */
1917  szValueName = CSIDL_Data[folder].szValueName;
1918  if (!szValueName)
1919  {
1921  szValueName = &buffer[0];
1922  }
1923 
1924 #ifndef __REACTOS__
1925  hr = _SHGetUserShellFolderPath(hRootKey, userPrefix, szValueName, pszPath);
1926  if (FAILED(hr) && hRootKey != HKEY_LOCAL_MACHINE)
1927  hr = _SHGetUserShellFolderPath(HKEY_LOCAL_MACHINE, NULL, szValueName, pszPath);
1928  if (FAILED(hr))
1929  hr = _SHGetDefaultValue(folder, pszPath);
1930 #else
1931  hr = _SHGetUserShellFolderPath(hRootKey, hToken, userPrefix, szValueName, pszPath);
1932  if (FAILED(hr) && hRootKey != HKEY_LOCAL_MACHINE)
1933  hr = _SHGetUserShellFolderPath(HKEY_LOCAL_MACHINE, hToken, NULL, szValueName, pszPath);
1934  if (FAILED(hr))
1935  hr = _SHGetDefaultValue(hToken, folder, pszPath);
1936 #endif
1937  if (userPrefix != NULL && userPrefix != DefaultW)
1938  LocalFree((HLOCAL) userPrefix);
1939  }
1940 error:
1941  TRACE("returning 0x%08x (output path is %s)\n", hr, debugstr_w(pszPath));
1942  return hr;
1943 }
1944 
1945 /* Gets the (unexpanded) path for the CSIDL with index folder. If dwFlags has
1946  * SHGFP_TYPE_DEFAULT set, calls _SHGetDefaultValue. Otherwise calls
1947  * _SHGetUserShellFolderPath for it, looking only in HKEY_LOCAL_MACHINE.
1948  * If this fails, falls back to _SHGetDefaultValue.
1949  */
1951  LPWSTR pszPath)
1952 {
1953  HRESULT hr;
1954 
1955  TRACE("0x%08x,0x%02x,%p\n", dwFlags, folder, pszPath);
1956 
1957  if (folder >= ARRAY_SIZE(CSIDL_Data))
1958  return E_INVALIDARG;
1960  return E_INVALIDARG;
1961  if (!pszPath)
1962  return E_INVALIDARG;
1963 
1965 #ifndef __REACTOS__
1966  hr = _SHGetDefaultValue(folder, pszPath);
1967 #else
1968  hr = _SHGetDefaultValue(NULL, folder, pszPath);
1969 #endif
1970  else
1971  {
1972 #ifndef __REACTOS__
1974 #else
1976 #endif
1977  CSIDL_Data[folder].szValueName, pszPath);
1978  if (FAILED(hr))
1979 #ifndef __REACTOS__
1980  hr = _SHGetDefaultValue(folder, pszPath);
1981 #else
1982  hr = _SHGetDefaultValue(NULL, folder, pszPath);
1983 #endif
1984  }
1985  TRACE("returning 0x%08x (output path is %s)\n", hr, debugstr_w(pszPath));
1986  return hr;
1987 }
1988 
1989 #ifndef __REACTOS__
1991 {
1992  LONG lRet;
1993  DWORD disp;
1994 
1996  KEY_ALL_ACCESS, NULL, pKey, &disp);
1997  return HRESULT_FROM_WIN32(lRet);
1998 }
1999 
2000 /* Reads the value named szValueName from the key profilesKey (assumed to be
2001  * opened by _SHOpenProfilesKey) into szValue, which is assumed to be MAX_PATH
2002  * WCHARs in length. If it doesn't exist, returns szDefault (and saves
2003  * szDefault to the registry).
2004  */
2005 static HRESULT _SHGetProfilesValue(HKEY profilesKey, LPCWSTR szValueName,
2006  LPWSTR szValue, LPCWSTR szDefault)
2007 {
2008  HRESULT hr;
2009  DWORD type, dwPathLen = MAX_PATH * sizeof(WCHAR);
2010  LONG lRet;
2011 
2012  TRACE("%p,%s,%p,%s\n", profilesKey, debugstr_w(szValueName), szValue,
2013  debugstr_w(szDefault));
2014  lRet = RegQueryValueExW(profilesKey, szValueName, NULL, &type,
2015  (LPBYTE)szValue, &dwPathLen);
2016  if (!lRet && (type == REG_SZ || type == REG_EXPAND_SZ) && dwPathLen
2017  && *szValue)
2018  {
2019  dwPathLen /= sizeof(WCHAR);
2020  szValue[dwPathLen] = '\0';
2021  hr = S_OK;
2022  }
2023  else
2024  {
2025  /* Missing or invalid value, set a default */
2026  lstrcpynW(szValue, szDefault, MAX_PATH);
2027  TRACE("Setting missing value %s to %s\n", debugstr_w(szValueName),
2028  debugstr_w(szValue));
2029  lRet = RegSetValueExW(profilesKey, szValueName, 0, REG_EXPAND_SZ,
2030  (LPBYTE)szValue,
2031  (strlenW(szValue) + 1) * sizeof(WCHAR));
2032  if (lRet)
2033  hr = HRESULT_FROM_WIN32(lRet);
2034  else
2035  hr = S_OK;
2036  }
2037  TRACE("returning 0x%08x (output value is %s)\n", hr, debugstr_w(szValue));
2038  return hr;
2039 }
2040 #endif
2041 
2042 /* Attempts to expand environment variables from szSrc into szDest, which is
2043  * assumed to be MAX_PATH characters in length. Before referring to the
2044  * environment, handles a few variables directly, because the environment
2045  * variables may not be set when this is called (as during Wine's installation
2046  * when default values are being written to the registry).
2047  * The directly handled environment variables, and their source, are:
2048  * - ALLUSERSPROFILE, USERPROFILE: reads from the registry
2049  * - SystemDrive: uses GetSystemDirectoryW and uses the drive portion of its
2050  * path
2051  * If one of the directly handled environment variables is expanded, only
2052  * expands a single variable, and only in the beginning of szSrc.
2053  */
2054 #ifndef __REACTOS__
2056 #else
2057 static HRESULT _SHExpandEnvironmentStrings(HANDLE hToken, LPCWSTR szSrc, LPWSTR szDest, DWORD cchDest)
2058 #endif
2059 {
2060  HRESULT hr;
2061 #ifndef __REACTOS__
2062  WCHAR szTemp[MAX_PATH], szProfilesPrefix[MAX_PATH] = { 0 };
2063  HKEY key = NULL;
2064 #else
2065  WCHAR szTemp[MAX_PATH];
2066 #endif
2067 
2068  TRACE("%s, %p\n", debugstr_w(szSrc), szDest);
2069 
2070  if (!szSrc || !szDest) return E_INVALIDARG;
2071 
2072  /* short-circuit if there's nothing to expand */
2073  if (szSrc[0] != '%')
2074  {
2075  strcpyW(szDest, szSrc);
2076  hr = S_OK;
2077  goto end;
2078  }
2079 #ifndef __REACTOS__
2080  /* Get the profile prefix, we'll probably be needing it */
2082  if (SUCCEEDED(hr))
2083  {
2084  WCHAR def_val[MAX_PATH];
2085 
2086  /* get the system drive */
2087  GetSystemDirectoryW(def_val, MAX_PATH);
2088  strcpyW( def_val + 3, szDefaultProfileDirW );
2089 
2090  hr = _SHGetProfilesValue(key, ProfilesDirectoryW, szProfilesPrefix, def_val );
2091  }
2092 #else
2093  hr = S_OK;
2094 #endif
2095 
2096  *szDest = 0;
2097  strcpyW(szTemp, szSrc);
2098  while (SUCCEEDED(hr) && szTemp[0] == '%')
2099  {
2101  {
2102 #ifndef __REACTOS__
2104 
2105  strcpyW(szDest, szProfilesPrefix);
2108  PathAppendW(szDest, szAllUsers);
2109 #else
2110  DWORD cchSize = cchDest;
2111  if (!GetAllUsersProfileDirectoryW(szDest, &cchSize))
2112  goto fallback_expand;
2113 #endif
2114  PathAppendW(szDest, szTemp + strlenW(AllUsersProfileW));
2115  }
2116 #ifndef __REACTOS__
2117  else if (!strncmpiW(szTemp, PublicProfileW, strlenW(PublicProfileW)))
2118  {
2119  WCHAR szAllUsers[MAX_PATH], def_val[MAX_PATH];
2120 
2121  GetSystemDirectoryW(def_val, MAX_PATH);
2122  strcpyW( def_val + 3, UsersPublicW );
2123 
2125  PathAppendW(szDest, szAllUsers);
2126  PathAppendW(szDest, szTemp + strlenW(PublicProfileW));
2127  }
2128 #endif
2129  else if (!strncmpiW(szTemp, UserProfileW, strlenW(UserProfileW)))
2130  {
2131 #ifndef __REACTOS__
2133  DWORD userLen = MAX_PATH;
2134 
2135  strcpyW(szDest, szProfilesPrefix);
2136  GetUserNameW(userName, &userLen);
2137  PathAppendW(szDest, userName);
2138 #else
2139  DWORD cchSize = cchDest;
2140  if (!_SHGetUserProfileDirectoryW(hToken, szDest, &cchSize))
2141  goto fallback_expand;
2142 #endif
2143  PathAppendW(szDest, szTemp + strlenW(UserProfileW));
2144  }
2145  else if (!strncmpiW(szTemp, SystemDriveW, strlenW(SystemDriveW)))
2146  {
2147 #ifndef __REACTOS__
2148  GetSystemDirectoryW(szDest, MAX_PATH);
2149 #else
2150  if (!GetSystemDirectoryW(szDest, cchDest))
2151  goto fallback_expand;
2152 #endif
2153  strcpyW(szDest + 3, szTemp + strlenW(SystemDriveW) + 1);
2154  }
2155  else
2156 #ifdef __REACTOS__
2157 fallback_expand:
2158 #endif
2159  {
2160 #ifndef __REACTOS__
2161  DWORD ret = ExpandEnvironmentStringsW(szTemp, szDest, MAX_PATH);
2162 #else
2163  DWORD ret = SHExpandEnvironmentStringsForUserW(hToken, szTemp, szDest, cchDest);
2164 #endif
2165 
2166 #ifndef __REACTOS__
2167  if (ret > MAX_PATH)
2168 #else
2169  if (ret > cchDest)
2170 #endif
2172  else if (ret == 0)
2174  else if (!strcmpW( szTemp, szDest )) break; /* nothing expanded */
2175  }
2176  if (SUCCEEDED(hr)) strcpyW(szTemp, szDest);
2177  }
2178 end:
2179 #ifndef __REACTOS__
2180  if (key)
2181  RegCloseKey(key);
2182 #endif
2183  TRACE("returning 0x%08x (input was %s, output is %s)\n", hr,
2184  debugstr_w(szSrc), debugstr_w(szDest));
2185  return hr;
2186 }
2187 
2188 /*************************************************************************
2189  * SHGetFolderPathW [SHELL32.@]
2190  *
2191  * Convert nFolder to path.
2192  *
2193  * RETURNS
2194  * Success: S_OK
2195  * Failure: standard HRESULT error codes.
2196  *
2197  * NOTES
2198  * Most values can be overridden in either
2199  * HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
2200  * or in the same location in HKLM.
2201  * The "Shell Folders" registry key was used in NT4 and earlier systems.
2202  * Beginning with Windows 2000, the "User Shell Folders" key is used, so
2203  * changes made to it are made to the former key too. This synchronization is
2204  * done on-demand: not until someone requests the value of one of these paths
2205  * (by calling one of the SHGet functions) is the value synchronized.
2206  * Furthermore, the HKCU paths take precedence over the HKLM paths.
2207  */
2209  HWND hwndOwner, /* [I] owner window */
2210  int nFolder, /* [I] CSIDL identifying the folder */
2211  HANDLE hToken, /* [I] access token */
2212  DWORD dwFlags, /* [I] which path to return */
2213  LPWSTR pszPath) /* [O] converted path */
2214 {
2215  HRESULT hr = SHGetFolderPathAndSubDirW(hwndOwner, nFolder, hToken, dwFlags, NULL, pszPath);
2218  return hr;
2219 }
2220 
2222  HWND hwndOwner, /* [I] owner window */
2223  int nFolder, /* [I] CSIDL identifying the folder */
2224  HANDLE hToken, /* [I] access token */
2225  DWORD dwFlags, /* [I] which path to return */
2226  LPCSTR pszSubPath, /* [I] sub directory of the specified folder */
2227  LPSTR pszPath) /* [O] converted path */
2228 {
2229  int length;
2230  HRESULT hr = S_OK;
2231  LPWSTR pszSubPathW = NULL;
2232  LPWSTR pszPathW = NULL;
2233 
2234  TRACE("%p,%#x,%p,%#x,%s,%p\n", hwndOwner, nFolder, hToken, dwFlags, debugstr_a(pszSubPath), pszPath);
2235 
2236  if(pszPath) {
2237  pszPathW = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
2238  if(!pszPathW) {
2240  goto cleanup;
2241  }
2242  }
2243  TRACE("%08x,%08x,%s\n",nFolder, dwFlags, debugstr_w(pszSubPathW));
2244 
2245  /* SHGetFolderPathAndSubDirW does not distinguish if pszSubPath isn't
2246  * set (null), or an empty string.therefore call it without the parameter set
2247  * if pszSubPath is an empty string
2248  */
2249  if (pszSubPath && pszSubPath[0]) {
2250  length = MultiByteToWideChar(CP_ACP, 0, pszSubPath, -1, NULL, 0);
2251  pszSubPathW = HeapAlloc(GetProcessHeap(), 0, length * sizeof(WCHAR));
2252  if(!pszSubPathW) {
2254  goto cleanup;
2255  }
2256  MultiByteToWideChar(CP_ACP, 0, pszSubPath, -1, pszSubPathW, length);
2257  }
2258 
2259  hr = SHGetFolderPathAndSubDirW(hwndOwner, nFolder, hToken, dwFlags, pszSubPathW, pszPathW);
2260 
2261  if (SUCCEEDED(hr) && pszPath)
2262  WideCharToMultiByte(CP_ACP, 0, pszPathW, -1, pszPath, MAX_PATH, NULL, NULL);
2263 
2264 cleanup:
2265  HeapFree(GetProcessHeap(), 0, pszPathW);
2266  HeapFree(GetProcessHeap(), 0, pszSubPathW);
2267  return hr;
2268 }
2269 
2270 /*************************************************************************
2271  * SHGetFolderPathAndSubDirW [SHELL32.@]
2272  */
2274  HWND hwndOwner, /* [I] owner window */
2275  int nFolder, /* [I] CSIDL identifying the folder */
2276  HANDLE hToken, /* [I] access token */
2277  DWORD dwFlags, /* [I] which path to return */
2278  LPCWSTR pszSubPath,/* [I] sub directory of the specified folder */
2279  LPWSTR pszPath) /* [O] converted path */
2280 {
2281  HRESULT hr;
2282  WCHAR szBuildPath[MAX_PATH], szTemp[MAX_PATH];
2284  CSIDL_Type type;
2285  int ret;
2286 
2287  TRACE("%p,%#x,%p,%#x,%s,%p\n", hwndOwner, nFolder, hToken, dwFlags, debugstr_w(pszSubPath), pszPath);
2288 
2289  /* Windows always NULL-terminates the resulting path regardless of success
2290  * or failure, so do so first
2291  */
2292  if (pszPath)
2293  *pszPath = '\0';
2294 
2295  if (folder >= ARRAY_SIZE(CSIDL_Data))
2296  return E_INVALIDARG;
2298  return E_INVALIDARG;
2299  szTemp[0] = 0;
2301  switch (type)
2302  {
2303  case CSIDL_Type_Disallowed:
2304  hr = E_INVALIDARG;
2305  break;
2307  hr = S_FALSE;
2308  break;
2310  GetWindowsDirectoryW(szTemp, MAX_PATH);
2311  if (CSIDL_Data[folder].szDefaultPath &&
2312  !IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath) &&
2313  *CSIDL_Data[folder].szDefaultPath)
2314  {
2315  PathAddBackslashW(szTemp);
2316  strcatW(szTemp, CSIDL_Data[folder].szDefaultPath);
2317  }
2318  hr = S_OK;
2319  break;
2320  case CSIDL_Type_SystemPath:
2321  GetSystemDirectoryW(szTemp, MAX_PATH);
2322  if (CSIDL_Data[folder].szDefaultPath &&
2323  !IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath) &&
2324  *CSIDL_Data[folder].szDefaultPath)
2325  {
2326  PathAddBackslashW(szTemp);
2327  strcatW(szTemp, CSIDL_Data[folder].szDefaultPath);
2328  }
2329  hr = S_OK;
2330  break;
2333  if (CSIDL_Data[folder].szDefaultPath &&
2334  !IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath) &&
2335  *CSIDL_Data[folder].szDefaultPath)
2336  {
2337  PathAddBackslashW(szTemp);
2338  strcatW(szTemp, CSIDL_Data[folder].szDefaultPath);
2339  }
2340  hr = S_OK;
2341  break;
2342  case CSIDL_Type_CurrVer:
2344  break;
2345  case CSIDL_Type_User:
2346 #ifdef __REACTOS__
2347  case CSIDL_Type_InMyDocuments:
2348 #endif
2349  hr = _SHGetUserProfilePath(hToken, dwFlags, folder, szTemp);
2350  break;
2351  case CSIDL_Type_AllUsers:
2353  break;
2354  default:
2355  FIXME("bogus type %d, please fix\n", type);
2356  hr = E_INVALIDARG;
2357  break;
2358  }
2359 
2360  /* Expand environment strings if necessary */
2361  if (*szTemp == '%')
2362 #ifndef __REACTOS__
2363  hr = _SHExpandEnvironmentStrings(szTemp, szBuildPath);
2364 #else
2365  hr = _SHExpandEnvironmentStrings(hToken, szTemp, szBuildPath, _countof(szBuildPath));
2366 #endif
2367  else
2368  strcpyW(szBuildPath, szTemp);
2369 
2370  if (FAILED(hr)) goto end;
2371 
2372  if(pszSubPath) {
2373  /* make sure the new path does not exceed the buffer length
2374  * and remember to backslash and terminate it */
2375  if(MAX_PATH < (lstrlenW(szBuildPath) + lstrlenW(pszSubPath) + 2)) {
2377  goto end;
2378  }
2379  PathAppendW(szBuildPath, pszSubPath);
2380  PathRemoveBackslashW(szBuildPath);
2381  }
2382  /* Copy the path if it's available before we might return */
2383  if (SUCCEEDED(hr) && pszPath)
2384  strcpyW(pszPath, szBuildPath);
2385 
2386  /* if we don't care about existing directories we are ready */
2387  if(nFolder & CSIDL_FLAG_DONT_VERIFY) goto end;
2388 
2389  if (PathFileExistsW(szBuildPath)) goto end;
2390 
2391  /* not existing but we are not allowed to create it. The return value
2392  * is verified against shell32 version 6.0.
2393  */
2394  if (!(nFolder & CSIDL_FLAG_CREATE))
2395  {
2397  goto end;
2398  }
2399 
2400  /* create directory/directories */
2401  ret = SHCreateDirectoryExW(hwndOwner, szBuildPath, NULL);
2402  if (ret && ret != ERROR_ALREADY_EXISTS)
2403  {
2404  ERR("Failed to create directory %s.\n", debugstr_w(szBuildPath));
2405  hr = E_FAIL;
2406  goto end;
2407  }
2408 
2409  TRACE("Created missing system directory %s\n", debugstr_w(szBuildPath));
2410 
2411 end:
2412  /* create desktop.ini for custom icon */
2413  if ((nFolder & CSIDL_FLAG_CREATE) &&
2414  CSIDL_Data[folder].nShell32IconIndex)
2415  {
2416  static const WCHAR s_szFormat[] = L"%%SystemRoot%%\\system32\\shell32.dll,%d";
2417  WCHAR szIconLocation[MAX_PATH];
2419 
2420  /* make the directory a read-only folder */
2421  dwAttributes = GetFileAttributesW(szBuildPath);
2423  SetFileAttributesW(szBuildPath, dwAttributes);
2424 
2425  /* build the desktop.ini file path */
2426  PathAppendW(szBuildPath, L"desktop.ini");
2427 
2428  /* build the icon location */
2429  StringCchPrintfW(szIconLocation, _countof(szIconLocation), s_szFormat,
2430  CSIDL_Data[folder].nShell32IconIndex);
2431 
2432  /* write desktop.ini */
2433  WritePrivateProfileStringW(L".ShellClassInfo", L"IconResource", szIconLocation, szBuildPath);
2434 
2435  /* flush! */
2436  WritePrivateProfileStringW(NULL, NULL, NULL, szBuildPath);
2437 
2438  /* make the desktop.ini a system and hidden file */
2439  dwAttributes = GetFileAttributesW(szBuildPath);
2441  SetFileAttributesW(szBuildPath, dwAttributes);
2442  }
2443 
2444  TRACE("returning 0x%08x (final path is %s)\n", hr, debugstr_w(szBuildPath));
2445  return hr;
2446 }
2447 
2448 /*************************************************************************
2449  * SHGetFolderPathA [SHELL32.@]
2450  *
2451  * See SHGetFolderPathW.
2452  */
2454  HWND hwndOwner,
2455  int nFolder,
2456  HANDLE hToken,
2457  DWORD dwFlags,
2458  LPSTR pszPath)
2459 {
2460  WCHAR szTemp[MAX_PATH];
2461  HRESULT hr;
2462 
2463  TRACE("%p,%d,%p,%#x,%p\n", hwndOwner, nFolder, hToken, dwFlags, pszPath);
2464 
2465  if (pszPath)
2466  *pszPath = '\0';
2467  hr = SHGetFolderPathW(hwndOwner, nFolder, hToken, dwFlags, szTemp);
2468  if (SUCCEEDED(hr) && pszPath)
2469  WideCharToMultiByte(CP_ACP, 0, szTemp, -1, pszPath, MAX_PATH, NULL,
2470  NULL);
2471 
2472  return hr;
2473 }
2474 
2475 /* For each folder in folders, if its value has not been set in the registry,
2476  * calls _SHGetUserProfilePath or _SHGetAllUsersProfilePath (depending on the
2477  * folder's type) to get the unexpanded value first.
2478  * Writes the unexpanded value to User Shell Folders, and queries it with
2479  * SHGetFolderPathW to force the creation of the directory if it doesn't
2480  * already exist. SHGetFolderPathW also returns the expanded value, which
2481  * this then writes to Shell Folders.
2482  */
2483 static HRESULT _SHRegisterFolders(HKEY hRootKey, HANDLE hToken,
2484  LPCWSTR szUserShellFolderPath, LPCWSTR szShellFolderPath, const UINT folders[],
2485  UINT foldersLen)
2486 {
2487  const WCHAR *szValueName;
2488  WCHAR buffer[40];
2489  UINT i;
2490  WCHAR path[MAX_PATH];
2491  HRESULT hr = S_OK;
2492  HKEY hUserKey = NULL, hKey = NULL;
2493  DWORD dwType, dwPathLen;
2494  LONG ret;
2495 
2496  TRACE("%p,%p,%s,%p,%u\n", hRootKey, hToken,
2497  debugstr_w(szUserShellFolderPath), folders, foldersLen);
2498 
2499  ret = RegCreateKeyW(hRootKey, szUserShellFolderPath, &hUserKey);
2500  if (ret)
2502  else
2503  {
2504  ret = RegCreateKeyW(hRootKey, szShellFolderPath, &hKey);
2505  if (ret)
2507  }
2508  for (i = 0; SUCCEEDED(hr) && i < foldersLen; i++)
2509  {
2510  dwPathLen = MAX_PATH * sizeof(WCHAR);
2511 
2512  /* For CSIDL_Type_User we also use the GUID if no szValueName is provided */
2513  szValueName = CSIDL_Data[folders[i]].szValueName;
2514 #ifdef __REACTOS__
2515  if (!szValueName &&
2516  (CSIDL_Data[folders[i]].type == CSIDL_Type_User ||
2517  CSIDL_Data[folders[i]].type == CSIDL_Type_InMyDocuments))
2518 #else
2519  if (!szValueName && CSIDL_Data[folders[i]].type == CSIDL_Type_User)
2520 #endif
2521  {
2522  StringFromGUID2( CSIDL_Data[folders[i]].id, buffer, 39 );
2523  szValueName = &buffer[0];
2524  }
2525 
2526  if (!RegQueryValueExW(hUserKey, szValueName, NULL,
2527  &dwType, (LPBYTE)path, &dwPathLen) &&
2528  (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
2529  {
2530  hr = SHGetFolderPathW(NULL, folders[i] | CSIDL_FLAG_CREATE,
2531  hToken, SHGFP_TYPE_CURRENT, path);
2532  }
2533  else
2534  {
2535  *path = '\0';
2536 #ifdef __REACTOS__
2537  if (CSIDL_Data[folders[i]].type == CSIDL_Type_User ||
2538  CSIDL_Data[folders[i]].type == CSIDL_Type_InMyDocuments)
2539 #else
2540  if (CSIDL_Data[folders[i]].type == CSIDL_Type_User)
2541 #endif
2542  _SHGetUserProfilePath(hToken, SHGFP_TYPE_CURRENT, folders[i],
2543  path);
2544  else if (CSIDL_Data[folders[i]].type == CSIDL_Type_AllUsers)
2546  else if (CSIDL_Data[folders[i]].type == CSIDL_Type_WindowsPath)
2547  {
2549  if (CSIDL_Data[folders[i]].szDefaultPath &&
2550  !IS_INTRESOURCE(CSIDL_Data[folders[i]].szDefaultPath))
2551  {
2553  strcatW(path, CSIDL_Data[folders[i]].szDefaultPath);
2554  }
2555  }
2556  else
2557  hr = E_FAIL;
2558  if (*path)
2559  {
2560  ret = RegSetValueExW(hUserKey, szValueName, 0, REG_EXPAND_SZ,
2561  (LPBYTE)path, (strlenW(path) + 1) * sizeof(WCHAR));
2562  if (ret)
2564  else
2565  {
2566  hr = SHGetFolderPathW(NULL, folders[i] | CSIDL_FLAG_CREATE,
2567  hToken, SHGFP_TYPE_CURRENT, path);
2568  ret = RegSetValueExW(hKey, szValueName, 0, REG_SZ,
2569  (LPBYTE)path, (strlenW(path) + 1) * sizeof(WCHAR));
2570  if (ret)
2572  }
2573  }
2574  }
2575  }
2576  if (hUserKey)
2577  RegCloseKey(hUserKey);
2578  if (hKey)
2579  RegCloseKey(hKey);
2580 
2581  TRACE("returning 0x%08x\n", hr);
2582  return hr;
2583 }
2584 
2586 {
2587  static const UINT folders[] = {
2591  CSIDL_APPDATA,
2592  CSIDL_STARTUP,
2593  CSIDL_RECENT,
2594  CSIDL_SENDTO,
2596  CSIDL_MYMUSIC,
2597  CSIDL_MYVIDEO,
2599  CSIDL_NETHOOD,
2604  CSIDL_COOKIES,
2605  CSIDL_HISTORY,
2607  CSIDL_FONTS,
2609 /* Cannot use #if _WIN32_WINNT >= 0x0600 because _WIN32_WINNT == 0x0600 here. */
2610 #ifndef __REACTOS__
2613  CSIDL_LINKS,
2617 #endif
2618  };
2619  WCHAR userShellFolderPath[MAX_PATH], shellFolderPath[MAX_PATH];
2620  LPCWSTR pUserShellFolderPath, pShellFolderPath;
2621  HRESULT hr = S_OK;
2622  HKEY hRootKey;
2623  HANDLE hToken;
2624 
2625  TRACE("%s\n", bDefault ? "TRUE" : "FALSE");
2626  if (bDefault)
2627  {
2628  hToken = (HANDLE)-1;
2629  hRootKey = HKEY_USERS;
2630  strcpyW(userShellFolderPath, DefaultW);
2631  PathAddBackslashW(userShellFolderPath);
2632  strcatW(userShellFolderPath, szSHUserFolders);
2633  pUserShellFolderPath = userShellFolderPath;
2634  strcpyW(shellFolderPath, DefaultW);
2635  PathAddBackslashW(shellFolderPath);
2636  strcatW(shellFolderPath, szSHFolders);
2637  pShellFolderPath = shellFolderPath;
2638  }
2639  else
2640  {
2641  hToken = NULL;
2642  hRootKey = HKEY_CURRENT_USER;
2643  pUserShellFolderPath = szSHUserFolders;
2644  pShellFolderPath = szSHFolders;
2645  }
2646 
2647  hr = _SHRegisterFolders(hRootKey, hToken, pUserShellFolderPath,
2648  pShellFolderPath, folders, ARRAY_SIZE(folders));
2649  TRACE("returning 0x%08x\n", hr);
2650  return hr;
2651 }
2652 
2654 {
2655  static const UINT folders[] = {
2668  };
2669  HRESULT hr;
2670 
2671  TRACE("\n");
2673  szSHFolders, folders, ARRAY_SIZE(folders));
2674  TRACE("returning 0x%08x\n", hr);
2675  return hr;
2676 }
2677 
2678 /* Register the default values in the registry, as some apps seem to depend
2679  * on their presence. The set registered was taken from Windows XP.
2680  */
2682 {
2683  HRESULT hr;
2684 
2686  if (SUCCEEDED(hr))
2688  if (SUCCEEDED(hr))
2690  return hr;
2691 }
2692 
2693 /*************************************************************************
2694  * SHGetSpecialFolderPathA [SHELL32.@]
2695  */
2697  HWND hwndOwner,
2698  LPSTR szPath,
2699  int nFolder,
2700  BOOL bCreate)
2701 {
2702  return SHGetFolderPathA(hwndOwner, nFolder + (bCreate ? CSIDL_FLAG_CREATE : 0), NULL, 0,
2703  szPath) == S_OK;
2704 }
2705 
2706 /*************************************************************************
2707  * SHGetSpecialFolderPathW
2708  */
2710  HWND hwndOwner,
2711  LPWSTR szPath,
2712  int nFolder,
2713  BOOL bCreate)
2714 {
2715  return SHGetFolderPathW(hwndOwner, nFolder + (bCreate ? CSIDL_FLAG_CREATE : 0), NULL, 0,
2716  szPath) == S_OK;
2717 }
2718 
2719 /*************************************************************************
2720  * SHGetFolderLocation [SHELL32.@]
2721  *
2722  * Gets the folder locations from the registry and creates a pidl.
2723  *
2724  * PARAMS
2725  * hwndOwner [I]
2726  * nFolder [I] CSIDL_xxxxx
2727  * hToken [I] token representing user, or NULL for current user, or -1 for
2728  * default user
2729  * dwReserved [I] must be zero
2730  * ppidl [O] PIDL of a special folder
2731  *
2732  * RETURNS
2733  * Success: S_OK
2734  * Failure: Standard OLE-defined error result, S_FALSE or E_INVALIDARG
2735  *
2736  * NOTES
2737  * Creates missing reg keys and directories.
2738  * Mostly forwards to SHGetFolderPathW, but a few values of nFolder return
2739  * virtual folders that are handled here.
2740  */
2742  HWND hwndOwner,
2743  int nFolder,
2744  HANDLE hToken,
2745  DWORD dwReserved,
2746  LPITEMIDLIST *ppidl)
2747 {
2749 
2750  TRACE("%p 0x%08x %p 0x%08x %p\n",
2751  hwndOwner, nFolder, hToken, dwReserved, ppidl);
2752 
2753  if (!ppidl)
2754  return E_INVALIDARG;
2755  if (dwReserved)
2756  return E_INVALIDARG;
2757 
2758  /* The virtual folders' locations are not user-dependent */
2759  *ppidl = NULL;
2760  switch (nFolder & CSIDL_FOLDER_MASK)
2761  {
2762  case CSIDL_DESKTOP:
2763  *ppidl = _ILCreateDesktop();
2764  break;
2765 
2766  case CSIDL_PERSONAL:
2767  *ppidl = _ILCreateMyDocuments();
2768  break;
2769 
2770  case CSIDL_INTERNET:
2771  *ppidl = _ILCreateIExplore();
2772  break;
2773 
2774  case CSIDL_CONTROLS:
2775  *ppidl = _ILCreateControlPanel();
2776  break;
2777 
2778  case CSIDL_PRINTERS:
2779  *ppidl = _ILCreatePrinters();
2780  break;
2781 
2782  case CSIDL_BITBUCKET:
2783  *ppidl = _ILCreateBitBucket();
2784  break;
2785 
2786  case CSIDL_DRIVES:
2787  *ppidl = _ILCreateMyComputer();
2788  break;
2789 
2790  case CSIDL_NETWORK:
2791  *ppidl = _ILCreateNetwork();
2792  break;
2793 
2794  default:
2795  {
2797 
2798  hr = SHGetFolderPathW(hwndOwner, nFolder, hToken,
2800  if (SUCCEEDED(hr))
2801  {
2802  DWORD attributes=0;
2803 
2804  TRACE("Value=%s\n", debugstr_w(szPath));
2805  hr = SHILCreateFromPathW(szPath, ppidl, &attributes);
2806  }
2808  {
2809  /* unlike SHGetFolderPath, SHGetFolderLocation in shell32
2810  * version 6.0 returns E_FAIL for nonexistent paths
2811  */
2812  hr = E_FAIL;
2813  }
2814  }
2815  }
2816  if(*ppidl)
2817  hr = S_OK;
2818 
2819  TRACE("-- (new pidl %p)\n",*ppidl);
2820  return hr;
2821 }
2822 
2823 /*************************************************************************
2824  * SHGetSpecialFolderLocation [SHELL32.@]
2825  *
2826  * NOTES
2827  * In NT5, SHGetSpecialFolderLocation needs the <winntdir>/Recent
2828  * directory.
2829  */
2831  HWND hwndOwner,
2832  INT nFolder,
2833  LPITEMIDLIST * ppidl)
2834 {
2836 
2837  TRACE("(%p,0x%x,%p)\n", hwndOwner,nFolder,ppidl);
2838 
2839  if (!ppidl)
2840  return E_INVALIDARG;
2841 
2842  hr = SHGetFolderLocation(hwndOwner, nFolder, NULL, 0, ppidl);
2843  return hr;
2844 }
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:2653
BOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:944
static const WCHAR Common_DesktopW[]
Definition: shellpath.c:588
static const WCHAR FavoritesW[]
Definition: shellpath.c:609
static LONG PathProcessCommandA(LPCSTR lpszPath, LPSTR lpszBuff, DWORD dwBuffSize, DWORD dwFlags)
Definition: shellpath.c:530
static const WCHAR UsersW[]
Definition: shellpath.c:671
disp
Definition: i386-dis.c:3181
#define IDI_SHELL_RECENT_DOCUMENTS
Definition: shresdef.h:499
static const WCHAR PublicProfileW[]
Definition: shellpath.c:679
static const WCHAR ContactsW[]
Definition: shellpath.c:601
#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:112
BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
Definition: path.c:624
#define IDS_STARTMENU
Definition: shresdef.h:84
#define TRUE
Definition: types.h:120
static const WCHAR DocumentsW[]
Definition: shellpath.c:606
static const WCHAR Microsoft_Windows_LibrariesW[]
Definition: shellpath.c:624
#define CloseHandle
Definition: compat.h:407
LPCWSTR szDefaultPath
Definition: shellpath.c:726
static const WCHAR RecentW[]
Definition: shellpath.c:655
LPITEMIDLIST _ILCreateDesktop(void)
Definition: pidl.c:1596
#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:546
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
static const WCHAR UserProfileW[]
Definition: shellpath.c:681
#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:693
#define WideCharToMultiByte
Definition: compat.h:101
HRESULT hr
Definition: shlfolder.c:183
#define error(str)
Definition: mkdosfs.c:1605
static HRESULT _SHExpandEnvironmentStrings(LPCWSTR szSrc, LPWSTR szDest)
Definition: shellpath.c:2055
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
LPITEMIDLIST _ILCreatePrinters(void)
Definition: pidl.c:1644
int WINAPI PathCleanupSpec(LPCWSTR lpszPathW, LPWSTR lpszFileW)
Definition: shellpath.c:407
static const WCHAR FontsW[]
Definition: shellpath.c:610
#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
static const WCHAR Common_ProgramsW[]
Definition: shellpath.c:595
#define CSIDL_MYPICTURES
Definition: shlobj.h:2050
#define IDS_APPDATA
Definition: shresdef.h:90
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static const WCHAR CommonFilesDirW[]
Definition: shellpath.c:591
#define IDI_SHELL_CONTROL_PANEL
Definition: shresdef.h:500
static const WCHAR Microsoft_Windows_RingtonesW[]
Definition: shellpath.c:625
#define KEY_READ
Definition: nt_native.h:1023
#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:1752
#define CSIDL_CONTACTS
Definition: shellpath.c:713
#define CP_ACP
Definition: compat.h:99
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:562
#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:2483
char CHAR
Definition: xmlstorage.h:175
#define IDS_COMMON_MUSIC
Definition: shresdef.h:101
#define IDI_SHELL_COMPUTER_FOLDER
Definition: shresdef.h:521
BOOL WINAPI PathAppendA(LPSTR lpszPath, LPCSTR lpszAppend)
Definition: path.c:101
static BOOL PathMakeUniqueNameW(LPWSTR lpszBuffer, DWORD dwBuffSize, LPCWSTR lpszShortName, LPCWSTR lpszLongName, LPCWSTR lpszPathName)
Definition: shellpath.c:337
#define IDS_INTERNET_CACHE
Definition: shresdef.h:93
static const WCHAR SendToW[]
Definition: shellpath.c:661
_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
static const WCHAR Program_FilesW[]
Definition: shellpath.c:644
static const CSIDL_DATA CSIDL_Data[]
Definition: shellpath.c:730
static const WCHAR VideosW[]
Definition: shellpath.c:673
#define CSIDL_COMMON_STARTUP
Definition: shlobj.h:2035
#define IDS_PERSONAL
Definition: shresdef.h:255
#define IDI_SHELL_FAVORITES
Definition: shresdef.h:522
#define IDS_FAVORITES
Definition: resource.h:31
_In_ int nFolder
Definition: shlobj.h:1444
enum _CSIDL_Type CSIDL_Type
static BOOL PathQualifyA(LPCSTR pszPath)
Definition: shellpath.c:479
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#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:1734
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
UINT WINAPI PathGetCharTypeW(WCHAR ch)
Definition: path.c:3015
#define IDI_SHELL_MY_MOVIES
Definition: shresdef.h:607
GLuint buffer
Definition: glext.h:5915
static const WCHAR OEM_LinksW[]
Definition: shellpath.c:635
#define CSIDL_BITBUCKET
Definition: shlobj.h:2022
static const WCHAR TemplatesW[]
Definition: shellpath.c:669
#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:150
GLuint GLuint end
Definition: gl.h:1545
#define CSIDL_COMMON_PICTURES
Definition: shlobj.h:2062
static const WCHAR szCurrentVersion[]
Definition: shellpath.c:577
#define IDI_SHELL_PROGRAMS_FOLDER
Definition: shresdef.h:498
static const WCHAR ProfilesDirectoryW[]
Definition: shellpath.c:685
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
static const WCHAR AppDataW[]
Definition: shellpath.c:579
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:3259
#define PCS_FATAL
Definition: shlobj.h:331
#define CSIDL_FONTS
Definition: shlobj.h:2031
#define lstrlenW
Definition: compat.h:416
#define E_FAIL
Definition: ddrawi.h:102
static const WCHAR Local_AppDataW[]
Definition: shellpath.c:615
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:57
BOOL WINAPI PathRemoveFileSpecA(LPSTR lpszPath)
Definition: path.c:581
static const WCHAR Common_FavoritesW[]
Definition: shellpath.c:590
WINE_DEFAULT_DEBUG_CHANNEL(shell)
#define CSIDL_INTERNET_CACHE
Definition: shlobj.h:2043
static const WCHAR ProgramsW[]
Definition: shellpath.c:651
BOOL WINAPI IsLFNDriveAW(LPCVOID lpszPath)
Definition: shellpath.c:308
DWORD dwAttributes
Definition: vdmdbg.h:34
#define CSIDL_COMMON_TEMPLATES
Definition: shlobj.h:2056
#define IDI_SHELL_PRINTERS_FOLDER
Definition: shresdef.h:516
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:406
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:121
#define CSIDL_PROGRAM_FILESX86
Definition: shlobj.h:2053
static const WCHAR szSHUserFolders[]
Definition: shellpath.c:689
#define CSIDL_COMMON_PROGRAMS
Definition: shlobj.h:2034
static const WCHAR Common_TemplatesW[]
Definition: shellpath.c:598
static const WCHAR MusicW[]
Definition: shellpath.c:626
static const WCHAR Music_PlaylistsW[]
Definition: shellpath.c:627
#define CSIDL_MYDOCUMENTS
Definition: shlobj.h:2024
#define CSIDL_RECENT
Definition: shlobj.h:2020
static const WCHAR ProgramFilesDirW[]
Definition: shellpath.c:649
static const WCHAR Local_Settings_Application_DataW[]
Definition: shellpath.c:617
#define CSIDL_FOLDER_MASK
Definition: shlobj.h:2070
enum _NT_PRODUCT_TYPE * PNT_PRODUCT_TYPE
static const WCHAR Program_Files_x86W[]
Definition: shellpath.c:647
#define IDS_PRINTHOOD
Definition: shresdef.h:91
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 PCS_PATHTOOLONG
Definition: shlobj.h:335
BOOL WINAPI SHGetSpecialFolderPathA(HWND hwndOwner, LPSTR szPath, int nFolder, BOOL bCreate)
Definition: shellpath.c:2696
#define CSIDL_PRINTERS
Definition: shlobj.h:2016
#define IDI_SHELL_DESKTOP
Definition: shresdef.h:513
#define CSIDL_DRIVES
Definition: shlobj.h:2028
#define GCT_WILD
Definition: shlwapi.h:778
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:53
static const WCHAR Administrative_ToolsW[]
Definition: shellpath.c:578
HINSTANCE shell32_hInstance
Definition: misc.cpp:82
#define CSIDL_FAVORITES
Definition: shlobj.h:2018
static const WCHAR PublicW[]
Definition: shellpath.c:653
void WINAPI PathRemoveExtensionW(LPWSTR lpszPath)
Definition: path.c:818
BOOL _SHGetUserProfileDirectoryW(HANDLE hToken, LPWSTR szPath, LPDWORD lpcchPath)
Definition: shellpath.c:1600
_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:289
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
static const WCHAR Videos_Sample_VideosW[]
Definition: shellpath.c:674
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:802
BOOL WINAPI PathIsRootAW(LPCVOID lpszPath)
Definition: shellpath.c:216
#define GCT_INVALID
Definition: shlwapi.h:775
static HRESULT _SHRegisterUserShellFolders(BOOL bDefault)
Definition: shellpath.c:2585
#define IDS_STARTUP
Definition: shresdef.h:81
#define debugstr_w
Definition: kernel32.h:32
#define IDS_PROGRAMS
Definition: resource.h:69
#define FIXME(fmt,...)
Definition: debug.h:111
static void PathGetShortPathW(LPWSTR pszPath)
Definition: shellpath.c:187
static const WCHAR AllUsersProfileW[]
Definition: shellpath.c:677
static const WCHAR Common_StartUpW[]
Definition: shellpath.c:596
#define S_FALSE
Definition: winerror.h:2357
BOOL WINAPI PathRemoveFileSpecAW(LPVOID lpszPath)
Definition: shellpath.c:158
#define E_INVALIDARG
Definition: ddrawi.h:101
static const WCHAR Program_Files_x86_Common_FilesW[]
Definition: shellpath.c:648
static const WCHAR Common_Start_MenuW[]
Definition: shellpath.c:597
static const BOOL is_win64
Definition: shellpath.c:55
smooth NULL
Definition: ftsmooth.c:416
char ext[3]
Definition: mkdosfs.c:358
#define IDS_DESKTOPDIRECTORY
Definition: shresdef.h:87
#define IDI_SHELL_TSKBAR_STARTMENU
Definition: shresdef.h:518
#define CSIDL_SEARCHES
Definition: shellpath.c:718
static const WCHAR UsersPublicW[]
Definition: shellpath.c:672
#define CSIDL_COMMON_STARTMENU
Definition: shlobj.h:2033
#define IDI_SHELL_NETWORK
Definition: shresdef.h:493
#define IDS_COMMON_VIDEO
Definition: shresdef.h:103
BOOL WINAPI IsLFNDriveW(LPCWSTR lpszPath)
Definition: shellpath.c:296
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c:1756
static const WCHAR Start_MenuW[]
Definition: shellpath.c:663
const char * LPCSTR
Definition: xmlstorage.h:183
LPITEMIDLIST _ILCreateMyComputer(void)
Definition: pidl.c:1607
static const WCHAR ProgramFilesDirX86W[]
Definition: shellpath.c:650
static const WCHAR Microsoft_Windows_GameExplorerW[]
Definition: shellpath.c:623
static const WCHAR Common_AppDataW[]
Definition: shellpath.c:587
struct CFFOLDER folder
Definition: fdi.c:102
LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
Definition: path.c:442
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static HRESULT _SHOpenProfilesKey(PHKEY pKey)
Definition: shellpath.c:1990
static const WCHAR Program_Files_Common_FilesW[]
Definition: shellpath.c:645
#define CSIDL_COMMON_ADMINTOOLS
Definition: shlobj.h:2058
static const WCHAR szKnownFolderDescriptions[]
Definition: shellpath.c:692
#define IDI_SHELL_FONTS_FOLDER
Definition: shresdef.h:517
BOOL WINAPI IsWow64Process(IN HANDLE hProcess, OUT PBOOL Wow64Process)
Definition: proc.c:1976
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:4895
UINT WINAPI PathGetCharTypeA(UCHAR ch)
Definition: path.c:3005
BOOL WINAPI PathIsRootW(LPCWSTR lpszPath)
Definition: path.c:1621
static const WCHAR Pictures_Slide_ShowsW[]
Definition: shellpath.c:640
#define IDI_SHELL_NETWORK_FOLDER
Definition: resource.h:5
#define IDS_TEMPLATES
Definition: shresdef.h:89
const KNOWNFOLDERID * id
Definition: shellpath.c:723
BOOL WINAPI GetUserNameW(LPWSTR lpszName, LPDWORD lpSize)
Definition: misc.c:291
#define TRACE(s)
Definition: solgame.cpp:4
static const WCHAR StartUpW[]
Definition: shellpath.c:662
static const WCHAR szAllUsers[]
Definition: msipriv.h:1138
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
static BOOL PathResolveW(LPWSTR path, LPCWSTR *paths, DWORD flags)
Definition: shellpath.c:510
#define GetProcessHeap()
Definition: compat.h:404
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define TOKEN_QUERY
Definition: setypes.h:874
static BOOL PathQualifyW(LPCWSTR pszPath)
Definition: shellpath.c:488
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
#define CSIDL_ADMINTOOLS
Definition: shlobj.h:2059
BOOL WINAPI PathMakeUniqueNameAW(LPVOID lpszBuffer, DWORD dwBuffSize, LPCVOID lpszShortName, LPCVOID lpszLongName, LPCVOID lpszPathName)
Definition: shellpath.c:353
__wchar_t WCHAR
Definition: xmlstorage.h:180
static HRESULT _SHGetUserProfilePath(HANDLE hToken, DWORD dwFlags, BYTE folder, LPWSTR pszPath)
Definition: shellpath.c:1862
#define debugstr_a
Definition: kernel32.h:31
HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST *ppidl)
Definition: shellpath.c:2830
LONG HRESULT
Definition: typedefs.h:78
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static const WCHAR Common_Administrative_ToolsW[]
Definition: shellpath.c:586
BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
Definition: shellpath.c:497
#define _countof(array)
Definition: sndvol32.h:68
#define CSIDL_LOCAL_APPDATA
Definition: shlobj.h:2039
static const WCHAR SystemDriveW[]
Definition: shellpath.c:682
HANDLE WINAPI GetCurrentProcess(VOID)
Definition: proc.c:1138
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
#define CSIDL_APPDATA
Definition: shlobj.h:2037
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:6
const char file[]
Definition: icontest.c:11
static const WCHAR AppData_LocalLowW[]
Definition: shellpath.c:581
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:244
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath)
Definition: shellpath.c:284
#define IDS_COOKIES
Definition: shresdef.h:94
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:172
#define IDS_RECENT
Definition: shresdef.h:82
static const WCHAR CommonFilesDirX86W[]
Definition: shellpath.c:592
static HRESULT _SHGetDefaultValue(BYTE folder, LPWSTR pszPath)
Definition: shellpath.c:1636
static const WCHAR HistoryW[]
Definition: shellpath.c:611
static HANDLE
Definition: shellpath.c:88
int ret
static const WCHAR CD_BurningW[]
Definition: shellpath.c:585
static const WCHAR Start_Menu_ProgramsW[]
Definition: shellpath.c:665
static HRESULT _SHGetAllUsersProfilePath(DWORD dwFlags, BYTE folder, LPWSTR pszPath)
Definition: shellpath.c:1950
static const WCHAR L[]
Definition: oid.c:1250
UINT WINAPI GetSystemWow64DirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2420
#define CSIDL_COMMON_APPDATA
Definition: shlobj.h:2046
static const WCHAR CommonVideoW[]
Definition: shellpath.c:599
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
static const WCHAR Saved_GamesW[]
Definition: shellpath.c:658
static const WCHAR Start_Menu_StartupW[]
Definition: shellpath.c:667
static const WCHAR CacheW[]
Definition: shellpath.c:584
#define IDS_COMMON_PICTURES
Definition: shresdef.h:102
static const WCHAR My_PicturesW[]
Definition: shellpath.c:632
#define IDS_PROGRAM_FILES_COMMON
Definition: shresdef.h:98
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1199
#define GUID_NULL
Definition: ks.h:106
#define IDS_HISTORY
Definition: shresdef.h:95
static const WCHAR Local_Settings_CD_BurningW[]
Definition: shellpath.c:619
BOOL WINAPI PathFileExistsAW(LPCVOID lpszPath)
Definition: shellpath.c:274
#define E_NOT_SUFFICIENT_BUFFER
Definition: winerror.h:2345
LPWSTR WINAPI PathRemoveBackslashW(LPWSTR lpszPath)
Definition: path.c:862
unsigned char BYTE
Definition: xxhash.c:193
#define PCS_REPLACEDCHAR
Definition: shlobj.h:332
static const WCHAR DownloadsW[]
Definition: shellpath.c:607
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 strcmpiW(s1, s2)
Definition: unicode.h:39
#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:715
BOOL WINAPI PathIsRootA(LPCSTR lpszPath)
Definition: path.c:1581
#define ERR(fmt,...)
Definition: debug.h:110
static const WCHAR Local_Settings_HistoryW[]
Definition: shellpath.c:621
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:716
static const WCHAR DesktopW[]
Definition: shellpath.c:604
LPITEMIDLIST _ILCreateNetwork(void)
Definition: pidl.c:1663
#define S_OK
Definition: intsafe.h:59
static const WCHAR szDefaultProfileDirW[]
Definition: shellpath.c:690
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
#define IDI_SHELL_MY_MUSIC
Definition: shresdef.h:606
_In_ int _In_ BOOL bCreate
Definition: shlobj.h:1444
_NT_PRODUCT_TYPE
#define IDI_SHELL_MY_DOCUMENTS
Definition: shresdef.h:604
#define lstrcpyW
Definition: compat.h:415
#define IDI_SHELL_SYSTEM_GEAR
Definition: shresdef.h:643
LPSTR WINAPI PathFindExtensionA(LPCSTR lpszPath)
Definition: path.c:417
BOOL WINAPI SHGetSpecialFolderPathW(HWND hwndOwner, LPWSTR szPath, int nFolder, BOOL bCreate)
Definition: shellpath.c:2709
BOOL WINAPI PathResolveAW(LPVOID path, LPCVOID *paths, DWORD flags)
Definition: shellpath.c:519
static BOOL PathIsExeA(LPCSTR lpszPath)
Definition: shellpath.c:226
#define CSIDL_DOWNLOADS
Definition: shellpath.c:714
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:2453
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
LPCWSTR szPath
Definition: env.c:35
#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:846
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
static LPWSTR _GetUserSidStringFromToken(HANDLE Token)
Definition: shellpath.c:1821
static const WCHAR ProfileListW[]
Definition: shellpath.c:684
#define CSIDL_PRINTHOOD
Definition: shlobj.h:2038
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
static const WCHAR LinksW[]
Definition: shellpath.c:613
INT nShell32IconIndex
Definition: shellpath.c:727
static const WCHAR AllUsersW[]
Definition: shellpath.c:695
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
#define IDI_SHELL_NETWORK_CONNECTIONS
Definition: shresdef.h:563
#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:2005
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define IDI_SHELL_MY_PICTURES
Definition: shresdef.h:605
static BOOL PathResolveA(LPSTR path, LPCSTR *paths, DWORD flags)
Definition: shellpath.c:504
unsigned int UINT
Definition: ndis.h:50
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:724
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
HRESULT WINAPI SHGetFolderPathAndSubDirA(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPCSTR pszSubPath, LPSTR pszPath)
Definition: shellpath.c:2221
#define MultiByteToWideChar
Definition: compat.h:100
#define IDS_MYVIDEO
Definition: shresdef.h:86
HRESULT WINAPI SHILCreateFromPathW(LPCWSTR path, LPITEMIDLIST *ppidl, DWORD *attributes)
Definition: pidl.c:392
static LPWSTR PathGetExtensionW(LPCWSTR lpszPath)
Definition: shellpath.c:139
#define IDS_PROGRAM_FILES
Definition: shresdef.h:96
#define CSIDL_SAVED_GAMES
Definition: shellpath.c:717
static const WCHAR Common_DocumentsW[]
Definition: shellpath.c:589
#define CSIDL_NETHOOD
Definition: shlobj.h:2030
static const WCHAR ResourcesW[]
Definition: shellpath.c:656
static const WCHAR userName[]
Definition: wnet.c:2154
static const WCHAR AllUsersProfileValueW[]
Definition: shellpath.c:686
static const WCHAR szSHFolders[]
Definition: shellpath.c:688
#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:2208
#define CSIDL_STARTMENU
Definition: shlobj.h:2023
static const WCHAR Music_Sample_PlaylistsW[]
Definition: shellpath.c:629
WINE_UNICODE_INLINE int strcmpW(const WCHAR *str1, const WCHAR *str2)
Definition: unicode.h:229
LPCWSTR szValueName
Definition: shellpath.c:725
enum _NT_PRODUCT_TYPE NT_PRODUCT_TYPE
static const WCHAR Application_DataW[]
Definition: shellpath.c:582
uint32_t * LPDWORD
Definition: typedefs.h:58
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
static LPSTR PathGetExtensionA(LPCSTR lpszPath)
Definition: shellpath.c:128
static const WCHAR My_VideoW[]
Definition: shellpath.c:633
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:413
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
static const WCHAR Pictures_Sample_PicturesW[]
Definition: shellpath.c:639
static const WCHAR NetHoodW[]
Definition: shellpath.c:634
BOOL WINAPI PathIsExeAW(LPCVOID path)
Definition: shellpath.c:264
struct _TOKEN_USER * PTOKEN_USER
SID_AND_ATTRIBUTES User
Definition: setypes.h:956
char * cleanup(char *str)
Definition: wpickclick.c:99
HRESULT WINAPI SHGetFolderLocation(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwReserved, LPITEMIDLIST *ppidl)
Definition: shellpath.c:2741
#define IDS_ADMINTOOLS
Definition: shresdef.h:100
static const WCHAR CookiesW[]
Definition: shellpath.c:603
#define IDS_MYMUSIC
Definition: shresdef.h:85
LPITEMIDLIST _ILCreateIExplore(void)
Definition: pidl.c:1619
#define IDS_MYPICTURES
Definition: shresdef.h:97
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
BOOL WINAPI PathYetAnotherMakeUniqueName(LPWSTR buffer, LPCWSTR path, LPCWSTR shortname, LPCWSTR longname)
Definition: shellpath.c:368
#define IDS_NETHOOD
Definition: shresdef.h:88
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
static const WCHAR Local_Settings_Temporary_Internet_FilesW[]
Definition: shellpath.c:622
#define CSIDL_DESKTOPDIRECTORY
Definition: shlobj.h:2027
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
GLfloat GLfloat p
Definition: glext.h:8902
static const WCHAR SearchesW[]
Definition: shellpath.c:659
WCHAR * LPWSTR
Definition: xmlstorage.h:184
LPITEMIDLIST _ILCreateMyDocuments(void)
Definition: pidl.c:1613
LPITEMIDLIST _ILCreateControlPanel(void)
Definition: pidl.c:1625
#define CSIDL_NETWORK
Definition: shlobj.h:2029
HRESULT WINAPI SHGetFolderPathAndSubDirW(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPCWSTR pszSubPath, LPWSTR pszPath)
Definition: shellpath.c:2273
static const WCHAR My_MusicW[]
Definition: shellpath.c:631
#define CSIDL_PROGRAMS
Definition: shlobj.h:2014
LPWSTR WINAPI PathCombineW(LPWSTR lpszDest, LPCWSTR lpszDir, LPCWSTR lpszFile)
Definition: path.c:189
#define CSIDL_TEMPLATES
Definition: shlobj.h:2032
static const WCHAR Music_Sample_MusicW[]
Definition: shellpath.c:628
GLuint64EXT * result
Definition: glext.h:11304
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
static const WCHAR Start_Menu_Admin_ToolsW[]
Definition: shellpath.c:666
static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, LPCWSTR userPrefix, LPCWSTR value, LPWSTR path)
Definition: shellpath.c:1517
static const WCHAR PersonalW[]
Definition: shellpath.c:636
#define LOWORD(l)
Definition: pedump.c:82
static BOOL PathMakeUniqueNameA(LPSTR lpszBuffer, DWORD dwBuffSize, LPCSTR lpszShortName, LPCSTR lpszLongName, LPCSTR lpszPathName)
Definition: shellpath.c:321
#define HeapFree(x, y, z)
Definition: compat.h:403
LPITEMIDLIST _ILCreateBitBucket(void)
Definition: pidl.c:1669
#define IDS_SENDTO
Definition: shresdef.h:83
static const WCHAR PrintHoodW[]
Definition: shellpath.c:642
static const WCHAR DefaultW[]
Definition: shellpath.c:676
#define IDS_LOCAL_APPDATA
Definition: shresdef.h:92
static const WCHAR CommonPicturesW[]
Definition: shellpath.c:594
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static const WCHAR PicturesW[]
Definition: shellpath.c:638
_CSIDL_Type
Definition: shellpath.c:697
static const WCHAR CommonMusicW[]
Definition: shellpath.c:593
VOID WINAPI PathGetShortPathAW(LPVOID pszPath)
Definition: shellpath.c:202
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:2681
Definition: fci.c:126
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define REG_SZ
Definition: layer.c:22