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/debug.h"
33 #include "shell32_main.h"
34 #include "undocshell.h"
35 #include "wine/unicode.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(shell);
41 ########## Combining and Constructing paths ##########
44 /*************************************************************************
45 * PathAppend [SHELL32.36]
47 BOOL WINAPI PathAppendAW(
51 if (SHELL_OsIsUnicode())
52 return PathAppendW(lpszPath1, lpszPath2);
53 return PathAppendA(lpszPath1, lpszPath2);
56 /*************************************************************************
57 * PathCombine [SHELL32.37]
59 LPVOID WINAPI PathCombineAW(
64 if (SHELL_OsIsUnicode())
65 return PathCombineW( szDest, lpszDir, lpszFile );
66 return PathCombineA( szDest, lpszDir, lpszFile );
69 /*************************************************************************
70 * PathAddBackslash [SHELL32.32]
72 LPVOID WINAPI PathAddBackslashAW(LPVOID lpszPath)
74 if(SHELL_OsIsUnicode())
75 return PathAddBackslashW(lpszPath);
76 return PathAddBackslashA(lpszPath);
79 /*************************************************************************
80 * PathBuildRoot [SHELL32.30]
82 LPVOID WINAPI PathBuildRootAW(LPVOID lpszPath, int drive)
84 if(SHELL_OsIsUnicode())
85 return PathBuildRootW(lpszPath, drive);
86 return PathBuildRootA(lpszPath, drive);
90 Extracting Component Parts
93 /*************************************************************************
94 * PathFindFileName [SHELL32.34]
96 LPVOID WINAPI PathFindFileNameAW(LPCVOID lpszPath)
98 if(SHELL_OsIsUnicode())
99 return PathFindFileNameW(lpszPath);
100 return PathFindFileNameA(lpszPath);
103 /*************************************************************************
104 * PathFindExtension [SHELL32.31]
106 LPVOID WINAPI PathFindExtensionAW(LPCVOID lpszPath)
108 if (SHELL_OsIsUnicode())
109 return PathFindExtensionW(lpszPath);
110 return PathFindExtensionA(lpszPath);
114 /*************************************************************************
115 * PathGetExtensionA [internal]
118 * exported by ordinal
119 * return value points to the first char after the dot
121 static LPSTR PathGetExtensionA(LPCSTR lpszPath)
123 TRACE("(%s)\n",lpszPath);
125 lpszPath = PathFindExtensionA(lpszPath);
126 return (LPSTR)(*lpszPath?(lpszPath+1):lpszPath);
129 /*************************************************************************
130 * PathGetExtensionW [internal]
132 static LPWSTR PathGetExtensionW(LPCWSTR lpszPath)
134 TRACE("(%s)\n",debugstr_w(lpszPath));
136 lpszPath = PathFindExtensionW(lpszPath);
137 return (LPWSTR)(*lpszPath?(lpszPath+1):lpszPath);
140 /*************************************************************************
141 * PathGetExtension [SHELL32.158]
143 LPVOID WINAPI PathGetExtensionAW(LPCVOID lpszPath,DWORD void1, DWORD void2)
145 if (SHELL_OsIsUnicode())
146 return PathGetExtensionW(lpszPath);
147 return PathGetExtensionA(lpszPath);
150 /*************************************************************************
151 * PathGetArgs [SHELL32.52]
153 LPVOID WINAPI PathGetArgsAW(LPVOID lpszPath)
155 if (SHELL_OsIsUnicode())
156 return PathGetArgsW(lpszPath);
157 return PathGetArgsA(lpszPath);
160 /*************************************************************************
161 * PathGetDriveNumber [SHELL32.57]
163 int WINAPI PathGetDriveNumberAW(LPVOID lpszPath)
165 if (SHELL_OsIsUnicode())
166 return PathGetDriveNumberW(lpszPath);
167 return PathGetDriveNumberA(lpszPath);
170 /*************************************************************************
171 * PathRemoveFileSpec [SHELL32.35]
173 BOOL WINAPI PathRemoveFileSpecAW(LPVOID lpszPath)
175 if (SHELL_OsIsUnicode())
176 return PathRemoveFileSpecW(lpszPath);
177 return PathRemoveFileSpecA(lpszPath);
180 /*************************************************************************
181 * PathStripPath [SHELL32.38]
183 void WINAPI PathStripPathAW(LPVOID lpszPath)
185 if (SHELL_OsIsUnicode())
186 return PathStripPathW(lpszPath);
187 return PathStripPathA(lpszPath);
190 /*************************************************************************
191 * PathStripToRoot [SHELL32.50]
193 BOOL WINAPI PathStripToRootAW(LPVOID lpszPath)
195 if (SHELL_OsIsUnicode())
196 return PathStripToRootW(lpszPath);
197 return PathStripToRootA(lpszPath);
200 /*************************************************************************
201 * PathRemoveArgs [SHELL32.251]
203 void WINAPI PathRemoveArgsAW(LPVOID lpszPath)
205 if (SHELL_OsIsUnicode())
206 PathRemoveArgsW(lpszPath);
207 PathRemoveArgsA(lpszPath);
210 /*************************************************************************
211 * PathRemoveExtension [SHELL32.250]
213 void WINAPI PathRemoveExtensionAW(LPVOID lpszPath)
215 if (SHELL_OsIsUnicode())
216 return PathRemoveExtensionW(lpszPath);
217 return PathRemoveExtensionA(lpszPath);
225 /*************************************************************************
226 * PathGetShortPathA [internal]
228 LPSTR WINAPI PathGetShortPathA(LPSTR lpszPath)
230 FIXME("%s stub\n", lpszPath);
234 /*************************************************************************
235 * PathGetShortPathW [internal]
237 LPWSTR WINAPI PathGetShortPathW(LPWSTR lpszPath)
239 FIXME("%s stub\n", debugstr_w(lpszPath));
243 /*************************************************************************
244 * PathGetShortPath [SHELL32.92]
246 LPVOID WINAPI PathGetShortPathAW(LPVOID lpszPath)
248 if(SHELL_OsIsUnicode())
249 return PathGetShortPathW(lpszPath);
250 return PathGetShortPathA(lpszPath);
253 /*************************************************************************
254 * PathRemoveBlanks [SHELL32.33]
256 void WINAPI PathRemoveBlanksAW(LPVOID str)
258 if(SHELL_OsIsUnicode())
259 PathRemoveBlanksW(str);
260 PathRemoveBlanksA(str);
263 /*************************************************************************
264 * PathQuoteSpaces [SHELL32.55]
266 VOID WINAPI PathQuoteSpacesAW (LPVOID lpszPath)
268 if(SHELL_OsIsUnicode())
269 return PathQuoteSpacesW(lpszPath);
270 return PathQuoteSpacesA(lpszPath);
273 /*************************************************************************
274 * PathUnquoteSpaces [SHELL32.56]
276 VOID WINAPI PathUnquoteSpacesAW(LPVOID str)
278 if(SHELL_OsIsUnicode())
279 PathUnquoteSpacesW(str);
281 PathUnquoteSpacesA(str);
284 /*************************************************************************
285 * PathParseIconLocation [SHELL32.249]
287 int WINAPI PathParseIconLocationAW (LPVOID lpszPath)
289 if(SHELL_OsIsUnicode())
290 return PathParseIconLocationW(lpszPath);
291 return PathParseIconLocationA(lpszPath);
295 ########## Path Testing ##########
297 /*************************************************************************
298 * PathIsUNC [SHELL32.39]
300 BOOL WINAPI PathIsUNCAW (LPCVOID lpszPath)
302 if (SHELL_OsIsUnicode())
303 return PathIsUNCW( lpszPath );
304 return PathIsUNCA( lpszPath );
307 /*************************************************************************
308 * PathIsRelative [SHELL32.40]
310 BOOL WINAPI PathIsRelativeAW (LPCVOID lpszPath)
312 if (SHELL_OsIsUnicode())
313 return PathIsRelativeW( lpszPath );
314 return PathIsRelativeA( lpszPath );
317 /*************************************************************************
318 * PathIsRoot [SHELL32.29]
320 BOOL WINAPI PathIsRootAW(LPCVOID lpszPath)
322 if (SHELL_OsIsUnicode())
323 return PathIsRootW(lpszPath);
324 return PathIsRootA(lpszPath);
327 /*************************************************************************
328 * PathIsExeA [internal]
330 static BOOL PathIsExeA (LPCSTR lpszPath)
332 LPCSTR lpszExtension = PathGetExtensionA(lpszPath);
334 static char * lpszExtensions[6] = {"exe", "com", "pid", "cmd", "bat", NULL };
336 TRACE("path=%s\n",lpszPath);
338 for(i=0; lpszExtensions[i]; i++)
339 if (!strcasecmp(lpszExtension,lpszExtensions[i])) return TRUE;
344 /*************************************************************************
345 * PathIsExeW [internal]
347 static BOOL PathIsExeW (LPCWSTR lpszPath)
349 LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
351 static WCHAR lpszExtensions[6][4] =
352 {{'e','x','e','\0'}, {'c','o','m','\0'}, {'p','i','d','\0'},
353 {'c','m','d','\0'}, {'b','a','t','\0'}, {'\0'} };
355 TRACE("path=%s\n",debugstr_w(lpszPath));
357 for(i=0; lpszExtensions[i][0]; i++)
358 if (!strcmpiW(lpszExtension,lpszExtensions[i])) return TRUE;
363 /*************************************************************************
364 * PathIsExe [SHELL32.43]
366 BOOL WINAPI PathIsExeAW (LPCVOID path)
368 if (SHELL_OsIsUnicode())
369 return PathIsExeW (path);
370 return PathIsExeA(path);
373 /*************************************************************************
374 * PathIsDirectory [SHELL32.159]
376 BOOL WINAPI PathIsDirectoryAW (LPCVOID lpszPath)
378 if (SHELL_OsIsUnicode())
379 return PathIsDirectoryW (lpszPath);
380 return PathIsDirectoryA (lpszPath);
383 /*************************************************************************
384 * PathFileExists [SHELL32.45]
386 BOOL WINAPI PathFileExistsAW (LPCVOID lpszPath)
388 if (SHELL_OsIsUnicode())
389 return PathFileExistsW (lpszPath);
390 return PathFileExistsA (lpszPath);
393 /*************************************************************************
394 * PathMatchSpec [SHELL32.46]
396 BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
398 if (SHELL_OsIsUnicode())
399 return PathMatchSpecW( name, mask );
400 return PathMatchSpecA( name, mask );
403 /*************************************************************************
404 * PathIsSameRoot [SHELL32.650]
406 BOOL WINAPI PathIsSameRootAW(LPCVOID lpszPath1, LPCVOID lpszPath2)
408 if (SHELL_OsIsUnicode())
409 return PathIsSameRootW(lpszPath1, lpszPath2);
410 return PathIsSameRootA(lpszPath1, lpszPath2);
413 /*************************************************************************
414 * IsLFNDrive [SHELL32.119]
417 * exported by ordinal Name
419 BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath)
423 if (!GetVolumeInformationA(lpszPath,NULL,0,NULL,&fnlen,NULL,NULL,0))
429 ########## Creating Something Unique ##########
431 /*************************************************************************
432 * PathMakeUniqueNameA [internal]
434 BOOL WINAPI PathMakeUniqueNameA(
437 LPCSTR lpszShortName,
441 FIXME("%p %lu %s %s %s stub\n",
442 lpszBuffer, dwBuffSize, debugstr_a(lpszShortName),
443 debugstr_a(lpszLongName), debugstr_a(lpszPathName));
447 /*************************************************************************
448 * PathMakeUniqueNameW [internal]
450 BOOL WINAPI PathMakeUniqueNameW(
453 LPCWSTR lpszShortName,
454 LPCWSTR lpszLongName,
455 LPCWSTR lpszPathName)
457 FIXME("%p %lu %s %s %s stub\n",
458 lpszBuffer, dwBuffSize, debugstr_w(lpszShortName),
459 debugstr_w(lpszLongName), debugstr_w(lpszPathName));
463 /*************************************************************************
464 * PathMakeUniqueName [SHELL32.47]
466 BOOL WINAPI PathMakeUniqueNameAW(
469 LPCVOID lpszShortName,
470 LPCVOID lpszLongName,
471 LPCVOID lpszPathName)
473 if (SHELL_OsIsUnicode())
474 return PathMakeUniqueNameW(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
475 return PathMakeUniqueNameA(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
478 /*************************************************************************
479 * PathYetAnotherMakeUniqueName [SHELL32.75]
482 * exported by ordinal
484 BOOL WINAPI PathYetAnotherMakeUniqueNameA(
487 LPCSTR lpszShortName,
490 FIXME("(%p,%p, %p ,%p):stub.\n",
491 lpszBuffer, lpszPathName, lpszShortName, lpszLongName);
497 ########## cleaning and resolving paths ##########
500 /*************************************************************************
501 * PathFindOnPath [SHELL32.145]
503 BOOL WINAPI PathFindOnPathAW(LPVOID sFile, LPCVOID sOtherDirs)
505 if (SHELL_OsIsUnicode())
506 return PathFindOnPathW(sFile, (LPCWSTR *)sOtherDirs);
507 return PathFindOnPathA(sFile, (LPCSTR *)sOtherDirs);
510 /*************************************************************************
511 * PathCleanupSpec [SHELL32.171]
513 DWORD WINAPI PathCleanupSpecAW (LPCVOID x, LPVOID y)
515 FIXME("(%p, %p) stub\n",x,y);
519 /*************************************************************************
520 * PathQualifyA [SHELL32]
522 BOOL WINAPI PathQualifyA(LPCSTR pszPath)
524 FIXME("%s\n",pszPath);
528 /*************************************************************************
529 * PathQualifyW [SHELL32]
531 BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
533 FIXME("%s\n",debugstr_w(pszPath));
537 /*************************************************************************
538 * PathQualify [SHELL32.49]
540 BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
542 if (SHELL_OsIsUnicode())
543 return PathQualifyW(pszPath);
544 return PathQualifyA(pszPath);
547 /*************************************************************************
548 * PathResolveA [SHELL32.51]
550 BOOL WINAPI PathResolveA(
555 FIXME("(%s,%p,0x%08lx),stub!\n",
556 lpszPath, *alpszPaths, dwFlags);
560 /*************************************************************************
561 * PathResolveW [SHELL32]
563 BOOL WINAPI PathResolveW(
568 FIXME("(%s,%p,0x%08lx),stub!\n",
569 debugstr_w(lpszPath), debugstr_w(*alpszPaths), dwFlags);
573 /*************************************************************************
574 * PathResolve [SHELL32.51]
576 BOOL WINAPI PathResolveAW(
581 if (SHELL_OsIsUnicode())
582 return PathResolveW(lpszPath, (LPCWSTR*)alpszPaths, dwFlags);
583 return PathResolveA(lpszPath, (LPCSTR*)alpszPaths, dwFlags);
586 /*************************************************************************
587 * PathProcessCommandA [SHELL32.653]
589 HRESULT WINAPI PathProcessCommandA (
595 FIXME("%s %p 0x%04lx 0x%04lx stub\n",
596 lpszPath, lpszBuff, dwBuffSize, dwFlags);
597 strcpy(lpszBuff, lpszPath);
601 /*************************************************************************
602 * PathProcessCommandW
604 HRESULT WINAPI PathProcessCommandW (
610 FIXME("(%s, %p, 0x%04lx, 0x%04lx) stub\n",
611 debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags);
612 strcpyW(lpszBuff, lpszPath);
616 /*************************************************************************
617 * PathProcessCommand (SHELL32.653)
619 HRESULT WINAPI PathProcessCommandAW (
625 if (SHELL_OsIsUnicode())
626 return PathProcessCommandW(lpszPath, lpszBuff, dwBuffSize, dwFlags);
627 return PathProcessCommandA(lpszPath, lpszBuff, dwBuffSize, dwFlags);
631 ########## special ##########
634 /*************************************************************************
635 * PathSetDlgItemPath (SHELL32.48)
637 VOID WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
638 { if (SHELL_OsIsUnicode())
639 return PathSetDlgItemPathW(hDlg, id, pszPath);
640 return PathSetDlgItemPathA(hDlg, id, pszPath);
644 /*************************************************************************
645 * SHGetSpecialFolderPathA [SHELL32.@]
647 * converts csidl to path
650 static const char * const szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
651 static const char * const szSHUserFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
652 static const char * const szSetup = "Software\\Microsoft\\Windows\\CurrentVersion\\Setup";
653 static const char * const szCurrentVersion = "Software\\Microsoft\\Windows\\CurrentVersion";
655 static const char * const szEnvUserProfile = "%USERPROFILE%";
656 static const char * const szEnvSystemRoot = "%SYSTEMROOT%";
664 LPCSTR szDefaultPath; /* fallback string; sub dir of windows directory */
667 #define CSIDL_MYFLAG_SHFOLDER 1
668 #define CSIDL_MYFLAG_SETUP 2
669 #define CSIDL_MYFLAG_CURRVER 4
670 #define CSIDL_MYFLAG_RELATIVE 8
672 #define HKLM HKEY_LOCAL_MACHINE
673 #define HKCU HKEY_CURRENT_USER
674 static const CSIDL_DATA CSIDL_Data[] =
676 { /* CSIDL_DESKTOP */
681 { /* CSIDL_INTERNET */
686 { /* CSIDL_PROGRAMS */
689 "Start Menu\\Programs"
691 { /* CSIDL_CONTROLS (.CPL files) */
696 { /* CSIDL_PRINTERS */
701 { /* CSIDL_PERSONAL */
706 { /* CSIDL_FAVORITES */
711 { /* CSIDL_STARTUP */
714 "Start Menu\\Programs\\StartUp"
726 { /* CSIDL_BITBUCKET (is this c:\recycled ?) */
731 { /* CSIDL_STARTMENU */
736 { /* CSIDL_MYDOCUMENTS */
741 { /* CSIDL_MYMUSIC */
746 { /* CSIDL_MYVIDEO */
756 { /* CSIDL_DESKTOPDIRECTORY */
766 { /* CSIDL_NETWORK */
769 "Network Neighborhood"
771 { /* CSIDL_NETHOOD */
781 { /* CSIDL_TEMPLATES */
786 { /* CSIDL_COMMON_STARTMENU */
791 { /* CSIDL_COMMON_PROGRAMS */
796 { /* CSIDL_COMMON_STARTUP */
799 "All Users\\Start Menu\\Programs\\StartUp"
801 { /* CSIDL_COMMON_DESKTOPDIRECTORY */
806 { /* CSIDL_APPDATA */
811 { /* CSIDL_PRINTHOOD */
816 { /* CSIDL_LOCAL_APPDATA (win2k only/undocumented) */
819 "Local Settings\\Application Data",
821 { /* CSIDL_ALTSTARTUP */
826 { /* CSIDL_COMMON_ALTSTARTUP */
831 { /* CSIDL_COMMON_FAVORITES */
836 { /* CSIDL_INTERNET_CACHE */
839 "Temporary Internet Files"
841 { /* CSIDL_COOKIES */
846 { /* CSIDL_HISTORY */
851 { /* CSIDL_COMMON_APPDATA */
854 "All Users\\Application Data"
856 { /* CSIDL_WINDOWS */
866 { /* CSIDL_PROGRAM_FILES */
871 { /* CSIDL_MYPICTURES */
874 "My Documents\\My Pictures"
876 { /* CSIDL_PROFILE */
878 "WinDir", /* correct ? */
881 { /* CSIDL_SYSTEMX86 */
886 { /* CSIDL_PROGRAM_FILESX86 */
891 { /* CSIDL_PROGRAM_FILES_COMMON */
894 "Program Files\\Common Files" /* ? */
896 { /* CSIDL_PROGRAM_FILES_COMMONX86 */
899 "Program Files\\Common Files" /* ? */
901 { /* CSIDL_COMMON_TEMPLATES */
906 { /* CSIDL_COMMON_DOCUMENTS */
911 { /* CSIDL_COMMON_ADMINTOOLS */
916 { /* CSIDL_ADMINTOOLS */
918 "Administrative Tools",
919 "Start Menu\\Programs\\Administrative Tools"
921 { /* CSIDL_CONNECTIONS */
941 { /* CSIDL_COMMON_MUSIC */
946 { /* CSIDL_COMMON_PICTURES */
951 { /* CSIDL_COMMON_VIDEO */
956 { /* CSIDL_RESOURCES */
961 { /* CSIDL_RESOURCES_LOCALIZED */
966 { /* CSIDL_COMMON_OEM_LINKS */
971 { /* CSIDL_CDBURN_AREA */
976 { /* unassigned 3C */
981 { /* CSIDL_COMPUTERSNEARME */
990 /**********************************************************************/
992 BOOL WINAPI SHGetSpecialFolderPathA (
998 CHAR szValueName[MAX_PATH], szDefaultPath[MAX_PATH], szBuildPath[MAX_PATH];
1001 DWORD dwType, dwDisp, dwPathLen = MAX_PATH;
1002 DWORD folder = csidl & CSIDL_FOLDER_MASK;
1005 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
1007 if ((folder > CSIDL_COMPUTERSNEARME) || (CSIDL_Data[folder].hRootKey == 0))
1009 ERR("folder unknown or not allowed\n");
1012 if (CSIDL_Data[folder].hRootKey == 1)
1014 FIXME("folder unknown, please add.\n");
1018 dwFlags = CSIDL_Data[folder].dwFlags;
1019 hRootKey = CSIDL_Data[folder].hRootKey;
1020 strcpy(szValueName, CSIDL_Data[folder].szValueName);
1021 strcpy(szDefaultPath, CSIDL_Data[folder].szDefaultPath);
1023 if (dwFlags & CSIDL_MYFLAG_SHFOLDER)
1025 /* user shell folders */
1026 if (RegCreateKeyExA(hRootKey,szSHUserFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1028 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1033 if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1035 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1038 /* value not existing */
1039 if (dwFlags & CSIDL_MYFLAG_RELATIVE)
1041 GetWindowsDirectoryA(szPath, MAX_PATH);
1042 PathAddBackslashA(szPath);
1043 strcat(szPath, szDefaultPath);
1047 strcpy(szPath, "C:\\"); /* FIXME ??? */
1048 strcat(szPath, szDefaultPath);
1050 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
1059 if (dwFlags & CSIDL_MYFLAG_SETUP)
1062 if (dwFlags & CSIDL_MYFLAG_CURRVER)
1063 pRegPath = szCurrentVersion;
1066 ERR("folder settings broken, please correct !\n");
1070 if (RegCreateKeyExA(hRootKey,pRegPath,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1072 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1074 /* value not existing */
1075 if (dwFlags & CSIDL_MYFLAG_RELATIVE)
1077 GetWindowsDirectoryA(szPath, MAX_PATH);
1078 PathAddBackslashA(szPath);
1079 strcat(szPath, szDefaultPath);
1083 strcpy(szPath, "C:\\"); /* FIXME ??? */
1084 strcat(szPath, szDefaultPath);
1086 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
1091 /* expand paths like %USERPROFILE% */
1092 if (dwType == REG_EXPAND_SZ)
1094 ExpandEnvironmentStringsA(szPath, szDefaultPath, MAX_PATH);
1095 strcpy(szPath, szDefaultPath);
1098 /* if we don't care about existing directories we are ready */
1099 if(csidl & CSIDL_FLAG_DONT_VERIFY) return TRUE;
1101 if (PathFileExistsA(szPath)) return TRUE;
1103 /* not existing but we are not allowed to create it */
1104 if (!bCreate) return FALSE;
1106 /* create directory/directories */
1107 strcpy(szBuildPath, szPath);
1108 p = strchr(szBuildPath, '\\');
1112 if (!PathFileExistsA(szBuildPath))
1114 if (!CreateDirectoryA(szBuildPath,NULL))
1116 ERR("Failed to create directory '%s'.\n", szPath);
1121 p = strchr(p+1, '\\');
1123 /* last component must be created too. */
1124 if (!PathFileExistsA(szBuildPath))
1126 if (!CreateDirectoryA(szBuildPath,NULL))
1128 ERR("Failed to create directory '%s'.\n", szPath);
1133 MESSAGE("Created not existing system directory '%s'\n", szPath);
1137 /*************************************************************************
1138 * SHGetSpecialFolderPathW
1140 BOOL WINAPI SHGetSpecialFolderPathW (
1146 char szTemp[MAX_PATH];
1148 if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate))
1150 if (!MultiByteToWideChar( CP_ACP, 0, szTemp, -1, szPath, MAX_PATH ))
1151 szPath[MAX_PATH-1] = 0;
1154 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
1159 /*************************************************************************
1160 * SHGetSpecialFolderPath (SHELL32.175)
1162 BOOL WINAPI SHGetSpecialFolderPathAW (
1169 if (SHELL_OsIsUnicode())
1170 return SHGetSpecialFolderPathW (hwndOwner, szPath, csidl, bCreate);
1171 return SHGetSpecialFolderPathA (hwndOwner, szPath, csidl, bCreate);
1174 /*************************************************************************
1175 * SHGetFolderPathA [SHELL32.@]
1177 HRESULT WINAPI SHGetFolderPathA(
1180 HANDLE hToken, /* [in] FIXME: get paths for specific user */
1181 DWORD dwFlags, /* [in] FIXME: SHGFP_TYPE_CURRENT|SHGFP_TYPE_DEFAULT */
1184 return (SHGetSpecialFolderPathA(
1187 CSIDL_FOLDER_MASK & nFolder,
1188 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;
1191 /*************************************************************************
1192 * SHGetFolderPathW [SHELL32.@]
1194 HRESULT WINAPI SHGetFolderPathW(
1201 return (SHGetSpecialFolderPathW(
1204 CSIDL_FOLDER_MASK & nFolder,
1205 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;