4 * Many of this functions are in SHLWAPI.DLL also
9 #include "debugtools.h"
11 #include "winversion.h"
15 #include "shell32_main.h"
18 #include "wine/undocshell.h"
19 #include "wine/unicode.h"
22 DEFAULT_DEBUG_CHANNEL(shell);
24 #define isSlash(x) ((x)=='\\' || (x)=='/')
26 ########## Combining and Constructing paths ##########
29 /*************************************************************************
30 * PathAppendA [SHLWAPI.@]
33 * concat path lpszPath2 onto lpszPath1
36 * the resulting path is also canonicalized
38 BOOL WINAPI PathAppendA(
42 TRACE("%s %s\n",lpszPath1, lpszPath2);
43 while (lpszPath2[0]=='\\') lpszPath2++;
44 PathCombineA(lpszPath1,lpszPath1,lpszPath2);
48 /*************************************************************************
49 * PathAppendW [SHLWAPI.@]
51 BOOL WINAPI PathAppendW(
55 TRACE("%s %s\n",debugstr_w(lpszPath1), debugstr_w(lpszPath2));
56 while (lpszPath2[0]=='\\') lpszPath2++;
57 PathCombineW(lpszPath1,lpszPath1,lpszPath2);
61 /*************************************************************************
62 * PathAppendAW [SHELL32.36]
64 BOOL WINAPI PathAppendAW(
68 if (VERSION_OsIsUnicode())
69 return PathAppendW(lpszPath1, lpszPath2);
70 return PathAppendA(lpszPath1, lpszPath2);
73 /*************************************************************************
74 * PathCombineA [SHLWAPI.@]
77 * if lpszFile='.' skip it
78 * szDest can be equal to lpszFile. Thats why we use sTemp
81 * the resulting path is also canonicalized
83 LPSTR WINAPI PathCombineA(
89 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, lpszDir, lpszFile, lpszFile);
92 if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
94 strcpy(szDest,lpszDir);
98 /* if lpszFile is a complete path don't care about lpszDir */
99 if (PathGetDriveNumberA(lpszFile) != -1)
101 strcpy(szDest,lpszFile);
103 else if (lpszFile[0] == '\\' )
105 strcpy(sTemp,lpszDir);
106 PathStripToRootA(sTemp);
107 strcat(sTemp,lpszFile);
108 strcpy(szDest,sTemp);
112 strcpy(sTemp,lpszDir);
113 PathAddBackslashA(sTemp);
114 strcat(sTemp,lpszFile);
115 strcpy(szDest,sTemp);
120 /*************************************************************************
121 * PathCombineW [SHLWAPI.@]
123 LPWSTR WINAPI PathCombineW(
128 WCHAR sTemp[MAX_PATH];
129 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, debugstr_w(lpszDir),
130 lpszFile, debugstr_w(lpszFile));
133 if (!lpszFile || !lpszFile[0] || (lpszFile[0]==(WCHAR)'.' && !lpszFile[1]) )
135 strcpyW(szDest,lpszDir);
139 /* if lpszFile is a complete path don't care about lpszDir */
140 if (PathGetDriveNumberW(lpszFile) != -1)
142 strcpyW(szDest,lpszFile);
144 else if (lpszFile[0] == (WCHAR)'\\' )
146 strcpyW(sTemp,lpszDir);
147 PathStripToRootW(sTemp);
148 strcatW(sTemp,lpszFile);
149 strcpyW(szDest,sTemp);
153 strcpyW(sTemp,lpszDir);
154 PathAddBackslashW(sTemp);
155 strcatW(sTemp,lpszFile);
156 strcpyW(szDest,sTemp);
161 /*************************************************************************
162 * PathCombineAW [SHELL32.37]
164 LPVOID WINAPI PathCombineAW(
169 if (VERSION_OsIsUnicode())
170 return PathCombineW( szDest, lpszDir, lpszFile );
171 return PathCombineA( szDest, lpszDir, lpszFile );
174 /*************************************************************************
175 * PathAddBackslashA [SHLWAPI.@]
178 * append \ if there is none
180 LPSTR WINAPI PathAddBackslashA(LPSTR lpszPath)
183 TRACE("%p->%s\n",lpszPath,lpszPath);
185 len = strlen(lpszPath);
186 if (len && lpszPath[len-1]!='\\')
188 lpszPath[len] = '\\';
189 lpszPath[len+1]= 0x00;
190 return lpszPath+len+1;
195 /*************************************************************************
196 * PathAddBackslashW [SHLWAPI.@]
198 LPWSTR WINAPI PathAddBackslashW(LPWSTR lpszPath)
201 TRACE("%p->%s\n",lpszPath,debugstr_w(lpszPath));
203 len = strlenW(lpszPath);
204 if (len && lpszPath[len-1]!=(WCHAR)'\\')
206 lpszPath[len] = (WCHAR)'\\';
207 lpszPath[len+1]= 0x00;
208 return lpszPath+len+1;
213 /*************************************************************************
214 * PathAddBackslashAW [SHELL32.32]
216 LPVOID WINAPI PathAddBackslashAW(LPVOID lpszPath)
218 if(VERSION_OsIsUnicode())
219 return PathAddBackslashW(lpszPath);
220 return PathAddBackslashA(lpszPath);
223 /*************************************************************************
224 * PathBuildRootA [SHLWAPI.@]
226 LPSTR WINAPI PathBuildRootA(LPSTR lpszPath, int drive)
228 TRACE("%p %i\n",lpszPath, drive);
230 strcpy(lpszPath,"A:\\");
235 /*************************************************************************
236 * PathBuildRootW [SHLWAPI.@]
238 LPWSTR WINAPI PathBuildRootW(LPWSTR lpszPath, int drive)
240 TRACE("%p %i\n",debugstr_w(lpszPath), drive);
242 lstrcpyAtoW(lpszPath,"A:\\");
247 /*************************************************************************
248 * PathBuildRootAW [SHELL32.30]
250 LPVOID WINAPI PathBuildRootAW(LPVOID lpszPath, int drive)
252 if(VERSION_OsIsUnicode())
253 return PathBuildRootW(lpszPath, drive);
254 return PathBuildRootA(lpszPath, drive);
258 Extracting Component Parts
261 /*************************************************************************
262 * PathFindFileNameA [SHLWAPI.@]
264 LPSTR WINAPI PathFindFileNameA(LPCSTR lpszPath)
266 LPCSTR lastSlash = lpszPath;
268 TRACE("%s\n",lpszPath);
271 if ( isSlash(lpszPath[0]) && lpszPath[1])
272 lastSlash = lpszPath+1;
273 lpszPath = CharNextA(lpszPath);
275 return (LPSTR)lastSlash;
279 /*************************************************************************
280 * PathFindFileNameW [SHLWAPI.@]
282 LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
287 TRACE("%s\n",debugstr_w(wslash));
290 if (((lpszPath[0]=='\\') || (lpszPath[0]==':')) && lpszPath[1] && lpszPath[1]!='\\')
292 lpszPath = CharNextW(lpszPath);
294 return (LPWSTR)wslash;
297 /*************************************************************************
298 * PathFindFileNameAW [SHELL32.34]
300 LPVOID WINAPI PathFindFileNameAW(LPCVOID lpszPath)
302 if(VERSION_OsIsUnicode())
303 return PathFindFileNameW(lpszPath);
304 return PathFindFileNameA(lpszPath);
307 /*************************************************************************
308 * PathFindExtensionA [SHLWAPI.@]
311 * returns pointer to last . in last lpszPath component or at \0.
314 LPSTR WINAPI PathFindExtensionA(LPCSTR lpszPath)
316 LPCSTR lastpoint = NULL;
318 TRACE("%p %s\n",lpszPath,lpszPath);
322 if (*lpszPath=='\\'||*lpszPath==' ')
326 lpszPath = CharNextA(lpszPath);
328 return (LPSTR)(lastpoint?lastpoint:lpszPath);
331 /*************************************************************************
332 * PathFindExtensionW [SHLWAPI.@]
334 LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
336 LPCWSTR lastpoint = NULL;
338 TRACE("(%p %s)\n",lpszPath,debugstr_w(lpszPath));
342 if (*lpszPath==(WCHAR)'\\'||*lpszPath==(WCHAR)' ')
344 if (*lpszPath==(WCHAR)'.')
346 lpszPath = CharNextW(lpszPath);
348 return (LPWSTR)(lastpoint?lastpoint:lpszPath);
351 /*************************************************************************
352 * PathFindExtensionAW [SHELL32.31]
354 LPVOID WINAPI PathFindExtensionAW(LPCVOID lpszPath)
356 if (VERSION_OsIsUnicode())
357 return PathFindExtensionW(lpszPath);
358 return PathFindExtensionA(lpszPath);
362 /*************************************************************************
363 * PathGetExtensionA [internal]
366 * exported by ordinal
367 * return value points to the first char after the dot
369 LPSTR WINAPI PathGetExtensionA(LPCSTR lpszPath)
371 TRACE("(%s)\n",lpszPath);
373 lpszPath = PathFindExtensionA(lpszPath);
374 return (LPSTR)(*lpszPath?(lpszPath+1):lpszPath);
377 /*************************************************************************
378 * PathGetExtensionW [internal]
380 LPWSTR WINAPI PathGetExtensionW(LPCWSTR lpszPath)
382 TRACE("(%s)\n",debugstr_w(lpszPath));
384 lpszPath = PathFindExtensionW(lpszPath);
385 return (LPWSTR)(*lpszPath?(lpszPath+1):lpszPath);
388 /*************************************************************************
389 * PathGetExtensionAW [SHELL32.158]
391 LPVOID WINAPI PathGetExtensionAW(LPCVOID lpszPath)
393 if (VERSION_OsIsUnicode())
394 return PathGetExtensionW(lpszPath);
395 return PathGetExtensionA(lpszPath);
398 /*************************************************************************
399 * PathGetArgsA [SHLWAPI.@]
402 * look for next arg in string. handle "quoted" strings
403 * returns pointer to argument *AFTER* the space. Or to the \0.
408 LPSTR WINAPI PathGetArgsA(LPCSTR lpszPath)
412 TRACE("%s\n",lpszPath);
416 if ((*lpszPath==' ') && !qflag)
417 return (LPSTR)lpszPath+1;
420 lpszPath = CharNextA(lpszPath);
422 return (LPSTR)lpszPath;
425 /*************************************************************************
426 * PathGetArgsW [SHLWAPI.@]
428 LPWSTR WINAPI PathGetArgsW(LPCWSTR lpszPath)
432 TRACE("%s\n",debugstr_w(lpszPath));
436 if ((*lpszPath==' ') && !qflag)
437 return (LPWSTR)lpszPath+1;
440 lpszPath = CharNextW(lpszPath);
442 return (LPWSTR)lpszPath;
445 /*************************************************************************
446 * PathGetArgsAW [SHELL32.52]
448 LPVOID WINAPI PathGetArgsAW(LPVOID lpszPath)
450 if (VERSION_OsIsUnicode())
451 return PathGetArgsW(lpszPath);
452 return PathGetArgsA(lpszPath);
455 /*************************************************************************
456 * PathGetDriveNumberA [SHLWAPI.@]
458 int WINAPI PathGetDriveNumberA(LPCSTR lpszPath)
460 int chr = tolower(lpszPath[0]);
462 TRACE ("%s\n",debugstr_a(lpszPath));
464 if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
465 return tolower(lpszPath[0]) - 'a' ;
468 /*************************************************************************
469 * PathGetDriveNumberW [SHLWAPI.@]
471 int WINAPI PathGetDriveNumberW(LPCWSTR lpszPath)
473 int chr = tolowerW(lpszPath[0]);
475 TRACE ("%s\n",debugstr_w(lpszPath));
477 if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
478 return tolowerW(lpszPath[0]) - 'a' ;
481 /*************************************************************************
482 * PathGetDriveNumber [SHELL32.57]
484 int WINAPI PathGetDriveNumberAW(LPVOID lpszPath)
486 if (VERSION_OsIsUnicode())
487 return PathGetDriveNumberW(lpszPath);
488 return PathGetDriveNumberA(lpszPath);
491 /*************************************************************************
492 * PathRemoveFileSpecA [SHLWAPI.@]
495 * truncates passed argument to a valid path
496 * returns if the string was modified or not.
497 * "\foo\xx\foo"-> "\foo\xx"
501 BOOL WINAPI PathRemoveFileSpecA(LPSTR lpszPath)
503 LPSTR cutplace = lpszPath;
506 TRACE("%s\n",lpszPath);
510 while (*lpszPath == '\\') cutplace = ++lpszPath;
514 if(lpszPath[0] == '\\') cutplace = lpszPath;
516 if(lpszPath[0] == ':')
518 cutplace = lpszPath + 1;
519 if (lpszPath[1] == '\\') cutplace++;
522 lpszPath = CharNextA(lpszPath);
523 if (!lpszPath) break;
526 ret = (*cutplace!='\0');
532 /*************************************************************************
533 * PathRemoveFileSpecW [SHLWAPI.@]
535 BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
537 LPWSTR cutplace = lpszPath;
540 TRACE("%s\n",debugstr_w(lpszPath));
544 while (*lpszPath == '\\') cutplace = ++lpszPath;
548 if(lpszPath[0] == '\\') cutplace = lpszPath;
550 if(lpszPath[0] == ':')
552 cutplace = lpszPath + 1;
553 if (lpszPath[1] == '\\') cutplace++;
556 lpszPath = CharNextW(lpszPath);
557 if (!lpszPath) break;
560 ret = (*cutplace!='\0');
566 /*************************************************************************
567 * PathRemoveFileSpec [SHELL32.35]
569 BOOL WINAPI PathRemoveFileSpecAW(LPVOID lpszPath)
571 if (VERSION_OsIsUnicode())
572 return PathRemoveFileSpecW(lpszPath);
573 return PathRemoveFileSpecA(lpszPath);
576 /*************************************************************************
577 * PathStripPathA [SHELLWAPI.@]
580 * removes the path from the beginning of a filename
582 void WINAPI PathStripPathA(LPSTR lpszPath)
584 LPSTR lpszFileName = PathFindFileNameA(lpszPath);
586 TRACE("%s\n", lpszPath);
589 RtlMoveMemory(lpszPath, lpszFileName, strlen(lpszFileName)+1);
592 /*************************************************************************
593 * PathStripPathW [SHELLWAPI.@]
595 void WINAPI PathStripPathW(LPWSTR lpszPath)
597 LPWSTR lpszFileName = PathFindFileNameW(lpszPath);
599 TRACE("%s\n", debugstr_w(lpszPath));
601 RtlMoveMemory(lpszPath, lpszFileName, (lstrlenW(lpszFileName)+1)*sizeof(WCHAR));
604 /*************************************************************************
605 * PathStripPathAW [SHELL32.38]
607 void WINAPI PathStripPathAW(LPVOID lpszPath)
609 if (VERSION_OsIsUnicode())
610 return PathStripPathW(lpszPath);
611 return PathStripPathA(lpszPath);
614 /*************************************************************************
615 * PathStripToRootA [SHLWAPI.@]
617 BOOL WINAPI PathStripToRootA(LPSTR lpszPath)
619 TRACE("%s\n", lpszPath);
621 if (!lpszPath) return FALSE;
622 while(!PathIsRootA(lpszPath))
623 if (!PathRemoveFileSpecA(lpszPath)) return FALSE;
627 /*************************************************************************
628 * PathStripToRootW [SHLWAPI.@]
630 BOOL WINAPI PathStripToRootW(LPWSTR lpszPath)
632 TRACE("%s\n", debugstr_w(lpszPath));
634 if (!lpszPath) return FALSE;
635 while(!PathIsRootW(lpszPath))
636 if (!PathRemoveFileSpecW(lpszPath)) return FALSE;
640 /*************************************************************************
641 * PathStripToRootAW [SHELL32.50]
643 BOOL WINAPI PathStripToRootAW(LPVOID lpszPath)
645 if (VERSION_OsIsUnicode())
646 return PathStripToRootW(lpszPath);
647 return PathStripToRootA(lpszPath);
650 /*************************************************************************
651 * PathRemoveArgsA [SHLWAPI.@]
654 void WINAPI PathRemoveArgsA(LPSTR lpszPath)
656 TRACE("%s\n",lpszPath);
660 LPSTR lpszArgs = PathGetArgsA(lpszPath);
663 LPSTR lpszLastChar = CharPrevA(lpszPath, lpszArgs);
664 if(*lpszLastChar==' ') *lpszLastChar = '\0';
669 /*************************************************************************
670 * PathRemoveArgsW [SHLWAPI.@]
672 void WINAPI PathRemoveArgsW(LPWSTR lpszPath)
674 TRACE("%s\n", debugstr_w(lpszPath));
678 LPWSTR lpszArgs = PathGetArgsW(lpszPath);
681 LPWSTR lpszLastChar = CharPrevW(lpszPath, lpszArgs);
682 if(*lpszLastChar==' ') *lpszLastChar = '\0';
687 /*************************************************************************
688 * PathRemoveArgsAW [SHELL32.251]
690 void WINAPI PathRemoveArgsAW(LPVOID lpszPath)
692 if (VERSION_OsIsUnicode())
693 PathRemoveArgsW(lpszPath);
694 PathRemoveArgsA(lpszPath);
697 /*************************************************************************
698 * PathRemoveExtensionA [SHLWAPI.@]
700 void WINAPI PathRemoveExtensionA(LPSTR lpszPath)
702 LPSTR lpszExtension = PathFindExtensionA(lpszPath);
704 TRACE("%s\n", lpszPath);
706 if (lpszExtension) *lpszExtension='\0';
709 /*************************************************************************
710 * PathRemoveExtensionW [SHLWAPI.@]
712 void WINAPI PathRemoveExtensionW(LPWSTR lpszPath)
714 LPWSTR lpszExtension = PathFindExtensionW(lpszPath);
716 TRACE("%s\n", debugstr_w(lpszPath));
718 if (lpszExtension) *lpszExtension='\0';
721 /*************************************************************************
722 * PathRemoveExtensionAW [SHELL32.250]
724 void WINAPI PathRemoveExtensionAW(LPVOID lpszPath)
726 if (VERSION_OsIsUnicode())
727 return PathRemoveExtensionW(lpszPath);
728 return PathRemoveExtensionA(lpszPath);
731 /*************************************************************************
732 * PathRemoveBackslashA [SHLWAPI.@]
734 * If the path ends in a backslash it is replaced by a NULL
735 * and the address of the NULL is returned
737 * the address of the last character is returned.
740 * "c:\": keep backslash
742 LPSTR WINAPI PathRemoveBackslashA( LPSTR lpszPath )
749 len = strlen(lpszPath);
750 szTemp = CharPrevA(lpszPath, lpszPath+len);
751 if (! PathIsRootA(lpszPath))
753 if (*szTemp == '\\') *szTemp = '\0';
759 /*************************************************************************
760 * PathRemoveBackslashW [SHLWAPI.@]
762 LPWSTR WINAPI PathRemoveBackslashW( LPWSTR lpszPath )
765 LPWSTR szTemp = NULL;
769 len = lstrlenW(lpszPath);
770 szTemp = CharPrevW(lpszPath, lpszPath+len);
771 if (! PathIsRootW(lpszPath))
773 if (*szTemp == '\\') *szTemp = '\0';
783 /*************************************************************************
784 * PathGetShortPathA [internal]
786 LPSTR WINAPI PathGetShortPathA(LPSTR lpszPath)
788 FIXME("%s stub\n", lpszPath);
792 /*************************************************************************
793 * PathGetShortPathW [internal]
795 LPWSTR WINAPI PathGetShortPathW(LPWSTR lpszPath)
797 FIXME("%s stub\n", debugstr_w(lpszPath));
801 /*************************************************************************
802 * PathGetShortPathAW [SHELL32.92]
804 LPVOID WINAPI PathGetShortPathAW(LPVOID lpszPath)
806 if(VERSION_OsIsUnicode())
807 return PathGetShortPathW(lpszPath);
808 return PathGetShortPathA(lpszPath);
811 /*************************************************************************
812 * PathRemoveBlanksA [SHLWAPI.@]
815 * remove spaces from beginning and end of passed string
817 void WINAPI PathRemoveBlanksA(LPSTR str)
825 while (*x==' ') x = CharNextA(x);
826 if (x!=str) strcpy(str,x);
828 while (*x==' ') x = CharPrevA(str, x);
829 if (*x==' ') *x='\0';
833 /*************************************************************************
834 * PathRemoveBlanksW [SHLWAPI.@]
836 void WINAPI PathRemoveBlanksW(LPWSTR str)
840 TRACE("%s\n",debugstr_w(str));
844 while (*x==' ') x = CharNextW(x);
845 if (x!=str) lstrcpyW(str,x);
846 x=str+lstrlenW(str)-1;
847 while (*x==' ') x = CharPrevW(str, x);
848 if (*x==' ') *x='\0';
852 /*************************************************************************
853 * PathRemoveBlanksAW [SHELL32.33]
855 void WINAPI PathRemoveBlanksAW(LPVOID str)
857 if(VERSION_OsIsUnicode())
858 PathRemoveBlanksW(str);
859 PathRemoveBlanksA(str);
862 /*************************************************************************
863 * PathQuoteSpacesA [SHLWAPI.@]
866 LPSTR WINAPI PathQuoteSpacesA(LPSTR lpszPath)
868 TRACE("%s\n",lpszPath);
870 if(StrChrA(lpszPath,' '))
872 int len = strlen(lpszPath);
873 RtlMoveMemory(lpszPath+1, lpszPath, len);
883 /*************************************************************************
884 * PathQuoteSpacesW [SHLWAPI.@]
886 LPWSTR WINAPI PathQuoteSpacesW(LPWSTR lpszPath)
888 TRACE("%s\n",debugstr_w(lpszPath));
890 if(StrChrW(lpszPath,' '))
892 int len = lstrlenW(lpszPath);
893 RtlMoveMemory(lpszPath+1, lpszPath, len*sizeof(WCHAR));
903 /*************************************************************************
904 * PathQuoteSpacesAW [SHELL32.55]
906 LPVOID WINAPI PathQuoteSpacesAW (LPVOID lpszPath)
908 if(VERSION_OsIsUnicode())
909 return PathQuoteSpacesW(lpszPath);
910 return PathQuoteSpacesA(lpszPath);
913 /*************************************************************************
914 * PathUnquoteSpacesA [SHLWAPI.@]
917 * unquote string (remove ")
919 VOID WINAPI PathUnquoteSpacesA(LPSTR str)
921 DWORD len = lstrlenA(str);
934 /*************************************************************************
935 * PathUnquoteSpacesW [SHLWAPI.@]
937 VOID WINAPI PathUnquoteSpacesW(LPWSTR str)
939 DWORD len = strlenW(str);
941 TRACE("%s\n",debugstr_w(str));
952 /*************************************************************************
953 * PathUnquoteSpacesAW [SHELL32.56]
955 VOID WINAPI PathUnquoteSpacesAW(LPVOID str)
957 if(VERSION_OsIsUnicode())
958 PathUnquoteSpacesW(str);
960 PathUnquoteSpacesA(str);
963 /*************************************************************************
964 * PathParseIconLocationA [SHLWAPI.@]
966 int WINAPI PathParseIconLocationA(LPSTR lpszPath)
968 LPSTR lpstrComma = strchr(lpszPath, ',');
970 FIXME("%s stub\n", debugstr_a(lpszPath));
972 if (lpstrComma && lpstrComma[1])
975 /* return atoi(&lpstrComma[1]); FIXME */
978 PathUnquoteSpacesA(lpszPath);
982 /*************************************************************************
983 * PathParseIconLocationW [SHLWAPI.@]
985 int WINAPI PathParseIconLocationW(LPWSTR lpszPath)
987 LPWSTR lpstrComma = strchrW(lpszPath, ',');
989 FIXME("%s stub\n", debugstr_w(lpszPath));
991 if (lpstrComma && lpstrComma[1])
994 /* return _wtoi(&lpstrComma[1]); FIXME */
996 PathUnquoteSpacesW(lpszPath);
1000 /*************************************************************************
1001 * PathParseIconLocationAW [SHELL32.249]
1003 int WINAPI PathParseIconLocationAW (LPVOID lpszPath)
1005 if(VERSION_OsIsUnicode())
1006 return PathParseIconLocationW(lpszPath);
1007 return PathParseIconLocationA(lpszPath);
1011 ########## Path Testing ##########
1013 /*************************************************************************
1014 * PathIsUNCA [SHLWAPI.@]
1017 * PathIsUNC(char*path);
1019 BOOL WINAPI PathIsUNCA(LPCSTR lpszPath)
1021 TRACE("%s\n",lpszPath);
1023 return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
1026 /*************************************************************************
1027 * PathIsUNCW [SHLWAPI.@]
1029 BOOL WINAPI PathIsUNCW(LPCWSTR lpszPath)
1031 TRACE("%s\n",debugstr_w(lpszPath));
1033 return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
1036 /*************************************************************************
1037 * PathIsUNCAW [SHELL32.39]
1039 BOOL WINAPI PathIsUNCAW (LPCVOID lpszPath)
1041 if (VERSION_OsIsUnicode())
1042 return PathIsUNCW( lpszPath );
1043 return PathIsUNCA( lpszPath );
1046 /*************************************************************************
1047 * PathIsRelativeA [SHLWAPI.@]
1049 BOOL WINAPI PathIsRelativeA (LPCSTR lpszPath)
1051 TRACE("lpszPath=%s\n",lpszPath);
1053 return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
1056 /*************************************************************************
1057 * PathIsRelativeW [SHLWAPI.@]
1059 BOOL WINAPI PathIsRelativeW (LPCWSTR lpszPath)
1061 TRACE("lpszPath=%s\n",debugstr_w(lpszPath));
1063 return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
1066 /*************************************************************************
1067 * PathIsRelativeAW [SHELL32.40]
1069 BOOL WINAPI PathIsRelativeAW (LPCVOID lpszPath)
1071 if (VERSION_OsIsUnicode())
1072 return PathIsRelativeW( lpszPath );
1073 return PathIsRelativeA( lpszPath );
1076 /*************************************************************************
1077 * PathIsRootA [SHLWAPI.@]
1080 * TRUE if the path points to a root directory
1082 BOOL WINAPI PathIsRootA(LPCSTR lpszPath)
1084 TRACE("%s\n",lpszPath);
1087 if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
1091 if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
1094 /* UNC "\\<computer>\<share>" */
1095 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
1097 int foundbackslash = 0;
1101 if (*lpszPath=='\\') foundbackslash++;
1102 lpszPath = CharNextA(lpszPath);
1104 if (foundbackslash <= 1)
1110 /*************************************************************************
1111 * PathIsRootW [SHLWAPI.@]
1113 BOOL WINAPI PathIsRootW(LPCWSTR lpszPath)
1115 TRACE("%s\n",debugstr_w(lpszPath));
1118 if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
1122 if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
1125 /* UNC "\\<computer>\<share>" */
1126 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
1128 int foundbackslash = 0;
1132 if (*lpszPath=='\\') foundbackslash++;
1133 lpszPath = CharNextW(lpszPath);
1135 if (foundbackslash <= 1)
1142 /*************************************************************************
1143 * PathIsRootAW [SHELL32.29]
1145 BOOL WINAPI PathIsRootAW(LPCVOID lpszPath)
1147 if (VERSION_OsIsUnicode())
1148 return PathIsRootW(lpszPath);
1149 return PathIsRootA(lpszPath);
1152 /*************************************************************************
1153 * PathIsExeA [internal]
1155 BOOL WINAPI PathIsExeA (LPCSTR lpszPath)
1157 LPCSTR lpszExtension = PathGetExtensionA(lpszPath);
1159 static char * lpszExtensions[6] = {"exe", "com", "pid", "cmd", "bat", NULL };
1161 TRACE("path=%s\n",lpszPath);
1163 for(i=0; lpszExtensions[i]; i++)
1164 if (!strcasecmp(lpszExtension,lpszExtensions[i])) return TRUE;
1169 /*************************************************************************
1170 * PathIsExeW [internal]
1172 BOOL WINAPI PathIsExeW (LPCWSTR lpszPath)
1174 LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
1176 static WCHAR lpszExtensions[6][4] =
1177 {{'e','x','e','\0'}, {'c','o','m','\0'}, {'p','i','d','\0'},
1178 {'c','m','d','\0'}, {'b','a','t','\0'}, {'\0'} };
1180 TRACE("path=%s\n",debugstr_w(lpszPath));
1182 for(i=0; lpszExtensions[i]; i++)
1183 if (!strcmpiW(lpszExtension,lpszExtensions[i])) return TRUE;
1188 /*************************************************************************
1189 * PathIsExeAW [SHELL32.43]
1191 BOOL WINAPI PathIsExeAW (LPCVOID path)
1193 if (VERSION_OsIsUnicode())
1194 return PathIsExeW (path);
1195 return PathIsExeA(path);
1198 /*************************************************************************
1199 * PathIsDirectoryA [SHLWAPI.@]
1201 BOOL WINAPI PathIsDirectoryA(LPCSTR lpszPath)
1205 TRACE("%s\n", debugstr_a(lpszPath));
1207 dwAttr = GetFileAttributesA(lpszPath);
1208 return (dwAttr != -1) ? dwAttr & FILE_ATTRIBUTE_DIRECTORY : 0;
1211 /*************************************************************************
1212 * PathIsDirectoryW [SHLWAPI.@]
1214 BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
1218 TRACE("%s\n", debugstr_w(lpszPath));
1220 dwAttr = GetFileAttributesW(lpszPath);
1221 return (dwAttr != -1) ? dwAttr & FILE_ATTRIBUTE_DIRECTORY : 0;
1224 /*************************************************************************
1225 * PathIsDirectoryAW [SHELL32.159]
1227 BOOL WINAPI PathIsDirectoryAW (LPCVOID lpszPath)
1229 if (VERSION_OsIsUnicode())
1230 return PathIsDirectoryW (lpszPath);
1231 return PathIsDirectoryA (lpszPath);
1234 /*************************************************************************
1235 * PathFileExistsA [SHLWAPI.@]
1238 * file_exists(char *fn);
1240 BOOL WINAPI PathFileExistsA(LPCSTR lpszPath)
1242 TRACE("%s\n",lpszPath);
1243 return (GetFileAttributesA(lpszPath)!=-1);
1246 /*************************************************************************
1247 * PathFileExistsW [SHLWAPI.@]
1249 BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
1251 TRACE("%s\n",debugstr_w(lpszPath));
1252 return (GetFileAttributesW(lpszPath)!=-1);
1255 /*************************************************************************
1256 * PathFileExistsAW [SHELL32.45]
1258 BOOL WINAPI PathFileExistsAW (LPCVOID lpszPath)
1260 if (VERSION_OsIsUnicode())
1261 return PathFileExistsW (lpszPath);
1262 return PathFileExistsA (lpszPath);
1265 /*************************************************************************
1266 * PathMatchSingleMaskA [internal]
1269 * internal (used by PathMatchSpec)
1271 static BOOL PathMatchSingleMaskA(LPCSTR name, LPCSTR mask)
1273 while (*name && *mask && *mask!=';')
1279 if (PathMatchSingleMaskA(name,mask+1)) return 1; /* try substrings */
1283 if (toupper(*mask)!=toupper(*name) && *mask!='?') return 0;
1284 name = CharNextA(name);
1285 mask = CharNextA(mask);
1289 while (*mask=='*') mask++;
1290 if (!*mask || *mask==';') return 1;
1295 /*************************************************************************
1296 * PathMatchSingleMaskW [internal]
1298 static BOOL PathMatchSingleMaskW(LPCWSTR name, LPCWSTR mask)
1300 while (*name && *mask && *mask!=';')
1306 if (PathMatchSingleMaskW(name,mask+1)) return 1; /* try substrings */
1310 if (toupperW(*mask)!=toupperW(*name) && *mask!='?') return 0;
1311 name = CharNextW(name);
1312 mask = CharNextW(mask);
1316 while (*mask=='*') mask++;
1317 if (!*mask || *mask==';') return 1;
1321 /*************************************************************************
1322 * PathMatchSpecA [SHLWAPI.@]
1325 * used from COMDLG32
1327 BOOL WINAPI PathMatchSpecA(LPCSTR name, LPCSTR mask)
1329 TRACE("%s %s\n",name,mask);
1331 if (!lstrcmpA( mask, "*.*" )) return 1; /* we don't require a period */
1335 if (PathMatchSingleMaskA(name,mask)) return 1; /* helper function */
1336 while (*mask && *mask!=';') mask = CharNextA(mask);
1340 while (*mask==' ') mask++; /* masks may be separated by "; " */
1346 /*************************************************************************
1347 * PathMatchSpecW [SHLWAPI.@]
1349 BOOL WINAPI PathMatchSpecW(LPCWSTR name, LPCWSTR mask)
1352 TRACE("%s %s\n",debugstr_w(name),debugstr_w(mask));
1354 lstrcpyAtoW(stemp,"*.*");
1355 if (!lstrcmpW( mask, stemp )) return 1; /* we don't require a period */
1359 if (PathMatchSingleMaskW(name,mask)) return 1; /* helper function */
1360 while (*mask && *mask!=';') mask = CharNextW(mask);
1364 while (*mask==' ') mask++; /* masks may be separated by "; " */
1370 /*************************************************************************
1371 * PathMatchSpecAW [SHELL32.46]
1373 BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
1375 if (VERSION_OsIsUnicode())
1376 return PathMatchSpecW( name, mask );
1377 return PathMatchSpecA( name, mask );
1380 /*************************************************************************
1381 * PathIsSameRootA [SHLWAPI.@]
1384 * what to do with "\path" ??
1386 BOOL WINAPI PathIsSameRootA(LPCSTR lpszPath1, LPCSTR lpszPath2)
1388 TRACE("%s %s\n", lpszPath1, lpszPath2);
1390 if (PathIsRelativeA(lpszPath1) || PathIsRelativeA(lpszPath2)) return FALSE;
1393 if ( toupper(lpszPath1[0])==toupper(lpszPath2[0]) &&
1394 lpszPath1[1]==':' && lpszPath2[1]==':' &&
1395 lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
1399 if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
1400 lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
1402 int pos=2, bsfound=0;
1403 while (lpszPath1[pos] && lpszPath2[pos] &&
1404 (lpszPath1[pos] == lpszPath2[pos]))
1406 if (lpszPath1[pos]=='\\') bsfound++;
1407 if (bsfound == 2) return TRUE;
1408 pos++; /* fixme: use CharNext*/
1410 return (lpszPath1[pos] == lpszPath2[pos]);
1415 /*************************************************************************
1416 * PathIsSameRootW [SHLWAPI.@]
1418 BOOL WINAPI PathIsSameRootW(LPCWSTR lpszPath1, LPCWSTR lpszPath2)
1420 TRACE("%s %s\n", debugstr_w(lpszPath1), debugstr_w(lpszPath2));
1422 if (PathIsRelativeW(lpszPath1) || PathIsRelativeW(lpszPath2)) return FALSE;
1425 if ( toupperW(lpszPath1[0])==toupperW(lpszPath2[0]) &&
1426 lpszPath1[1]==':' && lpszPath2[1]==':' &&
1427 lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
1431 if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
1432 lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
1434 int pos=2, bsfound=0;
1435 while (lpszPath1[pos] && lpszPath2[pos] &&
1436 (lpszPath1[pos] == lpszPath2[pos]))
1438 if (lpszPath1[pos]=='\\') bsfound++;
1439 if (bsfound == 2) return TRUE;
1440 pos++;/* fixme: use CharNext*/
1442 return (lpszPath1[pos] == lpszPath2[pos]);
1447 /*************************************************************************
1448 * PathIsSameRootAW [SHELL32.650]
1450 BOOL WINAPI PathIsSameRootAW(LPCVOID lpszPath1, LPCVOID lpszPath2)
1452 if (VERSION_OsIsUnicode())
1453 return PathIsSameRootW(lpszPath1, lpszPath2);
1454 return PathIsSameRootA(lpszPath1, lpszPath2);
1457 /*************************************************************************
1460 BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
1464 static LPSTR SupportedProtocol[] =
1465 {"http","https","ftp","gopher","file","mailto",NULL};
1467 if(!lpstrPath) return FALSE;
1470 lpstrRes = strchr(lpstrPath,':');
1471 if(!lpstrRes) return FALSE;
1472 iSize = lpstrRes - lpstrPath;
1474 while(SupportedProtocol[i])
1476 if (iSize == strlen(SupportedProtocol[i]))
1477 if(!strncasecmp(lpstrPath, SupportedProtocol[i], iSize))
1485 /*************************************************************************
1488 BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
1492 static WCHAR SupportedProtocol[7][7] =
1493 {{'h','t','t','p','\0'},{'h','t','t','p','s','\0'},{'f','t','p','\0'},
1494 {'g','o','p','h','e','r','\0'},{'f','i','l','e','\0'},
1495 {'m','a','i','l','t','o','\0'},{0}};
1497 if(!lpstrPath) return FALSE;
1500 lpstrRes = strchrW(lpstrPath,':');
1501 if(!lpstrRes) return FALSE;
1502 iSize = lpstrRes - lpstrPath;
1504 while(SupportedProtocol[i])
1506 if (iSize == strlenW(SupportedProtocol[i]))
1507 if(!strncmpiW(lpstrPath, SupportedProtocol[i], iSize))
1515 /*************************************************************************
1516 * IsLFNDriveA [SHELL32.119]
1519 * exported by ordinal Name
1521 BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath)
1525 if (!GetVolumeInformationA(lpszPath,NULL,0,NULL,&fnlen,NULL,NULL,0))
1530 /*************************************************************************
1531 * PathIsContentTypeA
1533 BOOL WINAPI PathIsContentTypeA(LPCSTR pszPath, LPCSTR pszContentType)
1535 FIXME("%s %s\n", pszPath, pszContentType);
1539 /*************************************************************************
1540 * PathIsContentTypeW
1542 BOOL WINAPI PathIsContentTypeW(LPCWSTR pszPath, LPCWSTR pszContentType)
1544 FIXME("%s %s\n", debugstr_w(pszPath), debugstr_w(pszContentType));
1548 /*************************************************************************
1551 BOOL WINAPI PathIsFileSpecA(LPCSTR pszPath)
1553 FIXME("%s\n", pszPath);
1557 /*************************************************************************
1560 BOOL WINAPI PathIsFileSpecW(LPCWSTR pszPath)
1562 FIXME("%s\n", debugstr_w(pszPath));
1566 /*************************************************************************
1569 BOOL WINAPI PathIsPrefixA(LPCSTR pszPrefix, LPCSTR pszPath)
1571 FIXME("%s %s\n", pszPrefix, pszPath);
1575 /*************************************************************************
1578 BOOL WINAPI PathIsPrefixW(LPCWSTR pszPrefix, LPCWSTR pszPath)
1580 FIXME("%s %s\n", debugstr_w(pszPrefix), debugstr_w(pszPath));
1584 /*************************************************************************
1585 * PathIsSystemFolderA
1587 BOOL WINAPI PathIsSystemFolderA(LPCSTR pszPath, DWORD dwAttrb)
1589 FIXME("%s 0x%08lx\n", pszPath, dwAttrb);
1593 /*************************************************************************
1594 * PathIsSystemFolderW
1596 BOOL WINAPI PathIsSystemFolderW(LPCWSTR pszPath, DWORD dwAttrb)
1598 FIXME("%s 0x%08lx\n", debugstr_w(pszPath), dwAttrb);
1602 /*************************************************************************
1605 BOOL WINAPI PathIsUNCServerA(
1608 FIXME("%s\n", pszPath);
1612 /*************************************************************************
1615 BOOL WINAPI PathIsUNCServerW(
1618 FIXME("%s\n", debugstr_w(pszPath));
1622 /*************************************************************************
1623 * PathIsUNCServerShareA
1625 BOOL WINAPI PathIsUNCServerShareA(
1628 FIXME("%s\n", pszPath);
1632 /*************************************************************************
1633 * PathIsUNCServerShareW
1635 BOOL WINAPI PathIsUNCServerShareW(
1638 FIXME("%s\n", debugstr_w(pszPath));
1643 ########## Creating Something Unique ##########
1645 /*************************************************************************
1646 * PathMakeUniqueNameA [internal]
1648 BOOL WINAPI PathMakeUniqueNameA(
1651 LPCSTR lpszShortName,
1652 LPCSTR lpszLongName,
1653 LPCSTR lpszPathName)
1655 FIXME("%p %lu %s %s %s stub\n",
1656 lpszBuffer, dwBuffSize, debugstr_a(lpszShortName),
1657 debugstr_a(lpszLongName), debugstr_a(lpszPathName));
1661 /*************************************************************************
1662 * PathMakeUniqueNameW [internal]
1664 BOOL WINAPI PathMakeUniqueNameW(
1667 LPCWSTR lpszShortName,
1668 LPCWSTR lpszLongName,
1669 LPCWSTR lpszPathName)
1671 FIXME("%p %lu %s %s %s stub\n",
1672 lpszBuffer, dwBuffSize, debugstr_w(lpszShortName),
1673 debugstr_w(lpszLongName), debugstr_w(lpszPathName));
1677 /*************************************************************************
1678 * PathMakeUniqueNameAW [SHELL32.47]
1680 BOOL WINAPI PathMakeUniqueNameAW(
1683 LPCVOID lpszShortName,
1684 LPCVOID lpszLongName,
1685 LPCVOID lpszPathName)
1687 if (VERSION_OsIsUnicode())
1688 return PathMakeUniqueNameW(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
1689 return PathMakeUniqueNameA(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
1692 /*************************************************************************
1693 * PathYetAnotherMakeUniqueNameA [SHELL32.75]
1696 * exported by ordinal
1698 BOOL WINAPI PathYetAnotherMakeUniqueNameA(
1700 LPCSTR lpszPathName,
1701 LPCSTR lpszShortName,
1702 LPCSTR lpszLongName)
1704 FIXME("(%p,%p, %p ,%p):stub.\n",
1705 lpszBuffer, lpszPathName, lpszShortName, lpszLongName);
1711 ########## cleaning and resolving paths ##########
1714 /*************************************************************************
1715 * PathFindOnPathA [SHELL32.145]
1717 BOOL WINAPI PathFindOnPathA(LPSTR sFile, LPCSTR sOtherDirs)
1719 FIXME("%s %s\n",sFile, sOtherDirs);
1723 /*************************************************************************
1724 * PathFindOnPathW [SHELL32]
1726 BOOL WINAPI PathFindOnPathW(LPWSTR sFile, LPCWSTR sOtherDirs)
1728 FIXME("%s %s\n",debugstr_w(sFile), debugstr_w(sOtherDirs));
1732 /*************************************************************************
1733 * PathFindOnPathAW [SHELL32]
1735 BOOL WINAPI PathFindOnPathAW(LPVOID sFile, LPCVOID sOtherDirs)
1737 if (VERSION_OsIsUnicode())
1738 return PathFindOnPathW(sFile, sOtherDirs);
1739 return PathFindOnPathA(sFile, sOtherDirs);
1742 /*************************************************************************
1743 * PathCleanupSpecA [SHELL32.171]
1745 DWORD WINAPI PathCleanupSpecA(LPSTR x, LPSTR y)
1747 FIXME("(%p %s, %p %s) stub\n",x,debugstr_a(x),y,debugstr_a(y));
1751 /*************************************************************************
1752 * PathCleanupSpecA [SHELL32]
1754 DWORD WINAPI PathCleanupSpecW(LPWSTR x, LPWSTR y)
1756 FIXME("(%p %s, %p %s) stub\n",x,debugstr_w(x),y,debugstr_w(y));
1760 /*************************************************************************
1761 * PathCleanupSpecAW [SHELL32]
1763 DWORD WINAPI PathCleanupSpecAW (LPVOID x, LPVOID y)
1765 if (VERSION_OsIsUnicode())
1766 return PathCleanupSpecW(x,y);
1767 return PathCleanupSpecA(x,y);
1770 /*************************************************************************
1771 * PathQualifyA [SHELL32]
1773 BOOL WINAPI PathQualifyA(LPCSTR pszPath)
1775 FIXME("%s\n",pszPath);
1779 /*************************************************************************
1780 * PathQualifyW [SHELL32]
1782 BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
1784 FIXME("%s\n",debugstr_w(pszPath));
1788 /*************************************************************************
1789 * PathQualifyAW [SHELL32]
1791 BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
1793 if (VERSION_OsIsUnicode())
1794 return PathQualifyW(pszPath);
1795 return PathQualifyA(pszPath);
1798 /*************************************************************************
1799 * PathResolveA [SHELL32.51]
1801 BOOL WINAPI PathResolveA(
1806 FIXME("(%s,%p,0x%08lx),stub!\n",
1807 lpszPath, *alpszPaths, dwFlags);
1811 /*************************************************************************
1812 * PathResolveW [SHELL32]
1814 BOOL WINAPI PathResolveW(
1816 LPCWSTR *alpszPaths,
1819 FIXME("(%s,%p,0x%08lx),stub!\n",
1820 debugstr_w(lpszPath), debugstr_w(*alpszPaths), dwFlags);
1824 /*************************************************************************
1825 * PathResolveAW [SHELL32]
1827 BOOL WINAPI PathResolveAW(
1829 LPCVOID *alpszPaths,
1832 if (VERSION_OsIsUnicode())
1833 return PathResolveW(lpszPath, (LPCWSTR*)alpszPaths, dwFlags);
1834 return PathResolveA(lpszPath, (LPCSTR*)alpszPaths, dwFlags);
1837 /*************************************************************************
1838 * PathProcessCommandA [SHELL32.653]
1840 HRESULT WINAPI PathProcessCommandA (
1846 FIXME("%s %p 0x%04lx 0x%04lx stub\n",
1847 lpszPath, lpszBuff, dwBuffSize, dwFlags);
1848 lstrcpyA(lpszBuff, lpszPath);
1852 /*************************************************************************
1853 * PathProcessCommandW
1855 HRESULT WINAPI PathProcessCommandW (
1861 FIXME("(%s, %p, 0x%04lx, 0x%04lx) stub\n",
1862 debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags);
1863 lstrcpyW(lpszBuff, lpszPath);
1867 /*************************************************************************
1868 * PathProcessCommandAW
1870 HRESULT WINAPI PathProcessCommandAW (
1876 if (VERSION_OsIsUnicode())
1877 return PathProcessCommandW(lpszPath, lpszBuff, dwBuffSize, dwFlags);
1878 return PathProcessCommandA(lpszPath, lpszBuff, dwBuffSize, dwFlags);
1881 /*************************************************************************
1882 * PathCompactPathExA
1884 BOOL WINAPI PathCompactPathExA(
1890 FIXME("%p %s 0x%08x 0x%08lx\n", pszOut, pszSrc, cchMax, dwFlags);
1894 /*************************************************************************
1895 * PathCompactPathExW
1897 BOOL WINAPI PathCompactPathExW(
1903 FIXME("%p %s 0x%08x 0x%08lx\n", pszOut, debugstr_w(pszSrc), cchMax, dwFlags);
1908 ########## special ##########
1911 /*************************************************************************
1912 * PathSetDlgItemPathA
1915 * use PathCompactPath to make sure, the path fits into the control
1917 BOOL WINAPI PathSetDlgItemPathA(HWND hDlg, int id, LPCSTR pszPath)
1918 { TRACE("%x %x %s\n",hDlg, id, pszPath);
1919 return SetDlgItemTextA(hDlg, id, pszPath);
1922 /*************************************************************************
1923 * PathSetDlgItemPathW
1925 BOOL WINAPI PathSetDlgItemPathW(HWND hDlg, int id, LPCWSTR pszPath)
1926 { TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
1927 return SetDlgItemTextW(hDlg, id, pszPath);
1930 /*************************************************************************
1931 * PathSetDlgItemPathAW
1933 BOOL WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
1934 { if (VERSION_OsIsUnicode())
1935 return PathSetDlgItemPathW(hDlg, id, pszPath);
1936 return PathSetDlgItemPathA(hDlg, id, pszPath);
1940 /*************************************************************************
1941 * SHGetSpecialFolderPathA [SHELL32.175]
1943 * converts csidl to path
1946 static char * szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
1947 static char * szSHUserFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
1949 static char * szEnvUserProfile = "%USERPROFILE%";
1950 static char * szEnvSystemRoot = "%SYSTEMROOT%";
1953 BOOL WINAPI SHGetSpecialFolderPathA (
1959 CHAR szValueName[MAX_PATH], szDefaultPath[MAX_PATH];
1960 HKEY hRootKey, hKey;
1961 BOOL bRelative = TRUE;
1962 DWORD dwType, dwDisp, dwPathLen = MAX_PATH;
1964 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
1966 /* build default values */
1970 hRootKey = HKEY_CURRENT_USER;
1971 strcpy (szValueName, "AppData");
1972 strcpy (szDefaultPath, "AppData");
1976 hRootKey = HKEY_CURRENT_USER;
1977 strcpy (szValueName, "Cookies");
1978 strcpy(szDefaultPath, "Cookies");
1981 case CSIDL_DESKTOPDIRECTORY:
1982 hRootKey = HKEY_CURRENT_USER;
1983 strcpy(szValueName, "Desktop");
1984 strcpy(szDefaultPath, "Desktop");
1987 case CSIDL_COMMON_DESKTOPDIRECTORY:
1988 hRootKey = HKEY_LOCAL_MACHINE;
1989 strcpy(szValueName, "Common Desktop");
1990 strcpy(szDefaultPath, "Desktop");
1993 case CSIDL_FAVORITES:
1994 hRootKey = HKEY_CURRENT_USER;
1995 strcpy(szValueName, "Favorites");
1996 strcpy(szDefaultPath, "Favorites");
2000 hRootKey = HKEY_CURRENT_USER;
2001 strcpy(szValueName, "Fonts");
2002 strcpy(szDefaultPath, "Fonts");
2006 hRootKey = HKEY_CURRENT_USER;
2007 strcpy(szValueName, "History");
2008 strcpy(szDefaultPath, "History");
2012 hRootKey = HKEY_CURRENT_USER;
2013 strcpy(szValueName, "NetHood");
2014 strcpy(szDefaultPath, "NetHood");
2017 case CSIDL_INTERNET_CACHE:
2018 hRootKey = HKEY_CURRENT_USER;
2019 strcpy(szValueName, "Cache");
2020 strcpy(szDefaultPath, "Temporary Internet Files");
2023 case CSIDL_PERSONAL:
2024 hRootKey = HKEY_CURRENT_USER;
2025 strcpy(szValueName, "Personal");
2026 strcpy(szDefaultPath, "My Own Files");
2030 case CSIDL_PRINTHOOD:
2031 hRootKey = HKEY_CURRENT_USER;
2032 strcpy(szValueName, "PrintHood");
2033 strcpy(szDefaultPath, "PrintHood");
2036 case CSIDL_PROGRAMS:
2037 hRootKey = HKEY_CURRENT_USER;
2038 strcpy(szValueName, "Programs");
2039 strcpy(szDefaultPath, "StartMenu\\Programs");
2042 case CSIDL_COMMON_PROGRAMS:
2043 hRootKey = HKEY_LOCAL_MACHINE;
2044 strcpy(szValueName, "Common Programs");
2045 strcpy(szDefaultPath, "");
2049 hRootKey = HKEY_CURRENT_USER;
2050 strcpy(szValueName, "Recent");
2051 strcpy(szDefaultPath, "Recent");
2055 hRootKey = HKEY_CURRENT_USER;
2056 strcpy(szValueName, "SendTo");
2057 strcpy(szDefaultPath, "SendTo");
2060 case CSIDL_STARTMENU:
2061 hRootKey = HKEY_CURRENT_USER;
2062 strcpy(szValueName, "StartMenu");
2063 strcpy(szDefaultPath, "StartMenu");
2066 case CSIDL_COMMON_STARTMENU:
2067 hRootKey = HKEY_LOCAL_MACHINE;
2068 strcpy(szValueName, "Common StartMenu");
2069 strcpy(szDefaultPath, "StartMenu");
2073 hRootKey = HKEY_CURRENT_USER;
2074 strcpy(szValueName, "Startup");
2075 strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
2078 case CSIDL_COMMON_STARTUP:
2079 hRootKey = HKEY_LOCAL_MACHINE;
2080 strcpy(szValueName, "Common Startup");
2081 strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
2084 case CSIDL_TEMPLATES:
2085 hRootKey = HKEY_CURRENT_USER;
2086 strcpy(szValueName, "Templates");
2087 strcpy(szDefaultPath, "ShellNew");
2091 ERR("folder unknown or not allowed\n");
2095 /* user shell folders */
2096 if (RegCreateKeyExA(hRootKey,szSHUserFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
2098 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
2103 if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
2105 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
2108 /* value not existing */
2111 GetWindowsDirectoryA(szPath, MAX_PATH);
2112 PathAddBackslashA(szPath);
2113 strcat(szPath, szDefaultPath);
2117 strcpy(szPath, "C:\\"); /* fixme ??? */
2118 strcat(szPath, szDefaultPath);
2120 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
2125 /* expand paths like %USERPROFILE% */
2126 if (dwType == REG_EXPAND_SZ)
2128 ExpandEnvironmentStringsA(szPath, szDefaultPath, MAX_PATH);
2129 strcpy(szPath, szDefaultPath);
2132 /* if we don't care about existing directorys we are ready */
2133 if(csidl & CSIDL_FLAG_DONT_VERIFY) return TRUE;
2135 if (PathFileExistsA(szPath)) return TRUE;
2137 /* not existing but we not allowed to create it */
2138 if (!bCreate) return FALSE;
2140 if (!CreateDirectoryA(szPath,NULL))
2142 ERR("Failed to create directory '%s'.\n", szPath);
2146 MESSAGE("Created not existing system directory '%s'\n", szPath);
2150 /*************************************************************************
2151 * SHGetSpecialFolderPathW
2153 BOOL WINAPI SHGetSpecialFolderPathW (
2159 char szTemp[MAX_PATH];
2161 if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate))
2163 lstrcpynAtoW(szPath, szTemp, MAX_PATH);
2166 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
2171 /*************************************************************************
2172 * SHGetSpecialFolderPathAW
2174 BOOL WINAPI SHGetSpecialFolderPathAW (
2181 if (VERSION_OsIsUnicode())
2182 return SHGetSpecialFolderPathW (hwndOwner, szPath, csidl, bCreate);
2183 return SHGetSpecialFolderPathA (hwndOwner, szPath, csidl, bCreate);
2186 /*************************************************************************
2187 * SHGetFolderPathA [SHFOLDER.@]
2189 HRESULT WINAPI SHGetFolderPathA(
2192 HANDLE hToken, /* FIXME: get paths for specific user */
2193 DWORD dwFlags, /* FIXME: SHGFP_TYPE_CURRENT|SHGFP_TYPE_DEFAULT */
2196 return (SHGetSpecialFolderPathA(
2199 CSIDL_FOLDER_MASK & nFolder,
2200 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;
2203 /*************************************************************************
2204 * SHGetFolderPathW [SHFOLDER.@]
2206 HRESULT WINAPI SHGetFolderPathW(
2213 return (SHGetSpecialFolderPathW(
2216 CSIDL_FOLDER_MASK & nFolder,
2217 CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;
2220 /*************************************************************************
2224 * returnvalue, use CharNext
2227 BOOL WINAPI PathCanonicalizeA(LPSTR pszBuf, LPCSTR pszPath)
2229 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = strlen(pszPath);
2230 BOOL bModifyed = FALSE;
2232 TRACE("%p %s\n", pszBuf, pszPath);
2234 pszBuf[OffsetDst]='\0';
2236 /* keep the root of the path */
2237 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
2239 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2241 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
2243 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2244 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2245 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
2247 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2248 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
2251 OffsetSrc++; LenSrc--; bModifyed = TRUE;
2253 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
2256 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
2261 /* ".\" at the beginning of the path */
2262 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
2264 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
2269 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
2271 /* "\.." found, go one deeper */
2272 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
2273 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
2274 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
2275 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
2277 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
2279 /* "\." found, skip it */
2280 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
2284 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
2287 pszBuf[OffsetDst] = '\0';
2288 TRACE("-- %s %u\n", pszBuf, bModifyed);
2293 /*************************************************************************
2297 * returnvalue, use CharNext
2299 BOOL WINAPI PathCanonicalizeW(LPWSTR pszBuf, LPCWSTR pszPath)
2301 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = lstrlenW(pszPath);
2302 BOOL bModifyed = FALSE;
2304 TRACE("%p %s\n", pszBuf, debugstr_w(pszPath));
2306 pszBuf[OffsetDst]='\0';
2308 /* keep the root of the path */
2309 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
2311 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2313 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
2315 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2316 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2317 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
2319 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2320 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
2323 OffsetSrc++; LenSrc--; bModifyed = TRUE;
2325 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
2328 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
2333 /* ".\" at the beginning of the path */
2334 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
2336 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
2341 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
2343 /* "\.." found, go one deeper */
2344 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
2345 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
2346 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
2347 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
2349 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
2351 /* "\." found, skip it */
2352 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
2356 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
2359 pszBuf[OffsetDst] = '\0';
2360 TRACE("-- %s %u\n", debugstr_w(pszBuf), bModifyed);
2364 /*************************************************************************
2365 * PathFindNextComponentA
2370 * aa "" (pointer to traling NULL)
2371 * aa\ "" (pointer to traling NULL)
2372 * aa\\ "" (pointer to traling NULL)
2379 LPSTR WINAPI PathFindNextComponentA(LPCSTR pszPath)
2383 TRACE("%s\n", pszPath);
2385 if(!pszPath || !*pszPath) return NULL;
2386 if(!(pos = StrChrA(pszPath, '\\')))
2387 return (LPSTR) pszPath + strlen(pszPath);
2389 if(pos[0] == '\\') pos++;
2393 /*************************************************************************
2394 * PathFindNextComponentW
2396 LPWSTR WINAPI PathFindNextComponentW(LPCWSTR pszPath)
2400 TRACE("%s\n", debugstr_w(pszPath));
2402 if(!pszPath || !*pszPath) return NULL;
2403 if (!(pos = StrChrW(pszPath, '\\')))
2404 return (LPWSTR) pszPath + lstrlenW(pszPath);
2406 if(pos[0] == '\\') pos++;
2410 /*************************************************************************
2414 * it adds never a dot
2417 BOOL WINAPI PathAddExtensionA(
2419 LPCSTR pszExtension)
2423 if (*(PathFindExtensionA(pszPath))) return FALSE;
2425 if (!pszExtension || *pszExtension=='\0')
2426 strcat(pszPath, "exe");
2428 strcat(pszPath, pszExtension);
2434 /*************************************************************************
2437 BOOL WINAPI PathAddExtensionW(
2439 LPCWSTR pszExtension)
2441 static const WCHAR ext[] = { 'e','x','e',0 };
2445 if (*(PathFindExtensionW(pszPath))) return FALSE;
2447 if (!pszExtension || *pszExtension=='\0')
2448 lstrcatW(pszPath, ext);
2450 lstrcatW(pszPath, pszExtension);
2456 /*************************************************************************
2459 BOOL WINAPI PathMakePrettyA(
2462 FIXME("%s\n", lpPath);
2466 /*************************************************************************
2469 BOOL WINAPI PathMakePrettyW(
2472 FIXME("%s\n", debugstr_w(lpPath));
2477 /*************************************************************************
2480 int WINAPI PathCommonPrefixA(
2485 FIXME("%s %s %p\n", pszFile1, pszFile2, achPath);
2489 /*************************************************************************
2492 int WINAPI PathCommonPrefixW(
2497 FIXME("%s %s %p\n", debugstr_w(pszFile1), debugstr_w(pszFile2),achPath );
2501 /*************************************************************************
2504 BOOL WINAPI PathCompactPathA(HDC hDC, LPSTR pszPath, UINT dx)
2506 FIXME("0x%08x %s 0x%08x\n", hDC, pszPath, dx);
2510 /*************************************************************************
2513 BOOL WINAPI PathCompactPathW(HDC hDC, LPWSTR pszPath, UINT dx)
2515 FIXME("0x%08x %s 0x%08x\n", hDC, debugstr_w(pszPath), dx);
2519 /*************************************************************************
2522 UINT WINAPI PathGetCharTypeA(UCHAR ch)
2528 /*************************************************************************
2531 UINT WINAPI PathGetCharTypeW(WCHAR ch)
2537 /*************************************************************************
2538 * PathMakeSystemFolderA
2540 BOOL WINAPI PathMakeSystemFolderA(LPCSTR pszPath)
2542 FIXME("%s\n", pszPath);
2546 /*************************************************************************
2547 * PathMakeSystemFolderW
2549 BOOL WINAPI PathMakeSystemFolderW(LPCWSTR pszPath)
2551 FIXME("%s\n", debugstr_w(pszPath));
2555 /*************************************************************************
2556 * PathRenameExtensionA
2558 BOOL WINAPI PathRenameExtensionA(LPSTR pszPath, LPCSTR pszExt)
2560 FIXME("%s %s\n", pszPath, pszExt);
2564 /*************************************************************************
2565 * PathRenameExtensionW
2567 BOOL WINAPI PathRenameExtensionW(LPWSTR pszPath, LPCWSTR pszExt)
2569 FIXME("%s %s\n", debugstr_w(pszPath), debugstr_w(pszExt));
2573 /*************************************************************************
2574 * PathSearchAndQualifyA
2576 BOOL WINAPI PathSearchAndQualifyA(
2581 FIXME("%s %s 0x%08x\n", pszPath, pszBuf, cchBuf);
2585 /*************************************************************************
2586 * PathSearchAndQualifyW
2588 BOOL WINAPI PathSearchAndQualifyW(
2593 FIXME("%s %s 0x%08x\n", debugstr_w(pszPath), debugstr_w(pszBuf), cchBuf);
2597 /*************************************************************************
2600 LPSTR WINAPI PathSkipRootA(LPCSTR pszPath)
2602 FIXME("%s\n", pszPath);
2603 return (LPSTR)pszPath;
2606 /*************************************************************************
2609 LPWSTR WINAPI PathSkipRootW(LPCWSTR pszPath)
2611 FIXME("%s\n", debugstr_w(pszPath));
2612 return (LPWSTR)pszPath;
2615 /*************************************************************************
2616 * PathCreateFromUrlA
2618 HRESULT WINAPI PathCreateFromUrlA(
2624 FIXME("%s %p %p 0x%08lx\n",
2625 pszUrl, pszPath, pcchPath, dwFlags);
2629 /*************************************************************************
2630 * PathCreateFromUrlW
2632 HRESULT WINAPI PathCreateFromUrlW(
2638 FIXME("%s %p %p 0x%08lx\n",
2639 debugstr_w(pszUrl), pszPath, pcchPath, dwFlags);
2643 /*************************************************************************
2644 * PathRelativePathToA
2646 BOOL WINAPI PathRelativePathToA(
2653 FIXME("%s %s 0x%08lx %s 0x%08lx\n",
2654 pszPath, pszFrom, dwAttrFrom, pszTo, dwAttrTo);
2658 /*************************************************************************
2659 * PathRelativePathToW
2661 BOOL WINAPI PathRelativePathToW(
2668 FIXME("%s %s 0x%08lx %s 0x%08lx\n",
2669 debugstr_w(pszPath), debugstr_w(pszFrom), dwAttrFrom, debugstr_w(pszTo), dwAttrTo);
2673 /*************************************************************************
2674 * PathUnmakeSystemFolderA
2676 BOOL WINAPI PathUnmakeSystemFolderA(LPCSTR pszPath)
2678 FIXME("%s\n", pszPath);
2682 /*************************************************************************
2683 * PathUnmakeSystemFolderW
2685 BOOL WINAPI PathUnmakeSystemFolderW(LPCWSTR pszPath)
2687 FIXME("%s\n", debugstr_w(pszPath));