Added the DFCS_{HOT,TRANSPARENT} definitions.
[wine/gsoc_dplay.git] / dlls / shell32 / shellpath.c
blobcb85a42eb37f6e54b56f9ca677d4940d32a350c3
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
25 #include <string.h>
26 #include <ctype.h>
27 #include "wine/debug.h"
28 #include "windef.h"
29 #include "winnls.h"
30 #include "winreg.h"
32 #include "shlobj.h"
33 #include "shell32_main.h"
34 #include "undocshell.h"
35 #include "wine/unicode.h"
36 #include "shlwapi.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(shell);
41 ########## Combining and Constructing paths ##########
44 /*************************************************************************
45 * PathAppend [SHELL32.36]
47 BOOL WINAPI PathAppendAW(
48 LPVOID lpszPath1,
49 LPCVOID lpszPath2)
51 if (SHELL_OsIsUnicode())
52 return PathAppendW(lpszPath1, lpszPath2);
53 return PathAppendA(lpszPath1, lpszPath2);
56 /*************************************************************************
57 * PathCombine [SHELL32.37]
59 LPVOID WINAPI PathCombineAW(
60 LPVOID szDest,
61 LPCVOID lpszDir,
62 LPCVOID lpszFile)
64 if (SHELL_OsIsUnicode())
65 return PathCombineW( szDest, lpszDir, lpszFile );
66 return PathCombineA( szDest, lpszDir, lpszFile );
69 /*************************************************************************
70 * PathAddBackslash [SHELL32.32]
72 LPVOID WINAPI PathAddBackslashAW(LPVOID lpszPath)
74 if(SHELL_OsIsUnicode())
75 return PathAddBackslashW(lpszPath);
76 return PathAddBackslashA(lpszPath);
79 /*************************************************************************
80 * PathBuildRoot [SHELL32.30]
82 LPVOID WINAPI PathBuildRootAW(LPVOID lpszPath, int drive)
84 if(SHELL_OsIsUnicode())
85 return PathBuildRootW(lpszPath, drive);
86 return PathBuildRootA(lpszPath, drive);
90 Extracting Component Parts
93 /*************************************************************************
94 * PathFindFileName [SHELL32.34]
96 LPVOID WINAPI PathFindFileNameAW(LPCVOID lpszPath)
98 if(SHELL_OsIsUnicode())
99 return PathFindFileNameW(lpszPath);
100 return PathFindFileNameA(lpszPath);
103 /*************************************************************************
104 * PathFindExtension [SHELL32.31]
106 LPVOID WINAPI PathFindExtensionAW(LPCVOID lpszPath)
108 if (SHELL_OsIsUnicode())
109 return PathFindExtensionW(lpszPath);
110 return PathFindExtensionA(lpszPath);
114 /*************************************************************************
115 * PathGetExtensionA [internal]
117 * NOTES
118 * exported by ordinal
119 * return value points to the first char after the dot
121 static LPSTR PathGetExtensionA(LPCSTR lpszPath)
123 TRACE("(%s)\n",lpszPath);
125 lpszPath = PathFindExtensionA(lpszPath);
126 return (LPSTR)(*lpszPath?(lpszPath+1):lpszPath);
129 /*************************************************************************
130 * PathGetExtensionW [internal]
132 static LPWSTR PathGetExtensionW(LPCWSTR lpszPath)
134 TRACE("(%s)\n",debugstr_w(lpszPath));
136 lpszPath = PathFindExtensionW(lpszPath);
137 return (LPWSTR)(*lpszPath?(lpszPath+1):lpszPath);
140 /*************************************************************************
141 * PathGetExtension [SHELL32.158]
143 LPVOID WINAPI PathGetExtensionAW(LPCVOID lpszPath,DWORD void1, DWORD void2)
145 if (SHELL_OsIsUnicode())
146 return PathGetExtensionW(lpszPath);
147 return PathGetExtensionA(lpszPath);
150 /*************************************************************************
151 * PathGetArgs [SHELL32.52]
153 LPVOID WINAPI PathGetArgsAW(LPVOID lpszPath)
155 if (SHELL_OsIsUnicode())
156 return PathGetArgsW(lpszPath);
157 return PathGetArgsA(lpszPath);
160 /*************************************************************************
161 * PathGetDriveNumber [SHELL32.57]
163 int WINAPI PathGetDriveNumberAW(LPVOID lpszPath)
165 if (SHELL_OsIsUnicode())
166 return PathGetDriveNumberW(lpszPath);
167 return PathGetDriveNumberA(lpszPath);
170 /*************************************************************************
171 * PathRemoveFileSpec [SHELL32.35]
173 BOOL WINAPI PathRemoveFileSpecAW(LPVOID lpszPath)
175 if (SHELL_OsIsUnicode())
176 return PathRemoveFileSpecW(lpszPath);
177 return PathRemoveFileSpecA(lpszPath);
180 /*************************************************************************
181 * PathStripPath [SHELL32.38]
183 void WINAPI PathStripPathAW(LPVOID lpszPath)
185 if (SHELL_OsIsUnicode())
186 return PathStripPathW(lpszPath);
187 return PathStripPathA(lpszPath);
190 /*************************************************************************
191 * PathStripToRoot [SHELL32.50]
193 BOOL WINAPI PathStripToRootAW(LPVOID lpszPath)
195 if (SHELL_OsIsUnicode())
196 return PathStripToRootW(lpszPath);
197 return PathStripToRootA(lpszPath);
200 /*************************************************************************
201 * PathRemoveArgs [SHELL32.251]
203 void WINAPI PathRemoveArgsAW(LPVOID lpszPath)
205 if (SHELL_OsIsUnicode())
206 PathRemoveArgsW(lpszPath);
207 PathRemoveArgsA(lpszPath);
210 /*************************************************************************
211 * PathRemoveExtension [SHELL32.250]
213 void WINAPI PathRemoveExtensionAW(LPVOID lpszPath)
215 if (SHELL_OsIsUnicode())
216 return PathRemoveExtensionW(lpszPath);
217 return PathRemoveExtensionA(lpszPath);
222 Path Manipulations
225 /*************************************************************************
226 * PathGetShortPathA [internal]
228 LPSTR WINAPI PathGetShortPathA(LPSTR lpszPath)
230 FIXME("%s stub\n", lpszPath);
231 return NULL;
234 /*************************************************************************
235 * PathGetShortPathW [internal]
237 LPWSTR WINAPI PathGetShortPathW(LPWSTR lpszPath)
239 FIXME("%s stub\n", debugstr_w(lpszPath));
240 return NULL;
243 /*************************************************************************
244 * PathGetShortPath [SHELL32.92]
246 LPVOID WINAPI PathGetShortPathAW(LPVOID lpszPath)
248 if(SHELL_OsIsUnicode())
249 return PathGetShortPathW(lpszPath);
250 return PathGetShortPathA(lpszPath);
253 /*************************************************************************
254 * PathRemoveBlanks [SHELL32.33]
256 void WINAPI PathRemoveBlanksAW(LPVOID str)
258 if(SHELL_OsIsUnicode())
259 PathRemoveBlanksW(str);
260 PathRemoveBlanksA(str);
263 /*************************************************************************
264 * PathQuoteSpaces [SHELL32.55]
266 VOID WINAPI PathQuoteSpacesAW (LPVOID lpszPath)
268 if(SHELL_OsIsUnicode())
269 return PathQuoteSpacesW(lpszPath);
270 return PathQuoteSpacesA(lpszPath);
273 /*************************************************************************
274 * PathUnquoteSpaces [SHELL32.56]
276 VOID WINAPI PathUnquoteSpacesAW(LPVOID str)
278 if(SHELL_OsIsUnicode())
279 PathUnquoteSpacesW(str);
280 else
281 PathUnquoteSpacesA(str);
284 /*************************************************************************
285 * PathParseIconLocation [SHELL32.249]
287 int WINAPI PathParseIconLocationAW (LPVOID lpszPath)
289 if(SHELL_OsIsUnicode())
290 return PathParseIconLocationW(lpszPath);
291 return PathParseIconLocationA(lpszPath);
295 ########## Path Testing ##########
297 /*************************************************************************
298 * PathIsUNC [SHELL32.39]
300 BOOL WINAPI PathIsUNCAW (LPCVOID lpszPath)
302 if (SHELL_OsIsUnicode())
303 return PathIsUNCW( lpszPath );
304 return PathIsUNCA( lpszPath );
307 /*************************************************************************
308 * PathIsRelative [SHELL32.40]
310 BOOL WINAPI PathIsRelativeAW (LPCVOID lpszPath)
312 if (SHELL_OsIsUnicode())
313 return PathIsRelativeW( lpszPath );
314 return PathIsRelativeA( lpszPath );
317 /*************************************************************************
318 * PathIsRoot [SHELL32.29]
320 BOOL WINAPI PathIsRootAW(LPCVOID lpszPath)
322 if (SHELL_OsIsUnicode())
323 return PathIsRootW(lpszPath);
324 return PathIsRootA(lpszPath);
327 /*************************************************************************
328 * PathIsExeA [internal]
330 static BOOL PathIsExeA (LPCSTR lpszPath)
332 LPCSTR lpszExtension = PathGetExtensionA(lpszPath);
333 int i = 0;
334 static char * lpszExtensions[6] = {"exe", "com", "pid", "cmd", "bat", NULL };
336 TRACE("path=%s\n",lpszPath);
338 for(i=0; lpszExtensions[i]; i++)
339 if (!strcasecmp(lpszExtension,lpszExtensions[i])) return TRUE;
341 return FALSE;
344 /*************************************************************************
345 * PathIsExeW [internal]
347 static BOOL PathIsExeW (LPCWSTR lpszPath)
349 LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
350 int i = 0;
351 static WCHAR lpszExtensions[6][4] =
352 {{'e','x','e','\0'}, {'c','o','m','\0'}, {'p','i','d','\0'},
353 {'c','m','d','\0'}, {'b','a','t','\0'}, {'\0'} };
355 TRACE("path=%s\n",debugstr_w(lpszPath));
357 for(i=0; lpszExtensions[i][0]; i++)
358 if (!strcmpiW(lpszExtension,lpszExtensions[i])) return TRUE;
360 return FALSE;
363 /*************************************************************************
364 * PathIsExe [SHELL32.43]
366 BOOL WINAPI PathIsExeAW (LPCVOID path)
368 if (SHELL_OsIsUnicode())
369 return PathIsExeW (path);
370 return PathIsExeA(path);
373 /*************************************************************************
374 * PathIsDirectory [SHELL32.159]
376 BOOL WINAPI PathIsDirectoryAW (LPCVOID lpszPath)
378 if (SHELL_OsIsUnicode())
379 return PathIsDirectoryW (lpszPath);
380 return PathIsDirectoryA (lpszPath);
383 /*************************************************************************
384 * PathFileExists [SHELL32.45]
386 BOOL WINAPI PathFileExistsAW (LPCVOID lpszPath)
388 if (SHELL_OsIsUnicode())
389 return PathFileExistsW (lpszPath);
390 return PathFileExistsA (lpszPath);
393 /*************************************************************************
394 * PathMatchSpec [SHELL32.46]
396 BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
398 if (SHELL_OsIsUnicode())
399 return PathMatchSpecW( name, mask );
400 return PathMatchSpecA( name, mask );
403 /*************************************************************************
404 * PathIsSameRoot [SHELL32.650]
406 BOOL WINAPI PathIsSameRootAW(LPCVOID lpszPath1, LPCVOID lpszPath2)
408 if (SHELL_OsIsUnicode())
409 return PathIsSameRootW(lpszPath1, lpszPath2);
410 return PathIsSameRootA(lpszPath1, lpszPath2);
413 /*************************************************************************
414 * IsLFNDrive [SHELL32.119]
416 * NOTES
417 * exported by ordinal Name
419 BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath)
421 DWORD fnlen;
423 if (!GetVolumeInformationA(lpszPath,NULL,0,NULL,&fnlen,NULL,NULL,0))
424 return FALSE;
425 return fnlen>12;
429 ########## Creating Something Unique ##########
431 /*************************************************************************
432 * PathMakeUniqueNameA [internal]
434 BOOL WINAPI PathMakeUniqueNameA(
435 LPSTR lpszBuffer,
436 DWORD dwBuffSize,
437 LPCSTR lpszShortName,
438 LPCSTR lpszLongName,
439 LPCSTR lpszPathName)
441 FIXME("%p %lu %s %s %s stub\n",
442 lpszBuffer, dwBuffSize, debugstr_a(lpszShortName),
443 debugstr_a(lpszLongName), debugstr_a(lpszPathName));
444 return TRUE;
447 /*************************************************************************
448 * PathMakeUniqueNameW [internal]
450 BOOL WINAPI PathMakeUniqueNameW(
451 LPWSTR lpszBuffer,
452 DWORD dwBuffSize,
453 LPCWSTR lpszShortName,
454 LPCWSTR lpszLongName,
455 LPCWSTR lpszPathName)
457 FIXME("%p %lu %s %s %s stub\n",
458 lpszBuffer, dwBuffSize, debugstr_w(lpszShortName),
459 debugstr_w(lpszLongName), debugstr_w(lpszPathName));
460 return TRUE;
463 /*************************************************************************
464 * PathMakeUniqueName [SHELL32.47]
466 BOOL WINAPI PathMakeUniqueNameAW(
467 LPVOID lpszBuffer,
468 DWORD dwBuffSize,
469 LPCVOID lpszShortName,
470 LPCVOID lpszLongName,
471 LPCVOID lpszPathName)
473 if (SHELL_OsIsUnicode())
474 return PathMakeUniqueNameW(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
475 return PathMakeUniqueNameA(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
478 /*************************************************************************
479 * PathYetAnotherMakeUniqueName [SHELL32.75]
481 * NOTES
482 * exported by ordinal
484 BOOL WINAPI PathYetAnotherMakeUniqueNameA(
485 LPSTR lpszBuffer,
486 LPCSTR lpszPathName,
487 LPCSTR lpszShortName,
488 LPCSTR lpszLongName)
490 FIXME("(%p,%p, %p ,%p):stub.\n",
491 lpszBuffer, lpszPathName, lpszShortName, lpszLongName);
492 return TRUE;
497 ########## cleaning and resolving paths ##########
500 /*************************************************************************
501 * PathFindOnPath [SHELL32.145]
503 BOOL WINAPI PathFindOnPathAW(LPVOID sFile, LPCVOID sOtherDirs)
505 if (SHELL_OsIsUnicode())
506 return PathFindOnPathW(sFile, (LPCWSTR *)sOtherDirs);
507 return PathFindOnPathA(sFile, (LPCSTR *)sOtherDirs);
510 /*************************************************************************
511 * PathCleanupSpec [SHELL32.171]
513 DWORD WINAPI PathCleanupSpecAW (LPCVOID x, LPVOID y)
515 FIXME("(%p, %p) stub\n",x,y);
516 return TRUE;
519 /*************************************************************************
520 * PathQualifyA [SHELL32]
522 BOOL WINAPI PathQualifyA(LPCSTR pszPath)
524 FIXME("%s\n",pszPath);
525 return 0;
528 /*************************************************************************
529 * PathQualifyW [SHELL32]
531 BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
533 FIXME("%s\n",debugstr_w(pszPath));
534 return 0;
537 /*************************************************************************
538 * PathQualify [SHELL32.49]
540 BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
542 if (SHELL_OsIsUnicode())
543 return PathQualifyW(pszPath);
544 return PathQualifyA(pszPath);
547 /*************************************************************************
548 * PathResolveA [SHELL32.51]
550 BOOL WINAPI PathResolveA(
551 LPSTR lpszPath,
552 LPCSTR *alpszPaths,
553 DWORD dwFlags)
555 FIXME("(%s,%p,0x%08lx),stub!\n",
556 lpszPath, *alpszPaths, dwFlags);
557 return 0;
560 /*************************************************************************
561 * PathResolveW [SHELL32]
563 BOOL WINAPI PathResolveW(
564 LPWSTR lpszPath,
565 LPCWSTR *alpszPaths,
566 DWORD dwFlags)
568 FIXME("(%s,%p,0x%08lx),stub!\n",
569 debugstr_w(lpszPath), debugstr_w(*alpszPaths), dwFlags);
570 return 0;
573 /*************************************************************************
574 * PathResolve [SHELL32.51]
576 BOOL WINAPI PathResolveAW(
577 LPVOID lpszPath,
578 LPCVOID *alpszPaths,
579 DWORD dwFlags)
581 if (SHELL_OsIsUnicode())
582 return PathResolveW(lpszPath, (LPCWSTR*)alpszPaths, dwFlags);
583 return PathResolveA(lpszPath, (LPCSTR*)alpszPaths, dwFlags);
586 /*************************************************************************
587 * PathProcessCommandA [SHELL32.653]
589 HRESULT WINAPI PathProcessCommandA (
590 LPCSTR lpszPath,
591 LPSTR lpszBuff,
592 DWORD dwBuffSize,
593 DWORD dwFlags)
595 FIXME("%s %p 0x%04lx 0x%04lx stub\n",
596 lpszPath, lpszBuff, dwBuffSize, dwFlags);
597 strcpy(lpszBuff, lpszPath);
598 return 0;
601 /*************************************************************************
602 * PathProcessCommandW
604 HRESULT WINAPI PathProcessCommandW (
605 LPCWSTR lpszPath,
606 LPWSTR lpszBuff,
607 DWORD dwBuffSize,
608 DWORD dwFlags)
610 FIXME("(%s, %p, 0x%04lx, 0x%04lx) stub\n",
611 debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags);
612 strcpyW(lpszBuff, lpszPath);
613 return 0;
616 /*************************************************************************
617 * PathProcessCommand (SHELL32.653)
619 HRESULT WINAPI PathProcessCommandAW (
620 LPCVOID lpszPath,
621 LPVOID lpszBuff,
622 DWORD dwBuffSize,
623 DWORD dwFlags)
625 if (SHELL_OsIsUnicode())
626 return PathProcessCommandW(lpszPath, lpszBuff, dwBuffSize, dwFlags);
627 return PathProcessCommandA(lpszPath, lpszBuff, dwBuffSize, dwFlags);
631 ########## special ##########
634 /*************************************************************************
635 * PathSetDlgItemPath (SHELL32.48)
637 VOID WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
638 { if (SHELL_OsIsUnicode())
639 return PathSetDlgItemPathW(hDlg, id, pszPath);
640 return PathSetDlgItemPathA(hDlg, id, pszPath);
644 /*************************************************************************
645 * SHGetSpecialFolderPathA [SHELL32.@]
647 * converts csidl to path
650 static const char * const szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
651 static const char * const szSHUserFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
652 static const char * const szSetup = "Software\\Microsoft\\Windows\\CurrentVersion\\Setup";
653 static const char * const szCurrentVersion = "Software\\Microsoft\\Windows\\CurrentVersion";
654 #if 0
655 static const char * const szEnvUserProfile = "%USERPROFILE%";
656 static const char * const szEnvSystemRoot = "%SYSTEMROOT%";
657 #endif
659 typedef struct
661 DWORD dwFlags;
662 HKEY hRootKey;
663 LPCSTR szValueName;
664 LPCSTR szDefaultPath; /* fallback string; sub dir of windows directory */
665 } CSIDL_DATA;
667 #define CSIDL_MYFLAG_SHFOLDER 1
668 #define CSIDL_MYFLAG_SETUP 2
669 #define CSIDL_MYFLAG_CURRVER 4
670 #define CSIDL_MYFLAG_RELATIVE 8
672 #define HKLM HKEY_LOCAL_MACHINE
673 #define HKCU HKEY_CURRENT_USER
674 static const CSIDL_DATA CSIDL_Data[] =
676 { /* CSIDL_DESKTOP */
677 9, HKCU,
678 "Desktop",
679 "Desktop"
681 { /* CSIDL_INTERNET */
682 0, 1, /* FIXME */
683 NULL,
684 NULL,
686 { /* CSIDL_PROGRAMS */
687 9, HKCU,
688 "Programs",
689 "Start Menu\\Programs"
691 { /* CSIDL_CONTROLS (.CPL files) */
692 10, HKLM,
693 "SysDir",
694 "SYSTEM"
696 { /* CSIDL_PRINTERS */
697 10, HKLM,
698 "SysDir",
699 "SYSTEM"
701 { /* CSIDL_PERSONAL */
702 1, HKCU,
703 "Personal",
704 "My Documents"
706 { /* CSIDL_FAVORITES */
707 9, HKCU,
708 "Favorites",
709 "Favorites"
711 { /* CSIDL_STARTUP */
712 9, HKCU,
713 "StartUp",
714 "Start Menu\\Programs\\StartUp"
716 { /* CSIDL_RECENT */
717 9, HKCU,
718 "Recent",
719 "Recent"
721 { /* CSIDL_SENDTO */
722 9, HKCU,
723 "SendTo",
724 "SendTo"
726 { /* CSIDL_BITBUCKET (is this c:\recycled ?) */
727 0, 1, /* FIXME */
728 NULL,
729 "recycled"
731 { /* CSIDL_STARTMENU */
732 9, HKCU,
733 "Start Menu",
734 "Start Menu"
736 { /* CSIDL_MYDOCUMENTS */
737 0, 1, /* FIXME */
738 NULL,
739 NULL,
741 { /* CSIDL_MYMUSIC */
742 0, 1, /* FIXME */
743 NULL,
744 NULL,
746 { /* CSIDL_MYVIDEO */
747 0, 1, /* FIXME */
748 NULL,
749 NULL,
751 { /* unassigned */
752 0, 0,
753 NULL,
754 NULL,
756 { /* CSIDL_DESKTOPDIRECTORY */
757 9, HKCU,
758 "Desktop",
759 "Desktop"
761 { /* CSIDL_DRIVES */
762 0, 1, /* FIXME */
763 NULL,
764 "My Computer"
766 { /* CSIDL_NETWORK */
767 0, 1, /* FIXME */
768 NULL,
769 "Network Neighborhood"
771 { /* CSIDL_NETHOOD */
772 9, HKCU,
773 "NetHood",
774 "NetHood"
776 { /* CSIDL_FONTS */
777 9, HKCU,
778 "Fonts",
779 "Fonts"
781 { /* CSIDL_TEMPLATES */
782 9, HKCU,
783 "Templates",
784 "ShellNew"
786 { /* CSIDL_COMMON_STARTMENU */
787 9, HKLM,
788 "Common Start Menu",
789 "Start Menu"
791 { /* CSIDL_COMMON_PROGRAMS */
792 9, HKLM,
793 "Common Programs",
796 { /* CSIDL_COMMON_STARTUP */
797 9, HKLM,
798 "Common StartUp",
799 "All Users\\Start Menu\\Programs\\StartUp"
801 { /* CSIDL_COMMON_DESKTOPDIRECTORY */
802 9, HKLM,
803 "Common Desktop",
804 "Desktop"
806 { /* CSIDL_APPDATA */
807 9, HKCU,
808 "AppData",
809 "Application Data"
811 { /* CSIDL_PRINTHOOD */
812 9, HKCU,
813 "PrintHood",
814 "PrintHood"
816 { /* CSIDL_LOCAL_APPDATA (win2k only/undocumented) */
817 1, HKCU,
818 "Local AppData",
819 "Local Settings\\Application Data",
821 { /* CSIDL_ALTSTARTUP */
822 0, 1, /* FIXME */
823 NULL,
824 NULL
826 { /* CSIDL_COMMON_ALTSTARTUP */
827 0, 1, /* FIXME */
828 NULL,
829 NULL
831 { /* CSIDL_COMMON_FAVORITES */
832 9, HKCU,
833 "Favorites",
834 "Favorites"
836 { /* CSIDL_INTERNET_CACHE */
837 9, HKCU,
838 "Cache",
839 "Temporary Internet Files"
841 { /* CSIDL_COOKIES */
842 9, HKCU,
843 "Cookies",
844 "Cookies"
846 { /* CSIDL_HISTORY */
847 9, HKCU,
848 "History",
849 "History"
851 { /* CSIDL_COMMON_APPDATA */
852 9, HKLM,
853 "Common AppData",
854 "All Users\\Application Data"
856 { /* CSIDL_WINDOWS */
857 2, HKLM,
858 "WinDir",
859 "Windows"
861 { /* CSIDL_SYSTEM */
862 10, HKLM,
863 "SysDir",
864 "SYSTEM"
866 { /* CSIDL_PROGRAM_FILES */
867 4, HKLM,
868 "ProgramFilesDir",
869 "Program Files"
871 { /* CSIDL_MYPICTURES */
872 1, HKCU,
873 "My Pictures",
874 "My Documents\\My Pictures"
876 { /* CSIDL_PROFILE */
877 10, HKLM,
878 "WinDir", /* correct ? */
881 { /* CSIDL_SYSTEMX86 */
882 10, HKLM,
883 "SysDir",
884 "SYSTEM"
886 { /* CSIDL_PROGRAM_FILESX86 */
887 4, HKLM,
888 "ProgramFilesDir",
889 "Program Files"
891 { /* CSIDL_PROGRAM_FILES_COMMON */
892 4, HKLM,
893 "CommonFilesDir",
894 "Program Files\\Common Files" /* ? */
896 { /* CSIDL_PROGRAM_FILES_COMMONX86 */
897 4, HKLM,
898 "CommonFilesDir",
899 "Program Files\\Common Files" /* ? */
901 { /* CSIDL_COMMON_TEMPLATES */
902 0, 1, /* FIXME */
903 NULL,
904 NULL
906 { /* CSIDL_COMMON_DOCUMENTS */
907 0, 1, /* FIXME */
908 NULL,
909 NULL
911 { /* CSIDL_COMMON_ADMINTOOLS */
912 0, 1, /* FIXME */
913 NULL,
914 NULL
916 { /* CSIDL_ADMINTOOLS */
917 9, HKCU,
918 "Administrative Tools",
919 "Start Menu\\Programs\\Administrative Tools"
921 { /* CSIDL_CONNECTIONS */
922 0, 1, /* FIXME */
923 NULL,
924 NULL
926 { /* unassigned 32*/
927 0, 0,
928 NULL,
929 NULL,
931 { /* unassigned 33*/
932 0, 0,
933 NULL,
934 NULL,
936 { /* unassigned 34*/
937 0, 0,
938 NULL,
939 NULL,
941 { /* CSIDL_COMMON_MUSIC */
942 0, 0, /* FIXME */
943 NULL,
944 NULL,
946 { /* CSIDL_COMMON_PICTURES */
947 0, 0, /* FIXME */
948 NULL,
949 NULL,
951 { /* CSIDL_COMMON_VIDEO */
952 0, 0, /* FIXME */
953 NULL,
954 NULL,
956 { /* CSIDL_RESOURCES */
957 0, 0, /* FIXME */
958 NULL,
959 NULL,
961 { /* CSIDL_RESOURCES_LOCALIZED */
962 0, 0, /* FIXME */
963 NULL,
964 NULL,
966 { /* CSIDL_COMMON_OEM_LINKS */
967 0, 0, /* FIXME */
968 NULL,
969 NULL,
971 { /* CSIDL_CDBURN_AREA */
972 0, 0, /* FIXME */
973 NULL,
974 NULL,
976 { /* unassigned 3C */
977 0, 0,
978 NULL,
979 NULL,
981 { /* CSIDL_COMPUTERSNEARME */
982 0, 0, /* FIXME */
983 NULL,
984 NULL,
987 #undef HKCU
988 #undef HKLM
990 /**********************************************************************/
992 BOOL WINAPI SHGetSpecialFolderPathA (
993 HWND hwndOwner,
994 LPSTR szPath,
995 DWORD csidl,
996 BOOL bCreate)
998 CHAR szValueName[MAX_PATH], szDefaultPath[MAX_PATH], szBuildPath[MAX_PATH];
999 HKEY hRootKey, hKey;
1000 DWORD dwFlags;
1001 DWORD dwType, dwDisp, dwPathLen = MAX_PATH;
1002 DWORD folder = csidl & CSIDL_FOLDER_MASK;
1003 CHAR *p;
1005 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
1007 if ((folder > CSIDL_COMPUTERSNEARME) || (CSIDL_Data[folder].hRootKey == 0))
1009 ERR("folder unknown or not allowed\n");
1010 return FALSE;
1012 if (CSIDL_Data[folder].hRootKey == 1)
1014 FIXME("folder unknown, please add.\n");
1015 return FALSE;
1018 dwFlags = CSIDL_Data[folder].dwFlags;
1019 hRootKey = CSIDL_Data[folder].hRootKey;
1020 strcpy(szValueName, CSIDL_Data[folder].szValueName);
1021 strcpy(szDefaultPath, CSIDL_Data[folder].szDefaultPath);
1023 if (dwFlags & CSIDL_MYFLAG_SHFOLDER)
1025 /* user shell folders */
1026 if (RegCreateKeyExA(hRootKey,szSHUserFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1028 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1030 RegCloseKey(hKey);
1032 /* shell folders */
1033 if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1035 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1038 /* value not existing */
1039 if (dwFlags & CSIDL_MYFLAG_RELATIVE)
1041 GetWindowsDirectoryA(szPath, MAX_PATH);
1042 PathAddBackslashA(szPath);
1043 strcat(szPath, szDefaultPath);
1045 else
1047 strcpy(szPath, "C:\\"); /* FIXME ??? */
1048 strcat(szPath, szDefaultPath);
1050 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
1053 RegCloseKey(hKey);
1055 else
1057 LPCSTR pRegPath;
1059 if (dwFlags & CSIDL_MYFLAG_SETUP)
1060 pRegPath = szSetup;
1061 else
1062 if (dwFlags & CSIDL_MYFLAG_CURRVER)
1063 pRegPath = szCurrentVersion;
1064 else
1066 ERR("folder settings broken, please correct !\n");
1067 return FALSE;
1070 if (RegCreateKeyExA(hRootKey,pRegPath,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1072 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1074 /* value not existing */
1075 if (dwFlags & CSIDL_MYFLAG_RELATIVE)
1077 GetWindowsDirectoryA(szPath, MAX_PATH);
1078 PathAddBackslashA(szPath);
1079 strcat(szPath, szDefaultPath);
1081 else
1083 strcpy(szPath, "C:\\"); /* FIXME ??? */
1084 strcat(szPath, szDefaultPath);
1086 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
1088 RegCloseKey(hKey);
1091 /* expand paths like %USERPROFILE% */
1092 if (dwType == REG_EXPAND_SZ)
1094 ExpandEnvironmentStringsA(szPath, szDefaultPath, MAX_PATH);
1095 strcpy(szPath, szDefaultPath);
1098 /* if we don't care about existing directories we are ready */
1099 if(csidl & CSIDL_FLAG_DONT_VERIFY) return TRUE;
1101 if (PathFileExistsA(szPath)) return TRUE;
1103 /* not existing but we are not allowed to create it */
1104 if (!bCreate) return FALSE;
1106 /* create directory/directories */
1107 strcpy(szBuildPath, szPath);
1108 p = strchr(szBuildPath, '\\');
1109 while (p)
1111 *p = 0;
1112 if (!PathFileExistsA(szBuildPath))
1114 if (!CreateDirectoryA(szBuildPath,NULL))
1116 ERR("Failed to create directory '%s'.\n", szPath);
1117 return FALSE;
1120 *p = '\\';
1121 p = strchr(p+1, '\\');
1123 /* last component must be created too. */
1124 if (!PathFileExistsA(szBuildPath))
1126 if (!CreateDirectoryA(szBuildPath,NULL))
1128 ERR("Failed to create directory '%s'.\n", szPath);
1129 return FALSE;
1133 MESSAGE("Created not existing system directory '%s'\n", szPath);
1134 return TRUE;
1137 /*************************************************************************
1138 * SHGetSpecialFolderPathW
1140 BOOL WINAPI SHGetSpecialFolderPathW (
1141 HWND hwndOwner,
1142 LPWSTR szPath,
1143 DWORD csidl,
1144 BOOL bCreate)
1146 char szTemp[MAX_PATH];
1148 if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate))
1150 if (!MultiByteToWideChar( CP_ACP, 0, szTemp, -1, szPath, MAX_PATH ))
1151 szPath[MAX_PATH-1] = 0;
1154 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
1156 return TRUE;
1159 /*************************************************************************
1160 * SHGetSpecialFolderPath (SHELL32.175)
1162 BOOL WINAPI SHGetSpecialFolderPathAW (
1163 HWND hwndOwner,
1164 LPVOID szPath,
1165 DWORD csidl,
1166 BOOL bCreate)
1169 if (SHELL_OsIsUnicode())
1170 return SHGetSpecialFolderPathW (hwndOwner, szPath, csidl, bCreate);
1171 return SHGetSpecialFolderPathA (hwndOwner, szPath, csidl, bCreate);
1174 /*************************************************************************
1175 * SHGetFolderPathA [SHELL32.@]
1177 HRESULT WINAPI SHGetFolderPathA(
1178 HWND hwndOwner,
1179 int nFolder,
1180 HANDLE hToken, /* [in] FIXME: get paths for specific user */
1181 DWORD dwFlags, /* [in] FIXME: SHGFP_TYPE_CURRENT|SHGFP_TYPE_DEFAULT */
1182 LPSTR pszPath)
1184 return (SHGetSpecialFolderPathA(
1185 hwndOwner,
1186 pszPath,
1187 CSIDL_FOLDER_MASK & nFolder,
1188 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;
1191 /*************************************************************************
1192 * SHGetFolderPathW [SHELL32.@]
1194 HRESULT WINAPI SHGetFolderPathW(
1195 HWND hwndOwner,
1196 int nFolder,
1197 HANDLE hToken,
1198 DWORD dwFlags,
1199 LPWSTR pszPath)
1201 return (SHGetSpecialFolderPathW(
1202 hwndOwner,
1203 pszPath,
1204 CSIDL_FOLDER_MASK & nFolder,
1205 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;