4 * Many of this functions are in SHLWAPI.DLL also
9 #include "debugtools.h"
11 #include "winversion.h"
15 #include "shell32_main.h"
18 #include "wine/undocshell.h"
19 #include "wine/unicode.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
79 LPSTR WINAPI PathCombineA(
85 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, lpszDir, lpszFile, lpszFile);
88 if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
90 strcpy(szDest,lpszDir);
94 /* if lpszFile is a complete path don't care about lpszDir */
95 if (PathGetDriveNumberA(lpszFile) != -1)
97 strcpy(szDest,lpszFile);
99 else if (lpszFile[0] == '\\' )
101 strcpy(sTemp,lpszDir);
102 PathStripToRootA(sTemp);
103 strcat(sTemp,lpszFile);
104 strcpy(szDest,sTemp);
108 strcpy(sTemp,lpszDir);
109 PathAddBackslashA(sTemp);
110 strcat(sTemp,lpszFile);
111 strcpy(szDest,sTemp);
116 /*************************************************************************
117 * PathCombineW [SHLWAPI.@]
119 LPWSTR WINAPI PathCombineW(
124 WCHAR sTemp[MAX_PATH];
125 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, debugstr_w(lpszDir),
126 lpszFile, debugstr_w(lpszFile));
129 if (!lpszFile || !lpszFile[0] || (lpszFile[0]==(WCHAR)'.' && !lpszFile[1]) )
131 strcpyW(szDest,lpszDir);
135 /* if lpszFile is a complete path don't care about lpszDir */
136 if (PathGetDriveNumberW(lpszFile) != -1)
138 strcpyW(szDest,lpszFile);
140 else if (lpszFile[0] == (WCHAR)'\\' )
142 strcpyW(sTemp,lpszDir);
143 PathStripToRootW(sTemp);
144 strcatW(sTemp,lpszFile);
145 strcpyW(szDest,sTemp);
149 strcpyW(sTemp,lpszDir);
150 PathAddBackslashW(sTemp);
151 strcatW(sTemp,lpszFile);
152 strcpyW(szDest,sTemp);
157 /*************************************************************************
158 * PathCombineAW [SHELL32.37]
160 LPVOID WINAPI PathCombineAW(
165 if (VERSION_OsIsUnicode())
166 return PathCombineW( szDest, lpszDir, lpszFile );
167 return PathCombineA( szDest, lpszDir, lpszFile );
170 /*************************************************************************
171 * PathAddBackslashA [SHLWAPI.@]
174 * append \ if there is none
176 LPSTR WINAPI PathAddBackslashA(LPSTR lpszPath)
179 TRACE("%p->%s\n",lpszPath,lpszPath);
181 len = strlen(lpszPath);
182 if (len && lpszPath[len-1]!='\\')
184 lpszPath[len] = '\\';
185 lpszPath[len+1]= 0x00;
186 return lpszPath+len+1;
191 /*************************************************************************
192 * PathAddBackslashW [SHLWAPI.@]
194 LPWSTR WINAPI PathAddBackslashW(LPWSTR lpszPath)
197 TRACE("%p->%s\n",lpszPath,debugstr_w(lpszPath));
199 len = strlenW(lpszPath);
200 if (len && lpszPath[len-1]!=(WCHAR)'\\')
202 lpszPath[len] = (WCHAR)'\\';
203 lpszPath[len+1]= 0x00;
204 return lpszPath+len+1;
209 /*************************************************************************
210 * PathAddBackslashAW [SHELL32.32]
212 LPVOID WINAPI PathAddBackslashAW(LPVOID lpszPath)
214 if(VERSION_OsIsUnicode())
215 return PathAddBackslashW(lpszPath);
216 return PathAddBackslashA(lpszPath);
219 /*************************************************************************
220 * PathBuildRootA [SHLWAPI.@]
222 LPSTR WINAPI PathBuildRootA(LPSTR lpszPath, int drive)
224 TRACE("%p %i\n",lpszPath, drive);
226 strcpy(lpszPath,"A:\\");
231 /*************************************************************************
232 * PathBuildRootW [SHLWAPI.@]
234 LPWSTR WINAPI PathBuildRootW(LPWSTR lpszPath, int drive)
236 TRACE("%p %i\n",debugstr_w(lpszPath), drive);
238 lstrcpyAtoW(lpszPath,"A:\\");
243 /*************************************************************************
244 * PathBuildRootAW [SHELL32.30]
246 LPVOID WINAPI PathBuildRootAW(LPVOID lpszPath, int drive)
248 if(VERSION_OsIsUnicode())
249 return PathBuildRootW(lpszPath, drive);
250 return PathBuildRootA(lpszPath, drive);
254 Extracting Component Parts
257 /*************************************************************************
258 * PathFindFileNameA [SHLWAPI.@]
260 LPSTR WINAPI PathFindFileNameA(LPCSTR lpszPath)
265 TRACE("%s\n",aslash);
268 if (((lpszPath[0]=='\\') || (lpszPath[0]==':')) && lpszPath[1] && lpszPath[1]!='\\')
272 return (LPSTR)aslash;
276 /*************************************************************************
277 * PathFindFileNameW [SHLWAPI.@]
279 LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
284 TRACE("%s\n",debugstr_w(wslash));
287 if (((lpszPath[0]=='\\') || (lpszPath[0]==':')) && lpszPath[1] && lpszPath[1]!='\\')
291 return (LPWSTR)wslash;
294 /*************************************************************************
295 * PathFindFileNameAW [SHELL32.34]
297 LPVOID WINAPI PathFindFileNameAW(LPCVOID lpszPath)
299 if(VERSION_OsIsUnicode())
300 return PathFindFileNameW(lpszPath);
301 return PathFindFileNameA(lpszPath);
304 /*************************************************************************
305 * PathFindExtensionA [SHLWAPI.@]
308 * returns pointer to last . in last lpszPath component or at \0.
311 LPSTR WINAPI PathFindExtensionA(LPCSTR lpszPath)
313 LPCSTR lastpoint = NULL;
315 TRACE("%p %s\n",lpszPath,lpszPath);
319 if (*lpszPath=='\\'||*lpszPath==' ')
325 return (LPSTR)(lastpoint?lastpoint:lpszPath);
328 /*************************************************************************
329 * PathFindExtensionW [SHLWAPI.@]
331 LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
333 LPCWSTR lastpoint = NULL;
335 TRACE("(%p %s)\n",lpszPath,debugstr_w(lpszPath));
339 if (*lpszPath==(WCHAR)'\\'||*lpszPath==(WCHAR)' ')
341 if (*lpszPath==(WCHAR)'.')
345 return (LPWSTR)(lastpoint?lastpoint:lpszPath);
348 /*************************************************************************
349 * PathFindExtensionAW [SHELL32.31]
351 LPVOID WINAPI PathFindExtensionAW(LPCVOID lpszPath)
353 if (VERSION_OsIsUnicode())
354 return PathFindExtensionW(lpszPath);
355 return PathFindExtensionA(lpszPath);
359 /*************************************************************************
360 * PathGetExtensionA [internal]
363 * exported by ordinal
364 * return value points to the first char after the dot
366 LPSTR WINAPI PathGetExtensionA(LPCSTR lpszPath)
368 TRACE("(%s)\n",lpszPath);
370 lpszPath = PathFindExtensionA(lpszPath);
371 return (LPSTR)(*lpszPath?(lpszPath+1):lpszPath);
374 /*************************************************************************
375 * PathGetExtensionW [internal]
377 LPWSTR WINAPI PathGetExtensionW(LPCWSTR lpszPath)
379 TRACE("(%s)\n",debugstr_w(lpszPath));
381 lpszPath = PathFindExtensionW(lpszPath);
382 return (LPWSTR)(*lpszPath?(lpszPath+1):lpszPath);
385 /*************************************************************************
386 * PathGetExtensionAW [SHELL32.158]
388 LPVOID WINAPI PathGetExtensionAW(LPCVOID lpszPath)
390 if (VERSION_OsIsUnicode())
391 return PathGetExtensionW(lpszPath);
392 return PathGetExtensionA(lpszPath);
395 /*************************************************************************
396 * PathGetArgsA [SHLWAPI.@]
399 * look for next arg in string. handle "quoted" strings
400 * returns pointer to argument *AFTER* the space. Or to the \0.
405 LPSTR WINAPI PathGetArgsA(LPCSTR lpszPath)
409 TRACE("%s\n",lpszPath);
413 if ((*lpszPath==' ') && !qflag)
414 return (LPSTR)lpszPath+1;
419 return (LPSTR)lpszPath;
422 /*************************************************************************
423 * PathGetArgsW [SHLWAPI.@]
425 LPWSTR WINAPI PathGetArgsW(LPCWSTR lpszPath)
429 TRACE("%s\n",debugstr_w(lpszPath));
433 if ((*lpszPath==' ') && !qflag)
434 return (LPWSTR)lpszPath+1;
439 return (LPWSTR)lpszPath;
442 /*************************************************************************
443 * PathGetArgsAW [SHELL32.52]
445 LPVOID WINAPI PathGetArgsAW(LPVOID lpszPath)
447 if (VERSION_OsIsUnicode())
448 return PathGetArgsW(lpszPath);
449 return PathGetArgsA(lpszPath);
452 /*************************************************************************
453 * PathGetDriveNumberA [SHLWAPI.@]
455 int WINAPI PathGetDriveNumberA(LPCSTR lpszPath)
457 int chr = tolower(lpszPath[0]);
459 TRACE ("%s\n",debugstr_a(lpszPath));
461 if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
462 return tolower(lpszPath[0]) - 'a' ;
465 /*************************************************************************
466 * PathGetDriveNumberW [SHLWAPI.@]
468 int WINAPI PathGetDriveNumberW(LPCWSTR lpszPath)
470 int chr = tolowerW(lpszPath[0]);
472 TRACE ("%s\n",debugstr_w(lpszPath));
474 if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
475 return tolowerW(lpszPath[0]) - 'a' ;
478 /*************************************************************************
479 * PathGetDriveNumber [SHELL32.57]
481 int WINAPI PathGetDriveNumberAW(LPVOID lpszPath)
483 if (VERSION_OsIsUnicode())
484 return PathGetDriveNumberW(lpszPath);
485 return PathGetDriveNumberA(lpszPath);
488 /*************************************************************************
489 * PathRemoveFileSpecA [SHLWAPI.@]
492 * truncates passed argument to a valid path
493 * returns if the string was modified or not.
494 * "\foo\xx\foo"-> "\foo\xx"
498 BOOL WINAPI PathRemoveFileSpecA(LPSTR lpszPath)
502 TRACE("%s\n",lpszPath);
504 if (!lpszPath[0]) return 0;
506 cutplace = PathFindFileNameA(lpszPath);
510 if (PathIsRootA(lpszPath))
512 PathAddBackslashA(lpszPath);
516 PathRemoveBackslashA(lpszPath);
523 /*************************************************************************
524 * PathRemoveFileSpecW [SHLWAPI.@]
526 BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
530 TRACE("%s\n",debugstr_w(lpszPath));
532 if (!lpszPath[0]) return 0;
533 cutplace = PathFindFileNameW(lpszPath);
537 if (PathIsRootW(lpszPath))
539 PathAddBackslashW(lpszPath);
543 PathRemoveBackslashW(lpszPath);
550 /*************************************************************************
551 * PathRemoveFileSpec [SHELL32.35]
553 BOOL WINAPI PathRemoveFileSpecAW(LPVOID lpszPath)
555 if (VERSION_OsIsUnicode())
556 return PathRemoveFileSpecW(lpszPath);
557 return PathRemoveFileSpecA(lpszPath);
560 /*************************************************************************
561 * PathStripPathA [SHELLWAPI.@]
564 * removes the path from the beginning of a filename
566 void WINAPI PathStripPathA(LPSTR lpszPath)
568 LPSTR lpszFileName = PathFindFileNameA(lpszPath);
570 TRACE("%s\n", lpszPath);
573 RtlMoveMemory(lpszPath, lpszFileName, strlen(lpszFileName)+1);
576 /*************************************************************************
577 * PathStripPathW [SHELLWAPI.@]
579 void WINAPI PathStripPathW(LPWSTR lpszPath)
581 LPWSTR lpszFileName = PathFindFileNameW(lpszPath);
583 TRACE("%s\n", debugstr_w(lpszPath));
585 RtlMoveMemory(lpszPath, lpszFileName, (lstrlenW(lpszFileName)+1)*sizeof(WCHAR));
588 /*************************************************************************
589 * PathStripPathAW [SHELL32.38]
591 void WINAPI PathStripPathAW(LPVOID lpszPath)
593 if (VERSION_OsIsUnicode())
594 return PathStripPathW(lpszPath);
595 return PathStripPathA(lpszPath);
598 /*************************************************************************
599 * PathStripToRootA [SHLWAPI.@]
601 BOOL WINAPI PathStripToRootA(LPSTR lpszPath)
603 TRACE("%s\n", lpszPath);
606 if (lpszPath[1]==':' )
608 if(lpszPath[2]=='\\')
617 /* UNC "\\<computer>\<share>" FIXME: not complete*/
618 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
620 int foundbackslash = 0;
624 if (*lpszPath=='\\') foundbackslash++;
625 if (foundbackslash==2)
635 if (lpszPath[0]=='\\')
645 /*************************************************************************
646 * PathStripToRootW [SHLWAPI.@]
648 BOOL WINAPI PathStripToRootW(LPWSTR lpszPath)
650 TRACE("%s\n", debugstr_w(lpszPath));
653 if (lpszPath[1]==':' )
655 if(lpszPath[2]=='\\')
665 /* UNC "\\<computer>\<share>" */
666 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
668 int foundbackslash = 0;
672 if (*lpszPath=='\\') foundbackslash++;
673 if (foundbackslash==2)
683 if (lpszPath[0]=='\\')
689 lpszPath[0]=(WCHAR)'\0';
693 /*************************************************************************
694 * PathStripToRootAW [SHELL32.50]
696 BOOL WINAPI PathStripToRootAW(LPVOID lpszPath)
698 if (VERSION_OsIsUnicode())
699 return PathStripToRootW(lpszPath);
700 return PathStripToRootA(lpszPath);
703 /*************************************************************************
704 * PathRemoveArgsA [SHLWAPI.@]
707 * returns pointer to last character, not void
709 LPSTR WINAPI PathRemoveArgsA(LPSTR lpszPath)
712 LPSTR pPos = lpszPath;
714 TRACE("%s\n",lpszPath);
718 if (!qflag && *lpszPath==' ') break;
719 if (*lpszPath=='"') qflag=!qflag;
721 if (*lpszPath) pPos++;
727 /*************************************************************************
728 * PathRemoveArgsW [SHLWAPI.@]
730 LPWSTR WINAPI PathRemoveArgsW(LPWSTR lpszPath)
733 LPWSTR pPos = lpszPath;
736 TRACE("%s\n", debugstr_w(lpszPath));
740 if (!qflag && *lpszPath==(WCHAR)' ') break;
741 if (*lpszPath==(WCHAR)'"') qflag=!qflag;
743 if (*lpszPath) pPos++;
745 *lpszPath = (WCHAR)'\0';
749 /*************************************************************************
750 * PathRemoveArgsAW [SHELL32.251]
752 LPVOID WINAPI PathRemoveArgsAW(LPVOID lpszPath)
754 if (VERSION_OsIsUnicode())
755 return PathRemoveArgsW(lpszPath);
756 return PathRemoveArgsA(lpszPath);
759 /*************************************************************************
760 * PathRemoveExtensionA [SHLWAPI.@]
762 void WINAPI PathRemoveExtensionA(LPSTR lpszPath)
764 LPSTR lpszExtension = PathFindExtensionA(lpszPath);
766 TRACE("%s\n", lpszPath);
768 if (lpszExtension) *lpszExtension='\0';
771 /*************************************************************************
772 * PathRemoveExtensionW [SHLWAPI.@]
774 void WINAPI PathRemoveExtensionW(LPWSTR lpszPath)
776 LPWSTR lpszExtension = PathFindExtensionW(lpszPath);
778 TRACE("%s\n", debugstr_w(lpszPath));
780 if (lpszExtension) *lpszExtension='\0';
783 /*************************************************************************
784 * PathRemoveExtensionAW [SHELL32.250]
786 void WINAPI PathRemoveExtensionAW(LPVOID lpszPath)
788 if (VERSION_OsIsUnicode())
789 return PathRemoveExtensionW(lpszPath);
790 return PathRemoveExtensionA(lpszPath);
793 /*************************************************************************
794 * PathRemoveBackslashA [SHLWAPI.@]
796 * If the path ends in a backslash it is replaced by a NULL
797 * and the address of the NULL is returned
799 * the address of the last character is returned.
802 * "c:\": keep backslash
804 LPSTR WINAPI PathRemoveBackslashA( LPSTR lpszPath )
808 while (*lpszPath) p = lpszPath++;
809 if ( *p == (CHAR)'\\') *p = (CHAR)'\0';
813 /*************************************************************************
814 * PathRemoveBackslashW [SHLWAPI.@]
816 LPWSTR WINAPI PathRemoveBackslashW( LPWSTR lpszPath )
820 while (*lpszPath) p = lpszPath++;
821 if ( *p == (WCHAR)'\\') *p = (WCHAR)'\0';
829 /*************************************************************************
830 * PathGetShortPathA [internal]
832 LPSTR WINAPI PathGetShortPathA(LPSTR lpszPath)
834 FIXME("%s stub\n", lpszPath);
838 /*************************************************************************
839 * PathGetShortPathW [internal]
841 LPWSTR WINAPI PathGetShortPathW(LPWSTR lpszPath)
843 FIXME("%s stub\n", debugstr_w(lpszPath));
847 /*************************************************************************
848 * PathGetShortPathAW [SHELL32.92]
850 LPVOID WINAPI PathGetShortPathAW(LPVOID lpszPath)
852 if(VERSION_OsIsUnicode())
853 return PathGetShortPathW(lpszPath);
854 return PathGetShortPathA(lpszPath);
857 /*************************************************************************
858 * PathRemoveBlanksA [SHLWAPI.@]
861 * remove spaces from beginning and end of passed string
863 LPSTR WINAPI PathRemoveBlanksA(LPSTR str)
882 /*************************************************************************
883 * PathRemoveBlanksW [SHLWAPI.@]
885 LPWSTR WINAPI PathRemoveBlanksW(LPWSTR str)
889 TRACE("%s\n",debugstr_w(str));
896 x=str+strlenW(str)-1;
904 /*************************************************************************
905 * PathRemoveBlanksAW [SHELL32.33]
907 LPVOID WINAPI PathRemoveBlanksAW(LPVOID str)
909 if(VERSION_OsIsUnicode())
910 return PathRemoveBlanksW(str);
911 return PathRemoveBlanksA(str);
914 /*************************************************************************
915 * PathQuoteSpacesA [SHLWAPI.@]
918 LPSTR WINAPI PathQuoteSpacesA(LPSTR lpszPath)
920 TRACE("%s\n",lpszPath);
922 if(StrChrA(lpszPath,' '))
924 int len = strlen(lpszPath);
925 RtlMoveMemory(lpszPath+1, lpszPath, len);
935 /*************************************************************************
936 * PathQuoteSpacesW [SHLWAPI.@]
938 LPWSTR WINAPI PathQuoteSpacesW(LPWSTR lpszPath)
940 TRACE("%s\n",debugstr_w(lpszPath));
942 if(StrChrW(lpszPath,' '))
944 int len = lstrlenW(lpszPath);
945 RtlMoveMemory(lpszPath+1, lpszPath, len*sizeof(WCHAR));
955 /*************************************************************************
956 * PathQuoteSpacesAW [SHELL32.55]
958 LPVOID WINAPI PathQuoteSpacesAW (LPVOID lpszPath)
960 if(VERSION_OsIsUnicode())
961 return PathQuoteSpacesW(lpszPath);
962 return PathQuoteSpacesA(lpszPath);
965 /*************************************************************************
966 * PathUnquoteSpacesA [SHLWAPI.@]
969 * unquote string (remove ")
971 VOID WINAPI PathUnquoteSpacesA(LPSTR str)
973 DWORD len = lstrlenA(str);
986 /*************************************************************************
987 * PathUnquoteSpacesW [SHLWAPI.@]
989 VOID WINAPI PathUnquoteSpacesW(LPWSTR str)
991 DWORD len = strlenW(str);
993 TRACE("%s\n",debugstr_w(str));
1004 /*************************************************************************
1005 * PathUnquoteSpacesAW [SHELL32.56]
1007 VOID WINAPI PathUnquoteSpacesAW(LPVOID str)
1009 if(VERSION_OsIsUnicode())
1010 PathUnquoteSpacesW(str);
1012 PathUnquoteSpacesA(str);
1015 /*************************************************************************
1016 * PathParseIconLocationA [SHLWAPI.@]
1018 int WINAPI PathParseIconLocationA(LPSTR lpszPath)
1020 LPSTR lpstrComma = strchr(lpszPath, ',');
1022 FIXME("%s stub\n", debugstr_a(lpszPath));
1024 if (lpstrComma && lpstrComma[1])
1027 /* return atoi(&lpstrComma[1]); FIXME */
1030 PathUnquoteSpacesA(lpszPath);
1034 /*************************************************************************
1035 * PathParseIconLocationW [SHLWAPI.@]
1037 int WINAPI PathParseIconLocationW(LPWSTR lpszPath)
1039 LPWSTR lpstrComma = strchrW(lpszPath, ',');
1041 FIXME("%s stub\n", debugstr_w(lpszPath));
1043 if (lpstrComma && lpstrComma[1])
1046 /* return _wtoi(&lpstrComma[1]); FIXME */
1048 PathUnquoteSpacesW(lpszPath);
1052 /*************************************************************************
1053 * PathParseIconLocationAW [SHELL32.249]
1055 int WINAPI PathParseIconLocationAW (LPVOID lpszPath)
1057 if(VERSION_OsIsUnicode())
1058 return PathParseIconLocationW(lpszPath);
1059 return PathParseIconLocationA(lpszPath);
1065 /*************************************************************************
1066 * PathIsUNCA [SHLWAPI.@]
1069 * PathIsUNC(char*path);
1071 BOOL WINAPI PathIsUNCA(LPCSTR lpszPath)
1073 TRACE("%s\n",lpszPath);
1075 return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
1078 /*************************************************************************
1079 * PathIsUNCW [SHLWAPI.@]
1081 BOOL WINAPI PathIsUNCW(LPCWSTR lpszPath)
1083 TRACE("%s\n",debugstr_w(lpszPath));
1085 return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
1088 /*************************************************************************
1089 * PathIsUNCAW [SHELL32.39]
1091 BOOL WINAPI PathIsUNCAW (LPCVOID lpszPath)
1093 if (VERSION_OsIsUnicode())
1094 return PathIsUNCW( lpszPath );
1095 return PathIsUNCA( lpszPath );
1098 /*************************************************************************
1099 * PathIsRelativeA [SHLWAPI.@]
1101 BOOL WINAPI PathIsRelativeA (LPCSTR lpszPath)
1103 TRACE("lpszPath=%s\n",lpszPath);
1105 return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
1108 /*************************************************************************
1109 * PathIsRelativeW [SHLWAPI.@]
1111 BOOL WINAPI PathIsRelativeW (LPCWSTR lpszPath)
1113 TRACE("lpszPath=%s\n",debugstr_w(lpszPath));
1115 return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
1118 /*************************************************************************
1119 * PathIsRelativeAW [SHELL32.40]
1121 BOOL WINAPI PathIsRelativeAW (LPCVOID lpszPath)
1123 if (VERSION_OsIsUnicode())
1124 return PathIsRelativeW( lpszPath );
1125 return PathIsRelativeA( lpszPath );
1128 /*************************************************************************
1129 * PathIsRootA [SHLWAPI.@]
1132 * TRUE if the path points to a root directory
1134 BOOL WINAPI PathIsRootA(LPCSTR lpszPath)
1136 TRACE("%s\n",lpszPath);
1139 if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
1143 if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
1146 /* UNC "\\<computer>\<share>" */
1147 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
1149 int foundbackslash = 0;
1153 if (*(lpszPath++)=='\\') foundbackslash++;
1155 if (foundbackslash <= 1)
1161 /*************************************************************************
1162 * PathIsRootW [SHLWAPI.@]
1164 BOOL WINAPI PathIsRootW(LPCWSTR lpszPath)
1166 TRACE("%s\n",debugstr_w(lpszPath));
1169 if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
1173 if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
1176 /* UNC "\\<computer>\<share>" */
1177 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
1179 int foundbackslash = 0;
1183 if (*(lpszPath++)=='\\') foundbackslash++;
1185 if (foundbackslash <= 1)
1192 /*************************************************************************
1193 * PathIsRootAW [SHELL32.29]
1195 BOOL WINAPI PathIsRootAW(LPCVOID lpszPath)
1197 if (VERSION_OsIsUnicode())
1198 return PathIsRootW(lpszPath);
1199 return PathIsRootA(lpszPath);
1202 /*************************************************************************
1203 * PathIsExeA [internal]
1205 BOOL WINAPI PathIsExeA (LPCSTR lpszPath)
1207 LPCSTR lpszExtension = PathGetExtensionA(lpszPath);
1209 static char * lpszExtensions[6] = {"exe", "com", "pid", "cmd", "bat", NULL };
1211 TRACE("path=%s\n",lpszPath);
1213 for(i=0; lpszExtensions[i]; i++)
1214 if (!strcasecmp(lpszExtension,lpszExtensions[i])) return TRUE;
1219 /*************************************************************************
1220 * PathIsExeW [internal]
1222 BOOL WINAPI PathIsExeW (LPCWSTR lpszPath)
1224 LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
1226 static WCHAR lpszExtensions[6][4] =
1227 {{'e','x','e','\0'}, {'c','o','m','\0'}, {'p','i','d','\0'},
1228 {'c','m','d','\0'}, {'b','a','t','\0'}, {'\0'} };
1230 TRACE("path=%s\n",debugstr_w(lpszPath));
1232 for(i=0; lpszExtensions[i]; i++)
1233 if (!strcmpiW(lpszExtension,lpszExtensions[i])) return TRUE;
1238 /*************************************************************************
1239 * PathIsExeAW [SHELL32.43]
1241 BOOL WINAPI PathIsExeAW (LPCVOID path)
1243 if (VERSION_OsIsUnicode())
1244 return PathIsExeW (path);
1245 return PathIsExeA(path);
1248 /*************************************************************************
1249 * PathIsDirectoryA [SHLWAPI.@]
1251 BOOL WINAPI PathIsDirectoryA(LPCSTR lpszPath)
1254 WIN32_FIND_DATAA stffile;
1256 TRACE("%s\n", debugstr_a(lpszPath));
1258 hFile = FindFirstFileA(lpszPath, &stffile);
1260 if ( hFile != INVALID_HANDLE_VALUE )
1263 return (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
1269 /*************************************************************************
1270 * PathIsDirectoryW [SHLWAPI.@]
1272 BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
1275 WIN32_FIND_DATAW stffile;
1277 TRACE("%s\n", debugstr_w(lpszPath));
1279 hFile = FindFirstFileW(lpszPath, &stffile);
1281 if ( hFile != INVALID_HANDLE_VALUE )
1284 return (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
1290 /*************************************************************************
1291 * PathIsDirectoryAW [SHELL32.159]
1293 BOOL WINAPI PathIsDirectoryAW (LPCVOID lpszPath)
1295 if (VERSION_OsIsUnicode())
1296 return PathIsDirectoryW (lpszPath);
1297 return PathIsDirectoryA (lpszPath);
1300 /*************************************************************************
1301 * PathFileExistsA [SHLWAPI.@]
1304 * file_exists(char *fn);
1306 BOOL WINAPI PathFileExistsA(LPCSTR lpszPath)
1308 TRACE("%s\n",lpszPath);
1309 return (GetFileAttributesA(lpszPath)!=-1);
1312 /*************************************************************************
1313 * PathFileExistsW [SHLWAPI.@]
1315 BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
1317 TRACE("%s\n",debugstr_w(lpszPath));
1318 return (GetFileAttributesW(lpszPath)!=-1);
1321 /*************************************************************************
1322 * PathFileExistsAW [SHELL32.45]
1324 BOOL WINAPI PathFileExistsAW (LPCVOID lpszPath)
1326 if (VERSION_OsIsUnicode())
1327 return PathFileExistsW (lpszPath);
1328 return PathFileExistsA (lpszPath);
1331 /*************************************************************************
1332 * PathMatchSingleMaskA [internal]
1335 * internal (used by PathMatchSpec)
1337 static BOOL PathMatchSingleMaskA(LPCSTR name, LPCSTR mask)
1339 while (*name && *mask && *mask!=';')
1345 if (PathMatchSingleMaskA(name,mask+1)) return 1; /* try substrings */
1349 if (toupper(*mask)!=toupper(*name) && *mask!='?') return 0;
1355 while (*mask=='*') mask++;
1356 if (!*mask || *mask==';') return 1;
1361 /*************************************************************************
1362 * PathMatchSingleMaskW [internal]
1364 static BOOL PathMatchSingleMaskW(LPCWSTR name, LPCWSTR mask)
1366 while (*name && *mask && *mask!=';')
1372 if (PathMatchSingleMaskW(name,mask+1)) return 1; /* try substrings */
1376 if (toupperW(*mask)!=toupperW(*name) && *mask!='?') return 0;
1382 while (*mask=='*') mask++;
1383 if (!*mask || *mask==';') return 1;
1387 /*************************************************************************
1388 * PathMatchSpecA [SHLWAPI.@]
1391 * used from COMDLG32
1393 BOOL WINAPI PathMatchSpecA(LPCSTR name, LPCSTR mask)
1395 TRACE("%s %s\n",name,mask);
1397 if (!lstrcmpA( mask, "*.*" )) return 1; /* we don't require a period */
1401 if (PathMatchSingleMaskA(name,mask)) return 1; /* helper function */
1402 while (*mask && *mask!=';') mask++;
1406 while (*mask==' ') mask++; /* masks may be separated by "; " */
1412 /*************************************************************************
1413 * PathMatchSpecW [SHLWAPI.@]
1415 BOOL WINAPI PathMatchSpecW(LPCWSTR name, LPCWSTR mask)
1418 TRACE("%s %s\n",debugstr_w(name),debugstr_w(mask));
1420 lstrcpyAtoW(stemp,"*.*");
1421 if (!lstrcmpW( mask, stemp )) return 1; /* we don't require a period */
1425 if (PathMatchSingleMaskW(name,mask)) return 1; /* helper function */
1426 while (*mask && *mask!=';') mask++;
1430 while (*mask==' ') mask++; /* masks may be separated by "; " */
1436 /*************************************************************************
1437 * PathMatchSpecAW [SHELL32.46]
1439 BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
1441 if (VERSION_OsIsUnicode())
1442 return PathMatchSpecW( name, mask );
1443 return PathMatchSpecA( name, mask );
1446 /*************************************************************************
1447 * PathIsSameRootA [SHLWAPI.@]
1450 * what to do with "\path" ??
1452 BOOL WINAPI PathIsSameRootA(LPCSTR lpszPath1, LPCSTR lpszPath2)
1454 TRACE("%s %s\n", lpszPath1, lpszPath2);
1456 if (PathIsRelativeA(lpszPath1) || PathIsRelativeA(lpszPath2)) return FALSE;
1459 if ( toupper(lpszPath1[0])==toupper(lpszPath2[0]) &&
1460 lpszPath1[1]==':' && lpszPath2[1]==':' &&
1461 lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
1465 if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
1466 lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
1468 int pos=2, bsfound=0;
1469 while (lpszPath1[pos] && lpszPath2[pos] &&
1470 (lpszPath1[pos] == lpszPath2[pos]))
1472 if (lpszPath1[pos]=='\\') bsfound++;
1473 if (bsfound == 2) return TRUE;
1476 return (lpszPath1[pos] == lpszPath2[pos]);
1481 /*************************************************************************
1482 * PathIsSameRootW [SHLWAPI.@]
1484 BOOL WINAPI PathIsSameRootW(LPCWSTR lpszPath1, LPCWSTR lpszPath2)
1486 TRACE("%s %s\n", debugstr_w(lpszPath1), debugstr_w(lpszPath2));
1488 if (PathIsRelativeW(lpszPath1) || PathIsRelativeW(lpszPath2)) return FALSE;
1491 if ( toupperW(lpszPath1[0])==toupperW(lpszPath2[0]) &&
1492 lpszPath1[1]==':' && lpszPath2[1]==':' &&
1493 lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
1497 if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
1498 lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
1500 int pos=2, bsfound=0;
1501 while (lpszPath1[pos] && lpszPath2[pos] &&
1502 (lpszPath1[pos] == lpszPath2[pos]))
1504 if (lpszPath1[pos]=='\\') bsfound++;
1505 if (bsfound == 2) return TRUE;
1508 return (lpszPath1[pos] == lpszPath2[pos]);
1513 /*************************************************************************
1514 * PathIsSameRootAW [SHELL32.650]
1516 BOOL WINAPI PathIsSameRootAW(LPCVOID lpszPath1, LPCVOID lpszPath2)
1518 if (VERSION_OsIsUnicode())
1519 return PathIsSameRootW(lpszPath1, lpszPath2);
1520 return PathIsSameRootA(lpszPath1, lpszPath2);
1523 /*************************************************************************
1526 BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
1530 static LPSTR SupportedProtocol[] =
1531 {"http","https","ftp","gopher","file","mailto",NULL};
1533 if(!lpstrPath) return FALSE;
1536 lpstrRes = strchr(lpstrPath,':');
1537 if(!lpstrRes) return FALSE;
1538 iSize = lpstrRes - lpstrPath;
1540 while(SupportedProtocol[i])
1542 if (iSize == strlen(SupportedProtocol[i]))
1543 if(!strncasecmp(lpstrPath, SupportedProtocol[i], iSize))
1551 /*************************************************************************
1554 BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
1558 static WCHAR SupportedProtocol[7][7] =
1559 {{'h','t','t','p','\0'},{'h','t','t','p','s','\0'},{'f','t','p','\0'},
1560 {'g','o','p','h','e','r','\0'},{'f','i','l','e','\0'},
1561 {'m','a','i','l','t','o','\0'},{0}};
1563 if(!lpstrPath) return FALSE;
1566 lpstrRes = strchrW(lpstrPath,':');
1567 if(!lpstrRes) return FALSE;
1568 iSize = lpstrRes - lpstrPath;
1570 while(SupportedProtocol[i])
1572 if (iSize == strlenW(SupportedProtocol[i]))
1573 if(!strncmpiW(lpstrPath, SupportedProtocol[i], iSize))
1581 /*************************************************************************
1582 * IsLFNDriveA [SHELL32.119]
1585 * exported by ordinal Name
1587 BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath)
1591 if (!GetVolumeInformationA(lpszPath,NULL,0,NULL,&fnlen,NULL,NULL,0))
1597 Creating Something Unique
1599 /*************************************************************************
1600 * PathMakeUniqueNameA [internal]
1602 BOOL WINAPI PathMakeUniqueNameA(
1605 LPCSTR lpszShortName,
1606 LPCSTR lpszLongName,
1607 LPCSTR lpszPathName)
1609 FIXME("%p %lu %s %s %s stub\n",
1610 lpszBuffer, dwBuffSize, debugstr_a(lpszShortName),
1611 debugstr_a(lpszLongName), debugstr_a(lpszPathName));
1615 /*************************************************************************
1616 * PathMakeUniqueNameW [internal]
1618 BOOL WINAPI PathMakeUniqueNameW(
1621 LPCWSTR lpszShortName,
1622 LPCWSTR lpszLongName,
1623 LPCWSTR lpszPathName)
1625 FIXME("%p %lu %s %s %s stub\n",
1626 lpszBuffer, dwBuffSize, debugstr_w(lpszShortName),
1627 debugstr_w(lpszLongName), debugstr_w(lpszPathName));
1631 /*************************************************************************
1632 * PathMakeUniqueNameAW [SHELL32.47]
1634 BOOL WINAPI PathMakeUniqueNameAW(
1637 LPCVOID lpszShortName,
1638 LPCVOID lpszLongName,
1639 LPCVOID lpszPathName)
1641 if (VERSION_OsIsUnicode())
1642 return PathMakeUniqueNameW(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
1643 return PathMakeUniqueNameA(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
1646 /*************************************************************************
1647 * PathYetAnotherMakeUniqueNameA [SHELL32.75]
1650 * exported by ordinal
1652 BOOL WINAPI PathYetAnotherMakeUniqueNameA(
1654 LPCSTR lpszPathName,
1655 LPCSTR lpszShortName,
1656 LPCSTR lpszLongName)
1658 FIXME("(%p,%p, %p ,%p):stub.\n",
1659 lpszBuffer, lpszPathName, lpszShortName, lpszLongName);
1665 cleaning and resolving paths
1668 /*************************************************************************
1669 * PathFindOnPathA [SHELL32.145]
1671 BOOL WINAPI PathFindOnPathA(LPSTR sFile, LPCSTR sOtherDirs)
1673 FIXME("%s %s\n",sFile, sOtherDirs);
1677 /*************************************************************************
1678 * PathFindOnPathW [SHELL32]
1680 BOOL WINAPI PathFindOnPathW(LPWSTR sFile, LPCWSTR sOtherDirs)
1682 FIXME("%s %s\n",debugstr_w(sFile), debugstr_w(sOtherDirs));
1686 /*************************************************************************
1687 * PathFindOnPathAW [SHELL32]
1689 BOOL WINAPI PathFindOnPathAW(LPVOID sFile, LPCVOID sOtherDirs)
1691 if (VERSION_OsIsUnicode())
1692 return PathFindOnPathW(sFile, sOtherDirs);
1693 return PathFindOnPathA(sFile, sOtherDirs);
1696 /*************************************************************************
1697 * PathCleanupSpecA [SHELL32.171]
1699 DWORD WINAPI PathCleanupSpecA(LPSTR x, LPSTR y)
1701 FIXME("(%p %s, %p %s) stub\n",x,debugstr_a(x),y,debugstr_a(y));
1705 /*************************************************************************
1706 * PathCleanupSpecA [SHELL32]
1708 DWORD WINAPI PathCleanupSpecW(LPWSTR x, LPWSTR y)
1710 FIXME("(%p %s, %p %s) stub\n",x,debugstr_w(x),y,debugstr_w(y));
1714 /*************************************************************************
1715 * PathCleanupSpecAW [SHELL32]
1717 DWORD WINAPI PathCleanupSpecAW (LPVOID x, LPVOID y)
1719 if (VERSION_OsIsUnicode())
1720 return PathCleanupSpecW(x,y);
1721 return PathCleanupSpecA(x,y);
1724 /*************************************************************************
1725 * PathQualifyA [SHELL32]
1727 BOOL WINAPI PathQualifyA(LPCSTR pszPath)
1729 FIXME("%s\n",pszPath);
1733 /*************************************************************************
1734 * PathQualifyW [SHELL32]
1736 BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
1738 FIXME("%s\n",debugstr_w(pszPath));
1742 /*************************************************************************
1743 * PathQualifyAW [SHELL32]
1745 BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
1747 if (VERSION_OsIsUnicode())
1748 return PathQualifyW(pszPath);
1749 return PathQualifyA(pszPath);
1752 /*************************************************************************
1753 * PathResolveA [SHELL32.51]
1755 BOOL WINAPI PathResolveA(
1760 FIXME("(%s,%p,0x%08lx),stub!\n",
1761 lpszPath, *alpszPaths, dwFlags);
1765 /*************************************************************************
1766 * PathResolveW [SHELL32]
1768 BOOL WINAPI PathResolveW(
1770 LPCWSTR *alpszPaths,
1773 FIXME("(%s,%p,0x%08lx),stub!\n",
1774 debugstr_w(lpszPath), debugstr_w(*alpszPaths), dwFlags);
1778 /*************************************************************************
1779 * PathResolveAW [SHELL32]
1781 BOOL WINAPI PathResolveAW(
1783 LPCVOID *alpszPaths,
1786 if (VERSION_OsIsUnicode())
1787 return PathResolveW(lpszPath, (LPCWSTR*)alpszPaths, dwFlags);
1788 return PathResolveA(lpszPath, (LPCSTR*)alpszPaths, dwFlags);
1791 /*************************************************************************
1792 * PathProcessCommandA [SHELL32.653]
1794 HRESULT WINAPI PathProcessCommandA (
1800 FIXME("%s %p 0x%04lx 0x%04lx stub\n",
1801 lpszPath, lpszBuff, dwBuffSize, dwFlags);
1802 lstrcpyA(lpszBuff, lpszPath);
1806 /*************************************************************************
1807 * PathProcessCommandW
1809 HRESULT WINAPI PathProcessCommandW (
1815 FIXME("(%s, %p, 0x%04lx, 0x%04lx) stub\n",
1816 debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags);
1817 lstrcpyW(lpszBuff, lpszPath);
1821 /*************************************************************************
1822 * PathProcessCommandAW
1824 HRESULT WINAPI PathProcessCommandAW (
1830 if (VERSION_OsIsUnicode())
1831 return PathProcessCommandW(lpszPath, lpszBuff, dwBuffSize, dwFlags);
1832 return PathProcessCommandA(lpszPath, lpszBuff, dwBuffSize, dwFlags);
1839 /*************************************************************************
1840 * PathSetDlgItemPathA
1843 * use PathCompactPath to make sure, the path fits into the control
1845 BOOL WINAPI PathSetDlgItemPathA(HWND hDlg, int id, LPCSTR pszPath)
1846 { TRACE("%x %x %s\n",hDlg, id, pszPath);
1847 return SetDlgItemTextA(hDlg, id, pszPath);
1850 /*************************************************************************
1851 * PathSetDlgItemPathW
1853 BOOL WINAPI PathSetDlgItemPathW(HWND hDlg, int id, LPCWSTR pszPath)
1854 { TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
1855 return SetDlgItemTextW(hDlg, id, pszPath);
1858 /*************************************************************************
1859 * PathSetDlgItemPathAW
1861 BOOL WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
1862 { if (VERSION_OsIsUnicode())
1863 return PathSetDlgItemPathW(hDlg, id, pszPath);
1864 return PathSetDlgItemPathA(hDlg, id, pszPath);
1868 /*************************************************************************
1869 * SHGetSpecialFolderPathA [SHELL32.175]
1871 * converts csidl to path
1875 static char * szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
1876 static char * szSHUserFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
1878 BOOL WINAPI SHGetSpecialFolderPathA (
1884 CHAR szValueName[MAX_PATH], szDefaultPath[MAX_PATH];
1885 HKEY hRootKey, hKey;
1886 BOOL bRelative = TRUE;
1887 DWORD dwType, dwDisp, dwPathLen = MAX_PATH;
1889 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
1891 /* build default values */
1895 hRootKey = HKEY_CURRENT_USER;
1896 strcpy (szValueName, "AppData");
1897 strcpy (szDefaultPath, "AppData");
1901 hRootKey = HKEY_CURRENT_USER;
1902 strcpy (szValueName, "Cookies");
1903 strcpy(szDefaultPath, "Cookies");
1906 case CSIDL_DESKTOPDIRECTORY:
1907 hRootKey = HKEY_CURRENT_USER;
1908 strcpy(szValueName, "Desktop");
1909 strcpy(szDefaultPath, "Desktop");
1912 case CSIDL_COMMON_DESKTOPDIRECTORY:
1913 hRootKey = HKEY_LOCAL_MACHINE;
1914 strcpy(szValueName, "Common Desktop");
1915 strcpy(szDefaultPath, "Desktop");
1918 case CSIDL_FAVORITES:
1919 hRootKey = HKEY_CURRENT_USER;
1920 strcpy(szValueName, "Favorites");
1921 strcpy(szDefaultPath, "Favorites");
1925 hRootKey = HKEY_CURRENT_USER;
1926 strcpy(szValueName, "Fonts");
1927 strcpy(szDefaultPath, "Fonts");
1931 hRootKey = HKEY_CURRENT_USER;
1932 strcpy(szValueName, "History");
1933 strcpy(szDefaultPath, "History");
1937 hRootKey = HKEY_CURRENT_USER;
1938 strcpy(szValueName, "NetHood");
1939 strcpy(szDefaultPath, "NetHood");
1942 case CSIDL_INTERNET_CACHE:
1943 hRootKey = HKEY_CURRENT_USER;
1944 strcpy(szValueName, "Cache");
1945 strcpy(szDefaultPath, "Temporary Internet Files");
1948 case CSIDL_PERSONAL:
1949 hRootKey = HKEY_CURRENT_USER;
1950 strcpy(szValueName, "Personal");
1951 strcpy(szDefaultPath, "My Own Files");
1955 case CSIDL_PRINTHOOD:
1956 hRootKey = HKEY_CURRENT_USER;
1957 strcpy(szValueName, "PrintHood");
1958 strcpy(szDefaultPath, "PrintHood");
1961 case CSIDL_PROGRAMS:
1962 hRootKey = HKEY_CURRENT_USER;
1963 strcpy(szValueName, "Programs");
1964 strcpy(szDefaultPath, "StartMenu\\Programs");
1967 case CSIDL_COMMON_PROGRAMS:
1968 hRootKey = HKEY_LOCAL_MACHINE;
1969 strcpy(szValueName, "Common Programs");
1970 strcpy(szDefaultPath, "");
1974 hRootKey = HKEY_CURRENT_USER;
1975 strcpy(szValueName, "Recent");
1976 strcpy(szDefaultPath, "Recent");
1980 hRootKey = HKEY_CURRENT_USER;
1981 strcpy(szValueName, "SendTo");
1982 strcpy(szDefaultPath, "SendTo");
1985 case CSIDL_STARTMENU:
1986 hRootKey = HKEY_CURRENT_USER;
1987 strcpy(szValueName, "StartMenu");
1988 strcpy(szDefaultPath, "StartMenu");
1991 case CSIDL_COMMON_STARTMENU:
1992 hRootKey = HKEY_LOCAL_MACHINE;
1993 strcpy(szValueName, "Common StartMenu");
1994 strcpy(szDefaultPath, "StartMenu");
1998 hRootKey = HKEY_CURRENT_USER;
1999 strcpy(szValueName, "Startup");
2000 strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
2003 case CSIDL_COMMON_STARTUP:
2004 hRootKey = HKEY_LOCAL_MACHINE;
2005 strcpy(szValueName, "Common Startup");
2006 strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
2009 case CSIDL_TEMPLATES:
2010 hRootKey = HKEY_CURRENT_USER;
2011 strcpy(szValueName, "Templates");
2012 strcpy(szDefaultPath, "ShellNew");
2016 ERR("folder unknown or not allowed\n");
2020 /* user shell folders */
2021 if (RegCreateKeyExA(hRootKey,szSHUserFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
2023 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
2028 if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
2030 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
2033 /* value not existing */
2036 GetWindowsDirectoryA(szPath, MAX_PATH);
2037 PathAddBackslashA(szPath);
2038 strcat(szPath, szDefaultPath);
2042 strcpy(szPath, "C:\\"); /* fixme ??? */
2043 strcat(szPath, szDefaultPath);
2045 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
2050 /* if we don't care about existing directorys we are ready */
2051 if(csidl & CSIDL_FLAG_DONT_VERIFY) return TRUE;
2053 if (PathFileExistsA(szPath)) return TRUE;
2055 /* not existing but we not allowed to create it */
2056 if (!bCreate) return FALSE;
2058 if (!CreateDirectoryA(szPath,NULL))
2060 ERR("Failed to create directory '%s'.\n", szPath);
2064 MESSAGE("Created not existing system directory '%s'\n", szPath);
2068 /*************************************************************************
2069 * SHGetSpecialFolderPathW
2071 BOOL WINAPI SHGetSpecialFolderPathW (
2077 char szTemp[MAX_PATH];
2079 if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate))
2081 lstrcpynAtoW(szPath, szTemp, MAX_PATH);
2084 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
2089 /*************************************************************************
2090 * SHGetSpecialFolderPathAW
2092 BOOL WINAPI SHGetSpecialFolderPathAW (
2099 if (VERSION_OsIsUnicode())
2100 return SHGetSpecialFolderPathW (hwndOwner, szPath, csidl, bCreate);
2101 return SHGetSpecialFolderPathA (hwndOwner, szPath, csidl, bCreate);
2104 /*************************************************************************
2105 * SHGetFolderPathA [SHFOLDER.@]
2107 HRESULT WINAPI SHGetFolderPathA(
2110 HANDLE hToken, /* FIXME: get paths for specific user */
2111 DWORD dwFlags, /* FIXME: SHGFP_TYPE_CURRENT|SHGFP_TYPE_DEFAULT */
2114 return (SHGetSpecialFolderPathA(
2117 CSIDL_FOLDER_MASK & nFolder,
2118 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;
2121 /*************************************************************************
2122 * SHGetFolderPathW [SHFOLDER.@]
2124 HRESULT WINAPI SHGetFolderPathW(
2131 return (SHGetSpecialFolderPathW(
2134 CSIDL_FOLDER_MASK & nFolder,
2135 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;
2138 /*************************************************************************
2145 BOOL WINAPI PathCanonicalizeA(LPSTR pszBuf, LPCSTR pszPath)
2147 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = strlen(pszPath);
2148 BOOL bModifyed = FALSE;
2150 TRACE("%p %s\n", pszBuf, pszPath);
2152 pszBuf[OffsetDst]='\0';
2154 /* keep the root of the path */
2155 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
2157 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2159 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
2161 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2162 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2163 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
2165 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2166 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
2169 OffsetSrc++; LenSrc--; bModifyed = TRUE;
2171 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
2174 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
2179 /* ".\" at the beginning of the path */
2180 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
2182 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
2187 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
2189 /* "\.." found, go one deeper */
2190 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
2191 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
2192 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
2193 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
2195 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
2197 /* "\." found, skip it */
2198 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
2202 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
2205 pszBuf[OffsetDst] = '\0';
2206 TRACE("-- %s %u\n", pszBuf, bModifyed);
2211 /*************************************************************************
2217 BOOL WINAPI PathCanonicalizeW(LPWSTR pszBuf, LPCWSTR pszPath)
2219 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = lstrlenW(pszPath);
2220 BOOL bModifyed = FALSE;
2222 TRACE("%p %s\n", pszBuf, debugstr_w(pszPath));
2224 pszBuf[OffsetDst]='\0';
2226 /* keep the root of the path */
2227 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
2229 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2231 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
2233 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2234 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2235 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
2237 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2238 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
2241 OffsetSrc++; LenSrc--; bModifyed = TRUE;
2243 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
2246 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
2251 /* ".\" at the beginning of the path */
2252 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
2254 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
2259 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
2261 /* "\.." found, go one deeper */
2262 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
2263 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
2264 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
2265 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
2267 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
2269 /* "\." found, skip it */
2270 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
2274 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
2277 pszBuf[OffsetDst] = '\0';
2278 TRACE("-- %s %u\n", debugstr_w(pszBuf), bModifyed);
2282 /*************************************************************************
2283 * PathFindNextComponentA
2288 * aa "" (pointer to traling NULL)
2289 * aa\ "" (pointer to traling NULL)
2290 * aa\\ "" (pointer to traling NULL)
2297 LPSTR WINAPI PathFindNextComponentA(LPCSTR pszPath)
2301 TRACE("%s\n", pszPath);
2303 if(!pszPath || !*pszPath) return NULL;
2304 if(!(pos = StrChrA(pszPath, '\\')))
2305 return (LPSTR) pszPath + strlen(pszPath);
2307 if(pos[0] == '\\') pos++;
2311 /*************************************************************************
2312 * PathFindNextComponentW
2314 LPWSTR WINAPI PathFindNextComponentW(LPCWSTR pszPath)
2318 TRACE("%s\n", debugstr_w(pszPath));
2320 if(!pszPath || !*pszPath) return NULL;
2321 if (!(pos = StrChrW(pszPath, '\\')))
2322 return (LPWSTR) pszPath + lstrlenW(pszPath);
2324 if(pos[0] == '\\') pos++;
2328 /*************************************************************************
2332 static void _PathAddDotA(LPSTR lpszPath)
2334 int len = strlen(lpszPath);
2335 if (len && lpszPath[len-1]!='.')
2337 lpszPath[len] = '.';
2338 lpszPath[len+1]= '\0';
2342 BOOL WINAPI PathAddExtensionA(
2344 LPCSTR pszExtension)
2348 LPSTR pszExt = PathFindFileNameA(pszPath); /* last path component */
2349 pszExt = PathFindExtensionA(pszExt);
2350 if (*pszExt != '\0') return FALSE; /* already with extension */
2351 _PathAddDotA(pszPath);
2354 if (!pszExtension || *pszExtension=='\0')
2355 strcat(pszPath, "exe");
2357 strcat(pszPath, pszExtension);
2361 /*************************************************************************
2364 static void _PathAddDotW(LPWSTR lpszPath)
2366 int len = lstrlenW(lpszPath);
2367 if (len && lpszPath[len-1]!='.')
2369 lpszPath[len] = '.';
2370 lpszPath[len+1]= '\0';
2374 /*************************************************************************
2377 BOOL WINAPI PathAddExtensionW(
2379 LPCWSTR pszExtension)
2381 static const WCHAR ext[] = { 'e','x','e',0 };
2385 LPWSTR pszExt = PathFindFileNameW(pszPath); /* last path component */
2386 pszExt = PathFindExtensionW(pszExt);
2387 if (*pszExt != '\0') return FALSE; /* already with extension */
2388 _PathAddDotW(pszPath);
2391 if (!pszExtension || *pszExtension=='\0')
2392 lstrcatW(pszPath, ext);
2394 lstrcatW(pszPath, pszExtension);
2399 /*************************************************************************
2402 BOOL WINAPI PathIsUNCServerA(
2405 FIXME("%s\n", pszPath);
2409 /*************************************************************************
2412 BOOL WINAPI PathIsUNCServerW(
2415 FIXME("%s\n", debugstr_w(pszPath));
2419 /*************************************************************************
2420 * PathIsUNCServerShareA
2422 BOOL WINAPI PathIsUNCServerShareA(
2425 FIXME("%s\n", pszPath);
2429 /*************************************************************************
2430 * PathIsUNCServerShareW
2432 BOOL WINAPI PathIsUNCServerShareW(
2435 FIXME("%s\n", debugstr_w(pszPath));
2439 /*************************************************************************
2442 BOOL WINAPI PathMakePrettyA(
2445 FIXME("%s\n", lpPath);
2449 /*************************************************************************
2452 BOOL WINAPI PathMakePrettyW(
2455 FIXME("%s\n", debugstr_w(lpPath));
2460 /*************************************************************************
2463 int WINAPI PathCommonPrefixA(
2468 FIXME("%s %s %p\n", pszFile1, pszFile2, achPath);
2472 /*************************************************************************
2475 int WINAPI PathCommonPrefixW(
2480 FIXME("%s %s %p\n", debugstr_w(pszFile1), debugstr_w(pszFile2),achPath );