Moved mode setting out of .spec file into Makefile.
[wine/gsoc_dplay.git] / dlls / shell32 / shellpath.c
blob8531f6a9ea5f93ebd6066dce81044f7b2860db5d
1 /*
2 * Path Functions
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
20 * NOTES:
22 * Many of these functions are in SHLWAPI.DLL also
26 #include "config.h"
27 #include "wine/port.h"
29 #include <string.h>
30 #include <ctype.h>
31 #include "wine/debug.h"
32 #include "windef.h"
33 #include "winnls.h"
34 #include "winreg.h"
36 #include "shlobj.h"
37 #include "shell32_main.h"
38 #include "undocshell.h"
39 #include "wine/unicode.h"
40 #include "shlwapi.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(shell);
45 ########## Combining and Constructing paths ##########
48 /*************************************************************************
49 * PathAppend [SHELL32.36]
51 BOOL WINAPI PathAppendAW(
52 LPVOID lpszPath1,
53 LPCVOID lpszPath2)
55 if (SHELL_OsIsUnicode())
56 return PathAppendW(lpszPath1, lpszPath2);
57 return PathAppendA(lpszPath1, lpszPath2);
60 /*************************************************************************
61 * PathCombine [SHELL32.37]
63 LPVOID WINAPI PathCombineAW(
64 LPVOID szDest,
65 LPCVOID lpszDir,
66 LPCVOID lpszFile)
68 if (SHELL_OsIsUnicode())
69 return PathCombineW( szDest, lpszDir, lpszFile );
70 return PathCombineA( szDest, lpszDir, lpszFile );
73 /*************************************************************************
74 * PathAddBackslash [SHELL32.32]
76 LPVOID WINAPI PathAddBackslashAW(LPVOID lpszPath)
78 if(SHELL_OsIsUnicode())
79 return PathAddBackslashW(lpszPath);
80 return PathAddBackslashA(lpszPath);
83 /*************************************************************************
84 * PathBuildRoot [SHELL32.30]
86 LPVOID WINAPI PathBuildRootAW(LPVOID lpszPath, int drive)
88 if(SHELL_OsIsUnicode())
89 return PathBuildRootW(lpszPath, drive);
90 return PathBuildRootA(lpszPath, drive);
94 Extracting Component Parts
97 /*************************************************************************
98 * PathFindFileName [SHELL32.34]
100 LPVOID WINAPI PathFindFileNameAW(LPCVOID lpszPath)
102 if(SHELL_OsIsUnicode())
103 return PathFindFileNameW(lpszPath);
104 return PathFindFileNameA(lpszPath);
107 /*************************************************************************
108 * PathFindExtension [SHELL32.31]
110 LPVOID WINAPI PathFindExtensionAW(LPCVOID lpszPath)
112 if (SHELL_OsIsUnicode())
113 return PathFindExtensionW(lpszPath);
114 return PathFindExtensionA(lpszPath);
118 /*************************************************************************
119 * PathGetExtensionA [internal]
121 * NOTES
122 * exported by ordinal
123 * return value points to the first char after the dot
125 static LPSTR PathGetExtensionA(LPCSTR lpszPath)
127 TRACE("(%s)\n",lpszPath);
129 lpszPath = PathFindExtensionA(lpszPath);
130 return (LPSTR)(*lpszPath?(lpszPath+1):lpszPath);
133 /*************************************************************************
134 * PathGetExtensionW [internal]
136 static LPWSTR PathGetExtensionW(LPCWSTR lpszPath)
138 TRACE("(%s)\n",debugstr_w(lpszPath));
140 lpszPath = PathFindExtensionW(lpszPath);
141 return (LPWSTR)(*lpszPath?(lpszPath+1):lpszPath);
144 /*************************************************************************
145 * PathGetExtension [SHELL32.158]
147 LPVOID WINAPI PathGetExtensionAW(LPCVOID lpszPath,DWORD void1, DWORD void2)
149 if (SHELL_OsIsUnicode())
150 return PathGetExtensionW(lpszPath);
151 return PathGetExtensionA(lpszPath);
154 /*************************************************************************
155 * PathGetArgs [SHELL32.52]
157 LPVOID WINAPI PathGetArgsAW(LPVOID lpszPath)
159 if (SHELL_OsIsUnicode())
160 return PathGetArgsW(lpszPath);
161 return PathGetArgsA(lpszPath);
164 /*************************************************************************
165 * PathGetDriveNumber [SHELL32.57]
167 int WINAPI PathGetDriveNumberAW(LPVOID lpszPath)
169 if (SHELL_OsIsUnicode())
170 return PathGetDriveNumberW(lpszPath);
171 return PathGetDriveNumberA(lpszPath);
174 /*************************************************************************
175 * PathRemoveFileSpec [SHELL32.35]
177 BOOL WINAPI PathRemoveFileSpecAW(LPVOID lpszPath)
179 if (SHELL_OsIsUnicode())
180 return PathRemoveFileSpecW(lpszPath);
181 return PathRemoveFileSpecA(lpszPath);
184 /*************************************************************************
185 * PathStripPath [SHELL32.38]
187 void WINAPI PathStripPathAW(LPVOID lpszPath)
189 if (SHELL_OsIsUnicode())
190 PathStripPathW(lpszPath);
191 else
192 PathStripPathA(lpszPath);
195 /*************************************************************************
196 * PathStripToRoot [SHELL32.50]
198 BOOL WINAPI PathStripToRootAW(LPVOID lpszPath)
200 if (SHELL_OsIsUnicode())
201 return PathStripToRootW(lpszPath);
202 return PathStripToRootA(lpszPath);
205 /*************************************************************************
206 * PathRemoveArgs [SHELL32.251]
208 void WINAPI PathRemoveArgsAW(LPVOID lpszPath)
210 if (SHELL_OsIsUnicode())
211 PathRemoveArgsW(lpszPath);
212 else
213 PathRemoveArgsA(lpszPath);
216 /*************************************************************************
217 * PathRemoveExtension [SHELL32.250]
219 void WINAPI PathRemoveExtensionAW(LPVOID lpszPath)
221 if (SHELL_OsIsUnicode())
222 PathRemoveExtensionW(lpszPath);
223 else
224 PathRemoveExtensionA(lpszPath);
229 Path Manipulations
232 /*************************************************************************
233 * PathGetShortPathA [internal]
235 LPSTR WINAPI PathGetShortPathA(LPSTR lpszPath)
237 FIXME("%s stub\n", lpszPath);
238 return NULL;
241 /*************************************************************************
242 * PathGetShortPathW [internal]
244 LPWSTR WINAPI PathGetShortPathW(LPWSTR lpszPath)
246 FIXME("%s stub\n", debugstr_w(lpszPath));
247 return NULL;
250 /*************************************************************************
251 * PathGetShortPath [SHELL32.92]
253 LPVOID WINAPI PathGetShortPathAW(LPVOID lpszPath)
255 if(SHELL_OsIsUnicode())
256 return PathGetShortPathW(lpszPath);
257 return PathGetShortPathA(lpszPath);
260 /*************************************************************************
261 * PathRemoveBlanks [SHELL32.33]
263 void WINAPI PathRemoveBlanksAW(LPVOID str)
265 if(SHELL_OsIsUnicode())
266 PathRemoveBlanksW(str);
267 else
268 PathRemoveBlanksA(str);
271 /*************************************************************************
272 * PathQuoteSpaces [SHELL32.55]
274 VOID WINAPI PathQuoteSpacesAW (LPVOID lpszPath)
276 if(SHELL_OsIsUnicode())
277 PathQuoteSpacesW(lpszPath);
278 else
279 PathQuoteSpacesA(lpszPath);
282 /*************************************************************************
283 * PathUnquoteSpaces [SHELL32.56]
285 VOID WINAPI PathUnquoteSpacesAW(LPVOID str)
287 if(SHELL_OsIsUnicode())
288 PathUnquoteSpacesW(str);
289 else
290 PathUnquoteSpacesA(str);
293 /*************************************************************************
294 * PathParseIconLocation [SHELL32.249]
296 int WINAPI PathParseIconLocationAW (LPVOID lpszPath)
298 if(SHELL_OsIsUnicode())
299 return PathParseIconLocationW(lpszPath);
300 return PathParseIconLocationA(lpszPath);
304 ########## Path Testing ##########
306 /*************************************************************************
307 * PathIsUNC [SHELL32.39]
309 BOOL WINAPI PathIsUNCAW (LPCVOID lpszPath)
311 if (SHELL_OsIsUnicode())
312 return PathIsUNCW( lpszPath );
313 return PathIsUNCA( lpszPath );
316 /*************************************************************************
317 * PathIsRelative [SHELL32.40]
319 BOOL WINAPI PathIsRelativeAW (LPCVOID lpszPath)
321 if (SHELL_OsIsUnicode())
322 return PathIsRelativeW( lpszPath );
323 return PathIsRelativeA( lpszPath );
326 /*************************************************************************
327 * PathIsRoot [SHELL32.29]
329 BOOL WINAPI PathIsRootAW(LPCVOID lpszPath)
331 if (SHELL_OsIsUnicode())
332 return PathIsRootW(lpszPath);
333 return PathIsRootA(lpszPath);
336 /*************************************************************************
337 * PathIsExeA [internal]
339 static BOOL PathIsExeA (LPCSTR lpszPath)
341 LPCSTR lpszExtension = PathGetExtensionA(lpszPath);
342 int i = 0;
343 static char * lpszExtensions[6] = {"exe", "com", "pid", "cmd", "bat", NULL };
345 TRACE("path=%s\n",lpszPath);
347 for(i=0; lpszExtensions[i]; i++)
348 if (!strcasecmp(lpszExtension,lpszExtensions[i])) return TRUE;
350 return FALSE;
353 /*************************************************************************
354 * PathIsExeW [internal]
356 static BOOL PathIsExeW (LPCWSTR lpszPath)
358 LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
359 int i = 0;
360 static WCHAR lpszExtensions[6][4] =
361 {{'e','x','e','\0'}, {'c','o','m','\0'}, {'p','i','d','\0'},
362 {'c','m','d','\0'}, {'b','a','t','\0'}, {'\0'} };
364 TRACE("path=%s\n",debugstr_w(lpszPath));
366 for(i=0; lpszExtensions[i][0]; i++)
367 if (!strcmpiW(lpszExtension,lpszExtensions[i])) return TRUE;
369 return FALSE;
372 /*************************************************************************
373 * PathIsExe [SHELL32.43]
375 BOOL WINAPI PathIsExeAW (LPCVOID path)
377 if (SHELL_OsIsUnicode())
378 return PathIsExeW (path);
379 return PathIsExeA(path);
382 /*************************************************************************
383 * PathIsDirectory [SHELL32.159]
385 BOOL WINAPI PathIsDirectoryAW (LPCVOID lpszPath)
387 if (SHELL_OsIsUnicode())
388 return PathIsDirectoryW (lpszPath);
389 return PathIsDirectoryA (lpszPath);
392 /*************************************************************************
393 * PathFileExists [SHELL32.45]
395 BOOL WINAPI PathFileExistsAW (LPCVOID lpszPath)
397 if (SHELL_OsIsUnicode())
398 return PathFileExistsW (lpszPath);
399 return PathFileExistsA (lpszPath);
402 /*************************************************************************
403 * PathMatchSpec [SHELL32.46]
405 BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
407 if (SHELL_OsIsUnicode())
408 return PathMatchSpecW( name, mask );
409 return PathMatchSpecA( name, mask );
412 /*************************************************************************
413 * PathIsSameRoot [SHELL32.650]
415 BOOL WINAPI PathIsSameRootAW(LPCVOID lpszPath1, LPCVOID lpszPath2)
417 if (SHELL_OsIsUnicode())
418 return PathIsSameRootW(lpszPath1, lpszPath2);
419 return PathIsSameRootA(lpszPath1, lpszPath2);
422 /*************************************************************************
423 * IsLFNDrive [SHELL32.119]
425 * NOTES
426 * exported by ordinal Name
428 BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath)
430 DWORD fnlen;
432 if (!GetVolumeInformationA(lpszPath,NULL,0,NULL,&fnlen,NULL,NULL,0))
433 return FALSE;
434 return fnlen>12;
438 ########## Creating Something Unique ##########
440 /*************************************************************************
441 * PathMakeUniqueNameA [internal]
443 BOOL WINAPI PathMakeUniqueNameA(
444 LPSTR lpszBuffer,
445 DWORD dwBuffSize,
446 LPCSTR lpszShortName,
447 LPCSTR lpszLongName,
448 LPCSTR lpszPathName)
450 FIXME("%p %lu %s %s %s stub\n",
451 lpszBuffer, dwBuffSize, debugstr_a(lpszShortName),
452 debugstr_a(lpszLongName), debugstr_a(lpszPathName));
453 return TRUE;
456 /*************************************************************************
457 * PathMakeUniqueNameW [internal]
459 BOOL WINAPI PathMakeUniqueNameW(
460 LPWSTR lpszBuffer,
461 DWORD dwBuffSize,
462 LPCWSTR lpszShortName,
463 LPCWSTR lpszLongName,
464 LPCWSTR lpszPathName)
466 FIXME("%p %lu %s %s %s stub\n",
467 lpszBuffer, dwBuffSize, debugstr_w(lpszShortName),
468 debugstr_w(lpszLongName), debugstr_w(lpszPathName));
469 return TRUE;
472 /*************************************************************************
473 * PathMakeUniqueName [SHELL32.47]
475 BOOL WINAPI PathMakeUniqueNameAW(
476 LPVOID lpszBuffer,
477 DWORD dwBuffSize,
478 LPCVOID lpszShortName,
479 LPCVOID lpszLongName,
480 LPCVOID lpszPathName)
482 if (SHELL_OsIsUnicode())
483 return PathMakeUniqueNameW(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
484 return PathMakeUniqueNameA(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
487 /*************************************************************************
488 * PathYetAnotherMakeUniqueName [SHELL32.75]
490 * NOTES
491 * exported by ordinal
493 BOOL WINAPI PathYetAnotherMakeUniqueNameA(
494 LPSTR lpszBuffer,
495 LPCSTR lpszPathName,
496 LPCSTR lpszShortName,
497 LPCSTR lpszLongName)
499 FIXME("(%p,%p, %p ,%p):stub.\n",
500 lpszBuffer, lpszPathName, lpszShortName, lpszLongName);
501 return TRUE;
506 ########## cleaning and resolving paths ##########
509 /*************************************************************************
510 * PathFindOnPath [SHELL32.145]
512 BOOL WINAPI PathFindOnPathAW(LPVOID sFile, LPCVOID sOtherDirs)
514 if (SHELL_OsIsUnicode())
515 return PathFindOnPathW(sFile, (LPCWSTR *)sOtherDirs);
516 return PathFindOnPathA(sFile, (LPCSTR *)sOtherDirs);
519 /*************************************************************************
520 * PathCleanupSpec [SHELL32.171]
522 DWORD WINAPI PathCleanupSpecAW (LPCVOID x, LPVOID y)
524 FIXME("(%p, %p) stub\n",x,y);
525 return TRUE;
528 /*************************************************************************
529 * PathQualifyA [SHELL32]
531 BOOL WINAPI PathQualifyA(LPCSTR pszPath)
533 FIXME("%s\n",pszPath);
534 return 0;
537 /*************************************************************************
538 * PathQualifyW [SHELL32]
540 BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
542 FIXME("%s\n",debugstr_w(pszPath));
543 return 0;
546 /*************************************************************************
547 * PathQualify [SHELL32.49]
549 BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
551 if (SHELL_OsIsUnicode())
552 return PathQualifyW(pszPath);
553 return PathQualifyA(pszPath);
556 /*************************************************************************
557 * PathResolveA [SHELL32.51]
559 BOOL WINAPI PathResolveA(
560 LPSTR lpszPath,
561 LPCSTR *alpszPaths,
562 DWORD dwFlags)
564 FIXME("(%s,%p,0x%08lx),stub!\n",
565 lpszPath, *alpszPaths, dwFlags);
566 return 0;
569 /*************************************************************************
570 * PathResolveW [SHELL32]
572 BOOL WINAPI PathResolveW(
573 LPWSTR lpszPath,
574 LPCWSTR *alpszPaths,
575 DWORD dwFlags)
577 FIXME("(%s,%p,0x%08lx),stub!\n",
578 debugstr_w(lpszPath), debugstr_w(*alpszPaths), dwFlags);
579 return 0;
582 /*************************************************************************
583 * PathResolve [SHELL32.51]
585 BOOL WINAPI PathResolveAW(
586 LPVOID lpszPath,
587 LPCVOID *alpszPaths,
588 DWORD dwFlags)
590 if (SHELL_OsIsUnicode())
591 return PathResolveW(lpszPath, (LPCWSTR*)alpszPaths, dwFlags);
592 return PathResolveA(lpszPath, (LPCSTR*)alpszPaths, dwFlags);
595 /*************************************************************************
596 * PathProcessCommandA [SHELL32.653]
598 HRESULT WINAPI PathProcessCommandA (
599 LPCSTR lpszPath,
600 LPSTR lpszBuff,
601 DWORD dwBuffSize,
602 DWORD dwFlags)
604 FIXME("%s %p 0x%04lx 0x%04lx stub\n",
605 lpszPath, lpszBuff, dwBuffSize, dwFlags);
606 strcpy(lpszBuff, lpszPath);
607 return 0;
610 /*************************************************************************
611 * PathProcessCommandW
613 HRESULT WINAPI PathProcessCommandW (
614 LPCWSTR lpszPath,
615 LPWSTR lpszBuff,
616 DWORD dwBuffSize,
617 DWORD dwFlags)
619 FIXME("(%s, %p, 0x%04lx, 0x%04lx) stub\n",
620 debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags);
621 strcpyW(lpszBuff, lpszPath);
622 return 0;
625 /*************************************************************************
626 * PathProcessCommand (SHELL32.653)
628 HRESULT WINAPI PathProcessCommandAW (
629 LPCVOID lpszPath,
630 LPVOID lpszBuff,
631 DWORD dwBuffSize,
632 DWORD dwFlags)
634 if (SHELL_OsIsUnicode())
635 return PathProcessCommandW(lpszPath, lpszBuff, dwBuffSize, dwFlags);
636 return PathProcessCommandA(lpszPath, lpszBuff, dwBuffSize, dwFlags);
640 ########## special ##########
643 /*************************************************************************
644 * PathSetDlgItemPath (SHELL32.48)
646 VOID WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
648 if (SHELL_OsIsUnicode())
649 PathSetDlgItemPathW(hDlg, id, pszPath);
650 else
651 PathSetDlgItemPathA(hDlg, id, pszPath);
655 /*************************************************************************
656 * SHGetSpecialFolderPathA [SHELL32.@]
658 * converts csidl to path
661 static const char * const szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
662 static const char * const szSHUserFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
663 static const char * const szSetup = "Software\\Microsoft\\Windows\\CurrentVersion\\Setup";
664 static const char * const szCurrentVersion = "Software\\Microsoft\\Windows\\CurrentVersion";
665 #if 0
666 static const char * const szEnvUserProfile = "%USERPROFILE%";
667 static const char * const szEnvSystemRoot = "%SYSTEMROOT%";
668 #endif
670 typedef struct
672 DWORD dwFlags;
673 HKEY hRootKey;
674 LPCSTR szValueName;
675 LPCSTR szDefaultPath; /* fallback string; sub dir of windows directory */
676 } CSIDL_DATA;
678 #define CSIDL_MYFLAG_SHFOLDER 1
679 #define CSIDL_MYFLAG_SETUP 2
680 #define CSIDL_MYFLAG_CURRVER 4
681 #define CSIDL_MYFLAG_RELATIVE 8
683 #define HKLM HKEY_LOCAL_MACHINE
684 #define HKCU HKEY_CURRENT_USER
685 static const CSIDL_DATA CSIDL_Data[] =
687 { /* CSIDL_DESKTOP */
688 9, HKCU,
689 "Desktop",
690 "Desktop"
692 { /* CSIDL_INTERNET */
693 0, 1, /* FIXME */
694 NULL,
695 NULL,
697 { /* CSIDL_PROGRAMS */
698 9, HKCU,
699 "Programs",
700 "Start Menu\\Programs"
702 { /* CSIDL_CONTROLS (.CPL files) */
703 10, HKLM,
704 "SysDir",
705 "SYSTEM"
707 { /* CSIDL_PRINTERS */
708 10, HKLM,
709 "SysDir",
710 "SYSTEM"
712 { /* CSIDL_PERSONAL */
713 1, HKCU,
714 "Personal",
715 "My Documents"
717 { /* CSIDL_FAVORITES */
718 9, HKCU,
719 "Favorites",
720 "Favorites"
722 { /* CSIDL_STARTUP */
723 9, HKCU,
724 "StartUp",
725 "Start Menu\\Programs\\StartUp"
727 { /* CSIDL_RECENT */
728 9, HKCU,
729 "Recent",
730 "Recent"
732 { /* CSIDL_SENDTO */
733 9, HKCU,
734 "SendTo",
735 "SendTo"
737 { /* CSIDL_BITBUCKET (is this c:\recycled ?) */
738 0, 1, /* FIXME */
739 NULL,
740 "recycled"
742 { /* CSIDL_STARTMENU */
743 9, HKCU,
744 "Start Menu",
745 "Start Menu"
747 { /* CSIDL_MYDOCUMENTS */
748 0, 1, /* FIXME */
749 NULL,
750 NULL,
752 { /* CSIDL_MYMUSIC */
753 0, 1, /* FIXME */
754 NULL,
755 NULL,
757 { /* CSIDL_MYVIDEO */
758 0, 1, /* FIXME */
759 NULL,
760 NULL,
762 { /* unassigned */
763 0, 0,
764 NULL,
765 NULL,
767 { /* CSIDL_DESKTOPDIRECTORY */
768 9, HKCU,
769 "Desktop",
770 "Desktop"
772 { /* CSIDL_DRIVES */
773 0, 1, /* FIXME */
774 NULL,
775 "My Computer"
777 { /* CSIDL_NETWORK */
778 0, 1, /* FIXME */
779 NULL,
780 "Network Neighborhood"
782 { /* CSIDL_NETHOOD */
783 9, HKCU,
784 "NetHood",
785 "NetHood"
787 { /* CSIDL_FONTS */
788 9, HKCU,
789 "Fonts",
790 "Fonts"
792 { /* CSIDL_TEMPLATES */
793 9, HKCU,
794 "Templates",
795 "ShellNew"
797 { /* CSIDL_COMMON_STARTMENU */
798 9, HKLM,
799 "Common Start Menu",
800 "Start Menu"
802 { /* CSIDL_COMMON_PROGRAMS */
803 9, HKLM,
804 "Common Programs",
807 { /* CSIDL_COMMON_STARTUP */
808 9, HKLM,
809 "Common StartUp",
810 "All Users\\Start Menu\\Programs\\StartUp"
812 { /* CSIDL_COMMON_DESKTOPDIRECTORY */
813 9, HKLM,
814 "Common Desktop",
815 "Desktop"
817 { /* CSIDL_APPDATA */
818 9, HKCU,
819 "AppData",
820 "Application Data"
822 { /* CSIDL_PRINTHOOD */
823 9, HKCU,
824 "PrintHood",
825 "PrintHood"
827 { /* CSIDL_LOCAL_APPDATA (win2k only/undocumented) */
828 1, HKCU,
829 "Local AppData",
830 "Local Settings\\Application Data",
832 { /* CSIDL_ALTSTARTUP */
833 0, 1, /* FIXME */
834 NULL,
835 NULL
837 { /* CSIDL_COMMON_ALTSTARTUP */
838 0, 1, /* FIXME */
839 NULL,
840 NULL
842 { /* CSIDL_COMMON_FAVORITES */
843 9, HKCU,
844 "Favorites",
845 "Favorites"
847 { /* CSIDL_INTERNET_CACHE */
848 9, HKCU,
849 "Cache",
850 "Temporary Internet Files"
852 { /* CSIDL_COOKIES */
853 9, HKCU,
854 "Cookies",
855 "Cookies"
857 { /* CSIDL_HISTORY */
858 9, HKCU,
859 "History",
860 "History"
862 { /* CSIDL_COMMON_APPDATA */
863 9, HKLM,
864 "Common AppData",
865 "All Users\\Application Data"
867 { /* CSIDL_WINDOWS */
868 2, HKLM,
869 "WinDir",
870 "Windows"
872 { /* CSIDL_SYSTEM */
873 10, HKLM,
874 "SysDir",
875 "SYSTEM"
877 { /* CSIDL_PROGRAM_FILES */
878 4, HKLM,
879 "ProgramFilesDir",
880 "Program Files"
882 { /* CSIDL_MYPICTURES */
883 1, HKCU,
884 "My Pictures",
885 "My Documents\\My Pictures"
887 { /* CSIDL_PROFILE */
888 10, HKLM,
889 "WinDir", /* correct ? */
892 { /* CSIDL_SYSTEMX86 */
893 10, HKLM,
894 "SysDir",
895 "SYSTEM"
897 { /* CSIDL_PROGRAM_FILESX86 */
898 4, HKLM,
899 "ProgramFilesDir",
900 "Program Files"
902 { /* CSIDL_PROGRAM_FILES_COMMON */
903 4, HKLM,
904 "CommonFilesDir",
905 "Program Files\\Common Files" /* ? */
907 { /* CSIDL_PROGRAM_FILES_COMMONX86 */
908 4, HKLM,
909 "CommonFilesDir",
910 "Program Files\\Common Files" /* ? */
912 { /* CSIDL_COMMON_TEMPLATES */
913 0, 1, /* FIXME */
914 NULL,
915 NULL
917 { /* CSIDL_COMMON_DOCUMENTS */
918 0, 1, /* FIXME */
919 NULL,
920 NULL
922 { /* CSIDL_COMMON_ADMINTOOLS */
923 0, 1, /* FIXME */
924 NULL,
925 NULL
927 { /* CSIDL_ADMINTOOLS */
928 9, HKCU,
929 "Administrative Tools",
930 "Start Menu\\Programs\\Administrative Tools"
932 { /* CSIDL_CONNECTIONS */
933 0, 1, /* FIXME */
934 NULL,
935 NULL
937 { /* unassigned 32*/
938 0, 0,
939 NULL,
940 NULL,
942 { /* unassigned 33*/
943 0, 0,
944 NULL,
945 NULL,
947 { /* unassigned 34*/
948 0, 0,
949 NULL,
950 NULL,
952 { /* CSIDL_COMMON_MUSIC */
953 0, 0, /* FIXME */
954 NULL,
955 NULL,
957 { /* CSIDL_COMMON_PICTURES */
958 0, 0, /* FIXME */
959 NULL,
960 NULL,
962 { /* CSIDL_COMMON_VIDEO */
963 0, 0, /* FIXME */
964 NULL,
965 NULL,
967 { /* CSIDL_RESOURCES */
968 0, 0, /* FIXME */
969 NULL,
970 NULL,
972 { /* CSIDL_RESOURCES_LOCALIZED */
973 0, 0, /* FIXME */
974 NULL,
975 NULL,
977 { /* CSIDL_COMMON_OEM_LINKS */
978 0, 0, /* FIXME */
979 NULL,
980 NULL,
982 { /* CSIDL_CDBURN_AREA */
983 0, 0, /* FIXME */
984 NULL,
985 NULL,
987 { /* unassigned 3C */
988 0, 0,
989 NULL,
990 NULL,
992 { /* CSIDL_COMPUTERSNEARME */
993 0, 0, /* FIXME */
994 NULL,
995 NULL,
998 #undef HKCU
999 #undef HKLM
1001 /**********************************************************************/
1003 BOOL WINAPI SHGetSpecialFolderPathA (
1004 HWND hwndOwner,
1005 LPSTR szPath,
1006 DWORD csidl,
1007 BOOL bCreate)
1009 CHAR szValueName[MAX_PATH], szDefaultPath[MAX_PATH], szBuildPath[MAX_PATH];
1010 HKEY hRootKey, hKey;
1011 DWORD dwFlags;
1012 DWORD dwType, dwDisp, dwPathLen = MAX_PATH;
1013 DWORD folder = csidl & CSIDL_FOLDER_MASK;
1014 CHAR *p;
1016 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
1018 if ((folder > CSIDL_COMPUTERSNEARME) || (CSIDL_Data[folder].hRootKey == 0))
1020 ERR("folder unknown or not allowed\n");
1021 return FALSE;
1023 if (CSIDL_Data[folder].hRootKey == 1)
1025 FIXME("folder unknown, please add.\n");
1026 return FALSE;
1029 dwFlags = CSIDL_Data[folder].dwFlags;
1030 hRootKey = CSIDL_Data[folder].hRootKey;
1031 strcpy(szValueName, CSIDL_Data[folder].szValueName);
1032 strcpy(szDefaultPath, CSIDL_Data[folder].szDefaultPath);
1034 if (dwFlags & CSIDL_MYFLAG_SHFOLDER)
1036 /* user shell folders */
1037 if (RegCreateKeyExA(hRootKey,szSHUserFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1039 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1041 RegCloseKey(hKey);
1043 /* shell folders */
1044 if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1046 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1049 /* value not existing */
1050 if (dwFlags & CSIDL_MYFLAG_RELATIVE)
1052 GetWindowsDirectoryA(szPath, MAX_PATH);
1053 PathAddBackslashA(szPath);
1054 strcat(szPath, szDefaultPath);
1056 else
1058 strcpy(szPath, "C:\\"); /* FIXME ??? */
1059 strcat(szPath, szDefaultPath);
1061 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
1064 RegCloseKey(hKey);
1066 else
1068 LPCSTR pRegPath;
1070 if (dwFlags & CSIDL_MYFLAG_SETUP)
1071 pRegPath = szSetup;
1072 else
1073 if (dwFlags & CSIDL_MYFLAG_CURRVER)
1074 pRegPath = szCurrentVersion;
1075 else
1077 ERR("folder settings broken, please correct !\n");
1078 return FALSE;
1081 if (RegCreateKeyExA(hRootKey,pRegPath,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1083 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1085 /* value not existing */
1086 if (dwFlags & CSIDL_MYFLAG_RELATIVE)
1088 GetWindowsDirectoryA(szPath, MAX_PATH);
1089 PathAddBackslashA(szPath);
1090 strcat(szPath, szDefaultPath);
1092 else
1094 strcpy(szPath, "C:\\"); /* FIXME ??? */
1095 strcat(szPath, szDefaultPath);
1097 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
1099 RegCloseKey(hKey);
1102 /* expand paths like %USERPROFILE% */
1103 if (dwType == REG_EXPAND_SZ)
1105 ExpandEnvironmentStringsA(szPath, szDefaultPath, MAX_PATH);
1106 strcpy(szPath, szDefaultPath);
1109 /* if we don't care about existing directories we are ready */
1110 if(csidl & CSIDL_FLAG_DONT_VERIFY) return TRUE;
1112 if (PathFileExistsA(szPath)) return TRUE;
1114 /* not existing but we are not allowed to create it */
1115 if (!bCreate) return FALSE;
1117 /* create directory/directories */
1118 strcpy(szBuildPath, szPath);
1119 p = strchr(szBuildPath, '\\');
1120 while (p)
1122 *p = 0;
1123 if (!PathFileExistsA(szBuildPath))
1125 if (!CreateDirectoryA(szBuildPath,NULL))
1127 ERR("Failed to create directory '%s'.\n", szPath);
1128 return FALSE;
1131 *p = '\\';
1132 p = strchr(p+1, '\\');
1134 /* last component must be created too. */
1135 if (!PathFileExistsA(szBuildPath))
1137 if (!CreateDirectoryA(szBuildPath,NULL))
1139 ERR("Failed to create directory '%s'.\n", szPath);
1140 return FALSE;
1144 MESSAGE("Created not existing system directory '%s'\n", szPath);
1145 return TRUE;
1148 /*************************************************************************
1149 * SHGetSpecialFolderPathW
1151 BOOL WINAPI SHGetSpecialFolderPathW (
1152 HWND hwndOwner,
1153 LPWSTR szPath,
1154 DWORD csidl,
1155 BOOL bCreate)
1157 char szTemp[MAX_PATH];
1159 if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate))
1161 if (!MultiByteToWideChar( CP_ACP, 0, szTemp, -1, szPath, MAX_PATH ))
1162 szPath[MAX_PATH-1] = 0;
1165 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
1167 return TRUE;
1170 /*************************************************************************
1171 * SHGetSpecialFolderPath (SHELL32.175)
1173 BOOL WINAPI SHGetSpecialFolderPathAW (
1174 HWND hwndOwner,
1175 LPVOID szPath,
1176 DWORD csidl,
1177 BOOL bCreate)
1180 if (SHELL_OsIsUnicode())
1181 return SHGetSpecialFolderPathW (hwndOwner, szPath, csidl, bCreate);
1182 return SHGetSpecialFolderPathA (hwndOwner, szPath, csidl, bCreate);
1185 /*************************************************************************
1186 * SHGetFolderPathA [SHELL32.@]
1188 HRESULT WINAPI SHGetFolderPathA(
1189 HWND hwndOwner,
1190 int nFolder,
1191 HANDLE hToken, /* [in] FIXME: get paths for specific user */
1192 DWORD dwFlags, /* [in] FIXME: SHGFP_TYPE_CURRENT|SHGFP_TYPE_DEFAULT */
1193 LPSTR pszPath)
1195 return (SHGetSpecialFolderPathA(
1196 hwndOwner,
1197 pszPath,
1198 CSIDL_FOLDER_MASK & nFolder,
1199 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;
1202 /*************************************************************************
1203 * SHGetFolderPathW [SHELL32.@]
1205 HRESULT WINAPI SHGetFolderPathW(
1206 HWND hwndOwner,
1207 int nFolder,
1208 HANDLE hToken,
1209 DWORD dwFlags,
1210 LPWSTR pszPath)
1212 return (SHGetSpecialFolderPathW(
1213 hwndOwner,
1214 pszPath,
1215 CSIDL_FOLDER_MASK & nFolder,
1216 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;