source: trunk/src/shlwapi/path.c@ 4081

Last change on this file since 4081 was 4081, checked in by sandervl, 25 years ago

resync with Wine 20000801

File size: 41.7 KB
Line 
1/*
2 * Path Functions
3 *
4 * Note: Odin changes marked by #ifdef __WIN32OS2__
5 */
6
7#ifdef __WIN32OS2__
8#include <odin.h>
9#include <odinwrap.h>
10#include <os2sel.h>
11
12#include <string.h>
13#include <wctype.h>
14#include <wcstr.h>
15#define HAVE_WCTYPE_H
16#include <win\shlwapi.h>
17
18#include <heapstring.h>
19#endif
20
21#include <ctype.h>
22#include <string.h>
23
24#include "winerror.h"
25#include "wine/unicode.h"
26#include "wine/undocshell.h"
27#include "shlwapi.h"
28#include "debugtools.h"
29
30DEFAULT_DEBUG_CHANNEL(shell);
31
32#define isSlash(x) ((x)=='\\' || (x)=='/')
33/*
34 ########## Combining and Constructing paths ##########
35*/
36
37/*************************************************************************
38 * PathAppendA [SHLWAPI.@]
39 *
40 * NOTES
41 * concat path lpszPath2 onto lpszPath1
42 *
43 * FIXME
44 * the resulting path is also canonicalized
45 */
46BOOL WINAPI PathAppendA(
47 LPSTR lpszPath1,
48 LPCSTR lpszPath2)
49{
50 TRACE("%s %s\n",lpszPath1, lpszPath2);
51 while (lpszPath2[0]=='\\') lpszPath2++;
52 PathCombineA(lpszPath1,lpszPath1,lpszPath2);
53 return TRUE;
54}
55
56/*************************************************************************
57 * PathAppendW [SHLWAPI.@]
58 */
59BOOL WINAPI PathAppendW(
60 LPWSTR lpszPath1,
61 LPCWSTR lpszPath2)
62{
63 TRACE("%s %s\n",debugstr_w(lpszPath1), debugstr_w(lpszPath2));
64 while (lpszPath2[0]=='\\') lpszPath2++;
65 PathCombineW(lpszPath1,lpszPath1,lpszPath2);
66 return TRUE;
67}
68
69/*************************************************************************
70 * PathCombineA [SHLWAPI.@]
71 *
72 * NOTES
73 * if lpszFile='.' skip it
74 * szDest can be equal to lpszFile. Thats why we use sTemp
75 *
76 * FIXME
77 * the resulting path is also canonicalized
78 */
79LPSTR WINAPI PathCombineA(
80 LPSTR szDest,
81 LPCSTR lpszDir,
82 LPCSTR lpszFile)
83{
84 char sTemp[MAX_PATH];
85 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, lpszDir, lpszFile, lpszFile);
86
87
88 if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
89 {
90 strcpy(szDest,lpszDir);
91 return szDest;
92 }
93
94 /* if lpszFile is a complete path don't care about lpszDir */
95 if (PathGetDriveNumberA(lpszFile) != -1)
96 {
97 strcpy(szDest,lpszFile);
98 }
99 else if (lpszFile[0] == '\\' )
100 {
101 strcpy(sTemp,lpszDir);
102 PathStripToRootA(sTemp);
103 strcat(sTemp,lpszFile);
104 strcpy(szDest,sTemp);
105 }
106 else
107 {
108 strcpy(sTemp,lpszDir);
109 PathAddBackslashA(sTemp);
110 strcat(sTemp,lpszFile);
111 strcpy(szDest,sTemp);
112 }
113 return szDest;
114}
115
116/*************************************************************************
117 * PathCombineW [SHLWAPI.@]
118 */
119LPWSTR WINAPI PathCombineW(
120 LPWSTR szDest,
121 LPCWSTR lpszDir,
122 LPCWSTR lpszFile)
123{
124 WCHAR sTemp[MAX_PATH];
125 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, debugstr_w(lpszDir),
126 lpszFile, debugstr_w(lpszFile));
127
128
129 if (!lpszFile || !lpszFile[0] || (lpszFile[0]==(WCHAR)'.' && !lpszFile[1]) )
130 {
131 strcpyW(szDest,lpszDir);
132 return szDest;
133 }
134
135 /* if lpszFile is a complete path don't care about lpszDir */
136 if (PathGetDriveNumberW(lpszFile) != -1)
137 {
138 strcpyW(szDest,lpszFile);
139 }
140 else if (lpszFile[0] == (WCHAR)'\\' )
141 {
142 strcpyW(sTemp,lpszDir);
143 PathStripToRootW(sTemp);
144 strcatW(sTemp,lpszFile);
145 strcpyW(szDest,sTemp);
146 }
147 else
148 {
149 strcpyW(sTemp,lpszDir);
150 PathAddBackslashW(sTemp);
151 strcatW(sTemp,lpszFile);
152 strcpyW(szDest,sTemp);
153 }
154 return szDest;
155}
156
157/*************************************************************************
158 * PathAddBackslashA [SHLWAPI.@]
159 *
160 * NOTES
161 * append \ if there is none
162 */
163LPSTR WINAPI PathAddBackslashA(LPSTR lpszPath)
164{
165 int len;
166 TRACE("%p->%s\n",lpszPath,lpszPath);
167
168 len = strlen(lpszPath);
169 if (len && lpszPath[len-1]!='\\')
170 {
171 lpszPath[len] = '\\';
172 lpszPath[len+1]= 0x00;
173 return lpszPath+len+1;
174 }
175 return lpszPath+len;
176}
177
178/*************************************************************************
179 * PathAddBackslashW [SHLWAPI.@]
180 */
181LPWSTR WINAPI PathAddBackslashW(LPWSTR lpszPath)
182{
183 int len;
184 TRACE("%p->%s\n",lpszPath,debugstr_w(lpszPath));
185
186 len = strlenW(lpszPath);
187 if (len && lpszPath[len-1]!=(WCHAR)'\\')
188 {
189 lpszPath[len] = (WCHAR)'\\';
190 lpszPath[len+1]= 0x00;
191 return lpszPath+len+1;
192 }
193 return lpszPath+len;
194}
195
196/*************************************************************************
197 * PathBuildRootA [SHLWAPI.@]
198 */
199LPSTR WINAPI PathBuildRootA(LPSTR lpszPath, int drive)
200{
201 TRACE("%p %i\n",lpszPath, drive);
202
203 strcpy(lpszPath,"A:\\");
204 lpszPath[0]+=drive;
205 return lpszPath;
206}
207
208/*************************************************************************
209 * PathBuildRootW [SHLWAPI.@]
210 */
211LPWSTR WINAPI PathBuildRootW(LPWSTR lpszPath, int drive)
212{
213 TRACE("%p %i\n",debugstr_w(lpszPath), drive);
214
215 lstrcpyAtoW(lpszPath,"A:\\");
216 lpszPath[0]+=drive;
217 return lpszPath;
218}
219
220/*
221 Extracting Component Parts
222*/
223
224/*************************************************************************
225 * PathFindFileNameA [SHLWAPI.@]
226 */
227LPSTR WINAPI PathFindFileNameA(LPCSTR lpszPath)
228{
229 LPCSTR lastSlash = lpszPath;
230
231 TRACE("%s\n",lpszPath);
232 while (*lpszPath)
233 {
234 if ( isSlash(lpszPath[0]) && lpszPath[1])
235 lastSlash = lpszPath+1;
236 lpszPath = CharNextA(lpszPath);
237 }
238 return (LPSTR)lastSlash;
239
240}
241
242/*************************************************************************
243 * PathFindFileNameW [SHLWAPI.@]
244 */
245LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
246{
247 LPCWSTR wslash;
248 wslash = lpszPath;
249
250 TRACE("%s\n",debugstr_w(wslash));
251 while (lpszPath[0])
252 {
253 if (((lpszPath[0]=='\\') || (lpszPath[0]==':')) && lpszPath[1] && lpszPath[1]!='\\')
254 wslash = lpszPath+1;
255 lpszPath = CharNextW(lpszPath);
256 }
257 return (LPWSTR)wslash;
258}
259
260/*************************************************************************
261 * PathFindExtensionA [SHLWAPI.@]
262 *
263 * NOTES
264 * returns pointer to last . in last lpszPath component or at \0.
265 */
266
267LPSTR WINAPI PathFindExtensionA(LPCSTR lpszPath)
268{
269 LPCSTR lastpoint = NULL;
270
271 TRACE("%p %s\n",lpszPath,lpszPath);
272
273 while (*lpszPath)
274 {
275 if (*lpszPath=='\\'||*lpszPath==' ')
276 lastpoint=NULL;
277 if (*lpszPath=='.')
278 lastpoint=lpszPath;
279 lpszPath = CharNextA(lpszPath);
280 }
281 return (LPSTR)(lastpoint?lastpoint:lpszPath);
282}
283
284/*************************************************************************
285 * PathFindExtensionW [SHLWAPI.@]
286 */
287LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
288{
289 LPCWSTR lastpoint = NULL;
290
291 TRACE("(%p %s)\n",lpszPath,debugstr_w(lpszPath));
292
293 while (*lpszPath)
294 {
295 if (*lpszPath==(WCHAR)'\\'||*lpszPath==(WCHAR)' ')
296 lastpoint=NULL;
297 if (*lpszPath==(WCHAR)'.')
298 lastpoint=lpszPath;
299 lpszPath = CharNextW(lpszPath);
300 }
301 return (LPWSTR)(lastpoint?lastpoint:lpszPath);
302}
303
304/*************************************************************************
305 * PathGetArgsA [SHLWAPI.@]
306 *
307 * NOTES
308 * look for next arg in string. handle "quoted" strings
309 * returns pointer to argument *AFTER* the space. Or to the \0.
310 *
311 * FIXME
312 * quoting by '\'
313 */
314LPSTR WINAPI PathGetArgsA(LPCSTR lpszPath)
315{
316 BOOL qflag = FALSE;
317
318 TRACE("%s\n",lpszPath);
319
320 while (*lpszPath)
321 {
322 if ((*lpszPath==' ') && !qflag)
323 return (LPSTR)lpszPath+1;
324 if (*lpszPath=='"')
325 qflag=!qflag;
326 lpszPath = CharNextA(lpszPath);
327 }
328 return (LPSTR)lpszPath;
329}
330
331/*************************************************************************
332 * PathGetArgsW [SHLWAPI.@]
333 */
334LPWSTR WINAPI PathGetArgsW(LPCWSTR lpszPath)
335{
336 BOOL qflag = FALSE;
337
338 TRACE("%s\n",debugstr_w(lpszPath));
339
340 while (*lpszPath)
341 {
342 if ((*lpszPath==' ') && !qflag)
343 return (LPWSTR)lpszPath+1;
344 if (*lpszPath=='"')
345 qflag=!qflag;
346 lpszPath = CharNextW(lpszPath);
347 }
348 return (LPWSTR)lpszPath;
349}
350
351/*************************************************************************
352 * PathGetDriveNumberA [SHLWAPI.@]
353 */
354int WINAPI PathGetDriveNumberA(LPCSTR lpszPath)
355{
356 int chr = tolower(lpszPath[0]);
357
358 TRACE ("%s\n",debugstr_a(lpszPath));
359
360 if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
361 return tolower(lpszPath[0]) - 'a' ;
362}
363
364/*************************************************************************
365 * PathGetDriveNumberW [SHLWAPI.@]
366 */
367int WINAPI PathGetDriveNumberW(LPCWSTR lpszPath)
368{
369 int chr = tolowerW(lpszPath[0]);
370
371 TRACE ("%s\n",debugstr_w(lpszPath));
372
373 if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
374 return tolowerW(lpszPath[0]) - 'a' ;
375}
376
377/*************************************************************************
378 * PathRemoveFileSpecA [SHLWAPI.@]
379 *
380 * NOTES
381 * truncates passed argument to a valid path
382 * returns if the string was modified or not.
383 * "\foo\xx\foo"-> "\foo\xx"
384 * "\" -> "\"
385 * "a:\foo" -> "a:\"
386 */
387BOOL WINAPI PathRemoveFileSpecA(LPSTR lpszPath)
388{
389 LPSTR cutplace = lpszPath;
390 BOOL ret = FALSE;
391
392 TRACE("%s\n",lpszPath);
393
394 if(lpszPath)
395 {
396 while (*lpszPath == '\\') cutplace = ++lpszPath;
397
398 while (*lpszPath)
399 {
400 if(lpszPath[0] == '\\') cutplace = lpszPath;
401
402 if(lpszPath[0] == ':')
403 {
404 cutplace = lpszPath + 1;
405 if (lpszPath[1] == '\\') cutplace++;
406 lpszPath++;
407 }
408 lpszPath = CharNextA(lpszPath);
409 if (!lpszPath) break;
410 }
411
412 ret = (*cutplace!='\0');
413 *cutplace = '\0';
414 }
415 return ret;
416}
417
418/*************************************************************************
419 * PathRemoveFileSpecW [SHLWAPI.@]
420 */
421BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
422{
423 LPWSTR cutplace = lpszPath;
424 BOOL ret = FALSE;
425
426 TRACE("%s\n",debugstr_w(lpszPath));
427
428 if(lpszPath)
429 {
430 while (*lpszPath == '\\') cutplace = ++lpszPath;
431
432 while (*lpszPath)
433 {
434 if(lpszPath[0] == '\\') cutplace = lpszPath;
435
436 if(lpszPath[0] == ':')
437 {
438 cutplace = lpszPath + 1;
439 if (lpszPath[1] == '\\') cutplace++;
440 lpszPath++;
441 }
442 lpszPath = CharNextW(lpszPath);
443 if (!lpszPath) break;
444 }
445
446 ret = (*cutplace!='\0');
447 *cutplace = '\0';
448 }
449 return ret;
450}
451
452/*************************************************************************
453 * PathStripPathA [SHELLWAPI.@]
454 *
455 * NOTES
456 * removes the path from the beginning of a filename
457 */
458void WINAPI PathStripPathA(LPSTR lpszPath)
459{
460 LPSTR lpszFileName = PathFindFileNameA(lpszPath);
461
462 TRACE("%s\n", lpszPath);
463
464 if(lpszFileName)
465 RtlMoveMemory(lpszPath, lpszFileName, strlen(lpszFileName)+1);
466}
467
468/*************************************************************************
469 * PathStripPathW [SHELLWAPI.@]
470 */
471void WINAPI PathStripPathW(LPWSTR lpszPath)
472{
473 LPWSTR lpszFileName = PathFindFileNameW(lpszPath);
474
475 TRACE("%s\n", debugstr_w(lpszPath));
476 if(lpszFileName)
477 RtlMoveMemory(lpszPath, lpszFileName, (strlenW(lpszFileName)+1)*sizeof(WCHAR));
478}
479
480/*************************************************************************
481 * PathStripToRootA [SHLWAPI.@]
482 */
483BOOL WINAPI PathStripToRootA(LPSTR lpszPath)
484{
485 TRACE("%s\n", lpszPath);
486
487 if (!lpszPath) return FALSE;
488 while(!PathIsRootA(lpszPath))
489 if (!PathRemoveFileSpecA(lpszPath)) return FALSE;
490 return TRUE;
491}
492
493/*************************************************************************
494 * PathStripToRootW [SHLWAPI.@]
495 */
496BOOL WINAPI PathStripToRootW(LPWSTR lpszPath)
497{
498 TRACE("%s\n", debugstr_w(lpszPath));
499
500 if (!lpszPath) return FALSE;
501 while(!PathIsRootW(lpszPath))
502 if (!PathRemoveFileSpecW(lpszPath)) return FALSE;
503 return TRUE;
504}
505
506/*************************************************************************
507 * PathRemoveArgsA [SHLWAPI.@]
508 *
509 */
510void WINAPI PathRemoveArgsA(LPSTR lpszPath)
511{
512 TRACE("%s\n",lpszPath);
513
514 if(lpszPath)
515 {
516 LPSTR lpszArgs = PathGetArgsA(lpszPath);
517 if (!*lpszArgs)
518 {
519 LPSTR lpszLastChar = CharPrevA(lpszPath, lpszArgs);
520 if(*lpszLastChar==' ') *lpszLastChar = '\0';
521 }
522 }
523}
524
525/*************************************************************************
526 * PathRemoveArgsW [SHLWAPI.@]
527 */
528void WINAPI PathRemoveArgsW(LPWSTR lpszPath)
529{
530 TRACE("%s\n", debugstr_w(lpszPath));
531
532 if(lpszPath)
533 {
534 LPWSTR lpszArgs = PathGetArgsW(lpszPath);
535 if (!*lpszArgs)
536 {
537 LPWSTR lpszLastChar = CharPrevW(lpszPath, lpszArgs);
538 if(*lpszLastChar==' ') *lpszLastChar = '\0';
539 }
540 }
541}
542
543/*************************************************************************
544 * PathRemoveExtensionA [SHLWAPI.@]
545 */
546void WINAPI PathRemoveExtensionA(LPSTR lpszPath)
547{
548 LPSTR lpszExtension = PathFindExtensionA(lpszPath);
549
550 TRACE("%s\n", lpszPath);
551
552 if (lpszExtension) *lpszExtension='\0';
553}
554
555/*************************************************************************
556 * PathRemoveExtensionW [SHLWAPI.@]
557 */
558void WINAPI PathRemoveExtensionW(LPWSTR lpszPath)
559{
560 LPWSTR lpszExtension = PathFindExtensionW(lpszPath);
561
562 TRACE("%s\n", debugstr_w(lpszPath));
563
564 if (lpszExtension) *lpszExtension='\0';
565}
566
567/*************************************************************************
568 * PathRemoveBackslashA [SHLWAPI.@]
569 *
570 * If the path ends in a backslash it is replaced by a NULL
571 * and the address of the NULL is returned
572 * Otherwise
573 * the address of the last character is returned.
574 *
575 * FIXME
576 * "c:\": keep backslash
577 */
578LPSTR WINAPI PathRemoveBackslashA( LPSTR lpszPath )
579{
580 int len;
581 LPSTR szTemp = NULL;
582
583 if(lpszPath)
584 {
585 len = strlen(lpszPath);
586 szTemp = CharPrevA(lpszPath, lpszPath+len);
587 if (! PathIsRootA(lpszPath))
588 {
589 if (*szTemp == '\\') *szTemp = '\0';
590 }
591 }
592 return szTemp;
593}
594
595/*************************************************************************
596 * PathRemoveBackslashW [SHLWAPI.@]
597 */
598LPWSTR WINAPI PathRemoveBackslashW( LPWSTR lpszPath )
599{
600 int len;
601 LPWSTR szTemp = NULL;
602
603 if(lpszPath)
604 {
605 len = strlenW(lpszPath);
606 szTemp = CharPrevW(lpszPath, lpszPath+len);
607 if (! PathIsRootW(lpszPath))
608 {
609 if (*szTemp == '\\') *szTemp = '\0';
610 }
611 }
612 return szTemp;
613}
614
615
616/*
617 Path Manipulations
618*/
619
620/*************************************************************************
621 * PathRemoveBlanksA [SHLWAPI.@]
622 *
623 * NOTES
624 * remove spaces from beginning and end of passed string
625 */
626void WINAPI PathRemoveBlanksA(LPSTR str)
627{
628 LPSTR x = str;
629
630 TRACE("%s\n",str);
631
632 if(str)
633 {
634 while (*x==' ') x = CharNextA(x);
635 if (x!=str) strcpy(str,x);
636 x=str+strlen(str)-1;
637 while (*x==' ') x = CharPrevA(str, x);
638 if (*x==' ') *x='\0';
639 }
640}
641
642/*************************************************************************
643 * PathRemoveBlanksW [SHLWAPI.@]
644 */
645void WINAPI PathRemoveBlanksW(LPWSTR str)
646{
647 LPWSTR x = str;
648
649 TRACE("%s\n",debugstr_w(str));
650
651 if(str)
652 {
653 while (*x==' ') x = CharNextW(x);
654 if (x!=str) strcpyW(str,x);
655 x=str+strlenW(str)-1;
656 while (*x==' ') x = CharPrevW(str, x);
657 if (*x==' ') *x='\0';
658 }
659}
660
661/*************************************************************************
662 * PathQuoteSpacesA [SHLWAPI.@]
663 *
664 */
665LPSTR WINAPI PathQuoteSpacesA(LPSTR lpszPath)
666{
667 TRACE("%s\n",lpszPath);
668
669 if(StrChrA(lpszPath,' '))
670 {
671 int len = strlen(lpszPath);
672 RtlMoveMemory(lpszPath+1, lpszPath, len);
673 *(lpszPath++) = '"';
674 lpszPath += len;
675 *(lpszPath++) = '"';
676 *(lpszPath) = '\0';
677 return --lpszPath;
678 }
679 return 0;
680}
681
682/*************************************************************************
683 * PathQuoteSpacesW [SHLWAPI.@]
684 */
685LPWSTR WINAPI PathQuoteSpacesW(LPWSTR lpszPath)
686{
687 TRACE("%s\n",debugstr_w(lpszPath));
688
689 if(StrChrW(lpszPath,' '))
690 {
691 int len = strlenW(lpszPath);
692 RtlMoveMemory(lpszPath+1, lpszPath, len*sizeof(WCHAR));
693 *(lpszPath++) = '"';
694 lpszPath += len;
695 *(lpszPath++) = '"';
696 *(lpszPath) = '\0';
697 return --lpszPath;
698 }
699 return 0;
700}
701
702/*************************************************************************
703 * PathUnquoteSpacesA [SHLWAPI.@]
704 *
705 * NOTES
706 * unquote string (remove ")
707 */
708VOID WINAPI PathUnquoteSpacesA(LPSTR str)
709{
710 DWORD len = strlen(str);
711
712 TRACE("%s\n",str);
713
714 if (*str!='"')
715 return;
716 if (str[len-1]!='"')
717 return;
718 str[len-1]='\0';
719 strcpy(str,str+1);
720 return;
721}
722
723/*************************************************************************
724 * PathUnquoteSpacesW [SHLWAPI.@]
725 */
726VOID WINAPI PathUnquoteSpacesW(LPWSTR str)
727{
728 DWORD len = strlenW(str);
729
730 TRACE("%s\n",debugstr_w(str));
731
732 if (*str!='"')
733 return;
734 if (str[len-1]!='"')
735 return;
736 str[len-1]='\0';
737 strcpyW(str,str+1);
738 return;
739}
740
741/*************************************************************************
742 * PathParseIconLocationA [SHLWAPI.@]
743 */
744int WINAPI PathParseIconLocationA(LPSTR lpszPath)
745{
746 LPSTR lpstrComma = strchr(lpszPath, ',');
747
748 FIXME("%s stub\n", debugstr_a(lpszPath));
749
750 if (lpstrComma && lpstrComma[1])
751 {
752 lpstrComma[0]='\0';
753/* return atoi(&lpstrComma[1]); FIXME */
754 }
755
756 PathUnquoteSpacesA(lpszPath);
757 return 0;
758}
759
760/*************************************************************************
761 * PathParseIconLocationW [SHLWAPI.@]
762 */
763int WINAPI PathParseIconLocationW(LPWSTR lpszPath)
764{
765 LPWSTR lpstrComma = strchrW(lpszPath, ',');
766
767 FIXME("%s stub\n", debugstr_w(lpszPath));
768
769 if (lpstrComma && lpstrComma[1])
770 {
771 lpstrComma[0]='\0';
772/* return _wtoi(&lpstrComma[1]); FIXME */
773 }
774 PathUnquoteSpacesW(lpszPath);
775 return 0;
776}
777
778/*
779 ########## cleaning and resolving paths ##########
780 */
781
782/*************************************************************************
783 * PathFindOnPathA [SHLWAPI.@]
784 */
785BOOL WINAPI PathFindOnPathA(LPSTR sFile, LPCSTR sOtherDirs)
786{
787 FIXME("%s %s\n",sFile, sOtherDirs);
788 return FALSE;
789}
790
791/*************************************************************************
792 * PathFindOnPathW [SHLWAPI.@]
793 */
794BOOL WINAPI PathFindOnPathW(LPWSTR sFile, LPCWSTR sOtherDirs)
795{
796 FIXME("%s %s\n",debugstr_w(sFile), debugstr_w(sOtherDirs));
797 return FALSE;
798}
799
800/*************************************************************************
801 * PathCompactPathExA [SHLWAPI.@]
802 */
803BOOL WINAPI PathCompactPathExA(
804 LPSTR pszOut,
805 LPCSTR pszSrc,
806 UINT cchMax,
807 DWORD dwFlags)
808{
809 FIXME("%p %s 0x%08x 0x%08lx\n", pszOut, pszSrc, cchMax, dwFlags);
810 return FALSE;
811}
812
813/*************************************************************************
814 * PathCompactPathExW [SHLWAPI.@]
815 */
816BOOL WINAPI PathCompactPathExW(
817 LPWSTR pszOut,
818 LPCWSTR pszSrc,
819 UINT cchMax,
820 DWORD dwFlags)
821{
822 FIXME("%p %s 0x%08x 0x%08lx\n", pszOut, debugstr_w(pszSrc), cchMax, dwFlags);
823 return FALSE;
824}
825
826/*
827 ########## Path Testing ##########
828*/
829
830/*************************************************************************
831 * PathIsUNCA [SHLWAPI.@]
832 *
833 * NOTES
834 * PathIsUNC(char*path);
835 */
836BOOL WINAPI PathIsUNCA(LPCSTR lpszPath)
837{
838 TRACE("%s\n",lpszPath);
839
840 return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
841}
842
843/*************************************************************************
844 * PathIsUNCW [SHLWAPI.@]
845 */
846BOOL WINAPI PathIsUNCW(LPCWSTR lpszPath)
847{
848 TRACE("%s\n",debugstr_w(lpszPath));
849
850 return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
851}
852
853/*************************************************************************
854 * PathIsRelativeA [SHLWAPI.@]
855 */
856BOOL WINAPI PathIsRelativeA (LPCSTR lpszPath)
857{
858 TRACE("lpszPath=%s\n",lpszPath);
859
860 return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
861}
862
863/*************************************************************************
864 * PathIsRelativeW [SHLWAPI.@]
865 */
866BOOL WINAPI PathIsRelativeW (LPCWSTR lpszPath)
867{
868 TRACE("lpszPath=%s\n",debugstr_w(lpszPath));
869
870 return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
871}
872
873/*************************************************************************
874 * PathIsRootA [SHLWAPI.@]
875 *
876 * notes
877 * TRUE if the path points to a root directory
878 */
879BOOL WINAPI PathIsRootA(LPCSTR lpszPath)
880{
881 TRACE("%s\n",lpszPath);
882
883 /* X:\ */
884 if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
885 return TRUE;
886
887 /* "\" */
888 if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
889 return TRUE;
890
891 /* UNC "\\<computer>\<share>" */
892 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
893 {
894 int foundbackslash = 0;
895 lpszPath += 2;
896 while (*lpszPath)
897 {
898 if (*lpszPath=='\\') foundbackslash++;
899 lpszPath = CharNextA(lpszPath);
900 }
901 if (foundbackslash <= 1)
902 return TRUE;
903 }
904 return FALSE;
905}
906
907/*************************************************************************
908 * PathIsRootW [SHLWAPI.@]
909 */
910BOOL WINAPI PathIsRootW(LPCWSTR lpszPath)
911{
912 TRACE("%s\n",debugstr_w(lpszPath));
913
914 /* X:\ */
915 if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
916 return TRUE;
917
918 /* "\" */
919 if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
920 return TRUE;
921
922 /* UNC "\\<computer>\<share>" */
923 if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
924 {
925 int foundbackslash = 0;
926 lpszPath += 2;
927 while (*lpszPath)
928 {
929 if (*lpszPath=='\\') foundbackslash++;
930 lpszPath = CharNextW(lpszPath);
931 }
932 if (foundbackslash <= 1)
933 return TRUE;
934 }
935 return FALSE;
936
937}
938
939/*************************************************************************
940 * PathIsDirectoryA [SHLWAPI.@]
941 */
942BOOL WINAPI PathIsDirectoryA(LPCSTR lpszPath)
943{
944 DWORD dwAttr;
945
946 TRACE("%s\n", debugstr_a(lpszPath));
947
948 dwAttr = GetFileAttributesA(lpszPath);
949 return (dwAttr != -1) ? dwAttr & FILE_ATTRIBUTE_DIRECTORY : 0;
950}
951
952/*************************************************************************
953 * PathIsDirectoryW [SHLWAPI.@]
954 */
955BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
956{
957 DWORD dwAttr;
958
959 TRACE("%s\n", debugstr_w(lpszPath));
960
961 dwAttr = GetFileAttributesW(lpszPath);
962 return (dwAttr != -1) ? dwAttr & FILE_ATTRIBUTE_DIRECTORY : 0;
963}
964
965/*************************************************************************
966 * PathFileExistsA [SHLWAPI.@]
967 *
968 * NOTES
969 * file_exists(char *fn);
970 */
971BOOL WINAPI PathFileExistsA(LPCSTR lpszPath)
972{
973 TRACE("%s\n",lpszPath);
974 return (GetFileAttributesA(lpszPath)!=-1);
975}
976
977/*************************************************************************
978 * PathFileExistsW [SHLWAPI.@]
979 */
980BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
981{
982 TRACE("%s\n",debugstr_w(lpszPath));
983 return (GetFileAttributesW(lpszPath)!=-1);
984}
985
986/*************************************************************************
987 * PathMatchSingleMaskA [internal]
988 *
989 * NOTES
990 * internal (used by PathMatchSpec)
991 */
992static BOOL PathMatchSingleMaskA(LPCSTR name, LPCSTR mask)
993{
994 while (*name && *mask && *mask!=';')
995 {
996 if (*mask=='*')
997 {
998 do
999 {
1000 if (PathMatchSingleMaskA(name,mask+1)) return 1; /* try substrings */
1001 } while (*name++);
1002 return 0;
1003 }
1004 if (toupper(*mask)!=toupper(*name) && *mask!='?') return 0;
1005 name = CharNextA(name);
1006 mask = CharNextA(mask);
1007 }
1008 if (!*name)
1009 {
1010 while (*mask=='*') mask++;
1011 if (!*mask || *mask==';') return 1;
1012 }
1013 return 0;
1014}
1015
1016/*************************************************************************
1017 * PathMatchSingleMaskW [internal]
1018 */
1019static BOOL PathMatchSingleMaskW(LPCWSTR name, LPCWSTR mask)
1020{
1021 while (*name && *mask && *mask!=';')
1022 {
1023 if (*mask=='*')
1024 {
1025 do
1026 {
1027 if (PathMatchSingleMaskW(name,mask+1)) return 1; /* try substrings */
1028 } while (*name++);
1029 return 0;
1030 }
1031 if (toupperW(*mask)!=toupperW(*name) && *mask!='?') return 0;
1032 name = CharNextW(name);
1033 mask = CharNextW(mask);
1034 }
1035 if (!*name)
1036 {
1037 while (*mask=='*') mask++;
1038 if (!*mask || *mask==';') return 1;
1039 }
1040 return 0;
1041}
1042/*************************************************************************
1043 * PathMatchSpecA [SHLWAPI.@]
1044 *
1045 * NOTES
1046 * used from COMDLG32
1047 */
1048BOOL WINAPI PathMatchSpecA(LPCSTR name, LPCSTR mask)
1049{
1050 TRACE("%s %s\n",name,mask);
1051
1052 if (!lstrcmpA( mask, "*.*" )) return 1; /* we don't require a period */
1053
1054 while (*mask)
1055 {
1056 if (PathMatchSingleMaskA(name,mask)) return 1; /* helper function */
1057 while (*mask && *mask!=';') mask = CharNextA(mask);
1058 if (*mask==';')
1059 {
1060 mask++;
1061 while (*mask==' ') mask++; /* masks may be separated by "; " */
1062 }
1063 }
1064 return 0;
1065}
1066
1067/*************************************************************************
1068 * PathMatchSpecW [SHLWAPI.@]
1069 */
1070BOOL WINAPI PathMatchSpecW(LPCWSTR name, LPCWSTR mask)
1071{
1072 WCHAR stemp[4];
1073 TRACE("%s %s\n",debugstr_w(name),debugstr_w(mask));
1074
1075 lstrcpyAtoW(stemp,"*.*");
1076 if (!lstrcmpW( mask, stemp )) return 1; /* we don't require a period */
1077
1078 while (*mask)
1079 {
1080 if (PathMatchSingleMaskW(name,mask)) return 1; /* helper function */
1081 while (*mask && *mask!=';') mask = CharNextW(mask);
1082 if (*mask==';')
1083 {
1084 mask++;
1085 while (*mask==' ') mask++; /* masks may be separated by "; " */
1086 }
1087 }
1088 return 0;
1089}
1090
1091/*************************************************************************
1092 * PathIsSameRootA [SHLWAPI.@]
1093 *
1094 * FIXME
1095 * what to do with "\path" ??
1096 */
1097BOOL WINAPI PathIsSameRootA(LPCSTR lpszPath1, LPCSTR lpszPath2)
1098{
1099 TRACE("%s %s\n", lpszPath1, lpszPath2);
1100
1101 if (PathIsRelativeA(lpszPath1) || PathIsRelativeA(lpszPath2)) return FALSE;
1102
1103 /* usual path */
1104 if ( toupper(lpszPath1[0])==toupper(lpszPath2[0]) &&
1105 lpszPath1[1]==':' && lpszPath2[1]==':' &&
1106 lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
1107 return TRUE;
1108
1109 /* UNC */
1110 if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
1111 lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
1112 {
1113 int pos=2, bsfound=0;
1114 while (lpszPath1[pos] && lpszPath2[pos] &&
1115 (lpszPath1[pos] == lpszPath2[pos]))
1116 {
1117 if (lpszPath1[pos]=='\\') bsfound++;
1118 if (bsfound == 2) return TRUE;
1119 pos++; /* fixme: use CharNext*/
1120 }
1121 return (lpszPath1[pos] == lpszPath2[pos]);
1122 }
1123 return FALSE;
1124}
1125
1126/*************************************************************************
1127 * PathIsSameRootW [SHLWAPI.@]
1128 */
1129BOOL WINAPI PathIsSameRootW(LPCWSTR lpszPath1, LPCWSTR lpszPath2)
1130{
1131 TRACE("%s %s\n", debugstr_w(lpszPath1), debugstr_w(lpszPath2));
1132
1133 if (PathIsRelativeW(lpszPath1) || PathIsRelativeW(lpszPath2)) return FALSE;
1134
1135 /* usual path */
1136 if ( toupperW(lpszPath1[0])==toupperW(lpszPath2[0]) &&
1137 lpszPath1[1]==':' && lpszPath2[1]==':' &&
1138 lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
1139 return TRUE;
1140
1141 /* UNC */
1142 if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
1143 lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
1144 {
1145 int pos=2, bsfound=0;
1146 while (lpszPath1[pos] && lpszPath2[pos] &&
1147 (lpszPath1[pos] == lpszPath2[pos]))
1148 {
1149 if (lpszPath1[pos]=='\\') bsfound++;
1150 if (bsfound == 2) return TRUE;
1151 pos++;/* fixme: use CharNext*/
1152 }
1153 return (lpszPath1[pos] == lpszPath2[pos]);
1154 }
1155 return FALSE;
1156}
1157
1158/*************************************************************************
1159 * PathIsURLA
1160 */
1161BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
1162{
1163 LPSTR lpstrRes;
1164 int iSize, i=0;
1165 static LPSTR SupportedProtocol[] =
1166 {"http","https","ftp","gopher","file","mailto",NULL};
1167
1168 if(!lpstrPath) return FALSE;
1169
1170 /* get protocol */
1171 lpstrRes = strchr(lpstrPath,':');
1172 if(!lpstrRes) return FALSE;
1173 iSize = lpstrRes - lpstrPath;
1174
1175 while(SupportedProtocol[i])
1176 {
1177 if (iSize == strlen(SupportedProtocol[i]))
1178 if(!strncasecmp(lpstrPath, SupportedProtocol[i], iSize))
1179 return TRUE;
1180 i++;
1181 }
1182
1183 return FALSE;
1184}
1185
1186/*************************************************************************
1187 * PathIsURLW
1188 */
1189BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
1190{
1191 LPWSTR lpstrRes;
1192 int iSize, i=0;
1193 static WCHAR SupportedProtocol[7][7] =
1194 {{'h','t','t','p','\0'},{'h','t','t','p','s','\0'},{'f','t','p','\0'},
1195 {'g','o','p','h','e','r','\0'},{'f','i','l','e','\0'},
1196 {'m','a','i','l','t','o','\0'},{0}};
1197
1198 if(!lpstrPath) return FALSE;
1199
1200 /* get protocol */
1201 lpstrRes = strchrW(lpstrPath,':');
1202 if(!lpstrRes) return FALSE;
1203 iSize = lpstrRes - lpstrPath;
1204
1205 while(SupportedProtocol[i])
1206 {
1207 if (iSize == strlenW(SupportedProtocol[i]))
1208 if(!strncmpiW(lpstrPath, SupportedProtocol[i], iSize))
1209 return TRUE;
1210 i++;
1211 }
1212
1213 return FALSE;
1214}
1215
1216
1217/*************************************************************************
1218 * PathIsContentTypeA [SHLWAPI.@]
1219 */
1220BOOL WINAPI PathIsContentTypeA(LPCSTR pszPath, LPCSTR pszContentType)
1221{
1222 FIXME("%s %s\n", pszPath, pszContentType);
1223 return FALSE;
1224}
1225
1226/*************************************************************************
1227 * PathIsContentTypeW [SHLWAPI.@]
1228 */
1229BOOL WINAPI PathIsContentTypeW(LPCWSTR pszPath, LPCWSTR pszContentType)
1230{
1231 FIXME("%s %s\n", debugstr_w(pszPath), debugstr_w(pszContentType));
1232 return FALSE;
1233}
1234
1235/*************************************************************************
1236 * PathIsFileSpecA [SHLWAPI.@]
1237 */
1238BOOL WINAPI PathIsFileSpecA(LPCSTR pszPath)
1239{
1240 FIXME("%s\n", pszPath);
1241 return FALSE;
1242}
1243
1244/*************************************************************************
1245 * PathIsFileSpecW [SHLWAPI.@]
1246 */
1247BOOL WINAPI PathIsFileSpecW(LPCWSTR pszPath)
1248{
1249 FIXME("%s\n", debugstr_w(pszPath));
1250 return FALSE;
1251}
1252
1253/*************************************************************************
1254 * PathIsPrefixA [SHLWAPI.@]
1255 */
1256BOOL WINAPI PathIsPrefixA(LPCSTR pszPrefix, LPCSTR pszPath)
1257{
1258 FIXME("%s %s\n", pszPrefix, pszPath);
1259 return FALSE;
1260}
1261
1262/*************************************************************************
1263 * PathIsPrefixW [SHLWAPI.@]
1264 */
1265BOOL WINAPI PathIsPrefixW(LPCWSTR pszPrefix, LPCWSTR pszPath)
1266{
1267 FIXME("%s %s\n", debugstr_w(pszPrefix), debugstr_w(pszPath));
1268 return FALSE;
1269}
1270
1271/*************************************************************************
1272 * PathIsSystemFolderA [SHLWAPI.@]
1273 */
1274BOOL WINAPI PathIsSystemFolderA(LPCSTR pszPath, DWORD dwAttrb)
1275{
1276 FIXME("%s 0x%08lx\n", pszPath, dwAttrb);
1277 return FALSE;
1278}
1279
1280/*************************************************************************
1281 * PathIsSystemFolderW [SHLWAPI.@]
1282 */
1283BOOL WINAPI PathIsSystemFolderW(LPCWSTR pszPath, DWORD dwAttrb)
1284{
1285 FIXME("%s 0x%08lx\n", debugstr_w(pszPath), dwAttrb);
1286 return FALSE;
1287}
1288
1289/*************************************************************************
1290 * PathIsUNCServerA [SHLWAPI.@]
1291 */
1292BOOL WINAPI PathIsUNCServerA(
1293 LPCSTR pszPath)
1294{
1295 FIXME("%s\n", pszPath);
1296 return FALSE;
1297}
1298
1299/*************************************************************************
1300 * PathIsUNCServerW [SHLWAPI.@]
1301 */
1302BOOL WINAPI PathIsUNCServerW(
1303 LPCWSTR pszPath)
1304{
1305 FIXME("%s\n", debugstr_w(pszPath));
1306 return FALSE;
1307}
1308
1309/*************************************************************************
1310 * PathIsUNCServerShareA [SHLWAPI.@]
1311 */
1312BOOL WINAPI PathIsUNCServerShareA(
1313 LPCSTR pszPath)
1314{
1315 FIXME("%s\n", pszPath);
1316 return FALSE;
1317}
1318
1319/*************************************************************************
1320 * PathIsUNCServerShareW [SHLWAPI.@]
1321 */
1322BOOL WINAPI PathIsUNCServerShareW(
1323 LPCWSTR pszPath)
1324{
1325 FIXME("%s\n", debugstr_w(pszPath));
1326 return FALSE;
1327}
1328
1329/*************************************************************************
1330 * PathCanonicalizeA [SHLWAPI.@]
1331 *
1332 * FIXME
1333 * returnvalue, use CharNext
1334 */
1335
1336BOOL WINAPI PathCanonicalizeA(LPSTR pszBuf, LPCSTR pszPath)
1337{
1338 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = strlen(pszPath);
1339 BOOL bModifyed = FALSE;
1340
1341 TRACE("%p %s\n", pszBuf, pszPath);
1342
1343 pszBuf[OffsetDst]='\0';
1344
1345 /* keep the root of the path */
1346 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
1347 {
1348 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1349 }
1350 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
1351 {
1352 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1353 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1354 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
1355 {
1356 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1357 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
1358 {
1359 /* C:\. */
1360 OffsetSrc++; LenSrc--; bModifyed = TRUE;
1361 }
1362 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
1363 {
1364 /* C:\.. */
1365 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1366 }
1367 }
1368 }
1369
1370 /* ".\" at the beginning of the path */
1371 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
1372 {
1373 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1374 }
1375
1376 while ( LenSrc )
1377 {
1378 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
1379 {
1380 /* "\.." found, go one deeper */
1381 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
1382 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
1383 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
1384 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
1385 }
1386 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
1387 {
1388 /* "\." found, skip it */
1389 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
1390 }
1391 else
1392 {
1393 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
1394 }
1395 }
1396 pszBuf[OffsetDst] = '\0';
1397 TRACE("-- %s %u\n", pszBuf, bModifyed);
1398 return bModifyed;
1399}
1400
1401
1402/*************************************************************************
1403 * PathCanonicalizeW [SHLWAPI.@]
1404 *
1405 * FIXME
1406 * returnvalue, use CharNext
1407 */
1408BOOL WINAPI PathCanonicalizeW(LPWSTR pszBuf, LPCWSTR pszPath)
1409{
1410 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = strlenW(pszPath);
1411 BOOL bModifyed = FALSE;
1412
1413 TRACE("%p %s\n", pszBuf, debugstr_w(pszPath));
1414
1415 pszBuf[OffsetDst]='\0';
1416
1417 /* keep the root of the path */
1418 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
1419 {
1420 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1421 }
1422 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
1423 {
1424 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1425 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1426 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
1427 {
1428 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1429 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
1430 {
1431 /* C:\. */
1432 OffsetSrc++; LenSrc--; bModifyed = TRUE;
1433 }
1434 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
1435 {
1436 /* C:\.. */
1437 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1438 }
1439 }
1440 }
1441
1442 /* ".\" at the beginning of the path */
1443 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
1444 {
1445 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1446 }
1447
1448 while ( LenSrc )
1449 {
1450 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
1451 {
1452 /* "\.." found, go one deeper */
1453 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
1454 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
1455 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
1456 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
1457 }
1458 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
1459 {
1460 /* "\." found, skip it */
1461 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
1462 }
1463 else
1464 {
1465 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
1466 }
1467 }
1468 pszBuf[OffsetDst] = '\0';
1469 TRACE("-- %s %u\n", debugstr_w(pszBuf), bModifyed);
1470 return bModifyed;
1471}
1472
1473/*************************************************************************
1474 * PathFindNextComponentA [SHLWAPI.@]
1475 *
1476 * NOTES
1477 * special cases:
1478 * "" null
1479 * aa "" (pointer to traling NULL)
1480 * aa\ "" (pointer to traling NULL)
1481 * aa\\ "" (pointer to traling NULL)
1482 * aa\\bb bb
1483 * aa\\\bb \bb
1484 * c:\aa\ "aa\"
1485 * \\aa aa
1486 * \\aa\b aa\b
1487*/
1488LPSTR WINAPI PathFindNextComponentA(LPCSTR pszPath)
1489{
1490 LPSTR pos;
1491
1492 TRACE("%s\n", pszPath);
1493
1494 if(!pszPath || !*pszPath) return NULL;
1495 if(!(pos = StrChrA(pszPath, '\\')))
1496 return (LPSTR) pszPath + strlen(pszPath);
1497 pos++;
1498 if(pos[0] == '\\') pos++;
1499 return pos;
1500}
1501
1502/*************************************************************************
1503 * PathFindNextComponentW [SHLWAPI.@]
1504 */
1505LPWSTR WINAPI PathFindNextComponentW(LPCWSTR pszPath)
1506{
1507 LPWSTR pos;
1508
1509 TRACE("%s\n", debugstr_w(pszPath));
1510
1511 if(!pszPath || !*pszPath) return NULL;
1512 if (!(pos = StrChrW(pszPath, '\\')))
1513 return (LPWSTR) pszPath + strlenW(pszPath);
1514 pos++;
1515 if(pos[0] == '\\') pos++;
1516 return pos;
1517}
1518
1519/*************************************************************************
1520 * PathAddExtensionA [SHLWAPI.@]
1521 *
1522 * NOTES
1523 * it adds never a dot
1524 */
1525
1526BOOL WINAPI PathAddExtensionA(
1527 LPSTR pszPath,
1528 LPCSTR pszExtension)
1529{
1530 if (*pszPath)
1531 {
1532 if (*(PathFindExtensionA(pszPath))) return FALSE;
1533
1534 if (!pszExtension || *pszExtension=='\0')
1535 strcat(pszPath, "exe");
1536 else
1537 strcat(pszPath, pszExtension);
1538 }
1539
1540 return TRUE;
1541}
1542
1543/*************************************************************************
1544 * PathAddExtensionW [SHLWAPI.@]
1545 */
1546BOOL WINAPI PathAddExtensionW(
1547 LPWSTR pszPath,
1548 LPCWSTR pszExtension)
1549{
1550 static const WCHAR ext[] = { 'e','x','e',0 };
1551
1552 if (*pszPath)
1553 {
1554 if (*(PathFindExtensionW(pszPath))) return FALSE;
1555
1556 if (!pszExtension || *pszExtension=='\0')
1557 strcatW(pszPath, ext);
1558 else
1559 strcatW(pszPath, pszExtension);
1560 }
1561 return TRUE;
1562
1563}
1564
1565/*************************************************************************
1566 * PathMakePrettyA [SHLWAPI.@]
1567 */
1568BOOL WINAPI PathMakePrettyA(
1569 LPSTR lpPath)
1570{
1571 FIXME("%s\n", lpPath);
1572 return TRUE;
1573}
1574
1575/*************************************************************************
1576 * PathMakePrettyW [SHLWAPI.@]
1577 */
1578BOOL WINAPI PathMakePrettyW(
1579 LPWSTR lpPath)
1580{
1581 FIXME("%s\n", debugstr_w(lpPath));
1582 return TRUE;
1583
1584}
1585
1586/*************************************************************************
1587 * PathCommonPrefixA [SHLWAPI.@]
1588 */
1589int WINAPI PathCommonPrefixA(
1590 LPCSTR pszFile1,
1591 LPCSTR pszFile2,
1592 LPSTR achPath)
1593{
1594 FIXME("%s %s %p\n", pszFile1, pszFile2, achPath);
1595 return 0;
1596}
1597
1598/*************************************************************************
1599 * PathCommonPrefixW [SHLWAPI.@]
1600 */
1601int WINAPI PathCommonPrefixW(
1602 LPCWSTR pszFile1,
1603 LPCWSTR pszFile2,
1604 LPWSTR achPath)
1605{
1606 FIXME("%s %s %p\n", debugstr_w(pszFile1), debugstr_w(pszFile2),achPath );
1607 return 0;
1608}
1609
1610/*************************************************************************
1611 * PathCompactPathA [SHLWAPI.@]
1612 */
1613BOOL WINAPI PathCompactPathA(HDC hDC, LPSTR pszPath, UINT dx)
1614{
1615 FIXME("0x%08x %s 0x%08x\n", hDC, pszPath, dx);
1616 return FALSE;
1617}
1618
1619/*************************************************************************
1620 * PathCompactPathW [SHLWAPI.@]
1621 */
1622BOOL WINAPI PathCompactPathW(HDC hDC, LPWSTR pszPath, UINT dx)
1623{
1624 FIXME("0x%08x %s 0x%08x\n", hDC, debugstr_w(pszPath), dx);
1625 return FALSE;
1626}
1627
1628/*************************************************************************
1629 * PathGetCharTypeA [SHLWAPI.@]
1630 */
1631UINT WINAPI PathGetCharTypeA(UCHAR ch)
1632{
1633 FIXME("%c\n", ch);
1634 return 0;
1635}
1636
1637/*************************************************************************
1638 * PathGetCharTypeW [SHLWAPI.@]
1639 */
1640UINT WINAPI PathGetCharTypeW(WCHAR ch)
1641{
1642 FIXME("%c\n", ch);
1643 return 0;
1644}
1645
1646/*************************************************************************
1647 * PathMakeSystemFolderA [SHLWAPI.@]
1648 */
1649BOOL WINAPI PathMakeSystemFolderA(LPCSTR pszPath)
1650{
1651 FIXME("%s\n", pszPath);
1652 return FALSE;
1653}
1654
1655/*************************************************************************
1656 * PathMakeSystemFolderW [SHLWAPI.@]
1657 */
1658BOOL WINAPI PathMakeSystemFolderW(LPCWSTR pszPath)
1659{
1660 FIXME("%s\n", debugstr_w(pszPath));
1661 return FALSE;
1662}
1663
1664/*************************************************************************
1665 * PathRenameExtensionA [SHLWAPI.@]
1666 */
1667BOOL WINAPI PathRenameExtensionA(LPSTR pszPath, LPCSTR pszExt)
1668{
1669 FIXME("%s %s\n", pszPath, pszExt);
1670 return FALSE;
1671}
1672
1673/*************************************************************************
1674 * PathRenameExtensionW [SHLWAPI.@]
1675 */
1676BOOL WINAPI PathRenameExtensionW(LPWSTR pszPath, LPCWSTR pszExt)
1677{
1678 FIXME("%s %s\n", debugstr_w(pszPath), debugstr_w(pszExt));
1679 return FALSE;
1680}
1681
1682/*************************************************************************
1683 * PathSearchAndQualifyA [SHLWAPI.@]
1684 */
1685BOOL WINAPI PathSearchAndQualifyA(
1686 LPCSTR pszPath,
1687 LPSTR pszBuf,
1688 UINT cchBuf)
1689{
1690 FIXME("%s %s 0x%08x\n", pszPath, pszBuf, cchBuf);
1691 return FALSE;
1692}
1693
1694/*************************************************************************
1695 * PathSearchAndQualifyW [SHLWAPI.@]
1696 */
1697BOOL WINAPI PathSearchAndQualifyW(
1698 LPCWSTR pszPath,
1699 LPWSTR pszBuf,
1700 UINT cchBuf)
1701{
1702 FIXME("%s %s 0x%08x\n", debugstr_w(pszPath), debugstr_w(pszBuf), cchBuf);
1703 return FALSE;
1704}
1705
1706#ifndef __WIN32OS2__
1707/*************************************************************************
1708 * PathSkipRootA [SHLWAPI.@]
1709 */
1710LPSTR WINAPI PathSkipRootA(LPCSTR pszPath)
1711{
1712 FIXME("%s\n", pszPath);
1713 return (LPSTR)pszPath;
1714}
1715
1716/*************************************************************************
1717 * PathSkipRootW [SHLWAPI.@]
1718 */
1719LPWSTR WINAPI PathSkipRootW(LPCWSTR pszPath)
1720{
1721 FIXME("%s\n", debugstr_w(pszPath));
1722 return (LPWSTR)pszPath;
1723}
1724#endif
1725
1726/*************************************************************************
1727 * PathCreateFromUrlA [SHLWAPI.@]
1728 */
1729HRESULT WINAPI PathCreateFromUrlA(
1730 LPCSTR pszUrl,
1731 LPSTR pszPath,
1732 LPDWORD pcchPath,
1733 DWORD dwFlags)
1734{
1735 FIXME("%s %p %p 0x%08lx\n",
1736 pszUrl, pszPath, pcchPath, dwFlags);
1737 return S_OK;
1738}
1739
1740/*************************************************************************
1741 * PathCreateFromUrlW [SHLWAPI.@]
1742 */
1743HRESULT WINAPI PathCreateFromUrlW(
1744 LPCWSTR pszUrl,
1745 LPWSTR pszPath,
1746 LPDWORD pcchPath,
1747 DWORD dwFlags)
1748{
1749 FIXME("%s %p %p 0x%08lx\n",
1750 debugstr_w(pszUrl), pszPath, pcchPath, dwFlags);
1751 return S_OK;
1752}
1753
1754/*************************************************************************
1755 * PathRelativePathToA [SHLWAPI.@]
1756 */
1757BOOL WINAPI PathRelativePathToA(
1758 LPSTR pszPath,
1759 LPCSTR pszFrom,
1760 DWORD dwAttrFrom,
1761 LPCSTR pszTo,
1762 DWORD dwAttrTo)
1763{
1764 FIXME("%s %s 0x%08lx %s 0x%08lx\n",
1765 pszPath, pszFrom, dwAttrFrom, pszTo, dwAttrTo);
1766 return FALSE;
1767}
1768
1769/*************************************************************************
1770 * PathRelativePathToW [SHLWAPI.@]
1771 */
1772BOOL WINAPI PathRelativePathToW(
1773 LPWSTR pszPath,
1774 LPCWSTR pszFrom,
1775 DWORD dwAttrFrom,
1776 LPCWSTR pszTo,
1777 DWORD dwAttrTo)
1778{
1779 FIXME("%s %s 0x%08lx %s 0x%08lx\n",
1780 debugstr_w(pszPath), debugstr_w(pszFrom), dwAttrFrom, debugstr_w(pszTo), dwAttrTo);
1781 return FALSE;
1782}
1783
1784/*************************************************************************
1785 * PathUnmakeSystemFolderA [SHLWAPI.@]
1786 */
1787BOOL WINAPI PathUnmakeSystemFolderA(LPCSTR pszPath)
1788{
1789 FIXME("%s\n", pszPath);
1790 return FALSE;
1791}
1792
1793/*************************************************************************
1794 * PathUnmakeSystemFolderW [SHLWAPI.@]
1795 */
1796BOOL WINAPI PathUnmakeSystemFolderW(LPCWSTR pszPath)
1797{
1798 FIXME("%s\n", debugstr_w(pszPath));
1799 return FALSE;
1800}
1801
1802/*
1803 ########## special ##########
1804*/
1805
1806/*************************************************************************
1807 * PathSetDlgItemPathA [SHLWAPI.@]
1808 *
1809 * NOTES
1810 * use PathCompactPath to make sure, the path fits into the control
1811 */
1812BOOL WINAPI PathSetDlgItemPathA(HWND hDlg, int id, LPCSTR pszPath)
1813{ TRACE("%x %x %s\n",hDlg, id, pszPath);
1814 return SetDlgItemTextA(hDlg, id, pszPath);
1815}
1816
1817/*************************************************************************
1818 * PathSetDlgItemPathW [SHLWAPI.@]
1819 */
1820BOOL WINAPI PathSetDlgItemPathW(HWND hDlg, int id, LPCWSTR pszPath)
1821{ TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
1822 return SetDlgItemTextW(hDlg, id, pszPath);
1823}
Note: See TracBrowser for help on using the repository browser.