ReactOS 0.4.16-dev-976-g18fc5a1
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 VALID_SHORT_PATH_CHAR_CLASSES ( \
227 PATH_CHAR_CLASS_DOT | \
228 PATH_CHAR_CLASS_BACKSLASH | \
229 PATH_CHAR_CLASS_COLON | \
230 PATH_CHAR_CLASS_OTHER_VALID \
231)
233 {
234 *pch = L'_';
235 }
236 }
237 }
238
239 StringCchCopyW(pszPath, MAX_PATH, szRoot);
240 cchPathLeft -= lstrlenW(pszPath) + 1;
241 }
242 else /* UNC path: Begins with double backslash */
243 {
244 bLFN = IsLFNDriveW(pchTemp);
245 if (bLFN)
246 {
247 pszPath[2] = UNICODE_NULL; /* Cut off */
248 cchPathLeft -= (2 + 1);
249 pchTemp += 2;
250 }
251 else
252 {
253 PWCHAR pchSlash = StrChrW(pszPath + 2, L'\\');
254 if (pchSlash)
255 pchSlash = StrChrW(pchSlash + 1, L'\\');
256
257 if (pchSlash)
258 {
259 *(pchSlash + 1) = UNICODE_NULL; /* Cut off */
260 pchTemp += pchSlash - pszPath;
261 cchPathLeft -= (INT)(SIZE_T)(pchSlash - pszPath) + 1;
262 }
263 else
264 {
265 bLFN = TRUE;
266 pszPath[2] = UNICODE_NULL; /* Cut off */
267 cchPathLeft -= 2;
268 pchTemp += 2;
269 }
270 }
271 }
272 /* Now pszPath is a root-like path or an empty string. */
273
274 /* Start appending the path components of szTemp to pszPath. */
275 while (*pchTemp && cchPathLeft > 0)
276 {
277 /* Collapse any .\ and ..\ parts in the path */
278 if (*pchTemp == L'.')
279 {
280 BOOL bDots = FALSE; /* '.' or '..' ? */
281
282 if (pchTemp[1] == UNICODE_NULL || pchTemp[1] == L'\\')
283 {
284 /* Component '.' */
285 bDots = TRUE;
286 }
287 else if (pchTemp[1] == L'.' && (pchTemp[2] == UNICODE_NULL || pchTemp[2] == L'\\'))
288 {
289 /* Component '..' */
290 PathRemoveFileSpecW(pszPath); /* Remove the last component from pszPath */
291 bDots = TRUE;
292 }
293
294 /* If a '.' or '..' was encountered, skip to the next component */
295 if (bDots)
296 {
297 while (*pchTemp && *pchTemp != L'\\')
298 {
299 ++pchTemp;
300 }
301
302 while (*pchTemp == L'\\')
303 {
304 ++pchTemp;
305 }
306
307 continue;
308 }
309 }
310
311 /* Otherwise, copy the other path component */
312
313 if (!PathAddBackslashW(pszPath)) /* Append a backslash at the end */
314 break;
315
316 --cchPathLeft;
317
318 pchPath = &pszPath[lstrlenW(pszPath)];
319
320 if (!bLFN) /* Not LFN? */
321 {
322 /* Copy MS-DOS 8.3 filename */
323 PWCHAR pchDot = NULL;
324 INT ich;
325 WCHAR szTitle[8 + 1] = L"";
326 INT cchTitle = 0;
327 WCHAR szDotExtension[1 + 3 + 1] = L"";
328 INT cchDotExtension = 0;
329
330 /* Copy the component to szTitle and szDotExtension... */
331 while (*pchTemp && *pchTemp != L'\\')
332 {
333 if (*pchTemp == L'.')
334 {
335 pchDot = pchTemp; /* Remember the last position */
336
337 /* Clear szDotExtension */
338 cchDotExtension = 0;
339 ZeroMemory(szDotExtension, sizeof(szDotExtension));
340 }
341
342 if (pchDot)
343 {
344 if (cchDotExtension < 1 + 3)
345 szDotExtension[cchDotExtension++] = *pchTemp;
346 }
347 else
348 {
349 if (cchTitle < 8)
350 szTitle[cchTitle++] = *pchTemp;
351 }
352
353 ++pchTemp;
354 }
355
356 /* Add file title 'szTitle' to pchPath */
357 for (ich = 0; szTitle[ich] && cchPathLeft > 0; ++ich)
358 {
359 *pchPath++ = szTitle[ich];
360 --cchPathLeft;
361 }
362
363 /* Add file extension 'szDotExtension' to pchPath */
364 if (pchDot)
365 {
366 for (ich = 0; szDotExtension[ich] && cchPathLeft > 0; ++ich)
367 {
368 *pchPath++ = szDotExtension[ich];
369 --cchPathLeft;
370 }
371 }
372 }
373 else /* LFN */
374 {
375 /* Copy the component up to the next separator */
376 while (*pchTemp != UNICODE_NULL && *pchTemp != L'\\' && cchPathLeft > 0)
377 {
378 *pchPath++ = *pchTemp++;
379 --cchPathLeft;
380 }
381 }
382
383 /* Skip the backslashes */
384 while (*pchTemp == L'\\')
385 {
386 ++pchTemp;
387 }
388
389 /* Keep null-terminated */
390 *pchPath = UNICODE_NULL;
391 }
392
393 /* Remove any trailing backslash */
394 PathRemoveBackslashW(pszPath);
395
396 if (!(dwFlags & 1)) /* Remove the trailing dot? */
397 {
398 pchPath = CharPrevW(pszPath, pszPath + lstrlenW(pszPath));
399 if (*pchPath == L'.')
400 *pchPath = UNICODE_NULL;
401 }
402}
403
404/*************************************************************************
405 * PathAppend [SHELL32.36]
406 */
408 LPVOID lpszPath1,
409 LPCVOID lpszPath2)
410{
411 if (SHELL_OsIsUnicode())
412 return PathAppendW(lpszPath1, lpszPath2);
413 return PathAppendA(lpszPath1, lpszPath2);
414}
415
416/*************************************************************************
417 * PathGetExtensionA [internal]
418 *
419 * NOTES
420 * exported by ordinal
421 * return value points to the first char after the dot
422 */
424{
425 TRACE("(%s)\n",lpszPath);
426
427 lpszPath = PathFindExtensionA(lpszPath);
428 return (LPSTR)(*lpszPath?(lpszPath+1):lpszPath);
429}
430
431/*************************************************************************
432 * PathGetExtensionW [internal]
433 */
435{
436 TRACE("(%s)\n",debugstr_w(lpszPath));
437
438 lpszPath = PathFindExtensionW(lpszPath);
439 return (LPWSTR)(*lpszPath?(lpszPath+1):lpszPath);
440}
441
442/*************************************************************************
443 * SHPathGetExtension [SHELL32.158]
444 */
446{
447 return PathGetExtensionW(lpszPath);
448}
449
450/*************************************************************************
451 * PathRemoveFileSpec [SHELL32.35]
452 */
454{
455 if (SHELL_OsIsUnicode())
456 return PathRemoveFileSpecW(lpszPath);
457 return PathRemoveFileSpecA(lpszPath);
458}
459
460/*
461 Path Manipulations
462*/
463
464/*************************************************************************
465 * PathGetShortPathA [internal]
466 */
467static void PathGetShortPathA(LPSTR pszPath)
468{
470
471 TRACE("%s\n", pszPath);
472
473 if (GetShortPathNameA(pszPath, path, MAX_PATH))
474 {
475 lstrcpyA(pszPath, path);
476 }
477}
478
479/*************************************************************************
480 * PathGetShortPathW [internal]
481 */
482static void PathGetShortPathW(LPWSTR pszPath)
483{
485
486 TRACE("%s\n", debugstr_w(pszPath));
487
488 if (GetShortPathNameW(pszPath, path, MAX_PATH))
489 {
490 lstrcpyW(pszPath, path);
491 }
492}
493
494/*************************************************************************
495 * PathGetShortPath [SHELL32.92]
496 */
498{
500 PathGetShortPathW(pszPath);
501 PathGetShortPathA(pszPath);
502}
503
504/*
505 ########## Path Testing ##########
506*/
507
508/*************************************************************************
509 * PathIsRoot [SHELL32.29]
510 */
512{
513 if (SHELL_OsIsUnicode())
514 return PathIsRootW(lpszPath);
515 return PathIsRootA(lpszPath);
516}
517
518/*************************************************************************
519 * PathIsExeA [internal]
520 */
521static BOOL PathIsExeA (LPCSTR lpszPath)
522{
523 LPCSTR lpszExtension = PathGetExtensionA(lpszPath);
524 int i;
525 static const char * const lpszExtensions[] =
526 {"exe", "com", "pif", "cmd", "bat", "scf", "scr", NULL };
527
528 TRACE("path=%s\n",lpszPath);
529
530 for(i=0; lpszExtensions[i]; i++)
531 if (!lstrcmpiA(lpszExtension,lpszExtensions[i])) return TRUE;
532
533 return FALSE;
534}
535
536/*************************************************************************
537 * PathIsExeW [internal]
538 */
540{
541 LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
542 int i;
543 static const WCHAR lpszExtensions[][4] =
544 {L"exe", L"com", L"pif", L"cmd", L"bat", L"scf", L"scr", L"" };
545
546 TRACE("path=%s\n",debugstr_w(lpszPath));
547
548 for(i=0; lpszExtensions[i][0]; i++)
549 if (!wcsicmp(lpszExtension,lpszExtensions[i])) return TRUE;
550
551 return FALSE;
552}
553
554/*************************************************************************
555 * PathIsExe [SHELL32.43]
556 */
558{
559 if (SHELL_OsIsUnicode())
560 return PathIsExeW (path);
561 return PathIsExeA(path);
562}
563
564/*************************************************************************
565 * PathFileExists [SHELL32.45]
566 */
568{
569 if (SHELL_OsIsUnicode())
570 return PathFileExistsW (lpszPath);
571 return PathFileExistsA (lpszPath);
572}
573
574/*************************************************************************
575 * IsLFNDriveA [SHELL32.41]
576 */
578{
579 WCHAR szBuffW[MAX_PATH], *pszW = NULL;
580 if (lpszPath)
581 {
582 SHAnsiToUnicode(lpszPath, szBuffW, _countof(szBuffW));
583 pszW = szBuffW;
584 }
585 return IsLFNDriveW(pszW);
586}
587
588/*************************************************************************
589 * IsLFNDriveW [SHELL32.42]
590 */
592{
593 DWORD cchMaxFileName, iDrive;
594 WCHAR szRoot[MAX_PATH];
595
596 if (lpszPath == NULL || lpszPath[0] == UNICODE_NULL)
597 {
598 szRoot[0] = 0;
599 GetWindowsDirectoryW(szRoot, _countof(szRoot));
600 lpszPath = szRoot;
601 }
602
603 if (PathIsUNCW(lpszPath))
604 {
605 StringCchCopyW(szRoot, _countof(szRoot), lpszPath);
606 PathStripToRootW(szRoot);
607
608 if (StrChrW(szRoot + 2, L'\\') == NULL)
609 return TRUE; /* LFN */
610
611 StringCchCatW(szRoot, _countof(szRoot), L"\\"); /* Add a backslash */
612 }
613 else
614 {
615 iDrive = ((lpszPath[0] - L'A') & 0x1F);
616 PathBuildRootW(szRoot, iDrive);
617
618 if (!IsRemovableDrive(iDrive))
619 {
620 /* FIXME: Cache correctly */
621 }
622 }
623
624#define MSDOS_8DOT3_LEN 12 /* MS-DOS 8.3 filename == length 12 */
625
626 /* GetVolumeInformation requires a root path */
627 if (!GetVolumeInformationW(szRoot, NULL, 0, NULL, &cchMaxFileName, NULL, NULL, 0))
628 {
629 /* Don't return FALSE when GetVolumeInformationW fails. */
630 return TRUE;
631 }
632
633 return cchMaxFileName > MSDOS_8DOT3_LEN;
634}
635
636/*************************************************************************
637 * IsLFNDrive [SHELL32.119]
638 */
640{
641 if (SHELL_OsIsUnicode())
642 return IsLFNDriveW(lpszPath);
643 return IsLFNDriveA(lpszPath);
644}
645
646/*
647 ########## Creating Something Unique ##########
648*/
649/*************************************************************************
650 * PathMakeUniqueNameA [internal]
651 */
653 LPSTR lpszBuffer,
654 DWORD dwBuffSize,
655 LPCSTR lpszShortName,
656 LPCSTR lpszLongName,
657 LPCSTR lpszPathName)
658{
659 FIXME("%p %u %s %s %s stub\n",
660 lpszBuffer, dwBuffSize, debugstr_a(lpszShortName),
661 debugstr_a(lpszLongName), debugstr_a(lpszPathName));
662 return TRUE;
663}
664
665/*************************************************************************
666 * PathMakeUniqueNameW [internal]
667 */
668#ifdef __REACTOS__
669/* https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-pathmakeuniquename */
671 _Out_ PWSTR pszUniqueName,
673 _In_ PCWSTR pszTemplate,
674 _In_opt_ PCWSTR pszLongPlate, /* Long template */
676{
677 TRACE("%p %u %s %s %s\n",
678 pszUniqueName, cchMax, debugstr_w(pszTemplate),
679 debugstr_w(pszLongPlate), debugstr_w(pszDir));
680
681 if (!cchMax || !pszUniqueName)
682 return FALSE;
683
684 pszUniqueName[0] = UNICODE_NULL;
685
686 PWSTR pszDest = pszUniqueName;
687 UINT dirLength = 0;
688 if (pszDir)
689 {
690 if (StringCchCopyW(pszUniqueName, cchMax - 1, pszDir) != S_OK)
691 return FALSE;
692
693 pszDest = PathAddBackslashW(pszUniqueName);
694 if (!pszDest)
695 return FALSE;
696
697 dirLength = lstrlenW(pszDir);
698 }
699
700 PCWSTR pszTitle = pszLongPlate ? pszLongPlate : pszTemplate;
701 PCWSTR pchDotExt, formatString = L"%d";
702 INT maxCount, cchTitle;
703
704 if ( !pszTitle
707 || pszDir
708#endif
709 )
710 {
711 if (!pszTemplate)
712 return FALSE;
713
714 pchDotExt = PathFindExtensionW(pszTemplate);
715
716 cchTitle = pchDotExt - pszTemplate;
717 if (cchTitle > 1)
718 {
719 PCWSTR pch = pchDotExt - 1;
720 while (cchTitle > 1 && (L'0' <= *pch && *pch <= L'9'))
721 {
722 --cchTitle;
723 --pch;
724 }
725 }
726
727#define MSDOS_8DOT3_FILENAME_TITLE_LEN 8
728 if (cchTitle > MSDOS_8DOT3_FILENAME_TITLE_LEN - 1)
729 cchTitle = MSDOS_8DOT3_FILENAME_TITLE_LEN - 1;
730
731 INT extLength = lstrlenW(pchDotExt);
732 while (cchTitle > 1 && (dirLength + cchTitle + extLength + 1 > (cchMax - 1)))
733 --cchTitle;
734
735 if (cchTitle <= 0)
736 maxCount = 1;
737 else if (cchTitle == 1)
738 maxCount = 10;
739 else
740 maxCount = 100;
741
742 pszTitle = pszTemplate;
743 }
744 else
745 {
746 PCWSTR openParen = StrChrW(pszTitle, L'(');
747 if (openParen)
748 {
749 while (openParen)
750 {
751 PCWSTR pch = openParen + 1;
752 while (*pch >= L'0' && *pch <= L'9')
753 ++pch;
754
755 if (*pch == L')')
756 break;
757
758 openParen = StrChrW(openParen + 1, L'(');
759 }
760
761 if (openParen)
762 {
763 pchDotExt = openParen + 1;
764 cchTitle = pchDotExt - pszTitle;
765 }
766 else
767 {
768 pchDotExt = PathFindExtensionW(pszTitle);
769 cchTitle = pchDotExt - pszTitle;
770 formatString = L" (%d)";
771 }
772 }
773 else
774 {
775 pchDotExt = PathFindExtensionW(pszTitle);
776 cchTitle = pchDotExt - pszTitle;
777 formatString = L" (%d)";
778 }
779
780 INT remainingChars = cchMax - (dirLength + cchTitle + (lstrlenW(formatString) - 2));
781 if (remainingChars <= 0)
782 maxCount = 1;
783 else if (remainingChars == 1)
784 maxCount = 10;
785 else if (remainingChars == 2)
786 maxCount = 100;
787 else
788 maxCount = 1000;
789 }
790
791 if (StringCchCopyNW(pszDest, cchMax - dirLength, pszTitle, cchTitle) != S_OK)
792 return FALSE;
793
794 PWSTR pchTitle = pszDest + cchTitle;
795 INT count;
796 for (count = 1; count < maxCount; ++count)
797 {
798 WCHAR tempName[MAX_PATH];
799 if (StringCchPrintfW(tempName, _countof(tempName), formatString, count) != S_OK ||
800 StringCchCatW(tempName, _countof(tempName), pchDotExt) != S_OK)
801 {
802 return FALSE;
803 }
804
805 if (StringCchCopyW(pchTitle, cchMax - (pchTitle - pszUniqueName), tempName) != S_OK)
806 return FALSE;
807
808 if (!PathFileExistsW(pszUniqueName))
809 return TRUE;
810 }
811
812 pszUniqueName[0] = UNICODE_NULL;
813 return FALSE;
814}
815#else
817 LPWSTR lpszBuffer,
818 DWORD dwBuffSize,
819 LPCWSTR lpszShortName,
820 LPCWSTR lpszLongName,
821 LPCWSTR lpszPathName)
822{
823 FIXME("%p %u %s %s %s stub\n",
824 lpszBuffer, dwBuffSize, debugstr_w(lpszShortName),
825 debugstr_w(lpszLongName), debugstr_w(lpszPathName));
826 return TRUE;
827}
828#endif
829
830/*************************************************************************
831 * PathMakeUniqueName [SHELL32.47]
832 */
834 LPVOID lpszBuffer,
835 DWORD dwBuffSize,
836 LPCVOID lpszShortName,
837 LPCVOID lpszLongName,
838 LPCVOID lpszPathName)
839{
840 if (SHELL_OsIsUnicode())
841 return PathMakeUniqueNameW(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
842 return PathMakeUniqueNameA(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
843}
844
845/*************************************************************************
846 * PathYetAnotherMakeUniqueName [SHELL32.75]
847 */
849{
850 WCHAR pathW[MAX_PATH], retW[MAX_PATH];
851 const WCHAR *file, *ext;
852 int i = 2;
853
854 TRACE("(%p, %s, %s, %s)\n", buffer, debugstr_w(path), debugstr_w(shortname), debugstr_w(longname));
855
856 file = longname ? longname : shortname;
857 PathCombineW(pathW, path, file);
858 strcpyW(retW, pathW);
860
862
863 /* now try to make it unique */
864 while (PathFileExistsW(retW))
865 {
866 sprintfW(retW, L"%s (%d)%s", pathW, i, ext);
867 i++;
868 }
869
870 strcpyW(buffer, retW);
871 TRACE("ret - %s\n", debugstr_w(buffer));
872
873 return TRUE;
874}
875
876/*
877 ########## cleaning and resolving paths ##########
878 */
879
880/*************************************************************************
881 * PathCleanupSpec [SHELL32.171]
882 *
883 * lpszFile is changed in place.
884 */
885int WINAPI PathCleanupSpec( LPCWSTR lpszPathW, LPWSTR lpszFileW )
886{
887 int i = 0;
888 DWORD rc = 0;
889 int length = 0;
890
891 if (SHELL_OsIsUnicode())
892 {
893 LPWSTR p = lpszFileW;
894
895 TRACE("Cleanup %s\n",debugstr_w(lpszFileW));
896
897 if (lpszPathW)
898 length = strlenW(lpszPathW);
899
900 while (*p)
901 {
902 int gct = PathGetCharTypeW(*p);
903 if (gct == GCT_INVALID || gct == GCT_WILD || gct == GCT_SEPARATOR)
904 {
905 lpszFileW[i]='-';
906 rc |= PCS_REPLACEDCHAR;
907 }
908 else
909 lpszFileW[i]=*p;
910 i++;
911 p++;
912 if (length + i == MAX_PATH)
913 {
915 break;
916 }
917 }
918 lpszFileW[i]=0;
919 }
920 else
921 {
922 LPSTR lpszFileA = (LPSTR)lpszFileW;
923 LPCSTR lpszPathA = (LPCSTR)lpszPathW;
924 LPSTR p = lpszFileA;
925
926 TRACE("Cleanup %s\n",debugstr_a(lpszFileA));
927
928 if (lpszPathA)
929 length = strlen(lpszPathA);
930
931 while (*p)
932 {
933 int gct = PathGetCharTypeA(*p);
934 if (gct == GCT_INVALID || gct == GCT_WILD || gct == GCT_SEPARATOR)
935 {
936 lpszFileA[i]='-';
937 rc |= PCS_REPLACEDCHAR;
938 }
939 else
940 lpszFileA[i]=*p;
941 i++;
942 p++;
943 if (length + i == MAX_PATH)
944 {
946 break;
947 }
948 }
949 lpszFileA[i]=0;
950 }
951 return rc;
952}
953
954/*************************************************************************
955 * PathQualifyA [SHELL32]
956 */
958{
960 TRACE("%s\n",pszPath);
964}
965
966/*************************************************************************
967 * PathQualifyW [SHELL32]
968 */
970{
971 TRACE("%s\n",debugstr_w(pszPath));
972 PathQualifyExW(pszPath, NULL, 0);
973}
974
975/*************************************************************************
976 * PathQualify [SHELL32.49]
977 */
979{
980 if (SHELL_OsIsUnicode())
981 PathQualifyW(pszPath);
982 else
983 PathQualifyA(pszPath);
984}
985
987{
988 BOOL ret = FALSE;
989 LPWSTR *dirsW = NULL;
990 DWORD iDir, cDirs, cbDirs;
991 WCHAR pathW[MAX_PATH];
992
993 TRACE("(%s,%p,0x%08x)\n", debugstr_a(path), dirs, flags);
994
995 if (dirs)
996 {
997 for (cDirs = 0; dirs[cDirs]; ++cDirs)
998 ;
999
1000 cbDirs = (cDirs + 1) * sizeof(LPWSTR);
1001 dirsW = SHAlloc(cbDirs);
1002 if (!dirsW)
1003 goto Cleanup;
1004
1005 ZeroMemory(dirsW, cbDirs);
1006 for (iDir = 0; iDir < cDirs; ++iDir)
1007 {
1008 __SHCloneStrAtoW(&dirsW[iDir], dirs[iDir]);
1009 if (dirsW[iDir] == NULL)
1010 goto Cleanup;
1011 }
1012 }
1013
1014 SHAnsiToUnicode(path, pathW, _countof(pathW));
1015
1016 ret = PathResolveW(pathW, (LPCWSTR*)dirsW, flags);
1017 if (ret)
1018 SHUnicodeToAnsi(pathW, path, MAX_PATH);
1019
1020Cleanup:
1021 if (dirsW)
1022 {
1023 for (iDir = 0; iDir < cDirs; ++iDir)
1024 {
1025 SHFree(dirsW[iDir]);
1026 }
1027 SHFree(dirsW);
1028 }
1029 return ret;
1030}
1031
1033{
1034 DWORD dwWhich = WHICH_DEFAULT; /* The extensions to be searched */
1035
1036 TRACE("(%s,%p,0x%08x)\n", debugstr_w(path), dirs, flags);
1037
1038 if (flags & PRF_DONTFINDLNK)
1039 dwWhich &= ~WHICH_LNK; /* Don't search '.LNK' (shortcut) */
1040
1041 if (flags & PRF_VERIFYEXISTS)
1042 SetLastError(ERROR_FILE_NOT_FOUND); /* We set this error code at first in verification */
1043
1045
1046 if (PathIsRootW(path)) /* Root path */
1047 {
1048 if (path[0] == L'\\' && path[1] == UNICODE_NULL) /* '\' only? */
1049 PathQualifyExW(path, ((flags & PRF_FIRSTDIRDEF) ? *dirs : NULL), 0); /* Qualify */
1050
1051 if (flags & PRF_VERIFYEXISTS)
1052 return PathFileExistsAndAttributesW(path, NULL); /* Check the existence */
1053
1054 return TRUE;
1055 }
1056
1057 if (PathIsFileSpecW(path)) /* Filename only */
1058 {
1059 /* Try to find the path with program extensions applied? */
1061 PathSearchOnExtensionsW(path, dirs, TRUE, dwWhich))
1062 {
1063 return TRUE; /* Found */
1064 }
1065
1066 /* Try to find the filename in the directories */
1067 if (PathFindOnPathW(path, dirs))
1068 goto CheckAbsoluteAndFinish;
1069
1070 return FALSE; /* Not found */
1071 }
1072
1073 if (PathIsURLW(path)) /* URL? */
1074 return FALSE;
1075
1076 /* Qualify the path */
1077 PathQualifyExW(path, ((flags & PRF_FIRSTDIRDEF) ? *dirs : NULL), 1);
1078
1079 TRACE("(%s)\n", debugstr_w(path));
1080
1081 if (!(flags & PRF_VERIFYEXISTS)) /* Don't verify the existence? */
1082 return TRUE;
1083
1084 /* Try to find the path with program extensions applied? */
1086 !PathSearchOnExtensionsW(path, dirs, FALSE, dwWhich))
1087 {
1089 return FALSE; /* Not found */
1090 }
1091
1092CheckAbsoluteAndFinish:
1093#if (_WIN32_WINNT >= _WIN32_WINNT_WS03)
1095 return TRUE;
1096
1097 if (!PathMakeAbsoluteW(path))
1098 return FALSE;
1099
1101#else
1102 return TRUE; /* Found */
1103#endif
1104}
1105
1106/*************************************************************************
1107 * PathResolve [SHELL32.51]
1108 */
1110{
1111 if (SHELL_OsIsUnicode())
1112 return PathResolveW(path, (LPCWSTR*)paths, flags);
1113 else
1114 return PathResolveA(path, (LPCSTR*)paths, flags);
1115}
1116
1117/*************************************************************************
1118* PathProcessCommandA
1119*/
1121 LPCSTR lpszPath,
1122 LPSTR lpszBuff,
1123 DWORD dwBuffSize,
1124 DWORD dwFlags)
1125{
1126 FIXME("%s %p 0x%04x 0x%04x stub\n",
1127 lpszPath, lpszBuff, dwBuffSize, dwFlags);
1128 if(!lpszPath) return -1;
1129 if(lpszBuff) strcpy(lpszBuff, lpszPath);
1130 return strlen(lpszPath);
1131}
1132
1133#ifndef __REACTOS__ // See ../shlexec.cpp
1134/*************************************************************************
1135* PathProcessCommandW
1136*/
1138 LPCWSTR lpszPath,
1139 LPWSTR lpszBuff,
1140 DWORD dwBuffSize,
1141 DWORD dwFlags)
1142{
1143 FIXME("(%s, %p, 0x%04x, 0x%04x) stub\n",
1144 debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags);
1145 if(!lpszPath) return -1;
1146 if(lpszBuff) strcpyW(lpszBuff, lpszPath);
1147 return strlenW(lpszPath);
1148}
1149#endif
1150
1151/*************************************************************************
1152* PathProcessCommand (SHELL32.653)
1153*/
1155 LPCVOID lpszPath,
1156 LPVOID lpszBuff,
1157 DWORD dwBuffSize,
1158 DWORD dwFlags)
1159{
1160 if (SHELL_OsIsUnicode())
1161 return PathProcessCommandW(lpszPath, lpszBuff, dwBuffSize, dwFlags);
1162 return PathProcessCommandA(lpszPath, lpszBuff, dwBuffSize, dwFlags);
1163}
1164
1165/*
1166 ########## special ##########
1167*/
1168
1169/* !! MISSING Win2k3-compatible paths from the list below; absent from Wine !! */
1170#ifndef __REACTOS__
1171static const WCHAR Application_DataW[] = L"Application Data";
1172static const WCHAR Local_Settings_Application_DataW[] = L"Local Settings\\Application Data";
1173static const WCHAR Local_Settings_HistoryW[] = L"Local Settings\\History";
1174static const WCHAR Local_Settings_Temporary_Internet_FilesW[] = L"Local Settings\\Temporary Internet Files";
1175static const WCHAR MusicW[] = L"Music";
1176static const WCHAR PicturesW[] = L"Pictures";
1177static const WCHAR Program_FilesW[] = L"Program Files";
1178static const WCHAR Program_Files_Common_FilesW[] = L"Program Files\\Common Files";
1179static const WCHAR Start_Menu_ProgramsW[] = L"Start Menu\\Programs";
1180static const WCHAR Start_Menu_Admin_ToolsW[] = L"Start Menu\\Programs\\Administrative Tools";
1181static const WCHAR Start_Menu_StartupW[] = L"Start Menu\\Programs\\StartUp";
1182#endif
1183
1184/* Long strings that are repeated many times: keep them here */
1185static const WCHAR szSHFolders[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
1186static const WCHAR szSHUserFolders[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
1187#ifndef __REACTOS__
1188static const WCHAR szKnownFolderDescriptions[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FolderDescriptions";
1189static const WCHAR szKnownFolderRedirections[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
1190#endif
1191
1192typedef enum _CSIDL_Type {
1194#ifdef __REACTOS__
1195 CSIDL_Type_InMyDocuments,
1196#endif
1205
1206/* Cannot use #if _WIN32_WINNT >= 0x0600 because _WIN32_WINNT == 0x0600 here. */
1207#ifndef __REACTOS__
1208#define CSIDL_CONTACTS 0x0043
1209#define CSIDL_DOWNLOADS 0x0047
1210#define CSIDL_LINKS 0x004d
1211#define CSIDL_APPDATA_LOCALLOW 0x004e
1212#define CSIDL_SAVED_GAMES 0x0062
1213#define CSIDL_SEARCHES 0x0063
1214#endif
1215
1216typedef struct
1217{
1221 LPCWSTR szDefaultPath; /* fallback string or resource ID */
1223} CSIDL_DATA;
1224
1225static const CSIDL_DATA CSIDL_Data[] =
1226{
1227 { /* 0x00 - CSIDL_DESKTOP */
1228 &FOLDERID_Desktop,
1230 L"Desktop",
1232#ifdef __REACTOS__
1233 0
1234#else
1236#endif
1237 },
1238 { /* 0x01 - CSIDL_INTERNET */
1239 &FOLDERID_InternetFolder,
1241 NULL,
1242 NULL
1243 },
1244 { /* 0x02 - CSIDL_PROGRAMS */
1245 &FOLDERID_Programs,
1247 L"Programs",
1249#ifdef __REACTOS__
1250 0
1251#else
1253#endif
1254 },
1255 { /* 0x03 - CSIDL_CONTROLS (.CPL files) */
1256 &FOLDERID_ControlPanelFolder,
1258 L"ControlPanelFolder",
1259 NULL,
1261 },
1262 { /* 0x04 - CSIDL_PRINTERS */
1263 &FOLDERID_PrintersFolder,
1265 L"PrintersFolder",
1266 NULL,
1268 },
1269 { /* 0x05 - CSIDL_PERSONAL */
1270 &FOLDERID_Documents,
1272 L"Personal",
1275 },
1276 { /* 0x06 - CSIDL_FAVORITES */
1277 &FOLDERID_Favorites,
1279 L"Favorites",
1282 },
1283 { /* 0x07 - CSIDL_STARTUP */
1284 &FOLDERID_Startup,
1286 L"StartUp",
1288 },
1289 { /* 0x08 - CSIDL_RECENT */
1290 &FOLDERID_Recent,
1292 L"Recent",
1295 },
1296 { /* 0x09 - CSIDL_SENDTO */
1297 &FOLDERID_SendTo,
1299 L"SendTo",
1301 },
1302 { /* 0x0a - CSIDL_BITBUCKET - Recycle Bin */
1303 &FOLDERID_RecycleBinFolder,
1305 L"RecycleBinFolder",
1306 NULL
1307 },
1308 { /* 0x0b - CSIDL_STARTMENU */
1309 &FOLDERID_StartMenu,
1311 L"Start Menu",
1314 },
1315 { /* 0x0c - CSIDL_MYDOCUMENTS */
1316 &GUID_NULL,
1317 CSIDL_Type_Disallowed, /* matches WinXP--can't get its path */
1318 NULL,
1319 NULL,
1321 },
1322 { /* 0x0d - CSIDL_MYMUSIC */
1323 &FOLDERID_Music,
1324#ifdef __REACTOS__
1325 CSIDL_Type_InMyDocuments,
1326#else
1328#endif
1329 L"My Music",
1332 },
1333 { /* 0x0e - CSIDL_MYVIDEO */
1334 &FOLDERID_Videos,
1335#ifdef __REACTOS__
1336 CSIDL_Type_InMyDocuments,
1337#else
1339#endif
1340 L"My Video",
1343 },
1344 { /* 0x0f - unassigned */
1345 &GUID_NULL,
1347 NULL,
1348 NULL,
1349 },
1350 { /* 0x10 - CSIDL_DESKTOPDIRECTORY */
1351 &FOLDERID_Desktop,
1353 L"Desktop",
1355#ifdef __REACTOS__
1356 0
1357#else
1359#endif
1360 },
1361 { /* 0x11 - CSIDL_DRIVES */
1362 &FOLDERID_ComputerFolder,
1364 L"MyComputerFolder",
1365 NULL,
1367 },
1368 { /* 0x12 - CSIDL_NETWORK */
1369 &FOLDERID_NetworkFolder,
1371 L"NetworkPlacesFolder",
1372 NULL,
1374 },
1375 { /* 0x13 - CSIDL_NETHOOD */
1376 &FOLDERID_NetHood,
1378 L"NetHood",
1381 },
1382 { /* 0x14 - CSIDL_FONTS */
1383 &FOLDERID_Fonts,
1385 L"Fonts",
1386 L"Fonts",
1388 },
1389 { /* 0x15 - CSIDL_TEMPLATES */
1390 &FOLDERID_Templates,
1392 L"Templates",
1394 },
1395 { /* 0x16 - CSIDL_COMMON_STARTMENU */
1396 &FOLDERID_CommonStartMenu,
1398 L"Common Start Menu",
1401 },
1402 { /* 0x17 - CSIDL_COMMON_PROGRAMS */
1403 &FOLDERID_CommonPrograms,
1405 L"Common Programs",
1407#ifdef __REACTOS__
1408 0
1409#else
1411#endif
1412 },
1413 { /* 0x18 - CSIDL_COMMON_STARTUP */
1414 &FOLDERID_CommonStartup,
1416 L"Common StartUp",
1418 },
1419 { /* 0x19 - CSIDL_COMMON_DESKTOPDIRECTORY */
1420 &FOLDERID_PublicDesktop,
1422 L"Common Desktop",
1424#ifdef __REACTOS__
1425 0
1426#else
1428#endif
1429 },
1430 { /* 0x1a - CSIDL_APPDATA */
1431 &FOLDERID_RoamingAppData,
1433 L"AppData",
1435 },
1436 { /* 0x1b - CSIDL_PRINTHOOD */
1437 &FOLDERID_PrintHood,
1439 L"PrintHood",
1442 },
1443 { /* 0x1c - CSIDL_LOCAL_APPDATA */
1444 &FOLDERID_LocalAppData,
1446 L"Local AppData",
1448 },
1449 { /* 0x1d - CSIDL_ALTSTARTUP */
1450 &GUID_NULL,
1452 NULL,
1453 NULL
1454 },
1455 { /* 0x1e - CSIDL_COMMON_ALTSTARTUP */
1456 &GUID_NULL,
1458 NULL,
1459 NULL
1460 },
1461 { /* 0x1f - CSIDL_COMMON_FAVORITES */
1462 &FOLDERID_Favorites,
1464 L"Common Favorites",
1467 },
1468 { /* 0x20 - CSIDL_INTERNET_CACHE */
1469 &FOLDERID_InternetCache,
1471 L"Cache",
1473 },
1474 { /* 0x21 - CSIDL_COOKIES */
1475 &FOLDERID_Cookies,
1477 L"Cookies",
1479 },
1480 { /* 0x22 - CSIDL_HISTORY */
1481 &FOLDERID_History,
1483 L"History",
1485 },
1486 { /* 0x23 - CSIDL_COMMON_APPDATA */
1487 &FOLDERID_ProgramData,
1489 L"Common AppData",
1491 },
1492 { /* 0x24 - CSIDL_WINDOWS */
1493 &FOLDERID_Windows,
1495 L"Windows",
1496 NULL,
1498 },
1499 { /* 0x25 - CSIDL_SYSTEM */
1500 &FOLDERID_System,
1502 L"System",
1503 NULL,
1505 },
1506 { /* 0x26 - CSIDL_PROGRAM_FILES */
1507 &FOLDERID_ProgramFiles,
1509 L"ProgramFiles",
1511#ifdef __REACTOS__
1512 0
1513#else
1515#endif
1516 },
1517 { /* 0x27 - CSIDL_MYPICTURES */
1518 &FOLDERID_Pictures,
1519#ifdef __REACTOS__
1520 CSIDL_Type_InMyDocuments,
1521#else
1523#endif
1524 L"My Pictures",
1527 },
1528 { /* 0x28 - CSIDL_PROFILE */
1529 &FOLDERID_Profile,
1531 NULL,
1532 NULL
1533 },
1534 { /* 0x29 - CSIDL_SYSTEMX86 */
1535 &FOLDERID_SystemX86,
1537 NULL,
1538 NULL,
1540 },
1541 { /* 0x2a - CSIDL_PROGRAM_FILESX86 */
1542 &FOLDERID_ProgramFilesX86,
1544 L"ProgramFilesX86",
1545 L"Program Files (x86)",
1547 },
1548 { /* 0x2b - CSIDL_PROGRAM_FILES_COMMON */
1549 &FOLDERID_ProgramFilesCommon,
1551 L"ProgramFilesCommon",
1554 },
1555 { /* 0x2c - CSIDL_PROGRAM_FILES_COMMONX86 */
1556 &FOLDERID_ProgramFilesCommonX86,
1558 L"ProgramFilesCommonX86",
1559 L"Program Files (x86)\\Common Files",
1561 },
1562 { /* 0x2d - CSIDL_COMMON_TEMPLATES */
1563 &FOLDERID_CommonTemplates,
1565 L"Common Templates",
1567 },
1568 { /* 0x2e - CSIDL_COMMON_DOCUMENTS */
1569 &FOLDERID_PublicDocuments,
1571 L"Common Documents",
1574 },
1575 { /* 0x2f - CSIDL_COMMON_ADMINTOOLS */
1576 &FOLDERID_CommonAdminTools,
1578 L"Common Administrative Tools",
1580 },
1581 { /* 0x30 - CSIDL_ADMINTOOLS */
1582 &FOLDERID_AdminTools,
1584 L"Administrative Tools",
1586 },
1587 { /* 0x31 - CSIDL_CONNECTIONS */
1588 &FOLDERID_ConnectionsFolder,
1590 L"ConnectionsFolder",
1591 NULL,
1593 },
1594 { /* 0x32 - unassigned */
1595 &GUID_NULL,
1597 NULL,
1598 NULL
1599 },
1600 { /* 0x33 - unassigned */
1601 &GUID_NULL,
1603 NULL,
1604 NULL
1605 },
1606 { /* 0x34 - unassigned */
1607 &GUID_NULL,
1609 NULL,
1610 NULL
1611 },
1612 { /* 0x35 - CSIDL_COMMON_MUSIC */
1613 &FOLDERID_PublicMusic,
1615 L"CommonMusic",
1618 },
1619 { /* 0x36 - CSIDL_COMMON_PICTURES */
1620 &FOLDERID_PublicPictures,
1622 L"CommonPictures",
1625 },
1626 { /* 0x37 - CSIDL_COMMON_VIDEO */
1627 &FOLDERID_PublicVideos,
1629 L"CommonVideo",
1632 },
1633 { /* 0x38 - CSIDL_RESOURCES */
1634 &FOLDERID_ResourceDir,
1636 NULL,
1637 L"Resources"
1638 },
1639 { /* 0x39 - CSIDL_RESOURCES_LOCALIZED */
1640 &FOLDERID_LocalizedResourcesDir,
1642 NULL,
1643 NULL
1644 },
1645 { /* 0x3a - CSIDL_COMMON_OEM_LINKS */
1646 &FOLDERID_CommonOEMLinks,
1648 NULL,
1649 L"OEM Links"
1650 },
1651 { /* 0x3b - CSIDL_CDBURN_AREA */
1652 &FOLDERID_CDBurning,
1654 L"CD Burning",
1655 L"Local Settings\\Application Data\\Microsoft\\CD Burning"
1656 },
1657 { /* 0x3c unassigned */
1658 &GUID_NULL,
1660 NULL,
1661 NULL
1662 },
1663 { /* 0x3d - CSIDL_COMPUTERSNEARME */
1664 &GUID_NULL,
1665 CSIDL_Type_Disallowed, /* FIXME */
1666 NULL,
1667 NULL
1668 },
1669 { /* 0x3e - CSIDL_PROFILES */
1670 &GUID_NULL,
1671 CSIDL_Type_Disallowed, /* oddly, this matches WinXP */
1672 NULL,
1673 NULL
1674 },
1675/* Cannot use #if _WIN32_WINNT >= 0x0600 because _WIN32_WINNT == 0x0600 here. */
1676#ifndef __REACTOS__
1677 { /* 0x3f */
1678 &FOLDERID_AddNewPrograms,
1680 NULL,
1681 NULL
1682 },
1683 { /* 0x40 */
1684 &FOLDERID_AppUpdates,
1686 NULL,
1687 NULL
1688 },
1689 { /* 0x41 */
1690 &FOLDERID_ChangeRemovePrograms,
1692 NULL,
1693 NULL
1694 },
1695 { /* 0x42 */
1696 &FOLDERID_ConflictFolder,
1698 NULL,
1699 NULL
1700 },
1701 { /* 0x43 - CSIDL_CONTACTS */
1702 &FOLDERID_Contacts,
1704 NULL,
1705 L"Contacts"
1706 },
1707 { /* 0x44 */
1708 &FOLDERID_DeviceMetadataStore,
1709 CSIDL_Type_Disallowed, /* FIXME */
1710 NULL,
1711 NULL
1712 },
1713 { /* 0x45 */
1714 &GUID_NULL,
1716 NULL,
1717 L"Documents"
1718 },
1719 { /* 0x46 */
1720 &FOLDERID_DocumentsLibrary,
1721 CSIDL_Type_Disallowed, /* FIXME */
1722 NULL,
1723 NULL
1724 },
1725 { /* 0x47 - CSIDL_DOWNLOADS */
1726 &FOLDERID_Downloads,
1727#ifdef __REACTOS__
1728 CSIDL_Type_InMyDocuments,
1729#else
1731#endif
1732 NULL,
1733 L"Downloads"
1734 },
1735 { /* 0x48 */
1736 &FOLDERID_Games,
1738 NULL,
1739 NULL
1740 },
1741 { /* 0x49 */
1742 &FOLDERID_GameTasks,
1743 CSIDL_Type_Disallowed, /* FIXME */
1744 NULL,
1745 NULL
1746 },
1747 { /* 0x4a */
1748 &FOLDERID_HomeGroup,
1750 NULL,
1751 NULL
1752 },
1753 { /* 0x4b */
1754 &FOLDERID_ImplicitAppShortcuts,
1755 CSIDL_Type_Disallowed, /* FIXME */
1756 NULL,
1757 NULL
1758 },
1759 { /* 0x4c */
1760 &FOLDERID_Libraries,
1761 CSIDL_Type_Disallowed, /* FIXME */
1762 NULL,
1763 NULL
1764 },
1765 { /* 0x4d - CSIDL_LINKS */
1766 &FOLDERID_Links,
1768 NULL,
1769 L"Links"
1770 },
1771 { /* 0x4e - CSIDL_APPDATA_LOCALLOW */
1772 &FOLDERID_LocalAppDataLow,
1774 NULL,
1775 L"AppData\\LocalLow"
1776 },
1777 { /* 0x4f */
1778 &FOLDERID_MusicLibrary,
1779 CSIDL_Type_Disallowed, /* FIXME */
1780 NULL,
1781 NULL
1782 },
1783 { /* 0x50 */
1784 &FOLDERID_OriginalImages,
1785 CSIDL_Type_Disallowed, /* FIXME */
1786 NULL,
1787 NULL
1788 },
1789 { /* 0x51 */
1790 &FOLDERID_PhotoAlbums,
1792 NULL,
1793 L"Pictures\\Slide Shows"
1794 },
1795 { /* 0x52 */
1796 &FOLDERID_PicturesLibrary,
1797 CSIDL_Type_Disallowed, /* FIXME */
1798 NULL,
1799 NULL
1800 },
1801 { /* 0x53 */
1802 &FOLDERID_Playlists,
1804 NULL,
1805 L"Music\\Playlists"
1806 },
1807 { /* 0x54 */
1808 &FOLDERID_ProgramFilesX64,
1810 NULL,
1811 NULL
1812 },
1813 { /* 0x55 */
1814 &FOLDERID_ProgramFilesCommonX64,
1816 NULL,
1817 NULL
1818 },
1819 { /* 0x56 */
1820 &FOLDERID_Public,
1821 CSIDL_Type_CurrVer, /* FIXME */
1822 NULL,
1823 L"Users\\Public"
1824 },
1825 { /* 0x57 */
1826 &FOLDERID_PublicDownloads,
1828 NULL,
1829 L"Downloads"
1830 },
1831 { /* 0x58 */
1832 &FOLDERID_PublicGameTasks,
1834 NULL,
1835 L"Microsoft\\Windows\\GameExplorer"
1836 },
1837 { /* 0x59 */
1838 &FOLDERID_PublicLibraries,
1840 NULL,
1841 L"Microsoft\\Windows\\Libraries"
1842 },
1843 { /* 0x5a */
1844 &FOLDERID_PublicRingtones,
1846 NULL,
1847 L"Microsoft\\Windows\\Ringtones"
1848 },
1849 { /* 0x5b */
1850 &FOLDERID_QuickLaunch,
1851 CSIDL_Type_Disallowed, /* FIXME */
1852 NULL,
1853 NULL
1854 },
1855 { /* 0x5c */
1856 &FOLDERID_RecordedTVLibrary,
1857 CSIDL_Type_Disallowed, /* FIXME */
1858 NULL,
1859 NULL
1860 },
1861 { /* 0x5d */
1862 &FOLDERID_Ringtones,
1863 CSIDL_Type_Disallowed, /* FIXME */
1864 NULL,
1865 NULL
1866 },
1867 { /* 0x5e */
1868 &FOLDERID_SampleMusic,
1870 NULL,
1871 L"Music\\Sample Music"
1872 },
1873 { /* 0x5f */
1874 &FOLDERID_SamplePictures,
1876 NULL,
1877 L"Pictures\\Sample Pictures"
1878 },
1879 { /* 0x60 */
1880 &FOLDERID_SamplePlaylists,
1882 NULL,
1883 L"Music\\Sample Playlists"
1884 },
1885 { /* 0x61 */
1886 &FOLDERID_SampleVideos,
1888 NULL,
1889 L"Videos\\Sample Videos"
1890 },
1891 { /* 0x62 - CSIDL_SAVED_GAMES */
1892 &FOLDERID_SavedGames,
1894 NULL,
1895 L"Saved Games"
1896 },
1897 { /* 0x63 - CSIDL_SEARCHES */
1898 &FOLDERID_SavedSearches,
1900 NULL,
1901 L"Searches"
1902 },
1903 { /* 0x64 */
1904 &FOLDERID_SEARCH_CSC,
1906 NULL,
1907 NULL
1908 },
1909 { /* 0x65 */
1910 &FOLDERID_SEARCH_MAPI,
1912 NULL,
1913 NULL
1914 },
1915 { /* 0x66 */
1916 &FOLDERID_SearchHome,
1918 NULL,
1919 NULL
1920 },
1921 { /* 0x67 */
1922 &FOLDERID_SidebarDefaultParts,
1923 CSIDL_Type_Disallowed, /* FIXME */
1924 NULL,
1925 NULL
1926 },
1927 { /* 0x68 */
1928 &FOLDERID_SidebarParts,
1929 CSIDL_Type_Disallowed, /* FIXME */
1930 NULL,
1931 NULL
1932 },
1933 { /* 0x69 */
1934 &FOLDERID_SyncManagerFolder,
1936 NULL,
1937 NULL
1938 },
1939 { /* 0x6a */
1940 &FOLDERID_SyncResultsFolder,
1942 NULL,
1943 NULL
1944 },
1945 { /* 0x6b */
1946 &FOLDERID_SyncSetupFolder,
1948 NULL,
1949 NULL
1950 },
1951 { /* 0x6c */
1952 &FOLDERID_UserPinned,
1953 CSIDL_Type_Disallowed, /* FIXME */
1954 NULL,
1955 NULL
1956 },
1957 { /* 0x6d */
1958 &FOLDERID_UserProfiles,
1960 L"Users",
1961 L"Users"
1962 },
1963 { /* 0x6e */
1964 &FOLDERID_UserProgramFiles,
1965 CSIDL_Type_Disallowed, /* FIXME */
1966 NULL,
1967 NULL
1968 },
1969 { /* 0x6f */
1970 &FOLDERID_UserProgramFilesCommon,
1971 CSIDL_Type_Disallowed, /* FIXME */
1972 NULL,
1973 NULL
1974 },
1975 { /* 0x70 */
1976 &FOLDERID_UsersFiles,
1978 NULL,
1979 NULL
1980 },
1981 { /* 0x71 */
1982 &FOLDERID_UsersLibraries,
1984 NULL,
1985 NULL
1986 },
1987 { /* 0x72 */
1988 &FOLDERID_VideosLibrary,
1989 CSIDL_Type_Disallowed, /* FIXME */
1990 NULL,
1991 NULL
1992 }
1993#endif
1994};
1995
1997{
1998 UINT csidl;
1999
2000 for (csidl = 0; csidl < _countof(CSIDL_Data); ++csidl)
2001 {
2002 const CSIDL_DATA *pData = &CSIDL_Data[csidl];
2003 if (pData->szValueName && lstrcmpiW(pszName, pData->szValueName) == 0)
2004 return csidl;
2005 }
2006
2007 return -1;
2008}
2009
2011{
2012 LPCWSTR pszPath, pchBackslash;
2014
2015 pchBackslash = StrChrW(pszStart, L'\\');
2016 if (pchBackslash)
2017 {
2018 *ppch = (LPWSTR)(pchBackslash + 1);
2019 *pcch = (pchBackslash - pszStart) + 1;
2020 StrCpyNW(szPath, pszStart, min(*pcch, _countof(szPath)));
2021 pszPath = szPath;
2022 }
2023 else
2024 {
2025 *ppch = NULL;
2026 *pcch = lstrlenW(pszStart);
2027 pszPath = pszStart;
2028 }
2029
2030 return SHGetSpecialFolderID(pszPath);
2031}
2032
2033#ifndef __REACTOS__
2035#else
2037#endif
2038
2039/* Gets the value named value from the registry key
2040 * rootKey\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
2041 * (or from rootKey\userPrefix\... if userPrefix is not NULL) into path, which
2042 * is assumed to be MAX_PATH WCHARs in length.
2043 * If it exists, expands the value and writes the expanded value to
2044 * rootKey\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
2045 * Returns successful error code if the value was retrieved from the registry,
2046 * and a failure otherwise.
2047 */
2048#ifndef __REACTOS__
2050#else
2051static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, HANDLE hToken, LPCWSTR userPrefix,
2052#endif
2054{
2055 HRESULT hr;
2056 WCHAR shellFolderPath[MAX_PATH], userShellFolderPath[MAX_PATH];
2057 LPCWSTR pShellFolderPath, pUserShellFolderPath;
2058 HKEY userShellFolderKey, shellFolderKey;
2059 DWORD dwType, dwPathLen;
2060
2061 TRACE("%p,%s,%s,%p\n",rootKey, debugstr_w(userPrefix), debugstr_w(value),
2062 path);
2063
2064 if (userPrefix)
2065 {
2066 strcpyW(shellFolderPath, userPrefix);
2067 PathAddBackslashW(shellFolderPath);
2068 strcatW(shellFolderPath, szSHFolders);
2069 pShellFolderPath = shellFolderPath;
2070 strcpyW(userShellFolderPath, userPrefix);
2071 PathAddBackslashW(userShellFolderPath);
2072 strcatW(userShellFolderPath, szSHUserFolders);
2073 pUserShellFolderPath = userShellFolderPath;
2074 }
2075 else
2076 {
2077 pUserShellFolderPath = szSHUserFolders;
2078 pShellFolderPath = szSHFolders;
2079 }
2080
2081 if (RegCreateKeyW(rootKey, pShellFolderPath, &shellFolderKey))
2082 {
2083 TRACE("Failed to create %s\n", debugstr_w(pShellFolderPath));
2084 return E_FAIL;
2085 }
2086 if (RegCreateKeyW(rootKey, pUserShellFolderPath, &userShellFolderKey))
2087 {
2088 TRACE("Failed to create %s\n",
2089 debugstr_w(pUserShellFolderPath));
2090 RegCloseKey(shellFolderKey);
2091 return E_FAIL;
2092 }
2093
2094 dwPathLen = MAX_PATH * sizeof(WCHAR);
2095 if (!RegQueryValueExW(userShellFolderKey, value, NULL, &dwType,
2096 (LPBYTE)path, &dwPathLen) && (dwType == REG_EXPAND_SZ || dwType == REG_SZ))
2097 {
2098 LONG ret;
2099
2100 path[dwPathLen / sizeof(WCHAR)] = '\0';
2101 if (dwType == REG_EXPAND_SZ && path[0] == '%')
2102 {
2103 WCHAR szTemp[MAX_PATH];
2104
2105#ifndef __REACTOS__
2107#else
2108 hr = _SHExpandEnvironmentStrings(hToken, path, szTemp, _countof(szTemp));
2109 if (FAILED(hr))
2110 goto end;
2111#endif
2112 lstrcpynW(path, szTemp, MAX_PATH);
2113 }
2114 ret = RegSetValueExW(shellFolderKey, value, 0, REG_SZ, (LPBYTE)path,
2115 (strlenW(path) + 1) * sizeof(WCHAR));
2116 if (ret != ERROR_SUCCESS)
2118 else
2119 hr = S_OK;
2120 }
2121 else
2122 hr = E_FAIL;
2123#ifdef __REACTOS__
2124end:
2125#endif
2126 RegCloseKey(shellFolderKey);
2127 RegCloseKey(userShellFolderKey);
2128 TRACE("returning 0x%08x\n", hr);
2129 return hr;
2130}
2131
2133{
2134 BOOL result;
2135 if (!hToken)
2136 {
2138 result = GetUserProfileDirectoryW(hToken, szPath, lpcchPath);
2139 CloseHandle(hToken);
2140 }
2141 else if ((INT) hToken == -1)
2142 {
2144 }
2145 else
2146 {
2147 result = GetUserProfileDirectoryW(hToken, szPath, lpcchPath);
2148 }
2149 TRACE("_SHGetUserProfileDirectoryW returning %S\n", szPath);
2150 return result;
2151}
2152
2153/* Gets a 'semi-expanded' default value of the CSIDL with index folder into
2154 * pszPath, based on the entries in CSIDL_Data. By semi-expanded, I mean:
2155 * - The entry's szDefaultPath may be either a string value or an integer
2156 * resource identifier. In the latter case, the string value of the resource
2157 * is written.
2158 * - Depending on the entry's type, the path may begin with an (unexpanded)
2159 * environment variable name. The caller is responsible for expanding
2160 * environment strings if so desired.
2161 * The types that are prepended with environment variables are:
2162 * CSIDL_Type_User: %USERPROFILE%
2163 * CSIDL_Type_AllUsers: %ALLUSERSPROFILE%
2164 * CSIDL_Type_CurrVer: %SystemDrive%
2165 * (Others might make sense too, but as yet are unneeded.)
2166 */
2167#ifndef __REACTOS__
2169#else
2170static HRESULT _SHGetDefaultValue(HANDLE hToken, BYTE folder, LPWSTR pszPath)
2171#endif
2172{
2173 HRESULT hr;
2174 WCHAR resourcePath[MAX_PATH];
2175#ifdef __REACTOS__
2176 NT_PRODUCT_TYPE ProductType;
2177#endif
2178
2179 TRACE("0x%02x,%p\n", folder, pszPath);
2180
2182 return E_INVALIDARG;
2183
2184 if (!pszPath)
2185 return E_INVALIDARG;
2186
2187#ifdef __REACTOS__
2188 if (hToken != NULL && hToken != (HANDLE)-1)
2189 {
2190 FIXME("unsupported for user other than current or default\n");
2191 }
2192#endif
2193
2194 if (!is_win64)
2195 {
2196 BOOL is_wow64;
2197
2198 switch (folder)
2199 {
2204 break;
2209 break;
2210 }
2211 }
2212
2213 switch (CSIDL_Data[folder].type)
2214 {
2215 case CSIDL_Type_User:
2216 strcpyW(pszPath, L"%USERPROFILE%");
2217 break;
2218#ifdef __REACTOS__
2219 case CSIDL_Type_InMyDocuments:
2220 strcpyW(pszPath, L"%USERPROFILE%");
2221 if (DoGetProductType(&ProductType) && ProductType == NtProductWinNt)
2222 {
2223 if (IS_INTRESOURCE(CSIDL_Data[CSIDL_MYDOCUMENTS].szDefaultPath))
2224 {
2225 WCHAR szItem[MAX_PATH];
2227 LOWORD(CSIDL_Data[CSIDL_MYDOCUMENTS].szDefaultPath),
2228 szItem, ARRAY_SIZE(szItem));
2229 PathAppendW(pszPath, szItem);
2230 }
2231 else
2232 {
2233 PathAppendW(pszPath, CSIDL_Data[CSIDL_MYDOCUMENTS].szDefaultPath);
2234 }
2235 }
2236 break;
2237#endif
2239#ifndef __REACTOS__
2240 strcpyW(pszPath, L"%PUBLIC%");
2241#else
2242 strcpyW(pszPath, L"%ALLUSERSPROFILE%");
2243#endif
2244 break;
2245 case CSIDL_Type_CurrVer:
2246 strcpyW(pszPath, L"%SystemDrive%");
2247 break;
2248 default:
2249 ; /* no corresponding env. var, do nothing */
2250 }
2251
2252 hr = S_OK;
2253 if (CSIDL_Data[folder].szDefaultPath)
2254 {
2255 if (IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath))
2256 {
2258 LOWORD(CSIDL_Data[folder].szDefaultPath), resourcePath, MAX_PATH))
2259 {
2260 PathAppendW(pszPath, resourcePath);
2261 }
2262 else
2263 {
2264 ERR("(%d,%s), LoadString failed, missing translation?\n", folder,
2265 debugstr_w(pszPath));
2266 hr = E_FAIL;
2267 }
2268 }
2269 else
2270 {
2271 PathAppendW(pszPath, CSIDL_Data[folder].szDefaultPath);
2272 }
2273 }
2274 TRACE("returning 0x%08x\n", hr);
2275 return hr;
2276}
2277
2278/* Gets the (unexpanded) value of the folder with index folder into pszPath.
2279 * The folder's type is assumed to be CSIDL_Type_CurrVer. Its default value
2280 * can be overridden in the HKLM\\Software\\Microsoft\\Windows\\CurrentVersion key.
2281 * If dwFlags has SHGFP_TYPE_DEFAULT set or if the value isn't overridden in
2282 * the registry, uses _SHGetDefaultValue to get the value.
2283 */
2285 LPWSTR pszPath)
2286{
2287 HRESULT hr;
2288
2289 TRACE("0x%08x,0x%02x,%p\n", dwFlags, folder, pszPath);
2290
2292 return E_INVALIDARG;
2294 return E_INVALIDARG;
2295 if (!pszPath)
2296 return E_INVALIDARG;
2297
2299#ifndef __REACTOS__
2300 hr = _SHGetDefaultValue(folder, pszPath);
2301#else
2302 hr = _SHGetDefaultValue(NULL, folder, pszPath);
2303#endif
2304 else
2305 {
2306 HKEY hKey;
2307
2308 if (RegCreateKeyW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion", &hKey))
2309 hr = E_FAIL;
2310 else
2311 {
2312 DWORD dwType, dwPathLen = MAX_PATH * sizeof(WCHAR);
2313
2314 if (RegQueryValueExW(hKey, CSIDL_Data[folder].szValueName, NULL,
2315 &dwType, (LPBYTE)pszPath, &dwPathLen) ||
2316 (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
2317 {
2318#ifndef __REACTOS__
2319 hr = _SHGetDefaultValue(folder, pszPath);
2320#else
2321 hr = _SHGetDefaultValue(NULL, folder, pszPath);
2322#endif
2323 dwType = REG_EXPAND_SZ;
2324 switch (folder)
2325 {
2328 /* these two should never be set on 32-bit setups */
2329 if (!is_win64)
2330 {
2331 BOOL is_wow64;
2333 if (!is_wow64) break;
2334 }
2335 /* fall through */
2336 default:
2337 RegSetValueExW(hKey, CSIDL_Data[folder].szValueName, 0, dwType,
2338 (LPBYTE)pszPath, (strlenW(pszPath)+1)*sizeof(WCHAR));
2339 }
2340 }
2341 else
2342 {
2343 pszPath[dwPathLen / sizeof(WCHAR)] = '\0';
2344 hr = S_OK;
2345 }
2347 }
2348 }
2349 TRACE("returning 0x%08x (output path is %s)\n", hr, debugstr_w(pszPath));
2350 return hr;
2351}
2352
2354{
2355 char InfoBuffer[64];
2356 PTOKEN_USER UserInfo;
2357 DWORD InfoSize;
2358 LPWSTR SidStr;
2359
2360 UserInfo = (PTOKEN_USER) InfoBuffer;
2361 if (! GetTokenInformation(Token, TokenUser, InfoBuffer, sizeof(InfoBuffer),
2362 &InfoSize))
2363 {
2365 return NULL;
2366 UserInfo = HeapAlloc(GetProcessHeap(), 0, InfoSize);
2367 if (UserInfo == NULL)
2368 return NULL;
2369 if (! GetTokenInformation(Token, TokenUser, UserInfo, InfoSize,
2370 &InfoSize))
2371 {
2372 HeapFree(GetProcessHeap(), 0, UserInfo);
2373 return NULL;
2374 }
2375 }
2376
2377 if (! ConvertSidToStringSidW(UserInfo->User.Sid, &SidStr))
2378 SidStr = NULL;
2379
2380 if (UserInfo != (PTOKEN_USER) InfoBuffer)
2381 HeapFree(GetProcessHeap(), 0, UserInfo);
2382
2383 return SidStr;
2384}
2385
2386/* Gets the user's path (unexpanded) for the CSIDL with index folder:
2387 * If SHGFP_TYPE_DEFAULT is set, calls _SHGetDefaultValue for it. Otherwise
2388 * calls _SHGetUserShellFolderPath for it. Where it looks depends on hToken:
2389 * - if hToken is -1, looks in HKEY_USERS\.Default
2390 * - otherwise looks first in HKEY_CURRENT_USER, followed by HKEY_LOCAL_MACHINE
2391 * if HKEY_CURRENT_USER doesn't contain any entries. If both fail, finally
2392 * calls _SHGetDefaultValue for it.
2393 */
2395 LPWSTR pszPath)
2396{
2397 const WCHAR *szValueName;
2398 WCHAR buffer[40];
2399 HRESULT hr;
2400
2401 TRACE("%p,0x%08x,0x%02x,%p\n", hToken, dwFlags, folder, pszPath);
2402
2404 return E_INVALIDARG;
2405#ifdef __REACTOS__
2407 CSIDL_Data[folder].type != CSIDL_Type_InMyDocuments)
2408#else
2410#endif
2411 {
2412 return E_INVALIDARG;
2413 }
2414 if (!pszPath)
2415 return E_INVALIDARG;
2416
2418 {
2419#ifndef __REACTOS__
2420 hr = _SHGetDefaultValue(folder, pszPath);
2421#else
2422 hr = _SHGetDefaultValue(hToken, folder, pszPath);
2423#endif
2424 }
2425 else
2426 {
2427 static const WCHAR DefaultW[] = L".Default";
2428 LPCWSTR userPrefix = NULL;
2429 HKEY hRootKey;
2430
2431 if (hToken == (HANDLE)-1)
2432 {
2433 hRootKey = HKEY_USERS;
2434 userPrefix = DefaultW;
2435 }
2436 else if (hToken == NULL)
2437 hRootKey = HKEY_CURRENT_USER;
2438 else
2439 {
2440 hRootKey = HKEY_USERS;
2441 userPrefix = _GetUserSidStringFromToken(hToken);
2442 if (userPrefix == NULL)
2443 {
2444 hr = E_FAIL;
2445 goto error;
2446 }
2447 }
2448
2449 /* For CSIDL_Type_User we also use the GUID if no szValueName is provided */
2450 szValueName = CSIDL_Data[folder].szValueName;
2451 if (!szValueName)
2452 {
2454 szValueName = &buffer[0];
2455 }
2456
2457#ifndef __REACTOS__
2458 hr = _SHGetUserShellFolderPath(hRootKey, userPrefix, szValueName, pszPath);
2459 if (FAILED(hr) && hRootKey != HKEY_LOCAL_MACHINE)
2460 hr = _SHGetUserShellFolderPath(HKEY_LOCAL_MACHINE, NULL, szValueName, pszPath);
2461 if (FAILED(hr))
2462 hr = _SHGetDefaultValue(folder, pszPath);
2463#else
2464 hr = _SHGetUserShellFolderPath(hRootKey, hToken, userPrefix, szValueName, pszPath);
2465 if (FAILED(hr) && hRootKey != HKEY_LOCAL_MACHINE)
2466 hr = _SHGetUserShellFolderPath(HKEY_LOCAL_MACHINE, hToken, NULL, szValueName, pszPath);
2467 if (FAILED(hr))
2468 hr = _SHGetDefaultValue(hToken, folder, pszPath);
2469#endif
2470 if (userPrefix != NULL && userPrefix != DefaultW)
2471 LocalFree((HLOCAL) userPrefix);
2472 }
2473error:
2474 TRACE("returning 0x%08x (output path is %s)\n", hr, debugstr_w(pszPath));
2475 return hr;
2476}
2477
2478/* Gets the (unexpanded) path for the CSIDL with index folder. If dwFlags has
2479 * SHGFP_TYPE_DEFAULT set, calls _SHGetDefaultValue. Otherwise calls
2480 * _SHGetUserShellFolderPath for it, looking only in HKEY_LOCAL_MACHINE.
2481 * If this fails, falls back to _SHGetDefaultValue.
2482 */
2484 LPWSTR pszPath)
2485{
2486 HRESULT hr;
2487
2488 TRACE("0x%08x,0x%02x,%p\n", dwFlags, folder, pszPath);
2489
2491 return E_INVALIDARG;
2493 return E_INVALIDARG;
2494 if (!pszPath)
2495 return E_INVALIDARG;
2496
2498#ifndef __REACTOS__
2499 hr = _SHGetDefaultValue(folder, pszPath);
2500#else
2501 hr = _SHGetDefaultValue(NULL, folder, pszPath);
2502#endif
2503 else
2504 {
2505#ifndef __REACTOS__
2507#else
2509#endif
2510 CSIDL_Data[folder].szValueName, pszPath);
2511 if (FAILED(hr))
2512#ifndef __REACTOS__
2513 hr = _SHGetDefaultValue(folder, pszPath);
2514#else
2515 hr = _SHGetDefaultValue(NULL, folder, pszPath);
2516#endif
2517 }
2518 TRACE("returning 0x%08x (output path is %s)\n", hr, debugstr_w(pszPath));
2519 return hr;
2520}
2521
2522#ifndef __REACTOS__
2524{
2525 LONG lRet;
2526 DWORD disp;
2527
2528 lRet = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList", 0, NULL, 0,
2529 KEY_ALL_ACCESS, NULL, pKey, &disp);
2530 return HRESULT_FROM_WIN32(lRet);
2531}
2532
2533/* Reads the value named szValueName from the key profilesKey (assumed to be
2534 * opened by _SHOpenProfilesKey) into szValue, which is assumed to be MAX_PATH
2535 * WCHARs in length. If it doesn't exist, returns szDefault (and saves
2536 * szDefault to the registry).
2537 */
2538static HRESULT _SHGetProfilesValue(HKEY profilesKey, LPCWSTR szValueName,
2539 LPWSTR szValue, LPCWSTR szDefault)
2540{
2541 HRESULT hr;
2542 DWORD type, dwPathLen = MAX_PATH * sizeof(WCHAR);
2543 LONG lRet;
2544
2545 TRACE("%p,%s,%p,%s\n", profilesKey, debugstr_w(szValueName), szValue,
2546 debugstr_w(szDefault));
2547 lRet = RegQueryValueExW(profilesKey, szValueName, NULL, &type,
2548 (LPBYTE)szValue, &dwPathLen);
2549 if (!lRet && (type == REG_SZ || type == REG_EXPAND_SZ) && dwPathLen
2550 && *szValue)
2551 {
2552 dwPathLen /= sizeof(WCHAR);
2553 szValue[dwPathLen] = '\0';
2554 hr = S_OK;
2555 }
2556 else
2557 {
2558 /* Missing or invalid value, set a default */
2559 lstrcpynW(szValue, szDefault, MAX_PATH);
2560 TRACE("Setting missing value %s to %s\n", debugstr_w(szValueName),
2561 debugstr_w(szValue));
2562 lRet = RegSetValueExW(profilesKey, szValueName, 0, REG_EXPAND_SZ,
2563 (LPBYTE)szValue,
2564 (strlenW(szValue) + 1) * sizeof(WCHAR));
2565 if (lRet)
2566 hr = HRESULT_FROM_WIN32(lRet);
2567 else
2568 hr = S_OK;
2569 }
2570 TRACE("returning 0x%08x (output value is %s)\n", hr, debugstr_w(szValue));
2571 return hr;
2572}
2573#endif
2574
2575/* Attempts to expand environment variables from szSrc into szDest, which is
2576 * assumed to be MAX_PATH characters in length. Before referring to the
2577 * environment, handles a few variables directly, because the environment
2578 * variables may not be set when this is called (as during Wine's installation
2579 * when default values are being written to the registry).
2580 * The directly handled environment variables, and their source, are:
2581 * - ALLUSERSPROFILE, USERPROFILE: reads from the registry
2582 * - SystemDrive: uses GetSystemDirectoryW and uses the drive portion of its
2583 * path
2584 * If one of the directly handled environment variables is expanded, only
2585 * expands a single variable, and only in the beginning of szSrc.
2586 */
2587#ifndef __REACTOS__
2589#else
2591#endif
2592{
2593 HRESULT hr;
2594#ifndef __REACTOS__
2595 WCHAR szTemp[MAX_PATH], szProfilesPrefix[MAX_PATH] = { 0 };
2596 HKEY key = NULL;
2597#else
2598 WCHAR szTemp[MAX_PATH];
2599#endif
2600
2601 TRACE("%s, %p\n", debugstr_w(szSrc), szDest);
2602
2603 if (!szSrc || !szDest) return E_INVALIDARG;
2604
2605 /* short-circuit if there's nothing to expand */
2606 if (szSrc[0] != '%')
2607 {
2608 strcpyW(szDest, szSrc);
2609 hr = S_OK;
2610 goto end;
2611 }
2612#ifndef __REACTOS__
2613 /* Get the profile prefix, we'll probably be needing it */
2615 if (SUCCEEDED(hr))
2616 {
2617 WCHAR def_val[MAX_PATH];
2618
2619 /* get the system drive */
2620 GetSystemDirectoryW(def_val, MAX_PATH);
2621 strcpyW( def_val + 3, L"Users" );
2622
2623 hr = _SHGetProfilesValue(key, L"ProfilesDirectory", szProfilesPrefix, def_val );
2624 }
2625#else
2626 hr = S_OK;
2627#endif
2628
2629 *szDest = 0;
2630 strcpyW(szTemp, szSrc);
2631 while (SUCCEEDED(hr) && szTemp[0] == '%')
2632 {
2633 if (!strncmpiW(szTemp, L"%ALLUSERSPROFILE%", ARRAY_SIZE(L"%ALLUSERSPROFILE%")-1))
2634 {
2635#ifndef __REACTOS__
2636 WCHAR szAllUsers[MAX_PATH];
2637
2638 strcpyW(szDest, szProfilesPrefix);
2639 hr = _SHGetProfilesValue(key, L"AllUsersProfile", szAllUsers, L"Public");
2640 PathAppendW(szDest, szAllUsers);
2641#else
2642 DWORD cchSize = cchDest;
2643 if (!GetAllUsersProfileDirectoryW(szDest, &cchSize))
2644 goto fallback_expand;
2645#endif
2646 PathAppendW(szDest, szTemp + ARRAY_SIZE(L"%ALLUSERSPROFILE%")-1);
2647 }
2648#ifndef __REACTOS__
2649 else if (!strncmpiW(szTemp, L"%PUBLIC%", ARRAY_SIZE(L"%PUBLIC%")-1))
2650 {
2651 WCHAR szAllUsers[MAX_PATH], def_val[MAX_PATH];
2652
2653 GetSystemDirectoryW(def_val, MAX_PATH);
2654 strcpyW( def_val + 3, L"Users\\Public" );
2655
2656 hr = _SHGetProfilesValue(key, L"Public", szAllUsers, def_val);
2657 PathAppendW(szDest, szAllUsers);
2658 PathAppendW(szDest, szTemp + ARRAY_SIZE(L"%PUBLIC%")-1);
2659 }
2660#endif
2661 else if (!strncmpiW(szTemp, L"%USERPROFILE%", ARRAY_SIZE(L"%USERPROFILE%")-1))
2662 {
2663#ifndef __REACTOS__
2665 DWORD userLen = MAX_PATH;
2666
2667 strcpyW(szDest, szProfilesPrefix);
2668 GetUserNameW(userName, &userLen);
2669 PathAppendW(szDest, userName);
2670#else
2671 DWORD cchSize = cchDest;
2672 if (!_SHGetUserProfileDirectoryW(hToken, szDest, &cchSize))
2673 goto fallback_expand;
2674#endif
2675 PathAppendW(szDest, szTemp + ARRAY_SIZE(L"%USERPROFILE%")-1);
2676 }
2677 else if (!strncmpiW(szTemp, L"%SystemDrive%", ARRAY_SIZE(L"%SystemDrive%")-1))
2678 {
2679#ifndef __REACTOS__
2681#else
2682 if (!GetSystemDirectoryW(szDest, cchDest))
2683 goto fallback_expand;
2684#endif
2685 strcpyW(szDest + 3, szTemp + ARRAY_SIZE(L"%SystemDrive%")-1 + 1);
2686 }
2687 else
2688#ifdef __REACTOS__
2689fallback_expand:
2690#endif
2691 {
2692#ifndef __REACTOS__
2693 DWORD ret = ExpandEnvironmentStringsW(szTemp, szDest, MAX_PATH);
2694#else
2695 DWORD ret = SHExpandEnvironmentStringsForUserW(hToken, szTemp, szDest, cchDest);
2696#endif
2697
2698#ifndef __REACTOS__
2699 if (ret > MAX_PATH)
2700#else
2701 if (ret > cchDest)
2702#endif
2704 else if (ret == 0)
2706 else if (!strcmpW( szTemp, szDest )) break; /* nothing expanded */
2707 }
2708 if (SUCCEEDED(hr)) strcpyW(szTemp, szDest);
2709 }
2710end:
2711#ifndef __REACTOS__
2712 if (key)
2714#endif
2715 TRACE("returning 0x%08x (input was %s, output is %s)\n", hr,
2716 debugstr_w(szSrc), debugstr_w(szDest));
2717 return hr;
2718}
2719
2720/*************************************************************************
2721 * SHGetFolderPathW [SHELL32.@]
2722 *
2723 * Convert nFolder to path.
2724 *
2725 * RETURNS
2726 * Success: S_OK
2727 * Failure: standard HRESULT error codes.
2728 *
2729 * NOTES
2730 * Most values can be overridden in either
2731 * HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
2732 * or in the same location in HKLM.
2733 * The "Shell Folders" registry key was used in NT4 and earlier systems.
2734 * Beginning with Windows 2000, the "User Shell Folders" key is used, so
2735 * changes made to it are made to the former key too. This synchronization is
2736 * done on-demand: not until someone requests the value of one of these paths
2737 * (by calling one of the SHGet functions) is the value synchronized.
2738 * Furthermore, the HKCU paths take precedence over the HKLM paths.
2739 */
2741 HWND hwndOwner, /* [I] owner window */
2742 int nFolder, /* [I] CSIDL identifying the folder */
2743 HANDLE hToken, /* [I] access token */
2744 DWORD dwFlags, /* [I] which path to return */
2745 LPWSTR pszPath) /* [O] converted path */
2746{
2747 HRESULT hr = SHGetFolderPathAndSubDirW(hwndOwner, nFolder, hToken, dwFlags, NULL, pszPath);
2750 return hr;
2751}
2752
2754 HWND hwndOwner, /* [I] owner window */
2755 int nFolder, /* [I] CSIDL identifying the folder */
2756 HANDLE hToken, /* [I] access token */
2757 DWORD dwFlags, /* [I] which path to return */
2758 LPCSTR pszSubPath, /* [I] sub directory of the specified folder */
2759 LPSTR pszPath) /* [O] converted path */
2760{
2761 int length;
2762 HRESULT hr = S_OK;
2763 LPWSTR pszSubPathW = NULL;
2764 LPWSTR pszPathW = NULL;
2765
2766 TRACE("%p,%#x,%p,%#x,%s,%p\n", hwndOwner, nFolder, hToken, dwFlags, debugstr_a(pszSubPath), pszPath);
2767
2768 if(pszPath) {
2769 pszPathW = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
2770 if(!pszPathW) {
2772 goto cleanup;
2773 }
2774 }
2775 TRACE("%08x,%08x,%s\n",nFolder, dwFlags, debugstr_w(pszSubPathW));
2776
2777 /* SHGetFolderPathAndSubDirW does not distinguish if pszSubPath isn't
2778 * set (null), or an empty string.therefore call it without the parameter set
2779 * if pszSubPath is an empty string
2780 */
2781 if (pszSubPath && pszSubPath[0]) {
2782 length = MultiByteToWideChar(CP_ACP, 0, pszSubPath, -1, NULL, 0);
2783 pszSubPathW = HeapAlloc(GetProcessHeap(), 0, length * sizeof(WCHAR));
2784 if(!pszSubPathW) {
2786 goto cleanup;
2787 }
2788 MultiByteToWideChar(CP_ACP, 0, pszSubPath, -1, pszSubPathW, length);
2789 }
2790
2791 hr = SHGetFolderPathAndSubDirW(hwndOwner, nFolder, hToken, dwFlags, pszSubPathW, pszPathW);
2792
2793 if (SUCCEEDED(hr) && pszPath)
2794 WideCharToMultiByte(CP_ACP, 0, pszPathW, -1, pszPath, MAX_PATH, NULL, NULL);
2795
2796cleanup:
2797 HeapFree(GetProcessHeap(), 0, pszPathW);
2798 HeapFree(GetProcessHeap(), 0, pszSubPathW);
2799 return hr;
2800}
2801
2802/*************************************************************************
2803 * SHGetFolderPathAndSubDirW [SHELL32.@]
2804 */
2806 HWND hwndOwner, /* [I] owner window */
2807 int nFolder, /* [I] CSIDL identifying the folder */
2808 HANDLE hToken, /* [I] access token */
2809 DWORD dwFlags, /* [I] which path to return */
2810 LPCWSTR pszSubPath,/* [I] sub directory of the specified folder */
2811 LPWSTR pszPath) /* [O] converted path */
2812{
2813 HRESULT hr;
2814 WCHAR szBuildPath[MAX_PATH], szTemp[MAX_PATH];
2817 int ret;
2818
2819 TRACE("%p,%#x,%p,%#x,%s,%p\n", hwndOwner, nFolder, hToken, dwFlags, debugstr_w(pszSubPath), pszPath);
2820
2821 /* Windows always NULL-terminates the resulting path regardless of success
2822 * or failure, so do so first
2823 */
2824 if (pszPath)
2825 *pszPath = '\0';
2826
2828 return E_INVALIDARG;
2830 return E_INVALIDARG;
2831 szTemp[0] = 0;
2833 switch (type)
2834 {
2836 hr = E_INVALIDARG;
2837 break;
2839 hr = S_FALSE;
2840 break;
2843 if (CSIDL_Data[folder].szDefaultPath &&
2844 !IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath) &&
2845 *CSIDL_Data[folder].szDefaultPath)
2846 {
2847 PathAddBackslashW(szTemp);
2848 strcatW(szTemp, CSIDL_Data[folder].szDefaultPath);
2849 }
2850 hr = S_OK;
2851 break;
2854 if (CSIDL_Data[folder].szDefaultPath &&
2855 !IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath) &&
2856 *CSIDL_Data[folder].szDefaultPath)
2857 {
2858 PathAddBackslashW(szTemp);
2859 strcatW(szTemp, CSIDL_Data[folder].szDefaultPath);
2860 }
2861 hr = S_OK;
2862 break;
2865 if (CSIDL_Data[folder].szDefaultPath &&
2866 !IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath) &&
2867 *CSIDL_Data[folder].szDefaultPath)
2868 {
2869 PathAddBackslashW(szTemp);
2870 strcatW(szTemp, CSIDL_Data[folder].szDefaultPath);
2871 }
2872 hr = S_OK;
2873 break;
2874 case CSIDL_Type_CurrVer:
2876 break;
2877 case CSIDL_Type_User:
2878#ifdef __REACTOS__
2879 case CSIDL_Type_InMyDocuments:
2880#endif
2881 hr = _SHGetUserProfilePath(hToken, dwFlags, folder, szTemp);
2882 break;
2885 break;
2886 default:
2887 FIXME("bogus type %d, please fix\n", type);
2888 hr = E_INVALIDARG;
2889 break;
2890 }
2891
2892 /* Expand environment strings if necessary */
2893 if (*szTemp == '%')
2894#ifndef __REACTOS__
2895 hr = _SHExpandEnvironmentStrings(szTemp, szBuildPath);
2896#else
2897 hr = _SHExpandEnvironmentStrings(hToken, szTemp, szBuildPath, _countof(szBuildPath));
2898#endif
2899 else
2900 strcpyW(szBuildPath, szTemp);
2901
2902 if (FAILED(hr)) goto end;
2903
2904 if(pszSubPath) {
2905 /* make sure the new path does not exceed the buffer length
2906 * and remember to backslash and terminate it */
2907 if(MAX_PATH < (lstrlenW(szBuildPath) + lstrlenW(pszSubPath) + 2)) {
2909 goto end;
2910 }
2911 PathAppendW(szBuildPath, pszSubPath);
2912 PathRemoveBackslashW(szBuildPath);
2913 }
2914 /* Copy the path if it's available before we might return */
2915 if (SUCCEEDED(hr) && pszPath)
2916 strcpyW(pszPath, szBuildPath);
2917
2918 /* if we don't care about existing directories we are ready */
2920
2921 if (PathFileExistsW(szBuildPath)) goto end;
2922
2923 /* not existing but we are not allowed to create it. The return value
2924 * is verified against shell32 version 6.0.
2925 */
2926 if (!(nFolder & CSIDL_FLAG_CREATE))
2927 {
2929 goto end;
2930 }
2931
2932 /* create directory/directories */
2933 ret = SHCreateDirectoryExW(hwndOwner, szBuildPath, NULL);
2934 if (ret && ret != ERROR_ALREADY_EXISTS)
2935 {
2936 ERR("Failed to create directory %s.\n", debugstr_w(szBuildPath));
2937 hr = E_FAIL;
2938 goto end;
2939 }
2940
2941 TRACE("Created missing system directory %s\n", debugstr_w(szBuildPath));
2942
2943end:
2944#ifdef __REACTOS__
2945 /* create desktop.ini for custom icon */
2946 if ((nFolder & CSIDL_FLAG_CREATE) &&
2947 CSIDL_Data[folder].nShell32IconIndex)
2948 {
2949 WCHAR szIconLocation[MAX_PATH];
2951
2952 /* make the directory a read-only folder */
2953 dwAttributes = GetFileAttributesW(szBuildPath);
2955 SetFileAttributesW(szBuildPath, dwAttributes);
2956
2957 /* build the desktop.ini file path */
2958 PathAppendW(szBuildPath, L"desktop.ini");
2959
2960 /* build the icon location */
2961 StringCchPrintfW(szIconLocation, _countof(szIconLocation),
2962 L"%%SystemRoot%%\\system32\\shell32.dll,%d",
2963 CSIDL_Data[folder].nShell32IconIndex);
2964
2965 /* write desktop.ini */
2966 WritePrivateProfileStringW(L".ShellClassInfo", L"IconResource", szIconLocation, szBuildPath);
2967
2968 /* flush! */
2969 WritePrivateProfileStringW(NULL, NULL, NULL, szBuildPath);
2970
2971 /* make the desktop.ini a system and hidden file */
2972 dwAttributes = GetFileAttributesW(szBuildPath);
2974 SetFileAttributesW(szBuildPath, dwAttributes);
2975 }
2976#endif
2977
2978 TRACE("returning 0x%08x (final path is %s)\n", hr, debugstr_w(szBuildPath));
2979 return hr;
2980}
2981
2982/*************************************************************************
2983 * SHGetFolderPathA [SHELL32.@]
2984 *
2985 * See SHGetFolderPathW.
2986 */
2988 HWND hwndOwner,
2989 int nFolder,
2990 HANDLE hToken,
2991 DWORD dwFlags,
2992 LPSTR pszPath)
2993{
2994 WCHAR szTemp[MAX_PATH];
2995 HRESULT hr;
2996
2997 TRACE("%p,%d,%p,%#x,%p\n", hwndOwner, nFolder, hToken, dwFlags, pszPath);
2998
2999 if (pszPath)
3000 *pszPath = '\0';
3001 hr = SHGetFolderPathW(hwndOwner, nFolder, hToken, dwFlags, szTemp);
3002 if (SUCCEEDED(hr) && pszPath)
3003 WideCharToMultiByte(CP_ACP, 0, szTemp, -1, pszPath, MAX_PATH, NULL,
3004 NULL);
3005
3006 return hr;
3007}
3008
3009/* For each folder in folders, if its value has not been set in the registry,
3010 * calls _SHGetUserProfilePath or _SHGetAllUsersProfilePath (depending on the
3011 * folder's type) to get the unexpanded value first.
3012 * Writes the unexpanded value to User Shell Folders, and queries it with
3013 * SHGetFolderPathW to force the creation of the directory if it doesn't
3014 * already exist. SHGetFolderPathW also returns the expanded value, which
3015 * this then writes to Shell Folders.
3016 */
3017static HRESULT _SHRegisterFolders(HKEY hRootKey, HANDLE hToken,
3018 LPCWSTR szUserShellFolderPath, LPCWSTR szShellFolderPath, const UINT folders[],
3019 UINT foldersLen)
3020{
3021 const WCHAR *szValueName;
3022 WCHAR buffer[40];
3023 UINT i;
3025 HRESULT hr = S_OK;
3026 HKEY hUserKey = NULL, hKey = NULL;
3027 DWORD dwType, dwPathLen;
3028 LONG ret;
3029
3030 TRACE("%p,%p,%s,%p,%u\n", hRootKey, hToken,
3031 debugstr_w(szUserShellFolderPath), folders, foldersLen);
3032
3033 ret = RegCreateKeyW(hRootKey, szUserShellFolderPath, &hUserKey);
3034 if (ret)
3036 else
3037 {
3038 ret = RegCreateKeyW(hRootKey, szShellFolderPath, &hKey);
3039 if (ret)
3041 }
3042 for (i = 0; SUCCEEDED(hr) && i < foldersLen; i++)
3043 {
3044 dwPathLen = MAX_PATH * sizeof(WCHAR);
3045
3046 /* For CSIDL_Type_User we also use the GUID if no szValueName is provided */
3047 szValueName = CSIDL_Data[folders[i]].szValueName;
3048#ifdef __REACTOS__
3049 if (!szValueName &&
3050 (CSIDL_Data[folders[i]].type == CSIDL_Type_User ||
3051 CSIDL_Data[folders[i]].type == CSIDL_Type_InMyDocuments))
3052#else
3053 if (!szValueName && CSIDL_Data[folders[i]].type == CSIDL_Type_User)
3054#endif
3055 {
3056 StringFromGUID2( CSIDL_Data[folders[i]].id, buffer, 39 );
3057 szValueName = &buffer[0];
3058 }
3059
3060 if (!RegQueryValueExW(hUserKey, szValueName, NULL,
3061 &dwType, (LPBYTE)path, &dwPathLen) &&
3062 (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
3063 {
3065 hToken, SHGFP_TYPE_CURRENT, path);
3066 }
3067 else
3068 {
3069 *path = '\0';
3070#ifdef __REACTOS__
3071 if (CSIDL_Data[folders[i]].type == CSIDL_Type_User ||
3072 CSIDL_Data[folders[i]].type == CSIDL_Type_InMyDocuments)
3073#else
3074 if (CSIDL_Data[folders[i]].type == CSIDL_Type_User)
3075#endif
3076 _SHGetUserProfilePath(hToken, SHGFP_TYPE_CURRENT, folders[i],
3077 path);
3078 else if (CSIDL_Data[folders[i]].type == CSIDL_Type_AllUsers)
3080 else if (CSIDL_Data[folders[i]].type == CSIDL_Type_WindowsPath)
3081 {
3083 if (CSIDL_Data[folders[i]].szDefaultPath &&
3084 !IS_INTRESOURCE(CSIDL_Data[folders[i]].szDefaultPath))
3085 {
3087 strcatW(path, CSIDL_Data[folders[i]].szDefaultPath);
3088 }
3089 }
3090 else
3091 hr = E_FAIL;
3092 if (*path)
3093 {
3094 ret = RegSetValueExW(hUserKey, szValueName, 0, REG_EXPAND_SZ,
3095 (LPBYTE)path, (strlenW(path) + 1) * sizeof(WCHAR));
3096 if (ret)
3098 else
3099 {
3101 hToken, SHGFP_TYPE_CURRENT, path);
3102 ret = RegSetValueExW(hKey, szValueName, 0, REG_SZ,
3103 (LPBYTE)path, (strlenW(path) + 1) * sizeof(WCHAR));
3104 if (ret)
3106 }
3107 }
3108 }
3109 }
3110 if (hUserKey)
3111 RegCloseKey(hUserKey);
3112 if (hKey)
3114
3115 TRACE("returning 0x%08x\n", hr);
3116 return hr;
3117}
3118
3120{
3121 static const UINT folders[] = {
3143/* Cannot use #if _WIN32_WINNT >= 0x0600 because _WIN32_WINNT == 0x0600 here. */
3144#ifndef __REACTOS__
3151#endif
3152 };
3153 WCHAR userShellFolderPath[MAX_PATH], shellFolderPath[MAX_PATH];
3154 LPCWSTR pUserShellFolderPath, pShellFolderPath;
3155 HRESULT hr = S_OK;
3156 HKEY hRootKey;
3157 HANDLE hToken;
3158
3159 TRACE("%s\n", bDefault ? "TRUE" : "FALSE");
3160 if (bDefault)
3161 {
3162 hToken = (HANDLE)-1;
3163 hRootKey = HKEY_USERS;
3164 strcpyW(userShellFolderPath, L".Default");
3165 PathAddBackslashW(userShellFolderPath);
3166 strcatW(userShellFolderPath, szSHUserFolders);
3167 pUserShellFolderPath = userShellFolderPath;
3168 strcpyW(shellFolderPath, L".Default");
3169 PathAddBackslashW(shellFolderPath);
3170 strcatW(shellFolderPath, szSHFolders);
3171 pShellFolderPath = shellFolderPath;
3172 }
3173 else
3174 {
3175 hToken = NULL;
3176 hRootKey = HKEY_CURRENT_USER;
3177 pUserShellFolderPath = szSHUserFolders;
3178 pShellFolderPath = szSHFolders;
3179 }
3180
3181 hr = _SHRegisterFolders(hRootKey, hToken, pUserShellFolderPath,
3182 pShellFolderPath, folders, ARRAY_SIZE(folders));
3183 TRACE("returning 0x%08x\n", hr);
3184 return hr;
3185}
3186
3188{
3189 static const UINT folders[] = {
3202 };
3203 HRESULT hr;
3204
3205 TRACE("\n");
3207 szSHFolders, folders, ARRAY_SIZE(folders));
3208 TRACE("returning 0x%08x\n", hr);
3209 return hr;
3210}
3211
3212/* Register the default values in the registry, as some apps seem to depend
3213 * on their presence. The set registered was taken from Windows XP.
3214 */
3216{
3217 HRESULT hr;
3218
3220 if (SUCCEEDED(hr))
3222 if (SUCCEEDED(hr))
3224 return hr;
3225}
3226
3227/*************************************************************************
3228 * SHGetSpecialFolderPathA [SHELL32.@]
3229 */
3231 HWND hwndOwner,
3232 LPSTR szPath,
3233 int nFolder,
3234 BOOL bCreate)
3235{
3236 return SHGetFolderPathA(hwndOwner, nFolder + (bCreate ? CSIDL_FLAG_CREATE : 0), NULL, 0,
3237 szPath) == S_OK;
3238}
3239
3240/*************************************************************************
3241 * SHGetSpecialFolderPathW
3242 */
3244 HWND hwndOwner,
3245 LPWSTR szPath,
3246 int nFolder,
3247 BOOL bCreate)
3248{
3249 return SHGetFolderPathW(hwndOwner, nFolder + (bCreate ? CSIDL_FLAG_CREATE : 0), NULL, 0,
3250 szPath) == S_OK;
3251}
3252
3253#ifdef __REACTOS__
3254HRESULT SHGetFolderLocationHelper(HWND hwnd, int nFolder, REFCLSID clsid, LPITEMIDLIST *ppidl)
3255{
3256 HRESULT hr;
3257 IShellFolder *psf;
3260 *ppidl = NULL;
3262 return hr;
3263 if (SUCCEEDED(hr = SHBindToObject(NULL, parent, &IID_IShellFolder, (void**)&psf)))
3264 {
3265 WCHAR clsidstr[2 + 38 + 1];
3266 clsidstr[0] = clsidstr[1] = L':';
3267 StringFromGUID2(clsid, clsidstr + 2, 38 + 1);
3268 hr = IShellFolder_ParseDisplayName(psf, hwnd, NULL, clsidstr, NULL, &child, NULL);
3269 if (SUCCEEDED(hr))
3270 *ppidl = ILCombine(parent, child);
3271 IShellFolder_Release(psf);
3272 ILFree(child);
3273 }
3274 ILFree(parent);
3275 return hr;
3276}
3277#endif
3278
3279/*************************************************************************
3280 * SHGetFolderLocation [SHELL32.@]
3281 *
3282 * Gets the folder locations from the registry and creates a pidl.
3283 *
3284 * PARAMS
3285 * hwndOwner [I]
3286 * nFolder [I] CSIDL_xxxxx
3287 * hToken [I] token representing user, or NULL for current user, or -1 for
3288 * default user
3289 * dwReserved [I] must be zero
3290 * ppidl [O] PIDL of a special folder
3291 *
3292 * RETURNS
3293 * Success: S_OK
3294 * Failure: Standard OLE-defined error result, S_FALSE or E_INVALIDARG
3295 *
3296 * NOTES
3297 * Creates missing reg keys and directories.
3298 * Mostly forwards to SHGetFolderPathW, but a few values of nFolder return
3299 * virtual folders that are handled here.
3300 */
3302 HWND hwndOwner,
3303 int nFolder,
3304 HANDLE hToken,
3306 LPITEMIDLIST *ppidl)
3307{
3309#ifdef __REACTOS__
3311#endif
3312
3313 TRACE("%p 0x%08x %p 0x%08x %p\n",
3314 hwndOwner, nFolder, hToken, dwReserved, ppidl);
3315
3316 if (!ppidl)
3317 return E_INVALIDARG;
3318 if (dwReserved)
3319 return E_INVALIDARG;
3320
3321#ifdef __REACTOS__
3322 if ((nFolder & CSIDL_FLAG_NO_ALIAS) &&
3324 {
3325 *ppidl = ILCreateFromPathW(szPath);
3326 if (*ppidl)
3327 return S_OK;
3328 }
3329#endif
3330 /* The virtual folders' locations are not user-dependent */
3331 *ppidl = NULL;
3332 switch (nFolder & CSIDL_FOLDER_MASK)
3333 {
3334 case CSIDL_DESKTOP:
3335 *ppidl = _ILCreateDesktop();
3336 break;
3337
3338 case CSIDL_PERSONAL:
3339 *ppidl = _ILCreateMyDocuments();
3340 break;
3341
3342 case CSIDL_INTERNET:
3343 *ppidl = _ILCreateIExplore();
3344 break;
3345
3346 case CSIDL_CONTROLS:
3347 *ppidl = _ILCreateControlPanel();
3348 break;
3349
3350 case CSIDL_PRINTERS:
3351 *ppidl = _ILCreatePrinters();
3352 break;
3353
3354 case CSIDL_BITBUCKET:
3355 *ppidl = _ILCreateBitBucket();
3356 break;
3357
3358 case CSIDL_DRIVES:
3359 *ppidl = _ILCreateMyComputer();
3360 break;
3361
3362 case CSIDL_NETWORK:
3363 *ppidl = _ILCreateNetwork();
3364 break;
3365
3366#ifdef __REACTOS__
3367 case CSIDL_CONNECTIONS:
3368 hr = SHGetFolderLocationHelper(hwndOwner, CSIDL_CONTROLS, &CLSID_NetworkConnections, ppidl);
3369 break;
3370#endif
3371
3372 default:
3373 {
3375
3376 hr = SHGetFolderPathW(hwndOwner, nFolder, hToken,
3378 if (SUCCEEDED(hr))
3379 {
3380 DWORD attributes=0;
3381
3382 TRACE("Value=%s\n", debugstr_w(szPath));
3383 hr = SHILCreateFromPathW(szPath, ppidl, &attributes);
3384 }
3386 {
3387 /* unlike SHGetFolderPath, SHGetFolderLocation in shell32
3388 * version 6.0 returns E_FAIL for nonexistent paths
3389 */
3390 hr = E_FAIL;
3391 }
3392 }
3393 }
3394 if(*ppidl)
3395 hr = S_OK;
3396
3397 TRACE("-- (new pidl %p)\n",*ppidl);
3398 return hr;
3399}
3400
3401/*************************************************************************
3402 * SHGetSpecialFolderLocation [SHELL32.@]
3403 *
3404 * NOTES
3405 * In NT5, SHGetSpecialFolderLocation needs the <winntdir>/Recent
3406 * directory.
3407 */
3409 HWND hwndOwner,
3410 INT nFolder,
3411 LPITEMIDLIST * ppidl)
3412{
3414
3415 TRACE("(%p,0x%x,%p)\n", hwndOwner,nFolder,ppidl);
3416
3417 if (!ppidl)
3418 return E_INVALIDARG;
3419
3420 hr = SHGetFolderLocation(hwndOwner, nFolder, NULL, 0, ppidl);
3421 return hr;
3422}
static _In_ LPCWSTR _In_ DWORD _In_ int _In_ int cchDest
#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
UINT cchMax
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#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:20
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
#define IDS_PROGRAMS
Definition: resource.h:69
#define EXTERN_C
Definition: basetyps.h:12
#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:3333
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1931
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:4882
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
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:464
#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
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4243
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4262
int WINAPI lstrcmpiA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4224
BOOL is_wow64
Definition: msi.c:52
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
#define RRF_RT_REG_SZ
Definition: driver.c:575
EXTERN_C HRESULT SHBindToObject(_In_opt_ IShellFolder *psf, _In_ LPCITEMIDLIST pidl, _In_ REFIID riid, _Out_ void **ppvObj)
Definition: utils.cpp:370
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:1210
static LPWSTR PathGetExtensionW(LPCWSTR lpszPath)
Definition: shellpath.c:434
#define CSIDL_APPDATA_LOCALLOW
Definition: shellpath.c:1211
VOID WINAPI PathQualifyAW(LPVOID pszPath)
Definition: shellpath.c:978
BOOL WINAPI PathIsRootAW(LPCVOID lpszPath)
Definition: shellpath.c:511
VOID WINAPI PathQualifyA(LPSTR pszPath)
Definition: shellpath.c:957
static const WCHAR Program_Files_Common_FilesW[]
Definition: shellpath.c:1178
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:3215
static const WCHAR szKnownFolderRedirections[]
Definition: shellpath.c:1189
HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST *ppidl)
Definition: shellpath.c:3408
enum _CSIDL_Type CSIDL_Type
LPVOID WINAPI SHPathGetExtensionW(LPCWSTR lpszPath, DWORD void1, DWORD void2)
Definition: shellpath.c:445
BOOL WINAPI IsLFNDriveAW(LPCVOID lpszPath)
Definition: shellpath.c:639
static const WCHAR Start_Menu_Admin_ToolsW[]
Definition: shellpath.c:1180
static const WCHAR szSHUserFolders[]
Definition: shellpath.c:1186
#define CSIDL_DOWNLOADS
Definition: shellpath.c:1209
HRESULT WINAPI SHGetFolderLocation(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwReserved, LPITEMIDLIST *ppidl)
Definition: shellpath.c:3301
#define VALID_SHORT_PATH_CHAR_CLASSES
HRESULT WINAPI SHGetFolderPathW(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath)
Definition: shellpath.c:2740
static const WCHAR Local_Settings_HistoryW[]
Definition: shellpath.c:1173
static HRESULT _SHGetCurrentVersionPath(DWORD dwFlags, BYTE folder, LPWSTR pszPath)
Definition: shellpath.c:2284
static BOOL PathMakeUniqueNameW(LPWSTR lpszBuffer, DWORD dwBuffSize, LPCWSTR lpszShortName, LPCWSTR lpszLongName, LPCWSTR lpszPathName)
Definition: shellpath.c:816
static LPSTR PathGetExtensionA(LPCSTR lpszPath)
Definition: shellpath.c:423
static HRESULT _SHRegisterUserShellFolders(BOOL bDefault)
Definition: shellpath.c:3119
BOOL WINAPI PathAppendAW(LPVOID lpszPath1, LPCVOID lpszPath2)
Definition: shellpath.c:407
static HRESULT _SHExpandEnvironmentStrings(LPCWSTR szSrc, LPWSTR szDest)
Definition: shellpath.c:2588
static void PathGetShortPathA(LPSTR pszPath)
Definition: shellpath.c:467
static BOOL PathMakeUniqueNameA(LPSTR lpszBuffer, DWORD dwBuffSize, LPCSTR lpszShortName, LPCSTR lpszLongName, LPCSTR lpszPathName)
Definition: shellpath.c:652
BOOL WINAPI PathIsExeAW(LPCVOID path)
Definition: shellpath.c:557
BOOL WINAPI PathFileExistsAW(LPCVOID lpszPath)
Definition: shellpath.c:567
static const WCHAR Program_FilesW[]
Definition: shellpath.c:1177
static const BOOL is_win64
Definition: shellpath.c:59
#define CSIDL_SEARCHES
Definition: shellpath.c:1213
_CSIDL_Type
Definition: shellpath.c:1192
@ CSIDL_Type_CurrVer
Definition: shellpath.c:1198
@ CSIDL_Type_AllUsers
Definition: shellpath.c:1197
@ CSIDL_Type_WindowsPath
Definition: shellpath.c:1201
@ CSIDL_Type_Disallowed
Definition: shellpath.c:1199
@ CSIDL_Type_SystemX86Path
Definition: shellpath.c:1203
@ CSIDL_Type_SystemPath
Definition: shellpath.c:1202
@ CSIDL_Type_User
Definition: shellpath.c:1193
@ CSIDL_Type_NonExistent
Definition: shellpath.c:1200
HRESULT WINAPI SHGetFolderPathAndSubDirW(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPCWSTR pszSubPath, LPWSTR pszPath)
Definition: shellpath.c:2805
static HRESULT _SHOpenProfilesKey(PHKEY pKey)
Definition: shellpath.c:2523
#define CSIDL_SAVED_GAMES
Definition: shellpath.c:1212
static LONG PathProcessCommandW(LPCWSTR lpszPath, LPWSTR lpszBuff, DWORD dwBuffSize, DWORD dwFlags)
Definition: shellpath.c:1137
static BOOL WINAPI PathMakeAbsoluteW(_Inout_ LPWSTR path)
Definition: shellpath.c:141
BOOL WINAPI IsLFNDriveW(LPCWSTR lpszPath)
Definition: shellpath.c:591
static HRESULT _SHGetAllUsersProfilePath(DWORD dwFlags, BYTE folder, LPWSTR pszPath)
Definition: shellpath.c:2483
HRESULT WINAPI SHGetFolderPathAndSubDirA(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPCSTR pszSubPath, LPSTR pszPath)
Definition: shellpath.c:2753
INT Shell_ParseSpecialFolder(_In_ LPCWSTR pszStart, _Out_ LPWSTR *ppch, _Out_ INT *pcch)
Definition: shellpath.c:2010
static HRESULT _SHGetDefaultValue(BYTE folder, LPWSTR pszPath)
Definition: shellpath.c:2168
static BOOL PathIsExeA(LPCSTR lpszPath)
Definition: shellpath.c:521
static const WCHAR Start_Menu_ProgramsW[]
Definition: shellpath.c:1179
static const WCHAR szSHFolders[]
Definition: shellpath.c:1185
BOOL APIENTRY IsRemovableDrive(DWORD iDrive)
Definition: shellpath.c:107
INT SHGetSpecialFolderID(_In_ LPCWSTR pszName)
Definition: shellpath.c:1996
static HRESULT _SHGetProfilesValue(HKEY profilesKey, LPCWSTR szValueName, LPWSTR szValue, LPCWSTR szDefault)
Definition: shellpath.c:2538
static const CSIDL_DATA CSIDL_Data[]
Definition: shellpath.c:1225
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:1174
static const WCHAR Start_Menu_StartupW[]
Definition: shellpath.c:1181
static const WCHAR szKnownFolderDescriptions[]
Definition: shellpath.c:1188
VOID WINAPI PathQualifyW(LPWSTR pszPath)
Definition: shellpath.c:969
BOOL WINAPI PathMakeUniqueNameAW(LPVOID lpszBuffer, DWORD dwBuffSize, LPCVOID lpszShortName, LPCVOID lpszLongName, LPCVOID lpszPathName)
Definition: shellpath.c:833
BOOL WINAPI PathResolveA(LPSTR path, LPCSTR *dirs, DWORD flags)
Definition: shellpath.c:986
BOOL _SHGetUserProfileDirectoryW(HANDLE hToken, LPWSTR szPath, LPDWORD lpcchPath)
Definition: shellpath.c:2132
LONG WINAPI PathProcessCommandAW(LPCVOID lpszPath, LPVOID lpszBuff, DWORD dwBuffSize, DWORD dwFlags)
Definition: shellpath.c:1154
VOID WINAPI PathGetShortPathAW(LPVOID pszPath)
Definition: shellpath.c:497
static const WCHAR MusicW[]
Definition: shellpath.c:1175
BOOL WINAPI PathResolveW(_Inout_ LPWSTR path, _Inout_opt_ LPCWSTR *dirs, _In_ DWORD flags)
Definition: shellpath.c:1032
static HRESULT _SHRegisterCommonShellFolders(void)
Definition: shellpath.c:3187
static LPWSTR _GetUserSidStringFromToken(HANDLE Token)
Definition: shellpath.c:2353
BOOL WINAPI PathResolveAW(LPVOID path, LPCVOID *paths, DWORD flags)
Definition: shellpath.c:1109
static const WCHAR PicturesW[]
Definition: shellpath.c:1176
static LONG PathProcessCommandA(LPCSTR lpszPath, LPSTR lpszBuff, DWORD dwBuffSize, DWORD dwFlags)
Definition: shellpath.c:1120
static HRESULT _SHRegisterFolders(HKEY hRootKey, HANDLE hToken, LPCWSTR szUserShellFolderPath, LPCWSTR szShellFolderPath, const UINT folders[], UINT foldersLen)
Definition: shellpath.c:3017
int WINAPI PathCleanupSpec(LPCWSTR lpszPathW, LPWSTR lpszFileW)
Definition: shellpath.c:885
static HRESULT _SHGetUserProfilePath(HANDLE hToken, DWORD dwFlags, BYTE folder, LPWSTR pszPath)
Definition: shellpath.c:2394
static const WCHAR Application_DataW[]
Definition: shellpath.c:1171
BOOL WINAPI PathRemoveFileSpecAW(LPVOID lpszPath)
Definition: shellpath.c:453
BOOL WINAPI SHGetSpecialFolderPathA(HWND hwndOwner, LPSTR szPath, int nFolder, BOOL bCreate)
Definition: shellpath.c:3230
HRESULT WINAPI SHGetFolderPathA(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPSTR pszPath)
Definition: shellpath.c:2987
BOOL WINAPI PathYetAnotherMakeUniqueName(LPWSTR buffer, LPCWSTR path, LPCWSTR shortname, LPCWSTR longname)
Definition: shellpath.c:848
#define MSDOS_8DOT3_LEN
BOOL WINAPI SHGetSpecialFolderPathW(HWND hwndOwner, LPWSTR szPath, int nFolder, BOOL bCreate)
Definition: shellpath.c:3243
BOOL PathIsExeW(LPCWSTR lpszPath)
Definition: shellpath.c:539
static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, LPCWSTR userPrefix, LPCWSTR value, LPWSTR path)
Definition: shellpath.c:2049
static void PathGetShortPathW(LPWSTR pszPath)
Definition: shellpath.c:482
BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath)
Definition: shellpath.c:577
static const WCHAR Local_Settings_Application_DataW[]
Definition: shellpath.c:1172
static BOOL WINAPI PathIsAbsoluteW(_In_ LPCWSTR path)
Definition: shellpath.c:136
enum _NT_PRODUCT_TYPE NT_PRODUCT_TYPE
#define CSIDL_CONTACTS
Definition: shellpath.c:1208
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:4551
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:1409
UINT WINAPI PathGetCharTypeA(UCHAR ch)
Definition: path.c:3032
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:1761
BOOL WINAPI PathIsRootW(LPCWSTR lpszPath)
Definition: path.c:1648
BOOL WINAPI PathIsRootA(LPCSTR lpszPath)
Definition: path.c:1608
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c:1783
VOID WINAPI PathUnquoteSpacesW(LPWSTR lpszPath)
Definition: path.c:1040
BOOL WINAPI PathIsUNCW(LPCWSTR lpszPath)
Definition: path.c:2272
BOOL WINAPI PathFindOnPathExW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs, DWORD dwWhich)
Definition: path.c:1357
LPSTR WINAPI PathFindExtensionA(LPCSTR lpszPath)
Definition: path.c:422
BOOL WINAPI PathIsValidCharW(WCHAR c, DWORD class)
Definition: path.c:4409
UINT WINAPI PathGetCharTypeW(WCHAR ch)
Definition: path.c:3042
BOOL WINAPI PathIsFileSpecW(LPCWSTR lpszPath)
Definition: path.c:2139
BOOL WINAPI PathFileExistsAndAttributesW(LPCWSTR lpszPath, DWORD *dwAttr)
Definition: path.c:1838
BOOL WINAPI PathFileExistsDefExtW(LPWSTR lpszPath, DWORD dwWhich)
Definition: path.c:1123
LPWSTR WINAPI PathRemoveBackslashW(LPWSTR lpszPath)
Definition: path.c:867
DWORD WINAPI SHAnsiToUnicode(LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen)
Definition: string.c:2673
INT WINAPI SHUnicodeToAnsi(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT iLen)
Definition: string.c:2797
LPWSTR WINAPI StrCpyNW(LPWSTR dst, LPCWSTR src, int count)
Definition: string.c:536
BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
Definition: url.c:2432
#define IShellFolder_ParseDisplayName
Definition: utils.cpp:14
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
r parent
Definition: btrfs.c:3010
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxRegKey * pKey
FxAutoRegKey hKey
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLuint buffer
Definition: glext.h:5915
GLsizei maxCount
Definition: glext.h:6042
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint64EXT * result
Definition: glext.h:11304
GLfloat GLfloat p
Definition: glext.h:8902
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
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define NTDDI_VERSION
Definition: k32.h:33
#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
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
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 HWND child
Definition: cursoricon.c:298
static const WCHAR path1[]
Definition: path.c:28
#define min(a, b)
Definition: monoChain.cc:55
REFCLSID clsid
Definition: msctf.c:82
_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 _Inout_
Definition: no_sal2.h:162
#define _Inout_opt_
Definition: no_sal2.h:216
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#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:1763
LPITEMIDLIST _ILCreateIExplore(void)
Definition: pidl.c:1775
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:1044
HRESULT WINAPI SHILCreateFromPathW(LPCWSTR path, LPITEMIDLIST *ppidl, DWORD *attributes)
Definition: pidl.c:403
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:816
LPITEMIDLIST _ILCreateDesktop(void)
Definition: pidl.c:1752
LPITEMIDLIST _ILCreateNetwork(void)
Definition: pidl.c:1826
LPITEMIDLIST _ILCreatePrinters(void)
Definition: pidl.c:1799
LPITEMIDLIST _ILCreateControlPanel(void)
Definition: pidl.c:1781
LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR path)
Definition: pidl.c:1101
LPITEMIDLIST _ILCreateMyDocuments(void)
Definition: pidl.c:1769
LPITEMIDLIST _ILCreateBitBucket(void)
Definition: pidl.c:1832
#define INT
Definition: polytest.cpp:20
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
#define strncmpiW(s1, s2, n)
Definition: unicode.h:46
#define strcmpW(s1, s2)
Definition: unicode.h:44
#define strlenW(s)
Definition: unicode.h:34
#define strcatW(d, s)
Definition: unicode.h:36
#define sprintfW
Definition: unicode.h:64
#define strcpyW(d, s)
Definition: unicode.h:35
strcpy
Definition: string.h:131
#define NTDDI_VISTA
Definition: sdkddkver.h:103
static __inline BOOL SHELL_OsIsUnicode(void)
Definition: shell32_main.h:154
static __inline LPWSTR __SHCloneStrAtoW(WCHAR **target, const char *source)
Definition: shell32_main.h:184
_In_ LPCSTR pszDir
Definition: shellapi.h:585
#define CSIDL_FLAG_CREATE
int WINAPI SHCreateDirectoryExW(HWND hWnd, LPCWSTR path, LPSECURITY_ATTRIBUTES sec)
Definition: shlfileop.cpp:1006
HRESULT hr
Definition: shlfolder.c:183
#define CSIDL_COMMON_TEMPLATES
Definition: shlobj.h:2225
#define CSIDL_COMMON_DESKTOPDIRECTORY
Definition: shlobj.h:2205
#define CSIDL_TEMPLATES
Definition: shlobj.h:2201
#define CSIDL_PROGRAM_FILES
Definition: shlobj.h:2218
#define CSIDL_INTERNET_CACHE
Definition: shlobj.h:2212
_In_ int _In_ BOOL bCreate
Definition: shlobj.h:1528
#define CSIDL_DESKTOPDIRECTORY
Definition: shlobj.h:2196
#define CSIDL_SENDTO
Definition: shlobj.h:2190
#define CSIDL_RECENT
Definition: shlobj.h:2189
#define CSIDL_MYDOCUMENTS
Definition: shlobj.h:2193
#define CSIDL_ADMINTOOLS
Definition: shlobj.h:2228
#define CSIDL_COMMON_STARTMENU
Definition: shlobj.h:2202
@ SHGFP_TYPE_DEFAULT
Definition: shlobj.h:2158
@ SHGFP_TYPE_CURRENT
Definition: shlobj.h:2157
#define PCS_REPLACEDCHAR
Definition: shlobj.h:367
#define CSIDL_FONTS
Definition: shlobj.h:2200
#define CSIDL_PERSONAL
Definition: shlobj.h:2186
#define CSIDL_FAVORITES
Definition: shlobj.h:2187
#define CSIDL_FLAG_NO_ALIAS
Definition: shlobj.h:2241
#define CSIDL_COMMON_APPDATA
Definition: shlobj.h:2215
#define CSIDL_CONNECTIONS
Definition: shlobj.h:2229
#define CSIDL_COMMON_PROGRAMS
Definition: shlobj.h:2203
#define PCS_PATHTOOLONG
Definition: shlobj.h:370
#define CSIDL_FLAG_DONT_VERIFY
Definition: shlobj.h:2242
#define CSIDL_MYPICTURES
Definition: shlobj.h:2219
#define CSIDL_COOKIES
Definition: shlobj.h:2213
#define CSIDL_COMMON_FAVORITES
Definition: shlobj.h:2211
#define CSIDL_PRINTERS
Definition: shlobj.h:2185
#define CSIDL_HISTORY
Definition: shlobj.h:2214
#define CSIDL_LOCAL_APPDATA
Definition: shlobj.h:2208
#define CSIDL_PROGRAM_FILES_COMMONX86
Definition: shlobj.h:2224
#define CSIDL_PROGRAM_FILES_COMMON
Definition: shlobj.h:2223
#define CSIDL_COMMON_MUSIC
Definition: shlobj.h:2230
#define PCS_FATAL
Definition: shlobj.h:366
#define CSIDL_COMMON_VIDEO
Definition: shlobj.h:2232
#define CSIDL_FOLDER_MASK
Definition: shlobj.h:2239
#define CSIDL_DESKTOP
Definition: shlobj.h:2181
#define CSIDL_NETWORK
Definition: shlobj.h:2198
#define CSIDL_STARTMENU
Definition: shlobj.h:2192
#define CSIDL_PROGRAM_FILESX86
Definition: shlobj.h:2222
#define CSIDL_COMMON_PICTURES
Definition: shlobj.h:2231
#define CSIDL_PROGRAMS
Definition: shlobj.h:2183
#define CSIDL_COMMON_STARTUP
Definition: shlobj.h:2204
#define CSIDL_APPDATA
Definition: shlobj.h:2206
#define CSIDL_PRINTHOOD
Definition: shlobj.h:2207
#define CSIDL_STARTUP
Definition: shlobj.h:2188
#define CSIDL_DRIVES
Definition: shlobj.h:2197
#define CSIDL_MYMUSIC
Definition: shlobj.h:2194
#define CSIDL_INTERNET
Definition: shlobj.h:2182
#define CSIDL_COMMON_DOCUMENTS
Definition: shlobj.h:2226
#define CSIDL_CONTROLS
Definition: shlobj.h:2184
#define CSIDL_BITBUCKET
Definition: shlobj.h:2191
#define CSIDL_NETHOOD
Definition: shlobj.h:2199
#define CSIDL_COMMON_ADMINTOOLS
Definition: shlobj.h:2227
#define CSIDL_MYVIDEO
Definition: shlobj.h:2195
_In_ int nFolder
Definition: shlobj.h:1527
#define GCT_SEPARATOR
Definition: shlwapi.h:814
#define GCT_INVALID
Definition: shlwapi.h:810
#define GCT_WILD
Definition: shlwapi.h:813
#define WHICH_DEFAULT
#define IDS_RECENT
Definition: shresdef.h:88
#define IDS_NETHOOD
Definition: shresdef.h:94
#define IDI_SHELL_MY_DOCUMENTS
Definition: shresdef.h:708
#define IDS_MYVIDEO
Definition: shresdef.h:92
#define IDI_SHELL_MY_MUSIC
Definition: shresdef.h:710
#define IDS_COOKIES
Definition: shresdef.h:100
#define IDI_SHELL_MY_PICTURES
Definition: shresdef.h:709
#define IDI_SHELL_TSKBAR_STARTMENU
Definition: shresdef.h:618
#define IDS_MYMUSIC
Definition: shresdef.h:91
#define IDI_SHELL_COMPUTER_FOLDER
Definition: shresdef.h:621
#define IDI_SHELL_DESKTOP
Definition: shresdef.h:613
#define IDI_SHELL_FAVORITES
Definition: shresdef.h:622
#define IDS_INTERNET_CACHE
Definition: shresdef.h:99
#define IDS_STARTUP
Definition: shresdef.h:87
#define IDS_COMMON_VIDEO
Definition: shresdef.h:109
#define IDI_SHELL_MY_MOVIES
Definition: shresdef.h:711
#define IDI_SHELL_PROGRAMS_FOLDER
Definition: shresdef.h:598
#define IDI_SHELL_RECENT_DOCUMENTS
Definition: shresdef.h:599
#define IDI_SHELL_NETWORK
Definition: shresdef.h:593
#define IDS_APPDATA
Definition: shresdef.h:96
#define IDI_SHELL_PRINTERS_FOLDER
Definition: shresdef.h:616
#define IDS_TEMPLATES
Definition: shresdef.h:95
#define IDS_COMMON_PICTURES
Definition: shresdef.h:108
#define IDS_PROGRAM_FILES_COMMON
Definition: shresdef.h:104
#define IDS_DESKTOPDIRECTORY
Definition: shresdef.h:93
#define IDS_PRINTHOOD
Definition: shresdef.h:97
#define IDS_SENDTO
Definition: shresdef.h:89
#define IDI_SHELL_NETWORK_CONNECTIONS
Definition: shresdef.h:667
#define IDI_SHELL_FONTS_FOLDER
Definition: shresdef.h:617
#define IDS_COMMON_MUSIC
Definition: shresdef.h:107
#define IDS_ADMINTOOLS
Definition: shresdef.h:106
#define IDS_MYPICTURES
Definition: shresdef.h:103
#define IDI_SHELL_CONTROL_PANEL
Definition: shresdef.h:600
#define IDS_STARTMENU
Definition: shresdef.h:90
#define IDS_PROGRAM_FILES
Definition: shresdef.h:102
#define IDS_HISTORY
Definition: shresdef.h:101
#define IDS_LOCAL_APPDATA
Definition: shresdef.h:98
#define IDI_SHELL_SYSTEM_GEAR
Definition: shresdef.h:747
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define _countof(array)
Definition: sndvol32.h:70
#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
STRSAFEAPI StringCchCopyNW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc, size_t cchToCopy)
Definition: strsafe.h:236
INT nShell32IconIndex
Definition: shellpath.c:1222
CSIDL_Type type
Definition: shellpath.c:1219
LPCWSTR szDefaultPath
Definition: shellpath.c:1221
LPCWSTR szValueName
Definition: shellpath.c:1220
const KNOWNFOLDERID * id
Definition: shellpath.c:1218
SID_AND_ATTRIBUTES User
Definition: setypes.h:1010
Definition: fci.c:127
Definition: fci.c:116
Definition: copy.c:22
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
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:96
DWORD dwAttributes
Definition: vdmdbg.h:34
int ret
#define ZeroMemory
Definition: winbase.h:1743
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define DRIVE_REMOVABLE
Definition: winbase.h:277
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
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:2156
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