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 LPSTR WINAPI
PathGetShortPathA(LPSTR lpszPath
)
241 FIXME("%s stub\n", lpszPath
);
245 /*************************************************************************
246 * PathGetShortPathW [internal]
248 LPWSTR WINAPI
PathGetShortPathW(LPWSTR lpszPath
)
250 FIXME("%s stub\n", debugstr_w(lpszPath
));
254 /*************************************************************************
255 * PathGetShortPath [SHELL32.92]
257 LPVOID WINAPI
PathGetShortPathAW(LPVOID lpszPath
)
259 if(SHELL_OsIsUnicode())
260 return PathGetShortPathW(lpszPath
);
261 return PathGetShortPathA(lpszPath
);
264 /*************************************************************************
265 * PathRemoveBlanks [SHELL32.33]
267 void WINAPI
PathRemoveBlanksAW(LPVOID str
)
269 if(SHELL_OsIsUnicode())
270 PathRemoveBlanksW(str
);
272 PathRemoveBlanksA(str
);
275 /*************************************************************************
276 * PathQuoteSpaces [SHELL32.55]
278 VOID WINAPI
PathQuoteSpacesAW (LPVOID lpszPath
)
280 if(SHELL_OsIsUnicode())
281 PathQuoteSpacesW(lpszPath
);
283 PathQuoteSpacesA(lpszPath
);
286 /*************************************************************************
287 * PathUnquoteSpaces [SHELL32.56]
289 VOID WINAPI
PathUnquoteSpacesAW(LPVOID str
)
291 if(SHELL_OsIsUnicode())
292 PathUnquoteSpacesW(str
);
294 PathUnquoteSpacesA(str
);
297 /*************************************************************************
298 * PathParseIconLocation [SHELL32.249]
300 int WINAPI
PathParseIconLocationAW (LPVOID lpszPath
)
302 if(SHELL_OsIsUnicode())
303 return PathParseIconLocationW(lpszPath
);
304 return PathParseIconLocationA(lpszPath
);
308 ########## Path Testing ##########
310 /*************************************************************************
311 * PathIsUNC [SHELL32.39]
313 BOOL WINAPI
PathIsUNCAW (LPCVOID lpszPath
)
315 if (SHELL_OsIsUnicode())
316 return PathIsUNCW( lpszPath
);
317 return PathIsUNCA( lpszPath
);
320 /*************************************************************************
321 * PathIsRelative [SHELL32.40]
323 BOOL WINAPI
PathIsRelativeAW (LPCVOID lpszPath
)
325 if (SHELL_OsIsUnicode())
326 return PathIsRelativeW( lpszPath
);
327 return PathIsRelativeA( lpszPath
);
330 /*************************************************************************
331 * PathIsRoot [SHELL32.29]
333 BOOL WINAPI
PathIsRootAW(LPCVOID lpszPath
)
335 if (SHELL_OsIsUnicode())
336 return PathIsRootW(lpszPath
);
337 return PathIsRootA(lpszPath
);
340 /*************************************************************************
341 * PathIsExeA [internal]
343 static BOOL
PathIsExeA (LPCSTR lpszPath
)
345 LPCSTR lpszExtension
= PathGetExtensionA(lpszPath
);
347 static const char * const lpszExtensions
[] =
348 {"exe", "com", "pif", "cmd", "bat", "scf", "scr", NULL
};
350 TRACE("path=%s\n",lpszPath
);
352 for(i
=0; lpszExtensions
[i
]; i
++)
353 if (!strcasecmp(lpszExtension
,lpszExtensions
[i
])) return TRUE
;
358 /*************************************************************************
359 * PathIsExeW [internal]
361 static BOOL
PathIsExeW (LPCWSTR lpszPath
)
363 LPCWSTR lpszExtension
= PathGetExtensionW(lpszPath
);
365 static const WCHAR lpszExtensions
[][4] =
366 {{'e','x','e','\0'}, {'c','o','m','\0'}, {'p','i','f','\0'},
367 {'c','m','d','\0'}, {'b','a','t','\0'}, {'s','c','f','\0'},
368 {'s','c','r','\0'}, {'\0'} };
370 TRACE("path=%s\n",debugstr_w(lpszPath
));
372 for(i
=0; lpszExtensions
[i
][0]; i
++)
373 if (!strcmpiW(lpszExtension
,lpszExtensions
[i
])) return TRUE
;
378 /*************************************************************************
379 * PathIsExe [SHELL32.43]
381 BOOL WINAPI
PathIsExeAW (LPCVOID path
)
383 if (SHELL_OsIsUnicode())
384 return PathIsExeW (path
);
385 return PathIsExeA(path
);
388 /*************************************************************************
389 * PathIsDirectory [SHELL32.159]
391 BOOL WINAPI
PathIsDirectoryAW (LPCVOID lpszPath
)
393 if (SHELL_OsIsUnicode())
394 return PathIsDirectoryW (lpszPath
);
395 return PathIsDirectoryA (lpszPath
);
398 /*************************************************************************
399 * PathFileExists [SHELL32.45]
401 BOOL WINAPI
PathFileExistsAW (LPCVOID lpszPath
)
403 if (SHELL_OsIsUnicode())
404 return PathFileExistsW (lpszPath
);
405 return PathFileExistsA (lpszPath
);
408 /*************************************************************************
409 * PathMatchSpec [SHELL32.46]
411 BOOL WINAPI
PathMatchSpecAW(LPVOID name
, LPVOID mask
)
413 if (SHELL_OsIsUnicode())
414 return PathMatchSpecW( name
, mask
);
415 return PathMatchSpecA( name
, mask
);
418 /*************************************************************************
419 * PathIsSameRoot [SHELL32.650]
421 BOOL WINAPI
PathIsSameRootAW(LPCVOID lpszPath1
, LPCVOID lpszPath2
)
423 if (SHELL_OsIsUnicode())
424 return PathIsSameRootW(lpszPath1
, lpszPath2
);
425 return PathIsSameRootA(lpszPath1
, lpszPath2
);
428 /*************************************************************************
429 * IsLFNDriveA [SHELL32.41]
431 BOOL WINAPI
IsLFNDriveA(LPCSTR lpszPath
)
435 if (!GetVolumeInformationA(lpszPath
, NULL
, 0, NULL
, &fnlen
, NULL
, NULL
, 0))
440 /*************************************************************************
441 * IsLFNDriveW [SHELL32.42]
443 BOOL WINAPI
IsLFNDriveW(LPCWSTR lpszPath
)
447 if (!GetVolumeInformationW(lpszPath
, NULL
, 0, NULL
, &fnlen
, NULL
, NULL
, 0))
452 /*************************************************************************
453 * IsLFNDrive [SHELL32.119]
455 BOOL WINAPI
IsLFNDriveAW(LPCVOID lpszPath
)
457 if (SHELL_OsIsUnicode())
458 return IsLFNDriveW(lpszPath
);
459 return IsLFNDriveA(lpszPath
);
463 ########## Creating Something Unique ##########
465 /*************************************************************************
466 * PathMakeUniqueNameA [internal]
468 BOOL WINAPI
PathMakeUniqueNameA(
471 LPCSTR lpszShortName
,
475 FIXME("%p %lu %s %s %s stub\n",
476 lpszBuffer
, dwBuffSize
, debugstr_a(lpszShortName
),
477 debugstr_a(lpszLongName
), debugstr_a(lpszPathName
));
481 /*************************************************************************
482 * PathMakeUniqueNameW [internal]
484 BOOL WINAPI
PathMakeUniqueNameW(
487 LPCWSTR lpszShortName
,
488 LPCWSTR lpszLongName
,
489 LPCWSTR lpszPathName
)
491 FIXME("%p %lu %s %s %s stub\n",
492 lpszBuffer
, dwBuffSize
, debugstr_w(lpszShortName
),
493 debugstr_w(lpszLongName
), debugstr_w(lpszPathName
));
497 /*************************************************************************
498 * PathMakeUniqueName [SHELL32.47]
500 BOOL WINAPI
PathMakeUniqueNameAW(
503 LPCVOID lpszShortName
,
504 LPCVOID lpszLongName
,
505 LPCVOID lpszPathName
)
507 if (SHELL_OsIsUnicode())
508 return PathMakeUniqueNameW(lpszBuffer
,dwBuffSize
, lpszShortName
,lpszLongName
,lpszPathName
);
509 return PathMakeUniqueNameA(lpszBuffer
,dwBuffSize
, lpszShortName
,lpszLongName
,lpszPathName
);
512 /*************************************************************************
513 * PathYetAnotherMakeUniqueName [SHELL32.75]
516 * exported by ordinal
518 BOOL WINAPI
PathYetAnotherMakeUniqueNameA(
521 LPCSTR lpszShortName
,
524 FIXME("(%p,%p, %p ,%p):stub.\n",
525 lpszBuffer
, lpszPathName
, lpszShortName
, lpszLongName
);
531 ########## cleaning and resolving paths ##########
534 /*************************************************************************
535 * PathFindOnPath [SHELL32.145]
537 BOOL WINAPI
PathFindOnPathAW(LPVOID sFile
, LPCVOID sOtherDirs
)
539 if (SHELL_OsIsUnicode())
540 return PathFindOnPathW(sFile
, (LPCWSTR
*)sOtherDirs
);
541 return PathFindOnPathA(sFile
, (LPCSTR
*)sOtherDirs
);
544 /*************************************************************************
545 * PathCleanupSpec [SHELL32.171]
547 DWORD WINAPI
PathCleanupSpecAW (LPCVOID x
, LPVOID y
)
549 FIXME("(%p, %p) stub\n",x
,y
);
553 /*************************************************************************
554 * PathQualifyA [SHELL32]
556 BOOL WINAPI
PathQualifyA(LPCSTR pszPath
)
558 FIXME("%s\n",pszPath
);
562 /*************************************************************************
563 * PathQualifyW [SHELL32]
565 BOOL WINAPI
PathQualifyW(LPCWSTR pszPath
)
567 FIXME("%s\n",debugstr_w(pszPath
));
571 /*************************************************************************
572 * PathQualify [SHELL32.49]
574 BOOL WINAPI
PathQualifyAW(LPCVOID pszPath
)
576 if (SHELL_OsIsUnicode())
577 return PathQualifyW(pszPath
);
578 return PathQualifyA(pszPath
);
581 /*************************************************************************
582 * PathResolveA [SHELL32.51]
584 BOOL WINAPI
PathResolveA(
589 FIXME("(%s,%p,0x%08lx),stub!\n",
590 lpszPath
, *alpszPaths
, dwFlags
);
594 /*************************************************************************
595 * PathResolveW [SHELL32]
597 BOOL WINAPI
PathResolveW(
602 FIXME("(%s,%p,0x%08lx),stub!\n",
603 debugstr_w(lpszPath
), debugstr_w(*alpszPaths
), dwFlags
);
607 /*************************************************************************
608 * PathResolve [SHELL32.51]
610 BOOL WINAPI
PathResolveAW(
615 if (SHELL_OsIsUnicode())
616 return PathResolveW(lpszPath
, (LPCWSTR
*)alpszPaths
, dwFlags
);
617 return PathResolveA(lpszPath
, (LPCSTR
*)alpszPaths
, dwFlags
);
620 /*************************************************************************
621 * PathProcessCommandA [SHELL32.653]
623 HRESULT WINAPI
PathProcessCommandA (
629 FIXME("%s %p 0x%04lx 0x%04lx stub\n",
630 lpszPath
, lpszBuff
, dwBuffSize
, dwFlags
);
631 strcpy(lpszBuff
, lpszPath
);
635 /*************************************************************************
636 * PathProcessCommandW
638 HRESULT WINAPI
PathProcessCommandW (
644 FIXME("(%s, %p, 0x%04lx, 0x%04lx) stub\n",
645 debugstr_w(lpszPath
), lpszBuff
, dwBuffSize
, dwFlags
);
646 strcpyW(lpszBuff
, lpszPath
);
650 /*************************************************************************
651 * PathProcessCommand (SHELL32.653)
653 HRESULT WINAPI
PathProcessCommandAW (
659 if (SHELL_OsIsUnicode())
660 return PathProcessCommandW(lpszPath
, lpszBuff
, dwBuffSize
, dwFlags
);
661 return PathProcessCommandA(lpszPath
, lpszBuff
, dwBuffSize
, dwFlags
);
665 ########## special ##########
668 /*************************************************************************
669 * PathSetDlgItemPath (SHELL32.48)
671 VOID WINAPI
PathSetDlgItemPathAW(HWND hDlg
, int id
, LPCVOID pszPath
)
673 if (SHELL_OsIsUnicode())
674 PathSetDlgItemPathW(hDlg
, id
, pszPath
);
676 PathSetDlgItemPathA(hDlg
, id
, pszPath
);
680 /*************************************************************************
681 * SHGetSpecialFolderPathA [SHELL32.@]
683 * converts csidl to path
686 static const char * const szSHFolders
= "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
687 static const char * const szSHUserFolders
= "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
688 static const char * const szSetup
= "Software\\Microsoft\\Windows\\CurrentVersion\\Setup";
689 static const char * const szCurrentVersion
= "Software\\Microsoft\\Windows\\CurrentVersion";
691 static const char * const szEnvUserProfile
= "%USERPROFILE%";
692 static const char * const szEnvSystemRoot
= "%SYSTEMROOT%";
700 LPCSTR szDefaultPath
; /* fallback string; sub dir of windows directory */
703 #define CSIDL_MYFLAG_SHFOLDER 1
704 #define CSIDL_MYFLAG_SETUP 2
705 #define CSIDL_MYFLAG_CURRVER 4
706 #define CSIDL_MYFLAG_RELATIVE 8
708 #define HKLM HKEY_LOCAL_MACHINE
709 #define HKCU HKEY_CURRENT_USER
710 static const CSIDL_DATA CSIDL_Data
[] =
712 { /* CSIDL_DESKTOP */
717 { /* CSIDL_INTERNET */
718 0, (HKEY
)1, /* FIXME */
722 { /* CSIDL_PROGRAMS */
725 "Start Menu\\Programs"
727 { /* CSIDL_CONTROLS (.CPL files) */
732 { /* CSIDL_PRINTERS */
737 { /* CSIDL_PERSONAL */
742 { /* CSIDL_FAVORITES */
747 { /* CSIDL_STARTUP */
750 "Start Menu\\Programs\\StartUp"
762 { /* CSIDL_BITBUCKET (is this c:\recycled ?) */
763 0, (HKEY
)1, /* FIXME */
767 { /* CSIDL_STARTMENU */
772 { /* CSIDL_MYDOCUMENTS */
773 0, (HKEY
)1, /* FIXME */
777 { /* CSIDL_MYMUSIC */
778 0, (HKEY
)1, /* FIXME */
782 { /* CSIDL_MYVIDEO */
783 0, (HKEY
)1, /* FIXME */
792 { /* CSIDL_DESKTOPDIRECTORY */
798 0, (HKEY
)1, /* FIXME */
802 { /* CSIDL_NETWORK */
803 0, (HKEY
)1, /* FIXME */
805 "Network Neighborhood"
807 { /* CSIDL_NETHOOD */
817 { /* CSIDL_TEMPLATES */
822 { /* CSIDL_COMMON_STARTMENU */
827 { /* CSIDL_COMMON_PROGRAMS */
832 { /* CSIDL_COMMON_STARTUP */
835 "All Users\\Start Menu\\Programs\\StartUp"
837 { /* CSIDL_COMMON_DESKTOPDIRECTORY */
842 { /* CSIDL_APPDATA */
847 { /* CSIDL_PRINTHOOD */
852 { /* CSIDL_LOCAL_APPDATA (win2k only/undocumented) */
855 "Local Settings\\Application Data",
857 { /* CSIDL_ALTSTARTUP */
858 0, (HKEY
)1, /* FIXME */
862 { /* CSIDL_COMMON_ALTSTARTUP */
863 0, (HKEY
)1, /* FIXME */
867 { /* CSIDL_COMMON_FAVORITES */
872 { /* CSIDL_INTERNET_CACHE */
875 "Temporary Internet Files"
877 { /* CSIDL_COOKIES */
882 { /* CSIDL_HISTORY */
887 { /* CSIDL_COMMON_APPDATA */
890 "All Users\\Application Data"
892 { /* CSIDL_WINDOWS */
902 { /* CSIDL_PROGRAM_FILES */
907 { /* CSIDL_MYPICTURES */
910 "My Documents\\My Pictures"
912 { /* CSIDL_PROFILE */
914 "WinDir", /* correct ? */
917 { /* CSIDL_SYSTEMX86 */
922 { /* CSIDL_PROGRAM_FILESX86 */
927 { /* CSIDL_PROGRAM_FILES_COMMON */
930 "Program Files\\Common Files" /* ? */
932 { /* CSIDL_PROGRAM_FILES_COMMONX86 */
935 "Program Files\\Common Files" /* ? */
937 { /* CSIDL_COMMON_TEMPLATES */
938 0, (HKEY
)1, /* FIXME */
942 { /* CSIDL_COMMON_DOCUMENTS */
943 0, (HKEY
)1, /* FIXME */
947 { /* CSIDL_COMMON_ADMINTOOLS */
948 0, (HKEY
)1, /* FIXME */
952 { /* CSIDL_ADMINTOOLS */
954 "Administrative Tools",
955 "Start Menu\\Programs\\Administrative Tools"
957 { /* CSIDL_CONNECTIONS */
958 0, (HKEY
)1, /* FIXME */
977 { /* CSIDL_COMMON_MUSIC */
982 { /* CSIDL_COMMON_PICTURES */
987 { /* CSIDL_COMMON_VIDEO */
992 { /* CSIDL_RESOURCES */
997 { /* CSIDL_RESOURCES_LOCALIZED */
1002 { /* CSIDL_COMMON_OEM_LINKS */
1007 { /* CSIDL_CDBURN_AREA */
1012 { /* unassigned 3C */
1017 { /* CSIDL_COMPUTERSNEARME */
1022 { /* CSIDL_PROFILES */
1031 /**********************************************************************/
1033 BOOL WINAPI
SHGetSpecialFolderPathA (
1039 CHAR szValueName
[MAX_PATH
], szDefaultPath
[MAX_PATH
], szBuildPath
[MAX_PATH
];
1040 HKEY hRootKey
, hKey
;
1042 DWORD dwType
, dwDisp
, dwPathLen
= MAX_PATH
;
1043 DWORD folder
= csidl
& CSIDL_FOLDER_MASK
;
1046 TRACE("%p,%p,csidl=%d,0x%04x\n", hwndOwner
,szPath
,csidl
,bCreate
);
1048 if ((folder
>= sizeof(CSIDL_Data
) / sizeof(CSIDL_Data
[0])) ||
1049 (CSIDL_Data
[folder
].hRootKey
== 0))
1051 ERR("folder 0x%04lx unknown or not allowed\n", folder
);
1054 if (CSIDL_Data
[folder
].hRootKey
== (HKEY
)1)
1056 FIXME("folder 0x%04lx unknown, please add.\n", folder
);
1060 dwFlags
= CSIDL_Data
[folder
].dwFlags
;
1061 hRootKey
= CSIDL_Data
[folder
].hRootKey
;
1062 strcpy(szValueName
, CSIDL_Data
[folder
].szValueName
);
1063 strcpy(szDefaultPath
, CSIDL_Data
[folder
].szDefaultPath
);
1065 if (dwFlags
& CSIDL_MYFLAG_SHFOLDER
)
1067 /* user shell folders */
1068 if (RegCreateKeyExA(hRootKey
,szSHUserFolders
,0,NULL
,0,KEY_ALL_ACCESS
,NULL
,&hKey
,&dwDisp
)) return FALSE
;
1070 if (RegQueryValueExA(hKey
,szValueName
,NULL
,&dwType
,(LPBYTE
)szPath
,&dwPathLen
))
1075 if (RegCreateKeyExA(hRootKey
,szSHFolders
,0,NULL
,0,KEY_ALL_ACCESS
,NULL
,&hKey
,&dwDisp
)) return FALSE
;
1077 if (RegQueryValueExA(hKey
,szValueName
,NULL
,&dwType
,(LPBYTE
)szPath
,&dwPathLen
))
1080 /* value not existing */
1081 if (dwFlags
& CSIDL_MYFLAG_RELATIVE
)
1083 GetWindowsDirectoryA(szPath
, MAX_PATH
);
1084 PathAddBackslashA(szPath
);
1085 strcat(szPath
, szDefaultPath
);
1089 strcpy(szPath
, "C:\\"); /* FIXME ??? */
1090 strcat(szPath
, szDefaultPath
);
1092 RegSetValueExA(hKey
,szValueName
,0,REG_SZ
,(LPBYTE
)szPath
,strlen(szPath
)+1);
1101 if (dwFlags
& CSIDL_MYFLAG_SETUP
)
1104 if (dwFlags
& CSIDL_MYFLAG_CURRVER
)
1105 pRegPath
= szCurrentVersion
;
1108 ERR("folder settings broken, please correct !\n");
1112 if (RegCreateKeyExA(hRootKey
,pRegPath
,0,NULL
,0,KEY_ALL_ACCESS
,NULL
,&hKey
,&dwDisp
)) return FALSE
;
1114 if (RegQueryValueExA(hKey
,szValueName
,NULL
,&dwType
,(LPBYTE
)szPath
,&dwPathLen
))
1116 /* value not existing */
1117 if (dwFlags
& CSIDL_MYFLAG_RELATIVE
)
1119 GetWindowsDirectoryA(szPath
, MAX_PATH
);
1120 PathAddBackslashA(szPath
);
1121 strcat(szPath
, szDefaultPath
);
1125 strcpy(szPath
, "C:\\"); /* FIXME ??? */
1126 strcat(szPath
, szDefaultPath
);
1128 RegSetValueExA(hKey
,szValueName
,0,REG_SZ
,(LPBYTE
)szPath
,strlen(szPath
)+1);
1133 /* expand paths like %USERPROFILE% */
1134 if (dwType
== REG_EXPAND_SZ
)
1136 ExpandEnvironmentStringsA(szPath
, szDefaultPath
, MAX_PATH
);
1137 strcpy(szPath
, szDefaultPath
);
1140 /* if we don't care about existing directories we are ready */
1141 if(csidl
& CSIDL_FLAG_DONT_VERIFY
) return TRUE
;
1143 if (PathFileExistsA(szPath
)) return TRUE
;
1145 /* not existing but we are not allowed to create it */
1146 if (!bCreate
) return FALSE
;
1148 /* create directory/directories */
1149 strcpy(szBuildPath
, szPath
);
1150 p
= strchr(szBuildPath
, '\\');
1154 if (!PathFileExistsA(szBuildPath
))
1156 if (!CreateDirectoryA(szBuildPath
,NULL
))
1158 ERR("Failed to create directory '%s'.\n", szPath
);
1163 p
= strchr(p
+1, '\\');
1165 /* last component must be created too. */
1166 if (!PathFileExistsA(szBuildPath
))
1168 if (!CreateDirectoryA(szBuildPath
,NULL
))
1170 ERR("Failed to create directory '%s'.\n", szPath
);
1175 TRACE("Created missing system directory '%s'\n", szPath
);
1179 /*************************************************************************
1180 * SHGetSpecialFolderPathW
1182 BOOL WINAPI
SHGetSpecialFolderPathW (
1188 char szTemp
[MAX_PATH
];
1190 if (SHGetSpecialFolderPathA(hwndOwner
, szTemp
, csidl
, bCreate
))
1192 if (!MultiByteToWideChar( CP_ACP
, 0, szTemp
, -1, szPath
, MAX_PATH
))
1193 szPath
[MAX_PATH
-1] = 0;
1196 TRACE("%p,%p,csidl=%d,0x%04x\n", hwndOwner
,szPath
,csidl
,bCreate
);
1201 /*************************************************************************
1202 * SHGetSpecialFolderPath (SHELL32.175)
1204 BOOL WINAPI
SHGetSpecialFolderPathAW (
1211 if (SHELL_OsIsUnicode())
1212 return SHGetSpecialFolderPathW (hwndOwner
, szPath
, csidl
, bCreate
);
1213 return SHGetSpecialFolderPathA (hwndOwner
, szPath
, csidl
, bCreate
);
1216 /*************************************************************************
1217 * SHGetFolderPathA [SHELL32.@]
1219 HRESULT WINAPI
SHGetFolderPathA(
1222 HANDLE hToken
, /* [in] FIXME: get paths for specific user */
1223 DWORD dwFlags
, /* [in] FIXME: SHGFP_TYPE_CURRENT|SHGFP_TYPE_DEFAULT */
1226 return (SHGetSpecialFolderPathA(
1229 CSIDL_FOLDER_MASK
& nFolder
,
1230 CSIDL_FLAG_CREATE
& nFolder
)) ? S_OK
: E_FAIL
;
1233 /*************************************************************************
1234 * SHGetFolderPathW [SHELL32.@]
1236 HRESULT WINAPI
SHGetFolderPathW(
1243 return (SHGetSpecialFolderPathW(
1246 CSIDL_FOLDER_MASK
& nFolder
,
1247 CSIDL_FLAG_CREATE
& nFolder
)) ? S_OK
: E_FAIL
;