ReactOS 0.4.15-dev-7788-g1ad9096
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-2022 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#include <assert.h>
44
45#include <shlwapi_undoc.h>
46#include <shellutils.h>
47
48#include <userenv.h>
49
50#include "pidl.h"
51#include "shell32_main.h"
52#include "shresdef.h"
53
54#undef _WIN32_WINNT
55#define _WIN32_WINNT _WIN32_WINNT_WS03
56
58
59static const BOOL is_win64 = sizeof(void *) > sizeof(int);
60
61/* FIXME: Remove this */
62typedef enum _NT_PRODUCT_TYPE
63{
68
69/* FIXME: We cannot refresh the RtlGetNtProductType value before reboot. */
70static BOOL
72{
73 HKEY hKey;
74 LONG error;
75 WCHAR szValue[9];
76 DWORD cbValue;
77 static DWORD s_dwProductType = 0;
78
79 if (s_dwProductType != 0)
80 {
81 *ProductType = s_dwProductType;
82 return TRUE;
83 }
84
85 *ProductType = NtProductServer;
86
87 error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions", 0, KEY_READ, &hKey);
88 if (error)
89 return FALSE;
90
91 cbValue = sizeof(szValue);
92 error = RegGetValueW(hKey, NULL, L"ProductType", RRF_RT_REG_SZ, NULL, (PVOID)szValue, &cbValue);
93 if (!error)
94 {
95 if (lstrcmpW(szValue, L"WinNT") == 0)
96 *ProductType = NtProductWinNt;
97 else if (lstrcmpW(szValue, L"LanmanNT") == 0)
98 *ProductType = NtProductLanManNt;
99 }
100
101 s_dwProductType = *ProductType;
102
104 return TRUE;
105}
106
108{
109 WCHAR szRoot[] = L"C:\\";
110 assert(L'A' + iDrive <= L'Z');
111 szRoot[0] = (WCHAR)(L'A' + iDrive);
112 return GetDriveTypeW(szRoot) == DRIVE_REMOVABLE;
113}
114
115/*
116 ########## Combining and Constructing paths ##########
117*/
118
119static BOOL WINAPI
121 _Inout_ LPWSTR pszPath,
122 _In_opt_ LPCWSTR *ppszDirs,
123 _In_ BOOL bDoSearch,
124 _In_ DWORD dwWhich)
125{
126 if (*PathFindExtensionW(pszPath) != 0)
127 return FALSE;
128
129 if (bDoSearch)
130 return PathFindOnPathExW(pszPath, ppszDirs, dwWhich);
131 else
132 return PathFileExistsDefExtW(pszPath, dwWhich);
133}
134
135#if (_WIN32_WINNT >= _WIN32_WINNT_WS03)
137{
138 return PathIsUNCW(path) || (PathGetDriveNumberW(path) != -1 && path[2] == L'\\');
139}
140
142{
144 DWORD cch;
145
146 if (path == NULL)
147 return FALSE;
149 if (!cch || cch > _countof(path1))
150 return FALSE;
151 return (PathCombineW(path, path1, path) != NULL);
152}
153#endif
154
156
157static VOID WINAPI
159{
160 INT iDrive, cchPathLeft;
161 WCHAR szTemp[MAX_PATH], szRoot[MAX_PATH];
162 PWCHAR pchTemp = szTemp, pchPath;
163 BOOL bLFN;
164
165 TRACE("(%s,%s,0x%08x)\n", debugstr_w(pszPath), debugstr_w(pszDir), dwFlags);
166
167 /* Save pszPath path into szTemp for rebuilding the path later */
168 if (FAILED(StringCchCopyW(szTemp, _countof(szTemp), pszPath)))
169 return;
170
171 /* Replace every '/' by '\' */
172 FixSlashesAndColonW(szTemp);
173
174 cchPathLeft = MAX_PATH;
175
176 /* Build the root-like path on pszPath, and set pchTemp */
177 if (!PathIsUNCW(szTemp))
178 {
179 /*
180 * Non-UNC path.
181 * Determine and normalize the root drive.
182 */
183 iDrive = PathGetDriveNumberW(szTemp);
184 if (iDrive == -1)
185 {
186 /*
187 * No drive was specified in the path. Try to find one from the
188 * optional directory (if this fails, fall back to the one of the
189 * Windows directory).
190 */
191 if (!pszDir || FAILED(StringCchCopyW(szRoot, _countof(szRoot), pszDir)))
192 {
193 /* pszDir was invalid or NULL. Fall back to the
194 * Windows directory and find its root. */
195 szRoot[0] = UNICODE_NULL;
196 GetWindowsDirectoryW(szRoot, _countof(szRoot));
197 iDrive = PathGetDriveNumberW(szRoot);
198 if (iDrive != -1)
199 PathBuildRootW(szRoot, iDrive);
200 }
201
202 if (szTemp[0] == L'\\')
203 {
204 PathStripToRootW(szRoot);
205 }
206 }
207 else
208 {
209 /*
210 * A drive is specified in the path, that can be either of the
211 * form 'C:\xxx' or of the form 'C:xxx' (relative path). Isolate
212 * the root part 'C:' and the rest of the path 'xxx' in pchTemp.
213 */
214 PathBuildRootW(szRoot, iDrive);
215 pchTemp += 2;
216 if (*pchTemp == L'\\')
217 ++pchTemp;
218 }
219
220 bLFN = IsLFNDriveW(szRoot);
221 if (!bLFN)
222 {
223 PWCHAR pch;
224 for (pch = pchTemp; *pch != UNICODE_NULL; ++pch)
225 {
226#define PATH_CHAR_CLASS_DOT 0x00000004
227#define PATH_CHAR_CLASS_BACKSLASH 0x00000008
228#define PATH_CHAR_CLASS_COLON 0x00000010
229#define PATH_CHAR_CLASS_OTHER_VALID 0x00000100
230#define VALID_SHORT_PATH_CHAR_CLASSES ( \
231 PATH_CHAR_CLASS_DOT | \
232 PATH_CHAR_CLASS_BACKSLASH | \
233 PATH_CHAR_CLASS_COLON | \
234 PATH_CHAR_CLASS_OTHER_VALID \
235)
237 {
238 *pch = L'_';
239 }
240 }
241 }
242
243 StringCchCopyW(pszPath, MAX_PATH, szRoot);
244 cchPathLeft -= lstrlenW(pszPath) + 1;
245 }
246 else /* UNC path: Begins with double backslash */
247 {
248 bLFN = IsLFNDriveW(pchTemp);
249 if (bLFN)
250 {
251 pszPath[2] = UNICODE_NULL; /* Cut off */
252 cchPathLeft -= (2 + 1);
253 pchTemp += 2;
254 }
255 else
256 {
257 PWCHAR pchSlash = StrChrW(pszPath + 2, L'\\');
258 if (pchSlash)
259 pchSlash = StrChrW(pchSlash + 1, L'\\');
260
261 if (pchSlash)
262 {
263 *(pchSlash + 1) = UNICODE_NULL; /* Cut off */
264 pchTemp += pchSlash - pszPath;
265 cchPathLeft -= (INT)(SIZE_T)(pchSlash - pszPath) + 1;
266 }
267 else
268 {
269 bLFN = TRUE;
270 pszPath[2] = UNICODE_NULL; /* Cut off */
271 cchPathLeft -= 2;
272 pchTemp += 2;
273 }
274 }
275 }
276 /* Now pszPath is a root-like path or an empty string. */
277
278 /* Start appending the path components of szTemp to pszPath. */
279 while (*pchTemp && cchPathLeft > 0)
280 {
281 /* Collapse any .\ and ..\ parts in the path */
282 if (*pchTemp == L'.')
283 {
284 BOOL bDots = FALSE; /* '.' or '..' ? */
285
286 if (pchTemp[1] == UNICODE_NULL || pchTemp[1] == L'\\')
287 {
288 /* Component '.' */
289 bDots = TRUE;
290 }
291 else if (pchTemp[1] == L'.' && (pchTemp[2] == UNICODE_NULL || pchTemp[2] == L'\\'))
292 {
293 /* Component '..' */
294 PathRemoveFileSpecW(pszPath); /* Remove the last component from pszPath */
295 bDots = TRUE;
296 }
297
298 /* If a '.' or '..' was encountered, skip to the next component */
299 if (bDots)
300 {
301 while (*pchTemp && *pchTemp != L'\\')
302 {
303 ++pchTemp;
304 }
305
306 while (*pchTemp == L'\\')
307 {
308 ++pchTemp;
309 }
310
311 continue;
312 }
313 }
314
315 /* Otherwise, copy the other path component */
316
317 if (!PathAddBackslashW(pszPath)) /* Append a backslash at the end */
318 break;
319
320 --cchPathLeft;
321
322 pchPath = &pszPath[lstrlenW(pszPath)];
323
324 if (!bLFN) /* Not LFN? */
325 {
326 /* Copy MS-DOS 8.3 filename */
327 PWCHAR pchDot = NULL;
328 INT ich;
329 WCHAR szTitle[8 + 1] = L"";
330 INT cchTitle = 0;
331 WCHAR szDotExtension[1 + 3 + 1] = L"";
332 INT cchDotExtension = 0;
333
334 /* Copy the component to szTitle and szDotExtension... */
335 while (*pchTemp && *pchTemp != L'\\')
336 {
337 if (*pchTemp == L'.')
338 {
339 pchDot = pchTemp; /* Remember the last position */
340
341 /* Clear szDotExtension */
342 cchDotExtension = 0;
343 ZeroMemory(szDotExtension, sizeof(szDotExtension));
344 }
345
346 if (pchDot)
347 {
348 if (cchDotExtension < 1 + 3)
349 szDotExtension[cchDotExtension++] = *pchTemp;
350 }
351 else
352 {
353 if (cchTitle < 8)
354 szTitle[cchTitle++] = *pchTemp;
355 }
356
357 ++pchTemp;
358 }
359
360 /* Add file title 'szTitle' to pchPath */
361 for (ich = 0; szTitle[ich] && cchPathLeft > 0; ++ich)
362 {
363 *pchPath++ = szTitle[ich];
364 --cchPathLeft;
365 }
366
367 /* Add file extension 'szDotExtension' to pchPath */
368 if (pchDot)
369 {
370 for (ich = 0; szDotExtension[ich] && cchPathLeft > 0; ++ich)
371 {
372 *pchPath++ = szDotExtension[ich];
373 --cchPathLeft;
374 }
375 }
376 }
377 else /* LFN */
378 {
379 /* Copy the component up to the next separator */
380 while (*pchTemp != UNICODE_NULL && *pchTemp != L'\\' && cchPathLeft > 0)
381 {
382 *pchPath++ = *pchTemp++;
383 --cchPathLeft;
384 }
385 }
386
387 /* Skip the backslashes */
388 while (*pchTemp == L'\\')
389 {
390 ++pchTemp;
391 }
392
393 /* Keep null-terminated */
394 *pchPath = UNICODE_NULL;
395 }
396
397 /* Remove any trailing backslash */
398 PathRemoveBackslashW(pszPath);
399
400 if (!(dwFlags & 1)) /* Remove the trailing dot? */
401 {
402 pchPath = CharPrevW(pszPath, pszPath + lstrlenW(pszPath));
403 if (*pchPath == L'.')
404 *pchPath = UNICODE_NULL;
405 }
406}
407
408/*************************************************************************
409 * PathAppend [SHELL32.36]
410 */
412 LPVOID lpszPath1,
413 LPCVOID lpszPath2)
414{
415 if (SHELL_OsIsUnicode())
416 return PathAppendW(lpszPath1, lpszPath2);
417 return PathAppendA(lpszPath1, lpszPath2);
418}
419
420/*************************************************************************
421 * PathGetExtensionA [internal]
422 *
423 * NOTES
424 * exported by ordinal
425 * return value points to the first char after the dot
426 */
428{
429 TRACE("(%s)\n",lpszPath);
430
431 lpszPath = PathFindExtensionA(lpszPath);
432 return (LPSTR)(*lpszPath?(lpszPath+1):lpszPath);
433}
434
435/*************************************************************************
436 * PathGetExtensionW [internal]
437 */
439{
440 TRACE("(%s)\n",debugstr_w(lpszPath));
441
442 lpszPath = PathFindExtensionW(lpszPath);
443 return (LPWSTR)(*lpszPath?(lpszPath+1):lpszPath);
444}
445
446/*************************************************************************
447 * SHPathGetExtension [SHELL32.158]
448 */
450{
451 return PathGetExtensionW(lpszPath);
452}
453
454/*************************************************************************
455 * PathRemoveFileSpec [SHELL32.35]
456 */
458{
459 if (SHELL_OsIsUnicode())
460 return PathRemoveFileSpecW(lpszPath);
461 return PathRemoveFileSpecA(lpszPath);
462}
463
464/*
465 Path Manipulations
466*/
467
468/*************************************************************************
469 * PathGetShortPathA [internal]
470 */
471static void PathGetShortPathA(LPSTR pszPath)
472{
474
475 TRACE("%s\n", pszPath);
476
477 if (GetShortPathNameA(pszPath, path, MAX_PATH))
478 {
479 lstrcpyA(pszPath, path);
480 }
481}
482
483/*************************************************************************
484 * PathGetShortPathW [internal]
485 */
486static void PathGetShortPathW(LPWSTR pszPath)
487{
489
490 TRACE("%s\n", debugstr_w(pszPath));
491
492 if (GetShortPathNameW(pszPath, path, MAX_PATH))
493 {
494 lstrcpyW(pszPath, path);
495 }
496}
497
498/*************************************************************************
499 * PathGetShortPath [SHELL32.92]
500 */
502{
504 PathGetShortPathW(pszPath);
505 PathGetShortPathA(pszPath);
506}
507
508/*
509 ########## Path Testing ##########
510*/
511
512/*************************************************************************
513 * PathIsRoot [SHELL32.29]
514 */
516{
517 if (SHELL_OsIsUnicode())
518 return PathIsRootW(lpszPath);
519 return PathIsRootA(lpszPath);
520}
521
522/*************************************************************************
523 * PathIsExeA [internal]
524 */
525static BOOL PathIsExeA (LPCSTR lpszPath)
526{
527 LPCSTR lpszExtension = PathGetExtensionA(lpszPath);
528 int i;
529 static const char * const lpszExtensions[] =
530 {"exe", "com", "pif", "cmd", "bat", "scf", "scr", NULL };
531
532 TRACE("path=%s\n",lpszPath);
533
534 for(i=0; lpszExtensions[i]; i++)
535 if (!lstrcmpiA(lpszExtension,lpszExtensions[i])) return TRUE;
536
537 return FALSE;
538}
539
540/*************************************************************************
541 * PathIsExeW [internal]
542 */
544{
545 LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
546 int i;
547 static const WCHAR lpszExtensions[][4] =
548 {L"exe", L"com", L"pif", L"cmd", L"bat", L"scf", L"scr", L"" };
549
550 TRACE("path=%s\n",debugstr_w(lpszPath));
551
552 for(i=0; lpszExtensions[i][0]; i++)
553 if (!wcsicmp(lpszExtension,lpszExtensions[i])) return TRUE;
554
555 return FALSE;
556}
557
558/*************************************************************************
559 * PathIsExe [SHELL32.43]
560 */
562{
563 if (SHELL_OsIsUnicode())
564 return PathIsExeW (path);
565 return PathIsExeA(path);
566}
567
568/*************************************************************************
569 * PathFileExists [SHELL32.45]
570 */
572{
573 if (SHELL_OsIsUnicode())
574 return PathFileExistsW (lpszPath);
575 return PathFileExistsA (lpszPath);
576}
577
578/*************************************************************************
579 * IsLFNDriveA [SHELL32.41]
580 */
582{
583 WCHAR szBuffW[MAX_PATH], *pszW = NULL;
584 if (lpszPath)
585 {
586 SHAnsiToUnicode(lpszPath, szBuffW, _countof(szBuffW));
587 pszW = szBuffW;
588 }
589 return IsLFNDriveW(pszW);
590}
591
592/*************************************************************************
593 * IsLFNDriveW [SHELL32.42]
594 */
596{
597 DWORD cchMaxFileName, iDrive;
598 WCHAR szRoot[MAX_PATH];
599
600 if (lpszPath == NULL || lpszPath[0] == UNICODE_NULL)
601 {
602 szRoot[0] = 0;
603 GetWindowsDirectoryW(szRoot, _countof(szRoot));
604 lpszPath = szRoot;
605 }
606
607 if (PathIsUNCW(lpszPath))
608 {
609 StringCchCopyW(szRoot, _countof(szRoot), lpszPath);
610 PathStripToRootW(szRoot);
611
612 if (StrChrW(szRoot + 2, L'\\') == NULL)
613 return TRUE; /* LFN */
614
615 StringCchCatW(szRoot, _countof(szRoot), L"\\"); /* Add a backslash */
616 }
617 else
618 {
619 assert(!PathIsRelativeW(lpszPath)); /* Assuming absolute path... */
620
621 iDrive = ((lpszPath[0] - L'A') & 0x1F);
622 PathBuildRootW(szRoot, iDrive);
623
624 if (!IsRemovableDrive(iDrive))
625 {
626 /* FIXME: Cache correctly */
627 }
628 }
629
630#define MSDOS_8DOT3_LEN 12 /* MS-DOS 8.3 filename == length 12 */
631
632 /* GetVolumeInformation requires a root path */
633 if (!GetVolumeInformationW(szRoot, NULL, 0, NULL, &cchMaxFileName, NULL, NULL, 0))
634 {
635 /* Don't return FALSE when GetVolumeInformationW fails. */
636 return TRUE;
637 }
638
639 return cchMaxFileName > MSDOS_8DOT3_LEN;
640}
641
642/*************************************************************************
643 * IsLFNDrive [SHELL32.119]
644 */
646{
647 if (SHELL_OsIsUnicode())
648 return IsLFNDriveW(lpszPath);
649 return IsLFNDriveA(lpszPath);
650}
651
652/*
653 ########## Creating Something Unique ##########
654*/
655/*************************************************************************
656 * PathMakeUniqueNameA [internal]
657 */
659 LPSTR lpszBuffer,
660 DWORD dwBuffSize,
661 LPCSTR lpszShortName,
662 LPCSTR lpszLongName,
663 LPCSTR lpszPathName)
664{
665 FIXME("%p %u %s %s %s stub\n",
666 lpszBuffer, dwBuffSize, debugstr_a(lpszShortName),
667 debugstr_a(lpszLongName), debugstr_a(lpszPathName));
668 return TRUE;
669}
670
671/*************************************************************************
672 * PathMakeUniqueNameW [internal]
673 */
675 LPWSTR lpszBuffer,
676 DWORD dwBuffSize,
677 LPCWSTR lpszShortName,
678 LPCWSTR lpszLongName,
679 LPCWSTR lpszPathName)
680{
681 FIXME("%p %u %s %s %s stub\n",
682 lpszBuffer, dwBuffSize, debugstr_w(lpszShortName),
683 debugstr_w(lpszLongName), debugstr_w(lpszPathName));
684 return TRUE;
685}
686
687/*************************************************************************
688 * PathMakeUniqueName [SHELL32.47]
689 */
691 LPVOID lpszBuffer,
692 DWORD dwBuffSize,
693 LPCVOID lpszShortName,
694 LPCVOID lpszLongName,
695 LPCVOID lpszPathName)
696{
697 if (SHELL_OsIsUnicode())
698 return PathMakeUniqueNameW(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
699 return PathMakeUniqueNameA(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
700}
701
702/*************************************************************************
703 * PathYetAnotherMakeUniqueName [SHELL32.75]
704 */
706{
707 WCHAR pathW[MAX_PATH], retW[MAX_PATH];
708 const WCHAR *file, *ext;
709 int i = 2;
710
711 TRACE("(%p, %s, %s, %s)\n", buffer, debugstr_w(path), debugstr_w(shortname), debugstr_w(longname));
712
713 file = longname ? longname : shortname;
714 PathCombineW(pathW, path, file);
715 strcpyW(retW, pathW);
717
719
720 /* now try to make it unique */
721 while (PathFileExistsW(retW))
722 {
723 sprintfW(retW, L"%s (%d)%s", pathW, i, ext);
724 i++;
725 }
726
727 strcpyW(buffer, retW);
728 TRACE("ret - %s\n", debugstr_w(buffer));
729
730 return TRUE;
731}
732
733/*
734 ########## cleaning and resolving paths ##########
735 */
736
737/*************************************************************************
738 * PathCleanupSpec [SHELL32.171]
739 *
740 * lpszFile is changed in place.
741 */
742int WINAPI PathCleanupSpec( LPCWSTR lpszPathW, LPWSTR lpszFileW )
743{
744 int i = 0;
745 DWORD rc = 0;
746 int length = 0;
747
748 if (SHELL_OsIsUnicode())
749 {
750 LPWSTR p = lpszFileW;
751
752 TRACE("Cleanup %s\n",debugstr_w(lpszFileW));
753
754 if (lpszPathW)
755 length = strlenW(lpszPathW);
756
757 while (*p)
758 {
759 int gct = PathGetCharTypeW(*p);
760 if (gct == GCT_INVALID || gct == GCT_WILD || gct == GCT_SEPARATOR)
761 {
762 lpszFileW[i]='-';
763 rc |= PCS_REPLACEDCHAR;
764 }
765 else
766 lpszFileW[i]=*p;
767 i++;
768 p++;
769 if (length + i == MAX_PATH)
770 {
772 break;
773 }
774 }
775 lpszFileW[i]=0;
776 }
777 else
778 {
779 LPSTR lpszFileA = (LPSTR)lpszFileW;
780 LPCSTR lpszPathA = (LPCSTR)lpszPathW;
781 LPSTR p = lpszFileA;
782
783 TRACE("Cleanup %s\n",debugstr_a(lpszFileA));
784
785 if (lpszPathA)
786 length = strlen(lpszPathA);
787
788 while (*p)
789 {
790 int gct = PathGetCharTypeA(*p);
791 if (gct == GCT_INVALID || gct == GCT_WILD || gct == GCT_SEPARATOR)
792 {
793 lpszFileA[i]='-';
794 rc |= PCS_REPLACEDCHAR;
795 }
796 else
797 lpszFileA[i]=*p;
798 i++;
799 p++;
800 if (length + i == MAX_PATH)
801 {
803 break;
804 }
805 }
806 lpszFileA[i]=0;
807 }
808 return rc;
809}
810
811/*************************************************************************
812 * PathQualifyA [SHELL32]
813 */
815{
817 TRACE("%s\n",pszPath);
821}
822
823/*************************************************************************
824 * PathQualifyW [SHELL32]
825 */
827{
828 TRACE("%s\n",debugstr_w(pszPath));
829 PathQualifyExW(pszPath, NULL, 0);
830}
831
832/*************************************************************************
833 * PathQualify [SHELL32.49]
834 */
836{
837 if (SHELL_OsIsUnicode())
838 PathQualifyW(pszPath);
839 else
840 PathQualifyA(pszPath);
841}
842
844{
845 BOOL ret = FALSE;
846 LPWSTR *dirsW = NULL;
847 DWORD iDir, cDirs, cbDirs;
848 WCHAR pathW[MAX_PATH];
849
850 TRACE("(%s,%p,0x%08x)\n", debugstr_a(path), dirs, flags);
851
852 if (dirs)
853 {
854 for (cDirs = 0; dirs[cDirs]; ++cDirs)
855 ;
856
857 cbDirs = (cDirs + 1) * sizeof(LPWSTR);
858 dirsW = SHAlloc(cbDirs);
859 if (!dirsW)
860 goto Cleanup;
861
862 ZeroMemory(dirsW, cbDirs);
863 for (iDir = 0; iDir < cDirs; ++iDir)
864 {
865 __SHCloneStrAtoW(&dirsW[iDir], dirs[iDir]);
866 if (dirsW[iDir] == NULL)
867 goto Cleanup;
868 }
869 }
870
871 SHAnsiToUnicode(path, pathW, _countof(pathW));
872
873 ret = PathResolveW(pathW, (LPCWSTR*)dirsW, flags);
874 if (ret)
876
877Cleanup:
878 if (dirsW)
879 {
880 for (iDir = 0; iDir < cDirs; ++iDir)
881 {
882 SHFree(dirsW[iDir]);
883 }
884 SHFree(dirsW);
885 }
886 return ret;
887}
888
890{
891 DWORD dwWhich = WHICH_DEFAULT; /* The extensions to be searched */
892
893 TRACE("(%s,%p,0x%08x)\n", debugstr_w(path), dirs, flags);
894
896 dwWhich &= ~WHICH_LNK; /* Don't search '.LNK' (shortcut) */
897
899 SetLastError(ERROR_FILE_NOT_FOUND); /* We set this error code at first in verification */
900
902
903 if (PathIsRootW(path)) /* Root path */
904 {
905 if (path[0] == L'\\' && path[1] == UNICODE_NULL) /* '\' only? */
906 PathQualifyExW(path, ((flags & PRF_FIRSTDIRDEF) ? *dirs : NULL), 0); /* Qualify */
907
909 return PathFileExistsAndAttributesW(path, NULL); /* Check the existence */
910
911 return TRUE;
912 }
913
914 if (PathIsFileSpecW(path)) /* Filename only */
915 {
916 /* Try to find the path with program extensions applied? */
918 PathSearchOnExtensionsW(path, dirs, TRUE, dwWhich))
919 {
920 return TRUE; /* Found */
921 }
922
923 /* Try to find the filename in the directories */
924 if (PathFindOnPathW(path, dirs))
925 goto CheckAbsoluteAndFinish;
926
927 return FALSE; /* Not found */
928 }
929
930 if (PathIsURLW(path)) /* URL? */
931 return FALSE;
932
933 /* Qualify the path */
934 PathQualifyExW(path, ((flags & PRF_FIRSTDIRDEF) ? *dirs : NULL), 1);
935
936 TRACE("(%s)\n", debugstr_w(path));
937
938 if (!(flags & PRF_VERIFYEXISTS)) /* Don't verify the existence? */
939 return TRUE;
940
941 /* Try to find the path with program extensions applied? */
943 !PathSearchOnExtensionsW(path, dirs, FALSE, dwWhich))
944 {
946 return FALSE; /* Not found */
947 }
948
949CheckAbsoluteAndFinish:
950#if (_WIN32_WINNT >= _WIN32_WINNT_WS03)
952 return TRUE;
953
955 return FALSE;
956
958#else
959 return TRUE; /* Found */
960#endif
961}
962
963/*************************************************************************
964 * PathResolve [SHELL32.51]
965 */
967{
968 if (SHELL_OsIsUnicode())
969 return PathResolveW(path, (LPCWSTR*)paths, flags);
970 else
971 return PathResolveA(path, (LPCSTR*)paths, flags);
972}
973
974/*************************************************************************
975* PathProcessCommandA
976*/
978 LPCSTR lpszPath,
979 LPSTR lpszBuff,
980 DWORD dwBuffSize,
982{
983 FIXME("%s %p 0x%04x 0x%04x stub\n",
984 lpszPath, lpszBuff, dwBuffSize, dwFlags);
985 if(!lpszPath) return -1;
986 if(lpszBuff) strcpy(lpszBuff, lpszPath);
987 return strlen(lpszPath);
988}
989
990/*************************************************************************
991* PathProcessCommandW
992*/
994 LPCWSTR lpszPath,
995 LPWSTR lpszBuff,
996 DWORD dwBuffSize,
998{
999 FIXME("(%s, %p, 0x%04x, 0x%04x) stub\n",
1000 debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags);
1001 if(!lpszPath) return -1;
1002 if(lpszBuff) strcpyW(lpszBuff, lpszPath);
1003 return strlenW(lpszPath);
1004}
1005
1006/*************************************************************************
1007* PathProcessCommand (SHELL32.653)
1008*/
1010 LPCVOID lpszPath,
1011 LPVOID lpszBuff,
1012 DWORD dwBuffSize,
1013 DWORD dwFlags)
1014{
1015 if (SHELL_OsIsUnicode())
1016 return PathProcessCommandW(lpszPath, lpszBuff, dwBuffSize, dwFlags);
1017 return PathProcessCommandA(lpszPath, lpszBuff, dwBuffSize, dwFlags);
1018}
1019
1020/*
1021 ########## special ##########
1022*/
1023
1024/* !! MISSING Win2k3-compatible paths from the list below; absent from Wine !! */
1025#ifndef __REACTOS__
1026static const WCHAR Application_DataW[] = L"Application Data";
1027static const WCHAR Local_Settings_Application_DataW[] = L"Local Settings\\Application Data";
1028static const WCHAR Local_Settings_HistoryW[] = L"Local Settings\\History";
1029static const WCHAR Local_Settings_Temporary_Internet_FilesW[] = L"Local Settings\\Temporary Internet Files";
1030static const WCHAR MusicW[] = L"Music";
1031static const WCHAR PicturesW[] = L"Pictures";
1032static const WCHAR Program_FilesW[] = L"Program Files";
1033static const WCHAR Program_Files_Common_FilesW[] = L"Program Files\\Common Files";
1034static const WCHAR Start_Menu_ProgramsW[] = L"Start Menu\\Programs";
1035static const WCHAR Start_Menu_Admin_ToolsW[] = L"Start Menu\\Programs\\Administrative Tools";
1036static const WCHAR Start_Menu_StartupW[] = L"Start Menu\\Programs\\StartUp";
1037#endif
1038
1039/* Long strings that are repeated many times: keep them here */
1040static const WCHAR szSHFolders[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
1041static const WCHAR szSHUserFolders[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
1042#ifndef __REACTOS__
1043static const WCHAR szKnownFolderDescriptions[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FolderDescriptions";
1044static const WCHAR szKnownFolderRedirections[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
1045#endif
1046
1047typedef enum _CSIDL_Type {
1049#ifdef __REACTOS__
1050 CSIDL_Type_InMyDocuments,
1051#endif
1060
1061/* Cannot use #if _WIN32_WINNT >= 0x0600 because _WIN32_WINNT == 0x0600 here. */
1062#ifndef __REACTOS__
1063#define CSIDL_CONTACTS 0x0043
1064#define CSIDL_DOWNLOADS 0x0047
1065#define CSIDL_LINKS 0x004d
1066#define CSIDL_APPDATA_LOCALLOW 0x004e
1067#define CSIDL_SAVED_GAMES 0x0062
1068#define CSIDL_SEARCHES 0x0063
1069#endif
1070
1071typedef struct
1072{
1076 LPCWSTR szDefaultPath; /* fallback string or resource ID */
1078} CSIDL_DATA;
1079
1080static const CSIDL_DATA CSIDL_Data[] =
1081{
1082 { /* 0x00 - CSIDL_DESKTOP */
1083 &FOLDERID_Desktop,
1085 L"Desktop",
1087#ifdef __REACTOS__
1088 0
1089#else
1091#endif
1092 },
1093 { /* 0x01 - CSIDL_INTERNET */
1094 &FOLDERID_InternetFolder,
1096 NULL,
1097 NULL
1098 },
1099 { /* 0x02 - CSIDL_PROGRAMS */
1100 &FOLDERID_Programs,
1102 L"Programs",
1104#ifdef __REACTOS__
1105 0
1106#else
1108#endif
1109 },
1110 { /* 0x03 - CSIDL_CONTROLS (.CPL files) */
1111 &FOLDERID_ControlPanelFolder,
1113 NULL,
1114 NULL,
1116 },
1117 { /* 0x04 - CSIDL_PRINTERS */
1118 &FOLDERID_PrintersFolder,
1120 NULL,
1121 NULL,
1123 },
1124 { /* 0x05 - CSIDL_PERSONAL */
1125 &FOLDERID_Documents,
1127 L"Personal",
1130 },
1131 { /* 0x06 - CSIDL_FAVORITES */
1132 &FOLDERID_Favorites,
1134 L"Favorites",
1137 },
1138 { /* 0x07 - CSIDL_STARTUP */
1139 &FOLDERID_Startup,
1141 L"StartUp",
1143 },
1144 { /* 0x08 - CSIDL_RECENT */
1145 &FOLDERID_Recent,
1147 L"Recent",
1150 },
1151 { /* 0x09 - CSIDL_SENDTO */
1152 &FOLDERID_SendTo,
1154 L"SendTo",
1156 },
1157 { /* 0x0a - CSIDL_BITBUCKET - Recycle Bin */
1158 &FOLDERID_RecycleBinFolder,
1160 NULL,
1161 NULL
1162 },
1163 { /* 0x0b - CSIDL_STARTMENU */
1164 &FOLDERID_StartMenu,
1166 L"Start Menu",
1169 },
1170 { /* 0x0c - CSIDL_MYDOCUMENTS */
1171 &GUID_NULL,
1172 CSIDL_Type_Disallowed, /* matches WinXP--can't get its path */
1173 NULL,
1174 NULL,
1176 },
1177 { /* 0x0d - CSIDL_MYMUSIC */
1178 &FOLDERID_Music,
1179#ifdef __REACTOS__
1180 CSIDL_Type_InMyDocuments,
1181#else
1183#endif
1184 L"My Music",
1187 },
1188 { /* 0x0e - CSIDL_MYVIDEO */
1189 &FOLDERID_Videos,
1190#ifdef __REACTOS__
1191 CSIDL_Type_InMyDocuments,
1192#else
1194#endif
1195 L"My Video",
1198 },
1199 { /* 0x0f - unassigned */
1200 &GUID_NULL,
1202 NULL,
1203 NULL,
1204 },
1205 { /* 0x10 - CSIDL_DESKTOPDIRECTORY */
1206 &FOLDERID_Desktop,
1208 L"Desktop",
1210#ifdef __REACTOS__
1211 0
1212#else
1214#endif
1215 },
1216 { /* 0x11 - CSIDL_DRIVES */
1217 &FOLDERID_ComputerFolder,
1219 NULL,
1220 NULL,
1222 },
1223 { /* 0x12 - CSIDL_NETWORK */
1224 &FOLDERID_NetworkFolder,
1226 NULL,
1227 NULL,
1229 },
1230 { /* 0x13 - CSIDL_NETHOOD */
1231 &FOLDERID_NetHood,
1233 L"NetHood",
1236 },
1237 { /* 0x14 - CSIDL_FONTS */
1238 &FOLDERID_Fonts,
1240 L"Fonts",
1241 L"Fonts",
1243 },
1244 { /* 0x15 - CSIDL_TEMPLATES */
1245 &FOLDERID_Templates,
1247 L"Templates",
1249 },
1250 { /* 0x16 - CSIDL_COMMON_STARTMENU */
1251 &FOLDERID_CommonStartMenu,
1253 L"Common Start Menu",
1256 },
1257 { /* 0x17 - CSIDL_COMMON_PROGRAMS */
1258 &FOLDERID_CommonPrograms,
1260 L"Common Programs",
1262#ifdef __REACTOS__
1263 0
1264#else
1266#endif
1267 },
1268 { /* 0x18 - CSIDL_COMMON_STARTUP */
1269 &FOLDERID_CommonStartup,
1271 L"Common StartUp",
1273 },
1274 { /* 0x19 - CSIDL_COMMON_DESKTOPDIRECTORY */
1275 &FOLDERID_PublicDesktop,
1277 L"Common Desktop",
1279#ifdef __REACTOS__
1280 0
1281#else
1283#endif
1284 },
1285 { /* 0x1a - CSIDL_APPDATA */
1286 &FOLDERID_RoamingAppData,
1288 L"AppData",
1290 },
1291 { /* 0x1b - CSIDL_PRINTHOOD */
1292 &FOLDERID_PrintHood,
1294 L"PrintHood",
1297 },
1298 { /* 0x1c - CSIDL_LOCAL_APPDATA */
1299 &FOLDERID_LocalAppData,
1301 L"Local AppData",
1303 },
1304 { /* 0x1d - CSIDL_ALTSTARTUP */
1305 &GUID_NULL,
1307 NULL,
1308 NULL
1309 },
1310 { /* 0x1e - CSIDL_COMMON_ALTSTARTUP */
1311 &GUID_NULL,
1313 NULL,
1314 NULL
1315 },
1316 { /* 0x1f - CSIDL_COMMON_FAVORITES */
1317 &FOLDERID_Favorites,
1319 L"Common Favorites",
1322 },
1323 { /* 0x20 - CSIDL_INTERNET_CACHE */
1324 &FOLDERID_InternetCache,
1326 L"Cache",
1328 },
1329 { /* 0x21 - CSIDL_COOKIES */
1330 &FOLDERID_Cookies,
1332 L"Cookies",
1334 },
1335 { /* 0x22 - CSIDL_HISTORY */
1336 &FOLDERID_History,
1338 L"History",
1340 },
1341 { /* 0x23 - CSIDL_COMMON_APPDATA */
1342 &FOLDERID_ProgramData,
1344 L"Common AppData",
1346 },
1347 { /* 0x24 - CSIDL_WINDOWS */
1348 &FOLDERID_Windows,
1350 NULL,
1351 NULL,
1353 },
1354 { /* 0x25 - CSIDL_SYSTEM */
1355 &FOLDERID_System,
1357 NULL,
1358 NULL,
1360 },
1361 { /* 0x26 - CSIDL_PROGRAM_FILES */
1362 &FOLDERID_ProgramFiles,
1364 L"ProgramFilesDir",
1366#ifdef __REACTOS__
1367 0
1368#else
1370#endif
1371 },
1372 { /* 0x27 - CSIDL_MYPICTURES */
1373 &FOLDERID_Pictures,
1374#ifdef __REACTOS__
1375 CSIDL_Type_InMyDocuments,
1376#else
1378#endif
1379 L"My Pictures",
1382 },
1383 { /* 0x28 - CSIDL_PROFILE */
1384 &FOLDERID_Profile,
1386 NULL,
1387 NULL
1388 },
1389 { /* 0x29 - CSIDL_SYSTEMX86 */
1390 &FOLDERID_SystemX86,
1392 NULL,
1393 NULL,
1395 },
1396 { /* 0x2a - CSIDL_PROGRAM_FILESX86 */
1397 &FOLDERID_ProgramFilesX86,
1399 L"ProgramFilesDir (x86)",
1400 L"Program Files (x86)",
1402 },
1403 { /* 0x2b - CSIDL_PROGRAM_FILES_COMMON */
1404 &FOLDERID_ProgramFilesCommon,
1406 L"CommonFilesDir",
1409 },
1410 { /* 0x2c - CSIDL_PROGRAM_FILES_COMMONX86 */
1411 &FOLDERID_ProgramFilesCommonX86,
1413 L"CommonFilesDir (x86)",
1414 L"Program Files (x86)\\Common Files",
1416 },
1417 { /* 0x2d - CSIDL_COMMON_TEMPLATES */
1418 &FOLDERID_CommonTemplates,
1420 L"Common Templates",
1422 },
1423 { /* 0x2e - CSIDL_COMMON_DOCUMENTS */
1424 &FOLDERID_PublicDocuments,
1426 L"Common Documents",
1429 },
1430 { /* 0x2f - CSIDL_COMMON_ADMINTOOLS */
1431 &FOLDERID_CommonAdminTools,
1433 L"Common Administrative Tools",
1435 },
1436 { /* 0x30 - CSIDL_ADMINTOOLS */
1437 &FOLDERID_AdminTools,
1439 L"Administrative Tools",
1441 },
1442 { /* 0x31 - CSIDL_CONNECTIONS */
1443 &FOLDERID_ConnectionsFolder,
1445 NULL,
1446 NULL,
1448 },
1449 { /* 0x32 - unassigned */
1450 &GUID_NULL,
1452 NULL,
1453 NULL
1454 },
1455 { /* 0x33 - unassigned */
1456 &GUID_NULL,
1458 NULL,
1459 NULL
1460 },
1461 { /* 0x34 - unassigned */
1462 &GUID_NULL,
1464 NULL,
1465 NULL
1466 },
1467 { /* 0x35 - CSIDL_COMMON_MUSIC */
1468 &FOLDERID_PublicMusic,
1470 L"CommonMusic",
1473 },
1474 { /* 0x36 - CSIDL_COMMON_PICTURES */
1475 &FOLDERID_PublicPictures,
1477 L"CommonPictures",
1480 },
1481 { /* 0x37 - CSIDL_COMMON_VIDEO */
1482 &FOLDERID_PublicVideos,
1484 L"CommonVideo",
1487 },
1488 { /* 0x38 - CSIDL_RESOURCES */
1489 &FOLDERID_ResourceDir,
1491 NULL,
1492 L"Resources"
1493 },
1494 { /* 0x39 - CSIDL_RESOURCES_LOCALIZED */
1495 &FOLDERID_LocalizedResourcesDir,
1497 NULL,
1498 NULL
1499 },
1500 { /* 0x3a - CSIDL_COMMON_OEM_LINKS */
1501 &FOLDERID_CommonOEMLinks,
1503 NULL,
1504 L"OEM Links"
1505 },
1506 { /* 0x3b - CSIDL_CDBURN_AREA */
1507 &FOLDERID_CDBurning,
1509 L"CD Burning",
1510 L"Local Settings\\Application Data\\Microsoft\\CD Burning"
1511 },
1512 { /* 0x3c unassigned */
1513 &GUID_NULL,
1515 NULL,
1516 NULL
1517 },
1518 { /* 0x3d - CSIDL_COMPUTERSNEARME */
1519 &GUID_NULL,
1520 CSIDL_Type_Disallowed, /* FIXME */
1521 NULL,
1522 NULL
1523 },
1524 { /* 0x3e - CSIDL_PROFILES */
1525 &GUID_NULL,
1526 CSIDL_Type_Disallowed, /* oddly, this matches WinXP */
1527 NULL,
1528 NULL
1529 },
1530/* Cannot use #if _WIN32_WINNT >= 0x0600 because _WIN32_WINNT == 0x0600 here. */
1531#ifndef __REACTOS__
1532 { /* 0x3f */
1533 &FOLDERID_AddNewPrograms,
1535 NULL,
1536 NULL
1537 },
1538 { /* 0x40 */
1539 &FOLDERID_AppUpdates,
1541 NULL,
1542 NULL
1543 },
1544 { /* 0x41 */
1545 &FOLDERID_ChangeRemovePrograms,
1547 NULL,
1548 NULL
1549 },
1550 { /* 0x42 */
1551 &FOLDERID_ConflictFolder,
1553 NULL,
1554 NULL
1555 },
1556 { /* 0x43 - CSIDL_CONTACTS */
1557 &FOLDERID_Contacts,
1559 NULL,
1560 L"Contacts"
1561 },
1562 { /* 0x44 */
1563 &FOLDERID_DeviceMetadataStore,
1564 CSIDL_Type_Disallowed, /* FIXME */
1565 NULL,
1566 NULL
1567 },
1568 { /* 0x45 */
1569 &GUID_NULL,
1571 NULL,
1572 L"Documents"
1573 },
1574 { /* 0x46 */
1575 &FOLDERID_DocumentsLibrary,
1576 CSIDL_Type_Disallowed, /* FIXME */
1577 NULL,
1578 NULL
1579 },
1580 { /* 0x47 - CSIDL_DOWNLOADS */
1581 &FOLDERID_Downloads,
1582#ifdef __REACTOS__
1583 CSIDL_Type_InMyDocuments,
1584#else
1586#endif
1587 NULL,
1588 L"Downloads"
1589 },
1590 { /* 0x48 */
1591 &FOLDERID_Games,
1593 NULL,
1594 NULL
1595 },
1596 { /* 0x49 */
1597 &FOLDERID_GameTasks,
1598 CSIDL_Type_Disallowed, /* FIXME */
1599 NULL,
1600 NULL
1601 },
1602 { /* 0x4a */
1603 &FOLDERID_HomeGroup,
1605 NULL,
1606 NULL
1607 },
1608 { /* 0x4b */
1609 &FOLDERID_ImplicitAppShortcuts,
1610 CSIDL_Type_Disallowed, /* FIXME */
1611 NULL,
1612 NULL
1613 },
1614 { /* 0x4c */
1615 &FOLDERID_Libraries,
1616 CSIDL_Type_Disallowed, /* FIXME */
1617 NULL,
1618 NULL
1619 },
1620 { /* 0x4d - CSIDL_LINKS */
1621 &FOLDERID_Links,
1623 NULL,
1624 L"Links"
1625 },
1626 { /* 0x4e - CSIDL_APPDATA_LOCALLOW */
1627 &FOLDERID_LocalAppDataLow,
1629 NULL,
1630 L"AppData\\LocalLow"
1631 },
1632 { /* 0x4f */
1633 &FOLDERID_MusicLibrary,
1634 CSIDL_Type_Disallowed, /* FIXME */
1635 NULL,
1636 NULL
1637 },
1638 { /* 0x50 */
1639 &FOLDERID_OriginalImages,
1640 CSIDL_Type_Disallowed, /* FIXME */
1641 NULL,
1642 NULL
1643 },
1644 { /* 0x51 */
1645 &FOLDERID_PhotoAlbums,
1647 NULL,
1648 L"Pictures\\Slide Shows"
1649 },
1650 { /* 0x52 */
1651 &FOLDERID_PicturesLibrary,
1652 CSIDL_Type_Disallowed, /* FIXME */
1653 NULL,
1654 NULL
1655 },
1656 { /* 0x53 */
1657 &FOLDERID_Playlists,
1659 NULL,
1660 L"Music\\Playlists"
1661 },
1662 { /* 0x54 */
1663 &FOLDERID_ProgramFilesX64,
1665 NULL,
1666 NULL
1667 },
1668 { /* 0x55 */
1669 &FOLDERID_ProgramFilesCommonX64,
1671 NULL,
1672 NULL
1673 },
1674 { /* 0x56 */
1675 &FOLDERID_Public,
1676 CSIDL_Type_CurrVer, /* FIXME */
1677 NULL,
1678 L"Users\\Public"
1679 },
1680 { /* 0x57 */
1681 &FOLDERID_PublicDownloads,
1683 NULL,
1684 L"Downloads"
1685 },
1686 { /* 0x58 */
1687 &FOLDERID_PublicGameTasks,
1689 NULL,
1690 L"Microsoft\\Windows\\GameExplorer"
1691 },
1692 { /* 0x59 */
1693 &FOLDERID_PublicLibraries,
1695 NULL,
1696 L"Microsoft\\Windows\\Libraries"
1697 },
1698 { /* 0x5a */
1699 &FOLDERID_PublicRingtones,
1701 NULL,
1702 L"Microsoft\\Windows\\Ringtones"
1703 },
1704 { /* 0x5b */
1705 &FOLDERID_QuickLaunch,
1706 CSIDL_Type_Disallowed, /* FIXME */
1707 NULL,
1708 NULL
1709 },
1710 { /* 0x5c */
1711 &FOLDERID_RecordedTVLibrary,
1712 CSIDL_Type_Disallowed, /* FIXME */
1713 NULL,
1714 NULL
1715 },
1716 { /* 0x5d */
1717 &FOLDERID_Ringtones,
1718 CSIDL_Type_Disallowed, /* FIXME */
1719 NULL,
1720 NULL
1721 },
1722 { /* 0x5e */
1723 &FOLDERID_SampleMusic,
1725 NULL,
1726 L"Music\\Sample Music"
1727 },
1728 { /* 0x5f */
1729 &FOLDERID_SamplePictures,
1731 NULL,
1732 L"Pictures\\Sample Pictures"
1733 },
1734 { /* 0x60 */
1735 &FOLDERID_SamplePlaylists,
1737 NULL,
1738 L"Music\\Sample Playlists"
1739 },
1740 { /* 0x61 */
1741 &FOLDERID_SampleVideos,
1743 NULL,
1744 L"Videos\\Sample Videos"
1745 },
1746 { /* 0x62 - CSIDL_SAVED_GAMES */
1747 &FOLDERID_SavedGames,
1749 NULL,
1750 L"Saved Games"
1751 },
1752 { /* 0x63 - CSIDL_SEARCHES */
1753 &FOLDERID_SavedSearches,
1755 NULL,
1756 L"Searches"
1757 },
1758 { /* 0x64 */
1759 &FOLDERID_SEARCH_CSC,
1761 NULL,
1762 NULL
1763 },
1764 { /* 0x65 */
1765 &FOLDERID_SEARCH_MAPI,
1767 NULL,
1768 NULL
1769 },
1770 { /* 0x66 */
1771 &FOLDERID_SearchHome,
1773 NULL,
1774 NULL
1775 },
1776 { /* 0x67 */
1777 &FOLDERID_SidebarDefaultParts,
1778 CSIDL_Type_Disallowed, /* FIXME */
1779 NULL,
1780 NULL
1781 },
1782 { /* 0x68 */
1783 &FOLDERID_SidebarParts,
1784 CSIDL_Type_Disallowed, /* FIXME */
1785 NULL,
1786 NULL
1787 },
1788 { /* 0x69 */
1789 &FOLDERID_SyncManagerFolder,
1791 NULL,
1792 NULL
1793 },
1794 { /* 0x6a */
1795 &FOLDERID_SyncResultsFolder,
1797 NULL,
1798 NULL
1799 },
1800 { /* 0x6b */
1801 &FOLDERID_SyncSetupFolder,
1803 NULL,
1804 NULL
1805 },
1806 { /* 0x6c */
1807 &FOLDERID_UserPinned,
1808 CSIDL_Type_Disallowed, /* FIXME */
1809 NULL,
1810 NULL
1811 },
1812 { /* 0x6d */
1813 &FOLDERID_UserProfiles,
1815 L"Users",
1816 L"Users"
1817 },
1818 { /* 0x6e */
1819 &FOLDERID_UserProgramFiles,
1820 CSIDL_Type_Disallowed, /* FIXME */
1821 NULL,
1822 NULL
1823 },
1824 { /* 0x6f */
1825 &FOLDERID_UserProgramFilesCommon,
1826 CSIDL_Type_Disallowed, /* FIXME */
1827 NULL,
1828 NULL
1829 },
1830 { /* 0x70 */
1831 &FOLDERID_UsersFiles,
1833 NULL,
1834 NULL
1835 },
1836 { /* 0x71 */
1837 &FOLDERID_UsersLibraries,
1839 NULL,
1840 NULL
1841 },
1842 { /* 0x72 */
1843 &FOLDERID_VideosLibrary,
1844 CSIDL_Type_Disallowed, /* FIXME */
1845 NULL,
1846 NULL
1847 }
1848#endif
1849};
1850
1851#ifndef __REACTOS__
1853#else
1854static HRESULT _SHExpandEnvironmentStrings(HANDLE hToken, LPCWSTR szSrc, LPWSTR szDest, DWORD cchDest);
1855#endif
1856
1857/* Gets the value named value from the registry key
1858 * rootKey\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
1859 * (or from rootKey\userPrefix\... if userPrefix is not NULL) into path, which
1860 * is assumed to be MAX_PATH WCHARs in length.
1861 * If it exists, expands the value and writes the expanded value to
1862 * rootKey\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
1863 * Returns successful error code if the value was retrieved from the registry,
1864 * and a failure otherwise.
1865 */
1866#ifndef __REACTOS__
1868#else
1869static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, HANDLE hToken, LPCWSTR userPrefix,
1870#endif
1872{
1873 HRESULT hr;
1874 WCHAR shellFolderPath[MAX_PATH], userShellFolderPath[MAX_PATH];
1875 LPCWSTR pShellFolderPath, pUserShellFolderPath;
1876 HKEY userShellFolderKey, shellFolderKey;
1877 DWORD dwType, dwPathLen;
1878
1879 TRACE("%p,%s,%s,%p\n",rootKey, debugstr_w(userPrefix), debugstr_w(value),
1880 path);
1881
1882 if (userPrefix)
1883 {
1884 strcpyW(shellFolderPath, userPrefix);
1885 PathAddBackslashW(shellFolderPath);
1886 strcatW(shellFolderPath, szSHFolders);
1887 pShellFolderPath = shellFolderPath;
1888 strcpyW(userShellFolderPath, userPrefix);
1889 PathAddBackslashW(userShellFolderPath);
1890 strcatW(userShellFolderPath, szSHUserFolders);
1891 pUserShellFolderPath = userShellFolderPath;
1892 }
1893 else
1894 {
1895 pUserShellFolderPath = szSHUserFolders;
1896 pShellFolderPath = szSHFolders;
1897 }
1898
1899 if (RegCreateKeyW(rootKey, pShellFolderPath, &shellFolderKey))
1900 {
1901 TRACE("Failed to create %s\n", debugstr_w(pShellFolderPath));
1902 return E_FAIL;
1903 }
1904 if (RegCreateKeyW(rootKey, pUserShellFolderPath, &userShellFolderKey))
1905 {
1906 TRACE("Failed to create %s\n",
1907 debugstr_w(pUserShellFolderPath));
1908 RegCloseKey(shellFolderKey);
1909 return E_FAIL;
1910 }
1911
1912 dwPathLen = MAX_PATH * sizeof(WCHAR);
1913 if (!RegQueryValueExW(userShellFolderKey, value, NULL, &dwType,
1914 (LPBYTE)path, &dwPathLen) && (dwType == REG_EXPAND_SZ || dwType == REG_SZ))
1915 {
1916 LONG ret;
1917
1918 path[dwPathLen / sizeof(WCHAR)] = '\0';
1919 if (dwType == REG_EXPAND_SZ && path[0] == '%')
1920 {
1921 WCHAR szTemp[MAX_PATH];
1922
1923#ifndef __REACTOS__
1925#else
1926 hr = _SHExpandEnvironmentStrings(hToken, path, szTemp, _countof(szTemp));
1927 if (FAILED(hr))
1928 goto end;
1929#endif
1930 lstrcpynW(path, szTemp, MAX_PATH);
1931 }
1932 ret = RegSetValueExW(shellFolderKey, value, 0, REG_SZ, (LPBYTE)path,
1933 (strlenW(path) + 1) * sizeof(WCHAR));
1934 if (ret != ERROR_SUCCESS)
1936 else
1937 hr = S_OK;
1938 }
1939 else
1940 hr = E_FAIL;
1941#ifdef __REACTOS__
1942end:
1943#endif
1944 RegCloseKey(shellFolderKey);
1945 RegCloseKey(userShellFolderKey);
1946 TRACE("returning 0x%08x\n", hr);
1947 return hr;
1948}
1949
1951{
1952 BOOL result;
1953 if (!hToken)
1954 {
1956 result = GetUserProfileDirectoryW(hToken, szPath, lpcchPath);
1957 CloseHandle(hToken);
1958 }
1959 else if ((INT) hToken == -1)
1960 {
1962 }
1963 else
1964 {
1965 result = GetUserProfileDirectoryW(hToken, szPath, lpcchPath);
1966 }
1967 TRACE("_SHGetUserProfileDirectoryW returning %S\n", szPath);
1968 return result;
1969}
1970
1971/* Gets a 'semi-expanded' default value of the CSIDL with index folder into
1972 * pszPath, based on the entries in CSIDL_Data. By semi-expanded, I mean:
1973 * - The entry's szDefaultPath may be either a string value or an integer
1974 * resource identifier. In the latter case, the string value of the resource
1975 * is written.
1976 * - Depending on the entry's type, the path may begin with an (unexpanded)
1977 * environment variable name. The caller is responsible for expanding
1978 * environment strings if so desired.
1979 * The types that are prepended with environment variables are:
1980 * CSIDL_Type_User: %USERPROFILE%
1981 * CSIDL_Type_AllUsers: %ALLUSERSPROFILE%
1982 * CSIDL_Type_CurrVer: %SystemDrive%
1983 * (Others might make sense too, but as yet are unneeded.)
1984 */
1985#ifndef __REACTOS__
1987#else
1988static HRESULT _SHGetDefaultValue(HANDLE hToken, BYTE folder, LPWSTR pszPath)
1989#endif
1990{
1991 HRESULT hr;
1992 WCHAR resourcePath[MAX_PATH];
1993#ifdef __REACTOS__
1994 NT_PRODUCT_TYPE ProductType;
1995#endif
1996
1997 TRACE("0x%02x,%p\n", folder, pszPath);
1998
2000 return E_INVALIDARG;
2001
2002 if (!pszPath)
2003 return E_INVALIDARG;
2004
2005#ifdef __REACTOS__
2006 if (hToken != NULL && hToken != (HANDLE)-1)
2007 {
2008 FIXME("unsupported for user other than current or default\n");
2009 }
2010#endif
2011
2012 if (!is_win64)
2013 {
2014 BOOL is_wow64;
2015
2016 switch (folder)
2017 {
2022 break;
2027 break;
2028 }
2029 }
2030
2031 switch (CSIDL_Data[folder].type)
2032 {
2033 case CSIDL_Type_User:
2034 strcpyW(pszPath, L"%USERPROFILE%");
2035 break;
2036#ifdef __REACTOS__
2037 case CSIDL_Type_InMyDocuments:
2038 strcpyW(pszPath, L"%USERPROFILE%");
2039 if (DoGetProductType(&ProductType) && ProductType == NtProductWinNt)
2040 {
2041 if (IS_INTRESOURCE(CSIDL_Data[CSIDL_MYDOCUMENTS].szDefaultPath))
2042 {
2043 WCHAR szItem[MAX_PATH];
2045 LOWORD(CSIDL_Data[CSIDL_MYDOCUMENTS].szDefaultPath),
2046 szItem, ARRAY_SIZE(szItem));
2047 PathAppendW(pszPath, szItem);
2048 }
2049 else
2050 {
2051 PathAppendW(pszPath, CSIDL_Data[CSIDL_MYDOCUMENTS].szDefaultPath);
2052 }
2053 }
2054 break;
2055#endif
2057#ifndef __REACTOS__
2058 strcpyW(pszPath, L"%PUBLIC%");
2059#else
2060 strcpyW(pszPath, L"%ALLUSERSPROFILE%");
2061#endif
2062 break;
2063 case CSIDL_Type_CurrVer:
2064 strcpyW(pszPath, L"%SystemDrive%");
2065 break;
2066 default:
2067 ; /* no corresponding env. var, do nothing */
2068 }
2069
2070 hr = S_OK;
2071 if (CSIDL_Data[folder].szDefaultPath)
2072 {
2073 if (IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath))
2074 {
2076 LOWORD(CSIDL_Data[folder].szDefaultPath), resourcePath, MAX_PATH))
2077 {
2078 PathAppendW(pszPath, resourcePath);
2079 }
2080 else
2081 {
2082 ERR("(%d,%s), LoadString failed, missing translation?\n", folder,
2083 debugstr_w(pszPath));
2084 hr = E_FAIL;
2085 }
2086 }
2087 else
2088 {
2089 PathAppendW(pszPath, CSIDL_Data[folder].szDefaultPath);
2090 }
2091 }
2092 TRACE("returning 0x%08x\n", hr);
2093 return hr;
2094}
2095
2096/* Gets the (unexpanded) value of the folder with index folder into pszPath.
2097 * The folder's type is assumed to be CSIDL_Type_CurrVer. Its default value
2098 * can be overridden in the HKLM\\Software\\Microsoft\\Windows\\CurrentVersion key.
2099 * If dwFlags has SHGFP_TYPE_DEFAULT set or if the value isn't overridden in
2100 * the registry, uses _SHGetDefaultValue to get the value.
2101 */
2103 LPWSTR pszPath)
2104{
2105 HRESULT hr;
2106
2107 TRACE("0x%08x,0x%02x,%p\n", dwFlags, folder, pszPath);
2108
2110 return E_INVALIDARG;
2112 return E_INVALIDARG;
2113 if (!pszPath)
2114 return E_INVALIDARG;
2115
2117#ifndef __REACTOS__
2118 hr = _SHGetDefaultValue(folder, pszPath);
2119#else
2120 hr = _SHGetDefaultValue(NULL, folder, pszPath);
2121#endif
2122 else
2123 {
2124 HKEY hKey;
2125
2126 if (RegCreateKeyW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion", &hKey))
2127 hr = E_FAIL;
2128 else
2129 {
2130 DWORD dwType, dwPathLen = MAX_PATH * sizeof(WCHAR);
2131
2132 if (RegQueryValueExW(hKey, CSIDL_Data[folder].szValueName, NULL,
2133 &dwType, (LPBYTE)pszPath, &dwPathLen) ||
2134 (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
2135 {
2136#ifndef __REACTOS__
2137 hr = _SHGetDefaultValue(folder, pszPath);
2138#else
2139 hr = _SHGetDefaultValue(NULL, folder, pszPath);
2140#endif
2141 dwType = REG_EXPAND_SZ;
2142 switch (folder)
2143 {
2146 /* these two should never be set on 32-bit setups */
2147 if (!is_win64)
2148 {
2149 BOOL is_wow64;
2151 if (!is_wow64) break;
2152 }
2153 /* fall through */
2154 default:
2155 RegSetValueExW(hKey, CSIDL_Data[folder].szValueName, 0, dwType,
2156 (LPBYTE)pszPath, (strlenW(pszPath)+1)*sizeof(WCHAR));
2157 }
2158 }
2159 else
2160 {
2161 pszPath[dwPathLen / sizeof(WCHAR)] = '\0';
2162 hr = S_OK;
2163 }
2165 }
2166 }
2167 TRACE("returning 0x%08x (output path is %s)\n", hr, debugstr_w(pszPath));
2168 return hr;
2169}
2170
2172{
2173 char InfoBuffer[64];
2174 PTOKEN_USER UserInfo;
2175 DWORD InfoSize;
2176 LPWSTR SidStr;
2177
2178 UserInfo = (PTOKEN_USER) InfoBuffer;
2179 if (! GetTokenInformation(Token, TokenUser, InfoBuffer, sizeof(InfoBuffer),
2180 &InfoSize))
2181 {
2183 return NULL;
2184 UserInfo = HeapAlloc(GetProcessHeap(), 0, InfoSize);
2185 if (UserInfo == NULL)
2186 return NULL;
2187 if (! GetTokenInformation(Token, TokenUser, UserInfo, InfoSize,
2188 &InfoSize))
2189 {
2190 HeapFree(GetProcessHeap(), 0, UserInfo);
2191 return NULL;
2192 }
2193 }
2194
2195 if (! ConvertSidToStringSidW(UserInfo->User.Sid, &SidStr))
2196 SidStr = NULL;
2197
2198 if (UserInfo != (PTOKEN_USER) InfoBuffer)
2199 HeapFree(GetProcessHeap(), 0, UserInfo);
2200
2201 return SidStr;
2202}
2203
2204/* Gets the user's path (unexpanded) for the CSIDL with index folder:
2205 * If SHGFP_TYPE_DEFAULT is set, calls _SHGetDefaultValue for it. Otherwise
2206 * calls _SHGetUserShellFolderPath for it. Where it looks depends on hToken:
2207 * - if hToken is -1, looks in HKEY_USERS\.Default
2208 * - otherwise looks first in HKEY_CURRENT_USER, followed by HKEY_LOCAL_MACHINE
2209 * if HKEY_CURRENT_USER doesn't contain any entries. If both fail, finally
2210 * calls _SHGetDefaultValue for it.
2211 */
2213 LPWSTR pszPath)
2214{
2215 const WCHAR *szValueName;
2216 WCHAR buffer[40];
2217 HRESULT hr;
2218
2219 TRACE("%p,0x%08x,0x%02x,%p\n", hToken, dwFlags, folder, pszPath);
2220
2222 return E_INVALIDARG;
2223#ifdef __REACTOS__
2225 CSIDL_Data[folder].type != CSIDL_Type_InMyDocuments)
2226#else
2228#endif
2229 {
2230 return E_INVALIDARG;
2231 }
2232 if (!pszPath)
2233 return E_INVALIDARG;
2234
2236 {
2237#ifndef __REACTOS__
2238 hr = _SHGetDefaultValue(folder, pszPath);
2239#else
2240 hr = _SHGetDefaultValue(hToken, folder, pszPath);
2241#endif
2242 }
2243 else
2244 {
2245 static const WCHAR DefaultW[] = L".Default";
2246 LPCWSTR userPrefix = NULL;
2247 HKEY hRootKey;
2248
2249 if (hToken == (HANDLE)-1)
2250 {
2251 hRootKey = HKEY_USERS;
2252 userPrefix = DefaultW;
2253 }
2254 else if (hToken == NULL)
2255 hRootKey = HKEY_CURRENT_USER;
2256 else
2257 {
2258 hRootKey = HKEY_USERS;
2259 userPrefix = _GetUserSidStringFromToken(hToken);
2260 if (userPrefix == NULL)
2261 {
2262 hr = E_FAIL;
2263 goto error;
2264 }
2265 }
2266
2267 /* For CSIDL_Type_User we also use the GUID if no szValueName is provided */
2268 szValueName = CSIDL_Data[folder].szValueName;
2269 if (!szValueName)
2270 {
2272 szValueName = &buffer[0];
2273 }
2274
2275#ifndef __REACTOS__
2276 hr = _SHGetUserShellFolderPath(hRootKey, userPrefix, szValueName, pszPath);
2277 if (FAILED(hr) && hRootKey != HKEY_LOCAL_MACHINE)
2278 hr = _SHGetUserShellFolderPath(HKEY_LOCAL_MACHINE, NULL, szValueName, pszPath);
2279 if (FAILED(hr))
2280 hr = _SHGetDefaultValue(folder, pszPath);
2281#else
2282 hr = _SHGetUserShellFolderPath(hRootKey, hToken, userPrefix, szValueName, pszPath);
2283 if (FAILED(hr) && hRootKey != HKEY_LOCAL_MACHINE)
2284 hr = _SHGetUserShellFolderPath(HKEY_LOCAL_MACHINE, hToken, NULL, szValueName, pszPath);
2285 if (FAILED(hr))
2286 hr = _SHGetDefaultValue(hToken, folder, pszPath);
2287#endif
2288 if (userPrefix != NULL && userPrefix != DefaultW)
2289 LocalFree((HLOCAL) userPrefix);
2290 }
2291error:
2292 TRACE("returning 0x%08x (output path is %s)\n", hr, debugstr_w(pszPath));
2293 return hr;
2294}
2295
2296/* Gets the (unexpanded) path for the CSIDL with index folder. If dwFlags has
2297 * SHGFP_TYPE_DEFAULT set, calls _SHGetDefaultValue. Otherwise calls
2298 * _SHGetUserShellFolderPath for it, looking only in HKEY_LOCAL_MACHINE.
2299 * If this fails, falls back to _SHGetDefaultValue.
2300 */
2302 LPWSTR pszPath)
2303{
2304 HRESULT hr;
2305
2306 TRACE("0x%08x,0x%02x,%p\n", dwFlags, folder, pszPath);
2307
2309 return E_INVALIDARG;
2311 return E_INVALIDARG;
2312 if (!pszPath)
2313 return E_INVALIDARG;
2314
2316#ifndef __REACTOS__
2317 hr = _SHGetDefaultValue(folder, pszPath);
2318#else
2319 hr = _SHGetDefaultValue(NULL, folder, pszPath);
2320#endif
2321 else
2322 {
2323#ifndef __REACTOS__
2325#else
2327#endif
2328 CSIDL_Data[folder].szValueName, pszPath);
2329 if (FAILED(hr))
2330#ifndef __REACTOS__
2331 hr = _SHGetDefaultValue(folder, pszPath);
2332#else
2333 hr = _SHGetDefaultValue(NULL, folder, pszPath);
2334#endif
2335 }
2336 TRACE("returning 0x%08x (output path is %s)\n", hr, debugstr_w(pszPath));
2337 return hr;
2338}
2339
2340#ifndef __REACTOS__
2342{
2343 LONG lRet;
2344 DWORD disp;
2345
2346 lRet = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList", 0, NULL, 0,
2347 KEY_ALL_ACCESS, NULL, pKey, &disp);
2348 return HRESULT_FROM_WIN32(lRet);
2349}
2350
2351/* Reads the value named szValueName from the key profilesKey (assumed to be
2352 * opened by _SHOpenProfilesKey) into szValue, which is assumed to be MAX_PATH
2353 * WCHARs in length. If it doesn't exist, returns szDefault (and saves
2354 * szDefault to the registry).
2355 */
2356static HRESULT _SHGetProfilesValue(HKEY profilesKey, LPCWSTR szValueName,
2357 LPWSTR szValue, LPCWSTR szDefault)
2358{
2359 HRESULT hr;
2360 DWORD type, dwPathLen = MAX_PATH * sizeof(WCHAR);
2361 LONG lRet;
2362
2363 TRACE("%p,%s,%p,%s\n", profilesKey, debugstr_w(szValueName), szValue,
2364 debugstr_w(szDefault));
2365 lRet = RegQueryValueExW(profilesKey, szValueName, NULL, &type,
2366 (LPBYTE)szValue, &dwPathLen);
2367 if (!lRet && (type == REG_SZ || type == REG_EXPAND_SZ) && dwPathLen
2368 && *szValue)
2369 {
2370 dwPathLen /= sizeof(WCHAR);
2371 szValue[dwPathLen] = '\0';
2372 hr = S_OK;
2373 }
2374 else
2375 {
2376 /* Missing or invalid value, set a default */
2377 lstrcpynW(szValue, szDefault, MAX_PATH);
2378 TRACE("Setting missing value %s to %s\n", debugstr_w(szValueName),
2379 debugstr_w(szValue));
2380 lRet = RegSetValueExW(profilesKey, szValueName, 0, REG_EXPAND_SZ,
2381 (LPBYTE)szValue,
2382 (strlenW(szValue) + 1) * sizeof(WCHAR));
2383 if (lRet)
2384 hr = HRESULT_FROM_WIN32(lRet);
2385 else
2386 hr = S_OK;
2387 }
2388 TRACE("returning 0x%08x (output value is %s)\n", hr, debugstr_w(szValue));
2389 return hr;
2390}
2391#endif
2392
2393/* Attempts to expand environment variables from szSrc into szDest, which is
2394 * assumed to be MAX_PATH characters in length. Before referring to the
2395 * environment, handles a few variables directly, because the environment
2396 * variables may not be set when this is called (as during Wine's installation
2397 * when default values are being written to the registry).
2398 * The directly handled environment variables, and their source, are:
2399 * - ALLUSERSPROFILE, USERPROFILE: reads from the registry
2400 * - SystemDrive: uses GetSystemDirectoryW and uses the drive portion of its
2401 * path
2402 * If one of the directly handled environment variables is expanded, only
2403 * expands a single variable, and only in the beginning of szSrc.
2404 */
2405#ifndef __REACTOS__
2407#else
2408static HRESULT _SHExpandEnvironmentStrings(HANDLE hToken, LPCWSTR szSrc, LPWSTR szDest, DWORD cchDest)
2409#endif
2410{
2411 HRESULT hr;
2412#ifndef __REACTOS__
2413 WCHAR szTemp[MAX_PATH], szProfilesPrefix[MAX_PATH] = { 0 };
2414 HKEY key = NULL;
2415#else
2416 WCHAR szTemp[MAX_PATH];
2417#endif
2418
2419 TRACE("%s, %p\n", debugstr_w(szSrc), szDest);
2420
2421 if (!szSrc || !szDest) return E_INVALIDARG;
2422
2423 /* short-circuit if there's nothing to expand */
2424 if (szSrc[0] != '%')
2425 {
2426 strcpyW(szDest, szSrc);
2427 hr = S_OK;
2428 goto end;
2429 }
2430#ifndef __REACTOS__
2431 /* Get the profile prefix, we'll probably be needing it */
2433 if (SUCCEEDED(hr))
2434 {
2435 WCHAR def_val[MAX_PATH];
2436
2437 /* get the system drive */
2438 GetSystemDirectoryW(def_val, MAX_PATH);
2439 strcpyW( def_val + 3, L"Users" );
2440
2441 hr = _SHGetProfilesValue(key, L"ProfilesDirectory", szProfilesPrefix, def_val );
2442 }
2443#else
2444 hr = S_OK;
2445#endif
2446
2447 *szDest = 0;
2448 strcpyW(szTemp, szSrc);
2449 while (SUCCEEDED(hr) && szTemp[0] == '%')
2450 {
2451 if (!strncmpiW(szTemp, L"%ALLUSERSPROFILE%", ARRAY_SIZE(L"%ALLUSERSPROFILE%")-1))
2452 {
2453#ifndef __REACTOS__
2454 WCHAR szAllUsers[MAX_PATH];
2455
2456 strcpyW(szDest, szProfilesPrefix);
2457 hr = _SHGetProfilesValue(key, L"AllUsersProfile", szAllUsers, L"Public");
2458 PathAppendW(szDest, szAllUsers);
2459#else
2460 DWORD cchSize = cchDest;
2461 if (!GetAllUsersProfileDirectoryW(szDest, &cchSize))
2462 goto fallback_expand;
2463#endif
2464 PathAppendW(szDest, szTemp + ARRAY_SIZE(L"%ALLUSERSPROFILE%")-1);
2465 }
2466#ifndef __REACTOS__
2467 else if (!strncmpiW(szTemp, L"%PUBLIC%", ARRAY_SIZE(L"%PUBLIC%")-1))
2468 {
2469 WCHAR szAllUsers[MAX_PATH], def_val[MAX_PATH];
2470
2471 GetSystemDirectoryW(def_val, MAX_PATH);
2472 strcpyW( def_val + 3, L"Users\\Public" );
2473
2474 hr = _SHGetProfilesValue(key, L"Public", szAllUsers, def_val);
2475 PathAppendW(szDest, szAllUsers);
2476 PathAppendW(szDest, szTemp + ARRAY_SIZE(L"%PUBLIC%")-1);
2477 }
2478#endif
2479 else if (!strncmpiW(szTemp, L"%USERPROFILE%", ARRAY_SIZE(L"%USERPROFILE%")-1))
2480 {
2481#ifndef __REACTOS__
2483 DWORD userLen = MAX_PATH;
2484
2485 strcpyW(szDest, szProfilesPrefix);
2486 GetUserNameW(userName, &userLen);
2487 PathAppendW(szDest, userName);
2488#else
2489 DWORD cchSize = cchDest;
2490 if (!_SHGetUserProfileDirectoryW(hToken, szDest, &cchSize))
2491 goto fallback_expand;
2492#endif
2493 PathAppendW(szDest, szTemp + ARRAY_SIZE(L"%USERPROFILE%")-1);
2494 }
2495 else if (!strncmpiW(szTemp, L"%SystemDrive%", ARRAY_SIZE(L"%SystemDrive%")-1))
2496 {
2497#ifndef __REACTOS__
2499#else
2500 if (!GetSystemDirectoryW(szDest, cchDest))
2501 goto fallback_expand;
2502#endif
2503 strcpyW(szDest + 3, szTemp + ARRAY_SIZE(L"%SystemDrive%")-1 + 1);
2504 }
2505 else
2506#ifdef __REACTOS__
2507fallback_expand:
2508#endif
2509 {
2510#ifndef __REACTOS__
2511 DWORD ret = ExpandEnvironmentStringsW(szTemp, szDest, MAX_PATH);
2512#else
2513 DWORD ret = SHExpandEnvironmentStringsForUserW(hToken, szTemp, szDest, cchDest);
2514#endif
2515
2516#ifndef __REACTOS__
2517 if (ret > MAX_PATH)
2518#else
2519 if (ret > cchDest)
2520#endif
2522 else if (ret == 0)
2524 else if (!strcmpW( szTemp, szDest )) break; /* nothing expanded */
2525 }
2526 if (SUCCEEDED(hr)) strcpyW(szTemp, szDest);
2527 }
2528end:
2529#ifndef __REACTOS__
2530 if (key)
2532#endif
2533 TRACE("returning 0x%08x (input was %s, output is %s)\n", hr,
2534 debugstr_w(szSrc), debugstr_w(szDest));
2535 return hr;
2536}
2537
2538/*************************************************************************
2539 * SHGetFolderPathW [SHELL32.@]
2540 *
2541 * Convert nFolder to path.
2542 *
2543 * RETURNS
2544 * Success: S_OK
2545 * Failure: standard HRESULT error codes.
2546 *
2547 * NOTES
2548 * Most values can be overridden in either
2549 * HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
2550 * or in the same location in HKLM.
2551 * The "Shell Folders" registry key was used in NT4 and earlier systems.
2552 * Beginning with Windows 2000, the "User Shell Folders" key is used, so
2553 * changes made to it are made to the former key too. This synchronization is
2554 * done on-demand: not until someone requests the value of one of these paths
2555 * (by calling one of the SHGet functions) is the value synchronized.
2556 * Furthermore, the HKCU paths take precedence over the HKLM paths.
2557 */
2559 HWND hwndOwner, /* [I] owner window */
2560 int nFolder, /* [I] CSIDL identifying the folder */
2561 HANDLE hToken, /* [I] access token */
2562 DWORD dwFlags, /* [I] which path to return */
2563 LPWSTR pszPath) /* [O] converted path */
2564{
2565 HRESULT hr = SHGetFolderPathAndSubDirW(hwndOwner, nFolder, hToken, dwFlags, NULL, pszPath);
2568 return hr;
2569}
2570
2572 HWND hwndOwner, /* [I] owner window */
2573 int nFolder, /* [I] CSIDL identifying the folder */
2574 HANDLE hToken, /* [I] access token */
2575 DWORD dwFlags, /* [I] which path to return */
2576 LPCSTR pszSubPath, /* [I] sub directory of the specified folder */
2577 LPSTR pszPath) /* [O] converted path */
2578{
2579 int length;
2580 HRESULT hr = S_OK;
2581 LPWSTR pszSubPathW = NULL;
2582 LPWSTR pszPathW = NULL;
2583
2584 TRACE("%p,%#x,%p,%#x,%s,%p\n", hwndOwner, nFolder, hToken, dwFlags, debugstr_a(pszSubPath), pszPath);
2585
2586 if(pszPath) {
2587 pszPathW = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
2588 if(!pszPathW) {
2590 goto cleanup;
2591 }
2592 }
2593 TRACE("%08x,%08x,%s\n",nFolder, dwFlags, debugstr_w(pszSubPathW));
2594
2595 /* SHGetFolderPathAndSubDirW does not distinguish if pszSubPath isn't
2596 * set (null), or an empty string.therefore call it without the parameter set
2597 * if pszSubPath is an empty string
2598 */
2599 if (pszSubPath && pszSubPath[0]) {
2600 length = MultiByteToWideChar(CP_ACP, 0, pszSubPath, -1, NULL, 0);
2601 pszSubPathW = HeapAlloc(GetProcessHeap(), 0, length * sizeof(WCHAR));
2602 if(!pszSubPathW) {
2604 goto cleanup;
2605 }
2606 MultiByteToWideChar(CP_ACP, 0, pszSubPath, -1, pszSubPathW, length);
2607 }
2608
2609 hr = SHGetFolderPathAndSubDirW(hwndOwner, nFolder, hToken, dwFlags, pszSubPathW, pszPathW);
2610
2611 if (SUCCEEDED(hr) && pszPath)
2612 WideCharToMultiByte(CP_ACP, 0, pszPathW, -1, pszPath, MAX_PATH, NULL, NULL);
2613
2614cleanup:
2615 HeapFree(GetProcessHeap(), 0, pszPathW);
2616 HeapFree(GetProcessHeap(), 0, pszSubPathW);
2617 return hr;
2618}
2619
2620/*************************************************************************
2621 * SHGetFolderPathAndSubDirW [SHELL32.@]
2622 */
2624 HWND hwndOwner, /* [I] owner window */
2625 int nFolder, /* [I] CSIDL identifying the folder */
2626 HANDLE hToken, /* [I] access token */
2627 DWORD dwFlags, /* [I] which path to return */
2628 LPCWSTR pszSubPath,/* [I] sub directory of the specified folder */
2629 LPWSTR pszPath) /* [O] converted path */
2630{
2631 HRESULT hr;
2632 WCHAR szBuildPath[MAX_PATH], szTemp[MAX_PATH];
2635 int ret;
2636
2637 TRACE("%p,%#x,%p,%#x,%s,%p\n", hwndOwner, nFolder, hToken, dwFlags, debugstr_w(pszSubPath), pszPath);
2638
2639 /* Windows always NULL-terminates the resulting path regardless of success
2640 * or failure, so do so first
2641 */
2642 if (pszPath)
2643 *pszPath = '\0';
2644
2646 return E_INVALIDARG;
2648 return E_INVALIDARG;
2649 szTemp[0] = 0;
2651 switch (type)
2652 {
2654 hr = E_INVALIDARG;
2655 break;
2657 hr = S_FALSE;
2658 break;
2661 if (CSIDL_Data[folder].szDefaultPath &&
2662 !IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath) &&
2663 *CSIDL_Data[folder].szDefaultPath)
2664 {
2665 PathAddBackslashW(szTemp);
2666 strcatW(szTemp, CSIDL_Data[folder].szDefaultPath);
2667 }
2668 hr = S_OK;
2669 break;
2672 if (CSIDL_Data[folder].szDefaultPath &&
2673 !IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath) &&
2674 *CSIDL_Data[folder].szDefaultPath)
2675 {
2676 PathAddBackslashW(szTemp);
2677 strcatW(szTemp, CSIDL_Data[folder].szDefaultPath);
2678 }
2679 hr = S_OK;
2680 break;
2683 if (CSIDL_Data[folder].szDefaultPath &&
2684 !IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath) &&
2685 *CSIDL_Data[folder].szDefaultPath)
2686 {
2687 PathAddBackslashW(szTemp);
2688 strcatW(szTemp, CSIDL_Data[folder].szDefaultPath);
2689 }
2690 hr = S_OK;
2691 break;
2692 case CSIDL_Type_CurrVer:
2694 break;
2695 case CSIDL_Type_User:
2696#ifdef __REACTOS__
2697 case CSIDL_Type_InMyDocuments:
2698#endif
2699 hr = _SHGetUserProfilePath(hToken, dwFlags, folder, szTemp);
2700 break;
2703 break;
2704 default:
2705 FIXME("bogus type %d, please fix\n", type);
2706 hr = E_INVALIDARG;
2707 break;
2708 }
2709
2710 /* Expand environment strings if necessary */
2711 if (*szTemp == '%')
2712#ifndef __REACTOS__
2713 hr = _SHExpandEnvironmentStrings(szTemp, szBuildPath);
2714#else
2715 hr = _SHExpandEnvironmentStrings(hToken, szTemp, szBuildPath, _countof(szBuildPath));
2716#endif
2717 else
2718 strcpyW(szBuildPath, szTemp);
2719
2720 if (FAILED(hr)) goto end;
2721
2722 if(pszSubPath) {
2723 /* make sure the new path does not exceed the buffer length
2724 * and remember to backslash and terminate it */
2725 if(MAX_PATH < (lstrlenW(szBuildPath) + lstrlenW(pszSubPath) + 2)) {
2727 goto end;
2728 }
2729 PathAppendW(szBuildPath, pszSubPath);
2730 PathRemoveBackslashW(szBuildPath);
2731 }
2732 /* Copy the path if it's available before we might return */
2733 if (SUCCEEDED(hr) && pszPath)
2734 strcpyW(pszPath, szBuildPath);
2735
2736 /* if we don't care about existing directories we are ready */
2738
2739 if (PathFileExistsW(szBuildPath)) goto end;
2740
2741 /* not existing but we are not allowed to create it. The return value
2742 * is verified against shell32 version 6.0.
2743 */
2744 if (!(nFolder & CSIDL_FLAG_CREATE))
2745 {
2747 goto end;
2748 }
2749
2750 /* create directory/directories */
2751 ret = SHCreateDirectoryExW(hwndOwner, szBuildPath, NULL);
2752 if (ret && ret != ERROR_ALREADY_EXISTS)
2753 {
2754 ERR("Failed to create directory %s.\n", debugstr_w(szBuildPath));
2755 hr = E_FAIL;
2756 goto end;
2757 }
2758
2759 TRACE("Created missing system directory %s\n", debugstr_w(szBuildPath));
2760
2761end:
2762#ifdef __REACTOS__
2763 /* create desktop.ini for custom icon */
2764 if ((nFolder & CSIDL_FLAG_CREATE) &&
2765 CSIDL_Data[folder].nShell32IconIndex)
2766 {
2767 WCHAR szIconLocation[MAX_PATH];
2769
2770 /* make the directory a read-only folder */
2771 dwAttributes = GetFileAttributesW(szBuildPath);
2773 SetFileAttributesW(szBuildPath, dwAttributes);
2774
2775 /* build the desktop.ini file path */
2776 PathAppendW(szBuildPath, L"desktop.ini");
2777
2778 /* build the icon location */
2779 StringCchPrintfW(szIconLocation, _countof(szIconLocation),
2780 L"%%SystemRoot%%\\system32\\shell32.dll,%d",
2781 CSIDL_Data[folder].nShell32IconIndex);
2782
2783 /* write desktop.ini */
2784 WritePrivateProfileStringW(L".ShellClassInfo", L"IconResource", szIconLocation, szBuildPath);
2785
2786 /* flush! */
2787 WritePrivateProfileStringW(NULL, NULL, NULL, szBuildPath);
2788
2789 /* make the desktop.ini a system and hidden file */
2790 dwAttributes = GetFileAttributesW(szBuildPath);
2792 SetFileAttributesW(szBuildPath, dwAttributes);
2793 }
2794#endif
2795
2796 TRACE("returning 0x%08x (final path is %s)\n", hr, debugstr_w(szBuildPath));
2797 return hr;
2798}
2799
2800/*************************************************************************
2801 * SHGetFolderPathA [SHELL32.@]
2802 *
2803 * See SHGetFolderPathW.
2804 */
2806 HWND hwndOwner,
2807 int nFolder,
2808 HANDLE hToken,
2809 DWORD dwFlags,
2810 LPSTR pszPath)
2811{
2812 WCHAR szTemp[MAX_PATH];
2813 HRESULT hr;
2814
2815 TRACE("%p,%d,%p,%#x,%p\n", hwndOwner, nFolder, hToken, dwFlags, pszPath);
2816
2817 if (pszPath)
2818 *pszPath = '\0';
2819 hr = SHGetFolderPathW(hwndOwner, nFolder, hToken, dwFlags, szTemp);
2820 if (SUCCEEDED(hr) && pszPath)
2821 WideCharToMultiByte(CP_ACP, 0, szTemp, -1, pszPath, MAX_PATH, NULL,
2822 NULL);
2823
2824 return hr;
2825}
2826
2827/* For each folder in folders, if its value has not been set in the registry,
2828 * calls _SHGetUserProfilePath or _SHGetAllUsersProfilePath (depending on the
2829 * folder's type) to get the unexpanded value first.
2830 * Writes the unexpanded value to User Shell Folders, and queries it with
2831 * SHGetFolderPathW to force the creation of the directory if it doesn't
2832 * already exist. SHGetFolderPathW also returns the expanded value, which
2833 * this then writes to Shell Folders.
2834 */
2835static HRESULT _SHRegisterFolders(HKEY hRootKey, HANDLE hToken,
2836 LPCWSTR szUserShellFolderPath, LPCWSTR szShellFolderPath, const UINT folders[],
2837 UINT foldersLen)
2838{
2839 const WCHAR *szValueName;
2840 WCHAR buffer[40];
2841 UINT i;
2843 HRESULT hr = S_OK;
2844 HKEY hUserKey = NULL, hKey = NULL;
2845 DWORD dwType, dwPathLen;
2846 LONG ret;
2847
2848 TRACE("%p,%p,%s,%p,%u\n", hRootKey, hToken,
2849 debugstr_w(szUserShellFolderPath), folders, foldersLen);
2850
2851 ret = RegCreateKeyW(hRootKey, szUserShellFolderPath, &hUserKey);
2852 if (ret)
2854 else
2855 {
2856 ret = RegCreateKeyW(hRootKey, szShellFolderPath, &hKey);
2857 if (ret)
2859 }
2860 for (i = 0; SUCCEEDED(hr) && i < foldersLen; i++)
2861 {
2862 dwPathLen = MAX_PATH * sizeof(WCHAR);
2863
2864 /* For CSIDL_Type_User we also use the GUID if no szValueName is provided */
2865 szValueName = CSIDL_Data[folders[i]].szValueName;
2866#ifdef __REACTOS__
2867 if (!szValueName &&
2868 (CSIDL_Data[folders[i]].type == CSIDL_Type_User ||
2869 CSIDL_Data[folders[i]].type == CSIDL_Type_InMyDocuments))
2870#else
2871 if (!szValueName && CSIDL_Data[folders[i]].type == CSIDL_Type_User)
2872#endif
2873 {
2874 StringFromGUID2( CSIDL_Data[folders[i]].id, buffer, 39 );
2875 szValueName = &buffer[0];
2876 }
2877
2878 if (!RegQueryValueExW(hUserKey, szValueName, NULL,
2879 &dwType, (LPBYTE)path, &dwPathLen) &&
2880 (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
2881 {
2883 hToken, SHGFP_TYPE_CURRENT, path);
2884 }
2885 else
2886 {
2887 *path = '\0';
2888#ifdef __REACTOS__
2889 if (CSIDL_Data[folders[i]].type == CSIDL_Type_User ||
2890 CSIDL_Data[folders[i]].type == CSIDL_Type_InMyDocuments)
2891#else
2892 if (CSIDL_Data[folders[i]].type == CSIDL_Type_User)
2893#endif
2894 _SHGetUserProfilePath(hToken, SHGFP_TYPE_CURRENT, folders[i],
2895 path);
2896 else if (CSIDL_Data[folders[i]].type == CSIDL_Type_AllUsers)
2898 else if (CSIDL_Data[folders[i]].type == CSIDL_Type_WindowsPath)
2899 {
2901 if (CSIDL_Data[folders[i]].szDefaultPath &&
2902 !IS_INTRESOURCE(CSIDL_Data[folders[i]].szDefaultPath))
2903 {
2905 strcatW(path, CSIDL_Data[folders[i]].szDefaultPath);
2906 }
2907 }
2908 else
2909 hr = E_FAIL;
2910 if (*path)
2911 {
2912 ret = RegSetValueExW(hUserKey, szValueName, 0, REG_EXPAND_SZ,
2913 (LPBYTE)path, (strlenW(path) + 1) * sizeof(WCHAR));
2914 if (ret)
2916 else
2917 {
2919 hToken, SHGFP_TYPE_CURRENT, path);
2920 ret = RegSetValueExW(hKey, szValueName, 0, REG_SZ,
2921 (LPBYTE)path, (strlenW(path) + 1) * sizeof(WCHAR));
2922 if (ret)
2924 }
2925 }
2926 }
2927 }
2928 if (hUserKey)
2929 RegCloseKey(hUserKey);
2930 if (hKey)
2932
2933 TRACE("returning 0x%08x\n", hr);
2934 return hr;
2935}
2936
2938{
2939 static const UINT folders[] = {
2961/* Cannot use #if _WIN32_WINNT >= 0x0600 because _WIN32_WINNT == 0x0600 here. */
2962#ifndef __REACTOS__
2969#endif
2970 };
2971 WCHAR userShellFolderPath[MAX_PATH], shellFolderPath[MAX_PATH];
2972 LPCWSTR pUserShellFolderPath, pShellFolderPath;
2973 HRESULT hr = S_OK;
2974 HKEY hRootKey;
2975 HANDLE hToken;
2976
2977 TRACE("%s\n", bDefault ? "TRUE" : "FALSE");
2978 if (bDefault)
2979 {
2980 hToken = (HANDLE)-1;
2981 hRootKey = HKEY_USERS;
2982 strcpyW(userShellFolderPath, L".Default");
2983 PathAddBackslashW(userShellFolderPath);
2984 strcatW(userShellFolderPath, szSHUserFolders);
2985 pUserShellFolderPath = userShellFolderPath;
2986 strcpyW(shellFolderPath, L".Default");
2987 PathAddBackslashW(shellFolderPath);
2988 strcatW(shellFolderPath, szSHFolders);
2989 pShellFolderPath = shellFolderPath;
2990 }
2991 else
2992 {
2993 hToken = NULL;
2994 hRootKey = HKEY_CURRENT_USER;
2995 pUserShellFolderPath = szSHUserFolders;
2996 pShellFolderPath = szSHFolders;
2997 }
2998
2999 hr = _SHRegisterFolders(hRootKey, hToken, pUserShellFolderPath,
3000 pShellFolderPath, folders, ARRAY_SIZE(folders));
3001 TRACE("returning 0x%08x\n", hr);
3002 return hr;
3003}
3004
3006{
3007 static const UINT folders[] = {
3020 };
3021 HRESULT hr;
3022
3023 TRACE("\n");
3025 szSHFolders, folders, ARRAY_SIZE(folders));
3026 TRACE("returning 0x%08x\n", hr);
3027 return hr;
3028}
3029
3030/* Register the default values in the registry, as some apps seem to depend
3031 * on their presence. The set registered was taken from Windows XP.
3032 */
3034{
3035 HRESULT hr;
3036
3038 if (SUCCEEDED(hr))
3040 if (SUCCEEDED(hr))
3042 return hr;
3043}
3044
3045/*************************************************************************
3046 * SHGetSpecialFolderPathA [SHELL32.@]
3047 */
3049 HWND hwndOwner,
3050 LPSTR szPath,
3051 int nFolder,
3052 BOOL bCreate)
3053{
3054 return SHGetFolderPathA(hwndOwner, nFolder + (bCreate ? CSIDL_FLAG_CREATE : 0), NULL, 0,
3055 szPath) == S_OK;
3056}
3057
3058/*************************************************************************
3059 * SHGetSpecialFolderPathW
3060 */
3062 HWND hwndOwner,
3063 LPWSTR szPath,
3064 int nFolder,
3065 BOOL bCreate)
3066{
3067 return SHGetFolderPathW(hwndOwner, nFolder + (bCreate ? CSIDL_FLAG_CREATE : 0), NULL, 0,
3068 szPath) == S_OK;
3069}
3070
3071/*************************************************************************
3072 * SHGetFolderLocation [SHELL32.@]
3073 *
3074 * Gets the folder locations from the registry and creates a pidl.
3075 *
3076 * PARAMS
3077 * hwndOwner [I]
3078 * nFolder [I] CSIDL_xxxxx
3079 * hToken [I] token representing user, or NULL for current user, or -1 for
3080 * default user
3081 * dwReserved [I] must be zero
3082 * ppidl [O] PIDL of a special folder
3083 *
3084 * RETURNS
3085 * Success: S_OK
3086 * Failure: Standard OLE-defined error result, S_FALSE or E_INVALIDARG
3087 *
3088 * NOTES
3089 * Creates missing reg keys and directories.
3090 * Mostly forwards to SHGetFolderPathW, but a few values of nFolder return
3091 * virtual folders that are handled here.
3092 */
3094 HWND hwndOwner,
3095 int nFolder,
3096 HANDLE hToken,
3098 LPITEMIDLIST *ppidl)
3099{
3101#ifdef __REACTOS__
3103#endif
3104
3105 TRACE("%p 0x%08x %p 0x%08x %p\n",
3106 hwndOwner, nFolder, hToken, dwReserved, ppidl);
3107
3108 if (!ppidl)
3109 return E_INVALIDARG;
3110 if (dwReserved)
3111 return E_INVALIDARG;
3112
3113#ifdef __REACTOS__
3114 if ((nFolder & CSIDL_FLAG_NO_ALIAS) &&
3116 {
3117 *ppidl = ILCreateFromPathW(szPath);
3118 if (*ppidl)
3119 return S_OK;
3120 }
3121#endif
3122 /* The virtual folders' locations are not user-dependent */
3123 *ppidl = NULL;
3124 switch (nFolder & CSIDL_FOLDER_MASK)
3125 {
3126 case CSIDL_DESKTOP:
3127 *ppidl = _ILCreateDesktop();
3128 break;
3129
3130 case CSIDL_PERSONAL:
3131 *ppidl = _ILCreateMyDocuments();
3132 break;
3133
3134 case CSIDL_INTERNET:
3135 *ppidl = _ILCreateIExplore();
3136 break;
3137
3138 case CSIDL_CONTROLS:
3139 *ppidl = _ILCreateControlPanel();
3140 break;
3141
3142 case CSIDL_PRINTERS:
3143 *ppidl = _ILCreatePrinters();
3144 break;
3145
3146 case CSIDL_BITBUCKET:
3147 *ppidl = _ILCreateBitBucket();
3148 break;
3149
3150 case CSIDL_DRIVES:
3151 *ppidl = _ILCreateMyComputer();
3152 break;
3153
3154 case CSIDL_NETWORK:
3155 *ppidl = _ILCreateNetwork();
3156 break;
3157
3158 default:
3159 {
3161
3162 hr = SHGetFolderPathW(hwndOwner, nFolder, hToken,
3164 if (SUCCEEDED(hr))
3165 {
3166 DWORD attributes=0;
3167
3168 TRACE("Value=%s\n", debugstr_w(szPath));
3169 hr = SHILCreateFromPathW(szPath, ppidl, &attributes);
3170 }
3172 {
3173 /* unlike SHGetFolderPath, SHGetFolderLocation in shell32
3174 * version 6.0 returns E_FAIL for nonexistent paths
3175 */
3176 hr = E_FAIL;
3177 }
3178 }
3179 }
3180 if(*ppidl)
3181 hr = S_OK;
3182
3183 TRACE("-- (new pidl %p)\n",*ppidl);
3184 return hr;
3185}
3186
3187/*************************************************************************
3188 * SHGetSpecialFolderLocation [SHELL32.@]
3189 *
3190 * NOTES
3191 * In NT5, SHGetSpecialFolderLocation needs the <winntdir>/Recent
3192 * directory.
3193 */
3195 HWND hwndOwner,
3196 INT nFolder,
3197 LPITEMIDLIST * ppidl)
3198{
3200
3201 TRACE("(%p,0x%x,%p)\n", hwndOwner,nFolder,ppidl);
3202
3203 if (!ppidl)
3204 return E_INVALIDARG;
3205
3206 hr = SHGetFolderLocation(hwndOwner, nFolder, NULL, 0, ppidl);
3207 return hr;
3208}
#define PRF_VERIFYEXISTS
Definition: PathResolve.cpp:38
#define PRF_TRYPROGRAMEXTENSIONS
Definition: PathResolve.cpp:40
#define PRF_REQUIREABSOLUTE
Definition: PathResolve.cpp:45
#define PRF_FIRSTDIRDEF
Definition: PathResolve.cpp:41
#define PRF_DONTFINDLNK
Definition: PathResolve.cpp:42
#define shell32_hInstance
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
#define ARRAY_SIZE(A)
Definition: main.h:33
#define IDS_PROGRAMS
Definition: resource.h:69
#define FIXME(fmt,...)
Definition: debug.h:111
#define ERR(fmt,...)
Definition: debug.h:110
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define IDS_PERSONAL
Definition: desktop.c:27
#define APIENTRY
Definition: api.h:79
#define IDI_SHELL_NETWORK_FOLDER
Definition: resource.h:5
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:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3362
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1969
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:4911
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4132
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1201
BOOL WINAPI GetUserNameW(LPWSTR lpszName, LPDWORD lpSize)
Definition: misc.c:291
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:411
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:294
BOOL WINAPI ConvertSidToStringSidW(PSID Sid, LPWSTR *StringSid)
Definition: security.c:3583
LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:468
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:756
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define HeapAlloc
Definition: compat.h:733
#define GetCurrentProcess()
Definition: compat.h:759
#define IsWow64Process
Definition: compat.h:760
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define wcsicmp
Definition: compat.h:15
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
static const WCHAR *const ext[]
Definition: module.c:53
#define IDS_FAVORITES
Definition: resource.h:35
static void cleanup(void)
Definition: main.c:1335
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
UINT WINAPI GetDriveTypeW(IN LPCWSTR lpRootPathName)
Definition: disk.c:497
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
BOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:794
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
DWORD WINAPI GetShortPathNameA(IN LPCSTR lpszLongPath, OUT LPSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1752
UINT WINAPI GetSystemWow64DirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2421
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2313
DWORD WINAPI GetShortPathNameW(IN LPCWSTR lpszLongPath, OUT LPWSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1833
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2352
BOOL WINAPI WritePrivateProfileStringW(LPCWSTR section, LPCWSTR entry, LPCWSTR string, LPCWSTR filename)
Definition: profile.c:1453
BOOL is_wow64
Definition: msi.c:54
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
#define RRF_RT_REG_SZ
Definition: driver.c:575
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:304
#define CSIDL_LINKS
Definition: shellpath.c:1065
static LPWSTR PathGetExtensionW(LPCWSTR lpszPath)
Definition: shellpath.c:438
#define CSIDL_APPDATA_LOCALLOW
Definition: shellpath.c:1066
VOID WINAPI PathQualifyAW(LPVOID pszPath)
Definition: shellpath.c:835
BOOL WINAPI PathIsRootAW(LPCVOID lpszPath)
Definition: shellpath.c:515
VOID WINAPI PathQualifyA(LPSTR pszPath)
Definition: shellpath.c:814
static const WCHAR Program_Files_Common_FilesW[]
Definition: shellpath.c:1033
static VOID WINAPI PathQualifyExW(_Inout_ LPWSTR pszPath, _Inout_opt_ LPCWSTR pszDir, _In_ DWORD dwFlags)
Definition: shellpath.c:158
static BOOL DoGetProductType(PNT_PRODUCT_TYPE ProductType)
Definition: shellpath.c:71
HRESULT SHELL_RegisterShellFolders(void)
Definition: shellpath.c:3033
static const WCHAR szKnownFolderRedirections[]
Definition: shellpath.c:1044
HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST *ppidl)
Definition: shellpath.c:3194
enum _CSIDL_Type CSIDL_Type
LPVOID WINAPI SHPathGetExtensionW(LPCWSTR lpszPath, DWORD void1, DWORD void2)
Definition: shellpath.c:449
BOOL WINAPI IsLFNDriveAW(LPCVOID lpszPath)
Definition: shellpath.c:645
static const WCHAR Start_Menu_Admin_ToolsW[]
Definition: shellpath.c:1035
static const WCHAR szSHUserFolders[]
Definition: shellpath.c:1041
#define CSIDL_DOWNLOADS
Definition: shellpath.c:1064
HRESULT WINAPI SHGetFolderLocation(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwReserved, LPITEMIDLIST *ppidl)
Definition: shellpath.c:3093
#define VALID_SHORT_PATH_CHAR_CLASSES
HRESULT WINAPI SHGetFolderPathW(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath)
Definition: shellpath.c:2558
static const WCHAR Local_Settings_HistoryW[]
Definition: shellpath.c:1028
static HRESULT _SHGetCurrentVersionPath(DWORD dwFlags, BYTE folder, LPWSTR pszPath)
Definition: shellpath.c:2102
static BOOL PathMakeUniqueNameW(LPWSTR lpszBuffer, DWORD dwBuffSize, LPCWSTR lpszShortName, LPCWSTR lpszLongName, LPCWSTR lpszPathName)
Definition: shellpath.c:674
static LPSTR PathGetExtensionA(LPCSTR lpszPath)
Definition: shellpath.c:427
static HRESULT _SHRegisterUserShellFolders(BOOL bDefault)
Definition: shellpath.c:2937
BOOL WINAPI PathAppendAW(LPVOID lpszPath1, LPCVOID lpszPath2)
Definition: shellpath.c:411
static HRESULT _SHExpandEnvironmentStrings(LPCWSTR szSrc, LPWSTR szDest)
Definition: shellpath.c:2406
static void PathGetShortPathA(LPSTR pszPath)
Definition: shellpath.c:471
static BOOL PathMakeUniqueNameA(LPSTR lpszBuffer, DWORD dwBuffSize, LPCSTR lpszShortName, LPCSTR lpszLongName, LPCSTR lpszPathName)
Definition: shellpath.c:658
BOOL WINAPI PathIsExeAW(LPCVOID path)
Definition: shellpath.c:561
BOOL WINAPI PathFileExistsAW(LPCVOID lpszPath)
Definition: shellpath.c:571
static const WCHAR Program_FilesW[]
Definition: shellpath.c:1032
static const BOOL is_win64
Definition: shellpath.c:59
#define CSIDL_SEARCHES
Definition: shellpath.c:1068
_CSIDL_Type
Definition: shellpath.c:1047
@ CSIDL_Type_CurrVer
Definition: shellpath.c:1053
@ CSIDL_Type_AllUsers
Definition: shellpath.c:1052
@ CSIDL_Type_WindowsPath
Definition: shellpath.c:1056
@ CSIDL_Type_Disallowed
Definition: shellpath.c:1054
@ CSIDL_Type_SystemX86Path
Definition: shellpath.c:1058
@ CSIDL_Type_SystemPath
Definition: shellpath.c:1057
@ CSIDL_Type_User
Definition: shellpath.c:1048
@ CSIDL_Type_NonExistent
Definition: shellpath.c:1055
HRESULT WINAPI SHGetFolderPathAndSubDirW(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPCWSTR pszSubPath, LPWSTR pszPath)
Definition: shellpath.c:2623
static HRESULT _SHOpenProfilesKey(PHKEY pKey)
Definition: shellpath.c:2341
#define CSIDL_SAVED_GAMES
Definition: shellpath.c:1067
static LONG PathProcessCommandW(LPCWSTR lpszPath, LPWSTR lpszBuff, DWORD dwBuffSize, DWORD dwFlags)
Definition: shellpath.c:993
static BOOL WINAPI PathMakeAbsoluteW(_Inout_ LPWSTR path)
Definition: shellpath.c:141
BOOL WINAPI IsLFNDriveW(LPCWSTR lpszPath)
Definition: shellpath.c:595
static HRESULT _SHGetAllUsersProfilePath(DWORD dwFlags, BYTE folder, LPWSTR pszPath)
Definition: shellpath.c:2301
HRESULT WINAPI SHGetFolderPathAndSubDirA(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPCSTR pszSubPath, LPSTR pszPath)
Definition: shellpath.c:2571
static HRESULT _SHGetDefaultValue(BYTE folder, LPWSTR pszPath)
Definition: shellpath.c:1986
static BOOL PathIsExeA(LPCSTR lpszPath)
Definition: shellpath.c:525
static const WCHAR Start_Menu_ProgramsW[]
Definition: shellpath.c:1034
static const WCHAR szSHFolders[]
Definition: shellpath.c:1040
BOOL APIENTRY IsRemovableDrive(DWORD iDrive)
Definition: shellpath.c:107
static HRESULT _SHGetProfilesValue(HKEY profilesKey, LPCWSTR szValueName, LPWSTR szValue, LPCWSTR szDefault)
Definition: shellpath.c:2356
static const CSIDL_DATA CSIDL_Data[]
Definition: shellpath.c:1080
static BOOL WINAPI PathSearchOnExtensionsW(_Inout_ LPWSTR pszPath, _In_opt_ LPCWSTR *ppszDirs, _In_ BOOL bDoSearch, _In_ DWORD dwWhich)
Definition: shellpath.c:120
static const WCHAR Local_Settings_Temporary_Internet_FilesW[]
Definition: shellpath.c:1029
static const WCHAR Start_Menu_StartupW[]
Definition: shellpath.c:1036
static const WCHAR szKnownFolderDescriptions[]
Definition: shellpath.c:1043
VOID WINAPI PathQualifyW(LPWSTR pszPath)
Definition: shellpath.c:826
BOOL WINAPI PathMakeUniqueNameAW(LPVOID lpszBuffer, DWORD dwBuffSize, LPCVOID lpszShortName, LPCVOID lpszLongName, LPCVOID lpszPathName)
Definition: shellpath.c:690
BOOL WINAPI PathResolveA(LPSTR path, LPCSTR *dirs, DWORD flags)
Definition: shellpath.c:843
BOOL _SHGetUserProfileDirectoryW(HANDLE hToken, LPWSTR szPath, LPDWORD lpcchPath)
Definition: shellpath.c:1950
LONG WINAPI PathProcessCommandAW(LPCVOID lpszPath, LPVOID lpszBuff, DWORD dwBuffSize, DWORD dwFlags)
Definition: shellpath.c:1009
VOID WINAPI PathGetShortPathAW(LPVOID pszPath)
Definition: shellpath.c:501
static const WCHAR MusicW[]
Definition: shellpath.c:1030
BOOL WINAPI PathResolveW(_Inout_ LPWSTR path, _Inout_opt_ LPCWSTR *dirs, _In_ DWORD flags)
Definition: shellpath.c:889
static HRESULT _SHRegisterCommonShellFolders(void)
Definition: shellpath.c:3005
static LPWSTR _GetUserSidStringFromToken(HANDLE Token)
Definition: shellpath.c:2171
BOOL WINAPI PathResolveAW(LPVOID path, LPCVOID *paths, DWORD flags)
Definition: shellpath.c:966
static const WCHAR PicturesW[]
Definition: shellpath.c:1031
static LONG PathProcessCommandA(LPCSTR lpszPath, LPSTR lpszBuff, DWORD dwBuffSize, DWORD dwFlags)
Definition: shellpath.c:977
static HRESULT _SHRegisterFolders(HKEY hRootKey, HANDLE hToken, LPCWSTR szUserShellFolderPath, LPCWSTR szShellFolderPath, const UINT folders[], UINT foldersLen)
Definition: shellpath.c:2835
int WINAPI PathCleanupSpec(LPCWSTR lpszPathW, LPWSTR lpszFileW)
Definition: shellpath.c:742
static HRESULT _SHGetUserProfilePath(HANDLE hToken, DWORD dwFlags, BYTE folder, LPWSTR pszPath)
Definition: shellpath.c:2212
static const WCHAR Application_DataW[]
Definition: shellpath.c:1026
BOOL WINAPI PathRemoveFileSpecAW(LPVOID lpszPath)
Definition: shellpath.c:457
BOOL WINAPI SHGetSpecialFolderPathA(HWND hwndOwner, LPSTR szPath, int nFolder, BOOL bCreate)
Definition: shellpath.c:3048
HRESULT WINAPI SHGetFolderPathA(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPSTR pszPath)
Definition: shellpath.c:2805
BOOL WINAPI PathYetAnotherMakeUniqueName(LPWSTR buffer, LPCWSTR path, LPCWSTR shortname, LPCWSTR longname)
Definition: shellpath.c:705
#define MSDOS_8DOT3_LEN
BOOL WINAPI SHGetSpecialFolderPathW(HWND hwndOwner, LPWSTR szPath, int nFolder, BOOL bCreate)
Definition: shellpath.c:3061
BOOL PathIsExeW(LPCWSTR lpszPath)
Definition: shellpath.c:543
static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, LPCWSTR userPrefix, LPCWSTR value, LPWSTR path)
Definition: shellpath.c:1867
static void PathGetShortPathW(LPWSTR pszPath)
Definition: shellpath.c:486
BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath)
Definition: shellpath.c:581
static const WCHAR Local_Settings_Application_DataW[]
Definition: shellpath.c:1027
static BOOL WINAPI PathIsAbsoluteW(_In_ LPCWSTR path)
Definition: shellpath.c:136
enum _NT_PRODUCT_TYPE NT_PRODUCT_TYPE
#define CSIDL_CONTACTS
Definition: shellpath.c:1063
enum _NT_PRODUCT_TYPE * PNT_PRODUCT_TYPE
_NT_PRODUCT_TYPE
Definition: shellpath.c:63
@ NtProductWinNt
Definition: shellpath.c:64
@ NtProductLanManNt
Definition: shellpath.c:65
@ NtProductServer
Definition: shellpath.c:66
VOID WINAPI FixSlashesAndColonW(LPWSTR lpwstr)
Definition: ordinal.c:4514
int WINAPI PathGetDriveNumberW(const WCHAR *path)
Definition: path.c:553
BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
Definition: path.c:629
BOOL WINAPI PathFindOnPathW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs)
Definition: path.c:1403
UINT WINAPI PathGetCharTypeA(UCHAR ch)
Definition: path.c:3026
BOOL WINAPI PathRemoveFileSpecA(LPSTR lpszPath)
Definition: path.c:586
BOOL WINAPI PathStripToRootW(LPWSTR lpszPath)
Definition: path.c:733
LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
Definition: path.c:447
void WINAPI PathRemoveExtensionW(LPWSTR lpszPath)
Definition: path.c:823
LPWSTR WINAPI PathBuildRootW(LPWSTR lpszPath, int drive)
Definition: path.c:348
BOOL WINAPI PathFileExistsA(LPCSTR lpszPath)
Definition: path.c:1755
BOOL WINAPI PathIsRootW(LPCWSTR lpszPath)
Definition: path.c:1642
BOOL WINAPI PathIsRootA(LPCSTR lpszPath)
Definition: path.c:1602
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c:1777
VOID WINAPI PathUnquoteSpacesW(LPWSTR lpszPath)
Definition: path.c:1034
BOOL WINAPI PathIsUNCW(LPCWSTR lpszPath)
Definition: path.c:2266
BOOL WINAPI PathFindOnPathExW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs, DWORD dwWhich)
Definition: path.c:1351
LPSTR WINAPI PathFindExtensionA(LPCSTR lpszPath)
Definition: path.c:422
BOOL WINAPI PathIsValidCharW(WCHAR c, DWORD class)
Definition: path.c:4419
UINT WINAPI PathGetCharTypeW(WCHAR ch)
Definition: path.c:3036
BOOL WINAPI PathIsFileSpecW(LPCWSTR lpszPath)
Definition: path.c:2133
BOOL WINAPI PathFileExistsAndAttributesW(LPCWSTR lpszPath, DWORD *dwAttr)
Definition: path.c:1832
BOOL WINAPI PathFileExistsDefExtW(LPWSTR lpszPath, DWORD dwWhich)
Definition: path.c:1117
LPWSTR WINAPI PathRemoveBackslashW(LPWSTR lpszPath)
Definition: path.c:867
BOOL WINAPI PathIsRelativeW(LPCWSTR lpszPath)
Definition: path.c:1579
DWORD WINAPI SHAnsiToUnicode(LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen)
Definition: string.c:2659
INT WINAPI SHUnicodeToAnsi(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT iLen)
Definition: string.c:2783
BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
Definition: url.c:2432
BOOL WINAPI GetAllUsersProfileDirectoryW(_Out_opt_ LPWSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1310
BOOL WINAPI GetDefaultUserProfileDirectoryW(_Out_opt_ LPWSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1443
BOOL WINAPI GetUserProfileDirectoryW(_In_ HANDLE hToken, _Out_opt_ LPWSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1792
static const WCHAR Cleanup[]
Definition: register.c:80
#define assert(x)
Definition: debug.h:53
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxRegKey * pKey
FxAutoRegKey hKey
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLuint buffer
Definition: glext.h:5915
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLfloat GLfloat p
Definition: glext.h:8902
GLuint64EXT * result
Definition: glext.h:11304
GLsizei const GLuint * paths
Definition: glext.h:11717
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
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
#define GUID_NULL
Definition: ks.h:106
#define REG_SZ
Definition: layer.c:22
int WINAPI lstrcmpiA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:42
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
TCHAR szTitle[MAX_LOADSTRING]
Definition: magnifier.c:35
#define error(str)
Definition: mkdosfs.c:1605
#define pch(ap)
Definition: match.c:418
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
LPCWSTR szPath
Definition: env.c:37
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
static const WCHAR path1[]
Definition: path.c:28
#define _Inout_
Definition: ms_sal.h:378
#define _Inout_opt_
Definition: ms_sal.h:379
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:95
unsigned int UINT
Definition: ndis.h:50
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_READ
Definition: nt_native.h:1023
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define UNICODE_NULL
#define L(x)
Definition: ntvdm.h:50
#define PathAppendA
Definition: pathcch.h:308
#define PathCombineW
Definition: pathcch.h:317
#define PathAddBackslashW
Definition: pathcch.h:301
#define PathAppendW
Definition: pathcch.h:309
#define LOWORD(l)
Definition: pedump.c:82
long LONG
Definition: pedump.c:60
LPITEMIDLIST _ILCreateMyComputer(void)
Definition: pidl.c:1628
LPITEMIDLIST _ILCreateIExplore(void)
Definition: pidl.c:1640
HRESULT WINAPI SHILCreateFromPathW(LPCWSTR path, LPITEMIDLIST *ppidl, DWORD *attributes)
Definition: pidl.c:392
LPITEMIDLIST _ILCreateDesktop(void)
Definition: pidl.c:1617
LPITEMIDLIST _ILCreateNetwork(void)
Definition: pidl.c:1684
LPITEMIDLIST _ILCreatePrinters(void)
Definition: pidl.c:1665
LPITEMIDLIST _ILCreateControlPanel(void)
Definition: pidl.c:1646
LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR path)
Definition: pidl.c:986
LPITEMIDLIST _ILCreateMyDocuments(void)
Definition: pidl.c:1634
LPITEMIDLIST _ILCreateBitBucket(void)
Definition: pidl.c:1690
#define INT
Definition: polytest.cpp:20
#define strncmpiW(s1, s2, n)
Definition: unicode.h:40
#define strcmpW(s1, s2)
Definition: unicode.h:38
#define strlenW(s)
Definition: unicode.h:28
#define strcatW(d, s)
Definition: unicode.h:30
#define sprintfW
Definition: unicode.h:58
#define strcpyW(d, s)
Definition: unicode.h:29
static __inline BOOL SHELL_OsIsUnicode(void)
Definition: shell32_main.h:140
static __inline LPWSTR __SHCloneStrAtoW(WCHAR **target, const char *source)
Definition: shell32_main.h:170
_In_ LPCSTR pszDir
Definition: shellapi.h:581
#define CSIDL_FLAG_CREATE
int WINAPI SHCreateDirectoryExW(HWND hWnd, LPCWSTR path, LPSECURITY_ATTRIBUTES sec)
Definition: shlfileop.cpp:905
HRESULT hr
Definition: shlfolder.c:183
#define CSIDL_COMMON_TEMPLATES
Definition: shlobj.h:2202
#define CSIDL_COMMON_DESKTOPDIRECTORY
Definition: shlobj.h:2182
#define CSIDL_TEMPLATES
Definition: shlobj.h:2178
#define CSIDL_PROGRAM_FILES
Definition: shlobj.h:2195
#define CSIDL_INTERNET_CACHE
Definition: shlobj.h:2189
_In_ int _In_ BOOL bCreate
Definition: shlobj.h:1511
#define CSIDL_DESKTOPDIRECTORY
Definition: shlobj.h:2173
#define CSIDL_SENDTO
Definition: shlobj.h:2167
#define CSIDL_RECENT
Definition: shlobj.h:2166
#define CSIDL_MYDOCUMENTS
Definition: shlobj.h:2170
#define CSIDL_ADMINTOOLS
Definition: shlobj.h:2205
#define CSIDL_COMMON_STARTMENU
Definition: shlobj.h:2179
@ SHGFP_TYPE_DEFAULT
Definition: shlobj.h:2135
@ SHGFP_TYPE_CURRENT
Definition: shlobj.h:2134
#define PCS_REPLACEDCHAR
Definition: shlobj.h:360
#define CSIDL_FONTS
Definition: shlobj.h:2177
#define CSIDL_PERSONAL
Definition: shlobj.h:2163
#define CSIDL_FAVORITES
Definition: shlobj.h:2164
#define CSIDL_FLAG_NO_ALIAS
Definition: shlobj.h:2218
#define CSIDL_COMMON_APPDATA
Definition: shlobj.h:2192
#define CSIDL_COMMON_PROGRAMS
Definition: shlobj.h:2180
#define PCS_PATHTOOLONG
Definition: shlobj.h:363
#define CSIDL_FLAG_DONT_VERIFY
Definition: shlobj.h:2219
#define CSIDL_MYPICTURES
Definition: shlobj.h:2196
#define CSIDL_COOKIES
Definition: shlobj.h:2190
#define CSIDL_COMMON_FAVORITES
Definition: shlobj.h:2188
#define CSIDL_PRINTERS
Definition: shlobj.h:2162
#define CSIDL_HISTORY
Definition: shlobj.h:2191
#define CSIDL_LOCAL_APPDATA
Definition: shlobj.h:2185
#define CSIDL_PROGRAM_FILES_COMMONX86
Definition: shlobj.h:2201
#define CSIDL_PROGRAM_FILES_COMMON
Definition: shlobj.h:2200
#define CSIDL_COMMON_MUSIC
Definition: shlobj.h:2207
#define PCS_FATAL
Definition: shlobj.h:359
#define CSIDL_COMMON_VIDEO
Definition: shlobj.h:2209
#define CSIDL_FOLDER_MASK
Definition: shlobj.h:2216
#define CSIDL_DESKTOP
Definition: shlobj.h:2158
#define CSIDL_NETWORK
Definition: shlobj.h:2175
#define CSIDL_STARTMENU
Definition: shlobj.h:2169
#define CSIDL_PROGRAM_FILESX86
Definition: shlobj.h:2199
#define CSIDL_COMMON_PICTURES
Definition: shlobj.h:2208
#define CSIDL_PROGRAMS
Definition: shlobj.h:2160
#define CSIDL_COMMON_STARTUP
Definition: shlobj.h:2181
#define CSIDL_APPDATA
Definition: shlobj.h:2183
#define CSIDL_PRINTHOOD
Definition: shlobj.h:2184
#define CSIDL_STARTUP
Definition: shlobj.h:2165
#define CSIDL_DRIVES
Definition: shlobj.h:2174
#define CSIDL_MYMUSIC
Definition: shlobj.h:2171
#define CSIDL_INTERNET
Definition: shlobj.h:2159
#define CSIDL_COMMON_DOCUMENTS
Definition: shlobj.h:2203
#define CSIDL_CONTROLS
Definition: shlobj.h:2161
#define CSIDL_BITBUCKET
Definition: shlobj.h:2168
#define CSIDL_NETHOOD
Definition: shlobj.h:2176
#define CSIDL_COMMON_ADMINTOOLS
Definition: shlobj.h:2204
#define CSIDL_MYVIDEO
Definition: shlobj.h:2172
_In_ int nFolder
Definition: shlobj.h:1510
#define GCT_SEPARATOR
Definition: shlwapi.h:779
#define GCT_INVALID
Definition: shlwapi.h:775
#define GCT_WILD
Definition: shlwapi.h:778
#define WHICH_DEFAULT
#define IDS_RECENT
Definition: shresdef.h:90
#define IDS_NETHOOD
Definition: shresdef.h:96
#define IDI_SHELL_MY_DOCUMENTS
Definition: shresdef.h:678
#define IDS_MYVIDEO
Definition: shresdef.h:94
#define IDI_SHELL_MY_MUSIC
Definition: shresdef.h:680
#define IDS_COOKIES
Definition: shresdef.h:102
#define IDI_SHELL_MY_PICTURES
Definition: shresdef.h:679
#define IDI_SHELL_TSKBAR_STARTMENU
Definition: shresdef.h:588
#define IDS_MYMUSIC
Definition: shresdef.h:93
#define IDI_SHELL_COMPUTER_FOLDER
Definition: shresdef.h:591
#define IDI_SHELL_DESKTOP
Definition: shresdef.h:583
#define IDI_SHELL_FAVORITES
Definition: shresdef.h:592
#define IDS_INTERNET_CACHE
Definition: shresdef.h:101
#define IDS_STARTUP
Definition: shresdef.h:89
#define IDS_COMMON_VIDEO
Definition: shresdef.h:111
#define IDI_SHELL_MY_MOVIES
Definition: shresdef.h:681
#define IDI_SHELL_PROGRAMS_FOLDER
Definition: shresdef.h:568
#define IDI_SHELL_RECENT_DOCUMENTS
Definition: shresdef.h:569
#define IDI_SHELL_NETWORK
Definition: shresdef.h:563
#define IDS_APPDATA
Definition: shresdef.h:98
#define IDI_SHELL_PRINTERS_FOLDER
Definition: shresdef.h:586
#define IDS_TEMPLATES
Definition: shresdef.h:97
#define IDS_COMMON_PICTURES
Definition: shresdef.h:110
#define IDS_PROGRAM_FILES_COMMON
Definition: shresdef.h:106
#define IDS_DESKTOPDIRECTORY
Definition: shresdef.h:95
#define IDS_PRINTHOOD
Definition: shresdef.h:99
#define IDS_SENDTO
Definition: shresdef.h:91
#define IDI_SHELL_NETWORK_CONNECTIONS
Definition: shresdef.h:637
#define IDI_SHELL_FONTS_FOLDER
Definition: shresdef.h:587
#define IDS_COMMON_MUSIC
Definition: shresdef.h:109
#define IDS_ADMINTOOLS
Definition: shresdef.h:108
#define IDS_MYPICTURES
Definition: shresdef.h:105
#define IDI_SHELL_CONTROL_PANEL
Definition: shresdef.h:570
#define IDS_STARTMENU
Definition: shresdef.h:92
#define IDS_PROGRAM_FILES
Definition: shresdef.h:104
#define IDS_HISTORY
Definition: shresdef.h:103
#define IDS_LOCAL_APPDATA
Definition: shresdef.h:100
#define IDI_SHELL_SYSTEM_GEAR
Definition: shresdef.h:717
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
#define _countof(array)
Definition: sndvol32.h:68
#define TRACE(s)
Definition: solgame.cpp:4
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:325
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
INT nShell32IconIndex
Definition: shellpath.c:1077
CSIDL_Type type
Definition: shellpath.c:1074
LPCWSTR szDefaultPath
Definition: shellpath.c:1076
LPCWSTR szValueName
Definition: shellpath.c:1075
const KNOWNFOLDERID * id
Definition: shellpath.c:1073
SID_AND_ATTRIBUTES User
Definition: setypes.h:1010
Definition: fci.c:127
Definition: fci.c:116
Definition: copy.c:22
unsigned char * LPBYTE
Definition: typedefs.h:53
PVOID HANDLE
Definition: typedefs.h:73
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t * LPDWORD
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
uint16_t * PWCHAR
Definition: typedefs.h:56
Definition: pdh_main.c:94
DWORD dwAttributes
Definition: vdmdbg.h:34
int ret
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define DRIVE_REMOVABLE
Definition: winbase.h:251
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
CONST void * LPCVOID
Definition: windef.h:191
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define E_NOT_SUFFICIENT_BUFFER
Definition: winerror.h:2345
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
#define ERROR_FILENAME_EXCED_RANGE
Definition: winerror.h:263
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define HKEY_USERS
Definition: winreg.h:13
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
LPWSTR WINAPI CharPrevW(_In_ LPCWSTR, _In_ LPCWSTR)
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
static const WCHAR userName[]
Definition: wnet.c:2154
struct _TOKEN_USER * PTOKEN_USER
#define TOKEN_QUERY
Definition: setypes.h:928
@ TokenUser
Definition: setypes.h:966
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193