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

Last change on this file since 5618 was 5618, checked in by sandervl, 24 years ago

resync with latest wine

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