Implemented localeconv() with libc function.
[wine.git] / dlls / shell32 / shellpath.c
blob844302c410fa3cc09e02aea37538b9afb79a2ccd
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;
343 static const char * const lpszExtensions[] =
344 {"exe", "com", "pif", "cmd", "bat", "scf", "scr", NULL };
346 TRACE("path=%s\n",lpszPath);
348 for(i=0; lpszExtensions[i]; i++)
349 if (!strcasecmp(lpszExtension,lpszExtensions[i])) return TRUE;
351 return FALSE;
354 /*************************************************************************
355 * PathIsExeW [internal]
357 static BOOL PathIsExeW (LPCWSTR lpszPath)
359 LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
360 int i;
361 static const WCHAR lpszExtensions[][4] =
362 {{'e','x','e','\0'}, {'c','o','m','\0'}, {'p','i','f','\0'},
363 {'c','m','d','\0'}, {'b','a','t','\0'}, {'s','c','f','\0'},
364 {'s','c','r','\0'}, {'\0'} };
366 TRACE("path=%s\n",debugstr_w(lpszPath));
368 for(i=0; lpszExtensions[i][0]; i++)
369 if (!strcmpiW(lpszExtension,lpszExtensions[i])) return TRUE;
371 return FALSE;
374 /*************************************************************************
375 * PathIsExe [SHELL32.43]
377 BOOL WINAPI PathIsExeAW (LPCVOID path)
379 if (SHELL_OsIsUnicode())
380 return PathIsExeW (path);
381 return PathIsExeA(path);
384 /*************************************************************************
385 * PathIsDirectory [SHELL32.159]
387 BOOL WINAPI PathIsDirectoryAW (LPCVOID lpszPath)
389 if (SHELL_OsIsUnicode())
390 return PathIsDirectoryW (lpszPath);
391 return PathIsDirectoryA (lpszPath);
394 /*************************************************************************
395 * PathFileExists [SHELL32.45]
397 BOOL WINAPI PathFileExistsAW (LPCVOID lpszPath)
399 if (SHELL_OsIsUnicode())
400 return PathFileExistsW (lpszPath);
401 return PathFileExistsA (lpszPath);
404 /*************************************************************************
405 * PathMatchSpec [SHELL32.46]
407 BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
409 if (SHELL_OsIsUnicode())
410 return PathMatchSpecW( name, mask );
411 return PathMatchSpecA( name, mask );
414 /*************************************************************************
415 * PathIsSameRoot [SHELL32.650]
417 BOOL WINAPI PathIsSameRootAW(LPCVOID lpszPath1, LPCVOID lpszPath2)
419 if (SHELL_OsIsUnicode())
420 return PathIsSameRootW(lpszPath1, lpszPath2);
421 return PathIsSameRootA(lpszPath1, lpszPath2);
424 /*************************************************************************
425 * IsLFNDrive [SHELL32.119]
427 * NOTES
428 * exported by ordinal Name
430 BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath)
432 DWORD fnlen;
434 if (!GetVolumeInformationA(lpszPath,NULL,0,NULL,&fnlen,NULL,NULL,0))
435 return FALSE;
436 return fnlen>12;
440 ########## Creating Something Unique ##########
442 /*************************************************************************
443 * PathMakeUniqueNameA [internal]
445 BOOL WINAPI PathMakeUniqueNameA(
446 LPSTR lpszBuffer,
447 DWORD dwBuffSize,
448 LPCSTR lpszShortName,
449 LPCSTR lpszLongName,
450 LPCSTR lpszPathName)
452 FIXME("%p %lu %s %s %s stub\n",
453 lpszBuffer, dwBuffSize, debugstr_a(lpszShortName),
454 debugstr_a(lpszLongName), debugstr_a(lpszPathName));
455 return TRUE;
458 /*************************************************************************
459 * PathMakeUniqueNameW [internal]
461 BOOL WINAPI PathMakeUniqueNameW(
462 LPWSTR lpszBuffer,
463 DWORD dwBuffSize,
464 LPCWSTR lpszShortName,
465 LPCWSTR lpszLongName,
466 LPCWSTR lpszPathName)
468 FIXME("%p %lu %s %s %s stub\n",
469 lpszBuffer, dwBuffSize, debugstr_w(lpszShortName),
470 debugstr_w(lpszLongName), debugstr_w(lpszPathName));
471 return TRUE;
474 /*************************************************************************
475 * PathMakeUniqueName [SHELL32.47]
477 BOOL WINAPI PathMakeUniqueNameAW(
478 LPVOID lpszBuffer,
479 DWORD dwBuffSize,
480 LPCVOID lpszShortName,
481 LPCVOID lpszLongName,
482 LPCVOID lpszPathName)
484 if (SHELL_OsIsUnicode())
485 return PathMakeUniqueNameW(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
486 return PathMakeUniqueNameA(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
489 /*************************************************************************
490 * PathYetAnotherMakeUniqueName [SHELL32.75]
492 * NOTES
493 * exported by ordinal
495 BOOL WINAPI PathYetAnotherMakeUniqueNameA(
496 LPSTR lpszBuffer,
497 LPCSTR lpszPathName,
498 LPCSTR lpszShortName,
499 LPCSTR lpszLongName)
501 FIXME("(%p,%p, %p ,%p):stub.\n",
502 lpszBuffer, lpszPathName, lpszShortName, lpszLongName);
503 return TRUE;
508 ########## cleaning and resolving paths ##########
511 /*************************************************************************
512 * PathFindOnPath [SHELL32.145]
514 BOOL WINAPI PathFindOnPathAW(LPVOID sFile, LPCVOID sOtherDirs)
516 if (SHELL_OsIsUnicode())
517 return PathFindOnPathW(sFile, (LPCWSTR *)sOtherDirs);
518 return PathFindOnPathA(sFile, (LPCSTR *)sOtherDirs);
521 /*************************************************************************
522 * PathCleanupSpec [SHELL32.171]
524 DWORD WINAPI PathCleanupSpecAW (LPCVOID x, LPVOID y)
526 FIXME("(%p, %p) stub\n",x,y);
527 return TRUE;
530 /*************************************************************************
531 * PathQualifyA [SHELL32]
533 BOOL WINAPI PathQualifyA(LPCSTR pszPath)
535 FIXME("%s\n",pszPath);
536 return 0;
539 /*************************************************************************
540 * PathQualifyW [SHELL32]
542 BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
544 FIXME("%s\n",debugstr_w(pszPath));
545 return 0;
548 /*************************************************************************
549 * PathQualify [SHELL32.49]
551 BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
553 if (SHELL_OsIsUnicode())
554 return PathQualifyW(pszPath);
555 return PathQualifyA(pszPath);
558 /*************************************************************************
559 * PathResolveA [SHELL32.51]
561 BOOL WINAPI PathResolveA(
562 LPSTR lpszPath,
563 LPCSTR *alpszPaths,
564 DWORD dwFlags)
566 FIXME("(%s,%p,0x%08lx),stub!\n",
567 lpszPath, *alpszPaths, dwFlags);
568 return 0;
571 /*************************************************************************
572 * PathResolveW [SHELL32]
574 BOOL WINAPI PathResolveW(
575 LPWSTR lpszPath,
576 LPCWSTR *alpszPaths,
577 DWORD dwFlags)
579 FIXME("(%s,%p,0x%08lx),stub!\n",
580 debugstr_w(lpszPath), debugstr_w(*alpszPaths), dwFlags);
581 return 0;
584 /*************************************************************************
585 * PathResolve [SHELL32.51]
587 BOOL WINAPI PathResolveAW(
588 LPVOID lpszPath,
589 LPCVOID *alpszPaths,
590 DWORD dwFlags)
592 if (SHELL_OsIsUnicode())
593 return PathResolveW(lpszPath, (LPCWSTR*)alpszPaths, dwFlags);
594 return PathResolveA(lpszPath, (LPCSTR*)alpszPaths, dwFlags);
597 /*************************************************************************
598 * PathProcessCommandA [SHELL32.653]
600 HRESULT WINAPI PathProcessCommandA (
601 LPCSTR lpszPath,
602 LPSTR lpszBuff,
603 DWORD dwBuffSize,
604 DWORD dwFlags)
606 FIXME("%s %p 0x%04lx 0x%04lx stub\n",
607 lpszPath, lpszBuff, dwBuffSize, dwFlags);
608 strcpy(lpszBuff, lpszPath);
609 return 0;
612 /*************************************************************************
613 * PathProcessCommandW
615 HRESULT WINAPI PathProcessCommandW (
616 LPCWSTR lpszPath,
617 LPWSTR lpszBuff,
618 DWORD dwBuffSize,
619 DWORD dwFlags)
621 FIXME("(%s, %p, 0x%04lx, 0x%04lx) stub\n",
622 debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags);
623 strcpyW(lpszBuff, lpszPath);
624 return 0;
627 /*************************************************************************
628 * PathProcessCommand (SHELL32.653)
630 HRESULT WINAPI PathProcessCommandAW (
631 LPCVOID lpszPath,
632 LPVOID lpszBuff,
633 DWORD dwBuffSize,
634 DWORD dwFlags)
636 if (SHELL_OsIsUnicode())
637 return PathProcessCommandW(lpszPath, lpszBuff, dwBuffSize, dwFlags);
638 return PathProcessCommandA(lpszPath, lpszBuff, dwBuffSize, dwFlags);
642 ########## special ##########
645 /*************************************************************************
646 * PathSetDlgItemPath (SHELL32.48)
648 VOID WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
650 if (SHELL_OsIsUnicode())
651 PathSetDlgItemPathW(hDlg, id, pszPath);
652 else
653 PathSetDlgItemPathA(hDlg, id, pszPath);
657 /*************************************************************************
658 * SHGetSpecialFolderPathA [SHELL32.@]
660 * converts csidl to path
663 static const char * const szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
664 static const char * const szSHUserFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
665 static const char * const szSetup = "Software\\Microsoft\\Windows\\CurrentVersion\\Setup";
666 static const char * const szCurrentVersion = "Software\\Microsoft\\Windows\\CurrentVersion";
667 #if 0
668 static const char * const szEnvUserProfile = "%USERPROFILE%";
669 static const char * const szEnvSystemRoot = "%SYSTEMROOT%";
670 #endif
672 typedef struct
674 DWORD dwFlags;
675 HKEY hRootKey;
676 LPCSTR szValueName;
677 LPCSTR szDefaultPath; /* fallback string; sub dir of windows directory */
678 } CSIDL_DATA;
680 #define CSIDL_MYFLAG_SHFOLDER 1
681 #define CSIDL_MYFLAG_SETUP 2
682 #define CSIDL_MYFLAG_CURRVER 4
683 #define CSIDL_MYFLAG_RELATIVE 8
685 #define HKLM HKEY_LOCAL_MACHINE
686 #define HKCU HKEY_CURRENT_USER
687 static const CSIDL_DATA CSIDL_Data[] =
689 { /* CSIDL_DESKTOP */
690 9, HKCU,
691 "Desktop",
692 "Desktop"
694 { /* CSIDL_INTERNET */
695 0, (HKEY)1, /* FIXME */
696 NULL,
697 NULL,
699 { /* CSIDL_PROGRAMS */
700 9, HKCU,
701 "Programs",
702 "Start Menu\\Programs"
704 { /* CSIDL_CONTROLS (.CPL files) */
705 10, HKLM,
706 "SysDir",
707 "SYSTEM"
709 { /* CSIDL_PRINTERS */
710 10, HKLM,
711 "SysDir",
712 "SYSTEM"
714 { /* CSIDL_PERSONAL */
715 1, HKCU,
716 "Personal",
717 "My Documents"
719 { /* CSIDL_FAVORITES */
720 9, HKCU,
721 "Favorites",
722 "Favorites"
724 { /* CSIDL_STARTUP */
725 9, HKCU,
726 "StartUp",
727 "Start Menu\\Programs\\StartUp"
729 { /* CSIDL_RECENT */
730 9, HKCU,
731 "Recent",
732 "Recent"
734 { /* CSIDL_SENDTO */
735 9, HKCU,
736 "SendTo",
737 "SendTo"
739 { /* CSIDL_BITBUCKET (is this c:\recycled ?) */
740 0, (HKEY)1, /* FIXME */
741 NULL,
742 "recycled"
744 { /* CSIDL_STARTMENU */
745 9, HKCU,
746 "Start Menu",
747 "Start Menu"
749 { /* CSIDL_MYDOCUMENTS */
750 0, (HKEY)1, /* FIXME */
751 NULL,
752 NULL,
754 { /* CSIDL_MYMUSIC */
755 0, (HKEY)1, /* FIXME */
756 NULL,
757 NULL,
759 { /* CSIDL_MYVIDEO */
760 0, (HKEY)1, /* FIXME */
761 NULL,
762 NULL,
764 { /* unassigned */
765 0, 0,
766 NULL,
767 NULL,
769 { /* CSIDL_DESKTOPDIRECTORY */
770 9, HKCU,
771 "Desktop",
772 "Desktop"
774 { /* CSIDL_DRIVES */
775 0, (HKEY)1, /* FIXME */
776 NULL,
777 "My Computer"
779 { /* CSIDL_NETWORK */
780 0, (HKEY)1, /* FIXME */
781 NULL,
782 "Network Neighborhood"
784 { /* CSIDL_NETHOOD */
785 9, HKCU,
786 "NetHood",
787 "NetHood"
789 { /* CSIDL_FONTS */
790 9, HKCU,
791 "Fonts",
792 "Fonts"
794 { /* CSIDL_TEMPLATES */
795 9, HKCU,
796 "Templates",
797 "ShellNew"
799 { /* CSIDL_COMMON_STARTMENU */
800 9, HKLM,
801 "Common Start Menu",
802 "Start Menu"
804 { /* CSIDL_COMMON_PROGRAMS */
805 9, HKLM,
806 "Common Programs",
809 { /* CSIDL_COMMON_STARTUP */
810 9, HKLM,
811 "Common StartUp",
812 "All Users\\Start Menu\\Programs\\StartUp"
814 { /* CSIDL_COMMON_DESKTOPDIRECTORY */
815 9, HKLM,
816 "Common Desktop",
817 "Desktop"
819 { /* CSIDL_APPDATA */
820 9, HKCU,
821 "AppData",
822 "Application Data"
824 { /* CSIDL_PRINTHOOD */
825 9, HKCU,
826 "PrintHood",
827 "PrintHood"
829 { /* CSIDL_LOCAL_APPDATA (win2k only/undocumented) */
830 1, HKCU,
831 "Local AppData",
832 "Local Settings\\Application Data",
834 { /* CSIDL_ALTSTARTUP */
835 0, (HKEY)1, /* FIXME */
836 NULL,
837 NULL
839 { /* CSIDL_COMMON_ALTSTARTUP */
840 0, (HKEY)1, /* FIXME */
841 NULL,
842 NULL
844 { /* CSIDL_COMMON_FAVORITES */
845 9, HKCU,
846 "Favorites",
847 "Favorites"
849 { /* CSIDL_INTERNET_CACHE */
850 9, HKCU,
851 "Cache",
852 "Temporary Internet Files"
854 { /* CSIDL_COOKIES */
855 9, HKCU,
856 "Cookies",
857 "Cookies"
859 { /* CSIDL_HISTORY */
860 9, HKCU,
861 "History",
862 "History"
864 { /* CSIDL_COMMON_APPDATA */
865 9, HKLM,
866 "Common AppData",
867 "All Users\\Application Data"
869 { /* CSIDL_WINDOWS */
870 2, HKLM,
871 "WinDir",
872 "Windows"
874 { /* CSIDL_SYSTEM */
875 10, HKLM,
876 "SysDir",
877 "SYSTEM"
879 { /* CSIDL_PROGRAM_FILES */
880 4, HKLM,
881 "ProgramFilesDir",
882 "Program Files"
884 { /* CSIDL_MYPICTURES */
885 1, HKCU,
886 "My Pictures",
887 "My Documents\\My Pictures"
889 { /* CSIDL_PROFILE */
890 10, HKLM,
891 "WinDir", /* correct ? */
894 { /* CSIDL_SYSTEMX86 */
895 10, HKLM,
896 "SysDir",
897 "SYSTEM"
899 { /* CSIDL_PROGRAM_FILESX86 */
900 4, HKLM,
901 "ProgramFilesDir",
902 "Program Files"
904 { /* CSIDL_PROGRAM_FILES_COMMON */
905 4, HKLM,
906 "CommonFilesDir",
907 "Program Files\\Common Files" /* ? */
909 { /* CSIDL_PROGRAM_FILES_COMMONX86 */
910 4, HKLM,
911 "CommonFilesDir",
912 "Program Files\\Common Files" /* ? */
914 { /* CSIDL_COMMON_TEMPLATES */
915 0, (HKEY)1, /* FIXME */
916 NULL,
917 NULL
919 { /* CSIDL_COMMON_DOCUMENTS */
920 0, (HKEY)1, /* FIXME */
921 NULL,
922 NULL
924 { /* CSIDL_COMMON_ADMINTOOLS */
925 0, (HKEY)1, /* FIXME */
926 NULL,
927 NULL
929 { /* CSIDL_ADMINTOOLS */
930 9, HKCU,
931 "Administrative Tools",
932 "Start Menu\\Programs\\Administrative Tools"
934 { /* CSIDL_CONNECTIONS */
935 0, (HKEY)1, /* FIXME */
936 NULL,
937 NULL
939 { /* unassigned 32*/
940 0, 0,
941 NULL,
942 NULL,
944 { /* unassigned 33*/
945 0, 0,
946 NULL,
947 NULL,
949 { /* unassigned 34*/
950 0, 0,
951 NULL,
952 NULL,
954 { /* CSIDL_COMMON_MUSIC */
955 0, 0, /* FIXME */
956 NULL,
957 NULL,
959 { /* CSIDL_COMMON_PICTURES */
960 0, 0, /* FIXME */
961 NULL,
962 NULL,
964 { /* CSIDL_COMMON_VIDEO */
965 0, 0, /* FIXME */
966 NULL,
967 NULL,
969 { /* CSIDL_RESOURCES */
970 0, 0, /* FIXME */
971 NULL,
972 NULL,
974 { /* CSIDL_RESOURCES_LOCALIZED */
975 0, 0, /* FIXME */
976 NULL,
977 NULL,
979 { /* CSIDL_COMMON_OEM_LINKS */
980 0, 0, /* FIXME */
981 NULL,
982 NULL,
984 { /* CSIDL_CDBURN_AREA */
985 0, 0, /* FIXME */
986 NULL,
987 NULL,
989 { /* unassigned 3C */
990 0, 0,
991 NULL,
992 NULL,
994 { /* CSIDL_COMPUTERSNEARME */
995 0, 0, /* FIXME */
996 NULL,
997 NULL,
999 { /* CSIDL_PROFILES */
1000 0, 0, /* FIXME */
1001 NULL,
1002 NULL,
1005 #undef HKCU
1006 #undef HKLM
1008 /**********************************************************************/
1010 BOOL WINAPI SHGetSpecialFolderPathA (
1011 HWND hwndOwner,
1012 LPSTR szPath,
1013 DWORD csidl,
1014 BOOL bCreate)
1016 CHAR szValueName[MAX_PATH], szDefaultPath[MAX_PATH], szBuildPath[MAX_PATH];
1017 HKEY hRootKey, hKey;
1018 DWORD dwFlags;
1019 DWORD dwType, dwDisp, dwPathLen = MAX_PATH;
1020 DWORD folder = csidl & CSIDL_FOLDER_MASK;
1021 CHAR *p;
1023 TRACE("%p,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
1025 if ((folder >= sizeof(CSIDL_Data) / sizeof(CSIDL_Data[0])) ||
1026 (CSIDL_Data[folder].hRootKey == 0))
1028 ERR("folder 0x%04lx unknown or not allowed\n", folder);
1029 return FALSE;
1031 if (CSIDL_Data[folder].hRootKey == (HKEY)1)
1033 FIXME("folder 0x%04lx unknown, please add.\n", folder);
1034 return FALSE;
1037 dwFlags = CSIDL_Data[folder].dwFlags;
1038 hRootKey = CSIDL_Data[folder].hRootKey;
1039 strcpy(szValueName, CSIDL_Data[folder].szValueName);
1040 strcpy(szDefaultPath, CSIDL_Data[folder].szDefaultPath);
1042 if (dwFlags & CSIDL_MYFLAG_SHFOLDER)
1044 /* user shell folders */
1045 if (RegCreateKeyExA(hRootKey,szSHUserFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1047 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1049 RegCloseKey(hKey);
1051 /* shell folders */
1052 if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1054 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1057 /* value not existing */
1058 if (dwFlags & CSIDL_MYFLAG_RELATIVE)
1060 GetWindowsDirectoryA(szPath, MAX_PATH);
1061 PathAddBackslashA(szPath);
1062 strcat(szPath, szDefaultPath);
1064 else
1066 strcpy(szPath, "C:\\"); /* FIXME ??? */
1067 strcat(szPath, szDefaultPath);
1069 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
1072 RegCloseKey(hKey);
1074 else
1076 LPCSTR pRegPath;
1078 if (dwFlags & CSIDL_MYFLAG_SETUP)
1079 pRegPath = szSetup;
1080 else
1081 if (dwFlags & CSIDL_MYFLAG_CURRVER)
1082 pRegPath = szCurrentVersion;
1083 else
1085 ERR("folder settings broken, please correct !\n");
1086 return FALSE;
1089 if (RegCreateKeyExA(hRootKey,pRegPath,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1091 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1093 /* value not existing */
1094 if (dwFlags & CSIDL_MYFLAG_RELATIVE)
1096 GetWindowsDirectoryA(szPath, MAX_PATH);
1097 PathAddBackslashA(szPath);
1098 strcat(szPath, szDefaultPath);
1100 else
1102 strcpy(szPath, "C:\\"); /* FIXME ??? */
1103 strcat(szPath, szDefaultPath);
1105 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
1107 RegCloseKey(hKey);
1110 /* expand paths like %USERPROFILE% */
1111 if (dwType == REG_EXPAND_SZ)
1113 ExpandEnvironmentStringsA(szPath, szDefaultPath, MAX_PATH);
1114 strcpy(szPath, szDefaultPath);
1117 /* if we don't care about existing directories we are ready */
1118 if(csidl & CSIDL_FLAG_DONT_VERIFY) return TRUE;
1120 if (PathFileExistsA(szPath)) return TRUE;
1122 /* not existing but we are not allowed to create it */
1123 if (!bCreate) return FALSE;
1125 /* create directory/directories */
1126 strcpy(szBuildPath, szPath);
1127 p = strchr(szBuildPath, '\\');
1128 while (p)
1130 *p = 0;
1131 if (!PathFileExistsA(szBuildPath))
1133 if (!CreateDirectoryA(szBuildPath,NULL))
1135 ERR("Failed to create directory '%s'.\n", szPath);
1136 return FALSE;
1139 *p = '\\';
1140 p = strchr(p+1, '\\');
1142 /* last component must be created too. */
1143 if (!PathFileExistsA(szBuildPath))
1145 if (!CreateDirectoryA(szBuildPath,NULL))
1147 ERR("Failed to create directory '%s'.\n", szPath);
1148 return FALSE;
1152 MESSAGE("Created not existing system directory '%s'\n", szPath);
1153 return TRUE;
1156 /*************************************************************************
1157 * SHGetSpecialFolderPathW
1159 BOOL WINAPI SHGetSpecialFolderPathW (
1160 HWND hwndOwner,
1161 LPWSTR szPath,
1162 DWORD csidl,
1163 BOOL bCreate)
1165 char szTemp[MAX_PATH];
1167 if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate))
1169 if (!MultiByteToWideChar( CP_ACP, 0, szTemp, -1, szPath, MAX_PATH ))
1170 szPath[MAX_PATH-1] = 0;
1173 TRACE("%p,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
1175 return TRUE;
1178 /*************************************************************************
1179 * SHGetSpecialFolderPath (SHELL32.175)
1181 BOOL WINAPI SHGetSpecialFolderPathAW (
1182 HWND hwndOwner,
1183 LPVOID szPath,
1184 DWORD csidl,
1185 BOOL bCreate)
1188 if (SHELL_OsIsUnicode())
1189 return SHGetSpecialFolderPathW (hwndOwner, szPath, csidl, bCreate);
1190 return SHGetSpecialFolderPathA (hwndOwner, szPath, csidl, bCreate);
1193 /*************************************************************************
1194 * SHGetFolderPathA [SHELL32.@]
1196 HRESULT WINAPI SHGetFolderPathA(
1197 HWND hwndOwner,
1198 int nFolder,
1199 HANDLE hToken, /* [in] FIXME: get paths for specific user */
1200 DWORD dwFlags, /* [in] FIXME: SHGFP_TYPE_CURRENT|SHGFP_TYPE_DEFAULT */
1201 LPSTR pszPath)
1203 return (SHGetSpecialFolderPathA(
1204 hwndOwner,
1205 pszPath,
1206 CSIDL_FOLDER_MASK & nFolder,
1207 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;
1210 /*************************************************************************
1211 * SHGetFolderPathW [SHELL32.@]
1213 HRESULT WINAPI SHGetFolderPathW(
1214 HWND hwndOwner,
1215 int nFolder,
1216 HANDLE hToken,
1217 DWORD dwFlags,
1218 LPWSTR pszPath)
1220 return (SHGetSpecialFolderPathW(
1221 hwndOwner,
1222 pszPath,
1223 CSIDL_FOLDER_MASK & nFolder,
1224 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;