4 * Many of this functions are in SHLWAPI.DLL also
9 #include "debugtools.h"
11 #include "winversion.h"
16 #include "shell32_main.h"
19 #include "wine/undocshell.h"
22 DEFAULT_DEBUG_CHANNEL(shell)
25 Combining and Constructing paths
28 /*************************************************************************
29 * PathAppendA [SHLWAPI.@]
32 * concat path lpszPath2 onto lpszPath1
35 * the resulting path is also canonicalized
37 LPSTR WINAPI PathAppendA(
41 TRACE("%s %s\n",lpszPath1, lpszPath2);
42 while (lpszPath2[0]=='\\') lpszPath2++;
43 return PathCombineA(lpszPath1,lpszPath1,lpszPath2);
46 /*************************************************************************
47 * PathAppendW [SHLWAPI.@]
49 LPSTR WINAPI PathAppendW(
53 FIXME("%s %s\n",debugstr_w(lpszPath1), debugstr_w(lpszPath2));
57 /*************************************************************************
58 * PathAppendAW [SHELL32.36]
60 LPVOID WINAPI PathAppendAW(
64 if (VERSION_OsIsUnicode())
65 return PathAppendW(lpszPath1, lpszPath2);
66 return PathAppendA(lpszPath1, lpszPath2);
69 /*************************************************************************
70 * PathCombineA [SHLWAPI.@]
73 * if lpszFile='.' skip it
74 * szDest can be equal to lpszFile. Thats why we use sTemp
77 * the resulting path is also canonicalized
78 * If lpszSrcPath2 starts with a backslash it is appended
79 * to the root of lpszSrcPath1.
81 LPSTR WINAPI PathCombineA(
87 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, lpszDir, lpszFile, lpszFile);
90 if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
92 strcpy(szDest,lpszDir);
96 /* if lpszFile is a complete path don't care about lpszDir */
97 if (PathIsRootA(lpszFile))
99 strcpy(szDest,lpszFile);
103 strcpy(sTemp,lpszDir);
104 PathAddBackslashA(sTemp);
105 strcat(sTemp,lpszFile);
106 strcpy(szDest,sTemp);
111 /*************************************************************************
112 * PathCombineW [SHLWAPI.@]
114 LPWSTR WINAPI PathCombineW(
119 WCHAR sTemp[MAX_PATH];
120 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, debugstr_w(lpszDir),
121 lpszFile, debugstr_w(lpszFile));
124 if (!lpszFile || !lpszFile[0] || (lpszFile[0]==(WCHAR)'.' && !lpszFile[1]) )
126 CRTDLL_wcscpy(szDest,lpszDir);
130 /* if lpszFile is a complete path don't care about lpszDir */
131 if (PathIsRootW(lpszFile))
133 CRTDLL_wcscpy(szDest,lpszFile);
137 CRTDLL_wcscpy(sTemp,lpszDir);
138 PathAddBackslashW(sTemp);
139 CRTDLL_wcscat(sTemp,lpszFile);
140 CRTDLL_wcscpy(szDest,sTemp);
145 /*************************************************************************
146 * PathCombineAW [SHELL32.37]
148 LPVOID WINAPI PathCombineAW(
153 if (VERSION_OsIsUnicode())
154 return PathCombineW( szDest, lpszDir, lpszFile );
155 return PathCombineA( szDest, lpszDir, lpszFile );
158 /*************************************************************************
159 * PathAddBackslashA [SHLWAPI.@]
162 * append \ if there is none
164 LPSTR WINAPI PathAddBackslashA(LPSTR lpszPath)
167 TRACE("%p->%s\n",lpszPath,lpszPath);
169 len = strlen(lpszPath);
170 if (len && lpszPath[len-1]!='\\')
172 lpszPath[len] = '\\';
173 lpszPath[len+1]= 0x00;
174 return lpszPath+len+1;
179 /*************************************************************************
180 * PathAddBackslashW [SHLWAPI.@]
182 LPWSTR WINAPI PathAddBackslashW(LPWSTR lpszPath)
185 TRACE("%p->%s\n",lpszPath,debugstr_w(lpszPath));
187 len = CRTDLL_wcslen(lpszPath);
188 if (len && lpszPath[len-1]!=(WCHAR)'\\')
190 lpszPath[len] = (WCHAR)'\\';
191 lpszPath[len+1]= 0x00;
192 return lpszPath+len+1;
197 /*************************************************************************
198 * PathAddBackslashAW [SHELL32.32]
200 LPVOID WINAPI PathAddBackslashAW(LPVOID lpszPath)
202 if(VERSION_OsIsUnicode())
203 return PathAddBackslashW(lpszPath);
204 return PathAddBackslashA(lpszPath);
207 /*************************************************************************
208 * PathBuildRootA [SHLWAPI.@]
210 LPSTR WINAPI PathBuildRootA(LPSTR lpszPath, int drive)
212 TRACE("%p %i\n",lpszPath, drive);
214 strcpy(lpszPath,"A:\\");
219 /*************************************************************************
220 * PathBuildRootW [SHLWAPI.@]
222 LPWSTR WINAPI PathBuildRootW(LPWSTR lpszPath, int drive)
224 TRACE("%p %i\n",debugstr_w(lpszPath), drive);
226 lstrcpyAtoW(lpszPath,"A:\\");
231 /*************************************************************************
232 * PathBuildRootAW [SHELL32.30]
234 LPVOID WINAPI PathBuildRootAW(LPVOID lpszPath, int drive)
236 if(VERSION_OsIsUnicode())
237 return PathBuildRootW(lpszPath, drive);
238 return PathBuildRootA(lpszPath, drive);
242 Extracting Component Parts
245 /*************************************************************************
246 * PathFindFileNameA [SHLWAPI.@]
248 LPSTR WINAPI PathFindFileNameA(LPCSTR lpszPath)
253 TRACE("%s\n",aslash);
256 if (((lpszPath[0]=='\\') || (lpszPath[0]==':')) && lpszPath[1] && lpszPath[1]!='\\')
260 return (LPSTR)aslash;
264 /*************************************************************************
265 * PathFindFileNameW [SHLWAPI.@]
267 LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
272 TRACE("%s\n",debugstr_w(wslash));
275 if (((lpszPath[0]=='\\') || (lpszPath[0]==':')) && lpszPath[1] && lpszPath[1]!='\\')
279 return (LPWSTR)wslash;
282 /*************************************************************************
283 * PathFindFileNameAW [SHELL32.34]
285 LPVOID WINAPI PathFindFileNameAW(LPCVOID lpszPath)
287 if(VERSION_OsIsUnicode())
288 return PathFindFileNameW(lpszPath);
289 return PathFindFileNameA(lpszPath);
292 /*************************************************************************
293 * PathFindExtensionA [SHLWAPI.@]
296 * returns pointer to last . in last lpszPath component or at \0.
299 LPSTR WINAPI PathFindExtensionA(LPCSTR lpszPath)
301 LPCSTR lastpoint = NULL;
303 TRACE("%p %s\n",lpszPath,lpszPath);
307 if (*lpszPath=='\\'||*lpszPath==' ')
313 return (LPSTR)(lastpoint?lastpoint:lpszPath);
316 /*************************************************************************
317 * PathFindExtensionW [SHLWAPI.@]
319 LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
321 LPCWSTR lastpoint = NULL;
323 TRACE("(%p %s)\n",lpszPath,debugstr_w(lpszPath));
327 if (*lpszPath==(WCHAR)'\\'||*lpszPath==(WCHAR)' ')
329 if (*lpszPath==(WCHAR)'.')
333 return (LPWSTR)(lastpoint?lastpoint:lpszPath);
336 /*************************************************************************
337 * PathFindExtensionAW [SHELL32.31]
339 LPVOID WINAPI PathFindExtensionAW(LPCVOID lpszPath)
341 if (VERSION_OsIsUnicode())
342 return PathFindExtensionW(lpszPath);
343 return PathFindExtensionA(lpszPath);
347 /*************************************************************************
348 * PathGetExtensionA [internal]
351 * exported by ordinal
352 * return value points to the first char after the dot
354 LPSTR WINAPI PathGetExtensionA(LPCSTR lpszPath)
356 TRACE("(%s)\n",lpszPath);
358 lpszPath = PathFindExtensionA(lpszPath);
359 return (LPSTR)(*lpszPath?(lpszPath+1):lpszPath);
362 /*************************************************************************
363 * PathGetExtensionW [internal]
365 LPWSTR WINAPI PathGetExtensionW(LPCWSTR lpszPath)
367 TRACE("(%s)\n",debugstr_w(lpszPath));
369 lpszPath = PathFindExtensionW(lpszPath);
370 return (LPWSTR)(*lpszPath?(lpszPath+1):lpszPath);
373 /*************************************************************************
374 * PathGetExtensionAW [SHELL32.158]
376 LPVOID WINAPI PathGetExtensionAW(LPCVOID lpszPath)
378 if (VERSION_OsIsUnicode())
379 return PathGetExtensionW(lpszPath);
380 return PathGetExtensionA(lpszPath);
383 /*************************************************************************
384 * PathGetArgsA [SHLWAPI.@]
387 * look for next arg in string. handle "quoted" strings
388 * returns pointer to argument *AFTER* the space. Or to the \0.
393 LPSTR WINAPI PathGetArgsA(LPCSTR lpszPath)
397 TRACE("%s\n",lpszPath);
401 if ((*lpszPath==' ') && !qflag)
402 return (LPSTR)lpszPath+1;
407 return (LPSTR)lpszPath;
411 /*************************************************************************
412 * PathGetArgsW [SHLWAPI.@]
414 LPWSTR WINAPI PathGetArgsW(LPCWSTR lpszPath)
418 TRACE("%s\n",debugstr_w(lpszPath));
422 if ((*lpszPath==' ') && !qflag)
423 return (LPWSTR)lpszPath+1;
428 return (LPWSTR)lpszPath;
431 /*************************************************************************
432 * PathGetArgsAW [SHELL32.52]
434 LPVOID WINAPI PathGetArgsAW(LPVOID lpszPath)
436 if (VERSION_OsIsUnicode())
437 return PathGetArgsW(lpszPath);
438 return PathGetArgsA(lpszPath);
441 /*************************************************************************
442 * PathGetDriveNumberA [SHLWAPI.@]
444 int WINAPI PathGetDriveNumberA(LPCSTR lpszPath)
446 int chr = tolower(lpszPath[0]);
448 TRACE ("%s\n",debugstr_a(lpszPath));
450 if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
451 return tolower(lpszPath[0]) - 'a' ;
454 /*************************************************************************
455 * PathGetDriveNumberW [SHLWAPI.@]
457 int WINAPI PathGetDriveNumberW(LPCWSTR lpszPath)
459 int chr = towlower(lpszPath[0]);
461 TRACE ("%s\n",debugstr_w(lpszPath));
463 if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
464 return tolower(lpszPath[0]) - 'a' ;
467 /*************************************************************************
468 * PathGetDriveNumber [SHELL32.57]
470 int WINAPI PathGetDriveNumberAW(LPVOID lpszPath)
472 if (VERSION_OsIsUnicode())
473 return PathGetDriveNumberW(lpszPath);
474 return PathGetDriveNumberA(lpszPath);
477 /*************************************************************************
478 * PathRemoveFileSpecA [SHLWAPI.@]
481 * truncates passed argument to a valid path
482 * returns if the string was modified or not.
483 * "\foo\xx\foo"-> "\foo\xx"
487 BOOL WINAPI PathRemoveFileSpecA(LPSTR lpszPath)
491 TRACE("%s\n",lpszPath);
493 if (!lpszPath[0]) return 0;
495 cutplace = PathFindFileNameA(lpszPath);
499 if (PathIsRootA(lpszPath))
501 PathAddBackslashA(lpszPath);
505 PathRemoveBackslashA(lpszPath);
512 /*************************************************************************
513 * PathRemoveFileSpecW [SHLWAPI.@]
515 BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
519 TRACE("%s\n",debugstr_w(lpszPath));
521 if (!lpszPath[0]) return 0;
522 cutplace = PathFindFileNameW(lpszPath);
526 if (PathIsRootW(lpszPath))
528 PathAddBackslashW(lpszPath);
532 PathRemoveBackslashW(lpszPath);
539 /*************************************************************************
540 * PathRemoveFileSpec [SHELL32.35]
542 BOOL WINAPI PathRemoveFileSpecAW(LPVOID lpszPath)
544 if (VERSION_OsIsUnicode())
545 return PathRemoveFileSpecW(lpszPath);
546 return PathRemoveFileSpecA(lpszPath);
549 /*************************************************************************
550 * PathStripPathA [SHELLWAPI.@]
553 * removes the path from the beginning of a filename
555 void WINAPI PathStripPathA(LPSTR lpszPath)
557 LPSTR lpszFileName = PathFindFileNameA(lpszPath);
559 TRACE("%s\n", lpszPath);
562 RtlMoveMemory(lpszPath, lpszFileName, strlen(lpszFileName));
565 /*************************************************************************
566 * PathStripPathW [SHELLWAPI.@]
568 void WINAPI PathStripPathW(LPWSTR lpszPath)
570 LPWSTR lpszFileName = PathFindFileNameW(lpszPath);
572 TRACE("%s\n", debugstr_w(lpszPath));
574 RtlMoveMemory(lpszPath, lpszFileName, lstrlenW(lpszFileName)*sizeof(WCHAR));
577 /*************************************************************************
578 * PathStripPathAW [SHELL32.38]
580 void WINAPI PathStripPathAW(LPVOID lpszPath)
582 if (VERSION_OsIsUnicode())
583 return PathStripPathW(lpszPath);
584 return PathStripPathA(lpszPath);
587 /*************************************************************************
588 * PathStripToRootA [SHLWAPI.@]
590 BOOL WINAPI PathStripToRootA(LPSTR lpszPath)
592 TRACE("%s\n", lpszPath);
595 if (lpszPath[1]==':' && lpszPath[2]=='\\')
602 if (lpszPath[0]=='\\')
608 /* UNC "\\<computer>\<share>" */
609 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
611 int foundbackslash = 0;
615 if (*lpszPath=='\\') foundbackslash++;
616 if (foundbackslash==2)
628 /*************************************************************************
629 * PathStripToRootW [SHLWAPI.@]
631 BOOL WINAPI PathStripToRootW(LPWSTR lpszPath)
633 TRACE("%s\n", debugstr_w(lpszPath));
636 if (lpszPath[1]==':' && lpszPath[2]=='\\')
643 if (lpszPath[0]=='\\')
649 /* UNC "\\<computer>\<share>" */
650 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
652 int foundbackslash = 0;
656 if (*lpszPath=='\\') foundbackslash++;
657 if (foundbackslash==2)
669 /*************************************************************************
670 * PathStripToRootAW [SHELL32.50]
672 BOOL WINAPI PathStripToRootAW(LPVOID lpszPath)
674 if (VERSION_OsIsUnicode())
675 return PathStripToRootW(lpszPath);
676 return PathStripToRootA(lpszPath);
679 /*************************************************************************
680 * PathRemoveArgsA [SHLWAPI.@]
682 void WINAPI PathRemoveArgsA(LPSTR lpszPath)
684 LPSTR lpszArgs = PathGetArgsA(lpszPath);
686 TRACE("%s\n", lpszPath);
688 if (lpszArgs) *(--lpszArgs)='\0';
691 /*************************************************************************
692 * PathRemoveArgsW [SHLWAPI.@]
694 void WINAPI PathRemoveArgsW(LPWSTR lpszPath)
696 LPWSTR lpszArgs = PathGetArgsW(lpszPath);
698 TRACE("%s\n", debugstr_w(lpszPath));
700 if (lpszArgs) *(--lpszArgs)='\0';
703 /*************************************************************************
704 * PathRemoveArgsAW [SHELL32.251]
706 void WINAPI PathRemoveArgsAW(LPVOID lpszPath)
708 if (VERSION_OsIsUnicode())
709 return PathRemoveArgsW(lpszPath);
710 return PathRemoveArgsA(lpszPath);
713 /*************************************************************************
714 * PathRemoveExtensionA [SHLWAPI.@]
716 void WINAPI PathRemoveExtensionA(LPSTR lpszPath)
718 LPSTR lpszExtension = PathFindExtensionA(lpszPath);
720 TRACE("%s\n", lpszPath);
722 if (lpszExtension) *lpszExtension='\0';
725 /*************************************************************************
726 * PathRemoveExtensionW [SHLWAPI.@]
728 void WINAPI PathRemoveExtensionW(LPWSTR lpszPath)
730 LPWSTR lpszExtension = PathFindExtensionW(lpszPath);
732 TRACE("%s\n", debugstr_w(lpszPath));
734 if (lpszExtension) *lpszExtension='\0';
737 /*************************************************************************
738 * PathRemoveExtensionAW [SHELL32.250]
740 void WINAPI PathRemoveExtensionAW(LPVOID lpszPath)
742 if (VERSION_OsIsUnicode())
743 return PathRemoveExtensionW(lpszPath);
744 return PathRemoveExtensionA(lpszPath);
747 /*************************************************************************
748 * PathRemoveBackslashA [SHLWAPI.@]
750 * If the path ends in a backslash it is replaced by a NULL
751 * and the address of the NULL is returned
753 * the address of the last character is returned.
756 LPSTR WINAPI PathRemoveBackslashA( LPSTR lpszPath )
760 while (*lpszPath) p = lpszPath++;
761 if ( *p == (CHAR)'\\') *p = (CHAR)'\0';
765 /*************************************************************************
766 * PathRemoveBackslashW [SHLWAPI.@]
768 LPWSTR WINAPI PathRemoveBackslashW( LPWSTR lpszPath )
772 while (*lpszPath); p = lpszPath++;
773 if ( *p == (WCHAR)'\\') *p = (WCHAR)'\0';
781 /*************************************************************************
782 * PathGetShortPathA [internal]
784 LPSTR WINAPI PathGetShortPathA(LPSTR lpszPath)
786 FIXME("%s stub\n", lpszPath);
790 /*************************************************************************
791 * PathGetShortPathW [internal]
793 LPWSTR WINAPI PathGetShortPathW(LPWSTR lpszPath)
795 FIXME("%s stub\n", debugstr_w(lpszPath));
799 /*************************************************************************
800 * PathGetShortPathAW [SHELL32.92]
802 LPVOID WINAPI PathGetShortPathAW(LPVOID lpszPath)
804 if(VERSION_OsIsUnicode())
805 return PathGetShortPathW(lpszPath);
806 return PathGetShortPathA(lpszPath);
809 /*************************************************************************
810 * PathRemoveBlanksA [SHLWAPI.@]
813 * remove spaces from beginning and end of passed string
815 LPSTR WINAPI PathRemoveBlanksA(LPSTR str)
834 /*************************************************************************
835 * PathRemoveBlanksW [SHLWAPI.@]
837 LPWSTR WINAPI PathRemoveBlanksW(LPWSTR str)
841 TRACE("%s\n",debugstr_w(str));
845 CRTDLL_wcscpy(str,x);
848 x=str+CRTDLL_wcslen(str)-1;
856 /*************************************************************************
857 * PathRemoveBlanksAW [SHELL32.33]
859 LPVOID WINAPI PathRemoveBlanksAW(LPVOID str)
861 if(VERSION_OsIsUnicode())
862 return PathRemoveBlanksW(str);
863 return PathRemoveBlanksA(str);
866 /*************************************************************************
867 * PathQuoteSpacesA [SHLWAPI.@]
871 LPSTR WINAPI PathQuoteSpacesA(LPCSTR lpszPath)
873 FIXME("%s\n",lpszPath);
877 /*************************************************************************
878 * PathQuoteSpacesW [SHLWAPI.@]
880 LPWSTR WINAPI PathQuoteSpacesW(LPCWSTR lpszPath)
882 FIXME("%s\n",debugstr_w(lpszPath));
886 /*************************************************************************
887 * PathQuoteSpacesAW [SHELL32.55]
889 LPVOID WINAPI PathQuoteSpacesAW (LPCVOID lpszPath)
891 if(VERSION_OsIsUnicode())
892 return PathQuoteSpacesW(lpszPath);
893 return PathQuoteSpacesA(lpszPath);
896 /*************************************************************************
897 * PathUnquoteSpacesA [SHLWAPI.@]
900 * unquote string (remove ")
902 VOID WINAPI PathUnquoteSpacesA(LPSTR str)
904 DWORD len = lstrlenA(str);
917 /*************************************************************************
918 * PathUnquoteSpacesW [SHLWAPI.@]
920 VOID WINAPI PathUnquoteSpacesW(LPWSTR str)
922 DWORD len = CRTDLL_wcslen(str);
924 TRACE("%s\n",debugstr_w(str));
931 CRTDLL_wcscpy(str,str+1);
935 /*************************************************************************
936 * PathUnquoteSpacesAW [SHELL32.56]
938 VOID WINAPI PathUnquoteSpacesAW(LPVOID str)
940 if(VERSION_OsIsUnicode())
941 PathUnquoteSpacesW(str);
943 PathUnquoteSpacesA(str);
946 /*************************************************************************
947 * PathParseIconLocationA [SHLWAPI.@]
949 int WINAPI PathParseIconLocationA(LPSTR lpszPath)
951 LPSTR lpstrComma = strchr(lpszPath, ',');
953 FIXME("%s stub\n", debugstr_a(lpszPath));
955 if (lpstrComma && lpstrComma[1])
958 /* return atoi(&lpstrComma[1]); FIXME */
963 /*************************************************************************
964 * PathParseIconLocationW [SHLWAPI.@]
966 int WINAPI PathParseIconLocationW(LPWSTR lpszPath)
968 LPWSTR lpstrComma = CRTDLL_wcschr(lpszPath, ',');
970 FIXME("%s stub\n", debugstr_w(lpszPath));
972 if (lpstrComma && lpstrComma[1])
975 /* return _wtoi(&lpstrComma[1]); FIXME */
980 /*************************************************************************
981 * PathParseIconLocationAW [SHELL32.249]
983 int WINAPI PathParseIconLocationAW (LPVOID lpszPath)
985 if(VERSION_OsIsUnicode())
986 return PathParseIconLocationW(lpszPath);
987 return PathParseIconLocationA(lpszPath);
993 /*************************************************************************
994 * PathIsUNCA [SHLWAPI.@]
997 * PathIsUNC(char*path);
999 BOOL WINAPI PathIsUNCA(LPCSTR lpszPath)
1001 TRACE("%s\n",lpszPath);
1003 return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
1006 /*************************************************************************
1007 * PathIsUNCW [SHLWAPI.@]
1009 BOOL WINAPI PathIsUNCW(LPCWSTR lpszPath)
1011 TRACE("%s\n",debugstr_w(lpszPath));
1013 return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
1016 /*************************************************************************
1017 * PathIsUNCAW [SHELL32.39]
1019 BOOL WINAPI PathIsUNCAW (LPCVOID lpszPath)
1021 if (VERSION_OsIsUnicode())
1022 return PathIsUNCW( lpszPath );
1023 return PathIsUNCA( lpszPath );
1026 /*************************************************************************
1027 * PathIsRelativeA [SHLWAPI.@]
1029 BOOL WINAPI PathIsRelativeA (LPCSTR lpszPath)
1031 TRACE("lpszPath=%s\n",lpszPath);
1033 return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
1036 /*************************************************************************
1037 * PathIsRelativeW [SHLWAPI.@]
1039 BOOL WINAPI PathIsRelativeW (LPCWSTR lpszPath)
1041 TRACE("lpszPath=%s\n",debugstr_w(lpszPath));
1043 return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
1046 /*************************************************************************
1047 * PathIsRelativeAW [SHELL32.40]
1049 BOOL WINAPI PathIsRelativeAW (LPCVOID lpszPath)
1051 if (VERSION_OsIsUnicode())
1052 return PathIsRelativeW( lpszPath );
1053 return PathIsRelativeA( lpszPath );
1056 /*************************************************************************
1057 * PathIsRootA [SHLWAPI.@]
1060 * TRUE if the path points to a root directory
1062 BOOL WINAPI PathIsRootA(LPCSTR lpszPath)
1064 TRACE("%s\n",lpszPath);
1067 if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
1071 if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
1074 /* UNC "\\<computer>\<share>" */
1075 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
1077 int foundbackslash = 0;
1081 if (*(lpszPath++)=='\\') foundbackslash++;
1083 if (foundbackslash==1)
1089 /*************************************************************************
1090 * PathIsRootW [SHLWAPI.@]
1092 BOOL WINAPI PathIsRootW(LPCWSTR lpszPath)
1094 TRACE("%s\n",debugstr_w(lpszPath));
1097 if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
1101 if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
1104 /* UNC "\\<computer>\<share>" */
1105 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
1107 int foundbackslash = 0;
1111 if (*(lpszPath++)=='\\') foundbackslash++;
1113 if (foundbackslash==1)
1120 /*************************************************************************
1121 * PathIsRootAW [SHELL32.29]
1123 BOOL WINAPI PathIsRootAW(LPCVOID lpszPath)
1125 if (VERSION_OsIsUnicode())
1126 return PathIsRootW(lpszPath);
1127 return PathIsRootA(lpszPath);
1130 /*************************************************************************
1131 * PathIsExeA [internal]
1133 BOOL WINAPI PathIsExeA (LPCSTR lpszPath)
1135 LPCSTR lpszExtension = PathGetExtensionA(lpszPath);
1137 static char * lpszExtensions[6] = {"exe", "com", "pid", "cmd", "bat", NULL };
1139 TRACE("path=%s\n",lpszPath);
1141 for(i=0; lpszExtensions[i]; i++)
1142 if (!strcasecmp(lpszExtension,lpszExtensions[i])) return TRUE;
1147 /*************************************************************************
1148 * PathIsExeW [internal]
1150 BOOL WINAPI PathIsExeW (LPCWSTR lpszPath)
1152 LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
1154 static WCHAR lpszExtensions[6][4] =
1155 {{'e','x','e','\0'}, {'c','o','m','\0'}, {'p','i','d','\0'},
1156 {'c','m','d','\0'}, {'b','a','t','\0'}, {'\0'} };
1158 TRACE("path=%s\n",debugstr_w(lpszPath));
1160 for(i=0; lpszExtensions[i]; i++)
1161 if (!CRTDLL__wcsicmp(lpszExtension,lpszExtensions[i])) return TRUE;
1166 /*************************************************************************
1167 * PathIsExeAW [SHELL32.43]
1169 BOOL WINAPI PathIsExeAW (LPCVOID path)
1171 if (VERSION_OsIsUnicode())
1172 return PathIsExeW (path);
1173 return PathIsExeA(path);
1176 /*************************************************************************
1177 * PathIsDirectoryA [SHLWAPI.@]
1179 BOOL WINAPI PathIsDirectoryA(LPCSTR lpszPath)
1182 WIN32_FIND_DATAA stffile;
1184 TRACE("%s\n", debugstr_a(lpszPath));
1186 hFile = FindFirstFileA(lpszPath, &stffile);
1188 if ( hFile != INVALID_HANDLE_VALUE )
1191 return (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
1197 /*************************************************************************
1198 * PathIsDirectoryW [SHLWAPI.@]
1200 BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
1203 WIN32_FIND_DATAW stffile;
1205 TRACE("%s\n", debugstr_w(lpszPath));
1207 hFile = FindFirstFileW(lpszPath, &stffile);
1209 if ( hFile != INVALID_HANDLE_VALUE )
1212 return (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
1218 /*************************************************************************
1219 * PathIsDirectoryAW [SHELL32.159]
1221 BOOL WINAPI PathIsDirectoryAW (LPCVOID lpszPath)
1223 if (VERSION_OsIsUnicode())
1224 return PathIsDirectoryW (lpszPath);
1225 return PathIsDirectoryA (lpszPath);
1228 /*************************************************************************
1229 * PathFileExistsA [SHLWAPI.@]
1232 * file_exists(char *fn);
1234 BOOL WINAPI PathFileExistsA(LPCSTR lpszPath)
1236 TRACE("%s\n",lpszPath);
1237 return (GetFileAttributesA(lpszPath)!=-1);
1240 /*************************************************************************
1241 * PathFileExistsW [SHLWAPI.@]
1243 BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
1245 TRACE("%s\n",debugstr_w(lpszPath));
1246 return (GetFileAttributesW(lpszPath)!=-1);
1249 /*************************************************************************
1250 * PathFileExistsAW [SHELL32.45]
1252 BOOL WINAPI PathFileExistsAW (LPCVOID lpszPath)
1254 if (VERSION_OsIsUnicode())
1255 return PathFileExistsW (lpszPath);
1256 return PathFileExistsA (lpszPath);
1259 /*************************************************************************
1260 * PathMatchSingleMaskA [internal]
1263 * internal (used by PathMatchSpec)
1265 static BOOL PathMatchSingleMaskA(LPCSTR name, LPCSTR mask)
1267 while (*name && *mask && *mask!=';')
1273 if (PathMatchSingleMaskA(name,mask+1)) return 1; /* try substrings */
1277 if (toupper(*mask)!=toupper(*name) && *mask!='?') return 0;
1283 while (*mask=='*') mask++;
1284 if (!*mask || *mask==';') return 1;
1289 /*************************************************************************
1290 * PathMatchSingleMaskW [internal]
1292 static BOOL PathMatchSingleMaskW(LPCWSTR name, LPCWSTR mask)
1294 while (*name && *mask && *mask!=';')
1300 if (PathMatchSingleMaskW(name,mask+1)) return 1; /* try substrings */
1304 if (towupper(*mask)!=towupper(*name) && *mask!='?') return 0;
1310 while (*mask=='*') mask++;
1311 if (!*mask || *mask==';') return 1;
1315 /*************************************************************************
1316 * PathMatchSpecA [SHLWAPI.@]
1319 * used from COMDLG32
1321 BOOL WINAPI PathMatchSpecA(LPCSTR name, LPCSTR mask)
1323 TRACE("%s %s\n",name,mask);
1325 if (!lstrcmpA( mask, "*.*" )) return 1; /* we don't require a period */
1329 if (PathMatchSingleMaskA(name,mask)) return 1; /* helper function */
1330 while (*mask && *mask!=';') mask++;
1334 while (*mask==' ') mask++; /* masks may be separated by "; " */
1340 /*************************************************************************
1341 * PathMatchSpecW [SHLWAPI.@]
1343 BOOL WINAPI PathMatchSpecW(LPCWSTR name, LPCWSTR mask)
1346 TRACE("%s %s\n",debugstr_w(name),debugstr_w(mask));
1348 lstrcpyAtoW(stemp,"*.*");
1349 if (!lstrcmpW( mask, stemp )) return 1; /* we don't require a period */
1353 if (PathMatchSingleMaskW(name,mask)) return 1; /* helper function */
1354 while (*mask && *mask!=';') mask++;
1358 while (*mask==' ') mask++; /* masks may be separated by "; " */
1364 /*************************************************************************
1365 * PathMatchSpecAW [SHELL32.46]
1367 BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
1369 if (VERSION_OsIsUnicode())
1370 return PathMatchSpecW( name, mask );
1371 return PathMatchSpecA( name, mask );
1374 /*************************************************************************
1375 * PathIsSameRootA [SHLWAPI.@]
1378 * what to do with "\path" ??
1380 BOOL WINAPI PathIsSameRootA(LPCSTR lpszPath1, LPCSTR lpszPath2)
1382 TRACE("%s %s\n", lpszPath1, lpszPath2);
1384 if (PathIsRelativeA(lpszPath1) || PathIsRelativeA(lpszPath2)) return FALSE;
1387 if ( toupper(lpszPath1[0])==toupper(lpszPath2[0]) &&
1388 lpszPath1[1]==':' && lpszPath2[1]==':' &&
1389 lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
1393 if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
1394 lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
1396 int pos=2, bsfound=0;
1397 while (lpszPath1[pos] && lpszPath2[pos] &&
1398 (lpszPath1[pos] == lpszPath2[pos]))
1400 if (lpszPath1[pos]=='\\') bsfound++;
1401 if (bsfound == 2) return TRUE;
1404 return (lpszPath1[pos] == lpszPath2[pos]);
1409 /*************************************************************************
1410 * PathIsSameRootW [SHLWAPI.@]
1412 BOOL WINAPI PathIsSameRootW(LPCWSTR lpszPath1, LPCWSTR lpszPath2)
1414 TRACE("%s %s\n", debugstr_w(lpszPath1), debugstr_w(lpszPath2));
1416 if (PathIsRelativeW(lpszPath1) || PathIsRelativeW(lpszPath2)) return FALSE;
1419 if ( towupper(lpszPath1[0])==towupper(lpszPath2[0]) &&
1420 lpszPath1[1]==':' && lpszPath2[1]==':' &&
1421 lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
1425 if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
1426 lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
1428 int pos=2, bsfound=0;
1429 while (lpszPath1[pos] && lpszPath2[pos] &&
1430 (lpszPath1[pos] == lpszPath2[pos]))
1432 if (lpszPath1[pos]=='\\') bsfound++;
1433 if (bsfound == 2) return TRUE;
1436 return (lpszPath1[pos] == lpszPath2[pos]);
1441 /*************************************************************************
1442 * PathIsSameRootAW [SHELL32.650]
1444 BOOL WINAPI PathIsSameRootAW(LPCVOID lpszPath1, LPCVOID lpszPath2)
1446 if (VERSION_OsIsUnicode())
1447 return PathIsSameRootW(lpszPath1, lpszPath2);
1448 return PathIsSameRootA(lpszPath1, lpszPath2);
1451 /*************************************************************************
1454 BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
1458 static LPSTR SupportedProtocol[] =
1459 {"http","https","ftp","gopher","file","mailto",NULL};
1461 if(!lpstrPath) return FALSE;
1464 lpstrRes = strchr(lpstrPath,':');
1465 if(!lpstrRes) return FALSE;
1466 iSize = lpstrRes - lpstrPath;
1468 while(SupportedProtocol[i])
1470 if (iSize == strlen(SupportedProtocol[i]))
1471 if(!strncasecmp(lpstrPath, SupportedProtocol[i], iSize));
1479 /*************************************************************************
1482 BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
1486 static WCHAR SupportedProtocol[7][7] =
1487 {{'h','t','t','p','\0'},{'h','t','t','p','s','\0'},{'f','t','p','\0'},
1488 {'g','o','p','h','e','r','\0'},{'f','i','l','e','\0'},
1489 {'m','a','i','l','t','o','\0'},{0}};
1491 if(!lpstrPath) return FALSE;
1494 lpstrRes = CRTDLL_wcschr(lpstrPath,':');
1495 if(!lpstrRes) return FALSE;
1496 iSize = lpstrRes - lpstrPath;
1498 while(SupportedProtocol[i])
1500 if (iSize == CRTDLL_wcslen(SupportedProtocol[i]))
1501 if(!CRTDLL__wcsnicmp(lpstrPath, SupportedProtocol[i], iSize));
1509 /*************************************************************************
1510 * IsLFNDriveA [SHELL32.119]
1513 * exported by ordinal Name
1515 BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath)
1519 if (!GetVolumeInformationA(lpszPath,NULL,0,NULL,&fnlen,NULL,NULL,0))
1525 Creating Something Unique
1527 /*************************************************************************
1528 * PathMakeUniqueNameA [internal]
1530 BOOL WINAPI PathMakeUniqueNameA(
1533 LPCSTR lpszShortName,
1534 LPCSTR lpszLongName,
1535 LPCSTR lpszPathName)
1537 FIXME("%p %lu %s %s %s stub\n",
1538 lpszBuffer, dwBuffSize, debugstr_a(lpszShortName),
1539 debugstr_a(lpszLongName), debugstr_a(lpszPathName));
1543 /*************************************************************************
1544 * PathMakeUniqueNameW [internal]
1546 BOOL WINAPI PathMakeUniqueNameW(
1549 LPCWSTR lpszShortName,
1550 LPCWSTR lpszLongName,
1551 LPCWSTR lpszPathName)
1553 FIXME("%p %lu %s %s %s stub\n",
1554 lpszBuffer, dwBuffSize, debugstr_w(lpszShortName),
1555 debugstr_w(lpszLongName), debugstr_w(lpszPathName));
1559 /*************************************************************************
1560 * PathMakeUniqueNameAW [SHELL32.47]
1562 BOOL WINAPI PathMakeUniqueNameAW(
1565 LPCVOID lpszShortName,
1566 LPCVOID lpszLongName,
1567 LPCVOID lpszPathName)
1569 if (VERSION_OsIsUnicode())
1570 return PathMakeUniqueNameW(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
1571 return PathMakeUniqueNameA(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
1574 /*************************************************************************
1575 * PathYetAnotherMakeUniqueNameA [SHELL32.75]
1578 * exported by ordinal
1580 BOOL WINAPI PathYetAnotherMakeUniqueNameA(
1582 LPCSTR lpszPathName,
1583 LPCSTR lpszShortName,
1584 LPCSTR lpszLongName)
1586 FIXME("(%p,%p, %p ,%p):stub.\n",
1587 lpszBuffer, lpszPathName, lpszShortName, lpszLongName);
1593 cleaning and resolving paths
1596 /*************************************************************************
1597 * PathFindOnPathA [SHELL32.145]
1599 BOOL WINAPI PathFindOnPathA(LPSTR sFile, LPCSTR sOtherDirs)
1601 FIXME("%s %s\n",sFile, sOtherDirs);
1605 /*************************************************************************
1606 * PathFindOnPathW [SHELL32]
1608 BOOL WINAPI PathFindOnPathW(LPWSTR sFile, LPCWSTR sOtherDirs)
1610 FIXME("%s %s\n",debugstr_w(sFile), debugstr_w(sOtherDirs));
1614 /*************************************************************************
1615 * PathFindOnPathAW [SHELL32]
1617 BOOL WINAPI PathFindOnPathAW(LPVOID sFile, LPCVOID sOtherDirs)
1619 if (VERSION_OsIsUnicode())
1620 return PathFindOnPathW(sFile, sOtherDirs);
1621 return PathFindOnPathA(sFile, sOtherDirs);
1624 /*************************************************************************
1625 * PathCleanupSpecA [SHELL32.171]
1627 DWORD WINAPI PathCleanupSpecA(LPSTR x, LPSTR y)
1629 FIXME("(%p %s, %p %s) stub\n",x,debugstr_a(x),y,debugstr_a(y));
1633 /*************************************************************************
1634 * PathCleanupSpecA [SHELL32]
1636 DWORD WINAPI PathCleanupSpecW(LPWSTR x, LPWSTR y)
1638 FIXME("(%p %s, %p %s) stub\n",x,debugstr_w(x),y,debugstr_w(y));
1642 /*************************************************************************
1643 * PathCleanupSpecAW [SHELL32]
1645 DWORD WINAPI PathCleanupSpecAW (LPVOID x, LPVOID y)
1647 if (VERSION_OsIsUnicode())
1648 return PathCleanupSpecW(x,y);
1649 return PathCleanupSpecA(x,y);
1652 /*************************************************************************
1653 * PathQualifyA [SHELL32]
1655 BOOL WINAPI PathQualifyA(LPCSTR pszPath)
1657 FIXME("%s\n",pszPath);
1661 /*************************************************************************
1662 * PathQualifyW [SHELL32]
1664 BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
1666 FIXME("%s\n",debugstr_w(pszPath));
1670 /*************************************************************************
1671 * PathQualifyAW [SHELL32]
1673 BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
1675 if (VERSION_OsIsUnicode())
1676 return PathQualifyW(pszPath);
1677 return PathQualifyA(pszPath);
1680 /*************************************************************************
1681 * PathResolveA [SHELL32.51]
1683 BOOL WINAPI PathResolveA(
1688 FIXME("(%s,%p,0x%08lx),stub!\n",
1689 lpszPath, *alpszPaths, dwFlags);
1693 /*************************************************************************
1694 * PathResolveW [SHELL32]
1696 BOOL WINAPI PathResolveW(
1698 LPCWSTR *alpszPaths,
1701 FIXME("(%s,%p,0x%08lx),stub!\n",
1702 debugstr_w(lpszPath), debugstr_w(*alpszPaths), dwFlags);
1706 /*************************************************************************
1707 * PathResolveAW [SHELL32]
1709 BOOL WINAPI PathResolveAW(
1711 LPCVOID *alpszPaths,
1714 if (VERSION_OsIsUnicode())
1715 return PathResolveW(lpszPath, (LPCWSTR*)alpszPaths, dwFlags);
1716 return PathResolveA(lpszPath, (LPCSTR*)alpszPaths, dwFlags);
1719 /*************************************************************************
1720 * PathProcessCommandA [SHELL32.653]
1722 HRESULT WINAPI PathProcessCommandA (
1728 FIXME("%s %p 0x%04lx 0x%04lx stub\n",
1729 lpszPath, lpszBuff, dwBuffSize, dwFlags);
1730 lstrcpyA(lpszBuff, lpszPath);
1734 /*************************************************************************
1735 * PathProcessCommandW
1737 HRESULT WINAPI PathProcessCommandW (
1743 FIXME("(%s, %p, 0x%04lx, 0x%04lx) stub\n",
1744 debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags);
1745 lstrcpyW(lpszBuff, lpszPath);
1749 /*************************************************************************
1750 * PathProcessCommandAW
1752 HRESULT WINAPI PathProcessCommandAW (
1758 if (VERSION_OsIsUnicode())
1759 return PathProcessCommandW(lpszPath, lpszBuff, dwBuffSize, dwFlags);
1760 return PathProcessCommandA(lpszPath, lpszBuff, dwBuffSize, dwFlags);
1767 /*************************************************************************
1768 * PathSetDlgItemPathA
1771 * use PathCompactPath to make sure, the path fits into the control
1773 BOOL WINAPI PathSetDlgItemPathA(HWND hDlg, int id, LPCSTR pszPath)
1774 { TRACE("%x %x %s\n",hDlg, id, pszPath);
1775 return SetDlgItemTextA(hDlg, id, pszPath);
1778 /*************************************************************************
1779 * PathSetDlgItemPathW
1781 BOOL WINAPI PathSetDlgItemPathW(HWND hDlg, int id, LPCWSTR pszPath)
1782 { TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
1783 return SetDlgItemTextW(hDlg, id, pszPath);
1786 /*************************************************************************
1787 * PathSetDlgItemPathAW
1789 BOOL WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
1790 { if (VERSION_OsIsUnicode())
1791 return PathSetDlgItemPathW(hDlg, id, pszPath);
1792 return PathSetDlgItemPathA(hDlg, id, pszPath);
1796 /*************************************************************************
1797 * SHGetSpecialFolderPathA [SHELL32.175]
1799 * converts csidl to path
1803 static char * szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
1804 static char * szSHUserFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
1806 BOOL WINAPI SHGetSpecialFolderPathA (
1812 CHAR szValueName[MAX_PATH], szDefaultPath[MAX_PATH];
1813 HKEY hRootKey, hKey;
1814 BOOL bRelative = TRUE;
1815 DWORD dwType, dwDisp, dwPathLen = MAX_PATH;
1817 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
1819 /* build default values */
1823 hRootKey = HKEY_CURRENT_USER;
1824 strcpy (szValueName, "AppData");
1825 strcpy (szDefaultPath, "AppData");
1829 hRootKey = HKEY_CURRENT_USER;
1830 strcpy (szValueName, "Cookies");
1831 strcpy(szDefaultPath, "Cookies");
1834 case CSIDL_DESKTOPDIRECTORY:
1835 hRootKey = HKEY_CURRENT_USER;
1836 strcpy(szValueName, "Desktop");
1837 strcpy(szDefaultPath, "Desktop");
1840 case CSIDL_COMMON_DESKTOPDIRECTORY:
1841 hRootKey = HKEY_LOCAL_MACHINE;
1842 strcpy(szValueName, "Common Desktop");
1843 strcpy(szDefaultPath, "Desktop");
1846 case CSIDL_FAVORITES:
1847 hRootKey = HKEY_CURRENT_USER;
1848 strcpy(szValueName, "Favorites");
1849 strcpy(szDefaultPath, "Favorites");
1853 hRootKey = HKEY_CURRENT_USER;
1854 strcpy(szValueName, "Fonts");
1855 strcpy(szDefaultPath, "Fonts");
1859 hRootKey = HKEY_CURRENT_USER;
1860 strcpy(szValueName, "History");
1861 strcpy(szDefaultPath, "History");
1865 hRootKey = HKEY_CURRENT_USER;
1866 strcpy(szValueName, "NetHood");
1867 strcpy(szDefaultPath, "NetHood");
1870 case CSIDL_INTERNET_CACHE:
1871 hRootKey = HKEY_CURRENT_USER;
1872 strcpy(szValueName, "Cache");
1873 strcpy(szDefaultPath, "Temporary Internet Files");
1876 case CSIDL_PERSONAL:
1877 hRootKey = HKEY_CURRENT_USER;
1878 strcpy(szValueName, "Personal");
1879 strcpy(szDefaultPath, "My Own Files");
1883 case CSIDL_PRINTHOOD:
1884 hRootKey = HKEY_CURRENT_USER;
1885 strcpy(szValueName, "PrintHood");
1886 strcpy(szDefaultPath, "PrintHood");
1889 case CSIDL_PROGRAMS:
1890 hRootKey = HKEY_CURRENT_USER;
1891 strcpy(szValueName, "Programs");
1892 strcpy(szDefaultPath, "StartMenu\\Programs");
1895 case CSIDL_COMMON_PROGRAMS:
1896 hRootKey = HKEY_LOCAL_MACHINE;
1897 strcpy(szValueName, "Common Programs");
1898 strcpy(szDefaultPath, "");
1902 hRootKey = HKEY_CURRENT_USER;
1903 strcpy(szValueName, "Recent");
1904 strcpy(szDefaultPath, "Recent");
1908 hRootKey = HKEY_CURRENT_USER;
1909 strcpy(szValueName, "SendTo");
1910 strcpy(szDefaultPath, "SendTo");
1913 case CSIDL_STARTMENU:
1914 hRootKey = HKEY_CURRENT_USER;
1915 strcpy(szValueName, "StartMenu");
1916 strcpy(szDefaultPath, "StartMenu");
1919 case CSIDL_COMMON_STARTMENU:
1920 hRootKey = HKEY_LOCAL_MACHINE;
1921 strcpy(szValueName, "Common StartMenu");
1922 strcpy(szDefaultPath, "StartMenu");
1926 hRootKey = HKEY_CURRENT_USER;
1927 strcpy(szValueName, "Startup");
1928 strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
1931 case CSIDL_COMMON_STARTUP:
1932 hRootKey = HKEY_LOCAL_MACHINE;
1933 strcpy(szValueName, "Common Startup");
1934 strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
1937 case CSIDL_TEMPLATES:
1938 hRootKey = HKEY_CURRENT_USER;
1939 strcpy(szValueName, "Templates");
1940 strcpy(szDefaultPath, "ShellNew");
1944 ERR("folder unknown or not allowed\n");
1948 /* user shell folders */
1949 if (RegCreateKeyExA(hRootKey,szSHUserFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1951 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1956 if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1958 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1961 /* value not existing */
1964 GetWindowsDirectoryA(szPath, MAX_PATH);
1965 PathAddBackslashA(szPath);
1966 strcat(szPath, szDefaultPath);
1970 strcpy(szPath, "C:\\"); /* fixme ??? */
1971 strcat(szPath, szDefaultPath);
1973 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
1978 if (bCreate && CreateDirectoryA(szPath,NULL))
1980 MESSAGE("Created not existing system directory '%s'\n", szPath);
1986 /*************************************************************************
1987 * SHGetSpecialFolderPathW
1989 BOOL WINAPI SHGetSpecialFolderPathW (
1995 char szTemp[MAX_PATH];
1997 if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate))
1999 lstrcpynAtoW(szPath, szTemp, MAX_PATH);
2002 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
2007 /*************************************************************************
2008 * SHGetSpecialFolderPathAW
2010 BOOL WINAPI SHGetSpecialFolderPathAW (
2017 if (VERSION_OsIsUnicode())
2018 return SHGetSpecialFolderPathW (hwndOwner, szPath, csidl, bCreate);
2019 return SHGetSpecialFolderPathA (hwndOwner, szPath, csidl, bCreate);
2022 /*************************************************************************
2029 BOOL WINAPI PathCanonicalizeA(LPSTR pszBuf, LPCSTR pszPath)
2031 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = strlen(pszPath);
2032 BOOL bModifyed = FALSE;
2034 TRACE("%p %s\n", pszBuf, pszPath);
2036 pszBuf[OffsetDst]='\0';
2038 /* keep the root of the path */
2039 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
2041 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2043 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
2045 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2046 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2047 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
2049 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2050 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
2053 OffsetSrc++; LenSrc--; bModifyed = TRUE;
2055 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
2058 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
2063 /* ".\" at the beginning of the path */
2064 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
2066 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
2071 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
2073 /* "\.." found, go one deeper */
2074 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
2075 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
2076 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
2077 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
2079 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
2081 /* "\." found, skip it */
2082 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
2086 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
2089 pszBuf[OffsetDst] = '\0';
2090 TRACE("-- %s %u\n", pszBuf, bModifyed);
2095 /*************************************************************************
2101 BOOL WINAPI PathCanonicalizeW(LPWSTR pszBuf, LPCWSTR pszPath)
2103 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = lstrlenW(pszPath);
2104 BOOL bModifyed = FALSE;
2106 TRACE("%p %s\n", pszBuf, debugstr_w(pszPath));
2108 pszBuf[OffsetDst]='\0';
2110 /* keep the root of the path */
2111 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
2113 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2115 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
2117 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2118 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2119 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
2121 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2122 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
2125 OffsetSrc++; LenSrc--; bModifyed = TRUE;
2127 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
2130 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
2135 /* ".\" at the beginning of the path */
2136 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
2138 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
2143 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
2145 /* "\.." found, go one deeper */
2146 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
2147 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
2148 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
2149 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
2151 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
2153 /* "\." found, skip it */
2154 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
2158 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
2161 pszBuf[OffsetDst] = '\0';
2162 TRACE("-- %s %u\n", debugstr_w(pszBuf), bModifyed);
2166 /*************************************************************************
2167 * PathFindNextComponentA
2169 LPSTR WINAPI PathFindNextComponentA(LPCSTR pszPath)
2173 if(*pszPath++=='\\')
2174 return (LPSTR)((*pszPath)? pszPath : NULL);
2179 /*************************************************************************
2180 * PathFindNextComponentW
2182 LPWSTR WINAPI PathFindNextComponentW(LPCWSTR pszPath)
2186 if(*pszPath++=='\\')
2187 return (LPWSTR)((*pszPath)? pszPath : NULL);