9 #include "wine/unicode.h"
10 #include "wine/undocshell.h"
11 #include "wine/winestring.h"
13 #include "debugtools.h"
15 DEFAULT_DEBUG_CHANNEL(shell);
17 #define isSlash(x) ((x)=='\\' || (x)=='/')
19 ########## Combining and Constructing paths ##########
22 /*************************************************************************
23 * PathAppendA [SHLWAPI.@]
26 * concat path lpszPath2 onto lpszPath1
29 * the resulting path is also canonicalized
31 BOOL WINAPI PathAppendA(
35 TRACE("%s %s\n",lpszPath1, lpszPath2);
36 while (lpszPath2[0]=='\\') lpszPath2++;
37 PathCombineA(lpszPath1,lpszPath1,lpszPath2);
41 /*************************************************************************
42 * PathAppendW [SHLWAPI.@]
44 BOOL WINAPI PathAppendW(
48 TRACE("%s %s\n",debugstr_w(lpszPath1), debugstr_w(lpszPath2));
49 while (lpszPath2[0]=='\\') lpszPath2++;
50 PathCombineW(lpszPath1,lpszPath1,lpszPath2);
54 /*************************************************************************
55 * PathCombineA [SHLWAPI.@]
58 * if lpszFile='.' skip it
59 * szDest can be equal to lpszFile. Thats why we use sTemp
62 * the resulting path is also canonicalized
64 LPSTR WINAPI PathCombineA(
70 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, lpszDir, lpszFile, lpszFile);
73 if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
75 strcpy(szDest,lpszDir);
79 /* if lpszFile is a complete path don't care about lpszDir */
80 if (PathGetDriveNumberA(lpszFile) != -1)
82 strcpy(szDest,lpszFile);
84 else if (lpszFile[0] == '\\' )
86 strcpy(sTemp,lpszDir);
87 PathStripToRootA(sTemp);
88 strcat(sTemp,lpszFile);
93 strcpy(sTemp,lpszDir);
94 PathAddBackslashA(sTemp);
95 strcat(sTemp,lpszFile);
101 /*************************************************************************
102 * PathCombineW [SHLWAPI.@]
104 LPWSTR WINAPI PathCombineW(
109 WCHAR sTemp[MAX_PATH];
110 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, debugstr_w(lpszDir),
111 lpszFile, debugstr_w(lpszFile));
114 if (!lpszFile || !lpszFile[0] || (lpszFile[0]==(WCHAR)'.' && !lpszFile[1]) )
116 strcpyW(szDest,lpszDir);
120 /* if lpszFile is a complete path don't care about lpszDir */
121 if (PathGetDriveNumberW(lpszFile) != -1)
123 strcpyW(szDest,lpszFile);
125 else if (lpszFile[0] == (WCHAR)'\\' )
127 strcpyW(sTemp,lpszDir);
128 PathStripToRootW(sTemp);
129 strcatW(sTemp,lpszFile);
130 strcpyW(szDest,sTemp);
134 strcpyW(sTemp,lpszDir);
135 PathAddBackslashW(sTemp);
136 strcatW(sTemp,lpszFile);
137 strcpyW(szDest,sTemp);
142 /*************************************************************************
143 * PathAddBackslashA [SHLWAPI.@]
146 * append \ if there is none
148 LPSTR WINAPI PathAddBackslashA(LPSTR lpszPath)
151 TRACE("%p->%s\n",lpszPath,lpszPath);
153 len = strlen(lpszPath);
154 if (len && lpszPath[len-1]!='\\')
156 lpszPath[len] = '\\';
157 lpszPath[len+1]= 0x00;
158 return lpszPath+len+1;
163 /*************************************************************************
164 * PathAddBackslashW [SHLWAPI.@]
166 LPWSTR WINAPI PathAddBackslashW(LPWSTR lpszPath)
169 TRACE("%p->%s\n",lpszPath,debugstr_w(lpszPath));
171 len = strlenW(lpszPath);
172 if (len && lpszPath[len-1]!=(WCHAR)'\\')
174 lpszPath[len] = (WCHAR)'\\';
175 lpszPath[len+1]= 0x00;
176 return lpszPath+len+1;
181 /*************************************************************************
182 * PathBuildRootA [SHLWAPI.@]
184 LPSTR WINAPI PathBuildRootA(LPSTR lpszPath, int drive)
186 TRACE("%p %i\n",lpszPath, drive);
188 strcpy(lpszPath,"A:\\");
193 /*************************************************************************
194 * PathBuildRootW [SHLWAPI.@]
196 LPWSTR WINAPI PathBuildRootW(LPWSTR lpszPath, int drive)
198 TRACE("%p %i\n",debugstr_w(lpszPath), drive);
200 lstrcpyAtoW(lpszPath,"A:\\");
206 Extracting Component Parts
209 /*************************************************************************
210 * PathFindFileNameA [SHLWAPI.@]
212 LPSTR WINAPI PathFindFileNameA(LPCSTR lpszPath)
214 LPCSTR lastSlash = lpszPath;
216 TRACE("%s\n",lpszPath);
219 if ( isSlash(lpszPath[0]) && lpszPath[1])
220 lastSlash = lpszPath+1;
221 lpszPath = CharNextA(lpszPath);
223 return (LPSTR)lastSlash;
227 /*************************************************************************
228 * PathFindFileNameW [SHLWAPI.@]
230 LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
235 TRACE("%s\n",debugstr_w(wslash));
238 if (((lpszPath[0]=='\\') || (lpszPath[0]==':')) && lpszPath[1] && lpszPath[1]!='\\')
240 lpszPath = CharNextW(lpszPath);
242 return (LPWSTR)wslash;
245 /*************************************************************************
246 * PathFindExtensionA [SHLWAPI.@]
249 * returns pointer to last . in last lpszPath component or at \0.
252 LPSTR WINAPI PathFindExtensionA(LPCSTR lpszPath)
254 LPCSTR lastpoint = NULL;
256 TRACE("%p %s\n",lpszPath,lpszPath);
260 if (*lpszPath=='\\'||*lpszPath==' ')
264 lpszPath = CharNextA(lpszPath);
266 return (LPSTR)(lastpoint?lastpoint:lpszPath);
269 /*************************************************************************
270 * PathFindExtensionW [SHLWAPI.@]
272 LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
274 LPCWSTR lastpoint = NULL;
276 TRACE("(%p %s)\n",lpszPath,debugstr_w(lpszPath));
280 if (*lpszPath==(WCHAR)'\\'||*lpszPath==(WCHAR)' ')
282 if (*lpszPath==(WCHAR)'.')
284 lpszPath = CharNextW(lpszPath);
286 return (LPWSTR)(lastpoint?lastpoint:lpszPath);
289 /*************************************************************************
290 * PathGetArgsA [SHLWAPI.@]
293 * look for next arg in string. handle "quoted" strings
294 * returns pointer to argument *AFTER* the space. Or to the \0.
299 LPSTR WINAPI PathGetArgsA(LPCSTR lpszPath)
303 TRACE("%s\n",lpszPath);
307 if ((*lpszPath==' ') && !qflag)
308 return (LPSTR)lpszPath+1;
311 lpszPath = CharNextA(lpszPath);
313 return (LPSTR)lpszPath;
316 /*************************************************************************
317 * PathGetArgsW [SHLWAPI.@]
319 LPWSTR WINAPI PathGetArgsW(LPCWSTR lpszPath)
323 TRACE("%s\n",debugstr_w(lpszPath));
327 if ((*lpszPath==' ') && !qflag)
328 return (LPWSTR)lpszPath+1;
331 lpszPath = CharNextW(lpszPath);
333 return (LPWSTR)lpszPath;
336 /*************************************************************************
337 * PathGetDriveNumberA [SHLWAPI.@]
339 int WINAPI PathGetDriveNumberA(LPCSTR lpszPath)
341 int chr = tolower(lpszPath[0]);
343 TRACE ("%s\n",debugstr_a(lpszPath));
345 if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
346 return tolower(lpszPath[0]) - 'a' ;
349 /*************************************************************************
350 * PathGetDriveNumberW [SHLWAPI.@]
352 int WINAPI PathGetDriveNumberW(LPCWSTR lpszPath)
354 int chr = tolowerW(lpszPath[0]);
356 TRACE ("%s\n",debugstr_w(lpszPath));
358 if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
359 return tolowerW(lpszPath[0]) - 'a' ;
362 /*************************************************************************
363 * PathRemoveFileSpecA [SHLWAPI.@]
366 * truncates passed argument to a valid path
367 * returns if the string was modified or not.
368 * "\foo\xx\foo"-> "\foo\xx"
372 BOOL WINAPI PathRemoveFileSpecA(LPSTR lpszPath)
374 LPSTR cutplace = lpszPath;
377 TRACE("%s\n",lpszPath);
381 while (*lpszPath == '\\') cutplace = ++lpszPath;
385 if(lpszPath[0] == '\\') cutplace = lpszPath;
387 if(lpszPath[0] == ':')
389 cutplace = lpszPath + 1;
390 if (lpszPath[1] == '\\') cutplace++;
393 lpszPath = CharNextA(lpszPath);
394 if (!lpszPath) break;
397 ret = (*cutplace!='\0');
403 /*************************************************************************
404 * PathRemoveFileSpecW [SHLWAPI.@]
406 BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
408 LPWSTR cutplace = lpszPath;
411 TRACE("%s\n",debugstr_w(lpszPath));
415 while (*lpszPath == '\\') cutplace = ++lpszPath;
419 if(lpszPath[0] == '\\') cutplace = lpszPath;
421 if(lpszPath[0] == ':')
423 cutplace = lpszPath + 1;
424 if (lpszPath[1] == '\\') cutplace++;
427 lpszPath = CharNextW(lpszPath);
428 if (!lpszPath) break;
431 ret = (*cutplace!='\0');
437 /*************************************************************************
438 * PathStripPathA [SHELLWAPI.@]
441 * removes the path from the beginning of a filename
443 void WINAPI PathStripPathA(LPSTR lpszPath)
445 LPSTR lpszFileName = PathFindFileNameA(lpszPath);
447 TRACE("%s\n", lpszPath);
450 RtlMoveMemory(lpszPath, lpszFileName, strlen(lpszFileName)+1);
453 /*************************************************************************
454 * PathStripPathW [SHELLWAPI.@]
456 void WINAPI PathStripPathW(LPWSTR lpszPath)
458 LPWSTR lpszFileName = PathFindFileNameW(lpszPath);
460 TRACE("%s\n", debugstr_w(lpszPath));
462 RtlMoveMemory(lpszPath, lpszFileName, (strlenW(lpszFileName)+1)*sizeof(WCHAR));
465 /*************************************************************************
466 * PathStripToRootA [SHLWAPI.@]
468 BOOL WINAPI PathStripToRootA(LPSTR lpszPath)
470 TRACE("%s\n", lpszPath);
472 if (!lpszPath) return FALSE;
473 while(!PathIsRootA(lpszPath))
474 if (!PathRemoveFileSpecA(lpszPath)) return FALSE;
478 /*************************************************************************
479 * PathStripToRootW [SHLWAPI.@]
481 BOOL WINAPI PathStripToRootW(LPWSTR lpszPath)
483 TRACE("%s\n", debugstr_w(lpszPath));
485 if (!lpszPath) return FALSE;
486 while(!PathIsRootW(lpszPath))
487 if (!PathRemoveFileSpecW(lpszPath)) return FALSE;
491 /*************************************************************************
492 * PathRemoveArgsA [SHLWAPI.@]
495 void WINAPI PathRemoveArgsA(LPSTR lpszPath)
497 TRACE("%s\n",lpszPath);
501 LPSTR lpszArgs = PathGetArgsA(lpszPath);
504 LPSTR lpszLastChar = CharPrevA(lpszPath, lpszArgs);
505 if(*lpszLastChar==' ') *lpszLastChar = '\0';
510 /*************************************************************************
511 * PathRemoveArgsW [SHLWAPI.@]
513 void WINAPI PathRemoveArgsW(LPWSTR lpszPath)
515 TRACE("%s\n", debugstr_w(lpszPath));
519 LPWSTR lpszArgs = PathGetArgsW(lpszPath);
522 LPWSTR lpszLastChar = CharPrevW(lpszPath, lpszArgs);
523 if(*lpszLastChar==' ') *lpszLastChar = '\0';
528 /*************************************************************************
529 * PathRemoveExtensionA [SHLWAPI.@]
531 void WINAPI PathRemoveExtensionA(LPSTR lpszPath)
533 LPSTR lpszExtension = PathFindExtensionA(lpszPath);
535 TRACE("%s\n", lpszPath);
537 if (lpszExtension) *lpszExtension='\0';
540 /*************************************************************************
541 * PathRemoveExtensionW [SHLWAPI.@]
543 void WINAPI PathRemoveExtensionW(LPWSTR lpszPath)
545 LPWSTR lpszExtension = PathFindExtensionW(lpszPath);
547 TRACE("%s\n", debugstr_w(lpszPath));
549 if (lpszExtension) *lpszExtension='\0';
552 /*************************************************************************
553 * PathRemoveBackslashA [SHLWAPI.@]
555 * If the path ends in a backslash it is replaced by a NULL
556 * and the address of the NULL is returned
558 * the address of the last character is returned.
561 * "c:\": keep backslash
563 LPSTR WINAPI PathRemoveBackslashA( LPSTR lpszPath )
570 len = strlen(lpszPath);
571 szTemp = CharPrevA(lpszPath, lpszPath+len);
572 if (! PathIsRootA(lpszPath))
574 if (*szTemp == '\\') *szTemp = '\0';
580 /*************************************************************************
581 * PathRemoveBackslashW [SHLWAPI.@]
583 LPWSTR WINAPI PathRemoveBackslashW( LPWSTR lpszPath )
586 LPWSTR szTemp = NULL;
590 len = strlenW(lpszPath);
591 szTemp = CharPrevW(lpszPath, lpszPath+len);
592 if (! PathIsRootW(lpszPath))
594 if (*szTemp == '\\') *szTemp = '\0';
605 /*************************************************************************
606 * PathRemoveBlanksA [SHLWAPI.@]
609 * remove spaces from beginning and end of passed string
611 void WINAPI PathRemoveBlanksA(LPSTR str)
619 while (*x==' ') x = CharNextA(x);
620 if (x!=str) strcpy(str,x);
622 while (*x==' ') x = CharPrevA(str, x);
623 if (*x==' ') *x='\0';
627 /*************************************************************************
628 * PathRemoveBlanksW [SHLWAPI.@]
630 void WINAPI PathRemoveBlanksW(LPWSTR str)
634 TRACE("%s\n",debugstr_w(str));
638 while (*x==' ') x = CharNextW(x);
639 if (x!=str) strcpyW(str,x);
640 x=str+strlenW(str)-1;
641 while (*x==' ') x = CharPrevW(str, x);
642 if (*x==' ') *x='\0';
646 /*************************************************************************
647 * PathQuoteSpacesA [SHLWAPI.@]
650 LPSTR WINAPI PathQuoteSpacesA(LPSTR lpszPath)
652 TRACE("%s\n",lpszPath);
654 if(StrChrA(lpszPath,' '))
656 int len = strlen(lpszPath);
657 RtlMoveMemory(lpszPath+1, lpszPath, len);
667 /*************************************************************************
668 * PathQuoteSpacesW [SHLWAPI.@]
670 LPWSTR WINAPI PathQuoteSpacesW(LPWSTR lpszPath)
672 TRACE("%s\n",debugstr_w(lpszPath));
674 if(StrChrW(lpszPath,' '))
676 int len = strlenW(lpszPath);
677 RtlMoveMemory(lpszPath+1, lpszPath, len*sizeof(WCHAR));
687 /*************************************************************************
688 * PathUnquoteSpacesA [SHLWAPI.@]
691 * unquote string (remove ")
693 VOID WINAPI PathUnquoteSpacesA(LPSTR str)
695 DWORD len = strlen(str);
708 /*************************************************************************
709 * PathUnquoteSpacesW [SHLWAPI.@]
711 VOID WINAPI PathUnquoteSpacesW(LPWSTR str)
713 DWORD len = strlenW(str);
715 TRACE("%s\n",debugstr_w(str));
726 /*************************************************************************
727 * PathParseIconLocationA [SHLWAPI.@]
729 int WINAPI PathParseIconLocationA(LPSTR lpszPath)
731 LPSTR lpstrComma = strchr(lpszPath, ',');
733 FIXME("%s stub\n", debugstr_a(lpszPath));
735 if (lpstrComma && lpstrComma[1])
738 /* return atoi(&lpstrComma[1]); FIXME */
741 PathUnquoteSpacesA(lpszPath);
745 /*************************************************************************
746 * PathParseIconLocationW [SHLWAPI.@]
748 int WINAPI PathParseIconLocationW(LPWSTR lpszPath)
750 LPWSTR lpstrComma = strchrW(lpszPath, ',');
752 FIXME("%s stub\n", debugstr_w(lpszPath));
754 if (lpstrComma && lpstrComma[1])
757 /* return _wtoi(&lpstrComma[1]); FIXME */
759 PathUnquoteSpacesW(lpszPath);
764 ########## cleaning and resolving paths ##########
767 /*************************************************************************
768 * PathFindOnPathA [SHLWAPI.@]
770 BOOL WINAPI PathFindOnPathA(LPSTR sFile, LPCSTR sOtherDirs)
772 FIXME("%s %s\n",sFile, sOtherDirs);
776 /*************************************************************************
777 * PathFindOnPathW [SHLWAPI.@]
779 BOOL WINAPI PathFindOnPathW(LPWSTR sFile, LPCWSTR sOtherDirs)
781 FIXME("%s %s\n",debugstr_w(sFile), debugstr_w(sOtherDirs));
785 /*************************************************************************
786 * PathCompactPathExA [SHLWAPI.@]
788 BOOL WINAPI PathCompactPathExA(
794 FIXME("%p %s 0x%08x 0x%08lx\n", pszOut, pszSrc, cchMax, dwFlags);
798 /*************************************************************************
799 * PathCompactPathExW [SHLWAPI.@]
801 BOOL WINAPI PathCompactPathExW(
807 FIXME("%p %s 0x%08x 0x%08lx\n", pszOut, debugstr_w(pszSrc), cchMax, dwFlags);
812 ########## Path Testing ##########
815 /*************************************************************************
816 * PathIsUNCA [SHLWAPI.@]
819 * PathIsUNC(char*path);
821 BOOL WINAPI PathIsUNCA(LPCSTR lpszPath)
823 TRACE("%s\n",lpszPath);
825 return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
828 /*************************************************************************
829 * PathIsUNCW [SHLWAPI.@]
831 BOOL WINAPI PathIsUNCW(LPCWSTR lpszPath)
833 TRACE("%s\n",debugstr_w(lpszPath));
835 return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
838 /*************************************************************************
839 * PathIsRelativeA [SHLWAPI.@]
841 BOOL WINAPI PathIsRelativeA (LPCSTR lpszPath)
843 TRACE("lpszPath=%s\n",lpszPath);
845 return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
848 /*************************************************************************
849 * PathIsRelativeW [SHLWAPI.@]
851 BOOL WINAPI PathIsRelativeW (LPCWSTR lpszPath)
853 TRACE("lpszPath=%s\n",debugstr_w(lpszPath));
855 return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
858 /*************************************************************************
859 * PathIsRootA [SHLWAPI.@]
862 * TRUE if the path points to a root directory
864 BOOL WINAPI PathIsRootA(LPCSTR lpszPath)
866 TRACE("%s\n",lpszPath);
869 if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
873 if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
876 /* UNC "\\<computer>\<share>" */
877 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
879 int foundbackslash = 0;
883 if (*lpszPath=='\\') foundbackslash++;
884 lpszPath = CharNextA(lpszPath);
886 if (foundbackslash <= 1)
892 /*************************************************************************
893 * PathIsRootW [SHLWAPI.@]
895 BOOL WINAPI PathIsRootW(LPCWSTR lpszPath)
897 TRACE("%s\n",debugstr_w(lpszPath));
900 if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
904 if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
907 /* UNC "\\<computer>\<share>" */
908 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
910 int foundbackslash = 0;
914 if (*lpszPath=='\\') foundbackslash++;
915 lpszPath = CharNextW(lpszPath);
917 if (foundbackslash <= 1)
924 /*************************************************************************
925 * PathIsDirectoryA [SHLWAPI.@]
927 BOOL WINAPI PathIsDirectoryA(LPCSTR lpszPath)
931 TRACE("%s\n", debugstr_a(lpszPath));
933 dwAttr = GetFileAttributesA(lpszPath);
934 return (dwAttr != -1) ? dwAttr & FILE_ATTRIBUTE_DIRECTORY : 0;
937 /*************************************************************************
938 * PathIsDirectoryW [SHLWAPI.@]
940 BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
944 TRACE("%s\n", debugstr_w(lpszPath));
946 dwAttr = GetFileAttributesW(lpszPath);
947 return (dwAttr != -1) ? dwAttr & FILE_ATTRIBUTE_DIRECTORY : 0;
950 /*************************************************************************
951 * PathFileExistsA [SHLWAPI.@]
954 * file_exists(char *fn);
956 BOOL WINAPI PathFileExistsA(LPCSTR lpszPath)
958 TRACE("%s\n",lpszPath);
959 return (GetFileAttributesA(lpszPath)!=-1);
962 /*************************************************************************
963 * PathFileExistsW [SHLWAPI.@]
965 BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
967 TRACE("%s\n",debugstr_w(lpszPath));
968 return (GetFileAttributesW(lpszPath)!=-1);
971 /*************************************************************************
972 * PathMatchSingleMaskA [internal]
975 * internal (used by PathMatchSpec)
977 static BOOL PathMatchSingleMaskA(LPCSTR name, LPCSTR mask)
979 while (*name && *mask && *mask!=';')
985 if (PathMatchSingleMaskA(name,mask+1)) return 1; /* try substrings */
989 if (toupper(*mask)!=toupper(*name) && *mask!='?') return 0;
990 name = CharNextA(name);
991 mask = CharNextA(mask);
995 while (*mask=='*') mask++;
996 if (!*mask || *mask==';') return 1;
1001 /*************************************************************************
1002 * PathMatchSingleMaskW [internal]
1004 static BOOL PathMatchSingleMaskW(LPCWSTR name, LPCWSTR mask)
1006 while (*name && *mask && *mask!=';')
1012 if (PathMatchSingleMaskW(name,mask+1)) return 1; /* try substrings */
1016 if (toupperW(*mask)!=toupperW(*name) && *mask!='?') return 0;
1017 name = CharNextW(name);
1018 mask = CharNextW(mask);
1022 while (*mask=='*') mask++;
1023 if (!*mask || *mask==';') return 1;
1027 /*************************************************************************
1028 * PathMatchSpecA [SHLWAPI.@]
1031 * used from COMDLG32
1033 BOOL WINAPI PathMatchSpecA(LPCSTR name, LPCSTR mask)
1035 TRACE("%s %s\n",name,mask);
1037 if (!lstrcmpA( mask, "*.*" )) return 1; /* we don't require a period */
1041 if (PathMatchSingleMaskA(name,mask)) return 1; /* helper function */
1042 while (*mask && *mask!=';') mask = CharNextA(mask);
1046 while (*mask==' ') mask++; /* masks may be separated by "; " */
1052 /*************************************************************************
1053 * PathMatchSpecW [SHLWAPI.@]
1055 BOOL WINAPI PathMatchSpecW(LPCWSTR name, LPCWSTR mask)
1058 TRACE("%s %s\n",debugstr_w(name),debugstr_w(mask));
1060 lstrcpyAtoW(stemp,"*.*");
1061 if (!lstrcmpW( mask, stemp )) return 1; /* we don't require a period */
1065 if (PathMatchSingleMaskW(name,mask)) return 1; /* helper function */
1066 while (*mask && *mask!=';') mask = CharNextW(mask);
1070 while (*mask==' ') mask++; /* masks may be separated by "; " */
1076 /*************************************************************************
1077 * PathIsSameRootA [SHLWAPI.@]
1080 * what to do with "\path" ??
1082 BOOL WINAPI PathIsSameRootA(LPCSTR lpszPath1, LPCSTR lpszPath2)
1084 TRACE("%s %s\n", lpszPath1, lpszPath2);
1086 if (PathIsRelativeA(lpszPath1) || PathIsRelativeA(lpszPath2)) return FALSE;
1089 if ( toupper(lpszPath1[0])==toupper(lpszPath2[0]) &&
1090 lpszPath1[1]==':' && lpszPath2[1]==':' &&
1091 lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
1095 if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
1096 lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
1098 int pos=2, bsfound=0;
1099 while (lpszPath1[pos] && lpszPath2[pos] &&
1100 (lpszPath1[pos] == lpszPath2[pos]))
1102 if (lpszPath1[pos]=='\\') bsfound++;
1103 if (bsfound == 2) return TRUE;
1104 pos++; /* fixme: use CharNext*/
1106 return (lpszPath1[pos] == lpszPath2[pos]);
1111 /*************************************************************************
1112 * PathIsSameRootW [SHLWAPI.@]
1114 BOOL WINAPI PathIsSameRootW(LPCWSTR lpszPath1, LPCWSTR lpszPath2)
1116 TRACE("%s %s\n", debugstr_w(lpszPath1), debugstr_w(lpszPath2));
1118 if (PathIsRelativeW(lpszPath1) || PathIsRelativeW(lpszPath2)) return FALSE;
1121 if ( toupperW(lpszPath1[0])==toupperW(lpszPath2[0]) &&
1122 lpszPath1[1]==':' && lpszPath2[1]==':' &&
1123 lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
1127 if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
1128 lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
1130 int pos=2, bsfound=0;
1131 while (lpszPath1[pos] && lpszPath2[pos] &&
1132 (lpszPath1[pos] == lpszPath2[pos]))
1134 if (lpszPath1[pos]=='\\') bsfound++;
1135 if (bsfound == 2) return TRUE;
1136 pos++;/* fixme: use CharNext*/
1138 return (lpszPath1[pos] == lpszPath2[pos]);
1143 /*************************************************************************
1146 BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
1150 static LPSTR SupportedProtocol[] =
1151 {"http","https","ftp","gopher","file","mailto",NULL};
1153 if(!lpstrPath) return FALSE;
1156 lpstrRes = strchr(lpstrPath,':');
1157 if(!lpstrRes) return FALSE;
1158 iSize = lpstrRes - lpstrPath;
1160 while(SupportedProtocol[i])
1162 if (iSize == strlen(SupportedProtocol[i]))
1163 if(!strncasecmp(lpstrPath, SupportedProtocol[i], iSize))
1171 /*************************************************************************
1174 BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
1178 static WCHAR SupportedProtocol[7][7] =
1179 {{'h','t','t','p','\0'},{'h','t','t','p','s','\0'},{'f','t','p','\0'},
1180 {'g','o','p','h','e','r','\0'},{'f','i','l','e','\0'},
1181 {'m','a','i','l','t','o','\0'},{0}};
1183 if(!lpstrPath) return FALSE;
1186 lpstrRes = strchrW(lpstrPath,':');
1187 if(!lpstrRes) return FALSE;
1188 iSize = lpstrRes - lpstrPath;
1190 while(SupportedProtocol[i])
1192 if (iSize == strlenW(SupportedProtocol[i]))
1193 if(!strncmpiW(lpstrPath, SupportedProtocol[i], iSize))
1202 /*************************************************************************
1203 * PathIsContentTypeA [SHLWAPI.@]
1205 BOOL WINAPI PathIsContentTypeA(LPCSTR pszPath, LPCSTR pszContentType)
1207 FIXME("%s %s\n", pszPath, pszContentType);
1211 /*************************************************************************
1212 * PathIsContentTypeW [SHLWAPI.@]
1214 BOOL WINAPI PathIsContentTypeW(LPCWSTR pszPath, LPCWSTR pszContentType)
1216 FIXME("%s %s\n", debugstr_w(pszPath), debugstr_w(pszContentType));
1220 /*************************************************************************
1221 * PathIsFileSpecA [SHLWAPI.@]
1223 BOOL WINAPI PathIsFileSpecA(LPCSTR pszPath)
1225 FIXME("%s\n", pszPath);
1229 /*************************************************************************
1230 * PathIsFileSpecW [SHLWAPI.@]
1232 BOOL WINAPI PathIsFileSpecW(LPCWSTR pszPath)
1234 FIXME("%s\n", debugstr_w(pszPath));
1238 /*************************************************************************
1239 * PathIsPrefixA [SHLWAPI.@]
1241 BOOL WINAPI PathIsPrefixA(LPCSTR pszPrefix, LPCSTR pszPath)
1243 FIXME("%s %s\n", pszPrefix, pszPath);
1247 /*************************************************************************
1248 * PathIsPrefixW [SHLWAPI.@]
1250 BOOL WINAPI PathIsPrefixW(LPCWSTR pszPrefix, LPCWSTR pszPath)
1252 FIXME("%s %s\n", debugstr_w(pszPrefix), debugstr_w(pszPath));
1256 /*************************************************************************
1257 * PathIsSystemFolderA [SHLWAPI.@]
1259 BOOL WINAPI PathIsSystemFolderA(LPCSTR pszPath, DWORD dwAttrb)
1261 FIXME("%s 0x%08lx\n", pszPath, dwAttrb);
1265 /*************************************************************************
1266 * PathIsSystemFolderW [SHLWAPI.@]
1268 BOOL WINAPI PathIsSystemFolderW(LPCWSTR pszPath, DWORD dwAttrb)
1270 FIXME("%s 0x%08lx\n", debugstr_w(pszPath), dwAttrb);
1274 /*************************************************************************
1275 * PathIsUNCServerA [SHLWAPI.@]
1277 BOOL WINAPI PathIsUNCServerA(
1280 FIXME("%s\n", pszPath);
1284 /*************************************************************************
1285 * PathIsUNCServerW [SHLWAPI.@]
1287 BOOL WINAPI PathIsUNCServerW(
1290 FIXME("%s\n", debugstr_w(pszPath));
1294 /*************************************************************************
1295 * PathIsUNCServerShareA [SHLWAPI.@]
1297 BOOL WINAPI PathIsUNCServerShareA(
1300 FIXME("%s\n", pszPath);
1304 /*************************************************************************
1305 * PathIsUNCServerShareW [SHLWAPI.@]
1307 BOOL WINAPI PathIsUNCServerShareW(
1310 FIXME("%s\n", debugstr_w(pszPath));
1314 /*************************************************************************
1315 * PathCanonicalizeA [SHLWAPI.@]
1318 * returnvalue, use CharNext
1321 BOOL WINAPI PathCanonicalizeA(LPSTR pszBuf, LPCSTR pszPath)
1323 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = strlen(pszPath);
1324 BOOL bModifyed = FALSE;
1326 TRACE("%p %s\n", pszBuf, pszPath);
1328 pszBuf[OffsetDst]='\0';
1330 /* keep the root of the path */
1331 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
1333 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1335 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
1337 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1338 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1339 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
1341 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1342 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
1345 OffsetSrc++; LenSrc--; bModifyed = TRUE;
1347 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
1350 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1355 /* ".\" at the beginning of the path */
1356 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
1358 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1363 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
1365 /* "\.." found, go one deeper */
1366 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
1367 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
1368 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
1369 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
1371 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
1373 /* "\." found, skip it */
1374 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
1378 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
1381 pszBuf[OffsetDst] = '\0';
1382 TRACE("-- %s %u\n", pszBuf, bModifyed);
1387 /*************************************************************************
1388 * PathCanonicalizeW [SHLWAPI.@]
1391 * returnvalue, use CharNext
1393 BOOL WINAPI PathCanonicalizeW(LPWSTR pszBuf, LPCWSTR pszPath)
1395 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = strlenW(pszPath);
1396 BOOL bModifyed = FALSE;
1398 TRACE("%p %s\n", pszBuf, debugstr_w(pszPath));
1400 pszBuf[OffsetDst]='\0';
1402 /* keep the root of the path */
1403 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
1405 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1407 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
1409 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1410 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1411 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
1413 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1414 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
1417 OffsetSrc++; LenSrc--; bModifyed = TRUE;
1419 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
1422 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1427 /* ".\" at the beginning of the path */
1428 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
1430 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1435 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
1437 /* "\.." found, go one deeper */
1438 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
1439 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
1440 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
1441 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
1443 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
1445 /* "\." found, skip it */
1446 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
1450 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
1453 pszBuf[OffsetDst] = '\0';
1454 TRACE("-- %s %u\n", debugstr_w(pszBuf), bModifyed);
1458 /*************************************************************************
1459 * PathFindNextComponentA [SHLWAPI.@]
1464 * aa "" (pointer to traling NULL)
1465 * aa\ "" (pointer to traling NULL)
1466 * aa\\ "" (pointer to traling NULL)
1473 LPSTR WINAPI PathFindNextComponentA(LPCSTR pszPath)
1477 TRACE("%s\n", pszPath);
1479 if(!pszPath || !*pszPath) return NULL;
1480 if(!(pos = StrChrA(pszPath, '\\')))
1481 return (LPSTR) pszPath + strlen(pszPath);
1483 if(pos[0] == '\\') pos++;
1487 /*************************************************************************
1488 * PathFindNextComponentW [SHLWAPI.@]
1490 LPWSTR WINAPI PathFindNextComponentW(LPCWSTR pszPath)
1494 TRACE("%s\n", debugstr_w(pszPath));
1496 if(!pszPath || !*pszPath) return NULL;
1497 if (!(pos = StrChrW(pszPath, '\\')))
1498 return (LPWSTR) pszPath + strlenW(pszPath);
1500 if(pos[0] == '\\') pos++;
1504 /*************************************************************************
1505 * PathAddExtensionA [SHLWAPI.@]
1508 * it adds never a dot
1511 BOOL WINAPI PathAddExtensionA(
1513 LPCSTR pszExtension)
1517 if (*(PathFindExtensionA(pszPath))) return FALSE;
1519 if (!pszExtension || *pszExtension=='\0')
1520 strcat(pszPath, "exe");
1522 strcat(pszPath, pszExtension);
1528 /*************************************************************************
1529 * PathAddExtensionW [SHLWAPI.@]
1531 BOOL WINAPI PathAddExtensionW(
1533 LPCWSTR pszExtension)
1535 static const WCHAR ext[] = { 'e','x','e',0 };
1539 if (*(PathFindExtensionW(pszPath))) return FALSE;
1541 if (!pszExtension || *pszExtension=='\0')
1542 strcatW(pszPath, ext);
1544 strcatW(pszPath, pszExtension);
1550 /*************************************************************************
1551 * PathMakePrettyA [SHLWAPI.@]
1553 BOOL WINAPI PathMakePrettyA(
1556 FIXME("%s\n", lpPath);
1560 /*************************************************************************
1561 * PathMakePrettyW [SHLWAPI.@]
1563 BOOL WINAPI PathMakePrettyW(
1566 FIXME("%s\n", debugstr_w(lpPath));
1571 /*************************************************************************
1572 * PathCommonPrefixA [SHLWAPI.@]
1574 int WINAPI PathCommonPrefixA(
1579 FIXME("%s %s %p\n", pszFile1, pszFile2, achPath);
1583 /*************************************************************************
1584 * PathCommonPrefixW [SHLWAPI.@]
1586 int WINAPI PathCommonPrefixW(
1591 FIXME("%s %s %p\n", debugstr_w(pszFile1), debugstr_w(pszFile2),achPath );
1595 /*************************************************************************
1596 * PathCompactPathA [SHLWAPI.@]
1598 BOOL WINAPI PathCompactPathA(HDC hDC, LPSTR pszPath, UINT dx)
1600 FIXME("0x%08x %s 0x%08x\n", hDC, pszPath, dx);
1604 /*************************************************************************
1605 * PathCompactPathW [SHLWAPI.@]
1607 BOOL WINAPI PathCompactPathW(HDC hDC, LPWSTR pszPath, UINT dx)
1609 FIXME("0x%08x %s 0x%08x\n", hDC, debugstr_w(pszPath), dx);
1613 /*************************************************************************
1614 * PathGetCharTypeA [SHLWAPI.@]
1616 UINT WINAPI PathGetCharTypeA(UCHAR ch)
1622 /*************************************************************************
1623 * PathGetCharTypeW [SHLWAPI.@]
1625 UINT WINAPI PathGetCharTypeW(WCHAR ch)
1631 /*************************************************************************
1632 * PathMakeSystemFolderA [SHLWAPI.@]
1634 BOOL WINAPI PathMakeSystemFolderA(LPCSTR pszPath)
1636 FIXME("%s\n", pszPath);
1640 /*************************************************************************
1641 * PathMakeSystemFolderW [SHLWAPI.@]
1643 BOOL WINAPI PathMakeSystemFolderW(LPCWSTR pszPath)
1645 FIXME("%s\n", debugstr_w(pszPath));
1649 /*************************************************************************
1650 * PathRenameExtensionA [SHLWAPI.@]
1652 BOOL WINAPI PathRenameExtensionA(LPSTR pszPath, LPCSTR pszExt)
1654 FIXME("%s %s\n", pszPath, pszExt);
1658 /*************************************************************************
1659 * PathRenameExtensionW [SHLWAPI.@]
1661 BOOL WINAPI PathRenameExtensionW(LPWSTR pszPath, LPCWSTR pszExt)
1663 FIXME("%s %s\n", debugstr_w(pszPath), debugstr_w(pszExt));
1667 /*************************************************************************
1668 * PathSearchAndQualifyA [SHLWAPI.@]
1670 BOOL WINAPI PathSearchAndQualifyA(
1675 FIXME("%s %s 0x%08x\n", pszPath, pszBuf, cchBuf);
1679 /*************************************************************************
1680 * PathSearchAndQualifyW [SHLWAPI.@]
1682 BOOL WINAPI PathSearchAndQualifyW(
1687 FIXME("%s %s 0x%08x\n", debugstr_w(pszPath), debugstr_w(pszBuf), cchBuf);
1691 /*************************************************************************
1692 * PathSkipRootA [SHLWAPI.@]
1694 LPSTR WINAPI PathSkipRootA(LPCSTR pszPath)
1696 FIXME("%s\n", pszPath);
1697 return (LPSTR)pszPath;
1700 /*************************************************************************
1701 * PathSkipRootW [SHLWAPI.@]
1703 LPWSTR WINAPI PathSkipRootW(LPCWSTR pszPath)
1705 FIXME("%s\n", debugstr_w(pszPath));
1706 return (LPWSTR)pszPath;
1709 /*************************************************************************
1710 * PathCreateFromUrlA [SHLWAPI.@]
1712 HRESULT WINAPI PathCreateFromUrlA(
1718 FIXME("%s %p %p 0x%08lx\n",
1719 pszUrl, pszPath, pcchPath, dwFlags);
1723 /*************************************************************************
1724 * PathCreateFromUrlW [SHLWAPI.@]
1726 HRESULT WINAPI PathCreateFromUrlW(
1732 FIXME("%s %p %p 0x%08lx\n",
1733 debugstr_w(pszUrl), pszPath, pcchPath, dwFlags);
1737 /*************************************************************************
1738 * PathRelativePathToA [SHLWAPI.@]
1740 BOOL WINAPI PathRelativePathToA(
1747 FIXME("%s %s 0x%08lx %s 0x%08lx\n",
1748 pszPath, pszFrom, dwAttrFrom, pszTo, dwAttrTo);
1752 /*************************************************************************
1753 * PathRelativePathToW [SHLWAPI.@]
1755 BOOL WINAPI PathRelativePathToW(
1762 FIXME("%s %s 0x%08lx %s 0x%08lx\n",
1763 debugstr_w(pszPath), debugstr_w(pszFrom), dwAttrFrom, debugstr_w(pszTo), dwAttrTo);
1767 /*************************************************************************
1768 * PathUnmakeSystemFolderA [SHLWAPI.@]
1770 BOOL WINAPI PathUnmakeSystemFolderA(LPCSTR pszPath)
1772 FIXME("%s\n", pszPath);
1776 /*************************************************************************
1777 * PathUnmakeSystemFolderW [SHLWAPI.@]
1779 BOOL WINAPI PathUnmakeSystemFolderW(LPCWSTR pszPath)
1781 FIXME("%s\n", debugstr_w(pszPath));
1786 ########## special ##########
1789 /*************************************************************************
1790 * PathSetDlgItemPathA [SHLWAPI.@]
1793 * use PathCompactPath to make sure, the path fits into the control
1795 BOOL WINAPI PathSetDlgItemPathA(HWND hDlg, int id, LPCSTR pszPath)
1796 { TRACE("%x %x %s\n",hDlg, id, pszPath);
1797 return SetDlgItemTextA(hDlg, id, pszPath);
1800 /*************************************************************************
1801 * PathSetDlgItemPathW [SHLWAPI.@]
1803 BOOL WINAPI PathSetDlgItemPathW(HWND hDlg, int id, LPCWSTR pszPath)
1804 { TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
1805 return SetDlgItemTextW(hDlg, id, pszPath);