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 PathStripPathW(lpszPath);
188 PathStripPathA(lpszPath);
191 /*************************************************************************
192 * PathStripToRoot [SHELL32.50]
194 BOOL WINAPI PathStripToRootAW(LPVOID lpszPath)
196 if (SHELL_OsIsUnicode())
197 return PathStripToRootW(lpszPath);
198 return PathStripToRootA(lpszPath);
201 /*************************************************************************
202 * PathRemoveArgs [SHELL32.251]
204 void WINAPI PathRemoveArgsAW(LPVOID lpszPath)
206 if (SHELL_OsIsUnicode())
207 PathRemoveArgsW(lpszPath);
209 PathRemoveArgsA(lpszPath);
212 /*************************************************************************
213 * PathRemoveExtension [SHELL32.250]
215 void WINAPI PathRemoveExtensionAW(LPVOID lpszPath)
217 if (SHELL_OsIsUnicode())
218 PathRemoveExtensionW(lpszPath);
220 PathRemoveExtensionA(lpszPath);
228 /*************************************************************************
229 * PathGetShortPathA [internal]
231 LPSTR WINAPI PathGetShortPathA(LPSTR lpszPath)
233 FIXME("%s stub\n", lpszPath);
237 /*************************************************************************
238 * PathGetShortPathW [internal]
240 LPWSTR WINAPI PathGetShortPathW(LPWSTR lpszPath)
242 FIXME("%s stub\n", debugstr_w(lpszPath));
246 /*************************************************************************
247 * PathGetShortPath [SHELL32.92]
249 LPVOID WINAPI PathGetShortPathAW(LPVOID lpszPath)
251 if(SHELL_OsIsUnicode())
252 return PathGetShortPathW(lpszPath);
253 return PathGetShortPathA(lpszPath);
256 /*************************************************************************
257 * PathRemoveBlanks [SHELL32.33]
259 void WINAPI PathRemoveBlanksAW(LPVOID str)
261 if(SHELL_OsIsUnicode())
262 PathRemoveBlanksW(str);
264 PathRemoveBlanksA(str);
267 /*************************************************************************
268 * PathQuoteSpaces [SHELL32.55]
270 VOID WINAPI PathQuoteSpacesAW (LPVOID lpszPath)
272 if(SHELL_OsIsUnicode())
273 PathQuoteSpacesW(lpszPath);
275 PathQuoteSpacesA(lpszPath);
278 /*************************************************************************
279 * PathUnquoteSpaces [SHELL32.56]
281 VOID WINAPI PathUnquoteSpacesAW(LPVOID str)
283 if(SHELL_OsIsUnicode())
284 PathUnquoteSpacesW(str);
286 PathUnquoteSpacesA(str);
289 /*************************************************************************
290 * PathParseIconLocation [SHELL32.249]
292 int WINAPI PathParseIconLocationAW (LPVOID lpszPath)
294 if(SHELL_OsIsUnicode())
295 return PathParseIconLocationW(lpszPath);
296 return PathParseIconLocationA(lpszPath);
300 ########## Path Testing ##########
302 /*************************************************************************
303 * PathIsUNC [SHELL32.39]
305 BOOL WINAPI PathIsUNCAW (LPCVOID lpszPath)
307 if (SHELL_OsIsUnicode())
308 return PathIsUNCW( lpszPath );
309 return PathIsUNCA( lpszPath );
312 /*************************************************************************
313 * PathIsRelative [SHELL32.40]
315 BOOL WINAPI PathIsRelativeAW (LPCVOID lpszPath)
317 if (SHELL_OsIsUnicode())
318 return PathIsRelativeW( lpszPath );
319 return PathIsRelativeA( lpszPath );
322 /*************************************************************************
323 * PathIsRoot [SHELL32.29]
325 BOOL WINAPI PathIsRootAW(LPCVOID lpszPath)
327 if (SHELL_OsIsUnicode())
328 return PathIsRootW(lpszPath);
329 return PathIsRootA(lpszPath);
332 /*************************************************************************
333 * PathIsExeA [internal]
335 static BOOL PathIsExeA (LPCSTR lpszPath)
337 LPCSTR lpszExtension = PathGetExtensionA(lpszPath);
339 static char * lpszExtensions[6] = {"exe", "com", "pid", "cmd", "bat", NULL };
341 TRACE("path=%s\n",lpszPath);
343 for(i=0; lpszExtensions[i]; i++)
344 if (!strcasecmp(lpszExtension,lpszExtensions[i])) return TRUE;
349 /*************************************************************************
350 * PathIsExeW [internal]
352 static BOOL PathIsExeW (LPCWSTR lpszPath)
354 LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
356 static WCHAR lpszExtensions[6][4] =
357 {{'e','x','e','\0'}, {'c','o','m','\0'}, {'p','i','d','\0'},
358 {'c','m','d','\0'}, {'b','a','t','\0'}, {'\0'} };
360 TRACE("path=%s\n",debugstr_w(lpszPath));
362 for(i=0; lpszExtensions[i][0]; i++)
363 if (!strcmpiW(lpszExtension,lpszExtensions[i])) return TRUE;
368 /*************************************************************************
369 * PathIsExe [SHELL32.43]
371 BOOL WINAPI PathIsExeAW (LPCVOID path)
373 if (SHELL_OsIsUnicode())
374 return PathIsExeW (path);
375 return PathIsExeA(path);
378 /*************************************************************************
379 * PathIsDirectory [SHELL32.159]
381 BOOL WINAPI PathIsDirectoryAW (LPCVOID lpszPath)
383 if (SHELL_OsIsUnicode())
384 return PathIsDirectoryW (lpszPath);
385 return PathIsDirectoryA (lpszPath);
388 /*************************************************************************
389 * PathFileExists [SHELL32.45]
391 BOOL WINAPI PathFileExistsAW (LPCVOID lpszPath)
393 if (SHELL_OsIsUnicode())
394 return PathFileExistsW (lpszPath);
395 return PathFileExistsA (lpszPath);
398 /*************************************************************************
399 * PathMatchSpec [SHELL32.46]
401 BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
403 if (SHELL_OsIsUnicode())
404 return PathMatchSpecW( name, mask );
405 return PathMatchSpecA( name, mask );
408 /*************************************************************************
409 * PathIsSameRoot [SHELL32.650]
411 BOOL WINAPI PathIsSameRootAW(LPCVOID lpszPath1, LPCVOID lpszPath2)
413 if (SHELL_OsIsUnicode())
414 return PathIsSameRootW(lpszPath1, lpszPath2);
415 return PathIsSameRootA(lpszPath1, lpszPath2);
418 /*************************************************************************
419 * IsLFNDrive [SHELL32.119]
422 * exported by ordinal Name
424 BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath)
428 if (!GetVolumeInformationA(lpszPath,NULL,0,NULL,&fnlen,NULL,NULL,0))
434 ########## Creating Something Unique ##########
436 /*************************************************************************
437 * PathMakeUniqueNameA [internal]
439 BOOL WINAPI PathMakeUniqueNameA(
442 LPCSTR lpszShortName,
446 FIXME("%p %lu %s %s %s stub\n",
447 lpszBuffer, dwBuffSize, debugstr_a(lpszShortName),
448 debugstr_a(lpszLongName), debugstr_a(lpszPathName));
452 /*************************************************************************
453 * PathMakeUniqueNameW [internal]
455 BOOL WINAPI PathMakeUniqueNameW(
458 LPCWSTR lpszShortName,
459 LPCWSTR lpszLongName,
460 LPCWSTR lpszPathName)
462 FIXME("%p %lu %s %s %s stub\n",
463 lpszBuffer, dwBuffSize, debugstr_w(lpszShortName),
464 debugstr_w(lpszLongName), debugstr_w(lpszPathName));
468 /*************************************************************************
469 * PathMakeUniqueName [SHELL32.47]
471 BOOL WINAPI PathMakeUniqueNameAW(
474 LPCVOID lpszShortName,
475 LPCVOID lpszLongName,
476 LPCVOID lpszPathName)
478 if (SHELL_OsIsUnicode())
479 return PathMakeUniqueNameW(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
480 return PathMakeUniqueNameA(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
483 /*************************************************************************
484 * PathYetAnotherMakeUniqueName [SHELL32.75]
487 * exported by ordinal
489 BOOL WINAPI PathYetAnotherMakeUniqueNameA(
492 LPCSTR lpszShortName,
495 FIXME("(%p,%p, %p ,%p):stub.\n",
496 lpszBuffer, lpszPathName, lpszShortName, lpszLongName);
502 ########## cleaning and resolving paths ##########
505 /*************************************************************************
506 * PathFindOnPath [SHELL32.145]
508 BOOL WINAPI PathFindOnPathAW(LPVOID sFile, LPCVOID sOtherDirs)
510 if (SHELL_OsIsUnicode())
511 return PathFindOnPathW(sFile, (LPCWSTR *)sOtherDirs);
512 return PathFindOnPathA(sFile, (LPCSTR *)sOtherDirs);
515 /*************************************************************************
516 * PathCleanupSpec [SHELL32.171]
518 DWORD WINAPI PathCleanupSpecAW (LPCVOID x, LPVOID y)
520 FIXME("(%p, %p) stub\n",x,y);
524 /*************************************************************************
525 * PathQualifyA [SHELL32]
527 BOOL WINAPI PathQualifyA(LPCSTR pszPath)
529 FIXME("%s\n",pszPath);
533 /*************************************************************************
534 * PathQualifyW [SHELL32]
536 BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
538 FIXME("%s\n",debugstr_w(pszPath));
542 /*************************************************************************
543 * PathQualify [SHELL32.49]
545 BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
547 if (SHELL_OsIsUnicode())
548 return PathQualifyW(pszPath);
549 return PathQualifyA(pszPath);
552 /*************************************************************************
553 * PathResolveA [SHELL32.51]
555 BOOL WINAPI PathResolveA(
560 FIXME("(%s,%p,0x%08lx),stub!\n",
561 lpszPath, *alpszPaths, dwFlags);
565 /*************************************************************************
566 * PathResolveW [SHELL32]
568 BOOL WINAPI PathResolveW(
573 FIXME("(%s,%p,0x%08lx),stub!\n",
574 debugstr_w(lpszPath), debugstr_w(*alpszPaths), dwFlags);
578 /*************************************************************************
579 * PathResolve [SHELL32.51]
581 BOOL WINAPI PathResolveAW(
586 if (SHELL_OsIsUnicode())
587 return PathResolveW(lpszPath, (LPCWSTR*)alpszPaths, dwFlags);
588 return PathResolveA(lpszPath, (LPCSTR*)alpszPaths, dwFlags);
591 /*************************************************************************
592 * PathProcessCommandA [SHELL32.653]
594 HRESULT WINAPI PathProcessCommandA (
600 FIXME("%s %p 0x%04lx 0x%04lx stub\n",
601 lpszPath, lpszBuff, dwBuffSize, dwFlags);
602 strcpy(lpszBuff, lpszPath);
606 /*************************************************************************
607 * PathProcessCommandW
609 HRESULT WINAPI PathProcessCommandW (
615 FIXME("(%s, %p, 0x%04lx, 0x%04lx) stub\n",
616 debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags);
617 strcpyW(lpszBuff, lpszPath);
621 /*************************************************************************
622 * PathProcessCommand (SHELL32.653)
624 HRESULT WINAPI PathProcessCommandAW (
630 if (SHELL_OsIsUnicode())
631 return PathProcessCommandW(lpszPath, lpszBuff, dwBuffSize, dwFlags);
632 return PathProcessCommandA(lpszPath, lpszBuff, dwBuffSize, dwFlags);
636 ########## special ##########
639 /*************************************************************************
640 * PathSetDlgItemPath (SHELL32.48)
642 VOID WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
644 if (SHELL_OsIsUnicode())
645 PathSetDlgItemPathW(hDlg, id, pszPath);
647 PathSetDlgItemPathA(hDlg, id, pszPath);
651 /*************************************************************************
652 * SHGetSpecialFolderPathA [SHELL32.@]
654 * converts csidl to path
657 static const char * const szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
658 static const char * const szSHUserFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
659 static const char * const szSetup = "Software\\Microsoft\\Windows\\CurrentVersion\\Setup";
660 static const char * const szCurrentVersion = "Software\\Microsoft\\Windows\\CurrentVersion";
662 static const char * const szEnvUserProfile = "%USERPROFILE%";
663 static const char * const szEnvSystemRoot = "%SYSTEMROOT%";
671 LPCSTR szDefaultPath; /* fallback string; sub dir of windows directory */
674 #define CSIDL_MYFLAG_SHFOLDER 1
675 #define CSIDL_MYFLAG_SETUP 2
676 #define CSIDL_MYFLAG_CURRVER 4
677 #define CSIDL_MYFLAG_RELATIVE 8
679 #define HKLM HKEY_LOCAL_MACHINE
680 #define HKCU HKEY_CURRENT_USER
681 static const CSIDL_DATA CSIDL_Data[] =
683 { /* CSIDL_DESKTOP */
688 { /* CSIDL_INTERNET */
693 { /* CSIDL_PROGRAMS */
696 "Start Menu\\Programs"
698 { /* CSIDL_CONTROLS (.CPL files) */
703 { /* CSIDL_PRINTERS */
708 { /* CSIDL_PERSONAL */
713 { /* CSIDL_FAVORITES */
718 { /* CSIDL_STARTUP */
721 "Start Menu\\Programs\\StartUp"
733 { /* CSIDL_BITBUCKET (is this c:\recycled ?) */
738 { /* CSIDL_STARTMENU */
743 { /* CSIDL_MYDOCUMENTS */
748 { /* CSIDL_MYMUSIC */
753 { /* CSIDL_MYVIDEO */
763 { /* CSIDL_DESKTOPDIRECTORY */
773 { /* CSIDL_NETWORK */
776 "Network Neighborhood"
778 { /* CSIDL_NETHOOD */
788 { /* CSIDL_TEMPLATES */
793 { /* CSIDL_COMMON_STARTMENU */
798 { /* CSIDL_COMMON_PROGRAMS */
803 { /* CSIDL_COMMON_STARTUP */
806 "All Users\\Start Menu\\Programs\\StartUp"
808 { /* CSIDL_COMMON_DESKTOPDIRECTORY */
813 { /* CSIDL_APPDATA */
818 { /* CSIDL_PRINTHOOD */
823 { /* CSIDL_LOCAL_APPDATA (win2k only/undocumented) */
826 "Local Settings\\Application Data",
828 { /* CSIDL_ALTSTARTUP */
833 { /* CSIDL_COMMON_ALTSTARTUP */
838 { /* CSIDL_COMMON_FAVORITES */
843 { /* CSIDL_INTERNET_CACHE */
846 "Temporary Internet Files"
848 { /* CSIDL_COOKIES */
853 { /* CSIDL_HISTORY */
858 { /* CSIDL_COMMON_APPDATA */
861 "All Users\\Application Data"
863 { /* CSIDL_WINDOWS */
873 { /* CSIDL_PROGRAM_FILES */
878 { /* CSIDL_MYPICTURES */
881 "My Documents\\My Pictures"
883 { /* CSIDL_PROFILE */
885 "WinDir", /* correct ? */
888 { /* CSIDL_SYSTEMX86 */
893 { /* CSIDL_PROGRAM_FILESX86 */
898 { /* CSIDL_PROGRAM_FILES_COMMON */
901 "Program Files\\Common Files" /* ? */
903 { /* CSIDL_PROGRAM_FILES_COMMONX86 */
906 "Program Files\\Common Files" /* ? */
908 { /* CSIDL_COMMON_TEMPLATES */
913 { /* CSIDL_COMMON_DOCUMENTS */
918 { /* CSIDL_COMMON_ADMINTOOLS */
923 { /* CSIDL_ADMINTOOLS */
925 "Administrative Tools",
926 "Start Menu\\Programs\\Administrative Tools"
928 { /* CSIDL_CONNECTIONS */
948 { /* CSIDL_COMMON_MUSIC */
953 { /* CSIDL_COMMON_PICTURES */
958 { /* CSIDL_COMMON_VIDEO */
963 { /* CSIDL_RESOURCES */
968 { /* CSIDL_RESOURCES_LOCALIZED */
973 { /* CSIDL_COMMON_OEM_LINKS */
978 { /* CSIDL_CDBURN_AREA */
983 { /* unassigned 3C */
988 { /* CSIDL_COMPUTERSNEARME */
997 /**********************************************************************/
999 BOOL WINAPI SHGetSpecialFolderPathA (
1005 CHAR szValueName[MAX_PATH], szDefaultPath[MAX_PATH], szBuildPath[MAX_PATH];
1006 HKEY hRootKey, hKey;
1008 DWORD dwType, dwDisp, dwPathLen = MAX_PATH;
1009 DWORD folder = csidl & CSIDL_FOLDER_MASK;
1012 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
1014 if ((folder > CSIDL_COMPUTERSNEARME) || (CSIDL_Data[folder].hRootKey == 0))
1016 ERR("folder unknown or not allowed\n");
1019 if (CSIDL_Data[folder].hRootKey == 1)
1021 FIXME("folder unknown, please add.\n");
1025 dwFlags = CSIDL_Data[folder].dwFlags;
1026 hRootKey = CSIDL_Data[folder].hRootKey;
1027 strcpy(szValueName, CSIDL_Data[folder].szValueName);
1028 strcpy(szDefaultPath, CSIDL_Data[folder].szDefaultPath);
1030 if (dwFlags & CSIDL_MYFLAG_SHFOLDER)
1032 /* user shell folders */
1033 if (RegCreateKeyExA(hRootKey,szSHUserFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1035 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1040 if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1042 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1045 /* value not existing */
1046 if (dwFlags & CSIDL_MYFLAG_RELATIVE)
1048 GetWindowsDirectoryA(szPath, MAX_PATH);
1049 PathAddBackslashA(szPath);
1050 strcat(szPath, szDefaultPath);
1054 strcpy(szPath, "C:\\"); /* FIXME ??? */
1055 strcat(szPath, szDefaultPath);
1057 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
1066 if (dwFlags & CSIDL_MYFLAG_SETUP)
1069 if (dwFlags & CSIDL_MYFLAG_CURRVER)
1070 pRegPath = szCurrentVersion;
1073 ERR("folder settings broken, please correct !\n");
1077 if (RegCreateKeyExA(hRootKey,pRegPath,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1079 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1081 /* value not existing */
1082 if (dwFlags & CSIDL_MYFLAG_RELATIVE)
1084 GetWindowsDirectoryA(szPath, MAX_PATH);
1085 PathAddBackslashA(szPath);
1086 strcat(szPath, szDefaultPath);
1090 strcpy(szPath, "C:\\"); /* FIXME ??? */
1091 strcat(szPath, szDefaultPath);
1093 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
1098 /* expand paths like %USERPROFILE% */
1099 if (dwType == REG_EXPAND_SZ)
1101 ExpandEnvironmentStringsA(szPath, szDefaultPath, MAX_PATH);
1102 strcpy(szPath, szDefaultPath);
1105 /* if we don't care about existing directories we are ready */
1106 if(csidl & CSIDL_FLAG_DONT_VERIFY) return TRUE;
1108 if (PathFileExistsA(szPath)) return TRUE;
1110 /* not existing but we are not allowed to create it */
1111 if (!bCreate) return FALSE;
1113 /* create directory/directories */
1114 strcpy(szBuildPath, szPath);
1115 p = strchr(szBuildPath, '\\');
1119 if (!PathFileExistsA(szBuildPath))
1121 if (!CreateDirectoryA(szBuildPath,NULL))
1123 ERR("Failed to create directory '%s'.\n", szPath);
1128 p = strchr(p+1, '\\');
1130 /* last component must be created too. */
1131 if (!PathFileExistsA(szBuildPath))
1133 if (!CreateDirectoryA(szBuildPath,NULL))
1135 ERR("Failed to create directory '%s'.\n", szPath);
1140 MESSAGE("Created not existing system directory '%s'\n", szPath);
1144 /*************************************************************************
1145 * SHGetSpecialFolderPathW
1147 BOOL WINAPI SHGetSpecialFolderPathW (
1153 char szTemp[MAX_PATH];
1155 if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate))
1157 if (!MultiByteToWideChar( CP_ACP, 0, szTemp, -1, szPath, MAX_PATH ))
1158 szPath[MAX_PATH-1] = 0;
1161 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
1166 /*************************************************************************
1167 * SHGetSpecialFolderPath (SHELL32.175)
1169 BOOL WINAPI SHGetSpecialFolderPathAW (
1176 if (SHELL_OsIsUnicode())
1177 return SHGetSpecialFolderPathW (hwndOwner, szPath, csidl, bCreate);
1178 return SHGetSpecialFolderPathA (hwndOwner, szPath, csidl, bCreate);
1181 /*************************************************************************
1182 * SHGetFolderPathA [SHELL32.@]
1184 HRESULT WINAPI SHGetFolderPathA(
1187 HANDLE hToken, /* [in] FIXME: get paths for specific user */
1188 DWORD dwFlags, /* [in] FIXME: SHGFP_TYPE_CURRENT|SHGFP_TYPE_DEFAULT */
1191 return (SHGetSpecialFolderPathA(
1194 CSIDL_FOLDER_MASK & nFolder,
1195 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;
1198 /*************************************************************************
1199 * SHGetFolderPathW [SHELL32.@]
1201 HRESULT WINAPI SHGetFolderPathW(
1208 return (SHGetSpecialFolderPathW(
1211 CSIDL_FOLDER_MASK & nFolder,
1212 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;