ReactOS 0.4.17-dev-573-g8315b8c
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,
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{
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;
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;
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
1015
1016 ret = PathResolveW(pathW, (LPCWSTR*)dirsW, flags);
1017 if (ret)
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
1206
1207/* Cannot use #if _WIN32_WINNT >= 0x0600 because _WIN32_WINNT == 0x0600 here. */
1208#ifndef __REACTOS__
1209#define CSIDL_CONTACTS 0x0043
1210#define CSIDL_DOWNLOADS 0x0047
1211#define CSIDL_LINKS 0x004d
1212#define CSIDL_APPDATA_LOCALLOW 0x004e
1213#define CSIDL_SAVED_GAMES 0x0062
1214#define CSIDL_SEARCHES 0x0063
1215#endif
1216
1217typedef struct
1218{
1222 LPCWSTR szDefaultPath; /* fallback string or resource ID */
1224} CSIDL_DATA;
1225
1226static const CSIDL_DATA CSIDL_Data[] =
1227{
1228 { /* 0x00 - CSIDL_DESKTOP */
1229 &FOLDERID_Desktop,
1231 L"Desktop",
1233 0
1234 },
1235 { /* 0x01 - CSIDL_INTERNET */
1236 &FOLDERID_InternetFolder,
1238 NULL,
1239 NULL
1240 },
1241 { /* 0x02 - CSIDL_PROGRAMS */
1242 &FOLDERID_Programs,
1244 L"Programs",
1246 0
1247 },
1248 { /* 0x03 - CSIDL_CONTROLS (.CPL files) */
1249 &FOLDERID_ControlPanelFolder,
1251 L"ControlPanelFolder",
1252 NULL,
1254 },
1255 { /* 0x04 - CSIDL_PRINTERS */
1256 &FOLDERID_PrintersFolder,
1258 L"PrintersFolder",
1259 NULL,
1261 },
1262 { /* 0x05 - CSIDL_PERSONAL */
1263 &FOLDERID_Documents,
1265 L"Personal",
1268 },
1269 { /* 0x06 - CSIDL_FAVORITES */
1270 &FOLDERID_Favorites,
1272 L"Favorites",
1275 },
1276 { /* 0x07 - CSIDL_STARTUP */
1277 &FOLDERID_Startup,
1279 L"StartUp",
1281 },
1282 { /* 0x08 - CSIDL_RECENT */
1283 &FOLDERID_Recent,
1285 L"Recent",
1288 },
1289 { /* 0x09 - CSIDL_SENDTO */
1290 &FOLDERID_SendTo,
1292 L"SendTo",
1294 },
1295 { /* 0x0a - CSIDL_BITBUCKET - Recycle Bin */
1296 &FOLDERID_RecycleBinFolder,
1298 L"RecycleBinFolder",
1299 NULL
1300 },
1301 { /* 0x0b - CSIDL_STARTMENU */
1302 &FOLDERID_StartMenu,
1304 L"Start Menu",
1307 },
1308 { /* 0x0c - CSIDL_MYDOCUMENTS */
1309 &GUID_NULL,
1310 CSIDL_Type_Disallowed, /* matches WinXP--can't get its path */
1311 NULL,
1312 NULL,
1314 },
1315 { /* 0x0d - CSIDL_MYMUSIC */
1316 &FOLDERID_Music,
1317#ifdef __REACTOS__
1318 CSIDL_Type_InMyDocuments,
1319#else
1321#endif
1322 L"My Music",
1325 },
1326 { /* 0x0e - CSIDL_MYVIDEO */
1327 &FOLDERID_Videos,
1328#ifdef __REACTOS__
1329 CSIDL_Type_InMyDocuments,
1330#else
1332#endif
1333 L"My Video",
1336 },
1337 { /* 0x0f - unassigned */
1338 &GUID_NULL,
1340 NULL,
1341 NULL,
1342 },
1343 { /* 0x10 - CSIDL_DESKTOPDIRECTORY */
1344 &FOLDERID_Desktop,
1346 L"Desktop",
1348 0
1349 },
1350 { /* 0x11 - CSIDL_DRIVES */
1351 &FOLDERID_ComputerFolder,
1353 L"MyComputerFolder",
1354 NULL,
1356 },
1357 { /* 0x12 - CSIDL_NETWORK */
1358 &FOLDERID_NetworkFolder,
1360 L"NetworkPlacesFolder",
1361 NULL,
1363 },
1364 { /* 0x13 - CSIDL_NETHOOD */
1365 &FOLDERID_NetHood,
1367 L"NetHood",
1370 },
1371 { /* 0x14 - CSIDL_FONTS */
1372 &FOLDERID_Fonts,
1374 L"Fonts",
1375 L"Fonts",
1377 },
1378 { /* 0x15 - CSIDL_TEMPLATES */
1379 &FOLDERID_Templates,
1381 L"Templates",
1383 },
1384 { /* 0x16 - CSIDL_COMMON_STARTMENU */
1385 &FOLDERID_CommonStartMenu,
1387 L"Common Start Menu",
1390 },
1391 { /* 0x17 - CSIDL_COMMON_PROGRAMS */
1392 &FOLDERID_CommonPrograms,
1394 L"Common Programs",
1396 0
1397 },
1398 { /* 0x18 - CSIDL_COMMON_STARTUP */
1399 &FOLDERID_CommonStartup,
1401 L"Common StartUp",
1403 },
1404 { /* 0x19 - CSIDL_COMMON_DESKTOPDIRECTORY */
1405 &FOLDERID_PublicDesktop,
1407 L"Common Desktop",
1409 0
1410 },
1411 { /* 0x1a - CSIDL_APPDATA */
1412 &FOLDERID_RoamingAppData,
1414 L"AppData",
1416 },
1417 { /* 0x1b - CSIDL_PRINTHOOD */
1418 &FOLDERID_PrintHood,
1420 L"PrintHood",
1423 },
1424 { /* 0x1c - CSIDL_LOCAL_APPDATA */
1425 &FOLDERID_LocalAppData,
1427 L"Local AppData",
1429 },
1430 { /* 0x1d - CSIDL_ALTSTARTUP */
1431 &GUID_NULL,
1433 NULL,
1434 NULL
1435 },
1436 { /* 0x1e - CSIDL_COMMON_ALTSTARTUP */
1437 &GUID_NULL,
1439 NULL,
1440 NULL
1441 },
1442 { /* 0x1f - CSIDL_COMMON_FAVORITES */
1443 &FOLDERID_Favorites,
1445 L"Common Favorites",
1448 },
1449 { /* 0x20 - CSIDL_INTERNET_CACHE */
1450 &FOLDERID_InternetCache,
1452 L"Cache",
1454 },
1455 { /* 0x21 - CSIDL_COOKIES */
1456 &FOLDERID_Cookies,
1458 L"Cookies",
1460 },
1461 { /* 0x22 - CSIDL_HISTORY */
1462 &FOLDERID_History,
1464 L"History",
1466 },
1467 { /* 0x23 - CSIDL_COMMON_APPDATA */
1468 &FOLDERID_ProgramData,
1470 L"Common AppData",
1472 },
1473 { /* 0x24 - CSIDL_WINDOWS */
1474 &FOLDERID_Windows,
1476 L"Windows",
1477 NULL,
1478 0
1479 },
1480 { /* 0x25 - CSIDL_SYSTEM */
1481 &FOLDERID_System,
1483 L"System",
1484 NULL,
1485 0
1486 },
1487 { /* 0x26 - CSIDL_PROGRAM_FILES */
1488 &FOLDERID_ProgramFiles,
1490 L"ProgramFiles",
1492 0
1493 },
1494 { /* 0x27 - CSIDL_MYPICTURES */
1495 &FOLDERID_Pictures,
1496#ifdef __REACTOS__
1497 CSIDL_Type_InMyDocuments,
1498#else
1500#endif
1501 L"My Pictures",
1504 },
1505 { /* 0x28 - CSIDL_PROFILE */
1506 &FOLDERID_Profile,
1508 NULL,
1509 NULL
1510 },
1511 { /* 0x29 - CSIDL_SYSTEMX86 */
1512 &FOLDERID_SystemX86,
1514 NULL,
1515 NULL,
1517 },
1518 { /* 0x2a - CSIDL_PROGRAM_FILESX86 */
1519 &FOLDERID_ProgramFilesX86,
1521 L"ProgramFilesX86",
1522 L"Program Files (x86)",
1523 0
1524 },
1525 { /* 0x2b - CSIDL_PROGRAM_FILES_COMMON */
1526 &FOLDERID_ProgramFilesCommon,
1528 L"ProgramFilesCommon",
1530 0
1531 },
1532 { /* 0x2c - CSIDL_PROGRAM_FILES_COMMONX86 */
1533 &FOLDERID_ProgramFilesCommonX86,
1535 L"ProgramFilesCommonX86",
1536 L"Program Files (x86)\\Common Files",
1537 0
1538 },
1539 { /* 0x2d - CSIDL_COMMON_TEMPLATES */
1540 &FOLDERID_CommonTemplates,
1542 L"Common Templates",
1544 },
1545 { /* 0x2e - CSIDL_COMMON_DOCUMENTS */
1546 &FOLDERID_PublicDocuments,
1548 L"Common Documents",
1551 },
1552 { /* 0x2f - CSIDL_COMMON_ADMINTOOLS */
1553 &FOLDERID_CommonAdminTools,
1555 L"Common Administrative Tools",
1557 },
1558 { /* 0x30 - CSIDL_ADMINTOOLS */
1559 &FOLDERID_AdminTools,
1561 L"Administrative Tools",
1563 },
1564 { /* 0x31 - CSIDL_CONNECTIONS */
1565 &FOLDERID_ConnectionsFolder,
1567 L"ConnectionsFolder",
1568 NULL,
1570 },
1571 { /* 0x32 - unassigned */
1572 &GUID_NULL,
1574 NULL,
1575 NULL
1576 },
1577 { /* 0x33 - unassigned */
1578 &GUID_NULL,
1580 NULL,
1581 NULL
1582 },
1583 { /* 0x34 - unassigned */
1584 &GUID_NULL,
1586 NULL,
1587 NULL
1588 },
1589 { /* 0x35 - CSIDL_COMMON_MUSIC */
1590 &FOLDERID_PublicMusic,
1592 L"CommonMusic",
1595 },
1596 { /* 0x36 - CSIDL_COMMON_PICTURES */
1597 &FOLDERID_PublicPictures,
1599 L"CommonPictures",
1602 },
1603 { /* 0x37 - CSIDL_COMMON_VIDEO */
1604 &FOLDERID_PublicVideos,
1606 L"CommonVideo",
1609 },
1610 { /* 0x38 - CSIDL_RESOURCES */
1611 &FOLDERID_ResourceDir,
1613 NULL,
1614 L"Resources"
1615 },
1616 { /* 0x39 - CSIDL_RESOURCES_LOCALIZED */
1617 &FOLDERID_LocalizedResourcesDir,
1619 NULL,
1620 NULL
1621 },
1622 { /* 0x3a - CSIDL_COMMON_OEM_LINKS */
1623 &FOLDERID_CommonOEMLinks,
1625 NULL,
1626 L"OEM Links"
1627 },
1628 { /* 0x3b - CSIDL_CDBURN_AREA */
1629 &FOLDERID_CDBurning,
1631 L"CD Burning",
1632 L"Local Settings\\Application Data\\Microsoft\\CD Burning"
1633 },
1634 { /* 0x3c unassigned */
1635 &GUID_NULL,
1637 NULL,
1638 NULL
1639 },
1640 { /* 0x3d - CSIDL_COMPUTERSNEARME */
1641 &GUID_NULL,
1642 CSIDL_Type_Disallowed, /* FIXME */
1643 NULL,
1644 NULL
1645 },
1646 { /* 0x3e - CSIDL_PROFILES */
1647 &GUID_NULL,
1648 CSIDL_Type_Disallowed, /* oddly, this matches WinXP */
1649 NULL,
1650 NULL
1651 },
1652/* Cannot use #if _WIN32_WINNT >= 0x0600 because _WIN32_WINNT == 0x0600 here. */
1653#ifndef __REACTOS__
1654 { /* 0x3f */
1655 &FOLDERID_AddNewPrograms,
1657 NULL,
1658 NULL
1659 },
1660 { /* 0x40 */
1661 &FOLDERID_AppUpdates,
1663 NULL,
1664 NULL
1665 },
1666 { /* 0x41 */
1667 &FOLDERID_ChangeRemovePrograms,
1669 NULL,
1670 NULL
1671 },
1672 { /* 0x42 */
1673 &FOLDERID_ConflictFolder,
1675 NULL,
1676 NULL
1677 },
1678 { /* 0x43 - CSIDL_CONTACTS */
1679 &FOLDERID_Contacts,
1681 NULL,
1682 L"Contacts"
1683 },
1684 { /* 0x44 */
1685 &FOLDERID_DeviceMetadataStore,
1686 CSIDL_Type_Disallowed, /* FIXME */
1687 NULL,
1688 NULL
1689 },
1690 { /* 0x45 */
1691 &GUID_NULL,
1693 NULL,
1694 L"Documents"
1695 },
1696 { /* 0x46 */
1697 &FOLDERID_DocumentsLibrary,
1698 CSIDL_Type_Disallowed, /* FIXME */
1699 NULL,
1700 NULL
1701 },
1702 { /* 0x47 - CSIDL_DOWNLOADS */
1703 &FOLDERID_Downloads,
1704#ifdef __REACTOS__
1705 CSIDL_Type_InMyDocuments,
1706#else
1708#endif
1709 NULL,
1710 L"Downloads"
1711 },
1712 { /* 0x48 */
1713 &FOLDERID_Games,
1715 NULL,
1716 NULL
1717 },
1718 { /* 0x49 */
1719 &FOLDERID_GameTasks,
1720 CSIDL_Type_Disallowed, /* FIXME */
1721 NULL,
1722 NULL
1723 },
1724 { /* 0x4a */
1725 &FOLDERID_HomeGroup,
1727 NULL,
1728 NULL
1729 },
1730 { /* 0x4b */
1731 &FOLDERID_ImplicitAppShortcuts,
1732 CSIDL_Type_Disallowed, /* FIXME */
1733 NULL,
1734 NULL
1735 },
1736 { /* 0x4c */
1737 &FOLDERID_Libraries,
1738 CSIDL_Type_Disallowed, /* FIXME */
1739 NULL,
1740 NULL
1741 },
1742 { /* 0x4d - CSIDL_LINKS */
1743 &FOLDERID_Links,
1745 NULL,
1746 L"Links"
1747 },
1748 { /* 0x4e - CSIDL_APPDATA_LOCALLOW */
1749 &FOLDERID_LocalAppDataLow,
1751 NULL,
1752 L"AppData\\LocalLow"
1753 },
1754 { /* 0x4f */
1755 &FOLDERID_MusicLibrary,
1756 CSIDL_Type_Disallowed, /* FIXME */
1757 NULL,
1758 NULL
1759 },
1760 { /* 0x50 */
1761 &FOLDERID_OriginalImages,
1762 CSIDL_Type_Disallowed, /* FIXME */
1763 NULL,
1764 NULL
1765 },
1766 { /* 0x51 */
1767 &FOLDERID_PhotoAlbums,
1769 NULL,
1770 L"Pictures\\Slide Shows"
1771 },
1772 { /* 0x52 */
1773 &FOLDERID_PicturesLibrary,
1774 CSIDL_Type_Disallowed, /* FIXME */
1775 NULL,
1776 NULL
1777 },
1778 { /* 0x53 */
1779 &FOLDERID_Playlists,
1781 NULL,
1782 L"Music\\Playlists"
1783 },
1784 { /* 0x54 */
1785 &FOLDERID_ProgramFilesX64,
1787 NULL,
1788 NULL
1789 },
1790 { /* 0x55 */
1791 &FOLDERID_ProgramFilesCommonX64,
1793 NULL,
1794 NULL
1795 },
1796 { /* 0x56 */
1797 &FOLDERID_Public,
1798 CSIDL_Type_CurrVer, /* FIXME */
1799 NULL,
1800 L"Users\\Public"
1801 },
1802 { /* 0x57 */
1803 &FOLDERID_PublicDownloads,
1805 NULL,
1806 L"Downloads"
1807 },
1808 { /* 0x58 */
1809 &FOLDERID_PublicGameTasks,
1811 NULL,
1812 L"Microsoft\\Windows\\GameExplorer"
1813 },
1814 { /* 0x59 */
1815 &FOLDERID_PublicLibraries,
1817 NULL,
1818 L"Microsoft\\Windows\\Libraries"
1819 },
1820 { /* 0x5a */
1821 &FOLDERID_PublicRingtones,
1823 NULL,
1824 L"Microsoft\\Windows\\Ringtones"
1825 },
1826 { /* 0x5b */
1827 &FOLDERID_QuickLaunch,
1828 CSIDL_Type_Disallowed, /* FIXME */
1829 NULL,
1830 NULL
1831 },
1832 { /* 0x5c */
1833 &FOLDERID_RecordedTVLibrary,
1834 CSIDL_Type_Disallowed, /* FIXME */
1835 NULL,
1836 NULL
1837 },
1838 { /* 0x5d */
1839 &FOLDERID_Ringtones,
1840 CSIDL_Type_Disallowed, /* FIXME */
1841 NULL,
1842 NULL
1843 },
1844 { /* 0x5e */
1845 &FOLDERID_SampleMusic,
1847 NULL,
1848 L"Music\\Sample Music"
1849 },
1850 { /* 0x5f */
1851 &FOLDERID_SamplePictures,
1853 NULL,
1854 L"Pictures\\Sample Pictures"
1855 },
1856 { /* 0x60 */
1857 &FOLDERID_SamplePlaylists,
1859 NULL,
1860 L"Music\\Sample Playlists"
1861 },
1862 { /* 0x61 */
1863 &FOLDERID_SampleVideos,
1865 NULL,
1866 L"Videos\\Sample Videos"
1867 },
1868 { /* 0x62 - CSIDL_SAVED_GAMES */
1869 &FOLDERID_SavedGames,
1871 NULL,
1872 L"Saved Games"
1873 },
1874 { /* 0x63 - CSIDL_SEARCHES */
1875 &FOLDERID_SavedSearches,
1877 NULL,
1878 L"Searches"
1879 },
1880 { /* 0x64 */
1881 &FOLDERID_SEARCH_CSC,
1883 NULL,
1884 NULL
1885 },
1886 { /* 0x65 */
1887 &FOLDERID_SEARCH_MAPI,
1889 NULL,
1890 NULL
1891 },
1892 { /* 0x66 */
1893 &FOLDERID_SearchHome,
1895 NULL,
1896 NULL
1897 },
1898 { /* 0x67 */
1899 &FOLDERID_SidebarDefaultParts,
1900 CSIDL_Type_Disallowed, /* FIXME */
1901 NULL,
1902 NULL
1903 },
1904 { /* 0x68 */
1905 &FOLDERID_SidebarParts,
1906 CSIDL_Type_Disallowed, /* FIXME */
1907 NULL,
1908 NULL
1909 },
1910 { /* 0x69 */
1911 &FOLDERID_SyncManagerFolder,
1913 NULL,
1914 NULL
1915 },
1916 { /* 0x6a */
1917 &FOLDERID_SyncResultsFolder,
1919 NULL,
1920 NULL
1921 },
1922 { /* 0x6b */
1923 &FOLDERID_SyncSetupFolder,
1925 NULL,
1926 NULL
1927 },
1928 { /* 0x6c */
1929 &FOLDERID_UserPinned,
1930 CSIDL_Type_Disallowed, /* FIXME */
1931 NULL,
1932 NULL
1933 },
1934 { /* 0x6d */
1935 &FOLDERID_UserProfiles,
1937 L"Users",
1938 L"Users"
1939 },
1940 { /* 0x6e */
1941 &FOLDERID_UserProgramFiles,
1942 CSIDL_Type_Disallowed, /* FIXME */
1943 NULL,
1944 NULL
1945 },
1946 { /* 0x6f */
1947 &FOLDERID_UserProgramFilesCommon,
1948 CSIDL_Type_Disallowed, /* FIXME */
1949 NULL,
1950 NULL
1951 },
1952 { /* 0x70 */
1953 &FOLDERID_UsersFiles,
1955 NULL,
1956 NULL
1957 },
1958 { /* 0x71 */
1959 &FOLDERID_UsersLibraries,
1961 NULL,
1962 NULL
1963 },
1964 { /* 0x72 */
1965 &FOLDERID_VideosLibrary,
1966 CSIDL_Type_Disallowed, /* FIXME */
1967 NULL,
1968 NULL
1969 }
1970#endif
1971};
1972
1974{
1975 UINT csidl;
1976
1977 for (csidl = 0; csidl < _countof(CSIDL_Data); ++csidl)
1978 {
1979 const CSIDL_DATA *pData = &CSIDL_Data[csidl];
1980 if (pData->szValueName && lstrcmpiW(pszName, pData->szValueName) == 0)
1981 return csidl;
1982 }
1983
1984 return -1;
1985}
1986
1988{
1989 LPCWSTR pszPath, pchBackslash;
1991
1992 pchBackslash = StrChrW(pszStart, L'\\');
1993 if (pchBackslash)
1994 {
1995 *ppch = (LPWSTR)(pchBackslash + 1);
1996 *pcch = (pchBackslash - pszStart) + 1;
1997 StrCpyNW(szPath, pszStart, min(*pcch, _countof(szPath)));
1998 pszPath = szPath;
1999 }
2000 else
2001 {
2002 *ppch = NULL;
2003 *pcch = lstrlenW(pszStart);
2004 pszPath = pszStart;
2005 }
2006
2007 return SHGetSpecialFolderID(pszPath);
2008}
2009
2010#ifndef __REACTOS__
2012#else
2014#endif
2015
2016/* Gets the value named value from the registry key
2017 * rootKey\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
2018 * (or from rootKey\userPrefix\... if userPrefix is not NULL) into path, which
2019 * is assumed to be MAX_PATH WCHARs in length.
2020 * If it exists, expands the value and writes the expanded value to
2021 * rootKey\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
2022 * Returns successful error code if the value was retrieved from the registry,
2023 * and a failure otherwise.
2024 */
2025#ifndef __REACTOS__
2027#else
2028static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, HANDLE hToken, LPCWSTR userPrefix,
2029#endif
2031{
2032 HRESULT hr;
2033 WCHAR shellFolderPath[MAX_PATH], userShellFolderPath[MAX_PATH];
2034 LPCWSTR pShellFolderPath, pUserShellFolderPath;
2035 HKEY userShellFolderKey, shellFolderKey;
2036 DWORD dwType, dwPathLen;
2037
2038 TRACE("%p,%s,%s,%p\n",rootKey, debugstr_w(userPrefix), debugstr_w(value),
2039 path);
2040
2041 if (userPrefix)
2042 {
2043 strcpyW(shellFolderPath, userPrefix);
2044 PathAddBackslashW(shellFolderPath);
2045 strcatW(shellFolderPath, szSHFolders);
2046 pShellFolderPath = shellFolderPath;
2047 strcpyW(userShellFolderPath, userPrefix);
2048 PathAddBackslashW(userShellFolderPath);
2049 strcatW(userShellFolderPath, szSHUserFolders);
2050 pUserShellFolderPath = userShellFolderPath;
2051 }
2052 else
2053 {
2054 pUserShellFolderPath = szSHUserFolders;
2055 pShellFolderPath = szSHFolders;
2056 }
2057
2058 if (RegCreateKeyW(rootKey, pShellFolderPath, &shellFolderKey))
2059 {
2060 TRACE("Failed to create %s\n", debugstr_w(pShellFolderPath));
2061 return E_FAIL;
2062 }
2063 if (RegCreateKeyW(rootKey, pUserShellFolderPath, &userShellFolderKey))
2064 {
2065 TRACE("Failed to create %s\n",
2066 debugstr_w(pUserShellFolderPath));
2067 RegCloseKey(shellFolderKey);
2068 return E_FAIL;
2069 }
2070
2071 dwPathLen = MAX_PATH * sizeof(WCHAR);
2072 if (!RegQueryValueExW(userShellFolderKey, value, NULL, &dwType,
2073 (LPBYTE)path, &dwPathLen) && (dwType == REG_EXPAND_SZ || dwType == REG_SZ))
2074 {
2075 LONG ret;
2076
2077 path[dwPathLen / sizeof(WCHAR)] = '\0';
2078 if (dwType == REG_EXPAND_SZ && path[0] == '%')
2079 {
2080 WCHAR szTemp[MAX_PATH];
2081
2082#ifndef __REACTOS__
2084#else
2085 hr = _SHExpandEnvironmentStrings(hToken, path, szTemp, _countof(szTemp));
2086 if (FAILED(hr))
2087 goto end;
2088#endif
2089 lstrcpynW(path, szTemp, MAX_PATH);
2090 }
2091 ret = RegSetValueExW(shellFolderKey, value, 0, REG_SZ, (LPBYTE)path,
2092 (strlenW(path) + 1) * sizeof(WCHAR));
2093 if (ret != ERROR_SUCCESS)
2095 else
2096 hr = S_OK;
2097 }
2098 else
2099 hr = E_FAIL;
2100#ifdef __REACTOS__
2101end:
2102#endif
2103 RegCloseKey(shellFolderKey);
2104 RegCloseKey(userShellFolderKey);
2105 TRACE("returning 0x%08x\n", hr);
2106 return hr;
2107}
2108
2110{
2111 BOOL result;
2112 if (!hToken)
2113 {
2115 result = GetUserProfileDirectoryW(hToken, szPath, lpcchPath);
2116 CloseHandle(hToken);
2117 }
2118 else if ((INT) hToken == -1)
2119 {
2121 }
2122 else
2123 {
2124 result = GetUserProfileDirectoryW(hToken, szPath, lpcchPath);
2125 }
2126 TRACE("_SHGetUserProfileDirectoryW returning %S\n", szPath);
2127 return result;
2128}
2129
2130/* Gets a 'semi-expanded' default value of the CSIDL with index folder into
2131 * pszPath, based on the entries in CSIDL_Data. By semi-expanded, I mean:
2132 * - The entry's szDefaultPath may be either a string value or an integer
2133 * resource identifier. In the latter case, the string value of the resource
2134 * is written.
2135 * - Depending on the entry's type, the path may begin with an (unexpanded)
2136 * environment variable name. The caller is responsible for expanding
2137 * environment strings if so desired.
2138 * The types that are prepended with environment variables are:
2139 * CSIDL_Type_User: %USERPROFILE%
2140 * CSIDL_Type_AllUsers: %ALLUSERSPROFILE%
2141 * CSIDL_Type_CurrVer: %SystemDrive%
2142 * (Others might make sense too, but as yet are unneeded.)
2143 */
2144#ifndef __REACTOS__
2146#else
2147static HRESULT _SHGetDefaultValue(HANDLE hToken, BYTE folder, LPWSTR pszPath)
2148#endif
2149{
2150 HRESULT hr;
2151 WCHAR resourcePath[MAX_PATH];
2152#ifdef __REACTOS__
2153 NT_PRODUCT_TYPE ProductType;
2154#endif
2155
2156 TRACE("0x%02x,%p\n", folder, pszPath);
2157
2159 return E_INVALIDARG;
2160
2161 if (!pszPath)
2162 return E_INVALIDARG;
2163
2164#ifdef __REACTOS__
2165 if (hToken != NULL && hToken != (HANDLE)-1)
2166 {
2167 FIXME("unsupported for user other than current or default\n");
2168 }
2169#endif
2170
2171 if (!is_win64)
2172 {
2173 BOOL is_wow64;
2174
2175 switch (folder)
2176 {
2181 break;
2186 break;
2187 }
2188 }
2189
2190 switch (CSIDL_Data[folder].type)
2191 {
2192 case CSIDL_Type_User:
2193 strcpyW(pszPath, L"%USERPROFILE%");
2194 break;
2195#ifdef __REACTOS__
2196 case CSIDL_Type_InMyDocuments:
2197 strcpyW(pszPath, L"%USERPROFILE%");
2198 if (DoGetProductType(&ProductType) && ProductType == NtProductWinNt)
2199 {
2200 if (IS_INTRESOURCE(CSIDL_Data[CSIDL_MYDOCUMENTS].szDefaultPath))
2201 {
2202 WCHAR szItem[MAX_PATH];
2204 LOWORD(CSIDL_Data[CSIDL_MYDOCUMENTS].szDefaultPath),
2205 szItem, ARRAY_SIZE(szItem));
2206 PathAppendW(pszPath, szItem);
2207 }
2208 else
2209 {
2210 PathAppendW(pszPath, CSIDL_Data[CSIDL_MYDOCUMENTS].szDefaultPath);
2211 }
2212 }
2213 break;
2214#endif
2216#ifndef __REACTOS__
2217 strcpyW(pszPath, L"%PUBLIC%");
2218#else
2219 strcpyW(pszPath, L"%ALLUSERSPROFILE%");
2220#endif
2221 break;
2222 case CSIDL_Type_CurrVer:
2223 strcpyW(pszPath, L"%SystemDrive%");
2224 break;
2225 default:
2226 ; /* no corresponding env. var, do nothing */
2227 }
2228
2229 hr = S_OK;
2230 if (CSIDL_Data[folder].szDefaultPath)
2231 {
2232 if (IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath))
2233 {
2235 LOWORD(CSIDL_Data[folder].szDefaultPath), resourcePath, MAX_PATH))
2236 {
2237 PathAppendW(pszPath, resourcePath);
2238 }
2239 else
2240 {
2241 ERR("(%d,%s), LoadString failed, missing translation?\n", folder,
2242 debugstr_w(pszPath));
2243 hr = E_FAIL;
2244 }
2245 }
2246 else
2247 {
2248 PathAppendW(pszPath, CSIDL_Data[folder].szDefaultPath);
2249 }
2250 }
2251 TRACE("returning 0x%08x\n", hr);
2252 return hr;
2253}
2254
2255/* Gets the (unexpanded) value of the folder with index folder into pszPath.
2256 * The folder's type is assumed to be CSIDL_Type_CurrVer. Its default value
2257 * can be overridden in the HKLM\\Software\\Microsoft\\Windows\\CurrentVersion key.
2258 * If dwFlags has SHGFP_TYPE_DEFAULT set or if the value isn't overridden in
2259 * the registry, uses _SHGetDefaultValue to get the value.
2260 */
2262 LPWSTR pszPath)
2263{
2264 HRESULT hr;
2265
2266 TRACE("0x%08x,0x%02x,%p\n", dwFlags, folder, pszPath);
2267
2269 return E_INVALIDARG;
2271 return E_INVALIDARG;
2272 if (!pszPath)
2273 return E_INVALIDARG;
2274
2276#ifndef __REACTOS__
2277 hr = _SHGetDefaultValue(folder, pszPath);
2278#else
2279 hr = _SHGetDefaultValue(NULL, folder, pszPath);
2280#endif
2281 else
2282 {
2283 HKEY hKey;
2284
2285 if (RegCreateKeyW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion", &hKey))
2286 hr = E_FAIL;
2287 else
2288 {
2289 DWORD dwType, dwPathLen = MAX_PATH * sizeof(WCHAR);
2290
2291 if (RegQueryValueExW(hKey, CSIDL_Data[folder].szValueName, NULL,
2292 &dwType, (LPBYTE)pszPath, &dwPathLen) ||
2293 (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
2294 {
2295#ifndef __REACTOS__
2296 hr = _SHGetDefaultValue(folder, pszPath);
2297#else
2298 hr = _SHGetDefaultValue(NULL, folder, pszPath);
2299#endif
2300 dwType = REG_EXPAND_SZ;
2301 switch (folder)
2302 {
2305 /* these two should never be set on 32-bit setups */
2306 if (!is_win64)
2307 {
2308 BOOL is_wow64;
2310 if (!is_wow64) break;
2311 }
2312 /* fall through */
2313 default:
2314 RegSetValueExW(hKey, CSIDL_Data[folder].szValueName, 0, dwType,
2315 (LPBYTE)pszPath, (strlenW(pszPath)+1)*sizeof(WCHAR));
2316 }
2317 }
2318 else
2319 {
2320 pszPath[dwPathLen / sizeof(WCHAR)] = '\0';
2321 hr = S_OK;
2322 }
2324 }
2325 }
2326 TRACE("returning 0x%08x (output path is %s)\n", hr, debugstr_w(pszPath));
2327 return hr;
2328}
2329
2331{
2332 char InfoBuffer[64];
2333 PTOKEN_USER UserInfo;
2334 DWORD InfoSize;
2335 LPWSTR SidStr;
2336
2337 UserInfo = (PTOKEN_USER) InfoBuffer;
2338 if (! GetTokenInformation(Token, TokenUser, InfoBuffer, sizeof(InfoBuffer),
2339 &InfoSize))
2340 {
2342 return NULL;
2343 UserInfo = HeapAlloc(GetProcessHeap(), 0, InfoSize);
2344 if (UserInfo == NULL)
2345 return NULL;
2346 if (! GetTokenInformation(Token, TokenUser, UserInfo, InfoSize,
2347 &InfoSize))
2348 {
2349 HeapFree(GetProcessHeap(), 0, UserInfo);
2350 return NULL;
2351 }
2352 }
2353
2354 if (! ConvertSidToStringSidW(UserInfo->User.Sid, &SidStr))
2355 SidStr = NULL;
2356
2357 if (UserInfo != (PTOKEN_USER) InfoBuffer)
2358 HeapFree(GetProcessHeap(), 0, UserInfo);
2359
2360 return SidStr;
2361}
2362
2363/* Gets the user's path (unexpanded) for the CSIDL with index folder:
2364 * If SHGFP_TYPE_DEFAULT is set, calls _SHGetDefaultValue for it. Otherwise
2365 * calls _SHGetUserShellFolderPath for it. Where it looks depends on hToken:
2366 * - if hToken is -1, looks in HKEY_USERS\.Default
2367 * - otherwise looks first in HKEY_CURRENT_USER, followed by HKEY_LOCAL_MACHINE
2368 * if HKEY_CURRENT_USER doesn't contain any entries. If both fail, finally
2369 * calls _SHGetDefaultValue for it.
2370 */
2372 LPWSTR pszPath)
2373{
2374 const WCHAR *szValueName;
2375 WCHAR buffer[40];
2376 HRESULT hr;
2377
2378 TRACE("%p,0x%08x,0x%02x,%p\n", hToken, dwFlags, folder, pszPath);
2379
2381 return E_INVALIDARG;
2382#ifdef __REACTOS__
2384 CSIDL_Data[folder].type != CSIDL_Type_InMyDocuments)
2385#else
2387#endif
2388 {
2389 return E_INVALIDARG;
2390 }
2391 if (!pszPath)
2392 return E_INVALIDARG;
2393
2395 {
2396#ifndef __REACTOS__
2397 hr = _SHGetDefaultValue(folder, pszPath);
2398#else
2399 hr = _SHGetDefaultValue(hToken, folder, pszPath);
2400#endif
2401 }
2402 else
2403 {
2404 static const WCHAR DefaultW[] = L".Default";
2405 LPCWSTR userPrefix = NULL;
2406 HKEY hRootKey;
2407
2408 if (hToken == (HANDLE)-1)
2409 {
2410 hRootKey = HKEY_USERS;
2411 userPrefix = DefaultW;
2412 }
2413 else if (hToken == NULL)
2414 hRootKey = HKEY_CURRENT_USER;
2415 else
2416 {
2417 hRootKey = HKEY_USERS;
2418 userPrefix = _GetUserSidStringFromToken(hToken);
2419 if (userPrefix == NULL)
2420 {
2421 hr = E_FAIL;
2422 goto error;
2423 }
2424 }
2425
2426 /* For CSIDL_Type_User we also use the GUID if no szValueName is provided */
2427 szValueName = CSIDL_Data[folder].szValueName;
2428 if (!szValueName)
2429 {
2431 szValueName = &buffer[0];
2432 }
2433
2434#ifndef __REACTOS__
2435 hr = _SHGetUserShellFolderPath(hRootKey, userPrefix, szValueName, pszPath);
2436 if (FAILED(hr) && hRootKey != HKEY_LOCAL_MACHINE)
2437 hr = _SHGetUserShellFolderPath(HKEY_LOCAL_MACHINE, NULL, szValueName, pszPath);
2438 if (FAILED(hr))
2439 hr = _SHGetDefaultValue(folder, pszPath);
2440#else
2441 hr = _SHGetUserShellFolderPath(hRootKey, hToken, userPrefix, szValueName, pszPath);
2442 if (FAILED(hr) && hRootKey != HKEY_LOCAL_MACHINE)
2443 hr = _SHGetUserShellFolderPath(HKEY_LOCAL_MACHINE, hToken, NULL, szValueName, pszPath);
2444 if (FAILED(hr))
2445 hr = _SHGetDefaultValue(hToken, folder, pszPath);
2446#endif
2447 if (userPrefix != NULL && userPrefix != DefaultW)
2448 LocalFree((HLOCAL) userPrefix);
2449 }
2450error:
2451 TRACE("returning 0x%08x (output path is %s)\n", hr, debugstr_w(pszPath));
2452 return hr;
2453}
2454
2455/* Gets the (unexpanded) path for the CSIDL with index folder. If dwFlags has
2456 * SHGFP_TYPE_DEFAULT set, calls _SHGetDefaultValue. Otherwise calls
2457 * _SHGetUserShellFolderPath for it, looking only in HKEY_LOCAL_MACHINE.
2458 * If this fails, falls back to _SHGetDefaultValue.
2459 */
2461 LPWSTR pszPath)
2462{
2463 HRESULT hr;
2464
2465 TRACE("0x%08x,0x%02x,%p\n", dwFlags, folder, pszPath);
2466
2468 return E_INVALIDARG;
2470 return E_INVALIDARG;
2471 if (!pszPath)
2472 return E_INVALIDARG;
2473
2475#ifndef __REACTOS__
2476 hr = _SHGetDefaultValue(folder, pszPath);
2477#else
2478 hr = _SHGetDefaultValue(NULL, folder, pszPath);
2479#endif
2480 else
2481 {
2482#ifndef __REACTOS__
2484#else
2486#endif
2487 CSIDL_Data[folder].szValueName, pszPath);
2488 if (FAILED(hr))
2489#ifndef __REACTOS__
2490 hr = _SHGetDefaultValue(folder, pszPath);
2491#else
2492 hr = _SHGetDefaultValue(NULL, folder, pszPath);
2493#endif
2494 }
2495 TRACE("returning 0x%08x (output path is %s)\n", hr, debugstr_w(pszPath));
2496 return hr;
2497}
2498
2499#ifndef __REACTOS__
2501{
2502 LONG lRet;
2503 DWORD disp;
2504
2505 lRet = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList", 0, NULL, 0,
2506 KEY_ALL_ACCESS, NULL, pKey, &disp);
2507 return HRESULT_FROM_WIN32(lRet);
2508}
2509
2510/* Reads the value named szValueName from the key profilesKey (assumed to be
2511 * opened by _SHOpenProfilesKey) into szValue, which is assumed to be MAX_PATH
2512 * WCHARs in length. If it doesn't exist, returns szDefault (and saves
2513 * szDefault to the registry).
2514 */
2515static HRESULT _SHGetProfilesValue(HKEY profilesKey, LPCWSTR szValueName,
2516 LPWSTR szValue, LPCWSTR szDefault)
2517{
2518 HRESULT hr;
2519 DWORD type, dwPathLen = MAX_PATH * sizeof(WCHAR);
2520 LONG lRet;
2521
2522 TRACE("%p,%s,%p,%s\n", profilesKey, debugstr_w(szValueName), szValue,
2523 debugstr_w(szDefault));
2524 lRet = RegQueryValueExW(profilesKey, szValueName, NULL, &type,
2525 (LPBYTE)szValue, &dwPathLen);
2526 if (!lRet && (type == REG_SZ || type == REG_EXPAND_SZ) && dwPathLen
2527 && *szValue)
2528 {
2529 dwPathLen /= sizeof(WCHAR);
2530 szValue[dwPathLen] = '\0';
2531 hr = S_OK;
2532 }
2533 else
2534 {
2535 /* Missing or invalid value, set a default */
2536 lstrcpynW(szValue, szDefault, MAX_PATH);
2537 TRACE("Setting missing value %s to %s\n", debugstr_w(szValueName),
2538 debugstr_w(szValue));
2539 lRet = RegSetValueExW(profilesKey, szValueName, 0, REG_EXPAND_SZ,
2540 (LPBYTE)szValue,
2541 (strlenW(szValue) + 1) * sizeof(WCHAR));
2542 if (lRet)
2543 hr = HRESULT_FROM_WIN32(lRet);
2544 else
2545 hr = S_OK;
2546 }
2547 TRACE("returning 0x%08x (output value is %s)\n", hr, debugstr_w(szValue));
2548 return hr;
2549}
2550#endif
2551
2552/* Attempts to expand environment variables from szSrc into szDest, which is
2553 * assumed to be MAX_PATH characters in length. Before referring to the
2554 * environment, handles a few variables directly, because the environment
2555 * variables may not be set when this is called (as during Wine's installation
2556 * when default values are being written to the registry).
2557 * The directly handled environment variables, and their source, are:
2558 * - ALLUSERSPROFILE, USERPROFILE: reads from the registry
2559 * - SystemDrive: uses GetSystemDirectoryW and uses the drive portion of its
2560 * path
2561 * If one of the directly handled environment variables is expanded, only
2562 * expands a single variable, and only in the beginning of szSrc.
2563 */
2564#ifndef __REACTOS__
2566#else
2568#endif
2569{
2570 HRESULT hr;
2571#ifndef __REACTOS__
2572 WCHAR szTemp[MAX_PATH], szProfilesPrefix[MAX_PATH] = { 0 };
2573 HKEY key = NULL;
2574#else
2575 WCHAR szTemp[MAX_PATH];
2576#endif
2577
2578 TRACE("%s, %p\n", debugstr_w(szSrc), szDest);
2579
2580 if (!szSrc || !szDest) return E_INVALIDARG;
2581
2582 /* short-circuit if there's nothing to expand */
2583 if (szSrc[0] != '%')
2584 {
2585 strcpyW(szDest, szSrc);
2586 hr = S_OK;
2587 goto end;
2588 }
2589#ifndef __REACTOS__
2590 /* Get the profile prefix, we'll probably be needing it */
2592 if (SUCCEEDED(hr))
2593 {
2594 WCHAR def_val[MAX_PATH];
2595
2596 /* get the system drive */
2597 GetSystemDirectoryW(def_val, MAX_PATH);
2598 strcpyW( def_val + 3, L"Users" );
2599
2600 hr = _SHGetProfilesValue(key, L"ProfilesDirectory", szProfilesPrefix, def_val );
2601 }
2602#else
2603 hr = S_OK;
2604#endif
2605
2606 *szDest = 0;
2607 strcpyW(szTemp, szSrc);
2608 while (SUCCEEDED(hr) && szTemp[0] == '%')
2609 {
2610 if (!strncmpiW(szTemp, L"%ALLUSERSPROFILE%", ARRAY_SIZE(L"%ALLUSERSPROFILE%")-1))
2611 {
2612#ifndef __REACTOS__
2613 WCHAR szAllUsers[MAX_PATH];
2614
2615 strcpyW(szDest, szProfilesPrefix);
2616 hr = _SHGetProfilesValue(key, L"AllUsersProfile", szAllUsers, L"Public");
2617 PathAppendW(szDest, szAllUsers);
2618#else
2619 DWORD cchSize = cchDest;
2620 if (!GetAllUsersProfileDirectoryW(szDest, &cchSize))
2621 goto fallback_expand;
2622#endif
2623 PathAppendW(szDest, szTemp + ARRAY_SIZE(L"%ALLUSERSPROFILE%")-1);
2624 }
2625#ifndef __REACTOS__
2626 else if (!strncmpiW(szTemp, L"%PUBLIC%", ARRAY_SIZE(L"%PUBLIC%")-1))
2627 {
2628 WCHAR szAllUsers[MAX_PATH], def_val[MAX_PATH];
2629
2630 GetSystemDirectoryW(def_val, MAX_PATH);
2631 strcpyW( def_val + 3, L"Users\\Public" );
2632
2633 hr = _SHGetProfilesValue(key, L"Public", szAllUsers, def_val);
2634 PathAppendW(szDest, szAllUsers);
2635 PathAppendW(szDest, szTemp + ARRAY_SIZE(L"%PUBLIC%")-1);
2636 }
2637#endif
2638 else if (!strncmpiW(szTemp, L"%USERPROFILE%", ARRAY_SIZE(L"%USERPROFILE%")-1))
2639 {
2640#ifndef __REACTOS__
2642 DWORD userLen = MAX_PATH;
2643
2644 strcpyW(szDest, szProfilesPrefix);
2645 GetUserNameW(userName, &userLen);
2646 PathAppendW(szDest, userName);
2647#else
2648 DWORD cchSize = cchDest;
2649 if (!_SHGetUserProfileDirectoryW(hToken, szDest, &cchSize))
2650 goto fallback_expand;
2651#endif
2652 PathAppendW(szDest, szTemp + ARRAY_SIZE(L"%USERPROFILE%")-1);
2653 }
2654 else if (!strncmpiW(szTemp, L"%SystemDrive%", ARRAY_SIZE(L"%SystemDrive%")-1))
2655 {
2656#ifndef __REACTOS__
2658#else
2659 if (!GetSystemDirectoryW(szDest, cchDest))
2660 goto fallback_expand;
2661#endif
2662 strcpyW(szDest + 3, szTemp + ARRAY_SIZE(L"%SystemDrive%")-1 + 1);
2663 }
2664 else
2665#ifdef __REACTOS__
2666fallback_expand:
2667#endif
2668 {
2669#ifndef __REACTOS__
2670 DWORD ret = ExpandEnvironmentStringsW(szTemp, szDest, MAX_PATH);
2671#else
2672 DWORD ret = SHExpandEnvironmentStringsForUserW(hToken, szTemp, szDest, cchDest);
2673#endif
2674
2675#ifndef __REACTOS__
2676 if (ret > MAX_PATH)
2677#else
2678 if (ret > cchDest)
2679#endif
2681 else if (ret == 0)
2683 else if (!strcmpW( szTemp, szDest )) break; /* nothing expanded */
2684 }
2685 if (SUCCEEDED(hr)) strcpyW(szTemp, szDest);
2686 }
2687end:
2688#ifndef __REACTOS__
2689 if (key)
2691#endif
2692 TRACE("returning 0x%08x (input was %s, output is %s)\n", hr,
2693 debugstr_w(szSrc), debugstr_w(szDest));
2694 return hr;
2695}
2696
2697/*************************************************************************
2698 * SHGetFolderPathW [SHELL32.@]
2699 *
2700 * Convert nFolder to path.
2701 *
2702 * RETURNS
2703 * Success: S_OK
2704 * Failure: standard HRESULT error codes.
2705 *
2706 * NOTES
2707 * Most values can be overridden in either
2708 * HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
2709 * or in the same location in HKLM.
2710 * The "Shell Folders" registry key was used in NT4 and earlier systems.
2711 * Beginning with Windows 2000, the "User Shell Folders" key is used, so
2712 * changes made to it are made to the former key too. This synchronization is
2713 * done on-demand: not until someone requests the value of one of these paths
2714 * (by calling one of the SHGet functions) is the value synchronized.
2715 * Furthermore, the HKCU paths take precedence over the HKLM paths.
2716 */
2718 HWND hwndOwner, /* [I] owner window */
2719 int nFolder, /* [I] CSIDL identifying the folder */
2720 HANDLE hToken, /* [I] access token */
2721 DWORD dwFlags, /* [I] which path to return */
2722 LPWSTR pszPath) /* [O] converted path */
2723{
2724 HRESULT hr = SHGetFolderPathAndSubDirW(hwndOwner, nFolder, hToken, dwFlags, NULL, pszPath);
2727 return hr;
2728}
2729
2731 HWND hwndOwner, /* [I] owner window */
2732 int nFolder, /* [I] CSIDL identifying the folder */
2733 HANDLE hToken, /* [I] access token */
2734 DWORD dwFlags, /* [I] which path to return */
2735 LPCSTR pszSubPath, /* [I] sub directory of the specified folder */
2736 LPSTR pszPath) /* [O] converted path */
2737{
2738 int length;
2739 HRESULT hr = S_OK;
2740 LPWSTR pszSubPathW = NULL;
2741 LPWSTR pszPathW = NULL;
2742
2743 TRACE("%p,%#x,%p,%#x,%s,%p\n", hwndOwner, nFolder, hToken, dwFlags, debugstr_a(pszSubPath), pszPath);
2744
2745 if(pszPath) {
2746 pszPathW = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
2747 if(!pszPathW) {
2749 goto cleanup;
2750 }
2751 }
2752 TRACE("%08x,%08x,%s\n",nFolder, dwFlags, debugstr_w(pszSubPathW));
2753
2754 /* SHGetFolderPathAndSubDirW does not distinguish if pszSubPath isn't
2755 * set (null), or an empty string.therefore call it without the parameter set
2756 * if pszSubPath is an empty string
2757 */
2758 if (pszSubPath && pszSubPath[0]) {
2759 length = MultiByteToWideChar(CP_ACP, 0, pszSubPath, -1, NULL, 0);
2760 pszSubPathW = HeapAlloc(GetProcessHeap(), 0, length * sizeof(WCHAR));
2761 if(!pszSubPathW) {
2763 goto cleanup;
2764 }
2765 MultiByteToWideChar(CP_ACP, 0, pszSubPath, -1, pszSubPathW, length);
2766 }
2767
2768 hr = SHGetFolderPathAndSubDirW(hwndOwner, nFolder, hToken, dwFlags, pszSubPathW, pszPathW);
2769
2770 if (SUCCEEDED(hr) && pszPath)
2771 WideCharToMultiByte(CP_ACP, 0, pszPathW, -1, pszPath, MAX_PATH, NULL, NULL);
2772
2773cleanup:
2774 HeapFree(GetProcessHeap(), 0, pszPathW);
2775 HeapFree(GetProcessHeap(), 0, pszSubPathW);
2776 return hr;
2777}
2778
2779/*************************************************************************
2780 * SHGetFolderPathAndSubDirW [SHELL32.@]
2781 */
2783 HWND hwndOwner, /* [I] owner window */
2784 int nFolder, /* [I] CSIDL identifying the folder */
2785 HANDLE hToken, /* [I] access token */
2786 DWORD dwFlags, /* [I] which path to return */
2787 LPCWSTR pszSubPath,/* [I] sub directory of the specified folder */
2788 LPWSTR pszPath) /* [O] converted path */
2789{
2790 HRESULT hr;
2791 WCHAR szBuildPath[MAX_PATH], szTemp[MAX_PATH];
2794 int ret;
2795
2796 TRACE("%p,%#x,%p,%#x,%s,%p\n", hwndOwner, nFolder, hToken, dwFlags, debugstr_w(pszSubPath), pszPath);
2797
2798 /* Windows always NULL-terminates the resulting path regardless of success
2799 * or failure, so do so first
2800 */
2801 if (pszPath)
2802 *pszPath = '\0';
2803
2805 return E_INVALIDARG;
2807 return E_INVALIDARG;
2808 szTemp[0] = 0;
2810 switch (type)
2811 {
2813 hr = E_INVALIDARG;
2814 break;
2816 hr = S_FALSE;
2817 break;
2820 if (CSIDL_Data[folder].szDefaultPath &&
2821 !IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath) &&
2822 *CSIDL_Data[folder].szDefaultPath)
2823 {
2824 PathAddBackslashW(szTemp);
2825 strcatW(szTemp, CSIDL_Data[folder].szDefaultPath);
2826 }
2827 hr = S_OK;
2828 break;
2831 if (CSIDL_Data[folder].szDefaultPath &&
2832 !IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath) &&
2833 *CSIDL_Data[folder].szDefaultPath)
2834 {
2835 PathAddBackslashW(szTemp);
2836 strcatW(szTemp, CSIDL_Data[folder].szDefaultPath);
2837 }
2838 hr = S_OK;
2839 break;
2842 if (CSIDL_Data[folder].szDefaultPath &&
2843 !IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath) &&
2844 *CSIDL_Data[folder].szDefaultPath)
2845 {
2846 PathAddBackslashW(szTemp);
2847 strcatW(szTemp, CSIDL_Data[folder].szDefaultPath);
2848 }
2849 hr = S_OK;
2850 break;
2851 case CSIDL_Type_CurrVer:
2853 break;
2854 case CSIDL_Type_User:
2855#ifdef __REACTOS__
2856 case CSIDL_Type_InMyDocuments:
2857#endif
2858 hr = _SHGetUserProfilePath(hToken, dwFlags, folder, szTemp);
2859 break;
2862 break;
2863 default:
2864 FIXME("bogus type %d, please fix\n", type);
2865 hr = E_INVALIDARG;
2866 break;
2867 }
2868
2869 /* Expand environment strings if necessary */
2870 if (*szTemp == '%')
2871#ifndef __REACTOS__
2872 hr = _SHExpandEnvironmentStrings(szTemp, szBuildPath);
2873#else
2874 hr = _SHExpandEnvironmentStrings(hToken, szTemp, szBuildPath, _countof(szBuildPath));
2875#endif
2876 else
2877 strcpyW(szBuildPath, szTemp);
2878
2879 if (FAILED(hr)) goto end;
2880
2881 if(pszSubPath) {
2882 /* make sure the new path does not exceed the buffer length
2883 * and remember to backslash and terminate it */
2884 if(MAX_PATH < (lstrlenW(szBuildPath) + lstrlenW(pszSubPath) + 2)) {
2886 goto end;
2887 }
2888 PathAppendW(szBuildPath, pszSubPath);
2889 PathRemoveBackslashW(szBuildPath);
2890 }
2891 /* Copy the path if it's available before we might return */
2892 if (SUCCEEDED(hr) && pszPath)
2893 strcpyW(pszPath, szBuildPath);
2894
2895 /* if we don't care about existing directories we are ready */
2897
2898 if (PathFileExistsW(szBuildPath)) goto end;
2899
2900 /* not existing but we are not allowed to create it. The return value
2901 * is verified against shell32 version 6.0.
2902 */
2903 if (!(nFolder & CSIDL_FLAG_CREATE))
2904 {
2906 goto end;
2907 }
2908
2909 /* create directory/directories */
2910 ret = SHCreateDirectoryExW(hwndOwner, szBuildPath, NULL);
2911 if (ret && ret != ERROR_ALREADY_EXISTS)
2912 {
2913 ERR("Failed to create directory %s.\n", debugstr_w(szBuildPath));
2914 hr = E_FAIL;
2915 goto end;
2916 }
2917
2918 TRACE("Created missing system directory %s\n", debugstr_w(szBuildPath));
2919
2920end:
2921#ifdef __REACTOS__
2922 /* create desktop.ini for custom icon */
2923 if ((nFolder & CSIDL_FLAG_CREATE) &&
2924 CSIDL_Data[folder].nShell32IconIndex)
2925 {
2926 WCHAR szIconLocation[MAX_PATH];
2928
2929 /* make the directory a read-only folder */
2930 dwAttributes = GetFileAttributesW(szBuildPath);
2932 SetFileAttributesW(szBuildPath, dwAttributes);
2933
2934 /* build the desktop.ini file path */
2935 PathAppendW(szBuildPath, L"desktop.ini");
2936
2937 /* build the icon location */
2938 StringCchPrintfW(szIconLocation, _countof(szIconLocation),
2939 L"%%SystemRoot%%\\system32\\shell32.dll,%d",
2940 CSIDL_Data[folder].nShell32IconIndex);
2941
2942 /* write desktop.ini */
2943 WritePrivateProfileStringW(L".ShellClassInfo", L"IconResource", szIconLocation, szBuildPath);
2944
2945 /* flush! */
2946 WritePrivateProfileStringW(NULL, NULL, NULL, szBuildPath);
2947
2948 /* make the desktop.ini a system and hidden file */
2949 dwAttributes = GetFileAttributesW(szBuildPath);
2951 SetFileAttributesW(szBuildPath, dwAttributes);
2952 }
2953#endif
2954
2955 TRACE("returning 0x%08x (final path is %s)\n", hr, debugstr_w(szBuildPath));
2956 return hr;
2957}
2958
2959/*************************************************************************
2960 * SHGetFolderPathA [SHELL32.@]
2961 *
2962 * See SHGetFolderPathW.
2963 */
2965 HWND hwndOwner,
2966 int nFolder,
2967 HANDLE hToken,
2968 DWORD dwFlags,
2969 LPSTR pszPath)
2970{
2971 WCHAR szTemp[MAX_PATH];
2972 HRESULT hr;
2973
2974 TRACE("%p,%d,%p,%#x,%p\n", hwndOwner, nFolder, hToken, dwFlags, pszPath);
2975
2976 if (pszPath)
2977 *pszPath = '\0';
2978 hr = SHGetFolderPathW(hwndOwner, nFolder, hToken, dwFlags, szTemp);
2979 if (SUCCEEDED(hr) && pszPath)
2980 WideCharToMultiByte(CP_ACP, 0, szTemp, -1, pszPath, MAX_PATH, NULL,
2981 NULL);
2982
2983 return hr;
2984}
2985
2986/* For each folder in folders, if its value has not been set in the registry,
2987 * calls _SHGetUserProfilePath or _SHGetAllUsersProfilePath (depending on the
2988 * folder's type) to get the unexpanded value first.
2989 * Writes the unexpanded value to User Shell Folders, and queries it with
2990 * SHGetFolderPathW to force the creation of the directory if it doesn't
2991 * already exist. SHGetFolderPathW also returns the expanded value, which
2992 * this then writes to Shell Folders.
2993 */
2994static HRESULT _SHRegisterFolders(HKEY hRootKey, HANDLE hToken,
2995 LPCWSTR szUserShellFolderPath, LPCWSTR szShellFolderPath, const UINT folders[],
2996 UINT foldersLen)
2997{
2998 const WCHAR *szValueName;
2999 WCHAR buffer[40];
3000 UINT i;
3002 HRESULT hr = S_OK;
3003 HKEY hUserKey = NULL, hKey = NULL;
3004 DWORD dwType, dwPathLen;
3005 LONG ret;
3006
3007 TRACE("%p,%p,%s,%p,%u\n", hRootKey, hToken,
3008 debugstr_w(szUserShellFolderPath), folders, foldersLen);
3009
3010 ret = RegCreateKeyW(hRootKey, szUserShellFolderPath, &hUserKey);
3011 if (ret)
3013 else
3014 {
3015 ret = RegCreateKeyW(hRootKey, szShellFolderPath, &hKey);
3016 if (ret)
3018 }
3019 for (i = 0; SUCCEEDED(hr) && i < foldersLen; i++)
3020 {
3021 dwPathLen = MAX_PATH * sizeof(WCHAR);
3022
3023 /* For CSIDL_Type_User we also use the GUID if no szValueName is provided */
3024 szValueName = CSIDL_Data[folders[i]].szValueName;
3025#ifdef __REACTOS__
3026 if (!szValueName &&
3027 (CSIDL_Data[folders[i]].type == CSIDL_Type_User ||
3028 CSIDL_Data[folders[i]].type == CSIDL_Type_InMyDocuments))
3029#else
3030 if (!szValueName && CSIDL_Data[folders[i]].type == CSIDL_Type_User)
3031#endif
3032 {
3033 StringFromGUID2( CSIDL_Data[folders[i]].id, buffer, 39 );
3034 szValueName = &buffer[0];
3035 }
3036
3037 if (!RegQueryValueExW(hUserKey, szValueName, NULL,
3038 &dwType, (LPBYTE)path, &dwPathLen) &&
3039 (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
3040 {
3042 hToken, SHGFP_TYPE_CURRENT, path);
3043 }
3044 else
3045 {
3046 *path = '\0';
3047#ifdef __REACTOS__
3048 if (CSIDL_Data[folders[i]].type == CSIDL_Type_User ||
3049 CSIDL_Data[folders[i]].type == CSIDL_Type_InMyDocuments)
3050#else
3051 if (CSIDL_Data[folders[i]].type == CSIDL_Type_User)
3052#endif
3053 _SHGetUserProfilePath(hToken, SHGFP_TYPE_CURRENT, folders[i],
3054 path);
3055 else if (CSIDL_Data[folders[i]].type == CSIDL_Type_AllUsers)
3057 else if (CSIDL_Data[folders[i]].type == CSIDL_Type_WindowsPath)
3058 {
3060 if (CSIDL_Data[folders[i]].szDefaultPath &&
3061 !IS_INTRESOURCE(CSIDL_Data[folders[i]].szDefaultPath))
3062 {
3064 strcatW(path, CSIDL_Data[folders[i]].szDefaultPath);
3065 }
3066 }
3067 else
3068 hr = E_FAIL;
3069 if (*path)
3070 {
3071 ret = RegSetValueExW(hUserKey, szValueName, 0, REG_EXPAND_SZ,
3072 (LPBYTE)path, (strlenW(path) + 1) * sizeof(WCHAR));
3073 if (ret)
3075 else
3076 {
3078 hToken, SHGFP_TYPE_CURRENT, path);
3079 ret = RegSetValueExW(hKey, szValueName, 0, REG_SZ,
3080 (LPBYTE)path, (strlenW(path) + 1) * sizeof(WCHAR));
3081 if (ret)
3083 }
3084 }
3085 }
3086 }
3087 if (hUserKey)
3088 RegCloseKey(hUserKey);
3089 if (hKey)
3091
3092 TRACE("returning 0x%08x\n", hr);
3093 return hr;
3094}
3095
3097{
3098 static const UINT folders[] = {
3120/* Cannot use #if _WIN32_WINNT >= 0x0600 because _WIN32_WINNT == 0x0600 here. */
3121#ifndef __REACTOS__
3128#endif
3129 };
3130 WCHAR userShellFolderPath[MAX_PATH], shellFolderPath[MAX_PATH];
3131 LPCWSTR pUserShellFolderPath, pShellFolderPath;
3132 HRESULT hr = S_OK;
3133 HKEY hRootKey;
3134 HANDLE hToken;
3135
3136 TRACE("%s\n", bDefault ? "TRUE" : "FALSE");
3137 if (bDefault)
3138 {
3139 hToken = (HANDLE)-1;
3140 hRootKey = HKEY_USERS;
3141 strcpyW(userShellFolderPath, L".Default");
3142 PathAddBackslashW(userShellFolderPath);
3143 strcatW(userShellFolderPath, szSHUserFolders);
3144 pUserShellFolderPath = userShellFolderPath;
3145 strcpyW(shellFolderPath, L".Default");
3146 PathAddBackslashW(shellFolderPath);
3147 strcatW(shellFolderPath, szSHFolders);
3148 pShellFolderPath = shellFolderPath;
3149 }
3150 else
3151 {
3152 hToken = NULL;
3153 hRootKey = HKEY_CURRENT_USER;
3154 pUserShellFolderPath = szSHUserFolders;
3155 pShellFolderPath = szSHFolders;
3156 }
3157
3158 hr = _SHRegisterFolders(hRootKey, hToken, pUserShellFolderPath,
3159 pShellFolderPath, folders, ARRAY_SIZE(folders));
3160 TRACE("returning 0x%08x\n", hr);
3161 return hr;
3162}
3163
3165{
3166 static const UINT folders[] = {
3179 };
3180 HRESULT hr;
3181
3182 TRACE("\n");
3184 szSHFolders, folders, ARRAY_SIZE(folders));
3185 TRACE("returning 0x%08x\n", hr);
3186 return hr;
3187}
3188
3189/* Register the default values in the registry, as some apps seem to depend
3190 * on their presence. The set registered was taken from Windows XP.
3191 */
3193{
3194 HRESULT hr;
3195
3197 if (SUCCEEDED(hr))
3199 if (SUCCEEDED(hr))
3201 return hr;
3202}
3203
3204/*************************************************************************
3205 * SHGetSpecialFolderPathA [SHELL32.@]
3206 */
3208 HWND hwndOwner,
3209 LPSTR szPath,
3210 int nFolder,
3211 BOOL bCreate)
3212{
3213 return SHGetFolderPathA(hwndOwner, nFolder + (bCreate ? CSIDL_FLAG_CREATE : 0), NULL, 0,
3214 szPath) == S_OK;
3215}
3216
3217/*************************************************************************
3218 * SHGetSpecialFolderPathW
3219 */
3221 HWND hwndOwner,
3222 LPWSTR szPath,
3223 int nFolder,
3224 BOOL bCreate)
3225{
3226 return SHGetFolderPathW(hwndOwner, nFolder + (bCreate ? CSIDL_FLAG_CREATE : 0), NULL, 0,
3227 szPath) == S_OK;
3228}
3229
3230#ifdef __REACTOS__
3231HRESULT SHGetFolderLocationHelper(HWND hwnd, int nFolder, REFCLSID clsid, LPITEMIDLIST *ppidl)
3232{
3233 HRESULT hr;
3234 IShellFolder *psf;
3236 SHSTDAPI SHBindToObject(IShellFolder *psf, LPCITEMIDLIST pidl, IBindCtx *pBindCtx, REFIID riid, void **ppvObj);
3237 *ppidl = NULL;
3239 return hr;
3240 if (SUCCEEDED(hr = SHBindToObject(NULL, parent, NULL, &IID_IShellFolder, (void**)&psf)))
3241 {
3242 WCHAR clsidstr[2 + 38 + 1];
3243 clsidstr[0] = clsidstr[1] = L':';
3244 StringFromGUID2(clsid, clsidstr + 2, 38 + 1);
3245 hr = IShellFolder_ParseDisplayName(psf, hwnd, NULL, clsidstr, NULL, &child, NULL);
3246 if (SUCCEEDED(hr))
3247 *ppidl = ILCombine(parent, child);
3248 IShellFolder_Release(psf);
3249 ILFree(child);
3250 }
3251 ILFree(parent);
3252 return hr;
3253}
3254#endif
3255
3256/*************************************************************************
3257 * SHGetFolderLocation [SHELL32.@]
3258 *
3259 * Gets the folder locations from the registry and creates a pidl.
3260 *
3261 * PARAMS
3262 * hwndOwner [I]
3263 * nFolder [I] CSIDL_xxxxx
3264 * hToken [I] token representing user, or NULL for current user, or -1 for
3265 * default user
3266 * dwReserved [I] must be zero
3267 * ppidl [O] PIDL of a special folder
3268 *
3269 * RETURNS
3270 * Success: S_OK
3271 * Failure: Standard OLE-defined error result, S_FALSE or E_INVALIDARG
3272 *
3273 * NOTES
3274 * Creates missing reg keys and directories.
3275 * Mostly forwards to SHGetFolderPathW, but a few values of nFolder return
3276 * virtual folders that are handled here.
3277 */
3279 HWND hwndOwner,
3280 int nFolder,
3281 HANDLE hToken,
3283 LPITEMIDLIST *ppidl)
3284{
3286#ifdef __REACTOS__
3288#endif
3289
3290 TRACE("%p 0x%08x %p 0x%08x %p\n",
3291 hwndOwner, nFolder, hToken, dwReserved, ppidl);
3292
3293 if (!ppidl)
3294 return E_INVALIDARG;
3295 if (dwReserved)
3296 return E_INVALIDARG;
3297
3298#ifdef __REACTOS__
3299 if ((nFolder & CSIDL_FLAG_NO_ALIAS) &&
3301 {
3302 *ppidl = ILCreateFromPathW(szPath);
3303 if (*ppidl)
3304 return S_OK;
3305 }
3306#endif
3307 /* The virtual folders' locations are not user-dependent */
3308 *ppidl = NULL;
3309 switch (nFolder & CSIDL_FOLDER_MASK)
3310 {
3311 case CSIDL_DESKTOP:
3312 *ppidl = _ILCreateDesktop();
3313 break;
3314
3315 case CSIDL_PERSONAL:
3316 *ppidl = _ILCreateMyDocuments();
3317 break;
3318
3319 case CSIDL_INTERNET:
3320 *ppidl = _ILCreateIExplore();
3321 break;
3322
3323 case CSIDL_CONTROLS:
3324 *ppidl = _ILCreateControlPanel();
3325 break;
3326
3327 case CSIDL_PRINTERS:
3328 *ppidl = _ILCreatePrinters();
3329 break;
3330
3331 case CSIDL_BITBUCKET:
3332 *ppidl = _ILCreateBitBucket();
3333 break;
3334
3335 case CSIDL_DRIVES:
3336 *ppidl = _ILCreateMyComputer();
3337 break;
3338
3339 case CSIDL_NETWORK:
3340 *ppidl = _ILCreateNetwork();
3341 break;
3342
3343#ifdef __REACTOS__
3344 case CSIDL_CONNECTIONS:
3345 hr = SHGetFolderLocationHelper(hwndOwner, CSIDL_CONTROLS, &CLSID_NetworkConnections, ppidl);
3346 break;
3347#endif
3348
3349 default:
3350 {
3352
3353 hr = SHGetFolderPathW(hwndOwner, nFolder, hToken,
3355 if (SUCCEEDED(hr))
3356 {
3357 DWORD attributes=0;
3358
3359 TRACE("Value=%s\n", debugstr_w(szPath));
3361 }
3363 {
3364 /* unlike SHGetFolderPath, SHGetFolderLocation in shell32
3365 * version 6.0 returns E_FAIL for nonexistent paths
3366 */
3367 hr = E_FAIL;
3368 }
3369 }
3370 }
3371 if(*ppidl)
3372 hr = S_OK;
3373
3374 TRACE("-- (new pidl %p)\n",*ppidl);
3375 return hr;
3376}
3377
3378/*************************************************************************
3379 * SHGetSpecialFolderLocation [SHELL32.@]
3380 *
3381 * NOTES
3382 * In NT5, SHGetSpecialFolderLocation needs the <winntdir>/Recent
3383 * directory.
3384 */
3386 HWND hwndOwner,
3387 INT nFolder,
3388 LPITEMIDLIST * ppidl)
3389{
3391
3392 TRACE("(%p,0x%x,%p)\n", hwndOwner,nFolder,ppidl);
3393
3394 if (!ppidl)
3395 return E_INVALIDARG;
3396
3397 hr = SHGetFolderLocation(hwndOwner, nFolder, NULL, 0, ppidl);
3398 return hr;
3399}
#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
#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
PCWSTR pszTemplate
Definition: reactos.c:3596
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
#define IDS_PROGRAMS
Definition: resource.h:69
#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
HRESULT hr
Definition: delayimp.cpp:582
#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
INT WINAPI StringFromGUID2(REFGUID guid, LPOLESTR str, INT cmax)
Definition: combase.c:1525
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:492
UINT WINAPI GetDriveTypeW(IN LPCWSTR lpRootPathName)
Definition: disk.c:497
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:636
BOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:778
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
UINT WINAPI GetSystemWow64DirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2340
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2232
DWORD WINAPI GetShortPathNameW(IN LPCWSTR lpszLongPath, OUT LPWSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1752
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2271
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:4152
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4171
int WINAPI lstrcmpiA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4133
#define IS_INTRESOURCE(x)
Definition: loader.c:613
BOOL WINAPI PathIsRootA(const char *path)
Definition: path.c:1064
void WINAPI PathRemoveExtensionW(WCHAR *path)
Definition: path.c:1922
BOOL WINAPI PathIsUNCW(const WCHAR *path)
Definition: path.c:989
LPSTR WINAPI PathFindExtensionA(const char *path)
Definition: path.c:1229
void WINAPI PathUnquoteSpacesW(WCHAR *path)
Definition: path.c:1982
int WINAPI PathGetDriveNumberW(const WCHAR *path)
Definition: path.c:1786
BOOL WINAPI PathRemoveFileSpecA(char *path)
Definition: path.c:1084
WCHAR *WINAPI PathRemoveBackslashW(WCHAR *path)
Definition: path.c:2016
BOOL WINAPI PathFileExistsA(const char *path)
Definition: path.c:2566
UINT WINAPI PathGetCharTypeA(UCHAR ch)
Definition: path.c:1769
BOOL WINAPI PathRemoveFileSpecW(WCHAR *path)
Definition: path.c:1121
LPWSTR WINAPI PathFindExtensionW(const WCHAR *path)
Definition: path.c:1250
BOOL WINAPI PathStripToRootW(WCHAR *path)
Definition: path.c:1171
BOOL WINAPI PathIsURLW(const WCHAR *path)
Definition: path.c:3214
BOOL WINAPI PathIsValidCharW(WCHAR c, DWORD class)
Definition: path.c:2197
UINT WINAPI PathGetCharTypeW(WCHAR ch)
Definition: path.c:1738
BOOL WINAPI PathFileExistsW(const WCHAR *path)
Definition: path.c:2583
BOOL WINAPI PathIsFileSpecW(const WCHAR *path)
Definition: path.c:1818
BOOL WINAPI PathIsRootW(const WCHAR *path)
Definition: path.c:1077
LPWSTR WINAPI CharPrevW(const WCHAR *start, const WCHAR *x)
Definition: string.c:1194
WCHAR *WINAPI StrCpyNW(WCHAR *dst, const WCHAR *src, int count)
Definition: string.c:470
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1597
DWORD WINAPI SHAnsiToUnicode(const char *src, WCHAR *dest, int dest_len)
Definition: main.c:1801
DWORD WINAPI SHUnicodeToAnsi(const WCHAR *src, char *dest, int dest_len)
Definition: main.c:1756
SHSTDAPI SHBindToObject(_In_opt_ IShellFolder *psf, _In_ LPCITEMIDLIST pidl, _In_opt_ IBindCtx *pBindCtx, _In_ REFIID riid, _Out_ void **ppvObj)
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:370
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:348
#define CSIDL_LINKS
Definition: shellpath.c:1211
static LPWSTR PathGetExtensionW(LPCWSTR lpszPath)
Definition: shellpath.c:434
#define CSIDL_APPDATA_LOCALLOW
Definition: shellpath.c:1212
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:3192
static const WCHAR szKnownFolderRedirections[]
Definition: shellpath.c:1189
HRESULT WINAPI SHGetSpecialFolderLocation(HWND hwndOwner, INT nFolder, LPITEMIDLIST *ppidl)
Definition: shellpath.c:3385
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:1210
HRESULT WINAPI SHGetFolderLocation(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwReserved, LPITEMIDLIST *ppidl)
Definition: shellpath.c:3278
#define VALID_SHORT_PATH_CHAR_CLASSES
HRESULT WINAPI SHGetFolderPathW(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath)
Definition: shellpath.c:2717
static const WCHAR Local_Settings_HistoryW[]
Definition: shellpath.c:1173
static HRESULT _SHGetCurrentVersionPath(DWORD dwFlags, BYTE folder, LPWSTR pszPath)
Definition: shellpath.c:2261
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:3096
BOOL WINAPI PathAppendAW(LPVOID lpszPath1, LPCVOID lpszPath2)
Definition: shellpath.c:407
static HRESULT _SHExpandEnvironmentStrings(LPCWSTR szSrc, LPWSTR szDest)
Definition: shellpath.c:2565
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:1214
_CSIDL_Type
Definition: shellpath.c:1192
@ CSIDL_Type_CurrVer
Definition: shellpath.c:1198
@ CSIDL_Type_ProgramData
Definition: shellpath.c:1204
@ 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:2782
static HRESULT _SHOpenProfilesKey(PHKEY pKey)
Definition: shellpath.c:2500
#define CSIDL_SAVED_GAMES
Definition: shellpath.c:1213
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:2460
HRESULT WINAPI SHGetFolderPathAndSubDirA(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPCSTR pszSubPath, LPSTR pszPath)
Definition: shellpath.c:2730
INT Shell_ParseSpecialFolder(_In_ LPCWSTR pszStart, _Out_ LPWSTR *ppch, _Out_ INT *pcch)
Definition: shellpath.c:1987
static HRESULT _SHGetDefaultValue(BYTE folder, LPWSTR pszPath)
Definition: shellpath.c:2145
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:1973
static HRESULT _SHGetProfilesValue(HKEY profilesKey, LPCWSTR szValueName, LPWSTR szValue, LPCWSTR szDefault)
Definition: shellpath.c:2515
static const CSIDL_DATA CSIDL_Data[]
Definition: shellpath.c:1226
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:2109
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:3164
static LPWSTR _GetUserSidStringFromToken(HANDLE Token)
Definition: shellpath.c:2330
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:2994
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:2371
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:3207
HRESULT WINAPI SHGetFolderPathA(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPSTR pszPath)
Definition: shellpath.c:2964
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:3220
BOOL PathIsExeW(LPCWSTR lpszPath)
Definition: shellpath.c:539
static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, LPCWSTR userPrefix, LPCWSTR value, LPWSTR path)
Definition: shellpath.c:2026
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:1209
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:3976
BOOL WINAPI PathFindOnPathW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs)
Definition: path.c:456
LPWSTR WINAPI PathBuildRootW(LPWSTR lpszPath, int drive)
Definition: path.c:105
BOOL WINAPI PathFindOnPathExW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs, DWORD dwWhich)
Definition: path.c:404
BOOL WINAPI PathFileExistsAndAttributesW(LPCWSTR lpszPath, DWORD *dwAttr)
Definition: path.c:747
BOOL WINAPI PathFileExistsDefExtW(LPWSTR lpszPath, DWORD dwWhich)
Definition: path.c:170
#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
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
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
unsigned int UINT
Definition: sysinfo.c:13
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:35
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
BOOL is_wow64
Definition: main.c:38
#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 ZeroMemory
Definition: minwinbase.h:31
CONST void * LPCVOID
Definition: minwindef.h:164
#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 const WCHAR pathW[]
Definition: path.c:2368
static HWND child
Definition: cursoricon.c:298
static const WCHAR path1[]
Definition: path.c:28
#define min(a, b)
Definition: monoChain.cc:55
const CLSID * clsid
Definition: msctf.cpp:50
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:95
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#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:1044
#define KEY_READ
Definition: nt_native.h:1026
#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:1497
#define UNICODE_NULL
static HANDLE ACCESS_MASK ULONG attributes
Definition: om.c:94
DWORD WINAPI GetShortPathNameA(IN LPCSTR lpszLongPath, OUT LPSTR lpszShortPath, IN DWORD cchBuffer)
Definition: pathansi.c:20
#define PathAppendA
Definition: pathcch.h:309
#define PathCombineW
Definition: pathcch.h:318
#define PathAddBackslashW
Definition: pathcch.h:302
#define PathAppendW
Definition: pathcch.h:310
#define LOWORD(l)
Definition: pedump.c:82
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
char CHAR
Definition: pedump.c:57
LPITEMIDLIST _ILCreateMyComputer(void)
Definition: pidl.c:1807
LPITEMIDLIST _ILCreateIExplore(void)
Definition: pidl.c:1819
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:1051
HRESULT WINAPI SHILCreateFromPathW(LPCWSTR path, LPITEMIDLIST *ppidl, DWORD *attributes)
Definition: pidl.c:404
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:817
LPITEMIDLIST _ILCreateDesktop(void)
Definition: pidl.c:1796
LPITEMIDLIST _ILCreateNetwork(void)
Definition: pidl.c:1870
LPITEMIDLIST _ILCreatePrinters(void)
Definition: pidl.c:1843
LPITEMIDLIST _ILCreateControlPanel(void)
Definition: pidl.c:1825
LPITEMIDLIST WINAPI ILCreateFromPathW(LPCWSTR path)
Definition: pidl.c:1108
LPITEMIDLIST _ILCreateMyDocuments(void)
Definition: pidl.c:1813
LPITEMIDLIST _ILCreateBitBucket(void)
Definition: pidl.c:1876
#define INT
Definition: polytest.cpp:20
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
#define GCT_SEPARATOR
Definition: shlwapi.h:275
_In_ INT cchDest
Definition: shlwapi.h:1161
#define GCT_INVALID
Definition: shlwapi.h:271
#define GCT_WILD
Definition: shlwapi.h:274
strcpy
Definition: string.h:131
#define LoadStringW
Definition: utils.h:64
#define NTDDI_VISTA
Definition: sdkddkver.h:103
static __inline BOOL SHELL_OsIsUnicode(void)
Definition: shell32_main.h:196
static __inline LPWSTR __SHCloneStrAtoW(WCHAR **target, const char *source)
Definition: shell32_main.h:226
_In_ UINT _In_ UINT cch
Definition: shellapi.h:432
_In_ LPCSTR pszDir
Definition: shellapi.h:609
int WINAPI SHCreateDirectoryExW(HWND hWnd, LPCWSTR path, LPSECURITY_ATTRIBUTES sec)
Definition: shlfileop.cpp:1006
#define CSIDL_COMMON_TEMPLATES
Definition: shlobj.h:2235
#define CSIDL_COMMON_DESKTOPDIRECTORY
Definition: shlobj.h:2215
#define CSIDL_TEMPLATES
Definition: shlobj.h:2211
#define CSIDL_PROGRAM_FILES
Definition: shlobj.h:2228
#define CSIDL_INTERNET_CACHE
Definition: shlobj.h:2222
_In_ int _In_ BOOL bCreate
Definition: shlobj.h:1536
#define CSIDL_DESKTOPDIRECTORY
Definition: shlobj.h:2206
#define CSIDL_SENDTO
Definition: shlobj.h:2200
#define CSIDL_RECENT
Definition: shlobj.h:2199
#define CSIDL_MYDOCUMENTS
Definition: shlobj.h:2203
#define CSIDL_ADMINTOOLS
Definition: shlobj.h:2238
#define CSIDL_COMMON_STARTMENU
Definition: shlobj.h:2212
@ SHGFP_TYPE_DEFAULT
Definition: shlobj.h:2168
@ SHGFP_TYPE_CURRENT
Definition: shlobj.h:2167
#define PCS_REPLACEDCHAR
Definition: shlobj.h:367
#define CSIDL_FONTS
Definition: shlobj.h:2210
#define CSIDL_PERSONAL
Definition: shlobj.h:2196
#define CSIDL_FAVORITES
Definition: shlobj.h:2197
#define CSIDL_FLAG_CREATE
Definition: shlobj.h:2253
#define CSIDL_FLAG_NO_ALIAS
Definition: shlobj.h:2251
#define CSIDL_COMMON_APPDATA
Definition: shlobj.h:2225
#define CSIDL_CONNECTIONS
Definition: shlobj.h:2239
#define CSIDL_COMMON_PROGRAMS
Definition: shlobj.h:2213
#define PCS_PATHTOOLONG
Definition: shlobj.h:370
#define CSIDL_FLAG_DONT_VERIFY
Definition: shlobj.h:2252
#define CSIDL_MYPICTURES
Definition: shlobj.h:2229
#define CSIDL_COOKIES
Definition: shlobj.h:2223
#define CSIDL_COMMON_FAVORITES
Definition: shlobj.h:2221
#define CSIDL_PRINTERS
Definition: shlobj.h:2195
#define CSIDL_HISTORY
Definition: shlobj.h:2224
#define CSIDL_LOCAL_APPDATA
Definition: shlobj.h:2218
#define CSIDL_PROGRAM_FILES_COMMONX86
Definition: shlobj.h:2234
#define CSIDL_PROGRAM_FILES_COMMON
Definition: shlobj.h:2233
#define CSIDL_COMMON_MUSIC
Definition: shlobj.h:2240
#define PCS_FATAL
Definition: shlobj.h:366
#define CSIDL_COMMON_VIDEO
Definition: shlobj.h:2242
#define CSIDL_FOLDER_MASK
Definition: shlobj.h:2249
#define CSIDL_DESKTOP
Definition: shlobj.h:2191
#define CSIDL_NETWORK
Definition: shlobj.h:2208
#define CSIDL_STARTMENU
Definition: shlobj.h:2202
#define CSIDL_PROGRAM_FILESX86
Definition: shlobj.h:2232
#define CSIDL_COMMON_PICTURES
Definition: shlobj.h:2241
#define CSIDL_PROGRAMS
Definition: shlobj.h:2193
#define CSIDL_COMMON_STARTUP
Definition: shlobj.h:2214
#define CSIDL_APPDATA
Definition: shlobj.h:2216
#define CSIDL_PRINTHOOD
Definition: shlobj.h:2217
#define CSIDL_STARTUP
Definition: shlobj.h:2198
#define CSIDL_DRIVES
Definition: shlobj.h:2207
#define CSIDL_MYMUSIC
Definition: shlobj.h:2204
#define CSIDL_INTERNET
Definition: shlobj.h:2192
#define CSIDL_COMMON_DOCUMENTS
Definition: shlobj.h:2236
#define CSIDL_CONTROLS
Definition: shlobj.h:2194
#define CSIDL_BITBUCKET
Definition: shlobj.h:2201
#define CSIDL_NETHOOD
Definition: shlobj.h:2209
#define CSIDL_COMMON_ADMINTOOLS
Definition: shlobj.h:2237
#define CSIDL_MYVIDEO
Definition: shlobj.h:2205
_In_ int nFolder
Definition: shlobj.h:1535
#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:723
#define IDS_MYVIDEO
Definition: shresdef.h:92
#define IDI_SHELL_MY_MUSIC
Definition: shresdef.h:725
#define IDS_COOKIES
Definition: shresdef.h:100
#define IDI_SHELL_MY_PICTURES
Definition: shresdef.h:724
#define IDI_SHELL_TSKBAR_STARTMENU
Definition: shresdef.h:633
#define IDS_MYMUSIC
Definition: shresdef.h:91
#define IDI_SHELL_COMPUTER_FOLDER
Definition: shresdef.h:636
#define IDI_SHELL_FAVORITES
Definition: shresdef.h:637
#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:726
#define IDI_SHELL_RECENT_DOCUMENTS
Definition: shresdef.h:614
#define IDI_SHELL_NETWORK
Definition: shresdef.h:608
#define IDS_APPDATA
Definition: shresdef.h:96
#define IDI_SHELL_PRINTERS_FOLDER
Definition: shresdef.h:631
#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:682
#define IDI_SHELL_FONTS_FOLDER
Definition: shresdef.h:632
#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:615
#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:762
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:1223
CSIDL_Type type
Definition: shellpath.c:1220
LPCWSTR szDefaultPath
Definition: shellpath.c:1222
LPCWSTR szValueName
Definition: shellpath.c:1221
const KNOWNFOLDERID * id
Definition: shellpath.c:1219
SID_AND_ATTRIBUTES User
Definition: setypes.h:1022
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 char * LPCSTR
Definition: typedefs.h:52
const uint16_t * PCWSTR
Definition: typedefs.h:57
const uint16_t * LPCWSTR
Definition: typedefs.h:57
unsigned char * LPBYTE
Definition: typedefs.h:53
uint16_t * LPWSTR
Definition: typedefs.h:56
PVOID HANDLE
Definition: typedefs.h:73
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t * LPDWORD
Definition: typedefs.h:59
char * LPSTR
Definition: typedefs.h:51
int32_t INT
Definition: typedefs.h:58
uint16_t * PWCHAR
Definition: typedefs.h:56
#define SHSTDAPI
Definition: undocshell.h:22
Definition: pdh_main.c:96
DWORD dwAttributes
Definition: vdmdbg.h:34
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define DRIVE_REMOVABLE
Definition: winbase.h:276
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define WINAPI
Definition: msvc.h:6
#define strncmpiW(s1, s2, n)
Definition: unicode.h:40
#define strcmpW(s1, s2)
Definition: unicode.h:38
#define strlenW(s)
Definition: unicode.h:28
#define strcatW(d, s)
Definition: unicode.h:30
#define sprintfW
Definition: unicode.h:58
#define strcpyW(d, s)
Definition: unicode.h:29
#define S_FALSE
Definition: winerror.h:3451
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define E_NOT_SUFFICIENT_BUFFER
Definition: winerror.h:3437
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:228
#define ERROR_FILENAME_EXCED_RANGE
Definition: winerror.h:385
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define RRF_RT_REG_SZ
Definition: winreg.h:58
#define HKEY_USERS
Definition: winreg.h:13
#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:940
@ TokenUser
Definition: setypes.h:978
unsigned char BYTE
Definition: xxhash.c:193