Fixed merge error.
[wine/wine64.git] / dlls / shlwapi / path.c
blob549ec124466b288b588d2c07818afaae1abfa1eb
1 /*
2 * Path Functions
3 */
5 #include <ctype.h>
6 #include <string.h>
7 #include <stdlib.h>
9 #include "winerror.h"
10 #include "wine/unicode.h"
11 #include "winbase.h"
12 #include "wingdi.h"
13 #include "winuser.h"
14 #include "winreg.h"
15 #define NO_SHLWAPI_STREAM
16 #include "shlwapi.h"
17 #include "debugtools.h"
18 #include "ordinal.h"
20 DEFAULT_DEBUG_CHANNEL(shell);
22 INT __cdecl _wtoi(LPWSTR string);
24 #define isSlash(x) ((x)=='\\' || (x)=='/')
26 ########## Combining and Constructing paths ##########
29 /*************************************************************************
30 * PathAppendA [SHLWAPI.@]
32 * NOTES
33 * concat path lpszPath2 onto lpszPath1
35 * FIXME
36 * the resulting path is also canonicalized
38 BOOL WINAPI PathAppendA(
39 LPSTR lpszPath1,
40 LPCSTR lpszPath2)
42 TRACE("%s %s\n",lpszPath1, lpszPath2);
43 while (lpszPath2[0]=='\\') lpszPath2++;
44 PathCombineA(lpszPath1,lpszPath1,lpszPath2);
45 return TRUE;
48 /*************************************************************************
49 * PathAppendW [SHLWAPI.@]
51 BOOL WINAPI PathAppendW(
52 LPWSTR lpszPath1,
53 LPCWSTR lpszPath2)
55 TRACE("%s %s\n",debugstr_w(lpszPath1), debugstr_w(lpszPath2));
56 while (lpszPath2[0]=='\\') lpszPath2++;
57 PathCombineW(lpszPath1,lpszPath1,lpszPath2);
58 return TRUE;
61 /*************************************************************************
62 * PathCombineA [SHLWAPI.@]
64 * NOTES
65 * if lpszFile='.' skip it
66 * szDest can be equal to lpszFile. Thats why we use sTemp
68 * FIXME
69 * the resulting path is also canonicalized
71 LPSTR WINAPI PathCombineA(
72 LPSTR szDest,
73 LPCSTR lpszDir,
74 LPCSTR lpszFile)
76 char sTemp[MAX_PATH];
77 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, lpszDir, lpszFile, lpszFile);
80 if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
82 strcpy(szDest,lpszDir);
83 return szDest;
86 /* if lpszFile is a complete path don't care about lpszDir */
87 if (PathGetDriveNumberA(lpszFile) != -1)
89 strcpy(szDest,lpszFile);
91 else if (lpszFile[0] == '\\' )
93 strcpy(sTemp,lpszDir);
94 PathStripToRootA(sTemp);
95 strcat(sTemp,lpszFile);
96 strcpy(szDest,sTemp);
98 else
100 strcpy(sTemp,lpszDir);
101 PathAddBackslashA(sTemp);
102 strcat(sTemp,lpszFile);
103 strcpy(szDest,sTemp);
105 return szDest;
108 /*************************************************************************
109 * PathCombineW [SHLWAPI.@]
111 LPWSTR WINAPI PathCombineW(
112 LPWSTR szDest,
113 LPCWSTR lpszDir,
114 LPCWSTR lpszFile)
116 WCHAR sTemp[MAX_PATH];
117 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, debugstr_w(lpszDir),
118 lpszFile, debugstr_w(lpszFile));
121 if (!lpszFile || !lpszFile[0] || (lpszFile[0]==(WCHAR)'.' && !lpszFile[1]) )
123 strcpyW(szDest,lpszDir);
124 return szDest;
127 /* if lpszFile is a complete path don't care about lpszDir */
128 if (PathGetDriveNumberW(lpszFile) != -1)
130 strcpyW(szDest,lpszFile);
132 else if (lpszFile[0] == (WCHAR)'\\' )
134 strcpyW(sTemp,lpszDir);
135 PathStripToRootW(sTemp);
136 strcatW(sTemp,lpszFile);
137 strcpyW(szDest,sTemp);
139 else
141 strcpyW(sTemp,lpszDir);
142 PathAddBackslashW(sTemp);
143 strcatW(sTemp,lpszFile);
144 strcpyW(szDest,sTemp);
146 return szDest;
149 /*************************************************************************
150 * PathAddBackslashA [SHLWAPI.@]
152 * NOTES
153 * append \ if there is none
155 LPSTR WINAPI PathAddBackslashA(LPSTR lpszPath)
157 int len;
158 TRACE("%p->%s\n",lpszPath,lpszPath);
160 len = strlen(lpszPath);
161 if (len && lpszPath[len-1]!='\\')
163 lpszPath[len] = '\\';
164 lpszPath[len+1]= 0x00;
165 return lpszPath+len+1;
167 return lpszPath+len;
170 /*************************************************************************
171 * PathAddBackslashW [SHLWAPI.@]
173 LPWSTR WINAPI PathAddBackslashW(LPWSTR lpszPath)
175 int len;
176 TRACE("%p->%s\n",lpszPath,debugstr_w(lpszPath));
178 len = strlenW(lpszPath);
179 if (len && lpszPath[len-1]!=(WCHAR)'\\')
181 lpszPath[len] = (WCHAR)'\\';
182 lpszPath[len+1]= 0x00;
183 return lpszPath+len+1;
185 return lpszPath+len;
188 /*************************************************************************
189 * PathBuildRootA [SHLWAPI.@]
191 LPSTR WINAPI PathBuildRootA(LPSTR lpszPath, int drive)
193 TRACE("%p %i\n",lpszPath, drive);
195 strcpy(lpszPath,"A:\\");
196 lpszPath[0]+=drive;
197 return lpszPath;
200 /*************************************************************************
201 * PathBuildRootW [SHLWAPI.@]
203 LPWSTR WINAPI PathBuildRootW(LPWSTR lpszPath, int drive)
205 lpszPath[0] = 'A' + drive;
206 lpszPath[1] = ':';
207 lpszPath[2] = '\\';
208 lpszPath[3] = 0;
209 TRACE("%p %i\n",debugstr_w(lpszPath), drive);
210 return lpszPath;
214 Extracting Component Parts
217 /*************************************************************************
218 * PathFindFileNameA [SHLWAPI.@]
220 LPSTR WINAPI PathFindFileNameA(LPCSTR lpszPath)
222 LPCSTR lastSlash = lpszPath;
224 TRACE("%s\n",lpszPath);
225 while (*lpszPath)
227 if ( isSlash(lpszPath[0]) && lpszPath[1])
228 lastSlash = lpszPath+1;
229 lpszPath = CharNextA(lpszPath);
231 return (LPSTR)lastSlash;
235 /*************************************************************************
236 * PathFindFileNameW [SHLWAPI.@]
238 LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
240 LPCWSTR wslash;
241 wslash = lpszPath;
243 TRACE("%s\n",debugstr_w(wslash));
244 while (lpszPath[0])
246 if (((lpszPath[0]=='\\') || (lpszPath[0]==':')) && lpszPath[1] && lpszPath[1]!='\\')
247 wslash = lpszPath+1;
248 lpszPath = CharNextW(lpszPath);
250 return (LPWSTR)wslash;
253 /*************************************************************************
254 * PathFindExtensionA [SHLWAPI.@]
256 * NOTES
257 * returns pointer to last . in last lpszPath component or at \0.
260 LPSTR WINAPI PathFindExtensionA(LPCSTR lpszPath)
262 LPCSTR lastpoint = NULL;
264 TRACE("%p %s\n",lpszPath,lpszPath);
266 while (*lpszPath)
268 if (*lpszPath=='\\'||*lpszPath==' ')
269 lastpoint=NULL;
270 if (*lpszPath=='.')
271 lastpoint=lpszPath;
272 lpszPath = CharNextA(lpszPath);
274 return (LPSTR)(lastpoint?lastpoint:lpszPath);
277 /*************************************************************************
278 * PathFindExtensionW [SHLWAPI.@]
280 LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
282 LPCWSTR lastpoint = NULL;
284 TRACE("(%p %s)\n",lpszPath,debugstr_w(lpszPath));
286 while (*lpszPath)
288 if (*lpszPath==(WCHAR)'\\'||*lpszPath==(WCHAR)' ')
289 lastpoint=NULL;
290 if (*lpszPath==(WCHAR)'.')
291 lastpoint=lpszPath;
292 lpszPath = CharNextW(lpszPath);
294 return (LPWSTR)(lastpoint?lastpoint:lpszPath);
297 /*************************************************************************
298 * PathGetArgsA [SHLWAPI.@]
300 * NOTES
301 * look for next arg in string. handle "quoted" strings
302 * returns pointer to argument *AFTER* the space. Or to the \0.
304 * FIXME
305 * quoting by '\'
307 LPSTR WINAPI PathGetArgsA(LPCSTR lpszPath)
309 BOOL qflag = FALSE;
311 TRACE("%s\n",lpszPath);
313 while (*lpszPath)
315 if ((*lpszPath==' ') && !qflag)
316 return (LPSTR)lpszPath+1;
317 if (*lpszPath=='"')
318 qflag=!qflag;
319 lpszPath = CharNextA(lpszPath);
321 return (LPSTR)lpszPath;
324 /*************************************************************************
325 * PathGetArgsW [SHLWAPI.@]
327 LPWSTR WINAPI PathGetArgsW(LPCWSTR lpszPath)
329 BOOL qflag = FALSE;
331 TRACE("%s\n",debugstr_w(lpszPath));
333 while (*lpszPath)
335 if ((*lpszPath==' ') && !qflag)
336 return (LPWSTR)lpszPath+1;
337 if (*lpszPath=='"')
338 qflag=!qflag;
339 lpszPath = CharNextW(lpszPath);
341 return (LPWSTR)lpszPath;
344 /*************************************************************************
345 * PathGetDriveNumberA [SHLWAPI.@]
347 int WINAPI PathGetDriveNumberA(LPCSTR lpszPath)
349 int chr = tolower(lpszPath[0]);
351 TRACE ("%s\n",debugstr_a(lpszPath));
353 if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
354 return tolower(lpszPath[0]) - 'a' ;
357 /*************************************************************************
358 * PathGetDriveNumberW [SHLWAPI.@]
360 int WINAPI PathGetDriveNumberW(LPCWSTR lpszPath)
362 int chr = tolowerW(lpszPath[0]);
364 TRACE ("%s\n",debugstr_w(lpszPath));
366 if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
367 return tolowerW(lpszPath[0]) - 'a' ;
370 /*************************************************************************
371 * PathRemoveFileSpecA [SHLWAPI.@]
373 * NOTES
374 * truncates passed argument to a valid path
375 * returns if the string was modified or not.
376 * "\foo\xx\foo"-> "\foo\xx"
377 * "\" -> "\"
378 * "a:\foo" -> "a:\"
380 BOOL WINAPI PathRemoveFileSpecA(LPSTR lpszPath)
382 LPSTR cutplace = lpszPath;
383 BOOL ret = FALSE;
385 TRACE("%s\n",lpszPath);
387 if(lpszPath)
389 while (*lpszPath == '\\') cutplace = ++lpszPath;
391 while (*lpszPath)
393 if(lpszPath[0] == '\\') cutplace = lpszPath;
395 if(lpszPath[0] == ':')
397 cutplace = lpszPath + 1;
398 if (lpszPath[1] == '\\') cutplace++;
399 lpszPath++;
401 lpszPath = CharNextA(lpszPath);
402 if (!lpszPath) break;
405 ret = (*cutplace!='\0');
406 *cutplace = '\0';
408 return ret;
411 /*************************************************************************
412 * PathRemoveFileSpecW [SHLWAPI.@]
414 BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
416 LPWSTR cutplace = lpszPath;
417 BOOL ret = FALSE;
419 TRACE("%s\n",debugstr_w(lpszPath));
421 if(lpszPath)
423 while (*lpszPath == '\\') cutplace = ++lpszPath;
425 while (*lpszPath)
427 if(lpszPath[0] == '\\') cutplace = lpszPath;
429 if(lpszPath[0] == ':')
431 cutplace = lpszPath + 1;
432 if (lpszPath[1] == '\\') cutplace++;
433 lpszPath++;
435 lpszPath = CharNextW(lpszPath);
436 if (!lpszPath) break;
439 ret = (*cutplace!='\0');
440 *cutplace = '\0';
442 return ret;
445 /*************************************************************************
446 * PathStripPathA [SHLWAPI.@]
448 * NOTES
449 * removes the path from the beginning of a filename
451 void WINAPI PathStripPathA(LPSTR lpszPath)
453 LPSTR lpszFileName = PathFindFileNameA(lpszPath);
455 TRACE("%s\n", lpszPath);
457 if(lpszFileName)
458 RtlMoveMemory(lpszPath, lpszFileName, strlen(lpszFileName)+1);
461 /*************************************************************************
462 * PathStripPathW [SHLWAPI.@]
464 void WINAPI PathStripPathW(LPWSTR lpszPath)
466 LPWSTR lpszFileName = PathFindFileNameW(lpszPath);
468 TRACE("%s\n", debugstr_w(lpszPath));
469 if(lpszFileName)
470 RtlMoveMemory(lpszPath, lpszFileName, (strlenW(lpszFileName)+1)*sizeof(WCHAR));
473 /*************************************************************************
474 * PathStripToRootA [SHLWAPI.@]
476 BOOL WINAPI PathStripToRootA(LPSTR lpszPath)
478 TRACE("%s\n", lpszPath);
480 if (!lpszPath) return FALSE;
481 while(!PathIsRootA(lpszPath))
482 if (!PathRemoveFileSpecA(lpszPath)) return FALSE;
483 return TRUE;
486 /*************************************************************************
487 * PathStripToRootW [SHLWAPI.@]
489 BOOL WINAPI PathStripToRootW(LPWSTR lpszPath)
491 TRACE("%s\n", debugstr_w(lpszPath));
493 if (!lpszPath) return FALSE;
494 while(!PathIsRootW(lpszPath))
495 if (!PathRemoveFileSpecW(lpszPath)) return FALSE;
496 return TRUE;
499 /*************************************************************************
500 * PathRemoveArgsA [SHLWAPI.@]
503 void WINAPI PathRemoveArgsA(LPSTR lpszPath)
505 TRACE("%s\n",lpszPath);
507 if(lpszPath)
509 LPSTR lpszArgs = PathGetArgsA(lpszPath);
510 if (!*lpszArgs)
512 LPSTR lpszLastChar = CharPrevA(lpszPath, lpszArgs);
513 if(*lpszLastChar==' ') *lpszLastChar = '\0';
518 /*************************************************************************
519 * PathRemoveArgsW [SHLWAPI.@]
521 void WINAPI PathRemoveArgsW(LPWSTR lpszPath)
523 TRACE("%s\n", debugstr_w(lpszPath));
525 if(lpszPath)
527 LPWSTR lpszArgs = PathGetArgsW(lpszPath);
528 if (!*lpszArgs)
530 LPWSTR lpszLastChar = CharPrevW(lpszPath, lpszArgs);
531 if(*lpszLastChar==' ') *lpszLastChar = '\0';
536 /*************************************************************************
537 * PathRemoveExtensionA [SHLWAPI.@]
539 void WINAPI PathRemoveExtensionA(LPSTR lpszPath)
541 LPSTR lpszExtension = PathFindExtensionA(lpszPath);
543 TRACE("%s\n", lpszPath);
545 if (lpszExtension) *lpszExtension='\0';
548 /*************************************************************************
549 * PathRemoveExtensionW [SHLWAPI.@]
551 void WINAPI PathRemoveExtensionW(LPWSTR lpszPath)
553 LPWSTR lpszExtension = PathFindExtensionW(lpszPath);
555 TRACE("%s\n", debugstr_w(lpszPath));
557 if (lpszExtension) *lpszExtension='\0';
560 /*************************************************************************
561 * PathRemoveBackslashA [SHLWAPI.@]
563 * If the path ends in a backslash it is replaced by a NULL
564 * and the address of the NULL is returned
565 * Otherwise
566 * the address of the last character is returned.
568 * FIXME
569 * "c:\": keep backslash
571 LPSTR WINAPI PathRemoveBackslashA( LPSTR lpszPath )
573 int len;
574 LPSTR szTemp = NULL;
576 if(lpszPath)
578 len = strlen(lpszPath);
579 szTemp = CharPrevA(lpszPath, lpszPath+len);
580 if (! PathIsRootA(lpszPath))
582 if (*szTemp == '\\') *szTemp = '\0';
585 return szTemp;
588 /*************************************************************************
589 * PathRemoveBackslashW [SHLWAPI.@]
591 LPWSTR WINAPI PathRemoveBackslashW( LPWSTR lpszPath )
593 int len;
594 LPWSTR szTemp = NULL;
596 if(lpszPath)
598 len = strlenW(lpszPath);
599 szTemp = CharPrevW(lpszPath, lpszPath+len);
600 if (! PathIsRootW(lpszPath))
602 if (*szTemp == '\\') *szTemp = '\0';
605 return szTemp;
610 Path Manipulations
613 /*************************************************************************
614 * PathRemoveBlanksA [SHLWAPI.@]
616 * NOTES
617 * remove spaces from beginning and end of passed string
619 void WINAPI PathRemoveBlanksA(LPSTR str)
621 LPSTR x = str;
623 TRACE("%s\n",str);
625 if(str)
627 while (*x==' ') x = CharNextA(x);
628 if (x!=str) strcpy(str,x);
629 x=str+strlen(str)-1;
630 while (*x==' ') x = CharPrevA(str, x);
631 if (*x==' ') *x='\0';
635 /*************************************************************************
636 * PathRemoveBlanksW [SHLWAPI.@]
638 void WINAPI PathRemoveBlanksW(LPWSTR str)
640 LPWSTR x = str;
642 TRACE("%s\n",debugstr_w(str));
644 if(str)
646 while (*x==' ') x = CharNextW(x);
647 if (x!=str) strcpyW(str,x);
648 x=str+strlenW(str)-1;
649 while (*x==' ') x = CharPrevW(str, x);
650 if (*x==' ') *x='\0';
654 /*************************************************************************
655 * PathQuoteSpacesA [SHLWAPI.@]
658 LPSTR WINAPI PathQuoteSpacesA(LPSTR lpszPath)
660 TRACE("%s\n",lpszPath);
662 if(StrChrA(lpszPath,' '))
664 int len = strlen(lpszPath);
665 RtlMoveMemory(lpszPath+1, lpszPath, len);
666 *(lpszPath++) = '"';
667 lpszPath += len;
668 *(lpszPath++) = '"';
669 *(lpszPath) = '\0';
670 return --lpszPath;
672 return 0;
675 /*************************************************************************
676 * PathQuoteSpacesW [SHLWAPI.@]
678 LPWSTR WINAPI PathQuoteSpacesW(LPWSTR lpszPath)
680 TRACE("%s\n",debugstr_w(lpszPath));
682 if(StrChrW(lpszPath,' '))
684 int len = strlenW(lpszPath);
685 RtlMoveMemory(lpszPath+1, lpszPath, len*sizeof(WCHAR));
686 *(lpszPath++) = '"';
687 lpszPath += len;
688 *(lpszPath++) = '"';
689 *(lpszPath) = '\0';
690 return --lpszPath;
692 return 0;
695 /*************************************************************************
696 * PathUnquoteSpacesA [SHLWAPI.@]
698 * NOTES
699 * unquote string (remove ")
701 VOID WINAPI PathUnquoteSpacesA(LPSTR str)
703 DWORD len = strlen(str);
705 TRACE("%s\n",str);
707 if (*str!='"')
708 return;
709 if (str[len-1]!='"')
710 return;
711 str[len-1]='\0';
712 strcpy(str,str+1);
713 return;
716 /*************************************************************************
717 * PathUnquoteSpacesW [SHLWAPI.@]
719 VOID WINAPI PathUnquoteSpacesW(LPWSTR str)
721 DWORD len = strlenW(str);
723 TRACE("%s\n",debugstr_w(str));
725 if (*str!='"')
726 return;
727 if (str[len-1]!='"')
728 return;
729 str[len-1]='\0';
730 strcpyW(str,str+1);
731 return;
734 /*************************************************************************
735 * PathParseIconLocationA [SHLWAPI.@]
737 int WINAPI PathParseIconLocationA(LPSTR lpszPath)
739 LPSTR lpstrComma = strchr(lpszPath, ',');
740 int ret = 0;
742 TRACE("%s\n", debugstr_a(lpszPath));
744 if (lpstrComma && lpstrComma[1])
746 lpstrComma[0]='\0';
747 ret = atoi(&lpstrComma[1]);
750 PathUnquoteSpacesA(lpszPath);
751 return ret;
754 /*************************************************************************
755 * PathParseIconLocationW [SHLWAPI.@]
757 int WINAPI PathParseIconLocationW(LPWSTR lpszPath)
759 LPWSTR lpstrComma = strchrW(lpszPath, ',');
760 int ret = 0;
762 TRACE("%s\n", debugstr_w(lpszPath));
764 if (lpstrComma && lpstrComma[1])
766 lpstrComma[0]='\0';
767 ret = _wtoi(&lpstrComma[1]);
769 PathUnquoteSpacesW(lpszPath);
770 return ret;
774 ########## cleaning and resolving paths ##########
777 /*************************************************************************
778 * PathFindOnPathA [SHLWAPI.@]
780 BOOL WINAPI PathFindOnPathA(LPSTR sFile, LPCSTR *sOtherDirs)
782 FIXME("%s %p\n",sFile, sOtherDirs);
783 return FALSE;
786 /*************************************************************************
787 * PathFindOnPathW [SHLWAPI.@]
789 BOOL WINAPI PathFindOnPathW(LPWSTR sFile, LPCWSTR *sOtherDirs)
791 FIXME("%s %p\n",debugstr_w(sFile), sOtherDirs);
792 return FALSE;
795 /*************************************************************************
796 * PathCompactPathExA [SHLWAPI.@]
798 BOOL WINAPI PathCompactPathExA(
799 LPSTR pszOut,
800 LPCSTR pszSrc,
801 UINT cchMax,
802 DWORD dwFlags)
804 FIXME("%p %s 0x%08x 0x%08lx\n", pszOut, pszSrc, cchMax, dwFlags);
805 return FALSE;
808 /*************************************************************************
809 * PathCompactPathExW [SHLWAPI.@]
811 BOOL WINAPI PathCompactPathExW(
812 LPWSTR pszOut,
813 LPCWSTR pszSrc,
814 UINT cchMax,
815 DWORD dwFlags)
817 FIXME("%p %s 0x%08x 0x%08lx\n", pszOut, debugstr_w(pszSrc), cchMax, dwFlags);
818 return FALSE;
822 ########## Path Testing ##########
825 /*************************************************************************
826 * PathIsUNCA [SHLWAPI.@]
828 * NOTES
829 * PathIsUNC(char*path);
831 BOOL WINAPI PathIsUNCA(LPCSTR lpszPath)
833 TRACE("%s\n",lpszPath);
835 return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
838 /*************************************************************************
839 * PathIsUNCW [SHLWAPI.@]
841 BOOL WINAPI PathIsUNCW(LPCWSTR lpszPath)
843 TRACE("%s\n",debugstr_w(lpszPath));
845 return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
848 /*************************************************************************
849 * PathIsRelativeA [SHLWAPI.@]
851 BOOL WINAPI PathIsRelativeA (LPCSTR lpszPath)
853 TRACE("lpszPath=%s\n",lpszPath);
855 return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
858 /*************************************************************************
859 * PathIsRelativeW [SHLWAPI.@]
861 BOOL WINAPI PathIsRelativeW (LPCWSTR lpszPath)
863 TRACE("lpszPath=%s\n",debugstr_w(lpszPath));
865 return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
868 /*************************************************************************
869 * PathIsRootA [SHLWAPI.@]
871 * notes
872 * TRUE if the path points to a root directory
874 BOOL WINAPI PathIsRootA(LPCSTR lpszPath)
876 TRACE("%s\n",lpszPath);
878 /* X:\ */
879 if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
880 return TRUE;
882 /* "\" */
883 if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
884 return TRUE;
886 /* UNC "\\<computer>\<share>" */
887 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
889 int foundbackslash = 0;
890 lpszPath += 2;
891 while (*lpszPath)
893 if (*lpszPath=='\\') foundbackslash++;
894 lpszPath = CharNextA(lpszPath);
896 if (foundbackslash <= 1)
897 return TRUE;
899 return FALSE;
902 /*************************************************************************
903 * PathIsRootW [SHLWAPI.@]
905 BOOL WINAPI PathIsRootW(LPCWSTR lpszPath)
907 TRACE("%s\n",debugstr_w(lpszPath));
909 /* X:\ */
910 if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
911 return TRUE;
913 /* "\" */
914 if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
915 return TRUE;
917 /* UNC "\\<computer>\<share>" */
918 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
920 int foundbackslash = 0;
921 lpszPath += 2;
922 while (*lpszPath)
924 if (*lpszPath=='\\') foundbackslash++;
925 lpszPath = CharNextW(lpszPath);
927 if (foundbackslash <= 1)
928 return TRUE;
930 return FALSE;
934 /*************************************************************************
935 * PathIsDirectoryA [SHLWAPI.@]
937 BOOL WINAPI PathIsDirectoryA(LPCSTR lpszPath)
939 DWORD dwAttr;
941 TRACE("%s\n", debugstr_a(lpszPath));
943 dwAttr = GetFileAttributesA(lpszPath);
944 return (dwAttr != -1) ? dwAttr & FILE_ATTRIBUTE_DIRECTORY : 0;
947 /*************************************************************************
948 * PathIsDirectoryW [SHLWAPI.@]
950 BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
952 DWORD dwAttr;
954 TRACE("%s\n", debugstr_w(lpszPath));
956 dwAttr = GetFileAttributesW(lpszPath);
957 return (dwAttr != -1) ? dwAttr & FILE_ATTRIBUTE_DIRECTORY : 0;
960 /*************************************************************************
961 * PathFileExistsA [SHLWAPI.@]
963 * NOTES
964 * file_exists(char *fn);
966 BOOL WINAPI PathFileExistsA(LPCSTR lpszPath)
968 TRACE("%s\n",lpszPath);
969 return (GetFileAttributesA(lpszPath)!=-1);
972 /*************************************************************************
973 * PathFileExistsW [SHLWAPI.@]
975 BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
977 TRACE("%s\n",debugstr_w(lpszPath));
978 return (GetFileAttributesW(lpszPath)!=-1);
981 /*************************************************************************
982 * PathMatchSingleMaskA [internal]
984 * NOTES
985 * internal (used by PathMatchSpec)
987 static BOOL PathMatchSingleMaskA(LPCSTR name, LPCSTR mask)
989 while (*name && *mask && *mask!=';')
991 if (*mask=='*')
995 if (PathMatchSingleMaskA(name,mask+1)) return 1; /* try substrings */
996 } while (*name++);
997 return 0;
999 if (toupper(*mask)!=toupper(*name) && *mask!='?') return 0;
1000 name = CharNextA(name);
1001 mask = CharNextA(mask);
1003 if (!*name)
1005 while (*mask=='*') mask++;
1006 if (!*mask || *mask==';') return 1;
1008 return 0;
1011 /*************************************************************************
1012 * PathMatchSingleMaskW [internal]
1014 static BOOL PathMatchSingleMaskW(LPCWSTR name, LPCWSTR mask)
1016 while (*name && *mask && *mask!=';')
1018 if (*mask=='*')
1022 if (PathMatchSingleMaskW(name,mask+1)) return 1; /* try substrings */
1023 } while (*name++);
1024 return 0;
1026 if (toupperW(*mask)!=toupperW(*name) && *mask!='?') return 0;
1027 name = CharNextW(name);
1028 mask = CharNextW(mask);
1030 if (!*name)
1032 while (*mask=='*') mask++;
1033 if (!*mask || *mask==';') return 1;
1035 return 0;
1037 /*************************************************************************
1038 * PathMatchSpecA [SHLWAPI.@]
1040 * NOTES
1041 * used from COMDLG32
1043 BOOL WINAPI PathMatchSpecA(LPCSTR name, LPCSTR mask)
1045 TRACE("%s %s\n",name,mask);
1047 if (!lstrcmpA( mask, "*.*" )) return 1; /* we don't require a period */
1049 while (*mask)
1051 if (PathMatchSingleMaskA(name,mask)) return 1; /* helper function */
1052 while (*mask && *mask!=';') mask = CharNextA(mask);
1053 if (*mask==';')
1055 mask++;
1056 while (*mask==' ') mask++; /* masks may be separated by "; " */
1059 return 0;
1062 /*************************************************************************
1063 * PathMatchSpecW [SHLWAPI.@]
1065 BOOL WINAPI PathMatchSpecW(LPCWSTR name, LPCWSTR mask)
1067 static const WCHAR stemp[] = { '*','.','*',0 };
1068 TRACE("%s %s\n",debugstr_w(name),debugstr_w(mask));
1070 if (!lstrcmpW( mask, stemp )) return 1; /* we don't require a period */
1072 while (*mask)
1074 if (PathMatchSingleMaskW(name,mask)) return 1; /* helper function */
1075 while (*mask && *mask!=';') mask = CharNextW(mask);
1076 if (*mask==';')
1078 mask++;
1079 while (*mask==' ') mask++; /* masks may be separated by "; " */
1082 return 0;
1085 /*************************************************************************
1086 * PathIsSameRootA [SHLWAPI.@]
1088 * FIXME
1089 * what to do with "\path" ??
1091 BOOL WINAPI PathIsSameRootA(LPCSTR lpszPath1, LPCSTR lpszPath2)
1093 TRACE("%s %s\n", lpszPath1, lpszPath2);
1095 if (PathIsRelativeA(lpszPath1) || PathIsRelativeA(lpszPath2)) return FALSE;
1097 /* usual path */
1098 if ( toupper(lpszPath1[0])==toupper(lpszPath2[0]) &&
1099 lpszPath1[1]==':' && lpszPath2[1]==':' &&
1100 lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
1101 return TRUE;
1103 /* UNC */
1104 if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
1105 lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
1107 int pos=2, bsfound=0;
1108 while (lpszPath1[pos] && lpszPath2[pos] &&
1109 (lpszPath1[pos] == lpszPath2[pos]))
1111 if (lpszPath1[pos]=='\\') bsfound++;
1112 if (bsfound == 2) return TRUE;
1113 pos++; /* FIXME: use CharNext*/
1115 return (lpszPath1[pos] == lpszPath2[pos]);
1117 return FALSE;
1120 /*************************************************************************
1121 * PathIsSameRootW [SHLWAPI.@]
1123 BOOL WINAPI PathIsSameRootW(LPCWSTR lpszPath1, LPCWSTR lpszPath2)
1125 TRACE("%s %s\n", debugstr_w(lpszPath1), debugstr_w(lpszPath2));
1127 if (PathIsRelativeW(lpszPath1) || PathIsRelativeW(lpszPath2)) return FALSE;
1129 /* usual path */
1130 if ( toupperW(lpszPath1[0])==toupperW(lpszPath2[0]) &&
1131 lpszPath1[1]==':' && lpszPath2[1]==':' &&
1132 lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
1133 return TRUE;
1135 /* UNC */
1136 if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
1137 lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
1139 int pos=2, bsfound=0;
1140 while (lpszPath1[pos] && lpszPath2[pos] &&
1141 (lpszPath1[pos] == lpszPath2[pos]))
1143 if (lpszPath1[pos]=='\\') bsfound++;
1144 if (bsfound == 2) return TRUE;
1145 pos++;/* FIXME: use CharNext*/
1147 return (lpszPath1[pos] == lpszPath2[pos]);
1149 return FALSE;
1152 /*************************************************************************
1153 * PathIsURLA (SHLWAPI.@)
1155 BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
1157 UNKNOWN_SHLWAPI_1 base;
1158 DWORD res1;
1160 if (!lpstrPath || !*lpstrPath) return FALSE;
1162 /* get protocol */
1163 base.size = 24;
1164 res1 = SHLWAPI_1(lpstrPath, &base);
1165 return (base.fcncde) ? TRUE : FALSE;
1168 /*************************************************************************
1169 * PathIsURLW (SHLWAPI.@)
1171 BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
1173 UNKNOWN_SHLWAPI_2 base;
1174 DWORD res1;
1176 if (!lpstrPath || !*lpstrPath) return FALSE;
1178 /* get protocol */
1179 base.size = 24;
1180 res1 = SHLWAPI_2(lpstrPath, &base);
1181 return (base.fcncde) ? TRUE : FALSE;
1185 /*************************************************************************
1186 * PathIsContentTypeA [SHLWAPI.@]
1188 BOOL WINAPI PathIsContentTypeA(LPCSTR pszPath, LPCSTR pszContentType)
1190 FIXME("%s %s\n", pszPath, pszContentType);
1191 return FALSE;
1194 /*************************************************************************
1195 * PathIsContentTypeW [SHLWAPI.@]
1197 BOOL WINAPI PathIsContentTypeW(LPCWSTR pszPath, LPCWSTR pszContentType)
1199 FIXME("%s %s\n", debugstr_w(pszPath), debugstr_w(pszContentType));
1200 return FALSE;
1203 /*************************************************************************
1204 * PathIsFileSpecA [SHLWAPI.@]
1206 BOOL WINAPI PathIsFileSpecA(LPCSTR pszPath)
1208 FIXME("%s\n", pszPath);
1209 return FALSE;
1212 /*************************************************************************
1213 * PathIsFileSpecW [SHLWAPI.@]
1215 BOOL WINAPI PathIsFileSpecW(LPCWSTR pszPath)
1217 FIXME("%s\n", debugstr_w(pszPath));
1218 return FALSE;
1221 /*************************************************************************
1222 * PathIsPrefixA [SHLWAPI.@]
1224 BOOL WINAPI PathIsPrefixA(LPCSTR pszPrefix, LPCSTR pszPath)
1226 FIXME("%s %s\n", pszPrefix, pszPath);
1227 return FALSE;
1230 /*************************************************************************
1231 * PathIsPrefixW [SHLWAPI.@]
1233 BOOL WINAPI PathIsPrefixW(LPCWSTR pszPrefix, LPCWSTR pszPath)
1235 FIXME("%s %s\n", debugstr_w(pszPrefix), debugstr_w(pszPath));
1236 return FALSE;
1239 /*************************************************************************
1240 * PathIsSystemFolderA [SHLWAPI.@]
1242 BOOL WINAPI PathIsSystemFolderA(LPCSTR pszPath, DWORD dwAttrb)
1244 FIXME("%s 0x%08lx\n", pszPath, dwAttrb);
1245 return FALSE;
1248 /*************************************************************************
1249 * PathIsSystemFolderW [SHLWAPI.@]
1251 BOOL WINAPI PathIsSystemFolderW(LPCWSTR pszPath, DWORD dwAttrb)
1253 FIXME("%s 0x%08lx\n", debugstr_w(pszPath), dwAttrb);
1254 return FALSE;
1257 /*************************************************************************
1258 * PathIsUNCServerA [SHLWAPI.@]
1260 BOOL WINAPI PathIsUNCServerA(
1261 LPCSTR lpszPath)
1263 TRACE("%s\n", debugstr_a(lpszPath));
1264 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
1266 int foundbackslash = 0;
1267 lpszPath += 2;
1268 while (*lpszPath)
1270 if (*lpszPath=='\\') foundbackslash++;
1271 lpszPath = CharNextA(lpszPath);
1273 if (foundbackslash == 0)
1274 return TRUE;
1276 return FALSE;
1279 /*************************************************************************
1280 * PathIsUNCServerW [SHLWAPI.@]
1282 BOOL WINAPI PathIsUNCServerW(
1283 LPCWSTR lpszPath)
1285 TRACE("%s\n", debugstr_w(lpszPath));
1286 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
1288 int foundbackslash = 0;
1289 lpszPath += 2;
1290 while (*lpszPath)
1292 if (*lpszPath=='\\') foundbackslash++;
1293 lpszPath = CharNextW(lpszPath);
1295 if (foundbackslash == 0)
1296 return TRUE;
1298 return FALSE;
1301 /*************************************************************************
1302 * PathIsUNCServerShareA [SHLWAPI.@]
1304 BOOL WINAPI PathIsUNCServerShareA(
1305 LPCSTR lpszPath)
1307 TRACE("%s\n", debugstr_a(lpszPath));
1308 if (!lpszPath) return FALSE;
1309 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
1311 int foundbackslash = 0;
1312 lpszPath += 2;
1313 while (*lpszPath)
1315 if (*lpszPath=='\\') foundbackslash++;
1316 lpszPath = CharNextA(lpszPath);
1318 if (foundbackslash == 1)
1319 return TRUE;
1321 return FALSE;
1324 /*************************************************************************
1325 * PathIsUNCServerShareW [SHLWAPI.@]
1327 BOOL WINAPI PathIsUNCServerShareW(
1328 LPCWSTR lpszPath)
1330 TRACE("%s\n", debugstr_w(lpszPath));
1331 if (!lpszPath) return FALSE;
1332 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
1334 int foundbackslash = 0;
1335 lpszPath += 2;
1336 while (*lpszPath)
1338 if (*lpszPath=='\\') foundbackslash++;
1339 lpszPath = CharNextW(lpszPath);
1341 if (foundbackslash == 1)
1342 return TRUE;
1344 return FALSE;
1347 /*************************************************************************
1348 * PathCanonicalizeA [SHLWAPI.@]
1350 * FIXME
1351 * returnvalue, use CharNext
1354 BOOL WINAPI PathCanonicalizeA(LPSTR pszBuf, LPCSTR pszPath)
1356 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = strlen(pszPath);
1357 BOOL bModifyed = FALSE;
1359 TRACE("%p %s\n", pszBuf, pszPath);
1361 pszBuf[OffsetDst]='\0';
1363 /* keep the root of the path */
1364 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
1366 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1368 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
1370 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1371 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1372 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
1374 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1375 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
1377 /* C:\. */
1378 OffsetSrc++; LenSrc--; bModifyed = TRUE;
1380 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
1382 /* C:\.. */
1383 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1388 /* ".\" at the beginning of the path */
1389 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
1391 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1394 while ( LenSrc )
1396 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
1398 /* "\.." found, go one deeper */
1399 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
1400 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
1401 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
1402 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
1404 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
1406 /* "\." found, skip it */
1407 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
1409 else
1411 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
1414 pszBuf[OffsetDst] = '\0';
1415 TRACE("-- %s %u\n", pszBuf, bModifyed);
1416 return bModifyed;
1420 /*************************************************************************
1421 * PathCanonicalizeW [SHLWAPI.@]
1423 * FIXME
1424 * returnvalue, use CharNext
1426 BOOL WINAPI PathCanonicalizeW(LPWSTR pszBuf, LPCWSTR pszPath)
1428 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = strlenW(pszPath);
1429 BOOL bModifyed = FALSE;
1431 TRACE("%p %s\n", pszBuf, debugstr_w(pszPath));
1433 pszBuf[OffsetDst]='\0';
1435 /* keep the root of the path */
1436 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
1438 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1440 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
1442 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1443 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1444 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
1446 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1447 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
1449 /* C:\. */
1450 OffsetSrc++; LenSrc--; bModifyed = TRUE;
1452 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
1454 /* C:\.. */
1455 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1460 /* ".\" at the beginning of the path */
1461 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
1463 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1466 while ( LenSrc )
1468 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
1470 /* "\.." found, go one deeper */
1471 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
1472 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
1473 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
1474 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
1476 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
1478 /* "\." found, skip it */
1479 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
1481 else
1483 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
1486 pszBuf[OffsetDst] = '\0';
1487 TRACE("-- %s %u\n", debugstr_w(pszBuf), bModifyed);
1488 return bModifyed;
1491 /*************************************************************************
1492 * PathFindNextComponentA [SHLWAPI.@]
1494 * NOTES
1495 * special cases:
1496 * "" null
1497 * aa "" (pointer to traling NULL)
1498 * aa\ "" (pointer to traling NULL)
1499 * aa\\ "" (pointer to traling NULL)
1500 * aa\\bb bb
1501 * aa\\\bb \bb
1502 * c:\aa\ "aa\"
1503 * \\aa aa
1504 * \\aa\b aa\b
1506 LPSTR WINAPI PathFindNextComponentA(LPCSTR pszPath)
1508 LPSTR pos;
1510 TRACE("%s\n", pszPath);
1512 if(!pszPath || !*pszPath) return NULL;
1513 if(!(pos = StrChrA(pszPath, '\\')))
1514 return (LPSTR) pszPath + strlen(pszPath);
1515 pos++;
1516 if(pos[0] == '\\') pos++;
1517 return pos;
1520 /*************************************************************************
1521 * PathFindNextComponentW [SHLWAPI.@]
1523 LPWSTR WINAPI PathFindNextComponentW(LPCWSTR pszPath)
1525 LPWSTR pos;
1527 TRACE("%s\n", debugstr_w(pszPath));
1529 if(!pszPath || !*pszPath) return NULL;
1530 if (!(pos = StrChrW(pszPath, '\\')))
1531 return (LPWSTR) pszPath + strlenW(pszPath);
1532 pos++;
1533 if(pos[0] == '\\') pos++;
1534 return pos;
1537 /*************************************************************************
1538 * PathAddExtensionA [SHLWAPI.@]
1540 * NOTES
1541 * it adds never a dot
1544 BOOL WINAPI PathAddExtensionA(
1545 LPSTR pszPath,
1546 LPCSTR pszExtension)
1548 if (*pszPath)
1550 if (*(PathFindExtensionA(pszPath))) return FALSE;
1552 if (!pszExtension || *pszExtension=='\0')
1553 strcat(pszPath, "exe");
1554 else
1555 strcat(pszPath, pszExtension);
1558 return TRUE;
1561 /*************************************************************************
1562 * PathAddExtensionW [SHLWAPI.@]
1564 BOOL WINAPI PathAddExtensionW(
1565 LPWSTR pszPath,
1566 LPCWSTR pszExtension)
1568 static const WCHAR ext[] = { 'e','x','e',0 };
1570 if (*pszPath)
1572 if (*(PathFindExtensionW(pszPath))) return FALSE;
1574 if (!pszExtension || *pszExtension=='\0')
1575 strcatW(pszPath, ext);
1576 else
1577 strcatW(pszPath, pszExtension);
1579 return TRUE;
1583 /*************************************************************************
1584 * PathMakePrettyA [SHLWAPI.@]
1586 BOOL WINAPI PathMakePrettyA(
1587 LPSTR lpPath)
1589 FIXME("%s\n", lpPath);
1590 return TRUE;
1593 /*************************************************************************
1594 * PathMakePrettyW [SHLWAPI.@]
1596 BOOL WINAPI PathMakePrettyW(
1597 LPWSTR lpPath)
1599 FIXME("%s\n", debugstr_w(lpPath));
1600 return TRUE;
1604 /*************************************************************************
1605 * PathCommonPrefixA [SHLWAPI.@]
1607 int WINAPI PathCommonPrefixA(
1608 LPCSTR pszFile1,
1609 LPCSTR pszFile2,
1610 LPSTR achPath)
1612 FIXME("%s %s %p\n", pszFile1, pszFile2, achPath);
1613 return 0;
1616 /*************************************************************************
1617 * PathCommonPrefixW [SHLWAPI.@]
1619 int WINAPI PathCommonPrefixW(
1620 LPCWSTR pszFile1,
1621 LPCWSTR pszFile2,
1622 LPWSTR achPath)
1624 FIXME("%s %s %p\n", debugstr_w(pszFile1), debugstr_w(pszFile2),achPath );
1625 return 0;
1628 /*************************************************************************
1629 * PathCompactPathA [SHLWAPI.@]
1631 BOOL WINAPI PathCompactPathA(HDC hDC, LPSTR pszPath, UINT dx)
1633 FIXME("0x%08x %s 0x%08x\n", hDC, pszPath, dx);
1634 return FALSE;
1637 /*************************************************************************
1638 * PathCompactPathW [SHLWAPI.@]
1640 BOOL WINAPI PathCompactPathW(HDC hDC, LPWSTR pszPath, UINT dx)
1642 FIXME("0x%08x %s 0x%08x\n", hDC, debugstr_w(pszPath), dx);
1643 return FALSE;
1646 /*************************************************************************
1647 * PathGetCharTypeA [SHLWAPI.@]
1649 UINT WINAPI PathGetCharTypeA(UCHAR ch)
1651 UINT flags = 0;
1653 TRACE("%c\n", ch);
1655 /* We could use them in filenames, but this would confuse 'ls' */
1656 if (iscntrl(ch))
1657 return GCT_INVALID;
1658 if ((ch == '*') || (ch=='?'))
1659 return GCT_WILD;
1660 if ((ch == '\\') || (ch=='/'))
1661 return GCT_SEPARATOR;
1662 flags = 0;
1663 /* all normal characters, no lower case letters */
1664 if ((ch > ' ') && (ch < 0x7f) && !islower(ch))
1665 flags |= GCT_SHORTCHAR;
1666 /* All other characters are valid in long filenames, even umlauts */
1667 return flags | GCT_LFNCHAR;
1670 /*************************************************************************
1671 * PathGetCharTypeW [SHLWAPI.@]
1673 UINT WINAPI PathGetCharTypeW(WCHAR ch)
1675 FIXME("%c, using ascii version\n", ch);
1676 return PathGetCharTypeA(ch);
1679 /*************************************************************************
1680 * PathMakeSystemFolderA [SHLWAPI.@]
1682 BOOL WINAPI PathMakeSystemFolderA(LPCSTR pszPath)
1684 FIXME("%s\n", pszPath);
1685 return FALSE;
1688 /*************************************************************************
1689 * PathMakeSystemFolderW [SHLWAPI.@]
1691 BOOL WINAPI PathMakeSystemFolderW(LPCWSTR pszPath)
1693 FIXME("%s\n", debugstr_w(pszPath));
1694 return FALSE;
1697 /*************************************************************************
1698 * PathRenameExtensionA [SHLWAPI.@]
1700 BOOL WINAPI PathRenameExtensionA(LPSTR pszPath, LPCSTR pszExt)
1702 LPSTR pszExtension = PathFindExtensionA(pszPath);
1704 if (!pszExtension) return FALSE;
1705 if (pszExtension-pszPath + strlen(pszExt) > MAX_PATH) return FALSE;
1707 strcpy(pszExtension, pszExt);
1708 TRACE("%s\n", pszPath);
1709 return TRUE;
1712 /*************************************************************************
1713 * PathRenameExtensionW [SHLWAPI.@]
1715 BOOL WINAPI PathRenameExtensionW(LPWSTR pszPath, LPCWSTR pszExt)
1717 LPWSTR pszExtension = PathFindExtensionW(pszPath);
1719 if (!pszExtension) return FALSE;
1720 if (pszExtension-pszPath + strlenW(pszExt) > MAX_PATH) return FALSE;
1722 strcpyW(pszExtension, pszExt);
1723 TRACE("%s\n", debugstr_w(pszPath));
1724 return TRUE;
1727 /*************************************************************************
1728 * PathSearchAndQualifyA [SHLWAPI.@]
1730 BOOL WINAPI PathSearchAndQualifyA(
1731 LPCSTR pszPath,
1732 LPSTR pszBuf,
1733 UINT cchBuf)
1735 FIXME("%s %s 0x%08x\n", pszPath, pszBuf, cchBuf);
1736 return FALSE;
1739 /*************************************************************************
1740 * PathSearchAndQualifyW [SHLWAPI.@]
1742 BOOL WINAPI PathSearchAndQualifyW(
1743 LPCWSTR pszPath,
1744 LPWSTR pszBuf,
1745 UINT cchBuf)
1747 FIXME("%s %s 0x%08x\n", debugstr_w(pszPath), debugstr_w(pszBuf), cchBuf);
1748 return FALSE;
1751 /*************************************************************************
1752 * PathSkipRootA [SHLWAPI.@]
1754 LPSTR WINAPI PathSkipRootA(LPCSTR pszPath)
1756 FIXME("%s\n", pszPath);
1757 return (LPSTR)pszPath;
1760 /*************************************************************************
1761 * PathSkipRootW [SHLWAPI.@]
1763 LPWSTR WINAPI PathSkipRootW(LPCWSTR pszPath)
1765 FIXME("%s\n", debugstr_w(pszPath));
1766 return (LPWSTR)pszPath;
1769 /*************************************************************************
1770 * PathCreateFromUrlA [SHLWAPI.@]
1772 HRESULT WINAPI PathCreateFromUrlA(
1773 LPCSTR pszUrl,
1774 LPSTR pszPath,
1775 LPDWORD pcchPath,
1776 DWORD dwFlags)
1778 /* extracts thing prior to : in pszURL and checks against:
1779 * https
1780 * shell
1781 * local
1782 * about - if match returns E_INVALIDARG
1784 FIXME("%s %p %p 0x%08lx\n",
1785 pszUrl, pszPath, pcchPath, dwFlags);
1786 return E_INVALIDARG;
1789 /*************************************************************************
1790 * PathCreateFromUrlW [SHLWAPI.@]
1792 HRESULT WINAPI PathCreateFromUrlW(
1793 LPCWSTR pszUrl,
1794 LPWSTR pszPath,
1795 LPDWORD pcchPath,
1796 DWORD dwFlags)
1798 /* extracts thing prior to : in pszURL and checks against:
1799 * https
1800 * shell
1801 * local
1802 * about - if match returns E_INVALIDARG
1804 FIXME("%s %p %p 0x%08lx\n",
1805 debugstr_w(pszUrl), pszPath, pcchPath, dwFlags);
1806 return E_INVALIDARG;
1809 /*************************************************************************
1810 * PathRelativePathToA [SHLWAPI.@]
1812 BOOL WINAPI PathRelativePathToA(
1813 LPSTR pszPath,
1814 LPCSTR pszFrom,
1815 DWORD dwAttrFrom,
1816 LPCSTR pszTo,
1817 DWORD dwAttrTo)
1819 FIXME("%s %s 0x%08lx %s 0x%08lx\n",
1820 pszPath, pszFrom, dwAttrFrom, pszTo, dwAttrTo);
1821 return FALSE;
1824 /*************************************************************************
1825 * PathRelativePathToW [SHLWAPI.@]
1827 BOOL WINAPI PathRelativePathToW(
1828 LPWSTR pszPath,
1829 LPCWSTR pszFrom,
1830 DWORD dwAttrFrom,
1831 LPCWSTR pszTo,
1832 DWORD dwAttrTo)
1834 FIXME("%s %s 0x%08lx %s 0x%08lx\n",
1835 debugstr_w(pszPath), debugstr_w(pszFrom), dwAttrFrom, debugstr_w(pszTo), dwAttrTo);
1836 return FALSE;
1839 /*************************************************************************
1840 * PathUnmakeSystemFolderA [SHLWAPI.@]
1842 BOOL WINAPI PathUnmakeSystemFolderA(LPCSTR pszPath)
1844 FIXME("%s\n", pszPath);
1845 return FALSE;
1848 /*************************************************************************
1849 * PathUnmakeSystemFolderW [SHLWAPI.@]
1851 BOOL WINAPI PathUnmakeSystemFolderW(LPCWSTR pszPath)
1853 FIXME("%s\n", debugstr_w(pszPath));
1854 return FALSE;
1858 ########## special ##########
1861 /*************************************************************************
1862 * PathSetDlgItemPathA [SHLWAPI.@]
1864 * NOTES
1865 * use PathCompactPath to make sure, the path fits into the control
1867 BOOL WINAPI PathSetDlgItemPathA(HWND hDlg, int id, LPCSTR pszPath)
1868 { TRACE("%x %x %s\n",hDlg, id, pszPath);
1869 return SetDlgItemTextA(hDlg, id, pszPath);
1872 /*************************************************************************
1873 * PathSetDlgItemPathW [SHLWAPI.@]
1875 BOOL WINAPI PathSetDlgItemPathW(HWND hDlg, int id, LPCWSTR pszPath)
1876 { TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
1877 return SetDlgItemTextW(hDlg, id, pszPath);