Removed inclusion of wine/winestring.h from winbase.h and added it to
[wine/testsucceed.git] / dlls / shell32 / shellpath.c
blob9943a269da4f440b2f6efebaf63cf932f4a1d8df
1 /*
2 * Path Functions
4 * Many of this functions are in SHLWAPI.DLL also
6 */
7 #include <string.h>
8 #include <ctype.h>
9 #include "debugtools.h"
10 #include "winnls.h"
11 #include "winreg.h"
13 #include "shlobj.h"
14 #include "shell32_main.h"
15 #include "windef.h"
16 #include "options.h"
17 #include "wine/winestring.h"
18 #include "wine/undocshell.h"
19 #include "wine/unicode.h"
20 #include "shlwapi.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(
33 LPVOID lpszPath1,
34 LPCVOID lpszPath2)
36 if (SHELL_OsIsUnicode())
37 return PathAppendW(lpszPath1, lpszPath2);
38 return PathAppendA(lpszPath1, lpszPath2);
41 /*************************************************************************
42 * PathCombineAW [SHELL32.37]
44 LPVOID WINAPI PathCombineAW(
45 LPVOID szDest,
46 LPCVOID lpszDir,
47 LPCVOID lpszFile)
49 if (SHELL_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(SHELL_OsIsUnicode())
60 return PathAddBackslashW(lpszPath);
61 return PathAddBackslashA(lpszPath);
64 /*************************************************************************
65 * PathBuildRootAW [SHELL32.30]
67 LPVOID WINAPI PathBuildRootAW(LPVOID lpszPath, int drive)
69 if(SHELL_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(SHELL_OsIsUnicode())
84 return PathFindFileNameW(lpszPath);
85 return PathFindFileNameA(lpszPath);
88 /*************************************************************************
89 * PathFindExtensionAW [SHELL32.31]
91 LPVOID WINAPI PathFindExtensionAW(LPCVOID lpszPath)
93 if (SHELL_OsIsUnicode())
94 return PathFindExtensionW(lpszPath);
95 return PathFindExtensionA(lpszPath);
99 /*************************************************************************
100 * PathGetExtensionA [internal]
102 * NOTES
103 * exported by ordinal
104 * return value points to the first char after the dot
106 static LPSTR PathGetExtensionA(LPCSTR lpszPath)
108 TRACE("(%s)\n",lpszPath);
110 lpszPath = PathFindExtensionA(lpszPath);
111 return (LPSTR)(*lpszPath?(lpszPath+1):lpszPath);
114 /*************************************************************************
115 * PathGetExtensionW [internal]
117 static LPWSTR PathGetExtensionW(LPCWSTR lpszPath)
119 TRACE("(%s)\n",debugstr_w(lpszPath));
121 lpszPath = PathFindExtensionW(lpszPath);
122 return (LPWSTR)(*lpszPath?(lpszPath+1):lpszPath);
125 /*************************************************************************
126 * PathGetExtensionAW [SHELL32.158]
128 LPVOID WINAPI PathGetExtensionAW(LPCVOID lpszPath)
130 if (SHELL_OsIsUnicode())
131 return PathGetExtensionW(lpszPath);
132 return PathGetExtensionA(lpszPath);
135 /*************************************************************************
136 * PathGetArgsAW [SHELL32.52]
138 LPVOID WINAPI PathGetArgsAW(LPVOID lpszPath)
140 if (SHELL_OsIsUnicode())
141 return PathGetArgsW(lpszPath);
142 return PathGetArgsA(lpszPath);
145 /*************************************************************************
146 * PathGetDriveNumber [SHELL32.57]
148 int WINAPI PathGetDriveNumberAW(LPVOID lpszPath)
150 if (SHELL_OsIsUnicode())
151 return PathGetDriveNumberW(lpszPath);
152 return PathGetDriveNumberA(lpszPath);
155 /*************************************************************************
156 * PathRemoveFileSpec [SHELL32.35]
158 BOOL WINAPI PathRemoveFileSpecAW(LPVOID lpszPath)
160 if (SHELL_OsIsUnicode())
161 return PathRemoveFileSpecW(lpszPath);
162 return PathRemoveFileSpecA(lpszPath);
165 /*************************************************************************
166 * PathStripPathAW [SHELL32.38]
168 void WINAPI PathStripPathAW(LPVOID lpszPath)
170 if (SHELL_OsIsUnicode())
171 return PathStripPathW(lpszPath);
172 return PathStripPathA(lpszPath);
175 /*************************************************************************
176 * PathStripToRootAW [SHELL32.50]
178 BOOL WINAPI PathStripToRootAW(LPVOID lpszPath)
180 if (SHELL_OsIsUnicode())
181 return PathStripToRootW(lpszPath);
182 return PathStripToRootA(lpszPath);
185 /*************************************************************************
186 * PathRemoveArgsAW [SHELL32.251]
188 void WINAPI PathRemoveArgsAW(LPVOID lpszPath)
190 if (SHELL_OsIsUnicode())
191 PathRemoveArgsW(lpszPath);
192 PathRemoveArgsA(lpszPath);
195 /*************************************************************************
196 * PathRemoveExtensionAW [SHELL32.250]
198 void WINAPI PathRemoveExtensionAW(LPVOID lpszPath)
200 if (SHELL_OsIsUnicode())
201 return PathRemoveExtensionW(lpszPath);
202 return PathRemoveExtensionA(lpszPath);
207 Path Manipulations
210 /*************************************************************************
211 * PathGetShortPathA [internal]
213 LPSTR WINAPI PathGetShortPathA(LPSTR lpszPath)
215 FIXME("%s stub\n", lpszPath);
216 return NULL;
219 /*************************************************************************
220 * PathGetShortPathW [internal]
222 LPWSTR WINAPI PathGetShortPathW(LPWSTR lpszPath)
224 FIXME("%s stub\n", debugstr_w(lpszPath));
225 return NULL;
228 /*************************************************************************
229 * PathGetShortPathAW [SHELL32.92]
231 LPVOID WINAPI PathGetShortPathAW(LPVOID lpszPath)
233 if(SHELL_OsIsUnicode())
234 return PathGetShortPathW(lpszPath);
235 return PathGetShortPathA(lpszPath);
238 /*************************************************************************
239 * PathRemoveBlanksAW [SHELL32.33]
241 void WINAPI PathRemoveBlanksAW(LPVOID str)
243 if(SHELL_OsIsUnicode())
244 PathRemoveBlanksW(str);
245 PathRemoveBlanksA(str);
248 /*************************************************************************
249 * PathQuoteSpacesAW [SHELL32.55]
251 LPVOID WINAPI PathQuoteSpacesAW (LPVOID lpszPath)
253 if(SHELL_OsIsUnicode())
254 return PathQuoteSpacesW(lpszPath);
255 return PathQuoteSpacesA(lpszPath);
258 /*************************************************************************
259 * PathUnquoteSpacesAW [SHELL32.56]
261 VOID WINAPI PathUnquoteSpacesAW(LPVOID str)
263 if(SHELL_OsIsUnicode())
264 PathUnquoteSpacesW(str);
265 else
266 PathUnquoteSpacesA(str);
269 /*************************************************************************
270 * PathParseIconLocationAW [SHELL32.249]
272 int WINAPI PathParseIconLocationAW (LPVOID lpszPath)
274 if(SHELL_OsIsUnicode())
275 return PathParseIconLocationW(lpszPath);
276 return PathParseIconLocationA(lpszPath);
280 ########## Path Testing ##########
282 /*************************************************************************
283 * PathIsUNCAW [SHELL32.39]
285 BOOL WINAPI PathIsUNCAW (LPCVOID lpszPath)
287 if (SHELL_OsIsUnicode())
288 return PathIsUNCW( lpszPath );
289 return PathIsUNCA( lpszPath );
292 /*************************************************************************
293 * PathIsRelativeAW [SHELL32.40]
295 BOOL WINAPI PathIsRelativeAW (LPCVOID lpszPath)
297 if (SHELL_OsIsUnicode())
298 return PathIsRelativeW( lpszPath );
299 return PathIsRelativeA( lpszPath );
302 /*************************************************************************
303 * PathIsRootAW [SHELL32.29]
305 BOOL WINAPI PathIsRootAW(LPCVOID lpszPath)
307 if (SHELL_OsIsUnicode())
308 return PathIsRootW(lpszPath);
309 return PathIsRootA(lpszPath);
312 /*************************************************************************
313 * PathIsExeA [internal]
315 static BOOL PathIsExeA (LPCSTR lpszPath)
317 LPCSTR lpszExtension = PathGetExtensionA(lpszPath);
318 int i = 0;
319 static char * lpszExtensions[6] = {"exe", "com", "pid", "cmd", "bat", NULL };
321 TRACE("path=%s\n",lpszPath);
323 for(i=0; lpszExtensions[i]; i++)
324 if (!strcasecmp(lpszExtension,lpszExtensions[i])) return TRUE;
326 return FALSE;
329 /*************************************************************************
330 * PathIsExeW [internal]
332 static BOOL PathIsExeW (LPCWSTR lpszPath)
334 LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
335 int i = 0;
336 static WCHAR lpszExtensions[6][4] =
337 {{'e','x','e','\0'}, {'c','o','m','\0'}, {'p','i','d','\0'},
338 {'c','m','d','\0'}, {'b','a','t','\0'}, {'\0'} };
340 TRACE("path=%s\n",debugstr_w(lpszPath));
342 for(i=0; lpszExtensions[i]; i++)
343 if (!strcmpiW(lpszExtension,lpszExtensions[i])) return TRUE;
345 return FALSE;
348 /*************************************************************************
349 * PathIsExeAW [SHELL32.43]
351 BOOL WINAPI PathIsExeAW (LPCVOID path)
353 if (SHELL_OsIsUnicode())
354 return PathIsExeW (path);
355 return PathIsExeA(path);
358 /*************************************************************************
359 * PathIsDirectoryAW [SHELL32.159]
361 BOOL WINAPI PathIsDirectoryAW (LPCVOID lpszPath)
363 if (SHELL_OsIsUnicode())
364 return PathIsDirectoryW (lpszPath);
365 return PathIsDirectoryA (lpszPath);
368 /*************************************************************************
369 * PathFileExistsAW [SHELL32.45]
371 BOOL WINAPI PathFileExistsAW (LPCVOID lpszPath)
373 if (SHELL_OsIsUnicode())
374 return PathFileExistsW (lpszPath);
375 return PathFileExistsA (lpszPath);
378 /*************************************************************************
379 * PathMatchSpecAW [SHELL32.46]
381 BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
383 if (SHELL_OsIsUnicode())
384 return PathMatchSpecW( name, mask );
385 return PathMatchSpecA( name, mask );
388 /*************************************************************************
389 * PathIsSameRootAW [SHELL32.650]
391 BOOL WINAPI PathIsSameRootAW(LPCVOID lpszPath1, LPCVOID lpszPath2)
393 if (SHELL_OsIsUnicode())
394 return PathIsSameRootW(lpszPath1, lpszPath2);
395 return PathIsSameRootA(lpszPath1, lpszPath2);
398 /*************************************************************************
399 * IsLFNDriveA [SHELL32.119]
401 * NOTES
402 * exported by ordinal Name
404 BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath)
406 DWORD fnlen;
408 if (!GetVolumeInformationA(lpszPath,NULL,0,NULL,&fnlen,NULL,NULL,0))
409 return FALSE;
410 return fnlen>12;
414 ########## Creating Something Unique ##########
416 /*************************************************************************
417 * PathMakeUniqueNameA [internal]
419 BOOL WINAPI PathMakeUniqueNameA(
420 LPSTR lpszBuffer,
421 DWORD dwBuffSize,
422 LPCSTR lpszShortName,
423 LPCSTR lpszLongName,
424 LPCSTR lpszPathName)
426 FIXME("%p %lu %s %s %s stub\n",
427 lpszBuffer, dwBuffSize, debugstr_a(lpszShortName),
428 debugstr_a(lpszLongName), debugstr_a(lpszPathName));
429 return TRUE;
432 /*************************************************************************
433 * PathMakeUniqueNameW [internal]
435 BOOL WINAPI PathMakeUniqueNameW(
436 LPWSTR lpszBuffer,
437 DWORD dwBuffSize,
438 LPCWSTR lpszShortName,
439 LPCWSTR lpszLongName,
440 LPCWSTR lpszPathName)
442 FIXME("%p %lu %s %s %s stub\n",
443 lpszBuffer, dwBuffSize, debugstr_w(lpszShortName),
444 debugstr_w(lpszLongName), debugstr_w(lpszPathName));
445 return TRUE;
448 /*************************************************************************
449 * PathMakeUniqueNameAW [SHELL32.47]
451 BOOL WINAPI PathMakeUniqueNameAW(
452 LPVOID lpszBuffer,
453 DWORD dwBuffSize,
454 LPCVOID lpszShortName,
455 LPCVOID lpszLongName,
456 LPCVOID lpszPathName)
458 if (SHELL_OsIsUnicode())
459 return PathMakeUniqueNameW(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
460 return PathMakeUniqueNameA(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
463 /*************************************************************************
464 * PathYetAnotherMakeUniqueNameA [SHELL32.75]
466 * NOTES
467 * exported by ordinal
469 BOOL WINAPI PathYetAnotherMakeUniqueNameA(
470 LPSTR lpszBuffer,
471 LPCSTR lpszPathName,
472 LPCSTR lpszShortName,
473 LPCSTR lpszLongName)
475 FIXME("(%p,%p, %p ,%p):stub.\n",
476 lpszBuffer, lpszPathName, lpszShortName, lpszLongName);
477 return TRUE;
482 ########## cleaning and resolving paths ##########
485 /*************************************************************************
486 * PathFindOnPathAW [SHELL32]
488 BOOL WINAPI PathFindOnPathAW(LPVOID sFile, LPCVOID sOtherDirs)
490 if (SHELL_OsIsUnicode())
491 return PathFindOnPathW(sFile, sOtherDirs);
492 return PathFindOnPathA(sFile, sOtherDirs);
495 /*************************************************************************
496 * PathCleanupSpecAW [SHELL32]
498 DWORD WINAPI PathCleanupSpecAW (LPVOID x, LPVOID y)
500 FIXME("(%p, %p) stub\n",x,y);
501 return TRUE;
504 /*************************************************************************
505 * PathQualifyA [SHELL32]
507 BOOL WINAPI PathQualifyA(LPCSTR pszPath)
509 FIXME("%s\n",pszPath);
510 return 0;
513 /*************************************************************************
514 * PathQualifyW [SHELL32]
516 BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
518 FIXME("%s\n",debugstr_w(pszPath));
519 return 0;
522 /*************************************************************************
523 * PathQualifyAW [SHELL32]
525 BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
527 if (SHELL_OsIsUnicode())
528 return PathQualifyW(pszPath);
529 return PathQualifyA(pszPath);
532 /*************************************************************************
533 * PathResolveA [SHELL32.51]
535 BOOL WINAPI PathResolveA(
536 LPSTR lpszPath,
537 LPCSTR *alpszPaths,
538 DWORD dwFlags)
540 FIXME("(%s,%p,0x%08lx),stub!\n",
541 lpszPath, *alpszPaths, dwFlags);
542 return 0;
545 /*************************************************************************
546 * PathResolveW [SHELL32]
548 BOOL WINAPI PathResolveW(
549 LPWSTR lpszPath,
550 LPCWSTR *alpszPaths,
551 DWORD dwFlags)
553 FIXME("(%s,%p,0x%08lx),stub!\n",
554 debugstr_w(lpszPath), debugstr_w(*alpszPaths), dwFlags);
555 return 0;
558 /*************************************************************************
559 * PathResolveAW [SHELL32]
561 BOOL WINAPI PathResolveAW(
562 LPVOID lpszPath,
563 LPCVOID *alpszPaths,
564 DWORD dwFlags)
566 if (SHELL_OsIsUnicode())
567 return PathResolveW(lpszPath, (LPCWSTR*)alpszPaths, dwFlags);
568 return PathResolveA(lpszPath, (LPCSTR*)alpszPaths, dwFlags);
571 /*************************************************************************
572 * PathProcessCommandA [SHELL32.653]
574 HRESULT WINAPI PathProcessCommandA (
575 LPCSTR lpszPath,
576 LPSTR lpszBuff,
577 DWORD dwBuffSize,
578 DWORD dwFlags)
580 FIXME("%s %p 0x%04lx 0x%04lx stub\n",
581 lpszPath, lpszBuff, dwBuffSize, dwFlags);
582 strcpy(lpszBuff, lpszPath);
583 return 0;
586 /*************************************************************************
587 * PathProcessCommandW
589 HRESULT WINAPI PathProcessCommandW (
590 LPCWSTR lpszPath,
591 LPWSTR lpszBuff,
592 DWORD dwBuffSize,
593 DWORD dwFlags)
595 FIXME("(%s, %p, 0x%04lx, 0x%04lx) stub\n",
596 debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags);
597 strcpyW(lpszBuff, lpszPath);
598 return 0;
601 /*************************************************************************
602 * PathProcessCommandAW
604 HRESULT WINAPI PathProcessCommandAW (
605 LPCVOID lpszPath,
606 LPVOID lpszBuff,
607 DWORD dwBuffSize,
608 DWORD dwFlags)
610 if (SHELL_OsIsUnicode())
611 return PathProcessCommandW(lpszPath, lpszBuff, dwBuffSize, dwFlags);
612 return PathProcessCommandA(lpszPath, lpszBuff, dwBuffSize, dwFlags);
616 ########## special ##########
619 /*************************************************************************
620 * PathSetDlgItemPathAW
622 BOOL WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
623 { if (SHELL_OsIsUnicode())
624 return PathSetDlgItemPathW(hDlg, id, pszPath);
625 return PathSetDlgItemPathA(hDlg, id, pszPath);
629 /*************************************************************************
630 * SHGetSpecialFolderPathA [SHELL32.175]
632 * converts csidl to path
635 static char * szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
636 static char * szSHUserFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
637 #if 0
638 static char * szEnvUserProfile = "%USERPROFILE%";
639 static char * szEnvSystemRoot = "%SYSTEMROOT%";
640 #endif
642 BOOL WINAPI SHGetSpecialFolderPathA (
643 HWND hwndOwner,
644 LPSTR szPath,
645 DWORD csidl,
646 BOOL bCreate)
648 CHAR szValueName[MAX_PATH], szDefaultPath[MAX_PATH];
649 HKEY hRootKey, hKey;
650 BOOL bRelative = TRUE;
651 DWORD dwType, dwDisp, dwPathLen = MAX_PATH;
653 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
655 /* build default values */
656 switch(csidl)
658 case CSIDL_APPDATA:
659 hRootKey = HKEY_CURRENT_USER;
660 strcpy (szValueName, "AppData");
661 strcpy (szDefaultPath, "AppData");
662 break;
664 case CSIDL_COOKIES:
665 hRootKey = HKEY_CURRENT_USER;
666 strcpy (szValueName, "Cookies");
667 strcpy(szDefaultPath, "Cookies");
668 break;
670 case CSIDL_DESKTOPDIRECTORY:
671 hRootKey = HKEY_CURRENT_USER;
672 strcpy(szValueName, "Desktop");
673 strcpy(szDefaultPath, "Desktop");
674 break;
676 case CSIDL_COMMON_DESKTOPDIRECTORY:
677 hRootKey = HKEY_LOCAL_MACHINE;
678 strcpy(szValueName, "Common Desktop");
679 strcpy(szDefaultPath, "Desktop");
680 break;
682 case CSIDL_FAVORITES:
683 hRootKey = HKEY_CURRENT_USER;
684 strcpy(szValueName, "Favorites");
685 strcpy(szDefaultPath, "Favorites");
686 break;
688 case CSIDL_FONTS:
689 hRootKey = HKEY_CURRENT_USER;
690 strcpy(szValueName, "Fonts");
691 strcpy(szDefaultPath, "Fonts");
692 break;
694 case CSIDL_HISTORY:
695 hRootKey = HKEY_CURRENT_USER;
696 strcpy(szValueName, "History");
697 strcpy(szDefaultPath, "History");
698 break;
700 case CSIDL_NETHOOD:
701 hRootKey = HKEY_CURRENT_USER;
702 strcpy(szValueName, "NetHood");
703 strcpy(szDefaultPath, "NetHood");
704 break;
706 case CSIDL_INTERNET_CACHE:
707 hRootKey = HKEY_CURRENT_USER;
708 strcpy(szValueName, "Cache");
709 strcpy(szDefaultPath, "Temporary Internet Files");
710 break;
712 case CSIDL_PERSONAL:
713 hRootKey = HKEY_CURRENT_USER;
714 strcpy(szValueName, "Personal");
715 strcpy(szDefaultPath, "My Own Files");
716 bRelative = FALSE;
717 break;
719 case CSIDL_PRINTHOOD:
720 hRootKey = HKEY_CURRENT_USER;
721 strcpy(szValueName, "PrintHood");
722 strcpy(szDefaultPath, "PrintHood");
723 break;
725 case CSIDL_PROGRAMS:
726 hRootKey = HKEY_CURRENT_USER;
727 strcpy(szValueName, "Programs");
728 strcpy(szDefaultPath, "StartMenu\\Programs");
729 break;
731 case CSIDL_COMMON_PROGRAMS:
732 hRootKey = HKEY_LOCAL_MACHINE;
733 strcpy(szValueName, "Common Programs");
734 strcpy(szDefaultPath, "");
735 break;
737 case CSIDL_RECENT:
738 hRootKey = HKEY_CURRENT_USER;
739 strcpy(szValueName, "Recent");
740 strcpy(szDefaultPath, "Recent");
741 break;
743 case CSIDL_SENDTO:
744 hRootKey = HKEY_CURRENT_USER;
745 strcpy(szValueName, "SendTo");
746 strcpy(szDefaultPath, "SendTo");
747 break;
749 case CSIDL_STARTMENU:
750 hRootKey = HKEY_CURRENT_USER;
751 strcpy(szValueName, "StartMenu");
752 strcpy(szDefaultPath, "StartMenu");
753 break;
755 case CSIDL_COMMON_STARTMENU:
756 hRootKey = HKEY_LOCAL_MACHINE;
757 strcpy(szValueName, "Common StartMenu");
758 strcpy(szDefaultPath, "StartMenu");
759 break;
761 case CSIDL_STARTUP:
762 hRootKey = HKEY_CURRENT_USER;
763 strcpy(szValueName, "Startup");
764 strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
765 break;
767 case CSIDL_COMMON_STARTUP:
768 hRootKey = HKEY_LOCAL_MACHINE;
769 strcpy(szValueName, "Common Startup");
770 strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
771 break;
773 case CSIDL_TEMPLATES:
774 hRootKey = HKEY_CURRENT_USER;
775 strcpy(szValueName, "Templates");
776 strcpy(szDefaultPath, "ShellNew");
777 break;
779 default:
780 ERR("folder unknown or not allowed\n");
781 return FALSE;
784 /* user shell folders */
785 if (RegCreateKeyExA(hRootKey,szSHUserFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
787 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
789 RegCloseKey(hKey);
791 /* shell folders */
792 if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
794 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
797 /* value not existing */
798 if (bRelative)
800 GetWindowsDirectoryA(szPath, MAX_PATH);
801 PathAddBackslashA(szPath);
802 strcat(szPath, szDefaultPath);
804 else
806 strcpy(szPath, "C:\\"); /* fixme ??? */
807 strcat(szPath, szDefaultPath);
809 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
812 RegCloseKey(hKey);
814 /* expand paths like %USERPROFILE% */
815 if (dwType == REG_EXPAND_SZ)
817 ExpandEnvironmentStringsA(szPath, szDefaultPath, MAX_PATH);
818 strcpy(szPath, szDefaultPath);
821 /* if we don't care about existing directorys we are ready */
822 if(csidl & CSIDL_FLAG_DONT_VERIFY) return TRUE;
824 if (PathFileExistsA(szPath)) return TRUE;
826 /* not existing but we not allowed to create it */
827 if (!bCreate) return FALSE;
829 if (!CreateDirectoryA(szPath,NULL))
831 ERR("Failed to create directory '%s'.\n", szPath);
832 return FALSE;
835 MESSAGE("Created not existing system directory '%s'\n", szPath);
836 return TRUE;
839 /*************************************************************************
840 * SHGetSpecialFolderPathW
842 BOOL WINAPI SHGetSpecialFolderPathW (
843 HWND hwndOwner,
844 LPWSTR szPath,
845 DWORD csidl,
846 BOOL bCreate)
848 char szTemp[MAX_PATH];
850 if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate))
852 lstrcpynAtoW(szPath, szTemp, MAX_PATH);
855 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
857 return TRUE;
860 /*************************************************************************
861 * SHGetSpecialFolderPathAW
863 BOOL WINAPI SHGetSpecialFolderPathAW (
864 HWND hwndOwner,
865 LPVOID szPath,
866 DWORD csidl,
867 BOOL bCreate)
870 if (SHELL_OsIsUnicode())
871 return SHGetSpecialFolderPathW (hwndOwner, szPath, csidl, bCreate);
872 return SHGetSpecialFolderPathA (hwndOwner, szPath, csidl, bCreate);
875 /*************************************************************************
876 * SHGetFolderPathA [SHFOLDER.@]
878 HRESULT WINAPI SHGetFolderPathA(
879 HWND hwndOwner,
880 int nFolder,
881 HANDLE hToken, /* FIXME: get paths for specific user */
882 DWORD dwFlags, /* FIXME: SHGFP_TYPE_CURRENT|SHGFP_TYPE_DEFAULT */
883 LPSTR pszPath)
885 return (SHGetSpecialFolderPathA(
886 hwndOwner,
887 pszPath,
888 CSIDL_FOLDER_MASK & nFolder,
889 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;
892 /*************************************************************************
893 * SHGetFolderPathW [SHFOLDER.@]
895 HRESULT WINAPI SHGetFolderPathW(
896 HWND hwndOwner,
897 int nFolder,
898 HANDLE hToken,
899 DWORD dwFlags,
900 LPWSTR pszPath)
902 return (SHGetSpecialFolderPathW(
903 hwndOwner,
904 pszPath,
905 CSIDL_FOLDER_MASK & nFolder,
906 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;