4 * Copyright 1998, 1999, 2000 Juergen Schmied
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * Many of these functions are in SHLWAPI.DLL also
27 #include "wine/port.h"
32 #include "wine/debug.h"
41 #include "shell32_main.h"
42 #include "undocshell.h"
43 #include "wine/unicode.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
49 ########## Combining and Constructing paths ##########
52 /*************************************************************************
53 * PathAppend [SHELL32.36]
55 BOOL WINAPI
PathAppendAW(
59 if (SHELL_OsIsUnicode())
60 return PathAppendW(lpszPath1
, lpszPath2
);
61 return PathAppendA(lpszPath1
, lpszPath2
);
64 /*************************************************************************
65 * PathCombine [SHELL32.37]
67 LPVOID WINAPI
PathCombineAW(
72 if (SHELL_OsIsUnicode())
73 return PathCombineW( szDest
, lpszDir
, lpszFile
);
74 return PathCombineA( szDest
, lpszDir
, lpszFile
);
77 /*************************************************************************
78 * PathAddBackslash [SHELL32.32]
80 LPVOID WINAPI
PathAddBackslashAW(LPVOID lpszPath
)
82 if(SHELL_OsIsUnicode())
83 return PathAddBackslashW(lpszPath
);
84 return PathAddBackslashA(lpszPath
);
87 /*************************************************************************
88 * PathBuildRoot [SHELL32.30]
90 LPVOID WINAPI
PathBuildRootAW(LPVOID lpszPath
, int drive
)
92 if(SHELL_OsIsUnicode())
93 return PathBuildRootW(lpszPath
, drive
);
94 return PathBuildRootA(lpszPath
, drive
);
98 Extracting Component Parts
101 /*************************************************************************
102 * PathFindFileName [SHELL32.34]
104 LPVOID WINAPI
PathFindFileNameAW(LPCVOID lpszPath
)
106 if(SHELL_OsIsUnicode())
107 return PathFindFileNameW(lpszPath
);
108 return PathFindFileNameA(lpszPath
);
111 /*************************************************************************
112 * PathFindExtension [SHELL32.31]
114 LPVOID WINAPI
PathFindExtensionAW(LPCVOID lpszPath
)
116 if (SHELL_OsIsUnicode())
117 return PathFindExtensionW(lpszPath
);
118 return PathFindExtensionA(lpszPath
);
122 /*************************************************************************
123 * PathGetExtensionA [internal]
126 * exported by ordinal
127 * return value points to the first char after the dot
129 static LPSTR
PathGetExtensionA(LPCSTR lpszPath
)
131 TRACE("(%s)\n",lpszPath
);
133 lpszPath
= PathFindExtensionA(lpszPath
);
134 return (LPSTR
)(*lpszPath
?(lpszPath
+1):lpszPath
);
137 /*************************************************************************
138 * PathGetExtensionW [internal]
140 static LPWSTR
PathGetExtensionW(LPCWSTR lpszPath
)
142 TRACE("(%s)\n",debugstr_w(lpszPath
));
144 lpszPath
= PathFindExtensionW(lpszPath
);
145 return (LPWSTR
)(*lpszPath
?(lpszPath
+1):lpszPath
);
148 /*************************************************************************
149 * PathGetExtension [SHELL32.158]
151 LPVOID WINAPI
PathGetExtensionAW(LPCVOID lpszPath
,DWORD void1
, DWORD void2
)
153 if (SHELL_OsIsUnicode())
154 return PathGetExtensionW(lpszPath
);
155 return PathGetExtensionA(lpszPath
);
158 /*************************************************************************
159 * PathGetArgs [SHELL32.52]
161 LPVOID WINAPI
PathGetArgsAW(LPVOID lpszPath
)
163 if (SHELL_OsIsUnicode())
164 return PathGetArgsW(lpszPath
);
165 return PathGetArgsA(lpszPath
);
168 /*************************************************************************
169 * PathGetDriveNumber [SHELL32.57]
171 int WINAPI
PathGetDriveNumberAW(LPVOID lpszPath
)
173 if (SHELL_OsIsUnicode())
174 return PathGetDriveNumberW(lpszPath
);
175 return PathGetDriveNumberA(lpszPath
);
178 /*************************************************************************
179 * PathRemoveFileSpec [SHELL32.35]
181 BOOL WINAPI
PathRemoveFileSpecAW(LPVOID lpszPath
)
183 if (SHELL_OsIsUnicode())
184 return PathRemoveFileSpecW(lpszPath
);
185 return PathRemoveFileSpecA(lpszPath
);
188 /*************************************************************************
189 * PathStripPath [SHELL32.38]
191 void WINAPI
PathStripPathAW(LPVOID lpszPath
)
193 if (SHELL_OsIsUnicode())
194 PathStripPathW(lpszPath
);
196 PathStripPathA(lpszPath
);
199 /*************************************************************************
200 * PathStripToRoot [SHELL32.50]
202 BOOL WINAPI
PathStripToRootAW(LPVOID lpszPath
)
204 if (SHELL_OsIsUnicode())
205 return PathStripToRootW(lpszPath
);
206 return PathStripToRootA(lpszPath
);
209 /*************************************************************************
210 * PathRemoveArgs [SHELL32.251]
212 void WINAPI
PathRemoveArgsAW(LPVOID lpszPath
)
214 if (SHELL_OsIsUnicode())
215 PathRemoveArgsW(lpszPath
);
217 PathRemoveArgsA(lpszPath
);
220 /*************************************************************************
221 * PathRemoveExtension [SHELL32.250]
223 void WINAPI
PathRemoveExtensionAW(LPVOID lpszPath
)
225 if (SHELL_OsIsUnicode())
226 PathRemoveExtensionW(lpszPath
);
228 PathRemoveExtensionA(lpszPath
);
236 /*************************************************************************
237 * PathGetShortPathA [internal]
239 static void PathGetShortPathA(LPSTR pszPath
)
243 TRACE("%s\n", pszPath
);
245 if (GetShortPathNameA(pszPath
, path
, MAX_PATH
))
247 lstrcpyA(pszPath
, path
);
251 /*************************************************************************
252 * PathGetShortPathW [internal]
254 static void PathGetShortPathW(LPWSTR pszPath
)
256 WCHAR path
[MAX_PATH
];
258 TRACE("%s\n", debugstr_w(pszPath
));
260 if (GetShortPathNameW(pszPath
, path
, MAX_PATH
))
262 lstrcpyW(pszPath
, path
);
266 /*************************************************************************
267 * PathGetShortPath [SHELL32.92]
269 VOID WINAPI
PathGetShortPathAW(LPVOID pszPath
)
271 if(SHELL_OsIsUnicode())
272 PathGetShortPathW(pszPath
);
273 PathGetShortPathA(pszPath
);
276 /*************************************************************************
277 * PathRemoveBlanks [SHELL32.33]
279 void WINAPI
PathRemoveBlanksAW(LPVOID str
)
281 if(SHELL_OsIsUnicode())
282 PathRemoveBlanksW(str
);
284 PathRemoveBlanksA(str
);
287 /*************************************************************************
288 * PathQuoteSpaces [SHELL32.55]
290 VOID WINAPI
PathQuoteSpacesAW (LPVOID lpszPath
)
292 if(SHELL_OsIsUnicode())
293 PathQuoteSpacesW(lpszPath
);
295 PathQuoteSpacesA(lpszPath
);
298 /*************************************************************************
299 * PathUnquoteSpaces [SHELL32.56]
301 VOID WINAPI
PathUnquoteSpacesAW(LPVOID str
)
303 if(SHELL_OsIsUnicode())
304 PathUnquoteSpacesW(str
);
306 PathUnquoteSpacesA(str
);
309 /*************************************************************************
310 * PathParseIconLocation [SHELL32.249]
312 int WINAPI
PathParseIconLocationAW (LPVOID lpszPath
)
314 if(SHELL_OsIsUnicode())
315 return PathParseIconLocationW(lpszPath
);
316 return PathParseIconLocationA(lpszPath
);
320 ########## Path Testing ##########
322 /*************************************************************************
323 * PathIsUNC [SHELL32.39]
325 BOOL WINAPI
PathIsUNCAW (LPCVOID lpszPath
)
327 if (SHELL_OsIsUnicode())
328 return PathIsUNCW( lpszPath
);
329 return PathIsUNCA( lpszPath
);
332 /*************************************************************************
333 * PathIsRelative [SHELL32.40]
335 BOOL WINAPI
PathIsRelativeAW (LPCVOID lpszPath
)
337 if (SHELL_OsIsUnicode())
338 return PathIsRelativeW( lpszPath
);
339 return PathIsRelativeA( lpszPath
);
342 /*************************************************************************
343 * PathIsRoot [SHELL32.29]
345 BOOL WINAPI
PathIsRootAW(LPCVOID lpszPath
)
347 if (SHELL_OsIsUnicode())
348 return PathIsRootW(lpszPath
);
349 return PathIsRootA(lpszPath
);
352 /*************************************************************************
353 * PathIsExeA [internal]
355 static BOOL
PathIsExeA (LPCSTR lpszPath
)
357 LPCSTR lpszExtension
= PathGetExtensionA(lpszPath
);
359 static const char * const lpszExtensions
[] =
360 {"exe", "com", "pif", "cmd", "bat", "scf", "scr", NULL
};
362 TRACE("path=%s\n",lpszPath
);
364 for(i
=0; lpszExtensions
[i
]; i
++)
365 if (!strcasecmp(lpszExtension
,lpszExtensions
[i
])) return TRUE
;
370 /*************************************************************************
371 * PathIsExeW [internal]
373 static BOOL
PathIsExeW (LPCWSTR lpszPath
)
375 LPCWSTR lpszExtension
= PathGetExtensionW(lpszPath
);
377 static const WCHAR lpszExtensions
[][4] =
378 {{'e','x','e','\0'}, {'c','o','m','\0'}, {'p','i','f','\0'},
379 {'c','m','d','\0'}, {'b','a','t','\0'}, {'s','c','f','\0'},
380 {'s','c','r','\0'}, {'\0'} };
382 TRACE("path=%s\n",debugstr_w(lpszPath
));
384 for(i
=0; lpszExtensions
[i
][0]; i
++)
385 if (!strcmpiW(lpszExtension
,lpszExtensions
[i
])) return TRUE
;
390 /*************************************************************************
391 * PathIsExe [SHELL32.43]
393 BOOL WINAPI
PathIsExeAW (LPCVOID path
)
395 if (SHELL_OsIsUnicode())
396 return PathIsExeW (path
);
397 return PathIsExeA(path
);
400 /*************************************************************************
401 * PathIsDirectory [SHELL32.159]
403 BOOL WINAPI
PathIsDirectoryAW (LPCVOID lpszPath
)
405 if (SHELL_OsIsUnicode())
406 return PathIsDirectoryW (lpszPath
);
407 return PathIsDirectoryA (lpszPath
);
410 /*************************************************************************
411 * PathFileExists [SHELL32.45]
413 BOOL WINAPI
PathFileExistsAW (LPCVOID lpszPath
)
415 if (SHELL_OsIsUnicode())
416 return PathFileExistsW (lpszPath
);
417 return PathFileExistsA (lpszPath
);
420 /*************************************************************************
421 * PathMatchSpec [SHELL32.46]
423 BOOL WINAPI
PathMatchSpecAW(LPVOID name
, LPVOID mask
)
425 if (SHELL_OsIsUnicode())
426 return PathMatchSpecW( name
, mask
);
427 return PathMatchSpecA( name
, mask
);
430 /*************************************************************************
431 * PathIsSameRoot [SHELL32.650]
433 BOOL WINAPI
PathIsSameRootAW(LPCVOID lpszPath1
, LPCVOID lpszPath2
)
435 if (SHELL_OsIsUnicode())
436 return PathIsSameRootW(lpszPath1
, lpszPath2
);
437 return PathIsSameRootA(lpszPath1
, lpszPath2
);
440 /*************************************************************************
441 * IsLFNDriveA [SHELL32.41]
443 BOOL WINAPI
IsLFNDriveA(LPCSTR lpszPath
)
447 if (!GetVolumeInformationA(lpszPath
, NULL
, 0, NULL
, &fnlen
, NULL
, NULL
, 0))
452 /*************************************************************************
453 * IsLFNDriveW [SHELL32.42]
455 BOOL WINAPI
IsLFNDriveW(LPCWSTR lpszPath
)
459 if (!GetVolumeInformationW(lpszPath
, NULL
, 0, NULL
, &fnlen
, NULL
, NULL
, 0))
464 /*************************************************************************
465 * IsLFNDrive [SHELL32.119]
467 BOOL WINAPI
IsLFNDriveAW(LPCVOID lpszPath
)
469 if (SHELL_OsIsUnicode())
470 return IsLFNDriveW(lpszPath
);
471 return IsLFNDriveA(lpszPath
);
475 ########## Creating Something Unique ##########
477 /*************************************************************************
478 * PathMakeUniqueNameA [internal]
480 BOOL WINAPI
PathMakeUniqueNameA(
483 LPCSTR lpszShortName
,
487 FIXME("%p %lu %s %s %s stub\n",
488 lpszBuffer
, dwBuffSize
, debugstr_a(lpszShortName
),
489 debugstr_a(lpszLongName
), debugstr_a(lpszPathName
));
493 /*************************************************************************
494 * PathMakeUniqueNameW [internal]
496 BOOL WINAPI
PathMakeUniqueNameW(
499 LPCWSTR lpszShortName
,
500 LPCWSTR lpszLongName
,
501 LPCWSTR lpszPathName
)
503 FIXME("%p %lu %s %s %s stub\n",
504 lpszBuffer
, dwBuffSize
, debugstr_w(lpszShortName
),
505 debugstr_w(lpszLongName
), debugstr_w(lpszPathName
));
509 /*************************************************************************
510 * PathMakeUniqueName [SHELL32.47]
512 BOOL WINAPI
PathMakeUniqueNameAW(
515 LPCVOID lpszShortName
,
516 LPCVOID lpszLongName
,
517 LPCVOID lpszPathName
)
519 if (SHELL_OsIsUnicode())
520 return PathMakeUniqueNameW(lpszBuffer
,dwBuffSize
, lpszShortName
,lpszLongName
,lpszPathName
);
521 return PathMakeUniqueNameA(lpszBuffer
,dwBuffSize
, lpszShortName
,lpszLongName
,lpszPathName
);
524 /*************************************************************************
525 * PathYetAnotherMakeUniqueName [SHELL32.75]
528 * exported by ordinal
530 BOOL WINAPI
PathYetAnotherMakeUniqueName(
532 LPCWSTR lpszPathName
,
533 LPCWSTR lpszShortName
,
534 LPCWSTR lpszLongName
)
536 FIXME("(%p, %s, %s ,%s):stub.\n",
537 lpszBuffer
, debugstr_w(lpszPathName
), debugstr_w(lpszShortName
), debugstr_w(lpszLongName
));
543 ########## cleaning and resolving paths ##########
546 /*************************************************************************
547 * PathFindOnPath [SHELL32.145]
549 BOOL WINAPI
PathFindOnPathAW(LPVOID sFile
, LPCVOID sOtherDirs
)
551 if (SHELL_OsIsUnicode())
552 return PathFindOnPathW(sFile
, (LPCWSTR
*)sOtherDirs
);
553 return PathFindOnPathA(sFile
, (LPCSTR
*)sOtherDirs
);
556 /*************************************************************************
557 * PathCleanupSpec [SHELL32.171]
559 DWORD WINAPI
PathCleanupSpecAW (LPCVOID x
, LPVOID y
)
561 FIXME("(%p, %p) stub\n",x
,y
);
565 /*************************************************************************
566 * PathQualifyA [SHELL32]
568 BOOL WINAPI
PathQualifyA(LPCSTR pszPath
)
570 FIXME("%s\n",pszPath
);
574 /*************************************************************************
575 * PathQualifyW [SHELL32]
577 BOOL WINAPI
PathQualifyW(LPCWSTR pszPath
)
579 FIXME("%s\n",debugstr_w(pszPath
));
583 /*************************************************************************
584 * PathQualify [SHELL32.49]
586 BOOL WINAPI
PathQualifyAW(LPCVOID pszPath
)
588 if (SHELL_OsIsUnicode())
589 return PathQualifyW(pszPath
);
590 return PathQualifyA(pszPath
);
593 /*************************************************************************
594 * PathResolveA [SHELL32.51]
596 BOOL WINAPI
PathResolveA(
601 FIXME("(%s,%p,0x%08lx),stub!\n",
602 lpszPath
, *alpszPaths
, dwFlags
);
606 /*************************************************************************
607 * PathResolveW [SHELL32]
609 BOOL WINAPI
PathResolveW(
614 FIXME("(%s,%p,0x%08lx),stub!\n",
615 debugstr_w(lpszPath
), debugstr_w(*alpszPaths
), dwFlags
);
619 /*************************************************************************
620 * PathResolve [SHELL32.51]
622 BOOL WINAPI
PathResolveAW(
627 if (SHELL_OsIsUnicode())
628 return PathResolveW(lpszPath
, (LPCWSTR
*)alpszPaths
, dwFlags
);
629 return PathResolveA(lpszPath
, (LPCSTR
*)alpszPaths
, dwFlags
);
632 /*************************************************************************
633 * PathProcessCommandA [SHELL32.653]
635 HRESULT WINAPI
PathProcessCommandA (
641 FIXME("%s %p 0x%04lx 0x%04lx stub\n",
642 lpszPath
, lpszBuff
, dwBuffSize
, dwFlags
);
643 strcpy(lpszBuff
, lpszPath
);
647 /*************************************************************************
648 * PathProcessCommandW
650 HRESULT WINAPI
PathProcessCommandW (
656 FIXME("(%s, %p, 0x%04lx, 0x%04lx) stub\n",
657 debugstr_w(lpszPath
), lpszBuff
, dwBuffSize
, dwFlags
);
658 strcpyW(lpszBuff
, lpszPath
);
662 /*************************************************************************
663 * PathProcessCommand (SHELL32.653)
665 HRESULT WINAPI
PathProcessCommandAW (
671 if (SHELL_OsIsUnicode())
672 return PathProcessCommandW(lpszPath
, lpszBuff
, dwBuffSize
, dwFlags
);
673 return PathProcessCommandA(lpszPath
, lpszBuff
, dwBuffSize
, dwFlags
);
677 ########## special ##########
680 /*************************************************************************
681 * PathSetDlgItemPath (SHELL32.48)
683 VOID WINAPI
PathSetDlgItemPathAW(HWND hDlg
, int id
, LPCVOID pszPath
)
685 if (SHELL_OsIsUnicode())
686 PathSetDlgItemPathW(hDlg
, id
, pszPath
);
688 PathSetDlgItemPathA(hDlg
, id
, pszPath
);
691 /*************************************************************************
692 * SHGetFolderPathW [SHELL32.@]
694 * converts csidl to path
697 static const WCHAR szSHFolders
[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','E','x','p','l','o','r','e','r','\\','S','h','e','l','l',' ','F','o','l','d','e','r','s','\0'};
698 static const WCHAR szSHUserFolders
[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','E','x','p','l','o','r','e','r','\\','U','s','e','r',' ','S','h','e','l','l',' ','F','o','l','d','e','r','s','\0'};
699 static const WCHAR szSetup
[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','E','x','p','l','o','r','e','r','\\','S','e','t','u','p','\0'};
700 static const WCHAR szCurrentVersion
[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0'};
707 LPCSTR szDefaultPath
; /* fallback string; sub dir of windows directory */
710 #define CSIDL_MYFLAG_SHFOLDER 1
711 #define CSIDL_MYFLAG_SETUP 2
712 #define CSIDL_MYFLAG_CURRVER 4
713 #define CSIDL_MYFLAG_RELATIVE 8
715 #define HKLM HKEY_LOCAL_MACHINE
716 #define HKCU HKEY_CURRENT_USER
717 static const CSIDL_DATA CSIDL_Data
[] =
719 { /* CSIDL_DESKTOP */
724 { /* CSIDL_INTERNET */
725 0, (HKEY
)1, /* FIXME */
729 { /* CSIDL_PROGRAMS */
732 "Start Menu\\Programs"
734 { /* CSIDL_CONTROLS (.CPL files) */
739 { /* CSIDL_PRINTERS */
744 { /* CSIDL_PERSONAL */
749 { /* CSIDL_FAVORITES */
754 { /* CSIDL_STARTUP */
757 "Start Menu\\Programs\\StartUp"
769 { /* CSIDL_BITBUCKET - Recycle Bin */
770 0, (HKEY
)1, /* FIXME */
774 { /* CSIDL_STARTMENU */
779 { /* CSIDL_MYDOCUMENTS */
780 0, (HKEY
)1, /* FIXME */
784 { /* CSIDL_MYMUSIC */
787 "My Documents\\My Music"
789 { /* CSIDL_MYMUSIC */
792 "My Documents\\My Video"
799 { /* CSIDL_DESKTOPDIRECTORY */
805 0, (HKEY
)1, /* FIXME */
809 { /* CSIDL_NETWORK */
810 0, (HKEY
)1, /* FIXME */
812 "Network Neighborhood"
814 { /* CSIDL_NETHOOD */
824 { /* CSIDL_TEMPLATES */
829 { /* CSIDL_COMMON_STARTMENU */
834 { /* CSIDL_COMMON_PROGRAMS */
839 { /* CSIDL_COMMON_STARTUP */
842 "All Users\\Start Menu\\Programs\\StartUp"
844 { /* CSIDL_COMMON_DESKTOPDIRECTORY */
849 { /* CSIDL_APPDATA */
854 { /* CSIDL_PRINTHOOD */
859 { /* CSIDL_LOCAL_APPDATA (win2k only/undocumented) */
862 "Local Settings\\Application Data",
864 { /* CSIDL_ALTSTARTUP */
865 0, (HKEY
)1, /* FIXME */
869 { /* CSIDL_COMMON_ALTSTARTUP */
870 0, (HKEY
)1, /* FIXME */
874 { /* CSIDL_COMMON_FAVORITES */
879 { /* CSIDL_INTERNET_CACHE (32) */
882 "Temporary Internet Files"
884 { /* CSIDL_COOKIES (33) */
889 { /* CSIDL_HISTORY (34) */
894 { /* CSIDL_COMMON_APPDATA */
897 "All Users\\Application Data"
899 { /* CSIDL_WINDOWS */
909 { /* CSIDL_PROGRAM_FILES */
914 { /* CSIDL_MYPICTURES */
917 "My Documents\\My Pictures"
919 { /* CSIDL_PROFILE */
921 "WinDir", /* correct ? */
924 { /* CSIDL_SYSTEMX86 */
929 { /* CSIDL_PROGRAM_FILESX86 */
934 { /* CSIDL_PROGRAM_FILES_COMMON */
937 "Program Files\\Common Files" /* ? */
939 { /* CSIDL_PROGRAM_FILES_COMMONX86 */
942 "Program Files\\Common Files" /* ? */
944 { /* CSIDL_COMMON_TEMPLATES */
947 /*"Documents and Settings\\"*/"All Users\\Templates"
949 { /* CSIDL_COMMON_DOCUMENTS */
952 /*"Documents and Settings\\"*/"All Users\\Documents"
954 { /* CSIDL_COMMON_ADMINTOOLS */
956 "Common Administrative Tools",
957 /*"Documents and Settings\\"*/"All Users\\Start Menu\\Programs\\Administrative Tools"
959 { /* CSIDL_ADMINTOOLS */
961 "Administrative Tools",
962 "Start Menu\\Programs\\Administrative Tools"
964 { /* CSIDL_CONNECTIONS */
969 { /* unassigned 32 */
974 { /* unassigned 33 */
979 { /* unassigned 34 */
984 { /* CSIDL_COMMON_MUSIC */
987 /*"Documents and Settings\\"*/"All Users\\Documents\\My Music"
989 { /* CSIDL_COMMON_PICTURES */
992 /*"Documents and Settings\\"*/"All Users\\Documents\\My Pictures"
994 { /* CSIDL_COMMON_VIDEO */
997 /*"Documents and Settings\\"*/"All Users\\Documents\\My Video"
999 { /* CSIDL_RESOURCES */
1004 { /* CSIDL_RESOURCES_LOCALIZED */
1009 { /* CSIDL_COMMON_OEM_LINKS */
1014 { /* CSIDL_CDBURN_AREA */
1017 "Local Settings\\Application Data\\Microsoft\\CD Burning"
1019 { /* unassigned 3C */
1024 { /* CSIDL_COMPUTERSNEARME */
1029 { /* CSIDL_PROFILES */
1038 /**********************************************************************/
1040 HRESULT WINAPI
SHGetFolderPathW(
1043 HANDLE hToken
, /* [in] FIXME: get paths for specific user */
1044 DWORD dwFlags
, /* [in] FIXME: SHGFP_TYPE_CURRENT|SHGFP_TYPE_DEFAULT */
1047 WCHAR szValueName
[MAX_PATH
], szDefaultPath
[MAX_PATH
], szBuildPath
[MAX_PATH
];
1048 HKEY hRootKey
, hKey
;
1050 DWORD dwType
, dwDisp
, dwPathLen
= MAX_PATH
;
1051 DWORD folder
= csidl
& CSIDL_FOLDER_MASK
;
1054 TRACE("%p,%p,csidl=0x%04x\n", hwndOwner
,pszPath
,csidl
);
1056 if ((folder
>= sizeof(CSIDL_Data
) / sizeof(CSIDL_Data
[0])) ||
1057 (CSIDL_Data
[folder
].hRootKey
== 0))
1059 ERR("folder 0x%04lx unknown or not allowed\n", folder
);
1062 if (CSIDL_Data
[folder
].hRootKey
== (HKEY
)1)
1064 FIXME("folder 0x%04lx unknown, please add.\n", folder
);
1068 dwCsidlFlags
= CSIDL_Data
[folder
].dwFlags
;
1069 hRootKey
= CSIDL_Data
[folder
].hRootKey
;
1070 MultiByteToWideChar(CP_ACP
, 0, CSIDL_Data
[folder
].szValueName
, -1, szValueName
, MAX_PATH
);
1071 MultiByteToWideChar(CP_ACP
, 0, CSIDL_Data
[folder
].szDefaultPath
, -1, szDefaultPath
, MAX_PATH
);
1073 /* Special case for some values that don't exist in registry */
1074 if (CSIDL_Data
[folder
].hRootKey
== (HKEY
)2)
1076 GetWindowsDirectoryW(pszPath
, MAX_PATH
);
1077 PathAddBackslashW(pszPath
);
1078 strcatW(pszPath
, szDefaultPath
);
1082 if (dwCsidlFlags
& CSIDL_MYFLAG_SHFOLDER
)
1084 /* user shell folders */
1085 if (RegCreateKeyExW(hRootKey
,szSHUserFolders
,0,NULL
,0,KEY_ALL_ACCESS
,NULL
,&hKey
,&dwDisp
)) return E_FAIL
;
1087 if (RegQueryValueExW(hKey
,szValueName
,NULL
,&dwType
,(LPBYTE
)pszPath
,&dwPathLen
))
1092 if (RegCreateKeyExW(hRootKey
,szSHFolders
,0,NULL
,0,KEY_ALL_ACCESS
,NULL
,&hKey
,&dwDisp
)) return E_FAIL
;
1094 if (RegQueryValueExW(hKey
,szValueName
,NULL
,&dwType
,(LPBYTE
)pszPath
,&dwPathLen
))
1097 /* value not existing */
1098 if (dwCsidlFlags
& CSIDL_MYFLAG_RELATIVE
)
1100 GetWindowsDirectoryW(pszPath
, MAX_PATH
);
1101 PathAddBackslashW(pszPath
);
1102 strcatW(pszPath
, szDefaultPath
);
1106 GetSystemDirectoryW(pszPath
, MAX_PATH
);
1107 strcpyW(pszPath
+ 3, szDefaultPath
);
1110 RegSetValueExW(hKey
,szValueName
,0,REG_SZ
,(LPBYTE
)pszPath
,strlenW(pszPath
)+1);
1119 if (dwCsidlFlags
& CSIDL_MYFLAG_SETUP
)
1121 else if (dwCsidlFlags
& CSIDL_MYFLAG_CURRVER
)
1122 pRegPath
= szCurrentVersion
;
1125 ERR("folder settings broken, please correct !\n");
1129 if (RegCreateKeyExW(hRootKey
,pRegPath
,0,NULL
,0,KEY_ALL_ACCESS
,NULL
,&hKey
,&dwDisp
)) return E_FAIL
;
1131 if (RegQueryValueExW(hKey
,szValueName
,NULL
,&dwType
,(LPBYTE
)pszPath
,&dwPathLen
))
1133 /* value not existing */
1134 if (dwCsidlFlags
& CSIDL_MYFLAG_RELATIVE
)
1136 GetWindowsDirectoryW(pszPath
, MAX_PATH
);
1137 PathAddBackslashW(pszPath
);
1138 strcatW(pszPath
, szDefaultPath
);
1142 GetSystemDirectoryW(pszPath
, MAX_PATH
);
1143 strcpyW(pszPath
+ 3, szDefaultPath
);
1146 RegSetValueExW(hKey
,szValueName
,0,REG_SZ
,(LPBYTE
)pszPath
,strlenW(pszPath
)+1);
1151 /* expand paths like %USERPROFILE% */
1152 if (dwType
== REG_EXPAND_SZ
)
1154 ExpandEnvironmentStringsW(pszPath
, szDefaultPath
, MAX_PATH
);
1155 strcpyW(pszPath
, szDefaultPath
);
1158 /* if we don't care about existing directories we are ready */
1159 if(csidl
& CSIDL_FLAG_DONT_VERIFY
) return S_OK
;
1161 if (PathFileExistsW(pszPath
)) return S_OK
;
1163 /* not existing but we are not allowed to create it */
1164 if (!(csidl
& CSIDL_FLAG_CREATE
)) return E_FAIL
;
1166 /* create directory/directories */
1167 strcpyW(szBuildPath
, pszPath
);
1168 p
= strchrW(szBuildPath
, '\\');
1172 if (!PathFileExistsW(szBuildPath
))
1174 if (!CreateDirectoryW(szBuildPath
,NULL
))
1176 ERR("Failed to create directory '%s'.\n", debugstr_w(pszPath
));
1181 p
= strchrW(p
+1, '\\');
1183 /* last component must be created too. */
1184 if (!PathFileExistsW(szBuildPath
))
1186 if (!CreateDirectoryW(szBuildPath
,NULL
))
1188 ERR("Failed to create directory '%s'.\n", debugstr_w(pszPath
));
1193 TRACE("Created missing system directory '%s'\n", debugstr_w(pszPath
));
1197 /*************************************************************************
1198 * SHGetFolderPathA [SHELL32.@]
1200 HRESULT WINAPI
SHGetFolderPathA(
1207 WCHAR szTemp
[MAX_PATH
];
1210 hr
= SHGetFolderPathW(hwndOwner
, csidl
, hToken
, dwFlags
, szTemp
);
1213 if (!WideCharToMultiByte( CP_ACP
, 0, szTemp
, -1, pszPath
, MAX_PATH
, NULL
, NULL
))
1214 pszPath
[MAX_PATH
- 1] = 0;
1217 TRACE("%p,%p,csidl=0x%04x\n",hwndOwner
,pszPath
,csidl
);
1222 /*************************************************************************
1223 * SHGetSpecialFolderPathA [SHELL32.@]
1225 BOOL WINAPI
SHGetSpecialFolderPathA (
1231 return (SHGetFolderPathA(
1233 csidl
+ (bCreate
? CSIDL_FLAG_CREATE
: 0),
1236 szPath
)) == S_OK
? TRUE
: FALSE
;
1239 /*************************************************************************
1240 * SHGetSpecialFolderPathW
1242 BOOL WINAPI
SHGetSpecialFolderPathW (
1248 return (SHGetFolderPathW(
1250 csidl
+ (bCreate
? CSIDL_FLAG_CREATE
: 0),
1253 szPath
)) == S_OK
? TRUE
: FALSE
;
1256 /*************************************************************************
1257 * SHGetSpecialFolderPath (SHELL32.175)
1259 BOOL WINAPI
SHGetSpecialFolderPathAW (
1266 if (SHELL_OsIsUnicode())
1267 return SHGetSpecialFolderPathW (hwndOwner
, szPath
, csidl
, bCreate
);
1268 return SHGetSpecialFolderPathA (hwndOwner
, szPath
, csidl
, bCreate
);