Use the Unicode string functions from wine/unicode.h instead of the
[wine.git] / dlls / shell32 / shellpath.c
blob114dab9484605ac30a243fc5d9ce0d096715efcb
1 /*
2 * Path Functions
4 * Many of this functions are in SHLWAPI.DLL also
6 */
7 #include <string.h>
8 #include <ctype.h>
9 #include "debugtools.h"
10 #include "winnls.h"
11 #include "winversion.h"
12 #include "winreg.h"
14 #include "shlobj.h"
15 #include "shell32_main.h"
16 #include "windef.h"
17 #include "options.h"
18 #include "wine/undocshell.h"
19 #include "wine/unicode.h"
20 #include "shlwapi.h"
22 DEFAULT_DEBUG_CHANNEL(shell);
25 Combining and Constructing paths
28 /*************************************************************************
29 * PathAppendA [SHLWAPI.@]
31 * NOTES
32 * concat path lpszPath2 onto lpszPath1
34 * FIXME
35 * the resulting path is also canonicalized
37 LPSTR WINAPI PathAppendA(
38 LPSTR lpszPath1,
39 LPCSTR lpszPath2)
41 TRACE("%s %s\n",lpszPath1, lpszPath2);
42 while (lpszPath2[0]=='\\') lpszPath2++;
43 return PathCombineA(lpszPath1,lpszPath1,lpszPath2);
46 /*************************************************************************
47 * PathAppendW [SHLWAPI.@]
49 LPSTR WINAPI PathAppendW(
50 LPWSTR lpszPath1,
51 LPCWSTR lpszPath2)
53 FIXME("%s %s\n",debugstr_w(lpszPath1), debugstr_w(lpszPath2));
54 return NULL;
57 /*************************************************************************
58 * PathAppendAW [SHELL32.36]
60 LPVOID WINAPI PathAppendAW(
61 LPVOID lpszPath1,
62 LPCVOID lpszPath2)
64 if (VERSION_OsIsUnicode())
65 return PathAppendW(lpszPath1, lpszPath2);
66 return PathAppendA(lpszPath1, lpszPath2);
69 /*************************************************************************
70 * PathCombineA [SHLWAPI.@]
72 * NOTES
73 * if lpszFile='.' skip it
74 * szDest can be equal to lpszFile. Thats why we use sTemp
76 * FIXME
77 * the resulting path is also canonicalized
79 LPSTR WINAPI PathCombineA(
80 LPSTR szDest,
81 LPCSTR lpszDir,
82 LPCSTR lpszFile)
84 char sTemp[MAX_PATH];
85 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, lpszDir, lpszFile, lpszFile);
88 if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
90 strcpy(szDest,lpszDir);
91 return szDest;
94 /* if lpszFile is a complete path don't care about lpszDir */
95 if (PathGetDriveNumberA(lpszFile) != -1)
97 strcpy(szDest,lpszFile);
99 else if (lpszFile[0] == '\\' )
101 strcpy(sTemp,lpszDir);
102 PathStripToRootA(sTemp);
103 strcat(sTemp,lpszFile);
104 strcpy(szDest,sTemp);
106 else
108 strcpy(sTemp,lpszDir);
109 PathAddBackslashA(sTemp);
110 strcat(sTemp,lpszFile);
111 strcpy(szDest,sTemp);
113 return szDest;
116 /*************************************************************************
117 * PathCombineW [SHLWAPI.@]
119 LPWSTR WINAPI PathCombineW(
120 LPWSTR szDest,
121 LPCWSTR lpszDir,
122 LPCWSTR lpszFile)
124 WCHAR sTemp[MAX_PATH];
125 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, debugstr_w(lpszDir),
126 lpszFile, debugstr_w(lpszFile));
129 if (!lpszFile || !lpszFile[0] || (lpszFile[0]==(WCHAR)'.' && !lpszFile[1]) )
131 strcpyW(szDest,lpszDir);
132 return szDest;
135 /* if lpszFile is a complete path don't care about lpszDir */
136 if (PathGetDriveNumberW(lpszFile) != -1)
138 strcpyW(szDest,lpszFile);
140 else if (lpszFile[0] == (WCHAR)'\\' )
142 strcpyW(sTemp,lpszDir);
143 PathStripToRootW(sTemp);
144 strcatW(sTemp,lpszFile);
145 strcpyW(szDest,sTemp);
147 else
149 strcpyW(sTemp,lpszDir);
150 PathAddBackslashW(sTemp);
151 strcatW(sTemp,lpszFile);
152 strcpyW(szDest,sTemp);
154 return szDest;
157 /*************************************************************************
158 * PathCombineAW [SHELL32.37]
160 LPVOID WINAPI PathCombineAW(
161 LPVOID szDest,
162 LPCVOID lpszDir,
163 LPCVOID lpszFile)
165 if (VERSION_OsIsUnicode())
166 return PathCombineW( szDest, lpszDir, lpszFile );
167 return PathCombineA( szDest, lpszDir, lpszFile );
170 /*************************************************************************
171 * PathAddBackslashA [SHLWAPI.@]
173 * NOTES
174 * append \ if there is none
176 LPSTR WINAPI PathAddBackslashA(LPSTR lpszPath)
178 int len;
179 TRACE("%p->%s\n",lpszPath,lpszPath);
181 len = strlen(lpszPath);
182 if (len && lpszPath[len-1]!='\\')
184 lpszPath[len] = '\\';
185 lpszPath[len+1]= 0x00;
186 return lpszPath+len+1;
188 return lpszPath+len;
191 /*************************************************************************
192 * PathAddBackslashW [SHLWAPI.@]
194 LPWSTR WINAPI PathAddBackslashW(LPWSTR lpszPath)
196 int len;
197 TRACE("%p->%s\n",lpszPath,debugstr_w(lpszPath));
199 len = strlenW(lpszPath);
200 if (len && lpszPath[len-1]!=(WCHAR)'\\')
202 lpszPath[len] = (WCHAR)'\\';
203 lpszPath[len+1]= 0x00;
204 return lpszPath+len+1;
206 return lpszPath+len;
209 /*************************************************************************
210 * PathAddBackslashAW [SHELL32.32]
212 LPVOID WINAPI PathAddBackslashAW(LPVOID lpszPath)
214 if(VERSION_OsIsUnicode())
215 return PathAddBackslashW(lpszPath);
216 return PathAddBackslashA(lpszPath);
219 /*************************************************************************
220 * PathBuildRootA [SHLWAPI.@]
222 LPSTR WINAPI PathBuildRootA(LPSTR lpszPath, int drive)
224 TRACE("%p %i\n",lpszPath, drive);
226 strcpy(lpszPath,"A:\\");
227 lpszPath[0]+=drive;
228 return lpszPath;
231 /*************************************************************************
232 * PathBuildRootW [SHLWAPI.@]
234 LPWSTR WINAPI PathBuildRootW(LPWSTR lpszPath, int drive)
236 TRACE("%p %i\n",debugstr_w(lpszPath), drive);
238 lstrcpyAtoW(lpszPath,"A:\\");
239 lpszPath[0]+=drive;
240 return lpszPath;
243 /*************************************************************************
244 * PathBuildRootAW [SHELL32.30]
246 LPVOID WINAPI PathBuildRootAW(LPVOID lpszPath, int drive)
248 if(VERSION_OsIsUnicode())
249 return PathBuildRootW(lpszPath, drive);
250 return PathBuildRootA(lpszPath, drive);
254 Extracting Component Parts
257 /*************************************************************************
258 * PathFindFileNameA [SHLWAPI.@]
260 LPSTR WINAPI PathFindFileNameA(LPCSTR lpszPath)
262 LPCSTR aslash;
263 aslash = lpszPath;
265 TRACE("%s\n",aslash);
266 while (lpszPath[0])
268 if (((lpszPath[0]=='\\') || (lpszPath[0]==':')) && lpszPath[1] && lpszPath[1]!='\\')
269 aslash = lpszPath+1;
270 lpszPath++;
272 return (LPSTR)aslash;
276 /*************************************************************************
277 * PathFindFileNameW [SHLWAPI.@]
279 LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
281 LPCWSTR wslash;
282 wslash = lpszPath;
284 TRACE("%s\n",debugstr_w(wslash));
285 while (lpszPath[0])
287 if (((lpszPath[0]=='\\') || (lpszPath[0]==':')) && lpszPath[1] && lpszPath[1]!='\\')
288 wslash = lpszPath+1;
289 lpszPath++;
291 return (LPWSTR)wslash;
294 /*************************************************************************
295 * PathFindFileNameAW [SHELL32.34]
297 LPVOID WINAPI PathFindFileNameAW(LPCVOID lpszPath)
299 if(VERSION_OsIsUnicode())
300 return PathFindFileNameW(lpszPath);
301 return PathFindFileNameA(lpszPath);
304 /*************************************************************************
305 * PathFindExtensionA [SHLWAPI.@]
307 * NOTES
308 * returns pointer to last . in last lpszPath component or at \0.
311 LPSTR WINAPI PathFindExtensionA(LPCSTR lpszPath)
313 LPCSTR lastpoint = NULL;
315 TRACE("%p %s\n",lpszPath,lpszPath);
317 while (*lpszPath)
319 if (*lpszPath=='\\'||*lpszPath==' ')
320 lastpoint=NULL;
321 if (*lpszPath=='.')
322 lastpoint=lpszPath;
323 lpszPath++;
325 return (LPSTR)(lastpoint?lastpoint:lpszPath);
328 /*************************************************************************
329 * PathFindExtensionW [SHLWAPI.@]
331 LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
333 LPCWSTR lastpoint = NULL;
335 TRACE("(%p %s)\n",lpszPath,debugstr_w(lpszPath));
337 while (*lpszPath)
339 if (*lpszPath==(WCHAR)'\\'||*lpszPath==(WCHAR)' ')
340 lastpoint=NULL;
341 if (*lpszPath==(WCHAR)'.')
342 lastpoint=lpszPath;
343 lpszPath++;
345 return (LPWSTR)(lastpoint?lastpoint:lpszPath);
348 /*************************************************************************
349 * PathFindExtensionAW [SHELL32.31]
351 LPVOID WINAPI PathFindExtensionAW(LPCVOID lpszPath)
353 if (VERSION_OsIsUnicode())
354 return PathFindExtensionW(lpszPath);
355 return PathFindExtensionA(lpszPath);
359 /*************************************************************************
360 * PathGetExtensionA [internal]
362 * NOTES
363 * exported by ordinal
364 * return value points to the first char after the dot
366 LPSTR WINAPI PathGetExtensionA(LPCSTR lpszPath)
368 TRACE("(%s)\n",lpszPath);
370 lpszPath = PathFindExtensionA(lpszPath);
371 return (LPSTR)(*lpszPath?(lpszPath+1):lpszPath);
374 /*************************************************************************
375 * PathGetExtensionW [internal]
377 LPWSTR WINAPI PathGetExtensionW(LPCWSTR lpszPath)
379 TRACE("(%s)\n",debugstr_w(lpszPath));
381 lpszPath = PathFindExtensionW(lpszPath);
382 return (LPWSTR)(*lpszPath?(lpszPath+1):lpszPath);
385 /*************************************************************************
386 * PathGetExtensionAW [SHELL32.158]
388 LPVOID WINAPI PathGetExtensionAW(LPCVOID lpszPath)
390 if (VERSION_OsIsUnicode())
391 return PathGetExtensionW(lpszPath);
392 return PathGetExtensionA(lpszPath);
395 /*************************************************************************
396 * PathGetArgsA [SHLWAPI.@]
398 * NOTES
399 * look for next arg in string. handle "quoted" strings
400 * returns pointer to argument *AFTER* the space. Or to the \0.
402 * FIXME
403 * quoting by '\'
405 LPSTR WINAPI PathGetArgsA(LPCSTR lpszPath)
407 BOOL qflag = FALSE;
409 TRACE("%s\n",lpszPath);
411 while (*lpszPath)
413 if ((*lpszPath==' ') && !qflag)
414 return (LPSTR)lpszPath+1;
415 if (*lpszPath=='"')
416 qflag=!qflag;
417 lpszPath++;
419 return (LPSTR)lpszPath;
423 /*************************************************************************
424 * PathGetArgsW [SHLWAPI.@]
426 LPWSTR WINAPI PathGetArgsW(LPCWSTR lpszPath)
428 BOOL qflag = FALSE;
430 TRACE("%s\n",debugstr_w(lpszPath));
432 while (*lpszPath)
434 if ((*lpszPath==' ') && !qflag)
435 return (LPWSTR)lpszPath+1;
436 if (*lpszPath=='"')
437 qflag=!qflag;
438 lpszPath++;
440 return (LPWSTR)lpszPath;
443 /*************************************************************************
444 * PathGetArgsAW [SHELL32.52]
446 LPVOID WINAPI PathGetArgsAW(LPVOID lpszPath)
448 if (VERSION_OsIsUnicode())
449 return PathGetArgsW(lpszPath);
450 return PathGetArgsA(lpszPath);
453 /*************************************************************************
454 * PathGetDriveNumberA [SHLWAPI.@]
456 int WINAPI PathGetDriveNumberA(LPCSTR lpszPath)
458 int chr = tolower(lpszPath[0]);
460 TRACE ("%s\n",debugstr_a(lpszPath));
462 if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
463 return tolower(lpszPath[0]) - 'a' ;
466 /*************************************************************************
467 * PathGetDriveNumberW [SHLWAPI.@]
469 int WINAPI PathGetDriveNumberW(LPCWSTR lpszPath)
471 int chr = tolowerW(lpszPath[0]);
473 TRACE ("%s\n",debugstr_w(lpszPath));
475 if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
476 return tolowerW(lpszPath[0]) - 'a' ;
479 /*************************************************************************
480 * PathGetDriveNumber [SHELL32.57]
482 int WINAPI PathGetDriveNumberAW(LPVOID lpszPath)
484 if (VERSION_OsIsUnicode())
485 return PathGetDriveNumberW(lpszPath);
486 return PathGetDriveNumberA(lpszPath);
489 /*************************************************************************
490 * PathRemoveFileSpecA [SHLWAPI.@]
492 * NOTES
493 * truncates passed argument to a valid path
494 * returns if the string was modified or not.
495 * "\foo\xx\foo"-> "\foo\xx"
496 * "\" -> "\"
497 * "a:\foo" -> "a:\"
499 BOOL WINAPI PathRemoveFileSpecA(LPSTR lpszPath)
501 LPSTR cutplace;
503 TRACE("%s\n",lpszPath);
505 if (!lpszPath[0]) return 0;
507 cutplace = PathFindFileNameA(lpszPath);
508 if (cutplace)
510 *cutplace='\0';
511 if (PathIsRootA(lpszPath))
513 PathAddBackslashA(lpszPath);
515 else
517 PathRemoveBackslashA(lpszPath);
519 return TRUE;
521 return FALSE;
524 /*************************************************************************
525 * PathRemoveFileSpecW [SHLWAPI.@]
527 BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
529 LPWSTR cutplace;
531 TRACE("%s\n",debugstr_w(lpszPath));
533 if (!lpszPath[0]) return 0;
534 cutplace = PathFindFileNameW(lpszPath);
535 if (cutplace)
537 *cutplace='\0';
538 if (PathIsRootW(lpszPath))
540 PathAddBackslashW(lpszPath);
542 else
544 PathRemoveBackslashW(lpszPath);
546 return TRUE;
548 return FALSE;
551 /*************************************************************************
552 * PathRemoveFileSpec [SHELL32.35]
554 BOOL WINAPI PathRemoveFileSpecAW(LPVOID lpszPath)
556 if (VERSION_OsIsUnicode())
557 return PathRemoveFileSpecW(lpszPath);
558 return PathRemoveFileSpecA(lpszPath);
561 /*************************************************************************
562 * PathStripPathA [SHELLWAPI.@]
564 * NOTES
565 * removes the path from the beginning of a filename
567 void WINAPI PathStripPathA(LPSTR lpszPath)
569 LPSTR lpszFileName = PathFindFileNameA(lpszPath);
571 TRACE("%s\n", lpszPath);
573 if(lpszFileName)
574 RtlMoveMemory(lpszPath, lpszFileName, strlen(lpszFileName));
577 /*************************************************************************
578 * PathStripPathW [SHELLWAPI.@]
580 void WINAPI PathStripPathW(LPWSTR lpszPath)
582 LPWSTR lpszFileName = PathFindFileNameW(lpszPath);
584 TRACE("%s\n", debugstr_w(lpszPath));
585 if(lpszFileName)
586 RtlMoveMemory(lpszPath, lpszFileName, lstrlenW(lpszFileName)*sizeof(WCHAR));
589 /*************************************************************************
590 * PathStripPathAW [SHELL32.38]
592 void WINAPI PathStripPathAW(LPVOID lpszPath)
594 if (VERSION_OsIsUnicode())
595 return PathStripPathW(lpszPath);
596 return PathStripPathA(lpszPath);
599 /*************************************************************************
600 * PathStripToRootA [SHLWAPI.@]
602 BOOL WINAPI PathStripToRootA(LPSTR lpszPath)
604 TRACE("%s\n", lpszPath);
606 /* X:\ */
607 if (lpszPath[1]==':' && lpszPath[2]=='\\')
609 lpszPath[3]='\0';
610 return TRUE;
613 /* "\" */
614 if (lpszPath[0]=='\\')
616 lpszPath[1]='\0';
617 return TRUE;
620 /* UNC "\\<computer>\<share>" */
621 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
623 int foundbackslash = 0;
624 lpszPath += 2;
625 while (*lpszPath)
627 if (*lpszPath=='\\') foundbackslash++;
628 if (foundbackslash==2)
630 *lpszPath = '\0';
631 return TRUE;
633 lpszPath++;
637 return FALSE;
640 /*************************************************************************
641 * PathStripToRootW [SHLWAPI.@]
643 BOOL WINAPI PathStripToRootW(LPWSTR lpszPath)
645 TRACE("%s\n", debugstr_w(lpszPath));
647 /* X:\ */
648 if (lpszPath[1]==':' && lpszPath[2]=='\\')
650 lpszPath[3]='\0';
651 return TRUE;
654 /* "\" */
655 if (lpszPath[0]=='\\')
657 lpszPath[1]='\0';
658 return TRUE;
661 /* UNC "\\<computer>\<share>" */
662 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
664 int foundbackslash = 0;
665 lpszPath += 2;
666 while (*lpszPath)
668 if (*lpszPath=='\\') foundbackslash++;
669 if (foundbackslash==2)
671 *lpszPath = '\0';
672 return TRUE;
674 lpszPath++;
678 return FALSE;
681 /*************************************************************************
682 * PathStripToRootAW [SHELL32.50]
684 BOOL WINAPI PathStripToRootAW(LPVOID lpszPath)
686 if (VERSION_OsIsUnicode())
687 return PathStripToRootW(lpszPath);
688 return PathStripToRootA(lpszPath);
691 /*************************************************************************
692 * PathRemoveArgsA [SHLWAPI.@]
694 void WINAPI PathRemoveArgsA(LPSTR lpszPath)
696 LPSTR lpszArgs = PathGetArgsA(lpszPath);
698 TRACE("%s\n", lpszPath);
700 if (lpszArgs) *(--lpszArgs)='\0';
703 /*************************************************************************
704 * PathRemoveArgsW [SHLWAPI.@]
706 void WINAPI PathRemoveArgsW(LPWSTR lpszPath)
708 LPWSTR lpszArgs = PathGetArgsW(lpszPath);
710 TRACE("%s\n", debugstr_w(lpszPath));
712 if (lpszArgs) *(--lpszArgs)='\0';
715 /*************************************************************************
716 * PathRemoveArgsAW [SHELL32.251]
718 void WINAPI PathRemoveArgsAW(LPVOID lpszPath)
720 if (VERSION_OsIsUnicode())
721 return PathRemoveArgsW(lpszPath);
722 return PathRemoveArgsA(lpszPath);
725 /*************************************************************************
726 * PathRemoveExtensionA [SHLWAPI.@]
728 void WINAPI PathRemoveExtensionA(LPSTR lpszPath)
730 LPSTR lpszExtension = PathFindExtensionA(lpszPath);
732 TRACE("%s\n", lpszPath);
734 if (lpszExtension) *lpszExtension='\0';
737 /*************************************************************************
738 * PathRemoveExtensionW [SHLWAPI.@]
740 void WINAPI PathRemoveExtensionW(LPWSTR lpszPath)
742 LPWSTR lpszExtension = PathFindExtensionW(lpszPath);
744 TRACE("%s\n", debugstr_w(lpszPath));
746 if (lpszExtension) *lpszExtension='\0';
749 /*************************************************************************
750 * PathRemoveExtensionAW [SHELL32.250]
752 void WINAPI PathRemoveExtensionAW(LPVOID lpszPath)
754 if (VERSION_OsIsUnicode())
755 return PathRemoveExtensionW(lpszPath);
756 return PathRemoveExtensionA(lpszPath);
759 /*************************************************************************
760 * PathRemoveBackslashA [SHLWAPI.@]
762 * If the path ends in a backslash it is replaced by a NULL
763 * and the address of the NULL is returned
764 * Otherwise
765 * the address of the last character is returned.
768 LPSTR WINAPI PathRemoveBackslashA( LPSTR lpszPath )
770 LPSTR p = lpszPath;
772 while (*lpszPath) p = lpszPath++;
773 if ( *p == (CHAR)'\\') *p = (CHAR)'\0';
774 return p;
777 /*************************************************************************
778 * PathRemoveBackslashW [SHLWAPI.@]
780 LPWSTR WINAPI PathRemoveBackslashW( LPWSTR lpszPath )
782 LPWSTR p = lpszPath;
784 while (*lpszPath) p = lpszPath++;
785 if ( *p == (WCHAR)'\\') *p = (WCHAR)'\0';
786 return p;
790 Path Manipulations
793 /*************************************************************************
794 * PathGetShortPathA [internal]
796 LPSTR WINAPI PathGetShortPathA(LPSTR lpszPath)
798 FIXME("%s stub\n", lpszPath);
799 return NULL;
802 /*************************************************************************
803 * PathGetShortPathW [internal]
805 LPWSTR WINAPI PathGetShortPathW(LPWSTR lpszPath)
807 FIXME("%s stub\n", debugstr_w(lpszPath));
808 return NULL;
811 /*************************************************************************
812 * PathGetShortPathAW [SHELL32.92]
814 LPVOID WINAPI PathGetShortPathAW(LPVOID lpszPath)
816 if(VERSION_OsIsUnicode())
817 return PathGetShortPathW(lpszPath);
818 return PathGetShortPathA(lpszPath);
821 /*************************************************************************
822 * PathRemoveBlanksA [SHLWAPI.@]
824 * NOTES
825 * remove spaces from beginning and end of passed string
827 LPSTR WINAPI PathRemoveBlanksA(LPSTR str)
829 LPSTR x = str;
831 TRACE("%s\n",str);
833 while (*x==' ') x++;
834 if (x!=str)
835 strcpy(str,x);
836 if (!*str)
837 return str;
838 x=str+strlen(str)-1;
839 while (*x==' ')
840 x--;
841 if (*x==' ')
842 *x='\0';
843 return x;
846 /*************************************************************************
847 * PathRemoveBlanksW [SHLWAPI.@]
849 LPWSTR WINAPI PathRemoveBlanksW(LPWSTR str)
851 LPWSTR x = str;
853 TRACE("%s\n",debugstr_w(str));
855 while (*x==' ') x++;
856 if (x!=str)
857 strcpyW(str,x);
858 if (!*str)
859 return str;
860 x=str+strlenW(str)-1;
861 while (*x==' ')
862 x--;
863 if (*x==' ')
864 *x='\0';
865 return x;
868 /*************************************************************************
869 * PathRemoveBlanksAW [SHELL32.33]
871 LPVOID WINAPI PathRemoveBlanksAW(LPVOID str)
873 if(VERSION_OsIsUnicode())
874 return PathRemoveBlanksW(str);
875 return PathRemoveBlanksA(str);
878 /*************************************************************************
879 * PathQuoteSpacesA [SHLWAPI.@]
881 * NOTES
883 LPSTR WINAPI PathQuoteSpacesA(LPCSTR lpszPath)
885 FIXME("%s\n",lpszPath);
886 return 0;
889 /*************************************************************************
890 * PathQuoteSpacesW [SHLWAPI.@]
892 LPWSTR WINAPI PathQuoteSpacesW(LPCWSTR lpszPath)
894 FIXME("%s\n",debugstr_w(lpszPath));
895 return 0;
898 /*************************************************************************
899 * PathQuoteSpacesAW [SHELL32.55]
901 LPVOID WINAPI PathQuoteSpacesAW (LPCVOID lpszPath)
903 if(VERSION_OsIsUnicode())
904 return PathQuoteSpacesW(lpszPath);
905 return PathQuoteSpacesA(lpszPath);
908 /*************************************************************************
909 * PathUnquoteSpacesA [SHLWAPI.@]
911 * NOTES
912 * unquote string (remove ")
914 VOID WINAPI PathUnquoteSpacesA(LPSTR str)
916 DWORD len = lstrlenA(str);
918 TRACE("%s\n",str);
920 if (*str!='"')
921 return;
922 if (str[len-1]!='"')
923 return;
924 str[len-1]='\0';
925 lstrcpyA(str,str+1);
926 return;
929 /*************************************************************************
930 * PathUnquoteSpacesW [SHLWAPI.@]
932 VOID WINAPI PathUnquoteSpacesW(LPWSTR str)
934 DWORD len = strlenW(str);
936 TRACE("%s\n",debugstr_w(str));
938 if (*str!='"')
939 return;
940 if (str[len-1]!='"')
941 return;
942 str[len-1]='\0';
943 strcpyW(str,str+1);
944 return;
947 /*************************************************************************
948 * PathUnquoteSpacesAW [SHELL32.56]
950 VOID WINAPI PathUnquoteSpacesAW(LPVOID str)
952 if(VERSION_OsIsUnicode())
953 PathUnquoteSpacesW(str);
954 else
955 PathUnquoteSpacesA(str);
958 /*************************************************************************
959 * PathParseIconLocationA [SHLWAPI.@]
961 int WINAPI PathParseIconLocationA(LPSTR lpszPath)
963 LPSTR lpstrComma = strchr(lpszPath, ',');
965 FIXME("%s stub\n", debugstr_a(lpszPath));
967 if (lpstrComma && lpstrComma[1])
969 lpstrComma[0]='\0';
970 /* return atoi(&lpstrComma[1]); FIXME */
972 return 0;
975 /*************************************************************************
976 * PathParseIconLocationW [SHLWAPI.@]
978 int WINAPI PathParseIconLocationW(LPWSTR lpszPath)
980 LPWSTR lpstrComma = strchrW(lpszPath, ',');
982 FIXME("%s stub\n", debugstr_w(lpszPath));
984 if (lpstrComma && lpstrComma[1])
986 lpstrComma[0]='\0';
987 /* return _wtoi(&lpstrComma[1]); FIXME */
989 return 0;
992 /*************************************************************************
993 * PathParseIconLocationAW [SHELL32.249]
995 int WINAPI PathParseIconLocationAW (LPVOID lpszPath)
997 if(VERSION_OsIsUnicode())
998 return PathParseIconLocationW(lpszPath);
999 return PathParseIconLocationA(lpszPath);
1003 Path Testing
1005 /*************************************************************************
1006 * PathIsUNCA [SHLWAPI.@]
1008 * NOTES
1009 * PathIsUNC(char*path);
1011 BOOL WINAPI PathIsUNCA(LPCSTR lpszPath)
1013 TRACE("%s\n",lpszPath);
1015 return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
1018 /*************************************************************************
1019 * PathIsUNCW [SHLWAPI.@]
1021 BOOL WINAPI PathIsUNCW(LPCWSTR lpszPath)
1023 TRACE("%s\n",debugstr_w(lpszPath));
1025 return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
1028 /*************************************************************************
1029 * PathIsUNCAW [SHELL32.39]
1031 BOOL WINAPI PathIsUNCAW (LPCVOID lpszPath)
1033 if (VERSION_OsIsUnicode())
1034 return PathIsUNCW( lpszPath );
1035 return PathIsUNCA( lpszPath );
1038 /*************************************************************************
1039 * PathIsRelativeA [SHLWAPI.@]
1041 BOOL WINAPI PathIsRelativeA (LPCSTR lpszPath)
1043 TRACE("lpszPath=%s\n",lpszPath);
1045 return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
1048 /*************************************************************************
1049 * PathIsRelativeW [SHLWAPI.@]
1051 BOOL WINAPI PathIsRelativeW (LPCWSTR lpszPath)
1053 TRACE("lpszPath=%s\n",debugstr_w(lpszPath));
1055 return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
1058 /*************************************************************************
1059 * PathIsRelativeAW [SHELL32.40]
1061 BOOL WINAPI PathIsRelativeAW (LPCVOID lpszPath)
1063 if (VERSION_OsIsUnicode())
1064 return PathIsRelativeW( lpszPath );
1065 return PathIsRelativeA( lpszPath );
1068 /*************************************************************************
1069 * PathIsRootA [SHLWAPI.@]
1071 * notes
1072 * TRUE if the path points to a root directory
1074 BOOL WINAPI PathIsRootA(LPCSTR lpszPath)
1076 TRACE("%s\n",lpszPath);
1078 /* X:\ */
1079 if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
1080 return TRUE;
1082 /* "\" */
1083 if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
1084 return TRUE;
1086 /* UNC "\\<computer>\<share>" */
1087 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
1089 int foundbackslash = 0;
1090 lpszPath += 2;
1091 while (*lpszPath)
1093 if (*(lpszPath++)=='\\') foundbackslash++;
1095 if (foundbackslash==1)
1096 return TRUE;
1098 return FALSE;
1101 /*************************************************************************
1102 * PathIsRootW [SHLWAPI.@]
1104 BOOL WINAPI PathIsRootW(LPCWSTR lpszPath)
1106 TRACE("%s\n",debugstr_w(lpszPath));
1108 /* X:\ */
1109 if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
1110 return TRUE;
1112 /* "\" */
1113 if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
1114 return TRUE;
1116 /* UNC "\\<computer>\<share>" */
1117 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
1119 int foundbackslash = 0;
1120 lpszPath += 2;
1121 while (*lpszPath)
1123 if (*(lpszPath++)=='\\') foundbackslash++;
1125 if (foundbackslash==1)
1126 return TRUE;
1128 return FALSE;
1132 /*************************************************************************
1133 * PathIsRootAW [SHELL32.29]
1135 BOOL WINAPI PathIsRootAW(LPCVOID lpszPath)
1137 if (VERSION_OsIsUnicode())
1138 return PathIsRootW(lpszPath);
1139 return PathIsRootA(lpszPath);
1142 /*************************************************************************
1143 * PathIsExeA [internal]
1145 BOOL WINAPI PathIsExeA (LPCSTR lpszPath)
1147 LPCSTR lpszExtension = PathGetExtensionA(lpszPath);
1148 int i = 0;
1149 static char * lpszExtensions[6] = {"exe", "com", "pid", "cmd", "bat", NULL };
1151 TRACE("path=%s\n",lpszPath);
1153 for(i=0; lpszExtensions[i]; i++)
1154 if (!strcasecmp(lpszExtension,lpszExtensions[i])) return TRUE;
1156 return FALSE;
1159 /*************************************************************************
1160 * PathIsExeW [internal]
1162 BOOL WINAPI PathIsExeW (LPCWSTR lpszPath)
1164 LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
1165 int i = 0;
1166 static WCHAR lpszExtensions[6][4] =
1167 {{'e','x','e','\0'}, {'c','o','m','\0'}, {'p','i','d','\0'},
1168 {'c','m','d','\0'}, {'b','a','t','\0'}, {'\0'} };
1170 TRACE("path=%s\n",debugstr_w(lpszPath));
1172 for(i=0; lpszExtensions[i]; i++)
1173 if (!strcmpiW(lpszExtension,lpszExtensions[i])) return TRUE;
1175 return FALSE;
1178 /*************************************************************************
1179 * PathIsExeAW [SHELL32.43]
1181 BOOL WINAPI PathIsExeAW (LPCVOID path)
1183 if (VERSION_OsIsUnicode())
1184 return PathIsExeW (path);
1185 return PathIsExeA(path);
1188 /*************************************************************************
1189 * PathIsDirectoryA [SHLWAPI.@]
1191 BOOL WINAPI PathIsDirectoryA(LPCSTR lpszPath)
1193 HANDLE hFile;
1194 WIN32_FIND_DATAA stffile;
1196 TRACE("%s\n", debugstr_a(lpszPath));
1198 hFile = FindFirstFileA(lpszPath, &stffile);
1200 if ( hFile != INVALID_HANDLE_VALUE )
1202 FindClose (hFile);
1203 return (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
1206 return FALSE;
1209 /*************************************************************************
1210 * PathIsDirectoryW [SHLWAPI.@]
1212 BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
1214 HANDLE hFile;
1215 WIN32_FIND_DATAW stffile;
1217 TRACE("%s\n", debugstr_w(lpszPath));
1219 hFile = FindFirstFileW(lpszPath, &stffile);
1221 if ( hFile != INVALID_HANDLE_VALUE )
1223 FindClose (hFile);
1224 return (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
1227 return FALSE;
1230 /*************************************************************************
1231 * PathIsDirectoryAW [SHELL32.159]
1233 BOOL WINAPI PathIsDirectoryAW (LPCVOID lpszPath)
1235 if (VERSION_OsIsUnicode())
1236 return PathIsDirectoryW (lpszPath);
1237 return PathIsDirectoryA (lpszPath);
1240 /*************************************************************************
1241 * PathFileExistsA [SHLWAPI.@]
1243 * NOTES
1244 * file_exists(char *fn);
1246 BOOL WINAPI PathFileExistsA(LPCSTR lpszPath)
1248 TRACE("%s\n",lpszPath);
1249 return (GetFileAttributesA(lpszPath)!=-1);
1252 /*************************************************************************
1253 * PathFileExistsW [SHLWAPI.@]
1255 BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
1257 TRACE("%s\n",debugstr_w(lpszPath));
1258 return (GetFileAttributesW(lpszPath)!=-1);
1261 /*************************************************************************
1262 * PathFileExistsAW [SHELL32.45]
1264 BOOL WINAPI PathFileExistsAW (LPCVOID lpszPath)
1266 if (VERSION_OsIsUnicode())
1267 return PathFileExistsW (lpszPath);
1268 return PathFileExistsA (lpszPath);
1271 /*************************************************************************
1272 * PathMatchSingleMaskA [internal]
1274 * NOTES
1275 * internal (used by PathMatchSpec)
1277 static BOOL PathMatchSingleMaskA(LPCSTR name, LPCSTR mask)
1279 while (*name && *mask && *mask!=';')
1281 if (*mask=='*')
1285 if (PathMatchSingleMaskA(name,mask+1)) return 1; /* try substrings */
1286 } while (*name++);
1287 return 0;
1289 if (toupper(*mask)!=toupper(*name) && *mask!='?') return 0;
1290 name++;
1291 mask++;
1293 if (!*name)
1295 while (*mask=='*') mask++;
1296 if (!*mask || *mask==';') return 1;
1298 return 0;
1301 /*************************************************************************
1302 * PathMatchSingleMaskW [internal]
1304 static BOOL PathMatchSingleMaskW(LPCWSTR name, LPCWSTR mask)
1306 while (*name && *mask && *mask!=';')
1308 if (*mask=='*')
1312 if (PathMatchSingleMaskW(name,mask+1)) return 1; /* try substrings */
1313 } while (*name++);
1314 return 0;
1316 if (toupperW(*mask)!=toupperW(*name) && *mask!='?') return 0;
1317 name++;
1318 mask++;
1320 if (!*name)
1322 while (*mask=='*') mask++;
1323 if (!*mask || *mask==';') return 1;
1325 return 0;
1327 /*************************************************************************
1328 * PathMatchSpecA [SHLWAPI.@]
1330 * NOTES
1331 * used from COMDLG32
1333 BOOL WINAPI PathMatchSpecA(LPCSTR name, LPCSTR mask)
1335 TRACE("%s %s\n",name,mask);
1337 if (!lstrcmpA( mask, "*.*" )) return 1; /* we don't require a period */
1339 while (*mask)
1341 if (PathMatchSingleMaskA(name,mask)) return 1; /* helper function */
1342 while (*mask && *mask!=';') mask++;
1343 if (*mask==';')
1345 mask++;
1346 while (*mask==' ') mask++; /* masks may be separated by "; " */
1349 return 0;
1352 /*************************************************************************
1353 * PathMatchSpecW [SHLWAPI.@]
1355 BOOL WINAPI PathMatchSpecW(LPCWSTR name, LPCWSTR mask)
1357 WCHAR stemp[4];
1358 TRACE("%s %s\n",debugstr_w(name),debugstr_w(mask));
1360 lstrcpyAtoW(stemp,"*.*");
1361 if (!lstrcmpW( mask, stemp )) return 1; /* we don't require a period */
1363 while (*mask)
1365 if (PathMatchSingleMaskW(name,mask)) return 1; /* helper function */
1366 while (*mask && *mask!=';') mask++;
1367 if (*mask==';')
1369 mask++;
1370 while (*mask==' ') mask++; /* masks may be separated by "; " */
1373 return 0;
1376 /*************************************************************************
1377 * PathMatchSpecAW [SHELL32.46]
1379 BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
1381 if (VERSION_OsIsUnicode())
1382 return PathMatchSpecW( name, mask );
1383 return PathMatchSpecA( name, mask );
1386 /*************************************************************************
1387 * PathIsSameRootA [SHLWAPI.@]
1389 * FIXME
1390 * what to do with "\path" ??
1392 BOOL WINAPI PathIsSameRootA(LPCSTR lpszPath1, LPCSTR lpszPath2)
1394 TRACE("%s %s\n", lpszPath1, lpszPath2);
1396 if (PathIsRelativeA(lpszPath1) || PathIsRelativeA(lpszPath2)) return FALSE;
1398 /* usual path */
1399 if ( toupper(lpszPath1[0])==toupper(lpszPath2[0]) &&
1400 lpszPath1[1]==':' && lpszPath2[1]==':' &&
1401 lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
1402 return TRUE;
1404 /* UNC */
1405 if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
1406 lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
1408 int pos=2, bsfound=0;
1409 while (lpszPath1[pos] && lpszPath2[pos] &&
1410 (lpszPath1[pos] == lpszPath2[pos]))
1412 if (lpszPath1[pos]=='\\') bsfound++;
1413 if (bsfound == 2) return TRUE;
1414 pos++;
1416 return (lpszPath1[pos] == lpszPath2[pos]);
1418 return FALSE;
1421 /*************************************************************************
1422 * PathIsSameRootW [SHLWAPI.@]
1424 BOOL WINAPI PathIsSameRootW(LPCWSTR lpszPath1, LPCWSTR lpszPath2)
1426 TRACE("%s %s\n", debugstr_w(lpszPath1), debugstr_w(lpszPath2));
1428 if (PathIsRelativeW(lpszPath1) || PathIsRelativeW(lpszPath2)) return FALSE;
1430 /* usual path */
1431 if ( toupperW(lpszPath1[0])==toupperW(lpszPath2[0]) &&
1432 lpszPath1[1]==':' && lpszPath2[1]==':' &&
1433 lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
1434 return TRUE;
1436 /* UNC */
1437 if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
1438 lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
1440 int pos=2, bsfound=0;
1441 while (lpszPath1[pos] && lpszPath2[pos] &&
1442 (lpszPath1[pos] == lpszPath2[pos]))
1444 if (lpszPath1[pos]=='\\') bsfound++;
1445 if (bsfound == 2) return TRUE;
1446 pos++;
1448 return (lpszPath1[pos] == lpszPath2[pos]);
1450 return FALSE;
1453 /*************************************************************************
1454 * PathIsSameRootAW [SHELL32.650]
1456 BOOL WINAPI PathIsSameRootAW(LPCVOID lpszPath1, LPCVOID lpszPath2)
1458 if (VERSION_OsIsUnicode())
1459 return PathIsSameRootW(lpszPath1, lpszPath2);
1460 return PathIsSameRootA(lpszPath1, lpszPath2);
1463 /*************************************************************************
1464 * PathIsURLA
1466 BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
1468 LPSTR lpstrRes;
1469 int iSize, i=0;
1470 static LPSTR SupportedProtocol[] =
1471 {"http","https","ftp","gopher","file","mailto",NULL};
1473 if(!lpstrPath) return FALSE;
1475 /* get protocol */
1476 lpstrRes = strchr(lpstrPath,':');
1477 if(!lpstrRes) return FALSE;
1478 iSize = lpstrRes - lpstrPath;
1480 while(SupportedProtocol[i])
1482 if (iSize == strlen(SupportedProtocol[i]))
1483 if(!strncasecmp(lpstrPath, SupportedProtocol[i], iSize));
1484 return TRUE;
1485 i++;
1488 return FALSE;
1491 /*************************************************************************
1492 * PathIsURLW
1494 BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
1496 LPWSTR lpstrRes;
1497 int iSize, i=0;
1498 static WCHAR SupportedProtocol[7][7] =
1499 {{'h','t','t','p','\0'},{'h','t','t','p','s','\0'},{'f','t','p','\0'},
1500 {'g','o','p','h','e','r','\0'},{'f','i','l','e','\0'},
1501 {'m','a','i','l','t','o','\0'},{0}};
1503 if(!lpstrPath) return FALSE;
1505 /* get protocol */
1506 lpstrRes = strchrW(lpstrPath,':');
1507 if(!lpstrRes) return FALSE;
1508 iSize = lpstrRes - lpstrPath;
1510 while(SupportedProtocol[i])
1512 if (iSize == strlenW(SupportedProtocol[i]))
1513 if(!strncmpiW(lpstrPath, SupportedProtocol[i], iSize));
1514 return TRUE;
1515 i++;
1518 return FALSE;
1521 /*************************************************************************
1522 * IsLFNDriveA [SHELL32.119]
1524 * NOTES
1525 * exported by ordinal Name
1527 BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath)
1529 DWORD fnlen;
1531 if (!GetVolumeInformationA(lpszPath,NULL,0,NULL,&fnlen,NULL,NULL,0))
1532 return FALSE;
1533 return fnlen>12;
1537 Creating Something Unique
1539 /*************************************************************************
1540 * PathMakeUniqueNameA [internal]
1542 BOOL WINAPI PathMakeUniqueNameA(
1543 LPSTR lpszBuffer,
1544 DWORD dwBuffSize,
1545 LPCSTR lpszShortName,
1546 LPCSTR lpszLongName,
1547 LPCSTR lpszPathName)
1549 FIXME("%p %lu %s %s %s stub\n",
1550 lpszBuffer, dwBuffSize, debugstr_a(lpszShortName),
1551 debugstr_a(lpszLongName), debugstr_a(lpszPathName));
1552 return TRUE;
1555 /*************************************************************************
1556 * PathMakeUniqueNameW [internal]
1558 BOOL WINAPI PathMakeUniqueNameW(
1559 LPWSTR lpszBuffer,
1560 DWORD dwBuffSize,
1561 LPCWSTR lpszShortName,
1562 LPCWSTR lpszLongName,
1563 LPCWSTR lpszPathName)
1565 FIXME("%p %lu %s %s %s stub\n",
1566 lpszBuffer, dwBuffSize, debugstr_w(lpszShortName),
1567 debugstr_w(lpszLongName), debugstr_w(lpszPathName));
1568 return TRUE;
1571 /*************************************************************************
1572 * PathMakeUniqueNameAW [SHELL32.47]
1574 BOOL WINAPI PathMakeUniqueNameAW(
1575 LPVOID lpszBuffer,
1576 DWORD dwBuffSize,
1577 LPCVOID lpszShortName,
1578 LPCVOID lpszLongName,
1579 LPCVOID lpszPathName)
1581 if (VERSION_OsIsUnicode())
1582 return PathMakeUniqueNameW(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
1583 return PathMakeUniqueNameA(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
1586 /*************************************************************************
1587 * PathYetAnotherMakeUniqueNameA [SHELL32.75]
1589 * NOTES
1590 * exported by ordinal
1592 BOOL WINAPI PathYetAnotherMakeUniqueNameA(
1593 LPSTR lpszBuffer,
1594 LPCSTR lpszPathName,
1595 LPCSTR lpszShortName,
1596 LPCSTR lpszLongName)
1598 FIXME("(%p,%p, %p ,%p):stub.\n",
1599 lpszBuffer, lpszPathName, lpszShortName, lpszLongName);
1600 return TRUE;
1605 cleaning and resolving paths
1608 /*************************************************************************
1609 * PathFindOnPathA [SHELL32.145]
1611 BOOL WINAPI PathFindOnPathA(LPSTR sFile, LPCSTR sOtherDirs)
1613 FIXME("%s %s\n",sFile, sOtherDirs);
1614 return FALSE;
1617 /*************************************************************************
1618 * PathFindOnPathW [SHELL32]
1620 BOOL WINAPI PathFindOnPathW(LPWSTR sFile, LPCWSTR sOtherDirs)
1622 FIXME("%s %s\n",debugstr_w(sFile), debugstr_w(sOtherDirs));
1623 return FALSE;
1626 /*************************************************************************
1627 * PathFindOnPathAW [SHELL32]
1629 BOOL WINAPI PathFindOnPathAW(LPVOID sFile, LPCVOID sOtherDirs)
1631 if (VERSION_OsIsUnicode())
1632 return PathFindOnPathW(sFile, sOtherDirs);
1633 return PathFindOnPathA(sFile, sOtherDirs);
1636 /*************************************************************************
1637 * PathCleanupSpecA [SHELL32.171]
1639 DWORD WINAPI PathCleanupSpecA(LPSTR x, LPSTR y)
1641 FIXME("(%p %s, %p %s) stub\n",x,debugstr_a(x),y,debugstr_a(y));
1642 return TRUE;
1645 /*************************************************************************
1646 * PathCleanupSpecA [SHELL32]
1648 DWORD WINAPI PathCleanupSpecW(LPWSTR x, LPWSTR y)
1650 FIXME("(%p %s, %p %s) stub\n",x,debugstr_w(x),y,debugstr_w(y));
1651 return TRUE;
1654 /*************************************************************************
1655 * PathCleanupSpecAW [SHELL32]
1657 DWORD WINAPI PathCleanupSpecAW (LPVOID x, LPVOID y)
1659 if (VERSION_OsIsUnicode())
1660 return PathCleanupSpecW(x,y);
1661 return PathCleanupSpecA(x,y);
1664 /*************************************************************************
1665 * PathQualifyA [SHELL32]
1667 BOOL WINAPI PathQualifyA(LPCSTR pszPath)
1669 FIXME("%s\n",pszPath);
1670 return 0;
1673 /*************************************************************************
1674 * PathQualifyW [SHELL32]
1676 BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
1678 FIXME("%s\n",debugstr_w(pszPath));
1679 return 0;
1682 /*************************************************************************
1683 * PathQualifyAW [SHELL32]
1685 BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
1687 if (VERSION_OsIsUnicode())
1688 return PathQualifyW(pszPath);
1689 return PathQualifyA(pszPath);
1692 /*************************************************************************
1693 * PathResolveA [SHELL32.51]
1695 BOOL WINAPI PathResolveA(
1696 LPSTR lpszPath,
1697 LPCSTR *alpszPaths,
1698 DWORD dwFlags)
1700 FIXME("(%s,%p,0x%08lx),stub!\n",
1701 lpszPath, *alpszPaths, dwFlags);
1702 return 0;
1705 /*************************************************************************
1706 * PathResolveW [SHELL32]
1708 BOOL WINAPI PathResolveW(
1709 LPWSTR lpszPath,
1710 LPCWSTR *alpszPaths,
1711 DWORD dwFlags)
1713 FIXME("(%s,%p,0x%08lx),stub!\n",
1714 debugstr_w(lpszPath), debugstr_w(*alpszPaths), dwFlags);
1715 return 0;
1718 /*************************************************************************
1719 * PathResolveAW [SHELL32]
1721 BOOL WINAPI PathResolveAW(
1722 LPVOID lpszPath,
1723 LPCVOID *alpszPaths,
1724 DWORD dwFlags)
1726 if (VERSION_OsIsUnicode())
1727 return PathResolveW(lpszPath, (LPCWSTR*)alpszPaths, dwFlags);
1728 return PathResolveA(lpszPath, (LPCSTR*)alpszPaths, dwFlags);
1731 /*************************************************************************
1732 * PathProcessCommandA [SHELL32.653]
1734 HRESULT WINAPI PathProcessCommandA (
1735 LPCSTR lpszPath,
1736 LPSTR lpszBuff,
1737 DWORD dwBuffSize,
1738 DWORD dwFlags)
1740 FIXME("%s %p 0x%04lx 0x%04lx stub\n",
1741 lpszPath, lpszBuff, dwBuffSize, dwFlags);
1742 lstrcpyA(lpszBuff, lpszPath);
1743 return 0;
1746 /*************************************************************************
1747 * PathProcessCommandW
1749 HRESULT WINAPI PathProcessCommandW (
1750 LPCWSTR lpszPath,
1751 LPWSTR lpszBuff,
1752 DWORD dwBuffSize,
1753 DWORD dwFlags)
1755 FIXME("(%s, %p, 0x%04lx, 0x%04lx) stub\n",
1756 debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags);
1757 lstrcpyW(lpszBuff, lpszPath);
1758 return 0;
1761 /*************************************************************************
1762 * PathProcessCommandAW
1764 HRESULT WINAPI PathProcessCommandAW (
1765 LPCVOID lpszPath,
1766 LPVOID lpszBuff,
1767 DWORD dwBuffSize,
1768 DWORD dwFlags)
1770 if (VERSION_OsIsUnicode())
1771 return PathProcessCommandW(lpszPath, lpszBuff, dwBuffSize, dwFlags);
1772 return PathProcessCommandA(lpszPath, lpszBuff, dwBuffSize, dwFlags);
1776 special
1779 /*************************************************************************
1780 * PathSetDlgItemPathA
1782 * NOTES
1783 * use PathCompactPath to make sure, the path fits into the control
1785 BOOL WINAPI PathSetDlgItemPathA(HWND hDlg, int id, LPCSTR pszPath)
1786 { TRACE("%x %x %s\n",hDlg, id, pszPath);
1787 return SetDlgItemTextA(hDlg, id, pszPath);
1790 /*************************************************************************
1791 * PathSetDlgItemPathW
1793 BOOL WINAPI PathSetDlgItemPathW(HWND hDlg, int id, LPCWSTR pszPath)
1794 { TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
1795 return SetDlgItemTextW(hDlg, id, pszPath);
1798 /*************************************************************************
1799 * PathSetDlgItemPathAW
1801 BOOL WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
1802 { if (VERSION_OsIsUnicode())
1803 return PathSetDlgItemPathW(hDlg, id, pszPath);
1804 return PathSetDlgItemPathA(hDlg, id, pszPath);
1808 /*************************************************************************
1809 * SHGetSpecialFolderPathA [SHELL32.175]
1811 * converts csidl to path
1815 static char * szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
1816 static char * szSHUserFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
1818 BOOL WINAPI SHGetSpecialFolderPathA (
1819 HWND hwndOwner,
1820 LPSTR szPath,
1821 DWORD csidl,
1822 BOOL bCreate)
1824 CHAR szValueName[MAX_PATH], szDefaultPath[MAX_PATH];
1825 HKEY hRootKey, hKey;
1826 BOOL bRelative = TRUE;
1827 DWORD dwType, dwDisp, dwPathLen = MAX_PATH;
1829 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
1831 /* build default values */
1832 switch(csidl)
1834 case CSIDL_APPDATA:
1835 hRootKey = HKEY_CURRENT_USER;
1836 strcpy (szValueName, "AppData");
1837 strcpy (szDefaultPath, "AppData");
1838 break;
1840 case CSIDL_COOKIES:
1841 hRootKey = HKEY_CURRENT_USER;
1842 strcpy (szValueName, "Cookies");
1843 strcpy(szDefaultPath, "Cookies");
1844 break;
1846 case CSIDL_DESKTOPDIRECTORY:
1847 hRootKey = HKEY_CURRENT_USER;
1848 strcpy(szValueName, "Desktop");
1849 strcpy(szDefaultPath, "Desktop");
1850 break;
1852 case CSIDL_COMMON_DESKTOPDIRECTORY:
1853 hRootKey = HKEY_LOCAL_MACHINE;
1854 strcpy(szValueName, "Common Desktop");
1855 strcpy(szDefaultPath, "Desktop");
1856 break;
1858 case CSIDL_FAVORITES:
1859 hRootKey = HKEY_CURRENT_USER;
1860 strcpy(szValueName, "Favorites");
1861 strcpy(szDefaultPath, "Favorites");
1862 break;
1864 case CSIDL_FONTS:
1865 hRootKey = HKEY_CURRENT_USER;
1866 strcpy(szValueName, "Fonts");
1867 strcpy(szDefaultPath, "Fonts");
1868 break;
1870 case CSIDL_HISTORY:
1871 hRootKey = HKEY_CURRENT_USER;
1872 strcpy(szValueName, "History");
1873 strcpy(szDefaultPath, "History");
1874 break;
1876 case CSIDL_NETHOOD:
1877 hRootKey = HKEY_CURRENT_USER;
1878 strcpy(szValueName, "NetHood");
1879 strcpy(szDefaultPath, "NetHood");
1880 break;
1882 case CSIDL_INTERNET_CACHE:
1883 hRootKey = HKEY_CURRENT_USER;
1884 strcpy(szValueName, "Cache");
1885 strcpy(szDefaultPath, "Temporary Internet Files");
1886 break;
1888 case CSIDL_PERSONAL:
1889 hRootKey = HKEY_CURRENT_USER;
1890 strcpy(szValueName, "Personal");
1891 strcpy(szDefaultPath, "My Own Files");
1892 bRelative = FALSE;
1893 break;
1895 case CSIDL_PRINTHOOD:
1896 hRootKey = HKEY_CURRENT_USER;
1897 strcpy(szValueName, "PrintHood");
1898 strcpy(szDefaultPath, "PrintHood");
1899 break;
1901 case CSIDL_PROGRAMS:
1902 hRootKey = HKEY_CURRENT_USER;
1903 strcpy(szValueName, "Programs");
1904 strcpy(szDefaultPath, "StartMenu\\Programs");
1905 break;
1907 case CSIDL_COMMON_PROGRAMS:
1908 hRootKey = HKEY_LOCAL_MACHINE;
1909 strcpy(szValueName, "Common Programs");
1910 strcpy(szDefaultPath, "");
1911 break;
1913 case CSIDL_RECENT:
1914 hRootKey = HKEY_CURRENT_USER;
1915 strcpy(szValueName, "Recent");
1916 strcpy(szDefaultPath, "Recent");
1917 break;
1919 case CSIDL_SENDTO:
1920 hRootKey = HKEY_CURRENT_USER;
1921 strcpy(szValueName, "SendTo");
1922 strcpy(szDefaultPath, "SendTo");
1923 break;
1925 case CSIDL_STARTMENU:
1926 hRootKey = HKEY_CURRENT_USER;
1927 strcpy(szValueName, "StartMenu");
1928 strcpy(szDefaultPath, "StartMenu");
1929 break;
1931 case CSIDL_COMMON_STARTMENU:
1932 hRootKey = HKEY_LOCAL_MACHINE;
1933 strcpy(szValueName, "Common StartMenu");
1934 strcpy(szDefaultPath, "StartMenu");
1935 break;
1937 case CSIDL_STARTUP:
1938 hRootKey = HKEY_CURRENT_USER;
1939 strcpy(szValueName, "Startup");
1940 strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
1941 break;
1943 case CSIDL_COMMON_STARTUP:
1944 hRootKey = HKEY_LOCAL_MACHINE;
1945 strcpy(szValueName, "Common Startup");
1946 strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
1947 break;
1949 case CSIDL_TEMPLATES:
1950 hRootKey = HKEY_CURRENT_USER;
1951 strcpy(szValueName, "Templates");
1952 strcpy(szDefaultPath, "ShellNew");
1953 break;
1955 default:
1956 ERR("folder unknown or not allowed\n");
1957 return FALSE;
1960 /* user shell folders */
1961 if (RegCreateKeyExA(hRootKey,szSHUserFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1963 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1965 RegCloseKey(hKey);
1967 /* shell folders */
1968 if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
1970 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
1973 /* value not existing */
1974 if (bRelative)
1976 GetWindowsDirectoryA(szPath, MAX_PATH);
1977 PathAddBackslashA(szPath);
1978 strcat(szPath, szDefaultPath);
1980 else
1982 strcpy(szPath, "C:\\"); /* fixme ??? */
1983 strcat(szPath, szDefaultPath);
1985 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
1988 RegCloseKey(hKey);
1990 if (bCreate && CreateDirectoryA(szPath,NULL))
1992 MESSAGE("Created not existing system directory '%s'\n", szPath);
1995 return TRUE;
1998 /*************************************************************************
1999 * SHGetSpecialFolderPathW
2001 BOOL WINAPI SHGetSpecialFolderPathW (
2002 HWND hwndOwner,
2003 LPWSTR szPath,
2004 DWORD csidl,
2005 BOOL bCreate)
2007 char szTemp[MAX_PATH];
2009 if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate))
2011 lstrcpynAtoW(szPath, szTemp, MAX_PATH);
2014 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
2016 return TRUE;
2019 /*************************************************************************
2020 * SHGetSpecialFolderPathAW
2022 BOOL WINAPI SHGetSpecialFolderPathAW (
2023 HWND hwndOwner,
2024 LPVOID szPath,
2025 DWORD csidl,
2026 BOOL bCreate)
2029 if (VERSION_OsIsUnicode())
2030 return SHGetSpecialFolderPathW (hwndOwner, szPath, csidl, bCreate);
2031 return SHGetSpecialFolderPathA (hwndOwner, szPath, csidl, bCreate);
2034 /*************************************************************************
2035 * PathCanonicalizeA
2037 * FIXME
2038 * returnvalue
2041 BOOL WINAPI PathCanonicalizeA(LPSTR pszBuf, LPCSTR pszPath)
2043 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = strlen(pszPath);
2044 BOOL bModifyed = FALSE;
2046 TRACE("%p %s\n", pszBuf, pszPath);
2048 pszBuf[OffsetDst]='\0';
2050 /* keep the root of the path */
2051 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
2053 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2055 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
2057 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2058 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2059 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
2061 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2062 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
2064 /* C:\. */
2065 OffsetSrc++; LenSrc--; bModifyed = TRUE;
2067 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
2069 /* C:\.. */
2070 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
2075 /* ".\" at the beginning of the path */
2076 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
2078 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
2081 while ( LenSrc )
2083 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
2085 /* "\.." found, go one deeper */
2086 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
2087 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
2088 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
2089 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
2091 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
2093 /* "\." found, skip it */
2094 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
2096 else
2098 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
2101 pszBuf[OffsetDst] = '\0';
2102 TRACE("-- %s %u\n", pszBuf, bModifyed);
2103 return bModifyed;
2107 /*************************************************************************
2108 * PathCanonicalizeW
2110 * FIXME
2111 * returnvalue
2113 BOOL WINAPI PathCanonicalizeW(LPWSTR pszBuf, LPCWSTR pszPath)
2115 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = lstrlenW(pszPath);
2116 BOOL bModifyed = FALSE;
2118 TRACE("%p %s\n", pszBuf, debugstr_w(pszPath));
2120 pszBuf[OffsetDst]='\0';
2122 /* keep the root of the path */
2123 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
2125 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2127 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
2129 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2130 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2131 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
2133 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
2134 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
2136 /* C:\. */
2137 OffsetSrc++; LenSrc--; bModifyed = TRUE;
2139 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
2141 /* C:\.. */
2142 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
2147 /* ".\" at the beginning of the path */
2148 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
2150 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
2153 while ( LenSrc )
2155 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
2157 /* "\.." found, go one deeper */
2158 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
2159 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
2160 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
2161 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
2163 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
2165 /* "\." found, skip it */
2166 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
2168 else
2170 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
2173 pszBuf[OffsetDst] = '\0';
2174 TRACE("-- %s %u\n", debugstr_w(pszBuf), bModifyed);
2175 return bModifyed;
2178 /*************************************************************************
2179 * PathFindNextComponentA
2181 * Windows returns a pointer NULL (BO 000605)
2183 LPSTR WINAPI PathFindNextComponentA(LPCSTR pszPath)
2185 while( *pszPath )
2187 if(*pszPath++=='\\')
2188 return (LPSTR) pszPath;
2190 return (LPSTR) pszPath;
2193 /*************************************************************************
2194 * PathFindNextComponentW
2196 LPWSTR WINAPI PathFindNextComponentW(LPCWSTR pszPath)
2198 while( *pszPath )
2200 if(*pszPath++=='\\')
2201 return (LPWSTR) pszPath;
2203 return (LPWSTR) pszPath;
2206 /*************************************************************************
2207 * PathAddExtensionA
2210 static void _PathAddDotA(LPSTR lpszPath)
2212 int len = strlen(lpszPath);
2213 if (len && lpszPath[len-1]!='.')
2215 lpszPath[len] = '.';
2216 lpszPath[len+1]= '\0';
2220 BOOL WINAPI PathAddExtensionA(
2221 LPSTR pszPath,
2222 LPCSTR pszExtension)
2224 if (*pszPath)
2226 LPSTR pszExt = PathFindFileNameA(pszPath); /* last path component */
2227 pszExt = PathFindExtensionA(pszExt);
2228 if (*pszExt != '\0') return FALSE; /* already with extension */
2229 _PathAddDotA(pszPath);
2232 if (!pszExtension || *pszExtension=='\0')
2233 strcat(pszPath, "exe");
2234 else
2235 strcat(pszPath, pszExtension);
2236 return TRUE;
2239 /*************************************************************************
2240 * PathAddExtensionW
2242 static void _PathAddDotW(LPWSTR lpszPath)
2244 int len = lstrlenW(lpszPath);
2245 if (len && lpszPath[len-1]!='.')
2247 lpszPath[len] = '.';
2248 lpszPath[len+1]= '\0';
2252 /*************************************************************************
2253 * PathAddExtensionW
2255 BOOL WINAPI PathAddExtensionW(
2256 LPWSTR pszPath,
2257 LPCWSTR pszExtension)
2259 static const WCHAR ext[] = { 'e','x','e',0 };
2261 if (*pszPath)
2263 LPWSTR pszExt = PathFindFileNameW(pszPath); /* last path component */
2264 pszExt = PathFindExtensionW(pszExt);
2265 if (*pszExt != '\0') return FALSE; /* already with extension */
2266 _PathAddDotW(pszPath);
2269 if (!pszExtension || *pszExtension=='\0')
2270 lstrcatW(pszPath, ext);
2271 else
2272 lstrcatW(pszPath, pszExtension);
2273 return TRUE;
2277 /*************************************************************************
2278 * PathIsUNCServerA
2280 BOOL WINAPI PathIsUNCServerA(
2281 LPCSTR pszPath)
2283 FIXME("%s\n", pszPath);
2284 return FALSE;
2287 /*************************************************************************
2288 * PathIsUNCServerW
2290 BOOL WINAPI PathIsUNCServerW(
2291 LPCWSTR pszPath)
2293 FIXME("%s\n", debugstr_w(pszPath));
2294 return FALSE;
2297 /*************************************************************************
2298 * PathIsUNCServerShareA
2300 BOOL WINAPI PathIsUNCServerShareA(
2301 LPCSTR pszPath)
2303 FIXME("%s\n", pszPath);
2304 return FALSE;
2307 /*************************************************************************
2308 * PathIsUNCServerShareW
2310 BOOL WINAPI PathIsUNCServerShareW(
2311 LPCWSTR pszPath)
2313 FIXME("%s\n", debugstr_w(pszPath));
2314 return FALSE;
2317 /*************************************************************************
2318 * PathMakePrettyA
2320 BOOL WINAPI PathMakePrettyA(
2321 LPSTR lpPath)
2323 FIXME("%s\n", lpPath);
2324 return TRUE;
2327 /*************************************************************************
2328 * PathMakePrettyW
2330 BOOL WINAPI PathMakePrettyW(
2331 LPWSTR lpPath)
2333 FIXME("%s\n", debugstr_w(lpPath));
2334 return TRUE;