9 #include "wine/unicode.h"
10 #include "wine/undocshell.h"
12 #include "debugtools.h"
14 DEFAULT_DEBUG_CHANNEL(shell);
16 #define isSlash(x) ((x)=='\\' || (x)=='/')
18 ########## Combining and Constructing paths ##########
21 /*************************************************************************
22 * PathAppendA [SHLWAPI.@]
25 * concat path lpszPath2 onto lpszPath1
28 * the resulting path is also canonicalized
30 BOOL WINAPI PathAppendA(
34 TRACE("%s %s\n",lpszPath1, lpszPath2);
35 while (lpszPath2[0]=='\\') lpszPath2++;
36 PathCombineA(lpszPath1,lpszPath1,lpszPath2);
40 /*************************************************************************
41 * PathAppendW [SHLWAPI.@]
43 BOOL WINAPI PathAppendW(
47 TRACE("%s %s\n",debugstr_w(lpszPath1), debugstr_w(lpszPath2));
48 while (lpszPath2[0]=='\\') lpszPath2++;
49 PathCombineW(lpszPath1,lpszPath1,lpszPath2);
53 /*************************************************************************
54 * PathCombineA [SHLWAPI.@]
57 * if lpszFile='.' skip it
58 * szDest can be equal to lpszFile. Thats why we use sTemp
61 * the resulting path is also canonicalized
63 LPSTR WINAPI PathCombineA(
69 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, lpszDir, lpszFile, lpszFile);
72 if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
74 strcpy(szDest,lpszDir);
78 /* if lpszFile is a complete path don't care about lpszDir */
79 if (PathGetDriveNumberA(lpszFile) != -1)
81 strcpy(szDest,lpszFile);
83 else if (lpszFile[0] == '\\' )
85 strcpy(sTemp,lpszDir);
86 PathStripToRootA(sTemp);
87 strcat(sTemp,lpszFile);
92 strcpy(sTemp,lpszDir);
93 PathAddBackslashA(sTemp);
94 strcat(sTemp,lpszFile);
100 /*************************************************************************
101 * PathCombineW [SHLWAPI.@]
103 LPWSTR WINAPI PathCombineW(
108 WCHAR sTemp[MAX_PATH];
109 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, debugstr_w(lpszDir),
110 lpszFile, debugstr_w(lpszFile));
113 if (!lpszFile || !lpszFile[0] || (lpszFile[0]==(WCHAR)'.' && !lpszFile[1]) )
115 strcpyW(szDest,lpszDir);
119 /* if lpszFile is a complete path don't care about lpszDir */
120 if (PathGetDriveNumberW(lpszFile) != -1)
122 strcpyW(szDest,lpszFile);
124 else if (lpszFile[0] == (WCHAR)'\\' )
126 strcpyW(sTemp,lpszDir);
127 PathStripToRootW(sTemp);
128 strcatW(sTemp,lpszFile);
129 strcpyW(szDest,sTemp);
133 strcpyW(sTemp,lpszDir);
134 PathAddBackslashW(sTemp);
135 strcatW(sTemp,lpszFile);
136 strcpyW(szDest,sTemp);
141 /*************************************************************************
142 * PathAddBackslashA [SHLWAPI.@]
145 * append \ if there is none
147 LPSTR WINAPI PathAddBackslashA(LPSTR lpszPath)
150 TRACE("%p->%s\n",lpszPath,lpszPath);
152 len = strlen(lpszPath);
153 if (len && lpszPath[len-1]!='\\')
155 lpszPath[len] = '\\';
156 lpszPath[len+1]= 0x00;
157 return lpszPath+len+1;
162 /*************************************************************************
163 * PathAddBackslashW [SHLWAPI.@]
165 LPWSTR WINAPI PathAddBackslashW(LPWSTR lpszPath)
168 TRACE("%p->%s\n",lpszPath,debugstr_w(lpszPath));
170 len = strlenW(lpszPath);
171 if (len && lpszPath[len-1]!=(WCHAR)'\\')
173 lpszPath[len] = (WCHAR)'\\';
174 lpszPath[len+1]= 0x00;
175 return lpszPath+len+1;
180 /*************************************************************************
181 * PathBuildRootA [SHLWAPI.@]
183 LPSTR WINAPI PathBuildRootA(LPSTR lpszPath, int drive)
185 TRACE("%p %i\n",lpszPath, drive);
187 strcpy(lpszPath,"A:\\");
192 /*************************************************************************
193 * PathBuildRootW [SHLWAPI.@]
195 LPWSTR WINAPI PathBuildRootW(LPWSTR lpszPath, int drive)
197 TRACE("%p %i\n",debugstr_w(lpszPath), drive);
199 lstrcpyAtoW(lpszPath,"A:\\");
205 Extracting Component Parts
208 /*************************************************************************
209 * PathFindFileNameA [SHLWAPI.@]
211 LPSTR WINAPI PathFindFileNameA(LPCSTR lpszPath)
213 LPCSTR lastSlash = lpszPath;
215 TRACE("%s\n",lpszPath);
218 if ( isSlash(lpszPath[0]) && lpszPath[1])
219 lastSlash = lpszPath+1;
220 lpszPath = CharNextA(lpszPath);
222 return (LPSTR)lastSlash;
226 /*************************************************************************
227 * PathFindFileNameW [SHLWAPI.@]
229 LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
234 TRACE("%s\n",debugstr_w(wslash));
237 if (((lpszPath[0]=='\\') || (lpszPath[0]==':')) && lpszPath[1] && lpszPath[1]!='\\')
239 lpszPath = CharNextW(lpszPath);
241 return (LPWSTR)wslash;
244 /*************************************************************************
245 * PathFindExtensionA [SHLWAPI.@]
248 * returns pointer to last . in last lpszPath component or at \0.
251 LPSTR WINAPI PathFindExtensionA(LPCSTR lpszPath)
253 LPCSTR lastpoint = NULL;
255 TRACE("%p %s\n",lpszPath,lpszPath);
259 if (*lpszPath=='\\'||*lpszPath==' ')
263 lpszPath = CharNextA(lpszPath);
265 return (LPSTR)(lastpoint?lastpoint:lpszPath);
268 /*************************************************************************
269 * PathFindExtensionW [SHLWAPI.@]
271 LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
273 LPCWSTR lastpoint = NULL;
275 TRACE("(%p %s)\n",lpszPath,debugstr_w(lpszPath));
279 if (*lpszPath==(WCHAR)'\\'||*lpszPath==(WCHAR)' ')
281 if (*lpszPath==(WCHAR)'.')
283 lpszPath = CharNextW(lpszPath);
285 return (LPWSTR)(lastpoint?lastpoint:lpszPath);
288 /*************************************************************************
289 * PathGetArgsA [SHLWAPI.@]
292 * look for next arg in string. handle "quoted" strings
293 * returns pointer to argument *AFTER* the space. Or to the \0.
298 LPSTR WINAPI PathGetArgsA(LPCSTR lpszPath)
302 TRACE("%s\n",lpszPath);
306 if ((*lpszPath==' ') && !qflag)
307 return (LPSTR)lpszPath+1;
310 lpszPath = CharNextA(lpszPath);
312 return (LPSTR)lpszPath;
315 /*************************************************************************
316 * PathGetArgsW [SHLWAPI.@]
318 LPWSTR WINAPI PathGetArgsW(LPCWSTR lpszPath)
322 TRACE("%s\n",debugstr_w(lpszPath));
326 if ((*lpszPath==' ') && !qflag)
327 return (LPWSTR)lpszPath+1;
330 lpszPath = CharNextW(lpszPath);
332 return (LPWSTR)lpszPath;
335 /*************************************************************************
336 * PathGetDriveNumberA [SHLWAPI.@]
338 int WINAPI PathGetDriveNumberA(LPCSTR lpszPath)
340 int chr = tolower(lpszPath[0]);
342 TRACE ("%s\n",debugstr_a(lpszPath));
344 if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
345 return tolower(lpszPath[0]) - 'a' ;
348 /*************************************************************************
349 * PathGetDriveNumberW [SHLWAPI.@]
351 int WINAPI PathGetDriveNumberW(LPCWSTR lpszPath)
353 int chr = tolowerW(lpszPath[0]);
355 TRACE ("%s\n",debugstr_w(lpszPath));
357 if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
358 return tolowerW(lpszPath[0]) - 'a' ;
361 /*************************************************************************
362 * PathRemoveFileSpecA [SHLWAPI.@]
365 * truncates passed argument to a valid path
366 * returns if the string was modified or not.
367 * "\foo\xx\foo"-> "\foo\xx"
371 BOOL WINAPI PathRemoveFileSpecA(LPSTR lpszPath)
373 LPSTR cutplace = lpszPath;
376 TRACE("%s\n",lpszPath);
380 while (*lpszPath == '\\') cutplace = ++lpszPath;
384 if(lpszPath[0] == '\\') cutplace = lpszPath;
386 if(lpszPath[0] == ':')
388 cutplace = lpszPath + 1;
389 if (lpszPath[1] == '\\') cutplace++;
392 lpszPath = CharNextA(lpszPath);
393 if (!lpszPath) break;
396 ret = (*cutplace!='\0');
402 /*************************************************************************
403 * PathRemoveFileSpecW [SHLWAPI.@]
405 BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
407 LPWSTR cutplace = lpszPath;
410 TRACE("%s\n",debugstr_w(lpszPath));
414 while (*lpszPath == '\\') cutplace = ++lpszPath;
418 if(lpszPath[0] == '\\') cutplace = lpszPath;
420 if(lpszPath[0] == ':')
422 cutplace = lpszPath + 1;
423 if (lpszPath[1] == '\\') cutplace++;
426 lpszPath = CharNextW(lpszPath);
427 if (!lpszPath) break;
430 ret = (*cutplace!='\0');
436 /*************************************************************************
437 * PathStripPathA [SHELLWAPI.@]
440 * removes the path from the beginning of a filename
442 void WINAPI PathStripPathA(LPSTR lpszPath)
444 LPSTR lpszFileName = PathFindFileNameA(lpszPath);
446 TRACE("%s\n", lpszPath);
449 RtlMoveMemory(lpszPath, lpszFileName, strlen(lpszFileName)+1);
452 /*************************************************************************
453 * PathStripPathW [SHELLWAPI.@]
455 void WINAPI PathStripPathW(LPWSTR lpszPath)
457 LPWSTR lpszFileName = PathFindFileNameW(lpszPath);
459 TRACE("%s\n", debugstr_w(lpszPath));
461 RtlMoveMemory(lpszPath, lpszFileName, (strlenW(lpszFileName)+1)*sizeof(WCHAR));
464 /*************************************************************************
465 * PathStripToRootA [SHLWAPI.@]
467 BOOL WINAPI PathStripToRootA(LPSTR lpszPath)
469 TRACE("%s\n", lpszPath);
471 if (!lpszPath) return FALSE;
472 while(!PathIsRootA(lpszPath))
473 if (!PathRemoveFileSpecA(lpszPath)) return FALSE;
477 /*************************************************************************
478 * PathStripToRootW [SHLWAPI.@]
480 BOOL WINAPI PathStripToRootW(LPWSTR lpszPath)
482 TRACE("%s\n", debugstr_w(lpszPath));
484 if (!lpszPath) return FALSE;
485 while(!PathIsRootW(lpszPath))
486 if (!PathRemoveFileSpecW(lpszPath)) return FALSE;
490 /*************************************************************************
491 * PathRemoveArgsA [SHLWAPI.@]
494 void WINAPI PathRemoveArgsA(LPSTR lpszPath)
496 TRACE("%s\n",lpszPath);
500 LPSTR lpszArgs = PathGetArgsA(lpszPath);
503 LPSTR lpszLastChar = CharPrevA(lpszPath, lpszArgs);
504 if(*lpszLastChar==' ') *lpszLastChar = '\0';
509 /*************************************************************************
510 * PathRemoveArgsW [SHLWAPI.@]
512 void WINAPI PathRemoveArgsW(LPWSTR lpszPath)
514 TRACE("%s\n", debugstr_w(lpszPath));
518 LPWSTR lpszArgs = PathGetArgsW(lpszPath);
521 LPWSTR lpszLastChar = CharPrevW(lpszPath, lpszArgs);
522 if(*lpszLastChar==' ') *lpszLastChar = '\0';
527 /*************************************************************************
528 * PathRemoveExtensionA [SHLWAPI.@]
530 void WINAPI PathRemoveExtensionA(LPSTR lpszPath)
532 LPSTR lpszExtension = PathFindExtensionA(lpszPath);
534 TRACE("%s\n", lpszPath);
536 if (lpszExtension) *lpszExtension='\0';
539 /*************************************************************************
540 * PathRemoveExtensionW [SHLWAPI.@]
542 void WINAPI PathRemoveExtensionW(LPWSTR lpszPath)
544 LPWSTR lpszExtension = PathFindExtensionW(lpszPath);
546 TRACE("%s\n", debugstr_w(lpszPath));
548 if (lpszExtension) *lpszExtension='\0';
551 /*************************************************************************
552 * PathRemoveBackslashA [SHLWAPI.@]
554 * If the path ends in a backslash it is replaced by a NULL
555 * and the address of the NULL is returned
557 * the address of the last character is returned.
560 * "c:\": keep backslash
562 LPSTR WINAPI PathRemoveBackslashA( LPSTR lpszPath )
569 len = strlen(lpszPath);
570 szTemp = CharPrevA(lpszPath, lpszPath+len);
571 if (! PathIsRootA(lpszPath))
573 if (*szTemp == '\\') *szTemp = '\0';
579 /*************************************************************************
580 * PathRemoveBackslashW [SHLWAPI.@]
582 LPWSTR WINAPI PathRemoveBackslashW( LPWSTR lpszPath )
585 LPWSTR szTemp = NULL;
589 len = strlenW(lpszPath);
590 szTemp = CharPrevW(lpszPath, lpszPath+len);
591 if (! PathIsRootW(lpszPath))
593 if (*szTemp == '\\') *szTemp = '\0';
604 /*************************************************************************
605 * PathRemoveBlanksA [SHLWAPI.@]
608 * remove spaces from beginning and end of passed string
610 void WINAPI PathRemoveBlanksA(LPSTR str)
618 while (*x==' ') x = CharNextA(x);
619 if (x!=str) strcpy(str,x);
621 while (*x==' ') x = CharPrevA(str, x);
622 if (*x==' ') *x='\0';
626 /*************************************************************************
627 * PathRemoveBlanksW [SHLWAPI.@]
629 void WINAPI PathRemoveBlanksW(LPWSTR str)
633 TRACE("%s\n",debugstr_w(str));
637 while (*x==' ') x = CharNextW(x);
638 if (x!=str) strcpyW(str,x);
639 x=str+strlenW(str)-1;
640 while (*x==' ') x = CharPrevW(str, x);
641 if (*x==' ') *x='\0';
645 /*************************************************************************
646 * PathQuoteSpacesA [SHLWAPI.@]
649 LPSTR WINAPI PathQuoteSpacesA(LPSTR lpszPath)
651 TRACE("%s\n",lpszPath);
653 if(StrChrA(lpszPath,' '))
655 int len = strlen(lpszPath);
656 RtlMoveMemory(lpszPath+1, lpszPath, len);
666 /*************************************************************************
667 * PathQuoteSpacesW [SHLWAPI.@]
669 LPWSTR WINAPI PathQuoteSpacesW(LPWSTR lpszPath)
671 TRACE("%s\n",debugstr_w(lpszPath));
673 if(StrChrW(lpszPath,' '))
675 int len = strlenW(lpszPath);
676 RtlMoveMemory(lpszPath+1, lpszPath, len*sizeof(WCHAR));
686 /*************************************************************************
687 * PathUnquoteSpacesA [SHLWAPI.@]
690 * unquote string (remove ")
692 VOID WINAPI PathUnquoteSpacesA(LPSTR str)
694 DWORD len = strlen(str);
707 /*************************************************************************
708 * PathUnquoteSpacesW [SHLWAPI.@]
710 VOID WINAPI PathUnquoteSpacesW(LPWSTR str)
712 DWORD len = strlenW(str);
714 TRACE("%s\n",debugstr_w(str));
725 /*************************************************************************
726 * PathParseIconLocationA [SHLWAPI.@]
728 int WINAPI PathParseIconLocationA(LPSTR lpszPath)
730 LPSTR lpstrComma = strchr(lpszPath, ',');
732 FIXME("%s stub\n", debugstr_a(lpszPath));
734 if (lpstrComma && lpstrComma[1])
737 /* return atoi(&lpstrComma[1]); FIXME */
740 PathUnquoteSpacesA(lpszPath);
744 /*************************************************************************
745 * PathParseIconLocationW [SHLWAPI.@]
747 int WINAPI PathParseIconLocationW(LPWSTR lpszPath)
749 LPWSTR lpstrComma = strchrW(lpszPath, ',');
751 FIXME("%s stub\n", debugstr_w(lpszPath));
753 if (lpstrComma && lpstrComma[1])
756 /* return _wtoi(&lpstrComma[1]); FIXME */
758 PathUnquoteSpacesW(lpszPath);
763 ########## cleaning and resolving paths ##########
766 /*************************************************************************
767 * PathFindOnPathA [SHLWAPI.@]
769 BOOL WINAPI PathFindOnPathA(LPSTR sFile, LPCSTR sOtherDirs)
771 FIXME("%s %s\n",sFile, sOtherDirs);
775 /*************************************************************************
776 * PathFindOnPathW [SHLWAPI.@]
778 BOOL WINAPI PathFindOnPathW(LPWSTR sFile, LPCWSTR sOtherDirs)
780 FIXME("%s %s\n",debugstr_w(sFile), debugstr_w(sOtherDirs));
784 /*************************************************************************
785 * PathCompactPathExA [SHLWAPI.@]
787 BOOL WINAPI PathCompactPathExA(
793 FIXME("%p %s 0x%08x 0x%08lx\n", pszOut, pszSrc, cchMax, dwFlags);
797 /*************************************************************************
798 * PathCompactPathExW [SHLWAPI.@]
800 BOOL WINAPI PathCompactPathExW(
806 FIXME("%p %s 0x%08x 0x%08lx\n", pszOut, debugstr_w(pszSrc), cchMax, dwFlags);
811 ########## Path Testing ##########
814 /*************************************************************************
815 * PathIsUNCA [SHLWAPI.@]
818 * PathIsUNC(char*path);
820 BOOL WINAPI PathIsUNCA(LPCSTR lpszPath)
822 TRACE("%s\n",lpszPath);
824 return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
827 /*************************************************************************
828 * PathIsUNCW [SHLWAPI.@]
830 BOOL WINAPI PathIsUNCW(LPCWSTR lpszPath)
832 TRACE("%s\n",debugstr_w(lpszPath));
834 return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
837 /*************************************************************************
838 * PathIsRelativeA [SHLWAPI.@]
840 BOOL WINAPI PathIsRelativeA (LPCSTR lpszPath)
842 TRACE("lpszPath=%s\n",lpszPath);
844 return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
847 /*************************************************************************
848 * PathIsRelativeW [SHLWAPI.@]
850 BOOL WINAPI PathIsRelativeW (LPCWSTR lpszPath)
852 TRACE("lpszPath=%s\n",debugstr_w(lpszPath));
854 return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
857 /*************************************************************************
858 * PathIsRootA [SHLWAPI.@]
861 * TRUE if the path points to a root directory
863 BOOL WINAPI PathIsRootA(LPCSTR lpszPath)
865 TRACE("%s\n",lpszPath);
868 if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
872 if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
875 /* UNC "\\<computer>\<share>" */
876 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
878 int foundbackslash = 0;
882 if (*lpszPath=='\\') foundbackslash++;
883 lpszPath = CharNextA(lpszPath);
885 if (foundbackslash <= 1)
891 /*************************************************************************
892 * PathIsRootW [SHLWAPI.@]
894 BOOL WINAPI PathIsRootW(LPCWSTR lpszPath)
896 TRACE("%s\n",debugstr_w(lpszPath));
899 if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
903 if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
906 /* UNC "\\<computer>\<share>" */
907 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
909 int foundbackslash = 0;
913 if (*lpszPath=='\\') foundbackslash++;
914 lpszPath = CharNextW(lpszPath);
916 if (foundbackslash <= 1)
923 /*************************************************************************
924 * PathIsDirectoryA [SHLWAPI.@]
926 BOOL WINAPI PathIsDirectoryA(LPCSTR lpszPath)
930 TRACE("%s\n", debugstr_a(lpszPath));
932 dwAttr = GetFileAttributesA(lpszPath);
933 return (dwAttr != -1) ? dwAttr & FILE_ATTRIBUTE_DIRECTORY : 0;
936 /*************************************************************************
937 * PathIsDirectoryW [SHLWAPI.@]
939 BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
943 TRACE("%s\n", debugstr_w(lpszPath));
945 dwAttr = GetFileAttributesW(lpszPath);
946 return (dwAttr != -1) ? dwAttr & FILE_ATTRIBUTE_DIRECTORY : 0;
949 /*************************************************************************
950 * PathFileExistsA [SHLWAPI.@]
953 * file_exists(char *fn);
955 BOOL WINAPI PathFileExistsA(LPCSTR lpszPath)
957 TRACE("%s\n",lpszPath);
958 return (GetFileAttributesA(lpszPath)!=-1);
961 /*************************************************************************
962 * PathFileExistsW [SHLWAPI.@]
964 BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
966 TRACE("%s\n",debugstr_w(lpszPath));
967 return (GetFileAttributesW(lpszPath)!=-1);
970 /*************************************************************************
971 * PathMatchSingleMaskA [internal]
974 * internal (used by PathMatchSpec)
976 static BOOL PathMatchSingleMaskA(LPCSTR name, LPCSTR mask)
978 while (*name && *mask && *mask!=';')
984 if (PathMatchSingleMaskA(name,mask+1)) return 1; /* try substrings */
988 if (toupper(*mask)!=toupper(*name) && *mask!='?') return 0;
989 name = CharNextA(name);
990 mask = CharNextA(mask);
994 while (*mask=='*') mask++;
995 if (!*mask || *mask==';') return 1;
1000 /*************************************************************************
1001 * PathMatchSingleMaskW [internal]
1003 static BOOL PathMatchSingleMaskW(LPCWSTR name, LPCWSTR mask)
1005 while (*name && *mask && *mask!=';')
1011 if (PathMatchSingleMaskW(name,mask+1)) return 1; /* try substrings */
1015 if (toupperW(*mask)!=toupperW(*name) && *mask!='?') return 0;
1016 name = CharNextW(name);
1017 mask = CharNextW(mask);
1021 while (*mask=='*') mask++;
1022 if (!*mask || *mask==';') return 1;
1026 /*************************************************************************
1027 * PathMatchSpecA [SHLWAPI.@]
1030 * used from COMDLG32
1032 BOOL WINAPI PathMatchSpecA(LPCSTR name, LPCSTR mask)
1034 TRACE("%s %s\n",name,mask);
1036 if (!lstrcmpA( mask, "*.*" )) return 1; /* we don't require a period */
1040 if (PathMatchSingleMaskA(name,mask)) return 1; /* helper function */
1041 while (*mask && *mask!=';') mask = CharNextA(mask);
1045 while (*mask==' ') mask++; /* masks may be separated by "; " */
1051 /*************************************************************************
1052 * PathMatchSpecW [SHLWAPI.@]
1054 BOOL WINAPI PathMatchSpecW(LPCWSTR name, LPCWSTR mask)
1057 TRACE("%s %s\n",debugstr_w(name),debugstr_w(mask));
1059 lstrcpyAtoW(stemp,"*.*");
1060 if (!lstrcmpW( mask, stemp )) return 1; /* we don't require a period */
1064 if (PathMatchSingleMaskW(name,mask)) return 1; /* helper function */
1065 while (*mask && *mask!=';') mask = CharNextW(mask);
1069 while (*mask==' ') mask++; /* masks may be separated by "; " */
1075 /*************************************************************************
1076 * PathIsSameRootA [SHLWAPI.@]
1079 * what to do with "\path" ??
1081 BOOL WINAPI PathIsSameRootA(LPCSTR lpszPath1, LPCSTR lpszPath2)
1083 TRACE("%s %s\n", lpszPath1, lpszPath2);
1085 if (PathIsRelativeA(lpszPath1) || PathIsRelativeA(lpszPath2)) return FALSE;
1088 if ( toupper(lpszPath1[0])==toupper(lpszPath2[0]) &&
1089 lpszPath1[1]==':' && lpszPath2[1]==':' &&
1090 lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
1094 if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
1095 lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
1097 int pos=2, bsfound=0;
1098 while (lpszPath1[pos] && lpszPath2[pos] &&
1099 (lpszPath1[pos] == lpszPath2[pos]))
1101 if (lpszPath1[pos]=='\\') bsfound++;
1102 if (bsfound == 2) return TRUE;
1103 pos++; /* fixme: use CharNext*/
1105 return (lpszPath1[pos] == lpszPath2[pos]);
1110 /*************************************************************************
1111 * PathIsSameRootW [SHLWAPI.@]
1113 BOOL WINAPI PathIsSameRootW(LPCWSTR lpszPath1, LPCWSTR lpszPath2)
1115 TRACE("%s %s\n", debugstr_w(lpszPath1), debugstr_w(lpszPath2));
1117 if (PathIsRelativeW(lpszPath1) || PathIsRelativeW(lpszPath2)) return FALSE;
1120 if ( toupperW(lpszPath1[0])==toupperW(lpszPath2[0]) &&
1121 lpszPath1[1]==':' && lpszPath2[1]==':' &&
1122 lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
1126 if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
1127 lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
1129 int pos=2, bsfound=0;
1130 while (lpszPath1[pos] && lpszPath2[pos] &&
1131 (lpszPath1[pos] == lpszPath2[pos]))
1133 if (lpszPath1[pos]=='\\') bsfound++;
1134 if (bsfound == 2) return TRUE;
1135 pos++;/* fixme: use CharNext*/
1137 return (lpszPath1[pos] == lpszPath2[pos]);
1142 /*************************************************************************
1145 BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
1149 static LPSTR SupportedProtocol[] =
1150 {"http","https","ftp","gopher","file","mailto",NULL};
1152 if(!lpstrPath) return FALSE;
1155 lpstrRes = strchr(lpstrPath,':');
1156 if(!lpstrRes) return FALSE;
1157 iSize = lpstrRes - lpstrPath;
1159 while(SupportedProtocol[i])
1161 if (iSize == strlen(SupportedProtocol[i]))
1162 if(!strncasecmp(lpstrPath, SupportedProtocol[i], iSize))
1170 /*************************************************************************
1173 BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
1177 static WCHAR SupportedProtocol[7][7] =
1178 {{'h','t','t','p','\0'},{'h','t','t','p','s','\0'},{'f','t','p','\0'},
1179 {'g','o','p','h','e','r','\0'},{'f','i','l','e','\0'},
1180 {'m','a','i','l','t','o','\0'},{0}};
1182 if(!lpstrPath) return FALSE;
1185 lpstrRes = strchrW(lpstrPath,':');
1186 if(!lpstrRes) return FALSE;
1187 iSize = lpstrRes - lpstrPath;
1189 while(SupportedProtocol[i])
1191 if (iSize == strlenW(SupportedProtocol[i]))
1192 if(!strncmpiW(lpstrPath, SupportedProtocol[i], iSize))
1201 /*************************************************************************
1202 * PathIsContentTypeA [SHLWAPI.@]
1204 BOOL WINAPI PathIsContentTypeA(LPCSTR pszPath, LPCSTR pszContentType)
1206 FIXME("%s %s\n", pszPath, pszContentType);
1210 /*************************************************************************
1211 * PathIsContentTypeW [SHLWAPI.@]
1213 BOOL WINAPI PathIsContentTypeW(LPCWSTR pszPath, LPCWSTR pszContentType)
1215 FIXME("%s %s\n", debugstr_w(pszPath), debugstr_w(pszContentType));
1219 /*************************************************************************
1220 * PathIsFileSpecA [SHLWAPI.@]
1222 BOOL WINAPI PathIsFileSpecA(LPCSTR pszPath)
1224 FIXME("%s\n", pszPath);
1228 /*************************************************************************
1229 * PathIsFileSpecW [SHLWAPI.@]
1231 BOOL WINAPI PathIsFileSpecW(LPCWSTR pszPath)
1233 FIXME("%s\n", debugstr_w(pszPath));
1237 /*************************************************************************
1238 * PathIsPrefixA [SHLWAPI.@]
1240 BOOL WINAPI PathIsPrefixA(LPCSTR pszPrefix, LPCSTR pszPath)
1242 FIXME("%s %s\n", pszPrefix, pszPath);
1246 /*************************************************************************
1247 * PathIsPrefixW [SHLWAPI.@]
1249 BOOL WINAPI PathIsPrefixW(LPCWSTR pszPrefix, LPCWSTR pszPath)
1251 FIXME("%s %s\n", debugstr_w(pszPrefix), debugstr_w(pszPath));
1255 /*************************************************************************
1256 * PathIsSystemFolderA [SHLWAPI.@]
1258 BOOL WINAPI PathIsSystemFolderA(LPCSTR pszPath, DWORD dwAttrb)
1260 FIXME("%s 0x%08lx\n", pszPath, dwAttrb);
1264 /*************************************************************************
1265 * PathIsSystemFolderW [SHLWAPI.@]
1267 BOOL WINAPI PathIsSystemFolderW(LPCWSTR pszPath, DWORD dwAttrb)
1269 FIXME("%s 0x%08lx\n", debugstr_w(pszPath), dwAttrb);
1273 /*************************************************************************
1274 * PathIsUNCServerA [SHLWAPI.@]
1276 BOOL WINAPI PathIsUNCServerA(
1279 FIXME("%s\n", pszPath);
1283 /*************************************************************************
1284 * PathIsUNCServerW [SHLWAPI.@]
1286 BOOL WINAPI PathIsUNCServerW(
1289 FIXME("%s\n", debugstr_w(pszPath));
1293 /*************************************************************************
1294 * PathIsUNCServerShareA [SHLWAPI.@]
1296 BOOL WINAPI PathIsUNCServerShareA(
1299 FIXME("%s\n", pszPath);
1303 /*************************************************************************
1304 * PathIsUNCServerShareW [SHLWAPI.@]
1306 BOOL WINAPI PathIsUNCServerShareW(
1309 FIXME("%s\n", debugstr_w(pszPath));
1313 /*************************************************************************
1314 * PathCanonicalizeA [SHLWAPI.@]
1317 * returnvalue, use CharNext
1320 BOOL WINAPI PathCanonicalizeA(LPSTR pszBuf, LPCSTR pszPath)
1322 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = strlen(pszPath);
1323 BOOL bModifyed = FALSE;
1325 TRACE("%p %s\n", pszBuf, pszPath);
1327 pszBuf[OffsetDst]='\0';
1329 /* keep the root of the path */
1330 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
1332 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1334 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
1336 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1337 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1338 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
1340 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1341 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
1344 OffsetSrc++; LenSrc--; bModifyed = TRUE;
1346 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
1349 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1354 /* ".\" at the beginning of the path */
1355 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
1357 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1362 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
1364 /* "\.." found, go one deeper */
1365 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
1366 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
1367 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
1368 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
1370 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
1372 /* "\." found, skip it */
1373 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
1377 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
1380 pszBuf[OffsetDst] = '\0';
1381 TRACE("-- %s %u\n", pszBuf, bModifyed);
1386 /*************************************************************************
1387 * PathCanonicalizeW [SHLWAPI.@]
1390 * returnvalue, use CharNext
1392 BOOL WINAPI PathCanonicalizeW(LPWSTR pszBuf, LPCWSTR pszPath)
1394 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = strlenW(pszPath);
1395 BOOL bModifyed = FALSE;
1397 TRACE("%p %s\n", pszBuf, debugstr_w(pszPath));
1399 pszBuf[OffsetDst]='\0';
1401 /* keep the root of the path */
1402 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
1404 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1406 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
1408 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1409 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1410 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
1412 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1413 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
1416 OffsetSrc++; LenSrc--; bModifyed = TRUE;
1418 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
1421 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1426 /* ".\" at the beginning of the path */
1427 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
1429 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1434 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
1436 /* "\.." found, go one deeper */
1437 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
1438 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
1439 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
1440 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
1442 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
1444 /* "\." found, skip it */
1445 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
1449 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
1452 pszBuf[OffsetDst] = '\0';
1453 TRACE("-- %s %u\n", debugstr_w(pszBuf), bModifyed);
1457 /*************************************************************************
1458 * PathFindNextComponentA [SHLWAPI.@]
1463 * aa "" (pointer to traling NULL)
1464 * aa\ "" (pointer to traling NULL)
1465 * aa\\ "" (pointer to traling NULL)
1472 LPSTR WINAPI PathFindNextComponentA(LPCSTR pszPath)
1476 TRACE("%s\n", pszPath);
1478 if(!pszPath || !*pszPath) return NULL;
1479 if(!(pos = StrChrA(pszPath, '\\')))
1480 return (LPSTR) pszPath + strlen(pszPath);
1482 if(pos[0] == '\\') pos++;
1486 /*************************************************************************
1487 * PathFindNextComponentW [SHLWAPI.@]
1489 LPWSTR WINAPI PathFindNextComponentW(LPCWSTR pszPath)
1493 TRACE("%s\n", debugstr_w(pszPath));
1495 if(!pszPath || !*pszPath) return NULL;
1496 if (!(pos = StrChrW(pszPath, '\\')))
1497 return (LPWSTR) pszPath + strlenW(pszPath);
1499 if(pos[0] == '\\') pos++;
1503 /*************************************************************************
1504 * PathAddExtensionA [SHLWAPI.@]
1507 * it adds never a dot
1510 BOOL WINAPI PathAddExtensionA(
1512 LPCSTR pszExtension)
1516 if (*(PathFindExtensionA(pszPath))) return FALSE;
1518 if (!pszExtension || *pszExtension=='\0')
1519 strcat(pszPath, "exe");
1521 strcat(pszPath, pszExtension);
1527 /*************************************************************************
1528 * PathAddExtensionW [SHLWAPI.@]
1530 BOOL WINAPI PathAddExtensionW(
1532 LPCWSTR pszExtension)
1534 static const WCHAR ext[] = { 'e','x','e',0 };
1538 if (*(PathFindExtensionW(pszPath))) return FALSE;
1540 if (!pszExtension || *pszExtension=='\0')
1541 strcatW(pszPath, ext);
1543 strcatW(pszPath, pszExtension);
1549 /*************************************************************************
1550 * PathMakePrettyA [SHLWAPI.@]
1552 BOOL WINAPI PathMakePrettyA(
1555 FIXME("%s\n", lpPath);
1559 /*************************************************************************
1560 * PathMakePrettyW [SHLWAPI.@]
1562 BOOL WINAPI PathMakePrettyW(
1565 FIXME("%s\n", debugstr_w(lpPath));
1570 /*************************************************************************
1571 * PathCommonPrefixA [SHLWAPI.@]
1573 int WINAPI PathCommonPrefixA(
1578 FIXME("%s %s %p\n", pszFile1, pszFile2, achPath);
1582 /*************************************************************************
1583 * PathCommonPrefixW [SHLWAPI.@]
1585 int WINAPI PathCommonPrefixW(
1590 FIXME("%s %s %p\n", debugstr_w(pszFile1), debugstr_w(pszFile2),achPath );
1594 /*************************************************************************
1595 * PathCompactPathA [SHLWAPI.@]
1597 BOOL WINAPI PathCompactPathA(HDC hDC, LPSTR pszPath, UINT dx)
1599 FIXME("0x%08x %s 0x%08x\n", hDC, pszPath, dx);
1603 /*************************************************************************
1604 * PathCompactPathW [SHLWAPI.@]
1606 BOOL WINAPI PathCompactPathW(HDC hDC, LPWSTR pszPath, UINT dx)
1608 FIXME("0x%08x %s 0x%08x\n", hDC, debugstr_w(pszPath), dx);
1612 /*************************************************************************
1613 * PathGetCharTypeA [SHLWAPI.@]
1615 UINT WINAPI PathGetCharTypeA(UCHAR ch)
1621 /*************************************************************************
1622 * PathGetCharTypeW [SHLWAPI.@]
1624 UINT WINAPI PathGetCharTypeW(WCHAR ch)
1630 /*************************************************************************
1631 * PathMakeSystemFolderA [SHLWAPI.@]
1633 BOOL WINAPI PathMakeSystemFolderA(LPCSTR pszPath)
1635 FIXME("%s\n", pszPath);
1639 /*************************************************************************
1640 * PathMakeSystemFolderW [SHLWAPI.@]
1642 BOOL WINAPI PathMakeSystemFolderW(LPCWSTR pszPath)
1644 FIXME("%s\n", debugstr_w(pszPath));
1648 /*************************************************************************
1649 * PathRenameExtensionA [SHLWAPI.@]
1651 BOOL WINAPI PathRenameExtensionA(LPSTR pszPath, LPCSTR pszExt)
1653 FIXME("%s %s\n", pszPath, pszExt);
1657 /*************************************************************************
1658 * PathRenameExtensionW [SHLWAPI.@]
1660 BOOL WINAPI PathRenameExtensionW(LPWSTR pszPath, LPCWSTR pszExt)
1662 FIXME("%s %s\n", debugstr_w(pszPath), debugstr_w(pszExt));
1666 /*************************************************************************
1667 * PathSearchAndQualifyA [SHLWAPI.@]
1669 BOOL WINAPI PathSearchAndQualifyA(
1674 FIXME("%s %s 0x%08x\n", pszPath, pszBuf, cchBuf);
1678 /*************************************************************************
1679 * PathSearchAndQualifyW [SHLWAPI.@]
1681 BOOL WINAPI PathSearchAndQualifyW(
1686 FIXME("%s %s 0x%08x\n", debugstr_w(pszPath), debugstr_w(pszBuf), cchBuf);
1690 /*************************************************************************
1691 * PathSkipRootA [SHLWAPI.@]
1693 LPSTR WINAPI PathSkipRootA(LPCSTR pszPath)
1695 FIXME("%s\n", pszPath);
1696 return (LPSTR)pszPath;
1699 /*************************************************************************
1700 * PathSkipRootW [SHLWAPI.@]
1702 LPWSTR WINAPI PathSkipRootW(LPCWSTR pszPath)
1704 FIXME("%s\n", debugstr_w(pszPath));
1705 return (LPWSTR)pszPath;
1708 /*************************************************************************
1709 * PathCreateFromUrlA [SHLWAPI.@]
1711 HRESULT WINAPI PathCreateFromUrlA(
1717 FIXME("%s %p %p 0x%08lx\n",
1718 pszUrl, pszPath, pcchPath, dwFlags);
1722 /*************************************************************************
1723 * PathCreateFromUrlW [SHLWAPI.@]
1725 HRESULT WINAPI PathCreateFromUrlW(
1731 FIXME("%s %p %p 0x%08lx\n",
1732 debugstr_w(pszUrl), pszPath, pcchPath, dwFlags);
1736 /*************************************************************************
1737 * PathRelativePathToA [SHLWAPI.@]
1739 BOOL WINAPI PathRelativePathToA(
1746 FIXME("%s %s 0x%08lx %s 0x%08lx\n",
1747 pszPath, pszFrom, dwAttrFrom, pszTo, dwAttrTo);
1751 /*************************************************************************
1752 * PathRelativePathToW [SHLWAPI.@]
1754 BOOL WINAPI PathRelativePathToW(
1761 FIXME("%s %s 0x%08lx %s 0x%08lx\n",
1762 debugstr_w(pszPath), debugstr_w(pszFrom), dwAttrFrom, debugstr_w(pszTo), dwAttrTo);
1766 /*************************************************************************
1767 * PathUnmakeSystemFolderA [SHLWAPI.@]
1769 BOOL WINAPI PathUnmakeSystemFolderA(LPCSTR pszPath)
1771 FIXME("%s\n", pszPath);
1775 /*************************************************************************
1776 * PathUnmakeSystemFolderW [SHLWAPI.@]
1778 BOOL WINAPI PathUnmakeSystemFolderW(LPCWSTR pszPath)
1780 FIXME("%s\n", debugstr_w(pszPath));
1785 ########## special ##########
1788 /*************************************************************************
1789 * PathSetDlgItemPathA [SHLWAPI.@]
1792 * use PathCompactPath to make sure, the path fits into the control
1794 BOOL WINAPI PathSetDlgItemPathA(HWND hDlg, int id, LPCSTR pszPath)
1795 { TRACE("%x %x %s\n",hDlg, id, pszPath);
1796 return SetDlgItemTextA(hDlg, id, pszPath);
1799 /*************************************************************************
1800 * PathSetDlgItemPathW [SHLWAPI.@]
1802 BOOL WINAPI PathSetDlgItemPathW(HWND hDlg, int id, LPCWSTR pszPath)
1803 { TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
1804 return SetDlgItemTextW(hDlg, id, pszPath);