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

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

added/implemented functions

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