4 * Many of this functions are in SHLWAPI.DLL also
9 #include "debugtools.h"
11 #include "winversion.h"
15 #include "shell32_main.h"
18 #include "wine/undocshell.h"
19 #include "wine/unicode.h"
22 DEFAULT_DEBUG_CHANNEL(shell);
24 #define isSlash(x) ((x)=='\\' || (x)=='/')
26 ########## Combining and Constructing paths ##########
29 /*************************************************************************
30 * PathAppendAW [SHELL32.36]
32 BOOL WINAPI PathAppendAW(
36 if (VERSION_OsIsUnicode())
37 return PathAppendW(lpszPath1, lpszPath2);
38 return PathAppendA(lpszPath1, lpszPath2);
41 /*************************************************************************
42 * PathCombineAW [SHELL32.37]
44 LPVOID WINAPI PathCombineAW(
49 if (VERSION_OsIsUnicode())
50 return PathCombineW( szDest, lpszDir, lpszFile );
51 return PathCombineA( szDest, lpszDir, lpszFile );
54 /*************************************************************************
55 * PathAddBackslashAW [SHELL32.32]
57 LPVOID WINAPI PathAddBackslashAW(LPVOID lpszPath)
59 if(VERSION_OsIsUnicode())
60 return PathAddBackslashW(lpszPath);
61 return PathAddBackslashA(lpszPath);
64 /*************************************************************************
65 * PathBuildRootAW [SHELL32.30]
67 LPVOID WINAPI PathBuildRootAW(LPVOID lpszPath, int drive)
69 if(VERSION_OsIsUnicode())
70 return PathBuildRootW(lpszPath, drive);
71 return PathBuildRootA(lpszPath, drive);
75 Extracting Component Parts
78 /*************************************************************************
79 * PathFindFileNameAW [SHELL32.34]
81 LPVOID WINAPI PathFindFileNameAW(LPCVOID lpszPath)
83 if(VERSION_OsIsUnicode())
84 return PathFindFileNameW(lpszPath);
85 return PathFindFileNameA(lpszPath);
88 /*************************************************************************
89 * PathFindExtensionAW [SHELL32.31]
91 LPVOID WINAPI PathFindExtensionAW(LPCVOID lpszPath)
93 if (VERSION_OsIsUnicode())
94 return PathFindExtensionW(lpszPath);
95 return PathFindExtensionA(lpszPath);
99 /*************************************************************************
100 * PathGetExtensionAW [SHELL32.158]
102 LPVOID WINAPI PathGetExtensionAW(LPCVOID lpszPath)
104 if (VERSION_OsIsUnicode())
105 return PathGetExtensionW(lpszPath);
106 return PathGetExtensionA(lpszPath);
109 /*************************************************************************
110 * PathGetArgsAW [SHELL32.52]
112 LPVOID WINAPI PathGetArgsAW(LPVOID lpszPath)
114 if (VERSION_OsIsUnicode())
115 return PathGetArgsW(lpszPath);
116 return PathGetArgsA(lpszPath);
119 /*************************************************************************
120 * PathGetDriveNumber [SHELL32.57]
122 int WINAPI PathGetDriveNumberAW(LPVOID lpszPath)
124 if (VERSION_OsIsUnicode())
125 return PathGetDriveNumberW(lpszPath);
126 return PathGetDriveNumberA(lpszPath);
129 /*************************************************************************
130 * PathRemoveFileSpec [SHELL32.35]
132 BOOL WINAPI PathRemoveFileSpecAW(LPVOID lpszPath)
134 if (VERSION_OsIsUnicode())
135 return PathRemoveFileSpecW(lpszPath);
136 return PathRemoveFileSpecA(lpszPath);
139 /*************************************************************************
140 * PathStripPathAW [SHELL32.38]
142 void WINAPI PathStripPathAW(LPVOID lpszPath)
144 if (VERSION_OsIsUnicode())
145 return PathStripPathW(lpszPath);
146 return PathStripPathA(lpszPath);
149 /*************************************************************************
150 * PathStripToRootAW [SHELL32.50]
152 BOOL WINAPI PathStripToRootAW(LPVOID lpszPath)
154 if (VERSION_OsIsUnicode())
155 return PathStripToRootW(lpszPath);
156 return PathStripToRootA(lpszPath);
159 /*************************************************************************
160 * PathRemoveArgsAW [SHELL32.251]
162 void WINAPI PathRemoveArgsAW(LPVOID lpszPath)
164 if (VERSION_OsIsUnicode())
165 PathRemoveArgsW(lpszPath);
166 PathRemoveArgsA(lpszPath);
169 /*************************************************************************
170 * PathRemoveExtensionAW [SHELL32.250]
172 void WINAPI PathRemoveExtensionAW(LPVOID lpszPath)
174 if (VERSION_OsIsUnicode())
175 return PathRemoveExtensionW(lpszPath);
176 return PathRemoveExtensionA(lpszPath);
184 /*************************************************************************
185 * PathGetShortPathA [internal]
187 LPSTR WINAPI PathGetShortPathA(LPSTR lpszPath)
189 FIXME("%s stub\n", lpszPath);
193 /*************************************************************************
194 * PathGetShortPathW [internal]
196 LPWSTR WINAPI PathGetShortPathW(LPWSTR lpszPath)
198 FIXME("%s stub\n", debugstr_w(lpszPath));
202 /*************************************************************************
203 * PathGetShortPathAW [SHELL32.92]
205 LPVOID WINAPI PathGetShortPathAW(LPVOID lpszPath)
207 if(VERSION_OsIsUnicode())
208 return PathGetShortPathW(lpszPath);
209 return PathGetShortPathA(lpszPath);
212 /*************************************************************************
213 * PathRemoveBlanksAW [SHELL32.33]
215 void WINAPI PathRemoveBlanksAW(LPVOID str)
217 if(VERSION_OsIsUnicode())
218 PathRemoveBlanksW(str);
219 PathRemoveBlanksA(str);
222 /*************************************************************************
223 * PathQuoteSpacesAW [SHELL32.55]
225 LPVOID WINAPI PathQuoteSpacesAW (LPVOID lpszPath)
227 if(VERSION_OsIsUnicode())
228 return PathQuoteSpacesW(lpszPath);
229 return PathQuoteSpacesA(lpszPath);
232 /*************************************************************************
233 * PathUnquoteSpacesAW [SHELL32.56]
235 VOID WINAPI PathUnquoteSpacesAW(LPVOID str)
237 if(VERSION_OsIsUnicode())
238 PathUnquoteSpacesW(str);
240 PathUnquoteSpacesA(str);
243 /*************************************************************************
244 * PathParseIconLocationAW [SHELL32.249]
246 int WINAPI PathParseIconLocationAW (LPVOID lpszPath)
248 if(VERSION_OsIsUnicode())
249 return PathParseIconLocationW(lpszPath);
250 return PathParseIconLocationA(lpszPath);
254 ########## Path Testing ##########
256 /*************************************************************************
257 * PathIsUNCAW [SHELL32.39]
259 BOOL WINAPI PathIsUNCAW (LPCVOID lpszPath)
261 if (VERSION_OsIsUnicode())
262 return PathIsUNCW( lpszPath );
263 return PathIsUNCA( lpszPath );
266 /*************************************************************************
267 * PathIsRelativeAW [SHELL32.40]
269 BOOL WINAPI PathIsRelativeAW (LPCVOID lpszPath)
271 if (VERSION_OsIsUnicode())
272 return PathIsRelativeW( lpszPath );
273 return PathIsRelativeA( lpszPath );
276 /*************************************************************************
277 * PathIsRootAW [SHELL32.29]
279 BOOL WINAPI PathIsRootAW(LPCVOID lpszPath)
281 if (VERSION_OsIsUnicode())
282 return PathIsRootW(lpszPath);
283 return PathIsRootA(lpszPath);
286 /*************************************************************************
287 * PathIsExeAW [SHELL32.43]
289 BOOL WINAPI PathIsExeAW (LPCVOID path)
291 if (VERSION_OsIsUnicode())
292 return PathIsExeW (path);
293 return PathIsExeA(path);
296 /*************************************************************************
297 * PathIsDirectoryAW [SHELL32.159]
299 BOOL WINAPI PathIsDirectoryAW (LPCVOID lpszPath)
301 if (VERSION_OsIsUnicode())
302 return PathIsDirectoryW (lpszPath);
303 return PathIsDirectoryA (lpszPath);
306 /*************************************************************************
307 * PathFileExistsAW [SHELL32.45]
309 BOOL WINAPI PathFileExistsAW (LPCVOID lpszPath)
311 if (VERSION_OsIsUnicode())
312 return PathFileExistsW (lpszPath);
313 return PathFileExistsA (lpszPath);
316 /*************************************************************************
317 * PathMatchSpecAW [SHELL32.46]
319 BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
321 if (VERSION_OsIsUnicode())
322 return PathMatchSpecW( name, mask );
323 return PathMatchSpecA( name, mask );
326 /*************************************************************************
327 * PathIsSameRootAW [SHELL32.650]
329 BOOL WINAPI PathIsSameRootAW(LPCVOID lpszPath1, LPCVOID lpszPath2)
331 if (VERSION_OsIsUnicode())
332 return PathIsSameRootW(lpszPath1, lpszPath2);
333 return PathIsSameRootA(lpszPath1, lpszPath2);
336 /*************************************************************************
337 * IsLFNDriveA [SHELL32.119]
340 * exported by ordinal Name
342 BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath)
346 if (!GetVolumeInformationA(lpszPath,NULL,0,NULL,&fnlen,NULL,NULL,0))
352 ########## Creating Something Unique ##########
354 /*************************************************************************
355 * PathMakeUniqueNameA [internal]
357 BOOL WINAPI PathMakeUniqueNameA(
360 LPCSTR lpszShortName,
364 FIXME("%p %lu %s %s %s stub\n",
365 lpszBuffer, dwBuffSize, debugstr_a(lpszShortName),
366 debugstr_a(lpszLongName), debugstr_a(lpszPathName));
370 /*************************************************************************
371 * PathMakeUniqueNameW [internal]
373 BOOL WINAPI PathMakeUniqueNameW(
376 LPCWSTR lpszShortName,
377 LPCWSTR lpszLongName,
378 LPCWSTR lpszPathName)
380 FIXME("%p %lu %s %s %s stub\n",
381 lpszBuffer, dwBuffSize, debugstr_w(lpszShortName),
382 debugstr_w(lpszLongName), debugstr_w(lpszPathName));
386 /*************************************************************************
387 * PathMakeUniqueNameAW [SHELL32.47]
389 BOOL WINAPI PathMakeUniqueNameAW(
392 LPCVOID lpszShortName,
393 LPCVOID lpszLongName,
394 LPCVOID lpszPathName)
396 if (VERSION_OsIsUnicode())
397 return PathMakeUniqueNameW(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
398 return PathMakeUniqueNameA(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
401 /*************************************************************************
402 * PathYetAnotherMakeUniqueNameA [SHELL32.75]
405 * exported by ordinal
407 BOOL WINAPI PathYetAnotherMakeUniqueNameA(
410 LPCSTR lpszShortName,
413 FIXME("(%p,%p, %p ,%p):stub.\n",
414 lpszBuffer, lpszPathName, lpszShortName, lpszLongName);
420 ########## cleaning and resolving paths ##########
423 /*************************************************************************
424 * PathFindOnPathAW [SHELL32]
426 BOOL WINAPI PathFindOnPathAW(LPVOID sFile, LPCVOID sOtherDirs)
428 if (VERSION_OsIsUnicode())
429 return PathFindOnPathW(sFile, sOtherDirs);
430 return PathFindOnPathA(sFile, sOtherDirs);
433 /*************************************************************************
434 * PathCleanupSpecAW [SHELL32]
436 DWORD WINAPI PathCleanupSpecAW (LPVOID x, LPVOID y)
438 if (VERSION_OsIsUnicode())
439 return PathCleanupSpecW(x,y);
440 return PathCleanupSpecA(x,y);
443 /*************************************************************************
444 * PathQualifyA [SHELL32]
446 BOOL WINAPI PathQualifyA(LPCSTR pszPath)
448 FIXME("%s\n",pszPath);
452 /*************************************************************************
453 * PathQualifyW [SHELL32]
455 BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
457 FIXME("%s\n",debugstr_w(pszPath));
461 /*************************************************************************
462 * PathQualifyAW [SHELL32]
464 BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
466 if (VERSION_OsIsUnicode())
467 return PathQualifyW(pszPath);
468 return PathQualifyA(pszPath);
471 /*************************************************************************
472 * PathResolveA [SHELL32.51]
474 BOOL WINAPI PathResolveA(
479 FIXME("(%s,%p,0x%08lx),stub!\n",
480 lpszPath, *alpszPaths, dwFlags);
484 /*************************************************************************
485 * PathResolveW [SHELL32]
487 BOOL WINAPI PathResolveW(
492 FIXME("(%s,%p,0x%08lx),stub!\n",
493 debugstr_w(lpszPath), debugstr_w(*alpszPaths), dwFlags);
497 /*************************************************************************
498 * PathResolveAW [SHELL32]
500 BOOL WINAPI PathResolveAW(
505 if (VERSION_OsIsUnicode())
506 return PathResolveW(lpszPath, (LPCWSTR*)alpszPaths, dwFlags);
507 return PathResolveA(lpszPath, (LPCSTR*)alpszPaths, dwFlags);
510 /*************************************************************************
511 * PathProcessCommandA [SHELL32.653]
513 HRESULT WINAPI PathProcessCommandA (
519 FIXME("%s %p 0x%04lx 0x%04lx stub\n",
520 lpszPath, lpszBuff, dwBuffSize, dwFlags);
521 lstrcpyA(lpszBuff, lpszPath);
525 /*************************************************************************
526 * PathProcessCommandW
528 HRESULT WINAPI PathProcessCommandW (
534 FIXME("(%s, %p, 0x%04lx, 0x%04lx) stub\n",
535 debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags);
536 lstrcpyW(lpszBuff, lpszPath);
540 /*************************************************************************
541 * PathProcessCommandAW
543 HRESULT WINAPI PathProcessCommandAW (
549 if (VERSION_OsIsUnicode())
550 return PathProcessCommandW(lpszPath, lpszBuff, dwBuffSize, dwFlags);
551 return PathProcessCommandA(lpszPath, lpszBuff, dwBuffSize, dwFlags);
555 ########## special ##########
558 /*************************************************************************
559 * PathSetDlgItemPathAW
561 BOOL WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
562 { if (VERSION_OsIsUnicode())
563 return PathSetDlgItemPathW(hDlg, id, pszPath);
564 return PathSetDlgItemPathA(hDlg, id, pszPath);
568 /*************************************************************************
569 * SHGetSpecialFolderPathA [SHELL32.175]
571 * converts csidl to path
574 static char * szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
575 static char * szSHUserFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
577 static char * szEnvUserProfile = "%USERPROFILE%";
578 static char * szEnvSystemRoot = "%SYSTEMROOT%";
581 BOOL WINAPI SHGetSpecialFolderPathA (
587 CHAR szValueName[MAX_PATH], szDefaultPath[MAX_PATH];
589 BOOL bRelative = TRUE;
590 DWORD dwType, dwDisp, dwPathLen = MAX_PATH;
592 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
594 /* build default values */
598 hRootKey = HKEY_CURRENT_USER;
599 strcpy (szValueName, "AppData");
600 strcpy (szDefaultPath, "AppData");
604 hRootKey = HKEY_CURRENT_USER;
605 strcpy (szValueName, "Cookies");
606 strcpy(szDefaultPath, "Cookies");
609 case CSIDL_DESKTOPDIRECTORY:
610 hRootKey = HKEY_CURRENT_USER;
611 strcpy(szValueName, "Desktop");
612 strcpy(szDefaultPath, "Desktop");
615 case CSIDL_COMMON_DESKTOPDIRECTORY:
616 hRootKey = HKEY_LOCAL_MACHINE;
617 strcpy(szValueName, "Common Desktop");
618 strcpy(szDefaultPath, "Desktop");
621 case CSIDL_FAVORITES:
622 hRootKey = HKEY_CURRENT_USER;
623 strcpy(szValueName, "Favorites");
624 strcpy(szDefaultPath, "Favorites");
628 hRootKey = HKEY_CURRENT_USER;
629 strcpy(szValueName, "Fonts");
630 strcpy(szDefaultPath, "Fonts");
634 hRootKey = HKEY_CURRENT_USER;
635 strcpy(szValueName, "History");
636 strcpy(szDefaultPath, "History");
640 hRootKey = HKEY_CURRENT_USER;
641 strcpy(szValueName, "NetHood");
642 strcpy(szDefaultPath, "NetHood");
645 case CSIDL_INTERNET_CACHE:
646 hRootKey = HKEY_CURRENT_USER;
647 strcpy(szValueName, "Cache");
648 strcpy(szDefaultPath, "Temporary Internet Files");
652 hRootKey = HKEY_CURRENT_USER;
653 strcpy(szValueName, "Personal");
654 strcpy(szDefaultPath, "My Own Files");
658 case CSIDL_PRINTHOOD:
659 hRootKey = HKEY_CURRENT_USER;
660 strcpy(szValueName, "PrintHood");
661 strcpy(szDefaultPath, "PrintHood");
665 hRootKey = HKEY_CURRENT_USER;
666 strcpy(szValueName, "Programs");
667 strcpy(szDefaultPath, "StartMenu\\Programs");
670 case CSIDL_COMMON_PROGRAMS:
671 hRootKey = HKEY_LOCAL_MACHINE;
672 strcpy(szValueName, "Common Programs");
673 strcpy(szDefaultPath, "");
677 hRootKey = HKEY_CURRENT_USER;
678 strcpy(szValueName, "Recent");
679 strcpy(szDefaultPath, "Recent");
683 hRootKey = HKEY_CURRENT_USER;
684 strcpy(szValueName, "SendTo");
685 strcpy(szDefaultPath, "SendTo");
688 case CSIDL_STARTMENU:
689 hRootKey = HKEY_CURRENT_USER;
690 strcpy(szValueName, "StartMenu");
691 strcpy(szDefaultPath, "StartMenu");
694 case CSIDL_COMMON_STARTMENU:
695 hRootKey = HKEY_LOCAL_MACHINE;
696 strcpy(szValueName, "Common StartMenu");
697 strcpy(szDefaultPath, "StartMenu");
701 hRootKey = HKEY_CURRENT_USER;
702 strcpy(szValueName, "Startup");
703 strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
706 case CSIDL_COMMON_STARTUP:
707 hRootKey = HKEY_LOCAL_MACHINE;
708 strcpy(szValueName, "Common Startup");
709 strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
712 case CSIDL_TEMPLATES:
713 hRootKey = HKEY_CURRENT_USER;
714 strcpy(szValueName, "Templates");
715 strcpy(szDefaultPath, "ShellNew");
719 ERR("folder unknown or not allowed\n");
723 /* user shell folders */
724 if (RegCreateKeyExA(hRootKey,szSHUserFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
726 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
731 if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
733 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
736 /* value not existing */
739 GetWindowsDirectoryA(szPath, MAX_PATH);
740 PathAddBackslashA(szPath);
741 strcat(szPath, szDefaultPath);
745 strcpy(szPath, "C:\\"); /* fixme ??? */
746 strcat(szPath, szDefaultPath);
748 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
753 /* expand paths like %USERPROFILE% */
754 if (dwType == REG_EXPAND_SZ)
756 ExpandEnvironmentStringsA(szPath, szDefaultPath, MAX_PATH);
757 strcpy(szPath, szDefaultPath);
760 /* if we don't care about existing directorys we are ready */
761 if(csidl & CSIDL_FLAG_DONT_VERIFY) return TRUE;
763 if (PathFileExistsA(szPath)) return TRUE;
765 /* not existing but we not allowed to create it */
766 if (!bCreate) return FALSE;
768 if (!CreateDirectoryA(szPath,NULL))
770 ERR("Failed to create directory '%s'.\n", szPath);
774 MESSAGE("Created not existing system directory '%s'\n", szPath);
778 /*************************************************************************
779 * SHGetSpecialFolderPathW
781 BOOL WINAPI SHGetSpecialFolderPathW (
787 char szTemp[MAX_PATH];
789 if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate))
791 lstrcpynAtoW(szPath, szTemp, MAX_PATH);
794 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
799 /*************************************************************************
800 * SHGetSpecialFolderPathAW
802 BOOL WINAPI SHGetSpecialFolderPathAW (
809 if (VERSION_OsIsUnicode())
810 return SHGetSpecialFolderPathW (hwndOwner, szPath, csidl, bCreate);
811 return SHGetSpecialFolderPathA (hwndOwner, szPath, csidl, bCreate);
814 /*************************************************************************
815 * SHGetFolderPathA [SHFOLDER.@]
817 HRESULT WINAPI SHGetFolderPathA(
820 HANDLE hToken, /* FIXME: get paths for specific user */
821 DWORD dwFlags, /* FIXME: SHGFP_TYPE_CURRENT|SHGFP_TYPE_DEFAULT */
824 return (SHGetSpecialFolderPathA(
827 CSIDL_FOLDER_MASK & nFolder,
828 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;
831 /*************************************************************************
832 * SHGetFolderPathW [SHFOLDER.@]
834 HRESULT WINAPI SHGetFolderPathW(
841 return (SHGetSpecialFolderPathW(
844 CSIDL_FOLDER_MASK & nFolder,
845 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;