Fixed header dependencies to be fully compatible with the Windows
[wine/multimedia.git] / dlls / shell32 / shellpath.c
blobfa3b276334ffa899870f043c0e9cfc572032b3bd
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 <stdarg.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include "wine/debug.h"
33 #include "windef.h"
34 #include "winbase.h"
35 #include "winnls.h"
36 #include "winreg.h"
37 #include "wingdi.h"
38 #include "winuser.h"
40 #include "shlobj.h"
41 #include "shell32_main.h"
42 #include "undocshell.h"
43 #include "wine/unicode.h"
44 #include "shlwapi.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(shell);
49 ########## Combining and Constructing paths ##########
52 /*************************************************************************
53 * PathAppend [SHELL32.36]
55 BOOL WINAPI PathAppendAW(
56 LPVOID lpszPath1,
57 LPCVOID lpszPath2)
59 if (SHELL_OsIsUnicode())
60 return PathAppendW(lpszPath1, lpszPath2);
61 return PathAppendA(lpszPath1, lpszPath2);
64 /*************************************************************************
65 * PathCombine [SHELL32.37]
67 LPVOID WINAPI PathCombineAW(
68 LPVOID szDest,
69 LPCVOID lpszDir,
70 LPCVOID lpszFile)
72 if (SHELL_OsIsUnicode())
73 return PathCombineW( szDest, lpszDir, lpszFile );
74 return PathCombineA( szDest, lpszDir, lpszFile );
77 /*************************************************************************
78 * PathAddBackslash [SHELL32.32]
80 LPVOID WINAPI PathAddBackslashAW(LPVOID lpszPath)
82 if(SHELL_OsIsUnicode())
83 return PathAddBackslashW(lpszPath);
84 return PathAddBackslashA(lpszPath);
87 /*************************************************************************
88 * PathBuildRoot [SHELL32.30]
90 LPVOID WINAPI PathBuildRootAW(LPVOID lpszPath, int drive)
92 if(SHELL_OsIsUnicode())
93 return PathBuildRootW(lpszPath, drive);
94 return PathBuildRootA(lpszPath, drive);
98 Extracting Component Parts
101 /*************************************************************************
102 * PathFindFileName [SHELL32.34]
104 LPVOID WINAPI PathFindFileNameAW(LPCVOID lpszPath)
106 if(SHELL_OsIsUnicode())
107 return PathFindFileNameW(lpszPath);
108 return PathFindFileNameA(lpszPath);
111 /*************************************************************************
112 * PathFindExtension [SHELL32.31]
114 LPVOID WINAPI PathFindExtensionAW(LPCVOID lpszPath)
116 if (SHELL_OsIsUnicode())
117 return PathFindExtensionW(lpszPath);
118 return PathFindExtensionA(lpszPath);
122 /*************************************************************************
123 * PathGetExtensionA [internal]
125 * NOTES
126 * exported by ordinal
127 * return value points to the first char after the dot
129 static LPSTR PathGetExtensionA(LPCSTR lpszPath)
131 TRACE("(%s)\n",lpszPath);
133 lpszPath = PathFindExtensionA(lpszPath);
134 return (LPSTR)(*lpszPath?(lpszPath+1):lpszPath);
137 /*************************************************************************
138 * PathGetExtensionW [internal]
140 static LPWSTR PathGetExtensionW(LPCWSTR lpszPath)
142 TRACE("(%s)\n",debugstr_w(lpszPath));
144 lpszPath = PathFindExtensionW(lpszPath);
145 return (LPWSTR)(*lpszPath?(lpszPath+1):lpszPath);
148 /*************************************************************************
149 * PathGetExtension [SHELL32.158]
151 LPVOID WINAPI PathGetExtensionAW(LPCVOID lpszPath,DWORD void1, DWORD void2)
153 if (SHELL_OsIsUnicode())
154 return PathGetExtensionW(lpszPath);
155 return PathGetExtensionA(lpszPath);
158 /*************************************************************************
159 * PathGetArgs [SHELL32.52]
161 LPVOID WINAPI PathGetArgsAW(LPVOID lpszPath)
163 if (SHELL_OsIsUnicode())
164 return PathGetArgsW(lpszPath);
165 return PathGetArgsA(lpszPath);
168 /*************************************************************************
169 * PathGetDriveNumber [SHELL32.57]
171 int WINAPI PathGetDriveNumberAW(LPVOID lpszPath)
173 if (SHELL_OsIsUnicode())
174 return PathGetDriveNumberW(lpszPath);
175 return PathGetDriveNumberA(lpszPath);
178 /*************************************************************************
179 * PathRemoveFileSpec [SHELL32.35]
181 BOOL WINAPI PathRemoveFileSpecAW(LPVOID lpszPath)
183 if (SHELL_OsIsUnicode())
184 return PathRemoveFileSpecW(lpszPath);
185 return PathRemoveFileSpecA(lpszPath);
188 /*************************************************************************
189 * PathStripPath [SHELL32.38]
191 void WINAPI PathStripPathAW(LPVOID lpszPath)
193 if (SHELL_OsIsUnicode())
194 PathStripPathW(lpszPath);
195 else
196 PathStripPathA(lpszPath);
199 /*************************************************************************
200 * PathStripToRoot [SHELL32.50]
202 BOOL WINAPI PathStripToRootAW(LPVOID lpszPath)
204 if (SHELL_OsIsUnicode())
205 return PathStripToRootW(lpszPath);
206 return PathStripToRootA(lpszPath);
209 /*************************************************************************
210 * PathRemoveArgs [SHELL32.251]
212 void WINAPI PathRemoveArgsAW(LPVOID lpszPath)
214 if (SHELL_OsIsUnicode())
215 PathRemoveArgsW(lpszPath);
216 else
217 PathRemoveArgsA(lpszPath);
220 /*************************************************************************
221 * PathRemoveExtension [SHELL32.250]
223 void WINAPI PathRemoveExtensionAW(LPVOID lpszPath)
225 if (SHELL_OsIsUnicode())
226 PathRemoveExtensionW(lpszPath);
227 else
228 PathRemoveExtensionA(lpszPath);
233 Path Manipulations
236 /*************************************************************************
237 * PathGetShortPathA [internal]
239 LPSTR WINAPI PathGetShortPathA(LPSTR lpszPath)
241 FIXME("%s stub\n", lpszPath);
242 return NULL;
245 /*************************************************************************
246 * PathGetShortPathW [internal]
248 LPWSTR WINAPI PathGetShortPathW(LPWSTR lpszPath)
250 FIXME("%s stub\n", debugstr_w(lpszPath));
251 return NULL;
254 /*************************************************************************
255 * PathGetShortPath [SHELL32.92]
257 LPVOID WINAPI PathGetShortPathAW(LPVOID lpszPath)
259 if(SHELL_OsIsUnicode())
260 return PathGetShortPathW(lpszPath);
261 return PathGetShortPathA(lpszPath);
264 /*************************************************************************
265 * PathRemoveBlanks [SHELL32.33]
267 void WINAPI PathRemoveBlanksAW(LPVOID str)
269 if(SHELL_OsIsUnicode())
270 PathRemoveBlanksW(str);
271 else
272 PathRemoveBlanksA(str);
275 /*************************************************************************
276 * PathQuoteSpaces [SHELL32.55]
278 VOID WINAPI PathQuoteSpacesAW (LPVOID lpszPath)
280 if(SHELL_OsIsUnicode())
281 PathQuoteSpacesW(lpszPath);
282 else
283 PathQuoteSpacesA(lpszPath);
286 /*************************************************************************
287 * PathUnquoteSpaces [SHELL32.56]
289 VOID WINAPI PathUnquoteSpacesAW(LPVOID str)
291 if(SHELL_OsIsUnicode())
292 PathUnquoteSpacesW(str);
293 else
294 PathUnquoteSpacesA(str);
297 /*************************************************************************
298 * PathParseIconLocation [SHELL32.249]
300 int WINAPI PathParseIconLocationAW (LPVOID lpszPath)
302 if(SHELL_OsIsUnicode())
303 return PathParseIconLocationW(lpszPath);
304 return PathParseIconLocationA(lpszPath);
308 ########## Path Testing ##########
310 /*************************************************************************
311 * PathIsUNC [SHELL32.39]
313 BOOL WINAPI PathIsUNCAW (LPCVOID lpszPath)
315 if (SHELL_OsIsUnicode())
316 return PathIsUNCW( lpszPath );
317 return PathIsUNCA( lpszPath );
320 /*************************************************************************
321 * PathIsRelative [SHELL32.40]
323 BOOL WINAPI PathIsRelativeAW (LPCVOID lpszPath)
325 if (SHELL_OsIsUnicode())
326 return PathIsRelativeW( lpszPath );
327 return PathIsRelativeA( lpszPath );
330 /*************************************************************************
331 * PathIsRoot [SHELL32.29]
333 BOOL WINAPI PathIsRootAW(LPCVOID lpszPath)
335 if (SHELL_OsIsUnicode())
336 return PathIsRootW(lpszPath);
337 return PathIsRootA(lpszPath);
340 /*************************************************************************
341 * PathIsExeA [internal]
343 static BOOL PathIsExeA (LPCSTR lpszPath)
345 LPCSTR lpszExtension = PathGetExtensionA(lpszPath);
346 int i;
347 static const char * const lpszExtensions[] =
348 {"exe", "com", "pif", "cmd", "bat", "scf", "scr", NULL };
350 TRACE("path=%s\n",lpszPath);
352 for(i=0; lpszExtensions[i]; i++)
353 if (!strcasecmp(lpszExtension,lpszExtensions[i])) return TRUE;
355 return FALSE;
358 /*************************************************************************
359 * PathIsExeW [internal]
361 static BOOL PathIsExeW (LPCWSTR lpszPath)
363 LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
364 int i;
365 static const WCHAR lpszExtensions[][4] =
366 {{'e','x','e','\0'}, {'c','o','m','\0'}, {'p','i','f','\0'},
367 {'c','m','d','\0'}, {'b','a','t','\0'}, {'s','c','f','\0'},
368 {'s','c','r','\0'}, {'\0'} };
370 TRACE("path=%s\n",debugstr_w(lpszPath));
372 for(i=0; lpszExtensions[i][0]; i++)
373 if (!strcmpiW(lpszExtension,lpszExtensions[i])) return TRUE;
375 return FALSE;
378 /*************************************************************************
379 * PathIsExe [SHELL32.43]
381 BOOL WINAPI PathIsExeAW (LPCVOID path)
383 if (SHELL_OsIsUnicode())
384 return PathIsExeW (path);
385 return PathIsExeA(path);
388 /*************************************************************************
389 * PathIsDirectory [SHELL32.159]
391 BOOL WINAPI PathIsDirectoryAW (LPCVOID lpszPath)
393 if (SHELL_OsIsUnicode())
394 return PathIsDirectoryW (lpszPath);
395 return PathIsDirectoryA (lpszPath);
398 /*************************************************************************
399 * PathFileExists [SHELL32.45]
401 BOOL WINAPI PathFileExistsAW (LPCVOID lpszPath)
403 if (SHELL_OsIsUnicode())
404 return PathFileExistsW (lpszPath);
405 return PathFileExistsA (lpszPath);
408 /*************************************************************************
409 * PathMatchSpec [SHELL32.46]
411 BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
413 if (SHELL_OsIsUnicode())
414 return PathMatchSpecW( name, mask );
415 return PathMatchSpecA( name, mask );
418 /*************************************************************************
419 * PathIsSameRoot [SHELL32.650]
421 BOOL WINAPI PathIsSameRootAW(LPCVOID lpszPath1, LPCVOID lpszPath2)
423 if (SHELL_OsIsUnicode())
424 return PathIsSameRootW(lpszPath1, lpszPath2);
425 return PathIsSameRootA(lpszPath1, lpszPath2);
428 /*************************************************************************
429 * IsLFNDrive [SHELL32.119]
431 * NOTES
432 * exported by ordinal Name
434 BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath)
436 DWORD fnlen;
438 if (!GetVolumeInformationA(lpszPath,NULL,0,NULL,&fnlen,NULL,NULL,0))
439 return FALSE;
440 return fnlen>12;
444 ########## Creating Something Unique ##########
446 /*************************************************************************
447 * PathMakeUniqueNameA [internal]
449 BOOL WINAPI PathMakeUniqueNameA(
450 LPSTR lpszBuffer,
451 DWORD dwBuffSize,
452 LPCSTR lpszShortName,
453 LPCSTR lpszLongName,
454 LPCSTR lpszPathName)
456 FIXME("%p %lu %s %s %s stub\n",
457 lpszBuffer, dwBuffSize, debugstr_a(lpszShortName),
458 debugstr_a(lpszLongName), debugstr_a(lpszPathName));
459 return TRUE;
462 /*************************************************************************
463 * PathMakeUniqueNameW [internal]
465 BOOL WINAPI PathMakeUniqueNameW(
466 LPWSTR lpszBuffer,
467 DWORD dwBuffSize,
468 LPCWSTR lpszShortName,
469 LPCWSTR lpszLongName,
470 LPCWSTR lpszPathName)
472 FIXME("%p %lu %s %s %s stub\n",
473 lpszBuffer, dwBuffSize, debugstr_w(lpszShortName),
474 debugstr_w(lpszLongName), debugstr_w(lpszPathName));
475 return TRUE;
478 /*************************************************************************
479 * PathMakeUniqueName [SHELL32.47]
481 BOOL WINAPI PathMakeUniqueNameAW(
482 LPVOID lpszBuffer,
483 DWORD dwBuffSize,
484 LPCVOID lpszShortName,
485 LPCVOID lpszLongName,
486 LPCVOID lpszPathName)
488 if (SHELL_OsIsUnicode())
489 return PathMakeUniqueNameW(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
490 return PathMakeUniqueNameA(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
493 /*************************************************************************
494 * PathYetAnotherMakeUniqueName [SHELL32.75]
496 * NOTES
497 * exported by ordinal
499 BOOL WINAPI PathYetAnotherMakeUniqueNameA(
500 LPSTR lpszBuffer,
501 LPCSTR lpszPathName,
502 LPCSTR lpszShortName,
503 LPCSTR lpszLongName)
505 FIXME("(%p,%p, %p ,%p):stub.\n",
506 lpszBuffer, lpszPathName, lpszShortName, lpszLongName);
507 return TRUE;
512 ########## cleaning and resolving paths ##########
515 /*************************************************************************
516 * PathFindOnPath [SHELL32.145]
518 BOOL WINAPI PathFindOnPathAW(LPVOID sFile, LPCVOID sOtherDirs)
520 if (SHELL_OsIsUnicode())
521 return PathFindOnPathW(sFile, (LPCWSTR *)sOtherDirs);
522 return PathFindOnPathA(sFile, (LPCSTR *)sOtherDirs);
525 /*************************************************************************
526 * PathCleanupSpec [SHELL32.171]
528 DWORD WINAPI PathCleanupSpecAW (LPCVOID x, LPVOID y)
530 FIXME("(%p, %p) stub\n",x,y);
531 return TRUE;
534 /*************************************************************************
535 * PathQualifyA [SHELL32]
537 BOOL WINAPI PathQualifyA(LPCSTR pszPath)
539 FIXME("%s\n",pszPath);
540 return 0;
543 /*************************************************************************
544 * PathQualifyW [SHELL32]
546 BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
548 FIXME("%s\n",debugstr_w(pszPath));
549 return 0;
552 /*************************************************************************
553 * PathQualify [SHELL32.49]
555 BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
557 if (SHELL_OsIsUnicode())
558 return PathQualifyW(pszPath);
559 return PathQualifyA(pszPath);
562 /*************************************************************************
563 * PathResolveA [SHELL32.51]
565 BOOL WINAPI PathResolveA(
566 LPSTR lpszPath,
567 LPCSTR *alpszPaths,
568 DWORD dwFlags)
570 FIXME("(%s,%p,0x%08lx),stub!\n",
571 lpszPath, *alpszPaths, dwFlags);
572 return 0;
575 /*************************************************************************
576 * PathResolveW [SHELL32]
578 BOOL WINAPI PathResolveW(
579 LPWSTR lpszPath,
580 LPCWSTR *alpszPaths,
581 DWORD dwFlags)
583 FIXME("(%s,%p,0x%08lx),stub!\n",
584 debugstr_w(lpszPath), debugstr_w(*alpszPaths), dwFlags);
585 return 0;
588 /*************************************************************************
589 * PathResolve [SHELL32.51]
591 BOOL WINAPI PathResolveAW(
592 LPVOID lpszPath,
593 LPCVOID *alpszPaths,
594 DWORD dwFlags)
596 if (SHELL_OsIsUnicode())
597 return PathResolveW(lpszPath, (LPCWSTR*)alpszPaths, dwFlags);
598 return PathResolveA(lpszPath, (LPCSTR*)alpszPaths, dwFlags);
601 /*************************************************************************
602 * PathProcessCommandA [SHELL32.653]
604 HRESULT WINAPI PathProcessCommandA (
605 LPCSTR lpszPath,
606 LPSTR lpszBuff,
607 DWORD dwBuffSize,
608 DWORD dwFlags)
610 FIXME("%s %p 0x%04lx 0x%04lx stub\n",
611 lpszPath, lpszBuff, dwBuffSize, dwFlags);
612 strcpy(lpszBuff, lpszPath);
613 return 0;
616 /*************************************************************************
617 * PathProcessCommandW
619 HRESULT WINAPI PathProcessCommandW (
620 LPCWSTR lpszPath,
621 LPWSTR lpszBuff,
622 DWORD dwBuffSize,
623 DWORD dwFlags)
625 FIXME("(%s, %p, 0x%04lx, 0x%04lx) stub\n",
626 debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags);
627 strcpyW(lpszBuff, lpszPath);
628 return 0;
631 /*************************************************************************
632 * PathProcessCommand (SHELL32.653)
634 HRESULT WINAPI PathProcessCommandAW (
635 LPCVOID lpszPath,
636 LPVOID lpszBuff,
637 DWORD dwBuffSize,
638 DWORD dwFlags)
640 if (SHELL_OsIsUnicode())
641 return PathProcessCommandW(lpszPath, lpszBuff, dwBuffSize, dwFlags);
642 return PathProcessCommandA(lpszPath, lpszBuff, dwBuffSize, dwFlags);
646 ########## special ##########
649 /*************************************************************************
650 * PathSetDlgItemPath (SHELL32.48)
652 VOID WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
654 if (SHELL_OsIsUnicode())
655 PathSetDlgItemPathW(hDlg, id, pszPath);
656 else
657 PathSetDlgItemPathA(hDlg, id, pszPath);
661 /*************************************************************************
662 * SHGetSpecialFolderPathA [SHELL32.@]
664 * converts csidl to path
667 static const char * const szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
668 static const char * const szSHUserFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
669 static const char * const szSetup = "Software\\Microsoft\\Windows\\CurrentVersion\\Setup";
670 static const char * const szCurrentVersion = "Software\\Microsoft\\Windows\\CurrentVersion";
671 #if 0
672 static const char * const szEnvUserProfile = "%USERPROFILE%";
673 static const char * const szEnvSystemRoot = "%SYSTEMROOT%";
674 #endif
676 typedef struct
678 DWORD dwFlags;
679 HKEY hRootKey;
680 LPCSTR szValueName;
681 LPCSTR szDefaultPath; /* fallback string; sub dir of windows directory */
682 } CSIDL_DATA;
684 #define CSIDL_MYFLAG_SHFOLDER 1
685 #define CSIDL_MYFLAG_SETUP 2
686 #define CSIDL_MYFLAG_CURRVER 4
687 #define CSIDL_MYFLAG_RELATIVE 8
689 #define HKLM HKEY_LOCAL_MACHINE
690 #define HKCU HKEY_CURRENT_USER
691 static const CSIDL_DATA CSIDL_Data[] =
693 { /* CSIDL_DESKTOP */
694 9, HKCU,
695 "Desktop",
696 "Desktop"
698 { /* CSIDL_INTERNET */
699 0, (HKEY)1, /* FIXME */
700 NULL,
701 NULL,
703 { /* CSIDL_PROGRAMS */
704 9, HKCU,
705 "Programs",
706 "Start Menu\\Programs"
708 { /* CSIDL_CONTROLS (.CPL files) */
709 10, HKLM,
710 "SysDir",
711 "SYSTEM"
713 { /* CSIDL_PRINTERS */
714 10, HKLM,
715 "SysDir",
716 "SYSTEM"
718 { /* CSIDL_PERSONAL */
719 1, HKCU,
720 "Personal",
721 "My Documents"
723 { /* CSIDL_FAVORITES */
724 9, HKCU,
725 "Favorites",
726 "Favorites"
728 { /* CSIDL_STARTUP */
729 9, HKCU,
730 "StartUp",
731 "Start Menu\\Programs\\StartUp"
733 { /* CSIDL_RECENT */
734 9, HKCU,
735 "Recent",
736 "Recent"
738 { /* CSIDL_SENDTO */
739 9, HKCU,
740 "SendTo",
741 "SendTo"
743 { /* CSIDL_BITBUCKET (is this c:\recycled ?) */
744 0, (HKEY)1, /* FIXME */
745 NULL,
746 "recycled"
748 { /* CSIDL_STARTMENU */
749 9, HKCU,
750 "Start Menu",
751 "Start Menu"
753 { /* CSIDL_MYDOCUMENTS */
754 0, (HKEY)1, /* FIXME */
755 NULL,
756 NULL,
758 { /* CSIDL_MYMUSIC */
759 0, (HKEY)1, /* FIXME */
760 NULL,
761 NULL,
763 { /* CSIDL_MYVIDEO */
764 0, (HKEY)1, /* FIXME */
765 NULL,
766 NULL,
768 { /* unassigned */
769 0, 0,
770 NULL,
771 NULL,
773 { /* CSIDL_DESKTOPDIRECTORY */
774 9, HKCU,
775 "Desktop",
776 "Desktop"
778 { /* CSIDL_DRIVES */
779 0, (HKEY)1, /* FIXME */
780 NULL,
781 "My Computer"
783 { /* CSIDL_NETWORK */
784 0, (HKEY)1, /* FIXME */
785 NULL,
786 "Network Neighborhood"
788 { /* CSIDL_NETHOOD */
789 9, HKCU,
790 "NetHood",
791 "NetHood"
793 { /* CSIDL_FONTS */
794 9, HKCU,
795 "Fonts",
796 "Fonts"
798 { /* CSIDL_TEMPLATES */
799 9, HKCU,
800 "Templates",
801 "ShellNew"
803 { /* CSIDL_COMMON_STARTMENU */
804 9, HKLM,
805 "Common Start Menu",
806 "Start Menu"
808 { /* CSIDL_COMMON_PROGRAMS */
809 9, HKLM,
810 "Common Programs",
813 { /* CSIDL_COMMON_STARTUP */
814 9, HKLM,
815 "Common StartUp",
816 "All Users\\Start Menu\\Programs\\StartUp"
818 { /* CSIDL_COMMON_DESKTOPDIRECTORY */
819 9, HKLM,
820 "Common Desktop",
821 "Desktop"
823 { /* CSIDL_APPDATA */
824 9, HKCU,
825 "AppData",
826 "Application Data"
828 { /* CSIDL_PRINTHOOD */
829 9, HKCU,
830 "PrintHood",
831 "PrintHood"
833 { /* CSIDL_LOCAL_APPDATA (win2k only/undocumented) */
834 1, HKCU,
835 "Local AppData",
836 "Local Settings\\Application Data",
838 { /* CSIDL_ALTSTARTUP */
839 0, (HKEY)1, /* FIXME */
840 NULL,
841 NULL
843 { /* CSIDL_COMMON_ALTSTARTUP */
844 0, (HKEY)1, /* FIXME */
845 NULL,
846 NULL
848 { /* CSIDL_COMMON_FAVORITES */
849 9, HKCU,
850 "Favorites",
851 "Favorites"
853 { /* CSIDL_INTERNET_CACHE */
854 9, HKCU,
855 "Cache",
856 "Temporary Internet Files"
858 { /* CSIDL_COOKIES */
859 9, HKCU,
860 "Cookies",
861 "Cookies"
863 { /* CSIDL_HISTORY */
864 9, HKCU,
865 "History",
866 "History"
868 { /* CSIDL_COMMON_APPDATA */
869 9, HKLM,
870 "Common AppData",
871 "All Users\\Application Data"
873 { /* CSIDL_WINDOWS */
874 2, HKLM,
875 "WinDir",
876 "Windows"
878 { /* CSIDL_SYSTEM */
879 10, HKLM,
880 "SysDir",
881 "SYSTEM"
883 { /* CSIDL_PROGRAM_FILES */
884 4, HKLM,
885 "ProgramFilesDir",
886 "Program Files"
888 { /* CSIDL_MYPICTURES */
889 1, HKCU,
890 "My Pictures",
891 "My Documents\\My Pictures"
893 { /* CSIDL_PROFILE */
894 10, HKLM,
895 "WinDir", /* correct ? */
898 { /* CSIDL_SYSTEMX86 */
899 10, HKLM,
900 "SysDir",
901 "SYSTEM"
903 { /* CSIDL_PROGRAM_FILESX86 */
904 4, HKLM,
905 "ProgramFilesDir",
906 "Program Files"
908 { /* CSIDL_PROGRAM_FILES_COMMON */
909 4, HKLM,
910 "CommonFilesDir",
911 "Program Files\\Common Files" /* ? */
913 { /* CSIDL_PROGRAM_FILES_COMMONX86 */
914 4, HKLM,
915 "CommonFilesDir",
916 "Program Files\\Common Files" /* ? */
918 { /* CSIDL_COMMON_TEMPLATES */
919 0, (HKEY)1, /* FIXME */
920 NULL,
921 NULL
923 { /* CSIDL_COMMON_DOCUMENTS */
924 0, (HKEY)1, /* FIXME */
925 NULL,
926 NULL
928 { /* CSIDL_COMMON_ADMINTOOLS */
929 0, (HKEY)1, /* FIXME */
930 NULL,
931 NULL
933 { /* CSIDL_ADMINTOOLS */
934 9, HKCU,
935 "Administrative Tools",
936 "Start Menu\\Programs\\Administrative Tools"
938 { /* CSIDL_CONNECTIONS */
939 0, (HKEY)1, /* FIXME */
940 NULL,
941 NULL
943 { /* unassigned 32*/
944 0, 0,
945 NULL,
946 NULL,
948 { /* unassigned 33*/
949 0, 0,
950 NULL,
951 NULL,
953 { /* unassigned 34*/
954 0, 0,
955 NULL,
956 NULL,
958 { /* CSIDL_COMMON_MUSIC */
959 0, 0, /* FIXME */
960 NULL,
961 NULL,
963 { /* CSIDL_COMMON_PICTURES */
964 0, 0, /* FIXME */
965 NULL,
966 NULL,
968 { /* CSIDL_COMMON_VIDEO */
969 0, 0, /* FIXME */
970 NULL,
971 NULL,
973 { /* CSIDL_RESOURCES */
974 0, 0, /* FIXME */
975 NULL,
976 NULL,
978 { /* CSIDL_RESOURCES_LOCALIZED */
979 0, 0, /* FIXME */
980 NULL,
981 NULL,
983 { /* CSIDL_COMMON_OEM_LINKS */
984 0, 0, /* FIXME */
985 NULL,
986 NULL,
988 { /* CSIDL_CDBURN_AREA */
989 0, 0, /* FIXME */
990 NULL,
991 NULL,
993 { /* unassigned 3C */
994 0, 0,
995 NULL,
996 NULL,
998 { /* CSIDL_COMPUTERSNEARME */
999 0, 0, /* FIXME */
1000 NULL,
1001 NULL,
1003 { /* CSIDL_PROFILES */
1004 0, 0, /* FIXME */
1005 NULL,
1006 NULL,
1009 #undef HKCU
1010 #undef HKLM
1012 /**********************************************************************/
1014 BOOL WINAPI SHGetSpecialFolderPathA (
1015 HWND hwndOwner,
1016 LPSTR szPath,
1017 DWORD csidl,
1018 BOOL bCreate)
1020 CHAR szValueName[MAX_PATH], szDefaultPath[MAX_PATH], szBuildPath[MAX_PATH];
1021 HKEY hRootKey, hKey;
1022 DWORD dwFlags;
1023 DWORD dwType, dwDisp, dwPathLen = MAX_PATH;
1024 DWORD folder = csidl & CSIDL_FOLDER_MASK;
1025 CHAR *p;
1027 TRACE("%p,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
1029 if ((folder >= sizeof(CSIDL_Data) / sizeof(CSIDL_Data[0])) ||
1030 (CSIDL_Data[folder].hRootKey == 0))
1032 ERR("folder 0x%04lx unknown or not allowed\n", folder);
1033 return FALSE;
1035 if (CSIDL_Data[folder].hRootKey == (HKEY)1)
1037 FIXME("folder 0x%04lx unknown, please add.\n", folder);
1038 return FALSE;
1041 dwFlags = CSIDL_Data[folder].dwFlags;
1042 hRootKey = CSIDL_Data[folder].hRootKey;
1043 strcpy(szValueName, CSIDL_Data[folder].szValueName);
1044 strcpy(szDefaultPath, CSIDL_Data[folder].szDefaultPath);
1046 if (dwFlags & CSIDL_MYFLAG_SHFOLDER)
1048 /* user shell folders */
1049 if (RegCreateKeyExA(hRootKey,szSHUserFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1051 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1053 RegCloseKey(hKey);
1055 /* shell folders */
1056 if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1058 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1061 /* value not existing */
1062 if (dwFlags & CSIDL_MYFLAG_RELATIVE)
1064 GetWindowsDirectoryA(szPath, MAX_PATH);
1065 PathAddBackslashA(szPath);
1066 strcat(szPath, szDefaultPath);
1068 else
1070 strcpy(szPath, "C:\\"); /* FIXME ??? */
1071 strcat(szPath, szDefaultPath);
1073 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
1076 RegCloseKey(hKey);
1078 else
1080 LPCSTR pRegPath;
1082 if (dwFlags & CSIDL_MYFLAG_SETUP)
1083 pRegPath = szSetup;
1084 else
1085 if (dwFlags & CSIDL_MYFLAG_CURRVER)
1086 pRegPath = szCurrentVersion;
1087 else
1089 ERR("folder settings broken, please correct !\n");
1090 return FALSE;
1093 if (RegCreateKeyExA(hRootKey,pRegPath,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1095 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1097 /* value not existing */
1098 if (dwFlags & CSIDL_MYFLAG_RELATIVE)
1100 GetWindowsDirectoryA(szPath, MAX_PATH);
1101 PathAddBackslashA(szPath);
1102 strcat(szPath, szDefaultPath);
1104 else
1106 strcpy(szPath, "C:\\"); /* FIXME ??? */
1107 strcat(szPath, szDefaultPath);
1109 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
1111 RegCloseKey(hKey);
1114 /* expand paths like %USERPROFILE% */
1115 if (dwType == REG_EXPAND_SZ)
1117 ExpandEnvironmentStringsA(szPath, szDefaultPath, MAX_PATH);
1118 strcpy(szPath, szDefaultPath);
1121 /* if we don't care about existing directories we are ready */
1122 if(csidl & CSIDL_FLAG_DONT_VERIFY) return TRUE;
1124 if (PathFileExistsA(szPath)) return TRUE;
1126 /* not existing but we are not allowed to create it */
1127 if (!bCreate) return FALSE;
1129 /* create directory/directories */
1130 strcpy(szBuildPath, szPath);
1131 p = strchr(szBuildPath, '\\');
1132 while (p)
1134 *p = 0;
1135 if (!PathFileExistsA(szBuildPath))
1137 if (!CreateDirectoryA(szBuildPath,NULL))
1139 ERR("Failed to create directory '%s'.\n", szPath);
1140 return FALSE;
1143 *p = '\\';
1144 p = strchr(p+1, '\\');
1146 /* last component must be created too. */
1147 if (!PathFileExistsA(szBuildPath))
1149 if (!CreateDirectoryA(szBuildPath,NULL))
1151 ERR("Failed to create directory '%s'.\n", szPath);
1152 return FALSE;
1156 MESSAGE("Created not existing system directory '%s'\n", szPath);
1157 return TRUE;
1160 /*************************************************************************
1161 * SHGetSpecialFolderPathW
1163 BOOL WINAPI SHGetSpecialFolderPathW (
1164 HWND hwndOwner,
1165 LPWSTR szPath,
1166 DWORD csidl,
1167 BOOL bCreate)
1169 char szTemp[MAX_PATH];
1171 if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate))
1173 if (!MultiByteToWideChar( CP_ACP, 0, szTemp, -1, szPath, MAX_PATH ))
1174 szPath[MAX_PATH-1] = 0;
1177 TRACE("%p,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
1179 return TRUE;
1182 /*************************************************************************
1183 * SHGetSpecialFolderPath (SHELL32.175)
1185 BOOL WINAPI SHGetSpecialFolderPathAW (
1186 HWND hwndOwner,
1187 LPVOID szPath,
1188 DWORD csidl,
1189 BOOL bCreate)
1192 if (SHELL_OsIsUnicode())
1193 return SHGetSpecialFolderPathW (hwndOwner, szPath, csidl, bCreate);
1194 return SHGetSpecialFolderPathA (hwndOwner, szPath, csidl, bCreate);
1197 /*************************************************************************
1198 * SHGetFolderPathA [SHELL32.@]
1200 HRESULT WINAPI SHGetFolderPathA(
1201 HWND hwndOwner,
1202 int nFolder,
1203 HANDLE hToken, /* [in] FIXME: get paths for specific user */
1204 DWORD dwFlags, /* [in] FIXME: SHGFP_TYPE_CURRENT|SHGFP_TYPE_DEFAULT */
1205 LPSTR pszPath)
1207 return (SHGetSpecialFolderPathA(
1208 hwndOwner,
1209 pszPath,
1210 CSIDL_FOLDER_MASK & nFolder,
1211 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;
1214 /*************************************************************************
1215 * SHGetFolderPathW [SHELL32.@]
1217 HRESULT WINAPI SHGetFolderPathW(
1218 HWND hwndOwner,
1219 int nFolder,
1220 HANDLE hToken,
1221 DWORD dwFlags,
1222 LPWSTR pszPath)
1224 return (SHGetSpecialFolderPathW(
1225 hwndOwner,
1226 pszPath,
1227 CSIDL_FOLDER_MASK & nFolder,
1228 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;