Make direct console input routines go through int16, rather than
[wine/testsucceed.git] / dlls / shlwapi / path.c
blob4582d49b1e665fb268dd9e7ab46e8178344f8c79
1 /*
2 * Path Functions
3 */
5 #include <ctype.h>
6 #include <string.h>
8 #include "winerror.h"
9 #include "wine/unicode.h"
10 #include "wine/undocshell.h"
11 #include "shlwapi.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.@]
24 * NOTES
25 * concat path lpszPath2 onto lpszPath1
27 * FIXME
28 * the resulting path is also canonicalized
30 BOOL WINAPI PathAppendA(
31 LPSTR lpszPath1,
32 LPCSTR lpszPath2)
34 TRACE("%s %s\n",lpszPath1, lpszPath2);
35 while (lpszPath2[0]=='\\') lpszPath2++;
36 PathCombineA(lpszPath1,lpszPath1,lpszPath2);
37 return TRUE;
40 /*************************************************************************
41 * PathAppendW [SHLWAPI.@]
43 BOOL WINAPI PathAppendW(
44 LPWSTR lpszPath1,
45 LPCWSTR lpszPath2)
47 TRACE("%s %s\n",debugstr_w(lpszPath1), debugstr_w(lpszPath2));
48 while (lpszPath2[0]=='\\') lpszPath2++;
49 PathCombineW(lpszPath1,lpszPath1,lpszPath2);
50 return TRUE;
53 /*************************************************************************
54 * PathCombineA [SHLWAPI.@]
56 * NOTES
57 * if lpszFile='.' skip it
58 * szDest can be equal to lpszFile. Thats why we use sTemp
60 * FIXME
61 * the resulting path is also canonicalized
63 LPSTR WINAPI PathCombineA(
64 LPSTR szDest,
65 LPCSTR lpszDir,
66 LPCSTR lpszFile)
68 char sTemp[MAX_PATH];
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);
75 return szDest;
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);
88 strcpy(szDest,sTemp);
90 else
92 strcpy(sTemp,lpszDir);
93 PathAddBackslashA(sTemp);
94 strcat(sTemp,lpszFile);
95 strcpy(szDest,sTemp);
97 return szDest;
100 /*************************************************************************
101 * PathCombineW [SHLWAPI.@]
103 LPWSTR WINAPI PathCombineW(
104 LPWSTR szDest,
105 LPCWSTR lpszDir,
106 LPCWSTR lpszFile)
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);
116 return szDest;
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);
131 else
133 strcpyW(sTemp,lpszDir);
134 PathAddBackslashW(sTemp);
135 strcatW(sTemp,lpszFile);
136 strcpyW(szDest,sTemp);
138 return szDest;
141 /*************************************************************************
142 * PathAddBackslashA [SHLWAPI.@]
144 * NOTES
145 * append \ if there is none
147 LPSTR WINAPI PathAddBackslashA(LPSTR lpszPath)
149 int len;
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;
159 return lpszPath+len;
162 /*************************************************************************
163 * PathAddBackslashW [SHLWAPI.@]
165 LPWSTR WINAPI PathAddBackslashW(LPWSTR lpszPath)
167 int len;
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;
177 return lpszPath+len;
180 /*************************************************************************
181 * PathBuildRootA [SHLWAPI.@]
183 LPSTR WINAPI PathBuildRootA(LPSTR lpszPath, int drive)
185 TRACE("%p %i\n",lpszPath, drive);
187 strcpy(lpszPath,"A:\\");
188 lpszPath[0]+=drive;
189 return lpszPath;
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:\\");
200 lpszPath[0]+=drive;
201 return lpszPath;
205 Extracting Component Parts
208 /*************************************************************************
209 * PathFindFileNameA [SHLWAPI.@]
211 LPSTR WINAPI PathFindFileNameA(LPCSTR lpszPath)
213 LPCSTR lastSlash = lpszPath;
215 TRACE("%s\n",lpszPath);
216 while (*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)
231 LPCWSTR wslash;
232 wslash = lpszPath;
234 TRACE("%s\n",debugstr_w(wslash));
235 while (lpszPath[0])
237 if (((lpszPath[0]=='\\') || (lpszPath[0]==':')) && lpszPath[1] && lpszPath[1]!='\\')
238 wslash = lpszPath+1;
239 lpszPath = CharNextW(lpszPath);
241 return (LPWSTR)wslash;
244 /*************************************************************************
245 * PathFindExtensionA [SHLWAPI.@]
247 * NOTES
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);
257 while (*lpszPath)
259 if (*lpszPath=='\\'||*lpszPath==' ')
260 lastpoint=NULL;
261 if (*lpszPath=='.')
262 lastpoint=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));
277 while (*lpszPath)
279 if (*lpszPath==(WCHAR)'\\'||*lpszPath==(WCHAR)' ')
280 lastpoint=NULL;
281 if (*lpszPath==(WCHAR)'.')
282 lastpoint=lpszPath;
283 lpszPath = CharNextW(lpszPath);
285 return (LPWSTR)(lastpoint?lastpoint:lpszPath);
288 /*************************************************************************
289 * PathGetExtensionA [internal]
291 * NOTES
292 * exported by ordinal
293 * return value points to the first char after the dot
295 LPSTR WINAPI PathGetExtensionA(LPCSTR lpszPath)
297 TRACE("(%s)\n",lpszPath);
299 lpszPath = PathFindExtensionA(lpszPath);
300 return (LPSTR)(*lpszPath?(lpszPath+1):lpszPath);
303 /*************************************************************************
304 * PathGetExtensionW [internal]
306 LPWSTR WINAPI PathGetExtensionW(LPCWSTR lpszPath)
308 TRACE("(%s)\n",debugstr_w(lpszPath));
310 lpszPath = PathFindExtensionW(lpszPath);
311 return (LPWSTR)(*lpszPath?(lpszPath+1):lpszPath);
314 /*************************************************************************
315 * PathGetArgsA [SHLWAPI.@]
317 * NOTES
318 * look for next arg in string. handle "quoted" strings
319 * returns pointer to argument *AFTER* the space. Or to the \0.
321 * FIXME
322 * quoting by '\'
324 LPSTR WINAPI PathGetArgsA(LPCSTR lpszPath)
326 BOOL qflag = FALSE;
328 TRACE("%s\n",lpszPath);
330 while (*lpszPath)
332 if ((*lpszPath==' ') && !qflag)
333 return (LPSTR)lpszPath+1;
334 if (*lpszPath=='"')
335 qflag=!qflag;
336 lpszPath = CharNextA(lpszPath);
338 return (LPSTR)lpszPath;
341 /*************************************************************************
342 * PathGetArgsW [SHLWAPI.@]
344 LPWSTR WINAPI PathGetArgsW(LPCWSTR lpszPath)
346 BOOL qflag = FALSE;
348 TRACE("%s\n",debugstr_w(lpszPath));
350 while (*lpszPath)
352 if ((*lpszPath==' ') && !qflag)
353 return (LPWSTR)lpszPath+1;
354 if (*lpszPath=='"')
355 qflag=!qflag;
356 lpszPath = CharNextW(lpszPath);
358 return (LPWSTR)lpszPath;
361 /*************************************************************************
362 * PathGetDriveNumberA [SHLWAPI.@]
364 int WINAPI PathGetDriveNumberA(LPCSTR lpszPath)
366 int chr = tolower(lpszPath[0]);
368 TRACE ("%s\n",debugstr_a(lpszPath));
370 if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
371 return tolower(lpszPath[0]) - 'a' ;
374 /*************************************************************************
375 * PathGetDriveNumberW [SHLWAPI.@]
377 int WINAPI PathGetDriveNumberW(LPCWSTR lpszPath)
379 int chr = tolowerW(lpszPath[0]);
381 TRACE ("%s\n",debugstr_w(lpszPath));
383 if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
384 return tolowerW(lpszPath[0]) - 'a' ;
387 /*************************************************************************
388 * PathRemoveFileSpecA [SHLWAPI.@]
390 * NOTES
391 * truncates passed argument to a valid path
392 * returns if the string was modified or not.
393 * "\foo\xx\foo"-> "\foo\xx"
394 * "\" -> "\"
395 * "a:\foo" -> "a:\"
397 BOOL WINAPI PathRemoveFileSpecA(LPSTR lpszPath)
399 LPSTR cutplace = lpszPath;
400 BOOL ret = FALSE;
402 TRACE("%s\n",lpszPath);
404 if(lpszPath)
406 while (*lpszPath == '\\') cutplace = ++lpszPath;
408 while (*lpszPath)
410 if(lpszPath[0] == '\\') cutplace = lpszPath;
412 if(lpszPath[0] == ':')
414 cutplace = lpszPath + 1;
415 if (lpszPath[1] == '\\') cutplace++;
416 lpszPath++;
418 lpszPath = CharNextA(lpszPath);
419 if (!lpszPath) break;
422 ret = (*cutplace!='\0');
423 *cutplace = '\0';
425 return ret;
428 /*************************************************************************
429 * PathRemoveFileSpecW [SHLWAPI.@]
431 BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
433 LPWSTR cutplace = lpszPath;
434 BOOL ret = FALSE;
436 TRACE("%s\n",debugstr_w(lpszPath));
438 if(lpszPath)
440 while (*lpszPath == '\\') cutplace = ++lpszPath;
442 while (*lpszPath)
444 if(lpszPath[0] == '\\') cutplace = lpszPath;
446 if(lpszPath[0] == ':')
448 cutplace = lpszPath + 1;
449 if (lpszPath[1] == '\\') cutplace++;
450 lpszPath++;
452 lpszPath = CharNextW(lpszPath);
453 if (!lpszPath) break;
456 ret = (*cutplace!='\0');
457 *cutplace = '\0';
459 return ret;
462 /*************************************************************************
463 * PathStripPathA [SHELLWAPI.@]
465 * NOTES
466 * removes the path from the beginning of a filename
468 void WINAPI PathStripPathA(LPSTR lpszPath)
470 LPSTR lpszFileName = PathFindFileNameA(lpszPath);
472 TRACE("%s\n", lpszPath);
474 if(lpszFileName)
475 RtlMoveMemory(lpszPath, lpszFileName, strlen(lpszFileName)+1);
478 /*************************************************************************
479 * PathStripPathW [SHELLWAPI.@]
481 void WINAPI PathStripPathW(LPWSTR lpszPath)
483 LPWSTR lpszFileName = PathFindFileNameW(lpszPath);
485 TRACE("%s\n", debugstr_w(lpszPath));
486 if(lpszFileName)
487 RtlMoveMemory(lpszPath, lpszFileName, (lstrlenW(lpszFileName)+1)*sizeof(WCHAR));
490 /*************************************************************************
491 * PathStripToRootA [SHLWAPI.@]
493 BOOL WINAPI PathStripToRootA(LPSTR lpszPath)
495 TRACE("%s\n", lpszPath);
497 if (!lpszPath) return FALSE;
498 while(!PathIsRootA(lpszPath))
499 if (!PathRemoveFileSpecA(lpszPath)) return FALSE;
500 return TRUE;
503 /*************************************************************************
504 * PathStripToRootW [SHLWAPI.@]
506 BOOL WINAPI PathStripToRootW(LPWSTR lpszPath)
508 TRACE("%s\n", debugstr_w(lpszPath));
510 if (!lpszPath) return FALSE;
511 while(!PathIsRootW(lpszPath))
512 if (!PathRemoveFileSpecW(lpszPath)) return FALSE;
513 return TRUE;
516 /*************************************************************************
517 * PathRemoveArgsA [SHLWAPI.@]
520 void WINAPI PathRemoveArgsA(LPSTR lpszPath)
522 TRACE("%s\n",lpszPath);
524 if(lpszPath)
526 LPSTR lpszArgs = PathGetArgsA(lpszPath);
527 if (!*lpszArgs)
529 LPSTR lpszLastChar = CharPrevA(lpszPath, lpszArgs);
530 if(*lpszLastChar==' ') *lpszLastChar = '\0';
535 /*************************************************************************
536 * PathRemoveArgsW [SHLWAPI.@]
538 void WINAPI PathRemoveArgsW(LPWSTR lpszPath)
540 TRACE("%s\n", debugstr_w(lpszPath));
542 if(lpszPath)
544 LPWSTR lpszArgs = PathGetArgsW(lpszPath);
545 if (!*lpszArgs)
547 LPWSTR lpszLastChar = CharPrevW(lpszPath, lpszArgs);
548 if(*lpszLastChar==' ') *lpszLastChar = '\0';
553 /*************************************************************************
554 * PathRemoveExtensionA [SHLWAPI.@]
556 void WINAPI PathRemoveExtensionA(LPSTR lpszPath)
558 LPSTR lpszExtension = PathFindExtensionA(lpszPath);
560 TRACE("%s\n", lpszPath);
562 if (lpszExtension) *lpszExtension='\0';
565 /*************************************************************************
566 * PathRemoveExtensionW [SHLWAPI.@]
568 void WINAPI PathRemoveExtensionW(LPWSTR lpszPath)
570 LPWSTR lpszExtension = PathFindExtensionW(lpszPath);
572 TRACE("%s\n", debugstr_w(lpszPath));
574 if (lpszExtension) *lpszExtension='\0';
577 /*************************************************************************
578 * PathRemoveBackslashA [SHLWAPI.@]
580 * If the path ends in a backslash it is replaced by a NULL
581 * and the address of the NULL is returned
582 * Otherwise
583 * the address of the last character is returned.
585 * FIXME
586 * "c:\": keep backslash
588 LPSTR WINAPI PathRemoveBackslashA( LPSTR lpszPath )
590 int len;
591 LPSTR szTemp = NULL;
593 if(lpszPath)
595 len = strlen(lpszPath);
596 szTemp = CharPrevA(lpszPath, lpszPath+len);
597 if (! PathIsRootA(lpszPath))
599 if (*szTemp == '\\') *szTemp = '\0';
602 return szTemp;
605 /*************************************************************************
606 * PathRemoveBackslashW [SHLWAPI.@]
608 LPWSTR WINAPI PathRemoveBackslashW( LPWSTR lpszPath )
610 int len;
611 LPWSTR szTemp = NULL;
613 if(lpszPath)
615 len = lstrlenW(lpszPath);
616 szTemp = CharPrevW(lpszPath, lpszPath+len);
617 if (! PathIsRootW(lpszPath))
619 if (*szTemp == '\\') *szTemp = '\0';
622 return szTemp;
627 Path Manipulations
630 /*************************************************************************
631 * PathRemoveBlanksA [SHLWAPI.@]
633 * NOTES
634 * remove spaces from beginning and end of passed string
636 void WINAPI PathRemoveBlanksA(LPSTR str)
638 LPSTR x = str;
640 TRACE("%s\n",str);
642 if(str)
644 while (*x==' ') x = CharNextA(x);
645 if (x!=str) strcpy(str,x);
646 x=str+strlen(str)-1;
647 while (*x==' ') x = CharPrevA(str, x);
648 if (*x==' ') *x='\0';
652 /*************************************************************************
653 * PathRemoveBlanksW [SHLWAPI.@]
655 void WINAPI PathRemoveBlanksW(LPWSTR str)
657 LPWSTR x = str;
659 TRACE("%s\n",debugstr_w(str));
661 if(str)
663 while (*x==' ') x = CharNextW(x);
664 if (x!=str) lstrcpyW(str,x);
665 x=str+lstrlenW(str)-1;
666 while (*x==' ') x = CharPrevW(str, x);
667 if (*x==' ') *x='\0';
671 /*************************************************************************
672 * PathQuoteSpacesA [SHLWAPI.@]
675 LPSTR WINAPI PathQuoteSpacesA(LPSTR lpszPath)
677 TRACE("%s\n",lpszPath);
679 if(StrChrA(lpszPath,' '))
681 int len = strlen(lpszPath);
682 RtlMoveMemory(lpszPath+1, lpszPath, len);
683 *(lpszPath++) = '"';
684 lpszPath += len;
685 *(lpszPath++) = '"';
686 *(lpszPath) = '\0';
687 return --lpszPath;
689 return 0;
692 /*************************************************************************
693 * PathQuoteSpacesW [SHLWAPI.@]
695 LPWSTR WINAPI PathQuoteSpacesW(LPWSTR lpszPath)
697 TRACE("%s\n",debugstr_w(lpszPath));
699 if(StrChrW(lpszPath,' '))
701 int len = lstrlenW(lpszPath);
702 RtlMoveMemory(lpszPath+1, lpszPath, len*sizeof(WCHAR));
703 *(lpszPath++) = '"';
704 lpszPath += len;
705 *(lpszPath++) = '"';
706 *(lpszPath) = '\0';
707 return --lpszPath;
709 return 0;
712 /*************************************************************************
713 * PathUnquoteSpacesA [SHLWAPI.@]
715 * NOTES
716 * unquote string (remove ")
718 VOID WINAPI PathUnquoteSpacesA(LPSTR str)
720 DWORD len = lstrlenA(str);
722 TRACE("%s\n",str);
724 if (*str!='"')
725 return;
726 if (str[len-1]!='"')
727 return;
728 str[len-1]='\0';
729 lstrcpyA(str,str+1);
730 return;
733 /*************************************************************************
734 * PathUnquoteSpacesW [SHLWAPI.@]
736 VOID WINAPI PathUnquoteSpacesW(LPWSTR str)
738 DWORD len = strlenW(str);
740 TRACE("%s\n",debugstr_w(str));
742 if (*str!='"')
743 return;
744 if (str[len-1]!='"')
745 return;
746 str[len-1]='\0';
747 strcpyW(str,str+1);
748 return;
751 /*************************************************************************
752 * PathParseIconLocationA [SHLWAPI.@]
754 int WINAPI PathParseIconLocationA(LPSTR lpszPath)
756 LPSTR lpstrComma = strchr(lpszPath, ',');
758 FIXME("%s stub\n", debugstr_a(lpszPath));
760 if (lpstrComma && lpstrComma[1])
762 lpstrComma[0]='\0';
763 /* return atoi(&lpstrComma[1]); FIXME */
766 PathUnquoteSpacesA(lpszPath);
767 return 0;
770 /*************************************************************************
771 * PathParseIconLocationW [SHLWAPI.@]
773 int WINAPI PathParseIconLocationW(LPWSTR lpszPath)
775 LPWSTR lpstrComma = strchrW(lpszPath, ',');
777 FIXME("%s stub\n", debugstr_w(lpszPath));
779 if (lpstrComma && lpstrComma[1])
781 lpstrComma[0]='\0';
782 /* return _wtoi(&lpstrComma[1]); FIXME */
784 PathUnquoteSpacesW(lpszPath);
785 return 0;
789 ########## cleaning and resolving paths ##########
792 /*************************************************************************
793 * PathFindOnPathA [SHLWAPI.@]
795 BOOL WINAPI PathFindOnPathA(LPSTR sFile, LPCSTR sOtherDirs)
797 FIXME("%s %s\n",sFile, sOtherDirs);
798 return FALSE;
801 /*************************************************************************
802 * PathFindOnPathW [SHLWAPI.@]
804 BOOL WINAPI PathFindOnPathW(LPWSTR sFile, LPCWSTR sOtherDirs)
806 FIXME("%s %s\n",debugstr_w(sFile), debugstr_w(sOtherDirs));
807 return FALSE;
810 /*************************************************************************
811 * PathCleanupSpecA [SHLWAPI.@]
813 DWORD WINAPI PathCleanupSpecA(LPSTR x, LPSTR y)
815 FIXME("(%p %s, %p %s) stub\n",x,debugstr_a(x),y,debugstr_a(y));
816 return TRUE;
819 /*************************************************************************
820 * PathCleanupSpecW [SHLWAPI.@]
822 DWORD WINAPI PathCleanupSpecW(LPWSTR x, LPWSTR y)
824 FIXME("(%p %s, %p %s) stub\n",x,debugstr_w(x),y,debugstr_w(y));
825 return TRUE;
828 /*************************************************************************
829 * PathCompactPathExA [SHLWAPI.@]
831 BOOL WINAPI PathCompactPathExA(
832 LPSTR pszOut,
833 LPCSTR pszSrc,
834 UINT cchMax,
835 DWORD dwFlags)
837 FIXME("%p %s 0x%08x 0x%08lx\n", pszOut, pszSrc, cchMax, dwFlags);
838 return FALSE;
841 /*************************************************************************
842 * PathCompactPathExW [SHLWAPI.@]
844 BOOL WINAPI PathCompactPathExW(
845 LPWSTR pszOut,
846 LPCWSTR pszSrc,
847 UINT cchMax,
848 DWORD dwFlags)
850 FIXME("%p %s 0x%08x 0x%08lx\n", pszOut, debugstr_w(pszSrc), cchMax, dwFlags);
851 return FALSE;
855 ########## Path Testing ##########
858 /*************************************************************************
859 * PathIsUNCA [SHLWAPI.@]
861 * NOTES
862 * PathIsUNC(char*path);
864 BOOL WINAPI PathIsUNCA(LPCSTR lpszPath)
866 TRACE("%s\n",lpszPath);
868 return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
871 /*************************************************************************
872 * PathIsUNCW [SHLWAPI.@]
874 BOOL WINAPI PathIsUNCW(LPCWSTR lpszPath)
876 TRACE("%s\n",debugstr_w(lpszPath));
878 return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
881 /*************************************************************************
882 * PathIsRelativeA [SHLWAPI.@]
884 BOOL WINAPI PathIsRelativeA (LPCSTR lpszPath)
886 TRACE("lpszPath=%s\n",lpszPath);
888 return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
891 /*************************************************************************
892 * PathIsRelativeW [SHLWAPI.@]
894 BOOL WINAPI PathIsRelativeW (LPCWSTR lpszPath)
896 TRACE("lpszPath=%s\n",debugstr_w(lpszPath));
898 return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
901 /*************************************************************************
902 * PathIsRootA [SHLWAPI.@]
904 * notes
905 * TRUE if the path points to a root directory
907 BOOL WINAPI PathIsRootA(LPCSTR lpszPath)
909 TRACE("%s\n",lpszPath);
911 /* X:\ */
912 if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
913 return TRUE;
915 /* "\" */
916 if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
917 return TRUE;
919 /* UNC "\\<computer>\<share>" */
920 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
922 int foundbackslash = 0;
923 lpszPath += 2;
924 while (*lpszPath)
926 if (*lpszPath=='\\') foundbackslash++;
927 lpszPath = CharNextA(lpszPath);
929 if (foundbackslash <= 1)
930 return TRUE;
932 return FALSE;
935 /*************************************************************************
936 * PathIsRootW [SHLWAPI.@]
938 BOOL WINAPI PathIsRootW(LPCWSTR lpszPath)
940 TRACE("%s\n",debugstr_w(lpszPath));
942 /* X:\ */
943 if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
944 return TRUE;
946 /* "\" */
947 if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
948 return TRUE;
950 /* UNC "\\<computer>\<share>" */
951 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
953 int foundbackslash = 0;
954 lpszPath += 2;
955 while (*lpszPath)
957 if (*lpszPath=='\\') foundbackslash++;
958 lpszPath = CharNextW(lpszPath);
960 if (foundbackslash <= 1)
961 return TRUE;
963 return FALSE;
967 /*************************************************************************
968 * PathIsExeA [internal]
970 BOOL WINAPI PathIsExeA (LPCSTR lpszPath)
972 LPCSTR lpszExtension = PathGetExtensionA(lpszPath);
973 int i = 0;
974 static char * lpszExtensions[6] = {"exe", "com", "pid", "cmd", "bat", NULL };
976 TRACE("path=%s\n",lpszPath);
978 for(i=0; lpszExtensions[i]; i++)
979 if (!strcasecmp(lpszExtension,lpszExtensions[i])) return TRUE;
981 return FALSE;
984 /*************************************************************************
985 * PathIsExeW [internal]
987 BOOL WINAPI PathIsExeW (LPCWSTR lpszPath)
989 LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
990 int i = 0;
991 static WCHAR lpszExtensions[6][4] =
992 {{'e','x','e','\0'}, {'c','o','m','\0'}, {'p','i','d','\0'},
993 {'c','m','d','\0'}, {'b','a','t','\0'}, {'\0'} };
995 TRACE("path=%s\n",debugstr_w(lpszPath));
997 for(i=0; lpszExtensions[i]; i++)
998 if (!strcmpiW(lpszExtension,lpszExtensions[i])) return TRUE;
1000 return FALSE;
1003 /*************************************************************************
1004 * PathIsDirectoryA [SHLWAPI.@]
1006 BOOL WINAPI PathIsDirectoryA(LPCSTR lpszPath)
1008 DWORD dwAttr;
1010 TRACE("%s\n", debugstr_a(lpszPath));
1012 dwAttr = GetFileAttributesA(lpszPath);
1013 return (dwAttr != -1) ? dwAttr & FILE_ATTRIBUTE_DIRECTORY : 0;
1016 /*************************************************************************
1017 * PathIsDirectoryW [SHLWAPI.@]
1019 BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
1021 DWORD dwAttr;
1023 TRACE("%s\n", debugstr_w(lpszPath));
1025 dwAttr = GetFileAttributesW(lpszPath);
1026 return (dwAttr != -1) ? dwAttr & FILE_ATTRIBUTE_DIRECTORY : 0;
1029 /*************************************************************************
1030 * PathFileExistsA [SHLWAPI.@]
1032 * NOTES
1033 * file_exists(char *fn);
1035 BOOL WINAPI PathFileExistsA(LPCSTR lpszPath)
1037 TRACE("%s\n",lpszPath);
1038 return (GetFileAttributesA(lpszPath)!=-1);
1041 /*************************************************************************
1042 * PathFileExistsW [SHLWAPI.@]
1044 BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
1046 TRACE("%s\n",debugstr_w(lpszPath));
1047 return (GetFileAttributesW(lpszPath)!=-1);
1050 /*************************************************************************
1051 * PathMatchSingleMaskA [internal]
1053 * NOTES
1054 * internal (used by PathMatchSpec)
1056 static BOOL PathMatchSingleMaskA(LPCSTR name, LPCSTR mask)
1058 while (*name && *mask && *mask!=';')
1060 if (*mask=='*')
1064 if (PathMatchSingleMaskA(name,mask+1)) return 1; /* try substrings */
1065 } while (*name++);
1066 return 0;
1068 if (toupper(*mask)!=toupper(*name) && *mask!='?') return 0;
1069 name = CharNextA(name);
1070 mask = CharNextA(mask);
1072 if (!*name)
1074 while (*mask=='*') mask++;
1075 if (!*mask || *mask==';') return 1;
1077 return 0;
1080 /*************************************************************************
1081 * PathMatchSingleMaskW [internal]
1083 static BOOL PathMatchSingleMaskW(LPCWSTR name, LPCWSTR mask)
1085 while (*name && *mask && *mask!=';')
1087 if (*mask=='*')
1091 if (PathMatchSingleMaskW(name,mask+1)) return 1; /* try substrings */
1092 } while (*name++);
1093 return 0;
1095 if (toupperW(*mask)!=toupperW(*name) && *mask!='?') return 0;
1096 name = CharNextW(name);
1097 mask = CharNextW(mask);
1099 if (!*name)
1101 while (*mask=='*') mask++;
1102 if (!*mask || *mask==';') return 1;
1104 return 0;
1106 /*************************************************************************
1107 * PathMatchSpecA [SHLWAPI.@]
1109 * NOTES
1110 * used from COMDLG32
1112 BOOL WINAPI PathMatchSpecA(LPCSTR name, LPCSTR mask)
1114 TRACE("%s %s\n",name,mask);
1116 if (!lstrcmpA( mask, "*.*" )) return 1; /* we don't require a period */
1118 while (*mask)
1120 if (PathMatchSingleMaskA(name,mask)) return 1; /* helper function */
1121 while (*mask && *mask!=';') mask = CharNextA(mask);
1122 if (*mask==';')
1124 mask++;
1125 while (*mask==' ') mask++; /* masks may be separated by "; " */
1128 return 0;
1131 /*************************************************************************
1132 * PathMatchSpecW [SHLWAPI.@]
1134 BOOL WINAPI PathMatchSpecW(LPCWSTR name, LPCWSTR mask)
1136 WCHAR stemp[4];
1137 TRACE("%s %s\n",debugstr_w(name),debugstr_w(mask));
1139 lstrcpyAtoW(stemp,"*.*");
1140 if (!lstrcmpW( mask, stemp )) return 1; /* we don't require a period */
1142 while (*mask)
1144 if (PathMatchSingleMaskW(name,mask)) return 1; /* helper function */
1145 while (*mask && *mask!=';') mask = CharNextW(mask);
1146 if (*mask==';')
1148 mask++;
1149 while (*mask==' ') mask++; /* masks may be separated by "; " */
1152 return 0;
1155 /*************************************************************************
1156 * PathIsSameRootA [SHLWAPI.@]
1158 * FIXME
1159 * what to do with "\path" ??
1161 BOOL WINAPI PathIsSameRootA(LPCSTR lpszPath1, LPCSTR lpszPath2)
1163 TRACE("%s %s\n", lpszPath1, lpszPath2);
1165 if (PathIsRelativeA(lpszPath1) || PathIsRelativeA(lpszPath2)) return FALSE;
1167 /* usual path */
1168 if ( toupper(lpszPath1[0])==toupper(lpszPath2[0]) &&
1169 lpszPath1[1]==':' && lpszPath2[1]==':' &&
1170 lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
1171 return TRUE;
1173 /* UNC */
1174 if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
1175 lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
1177 int pos=2, bsfound=0;
1178 while (lpszPath1[pos] && lpszPath2[pos] &&
1179 (lpszPath1[pos] == lpszPath2[pos]))
1181 if (lpszPath1[pos]=='\\') bsfound++;
1182 if (bsfound == 2) return TRUE;
1183 pos++; /* fixme: use CharNext*/
1185 return (lpszPath1[pos] == lpszPath2[pos]);
1187 return FALSE;
1190 /*************************************************************************
1191 * PathIsSameRootW [SHLWAPI.@]
1193 BOOL WINAPI PathIsSameRootW(LPCWSTR lpszPath1, LPCWSTR lpszPath2)
1195 TRACE("%s %s\n", debugstr_w(lpszPath1), debugstr_w(lpszPath2));
1197 if (PathIsRelativeW(lpszPath1) || PathIsRelativeW(lpszPath2)) return FALSE;
1199 /* usual path */
1200 if ( toupperW(lpszPath1[0])==toupperW(lpszPath2[0]) &&
1201 lpszPath1[1]==':' && lpszPath2[1]==':' &&
1202 lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
1203 return TRUE;
1205 /* UNC */
1206 if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
1207 lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
1209 int pos=2, bsfound=0;
1210 while (lpszPath1[pos] && lpszPath2[pos] &&
1211 (lpszPath1[pos] == lpszPath2[pos]))
1213 if (lpszPath1[pos]=='\\') bsfound++;
1214 if (bsfound == 2) return TRUE;
1215 pos++;/* fixme: use CharNext*/
1217 return (lpszPath1[pos] == lpszPath2[pos]);
1219 return FALSE;
1222 /*************************************************************************
1223 * PathIsURLA
1225 BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
1227 LPSTR lpstrRes;
1228 int iSize, i=0;
1229 static LPSTR SupportedProtocol[] =
1230 {"http","https","ftp","gopher","file","mailto",NULL};
1232 if(!lpstrPath) return FALSE;
1234 /* get protocol */
1235 lpstrRes = strchr(lpstrPath,':');
1236 if(!lpstrRes) return FALSE;
1237 iSize = lpstrRes - lpstrPath;
1239 while(SupportedProtocol[i])
1241 if (iSize == strlen(SupportedProtocol[i]))
1242 if(!strncasecmp(lpstrPath, SupportedProtocol[i], iSize))
1243 return TRUE;
1244 i++;
1247 return FALSE;
1250 /*************************************************************************
1251 * PathIsURLW
1253 BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
1255 LPWSTR lpstrRes;
1256 int iSize, i=0;
1257 static WCHAR SupportedProtocol[7][7] =
1258 {{'h','t','t','p','\0'},{'h','t','t','p','s','\0'},{'f','t','p','\0'},
1259 {'g','o','p','h','e','r','\0'},{'f','i','l','e','\0'},
1260 {'m','a','i','l','t','o','\0'},{0}};
1262 if(!lpstrPath) return FALSE;
1264 /* get protocol */
1265 lpstrRes = strchrW(lpstrPath,':');
1266 if(!lpstrRes) return FALSE;
1267 iSize = lpstrRes - lpstrPath;
1269 while(SupportedProtocol[i])
1271 if (iSize == strlenW(SupportedProtocol[i]))
1272 if(!strncmpiW(lpstrPath, SupportedProtocol[i], iSize))
1273 return TRUE;
1274 i++;
1277 return FALSE;
1281 /*************************************************************************
1282 * PathIsContentTypeA [SHLWAPI.@]
1284 BOOL WINAPI PathIsContentTypeA(LPCSTR pszPath, LPCSTR pszContentType)
1286 FIXME("%s %s\n", pszPath, pszContentType);
1287 return FALSE;
1290 /*************************************************************************
1291 * PathIsContentTypeW [SHLWAPI.@]
1293 BOOL WINAPI PathIsContentTypeW(LPCWSTR pszPath, LPCWSTR pszContentType)
1295 FIXME("%s %s\n", debugstr_w(pszPath), debugstr_w(pszContentType));
1296 return FALSE;
1299 /*************************************************************************
1300 * PathIsFileSpecA [SHLWAPI.@]
1302 BOOL WINAPI PathIsFileSpecA(LPCSTR pszPath)
1304 FIXME("%s\n", pszPath);
1305 return FALSE;
1308 /*************************************************************************
1309 * PathIsFileSpecW [SHLWAPI.@]
1311 BOOL WINAPI PathIsFileSpecW(LPCWSTR pszPath)
1313 FIXME("%s\n", debugstr_w(pszPath));
1314 return FALSE;
1317 /*************************************************************************
1318 * PathIsPrefixA [SHLWAPI.@]
1320 BOOL WINAPI PathIsPrefixA(LPCSTR pszPrefix, LPCSTR pszPath)
1322 FIXME("%s %s\n", pszPrefix, pszPath);
1323 return FALSE;
1326 /*************************************************************************
1327 * PathIsPrefixW [SHLWAPI.@]
1329 BOOL WINAPI PathIsPrefixW(LPCWSTR pszPrefix, LPCWSTR pszPath)
1331 FIXME("%s %s\n", debugstr_w(pszPrefix), debugstr_w(pszPath));
1332 return FALSE;
1335 /*************************************************************************
1336 * PathIsSystemFolderA [SHLWAPI.@]
1338 BOOL WINAPI PathIsSystemFolderA(LPCSTR pszPath, DWORD dwAttrb)
1340 FIXME("%s 0x%08lx\n", pszPath, dwAttrb);
1341 return FALSE;
1344 /*************************************************************************
1345 * PathIsSystemFolderW [SHLWAPI.@]
1347 BOOL WINAPI PathIsSystemFolderW(LPCWSTR pszPath, DWORD dwAttrb)
1349 FIXME("%s 0x%08lx\n", debugstr_w(pszPath), dwAttrb);
1350 return FALSE;
1353 /*************************************************************************
1354 * PathIsUNCServerA [SHLWAPI.@]
1356 BOOL WINAPI PathIsUNCServerA(
1357 LPCSTR pszPath)
1359 FIXME("%s\n", pszPath);
1360 return FALSE;
1363 /*************************************************************************
1364 * PathIsUNCServerW [SHLWAPI.@]
1366 BOOL WINAPI PathIsUNCServerW(
1367 LPCWSTR pszPath)
1369 FIXME("%s\n", debugstr_w(pszPath));
1370 return FALSE;
1373 /*************************************************************************
1374 * PathIsUNCServerShareA [SHLWAPI.@]
1376 BOOL WINAPI PathIsUNCServerShareA(
1377 LPCSTR pszPath)
1379 FIXME("%s\n", pszPath);
1380 return FALSE;
1383 /*************************************************************************
1384 * PathIsUNCServerShareW [SHLWAPI.@]
1386 BOOL WINAPI PathIsUNCServerShareW(
1387 LPCWSTR pszPath)
1389 FIXME("%s\n", debugstr_w(pszPath));
1390 return FALSE;
1393 /*************************************************************************
1394 * PathCanonicalizeA [SHLWAPI.@]
1396 * FIXME
1397 * returnvalue, use CharNext
1400 BOOL WINAPI PathCanonicalizeA(LPSTR pszBuf, LPCSTR pszPath)
1402 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = strlen(pszPath);
1403 BOOL bModifyed = FALSE;
1405 TRACE("%p %s\n", pszBuf, pszPath);
1407 pszBuf[OffsetDst]='\0';
1409 /* keep the root of the path */
1410 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
1412 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1414 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
1416 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1417 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1418 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
1420 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1421 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
1423 /* C:\. */
1424 OffsetSrc++; LenSrc--; bModifyed = TRUE;
1426 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
1428 /* C:\.. */
1429 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1434 /* ".\" at the beginning of the path */
1435 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
1437 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1440 while ( LenSrc )
1442 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
1444 /* "\.." found, go one deeper */
1445 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
1446 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
1447 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
1448 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
1450 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
1452 /* "\." found, skip it */
1453 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
1455 else
1457 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
1460 pszBuf[OffsetDst] = '\0';
1461 TRACE("-- %s %u\n", pszBuf, bModifyed);
1462 return bModifyed;
1466 /*************************************************************************
1467 * PathCanonicalizeW [SHLWAPI.@]
1469 * FIXME
1470 * returnvalue, use CharNext
1472 BOOL WINAPI PathCanonicalizeW(LPWSTR pszBuf, LPCWSTR pszPath)
1474 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = lstrlenW(pszPath);
1475 BOOL bModifyed = FALSE;
1477 TRACE("%p %s\n", pszBuf, debugstr_w(pszPath));
1479 pszBuf[OffsetDst]='\0';
1481 /* keep the root of the path */
1482 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
1484 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1486 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
1488 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1489 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1490 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
1492 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1493 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
1495 /* C:\. */
1496 OffsetSrc++; LenSrc--; bModifyed = TRUE;
1498 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
1500 /* C:\.. */
1501 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1506 /* ".\" at the beginning of the path */
1507 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
1509 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1512 while ( LenSrc )
1514 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
1516 /* "\.." found, go one deeper */
1517 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
1518 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
1519 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
1520 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
1522 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
1524 /* "\." found, skip it */
1525 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
1527 else
1529 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
1532 pszBuf[OffsetDst] = '\0';
1533 TRACE("-- %s %u\n", debugstr_w(pszBuf), bModifyed);
1534 return bModifyed;
1537 /*************************************************************************
1538 * PathFindNextComponentA [SHLWAPI.@]
1540 * NOTES
1541 * special cases:
1542 * "" null
1543 * aa "" (pointer to traling NULL)
1544 * aa\ "" (pointer to traling NULL)
1545 * aa\\ "" (pointer to traling NULL)
1546 * aa\\bb bb
1547 * aa\\\bb \bb
1548 * c:\aa\ "aa\"
1549 * \\aa aa
1550 * \\aa\b aa\b
1552 LPSTR WINAPI PathFindNextComponentA(LPCSTR pszPath)
1554 LPSTR pos;
1556 TRACE("%s\n", pszPath);
1558 if(!pszPath || !*pszPath) return NULL;
1559 if(!(pos = StrChrA(pszPath, '\\')))
1560 return (LPSTR) pszPath + strlen(pszPath);
1561 pos++;
1562 if(pos[0] == '\\') pos++;
1563 return pos;
1566 /*************************************************************************
1567 * PathFindNextComponentW [SHLWAPI.@]
1569 LPWSTR WINAPI PathFindNextComponentW(LPCWSTR pszPath)
1571 LPWSTR pos;
1573 TRACE("%s\n", debugstr_w(pszPath));
1575 if(!pszPath || !*pszPath) return NULL;
1576 if (!(pos = StrChrW(pszPath, '\\')))
1577 return (LPWSTR) pszPath + lstrlenW(pszPath);
1578 pos++;
1579 if(pos[0] == '\\') pos++;
1580 return pos;
1583 /*************************************************************************
1584 * PathAddExtensionA [SHLWAPI.@]
1586 * NOTES
1587 * it adds never a dot
1590 BOOL WINAPI PathAddExtensionA(
1591 LPSTR pszPath,
1592 LPCSTR pszExtension)
1594 if (*pszPath)
1596 if (*(PathFindExtensionA(pszPath))) return FALSE;
1598 if (!pszExtension || *pszExtension=='\0')
1599 strcat(pszPath, "exe");
1600 else
1601 strcat(pszPath, pszExtension);
1604 return TRUE;
1607 /*************************************************************************
1608 * PathAddExtensionW [SHLWAPI.@]
1610 BOOL WINAPI PathAddExtensionW(
1611 LPWSTR pszPath,
1612 LPCWSTR pszExtension)
1614 static const WCHAR ext[] = { 'e','x','e',0 };
1616 if (*pszPath)
1618 if (*(PathFindExtensionW(pszPath))) return FALSE;
1620 if (!pszExtension || *pszExtension=='\0')
1621 lstrcatW(pszPath, ext);
1622 else
1623 lstrcatW(pszPath, pszExtension);
1625 return TRUE;
1629 /*************************************************************************
1630 * PathMakePrettyA [SHLWAPI.@]
1632 BOOL WINAPI PathMakePrettyA(
1633 LPSTR lpPath)
1635 FIXME("%s\n", lpPath);
1636 return TRUE;
1639 /*************************************************************************
1640 * PathMakePrettyW [SHLWAPI.@]
1642 BOOL WINAPI PathMakePrettyW(
1643 LPWSTR lpPath)
1645 FIXME("%s\n", debugstr_w(lpPath));
1646 return TRUE;
1650 /*************************************************************************
1651 * PathCommonPrefixA [SHLWAPI.@]
1653 int WINAPI PathCommonPrefixA(
1654 LPCSTR pszFile1,
1655 LPCSTR pszFile2,
1656 LPSTR achPath)
1658 FIXME("%s %s %p\n", pszFile1, pszFile2, achPath);
1659 return 0;
1662 /*************************************************************************
1663 * PathCommonPrefixW [SHLWAPI.@]
1665 int WINAPI PathCommonPrefixW(
1666 LPCWSTR pszFile1,
1667 LPCWSTR pszFile2,
1668 LPWSTR achPath)
1670 FIXME("%s %s %p\n", debugstr_w(pszFile1), debugstr_w(pszFile2),achPath );
1671 return 0;
1674 /*************************************************************************
1675 * PathCompactPathA [SHLWAPI.@]
1677 BOOL WINAPI PathCompactPathA(HDC hDC, LPSTR pszPath, UINT dx)
1679 FIXME("0x%08x %s 0x%08x\n", hDC, pszPath, dx);
1680 return FALSE;
1683 /*************************************************************************
1684 * PathCompactPathW [SHLWAPI.@]
1686 BOOL WINAPI PathCompactPathW(HDC hDC, LPWSTR pszPath, UINT dx)
1688 FIXME("0x%08x %s 0x%08x\n", hDC, debugstr_w(pszPath), dx);
1689 return FALSE;
1692 /*************************************************************************
1693 * PathGetCharTypeA [SHLWAPI.@]
1695 UINT WINAPI PathGetCharTypeA(UCHAR ch)
1697 FIXME("%c\n", ch);
1698 return 0;
1701 /*************************************************************************
1702 * PathGetCharTypeW [SHLWAPI.@]
1704 UINT WINAPI PathGetCharTypeW(WCHAR ch)
1706 FIXME("%c\n", ch);
1707 return 0;
1710 /*************************************************************************
1711 * PathMakeSystemFolderA [SHLWAPI.@]
1713 BOOL WINAPI PathMakeSystemFolderA(LPCSTR pszPath)
1715 FIXME("%s\n", pszPath);
1716 return FALSE;
1719 /*************************************************************************
1720 * PathMakeSystemFolderW [SHLWAPI.@]
1722 BOOL WINAPI PathMakeSystemFolderW(LPCWSTR pszPath)
1724 FIXME("%s\n", debugstr_w(pszPath));
1725 return FALSE;
1728 /*************************************************************************
1729 * PathRenameExtensionA [SHLWAPI.@]
1731 BOOL WINAPI PathRenameExtensionA(LPSTR pszPath, LPCSTR pszExt)
1733 FIXME("%s %s\n", pszPath, pszExt);
1734 return FALSE;
1737 /*************************************************************************
1738 * PathRenameExtensionW [SHLWAPI.@]
1740 BOOL WINAPI PathRenameExtensionW(LPWSTR pszPath, LPCWSTR pszExt)
1742 FIXME("%s %s\n", debugstr_w(pszPath), debugstr_w(pszExt));
1743 return FALSE;
1746 /*************************************************************************
1747 * PathSearchAndQualifyA [SHLWAPI.@]
1749 BOOL WINAPI PathSearchAndQualifyA(
1750 LPCSTR pszPath,
1751 LPSTR pszBuf,
1752 UINT cchBuf)
1754 FIXME("%s %s 0x%08x\n", pszPath, pszBuf, cchBuf);
1755 return FALSE;
1758 /*************************************************************************
1759 * PathSearchAndQualifyW [SHLWAPI.@]
1761 BOOL WINAPI PathSearchAndQualifyW(
1762 LPCWSTR pszPath,
1763 LPWSTR pszBuf,
1764 UINT cchBuf)
1766 FIXME("%s %s 0x%08x\n", debugstr_w(pszPath), debugstr_w(pszBuf), cchBuf);
1767 return FALSE;
1770 /*************************************************************************
1771 * PathSkipRootA [SHLWAPI.@]
1773 LPSTR WINAPI PathSkipRootA(LPCSTR pszPath)
1775 FIXME("%s\n", pszPath);
1776 return (LPSTR)pszPath;
1779 /*************************************************************************
1780 * PathSkipRootW [SHLWAPI.@]
1782 LPWSTR WINAPI PathSkipRootW(LPCWSTR pszPath)
1784 FIXME("%s\n", debugstr_w(pszPath));
1785 return (LPWSTR)pszPath;
1788 /*************************************************************************
1789 * PathCreateFromUrlA [SHLWAPI.@]
1791 HRESULT WINAPI PathCreateFromUrlA(
1792 LPCSTR pszUrl,
1793 LPSTR pszPath,
1794 LPDWORD pcchPath,
1795 DWORD dwFlags)
1797 FIXME("%s %p %p 0x%08lx\n",
1798 pszUrl, pszPath, pcchPath, dwFlags);
1799 return S_OK;
1802 /*************************************************************************
1803 * PathCreateFromUrlW [SHLWAPI.@]
1805 HRESULT WINAPI PathCreateFromUrlW(
1806 LPCWSTR pszUrl,
1807 LPWSTR pszPath,
1808 LPDWORD pcchPath,
1809 DWORD dwFlags)
1811 FIXME("%s %p %p 0x%08lx\n",
1812 debugstr_w(pszUrl), pszPath, pcchPath, dwFlags);
1813 return S_OK;
1816 /*************************************************************************
1817 * PathRelativePathToA [SHLWAPI.@]
1819 BOOL WINAPI PathRelativePathToA(
1820 LPSTR pszPath,
1821 LPCSTR pszFrom,
1822 DWORD dwAttrFrom,
1823 LPCSTR pszTo,
1824 DWORD dwAttrTo)
1826 FIXME("%s %s 0x%08lx %s 0x%08lx\n",
1827 pszPath, pszFrom, dwAttrFrom, pszTo, dwAttrTo);
1828 return FALSE;
1831 /*************************************************************************
1832 * PathRelativePathToW [SHLWAPI.@]
1834 BOOL WINAPI PathRelativePathToW(
1835 LPWSTR pszPath,
1836 LPCWSTR pszFrom,
1837 DWORD dwAttrFrom,
1838 LPCWSTR pszTo,
1839 DWORD dwAttrTo)
1841 FIXME("%s %s 0x%08lx %s 0x%08lx\n",
1842 debugstr_w(pszPath), debugstr_w(pszFrom), dwAttrFrom, debugstr_w(pszTo), dwAttrTo);
1843 return FALSE;
1846 /*************************************************************************
1847 * PathUnmakeSystemFolderA [SHLWAPI.@]
1849 BOOL WINAPI PathUnmakeSystemFolderA(LPCSTR pszPath)
1851 FIXME("%s\n", pszPath);
1852 return FALSE;
1855 /*************************************************************************
1856 * PathUnmakeSystemFolderW [SHLWAPI.@]
1858 BOOL WINAPI PathUnmakeSystemFolderW(LPCWSTR pszPath)
1860 FIXME("%s\n", debugstr_w(pszPath));
1861 return FALSE;
1865 ########## special ##########
1868 /*************************************************************************
1869 * PathSetDlgItemPathA [SHLWAPI.@]
1871 * NOTES
1872 * use PathCompactPath to make sure, the path fits into the control
1874 BOOL WINAPI PathSetDlgItemPathA(HWND hDlg, int id, LPCSTR pszPath)
1875 { TRACE("%x %x %s\n",hDlg, id, pszPath);
1876 return SetDlgItemTextA(hDlg, id, pszPath);
1879 /*************************************************************************
1880 * PathSetDlgItemPathW [SHLWAPI.@]
1882 BOOL WINAPI PathSetDlgItemPathW(HWND hDlg, int id, LPCWSTR pszPath)
1883 { TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
1884 return SetDlgItemTextW(hDlg, id, pszPath);