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

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

removed TRACE/WARN macro redefinition

File size: 42.4 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 // 2001-08-30 PH
1165 // SHLWAPI/W95 Code:
1166 //
1167 // if (lpstrPath == NULL)
1168 // return FALSE;
1169 //
1170 // DWORD dwUnknown = SHREG_xxx; // 0x18
1171 // return SHLWAPI_1(lpstrPath, &dwUnknown);
1172
1173
1174 LPSTR lpstrRes;
1175 int iSize, i=0;
1176 static LPSTR SupportedProtocol[] =
1177 {"http","https","ftp","gopher","file","mailto",NULL};
1178
1179 if(!lpstrPath) return FALSE;
1180
1181 /* get protocol */
1182 lpstrRes = strchr(lpstrPath,':');
1183 if(!lpstrRes) return FALSE;
1184 iSize = lpstrRes - lpstrPath;
1185
1186 while(SupportedProtocol[i])
1187 {
1188 if (iSize == strlen(SupportedProtocol[i]))
1189 if(!strncasecmp(lpstrPath, SupportedProtocol[i], iSize))
1190 return TRUE;
1191 i++;
1192 }
1193
1194 return FALSE;
1195}
1196
1197/*************************************************************************
1198 * PathIsURLW
1199 */
1200BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
1201{
1202 LPWSTR lpstrRes;
1203 int iSize, i=0;
1204 static WCHAR SupportedProtocol[7][7] =
1205 {{'h','t','t','p','\0'},{'h','t','t','p','s','\0'},{'f','t','p','\0'},
1206 {'g','o','p','h','e','r','\0'},{'f','i','l','e','\0'},
1207 {'m','a','i','l','t','o','\0'},{0}};
1208
1209 if(!lpstrPath) return FALSE;
1210
1211 /* get protocol */
1212 lpstrRes = strchrW(lpstrPath,':');
1213 if(!lpstrRes) return FALSE;
1214 iSize = lpstrRes - lpstrPath;
1215
1216 while(SupportedProtocol[i])
1217 {
1218 if (iSize == strlenW(SupportedProtocol[i]))
1219 if(!strncmpiW(lpstrPath, SupportedProtocol[i], iSize))
1220 return TRUE;
1221 i++;
1222 }
1223
1224 return FALSE;
1225}
1226
1227
1228/*************************************************************************
1229 * PathIsContentTypeA [SHLWAPI.@]
1230 */
1231BOOL WINAPI PathIsContentTypeA(LPCSTR pszPath, LPCSTR pszContentType)
1232{
1233 FIXME("%s %s\n", pszPath, pszContentType);
1234 return FALSE;
1235}
1236
1237/*************************************************************************
1238 * PathIsContentTypeW [SHLWAPI.@]
1239 */
1240BOOL WINAPI PathIsContentTypeW(LPCWSTR pszPath, LPCWSTR pszContentType)
1241{
1242 FIXME("%s %s\n", debugstr_w(pszPath), debugstr_w(pszContentType));
1243 return FALSE;
1244}
1245
1246/*************************************************************************
1247 * PathIsFileSpecA [SHLWAPI.@]
1248 */
1249BOOL WINAPI PathIsFileSpecA(LPCSTR pszPath)
1250{
1251 FIXME("%s\n", pszPath);
1252 return FALSE;
1253}
1254
1255/*************************************************************************
1256 * PathIsFileSpecW [SHLWAPI.@]
1257 */
1258BOOL WINAPI PathIsFileSpecW(LPCWSTR pszPath)
1259{
1260 FIXME("%s\n", debugstr_w(pszPath));
1261 return FALSE;
1262}
1263
1264/*************************************************************************
1265 * PathIsPrefixA [SHLWAPI.@]
1266 */
1267BOOL WINAPI PathIsPrefixA(LPCSTR pszPrefix, LPCSTR pszPath)
1268{
1269 FIXME("%s %s\n", pszPrefix, pszPath);
1270 return FALSE;
1271}
1272
1273/*************************************************************************
1274 * PathIsPrefixW [SHLWAPI.@]
1275 */
1276BOOL WINAPI PathIsPrefixW(LPCWSTR pszPrefix, LPCWSTR pszPath)
1277{
1278 FIXME("%s %s\n", debugstr_w(pszPrefix), debugstr_w(pszPath));
1279 return FALSE;
1280}
1281
1282/*************************************************************************
1283 * PathIsSystemFolderA [SHLWAPI.@]
1284 */
1285BOOL WINAPI PathIsSystemFolderA(LPCSTR pszPath, DWORD dwAttrb)
1286{
1287 FIXME("%s 0x%08lx\n", pszPath, dwAttrb);
1288 return FALSE;
1289}
1290
1291/*************************************************************************
1292 * PathIsSystemFolderW [SHLWAPI.@]
1293 */
1294BOOL WINAPI PathIsSystemFolderW(LPCWSTR pszPath, DWORD dwAttrb)
1295{
1296 FIXME("%s 0x%08lx\n", debugstr_w(pszPath), dwAttrb);
1297 return FALSE;
1298}
1299
1300/*************************************************************************
1301 * PathIsUNCServerA [SHLWAPI.@]
1302 */
1303BOOL WINAPI PathIsUNCServerA(
1304 LPCSTR pszPath)
1305{
1306 FIXME("%s\n", pszPath);
1307 return FALSE;
1308}
1309
1310/*************************************************************************
1311 * PathIsUNCServerW [SHLWAPI.@]
1312 */
1313BOOL WINAPI PathIsUNCServerW(
1314 LPCWSTR pszPath)
1315{
1316 FIXME("%s\n", debugstr_w(pszPath));
1317 return FALSE;
1318}
1319
1320/*************************************************************************
1321 * PathIsUNCServerShareA [SHLWAPI.@]
1322 */
1323BOOL WINAPI PathIsUNCServerShareA(
1324 LPCSTR pszPath)
1325{
1326 FIXME("%s\n", pszPath);
1327 return FALSE;
1328}
1329
1330/*************************************************************************
1331 * PathIsUNCServerShareW [SHLWAPI.@]
1332 */
1333BOOL WINAPI PathIsUNCServerShareW(
1334 LPCWSTR pszPath)
1335{
1336 FIXME("%s\n", debugstr_w(pszPath));
1337 return FALSE;
1338}
1339
1340/*************************************************************************
1341 * PathCanonicalizeA [SHLWAPI.@]
1342 *
1343 * FIXME
1344 * returnvalue, use CharNext
1345 */
1346
1347BOOL WINAPI PathCanonicalizeA(LPSTR pszBuf, LPCSTR pszPath)
1348{
1349 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = strlen(pszPath);
1350 BOOL bModifyed = FALSE;
1351
1352 TRACE("%p %s\n", pszBuf, pszPath);
1353
1354 pszBuf[OffsetDst]='\0';
1355
1356 /* keep the root of the path */
1357 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
1358 {
1359 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1360 }
1361 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
1362 {
1363 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1364 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1365 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
1366 {
1367 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1368 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
1369 {
1370 /* C:\. */
1371 OffsetSrc++; LenSrc--; bModifyed = TRUE;
1372 }
1373 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
1374 {
1375 /* C:\.. */
1376 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1377 }
1378 }
1379 }
1380
1381 /* ".\" at the beginning of the path */
1382 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
1383 {
1384 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1385 }
1386
1387 while ( LenSrc )
1388 {
1389 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
1390 {
1391 /* "\.." found, go one deeper */
1392 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
1393 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
1394 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
1395 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
1396 }
1397 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
1398 {
1399 /* "\." found, skip it */
1400 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
1401 }
1402 else
1403 {
1404 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
1405 }
1406 }
1407 pszBuf[OffsetDst] = '\0';
1408 TRACE("-- %s %u\n", pszBuf, bModifyed);
1409 return bModifyed;
1410}
1411
1412
1413/*************************************************************************
1414 * PathCanonicalizeW [SHLWAPI.@]
1415 *
1416 * FIXME
1417 * returnvalue, use CharNext
1418 */
1419BOOL WINAPI PathCanonicalizeW(LPWSTR pszBuf, LPCWSTR pszPath)
1420{
1421 int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = strlenW(pszPath);
1422 BOOL bModifyed = FALSE;
1423
1424 TRACE("%p %s\n", pszBuf, debugstr_w(pszPath));
1425
1426 pszBuf[OffsetDst]='\0';
1427
1428 /* keep the root of the path */
1429 if( LenSrc && (pszPath[OffsetSrc]=='\\'))
1430 {
1431 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1432 }
1433 else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
1434 {
1435 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1436 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1437 if (LenSrc && (pszPath[OffsetSrc] == '\\'))
1438 {
1439 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
1440 if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
1441 {
1442 /* C:\. */
1443 OffsetSrc++; LenSrc--; bModifyed = TRUE;
1444 }
1445 else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
1446 {
1447 /* C:\.. */
1448 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1449 }
1450 }
1451 }
1452
1453 /* ".\" at the beginning of the path */
1454 if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
1455 {
1456 OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
1457 }
1458
1459 while ( LenSrc )
1460 {
1461 if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
1462 {
1463 /* "\.." found, go one deeper */
1464 while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
1465 OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
1466 if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
1467 pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
1468 }
1469 else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
1470 {
1471 /* "\." found, skip it */
1472 OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
1473 }
1474 else
1475 {
1476 pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
1477 }
1478 }
1479 pszBuf[OffsetDst] = '\0';
1480 TRACE("-- %s %u\n", debugstr_w(pszBuf), bModifyed);
1481 return bModifyed;
1482}
1483
1484/*************************************************************************
1485 * PathFindNextComponentA [SHLWAPI.@]
1486 *
1487 * NOTES
1488 * special cases:
1489 * "" null
1490 * aa "" (pointer to traling NULL)
1491 * aa\ "" (pointer to traling NULL)
1492 * aa\\ "" (pointer to traling NULL)
1493 * aa\\bb bb
1494 * aa\\\bb \bb
1495 * c:\aa\ "aa\"
1496 * \\aa aa
1497 * \\aa\b aa\b
1498*/
1499LPSTR WINAPI PathFindNextComponentA(LPCSTR pszPath)
1500{
1501 LPSTR pos;
1502
1503 TRACE("%s\n", pszPath);
1504
1505 if(!pszPath || !*pszPath) return NULL;
1506 if(!(pos = StrChrA(pszPath, '\\')))
1507 return (LPSTR) pszPath + strlen(pszPath);
1508 pos++;
1509 if(pos[0] == '\\') pos++;
1510 return pos;
1511}
1512
1513/*************************************************************************
1514 * PathFindNextComponentW [SHLWAPI.@]
1515 */
1516LPWSTR WINAPI PathFindNextComponentW(LPCWSTR pszPath)
1517{
1518 LPWSTR pos;
1519
1520 TRACE("%s\n", debugstr_w(pszPath));
1521
1522 if(!pszPath || !*pszPath) return NULL;
1523 if (!(pos = StrChrW(pszPath, '\\')))
1524 return (LPWSTR) pszPath + strlenW(pszPath);
1525 pos++;
1526 if(pos[0] == '\\') pos++;
1527 return pos;
1528}
1529
1530/*************************************************************************
1531 * PathAddExtensionA [SHLWAPI.@]
1532 *
1533 * NOTES
1534 * it adds never a dot
1535 */
1536
1537BOOL WINAPI PathAddExtensionA(
1538 LPSTR pszPath,
1539 LPCSTR pszExtension)
1540{
1541 if (*pszPath)
1542 {
1543 if (*(PathFindExtensionA(pszPath))) return FALSE;
1544
1545 if (!pszExtension || *pszExtension=='\0')
1546 strcat(pszPath, "exe");
1547 else
1548 strcat(pszPath, pszExtension);
1549 }
1550
1551 return TRUE;
1552}
1553
1554/*************************************************************************
1555 * PathAddExtensionW [SHLWAPI.@]
1556 */
1557BOOL WINAPI PathAddExtensionW(
1558 LPWSTR pszPath,
1559 LPCWSTR pszExtension)
1560{
1561 static const WCHAR ext[] = { 'e','x','e',0 };
1562
1563 if (*pszPath)
1564 {
1565 if (*(PathFindExtensionW(pszPath))) return FALSE;
1566
1567 if (!pszExtension || *pszExtension=='\0')
1568 strcatW(pszPath, ext);
1569 else
1570 strcatW(pszPath, pszExtension);
1571 }
1572 return TRUE;
1573
1574}
1575
1576/*************************************************************************
1577 * PathMakePrettyA [SHLWAPI.@]
1578 */
1579BOOL WINAPI PathMakePrettyA(
1580 LPSTR lpPath)
1581{
1582 FIXME("%s\n", lpPath);
1583 return TRUE;
1584}
1585
1586/*************************************************************************
1587 * PathMakePrettyW [SHLWAPI.@]
1588 */
1589BOOL WINAPI PathMakePrettyW(
1590 LPWSTR lpPath)
1591{
1592 FIXME("%s\n", debugstr_w(lpPath));
1593 return TRUE;
1594
1595}
1596
1597/*************************************************************************
1598 * PathCommonPrefixA [SHLWAPI.@]
1599 */
1600int WINAPI PathCommonPrefixA(
1601 LPCSTR pszFile1,
1602 LPCSTR pszFile2,
1603 LPSTR achPath)
1604{
1605 FIXME("%s %s %p\n", pszFile1, pszFile2, achPath);
1606 return 0;
1607}
1608
1609/*************************************************************************
1610 * PathCommonPrefixW [SHLWAPI.@]
1611 */
1612int WINAPI PathCommonPrefixW(
1613 LPCWSTR pszFile1,
1614 LPCWSTR pszFile2,
1615 LPWSTR achPath)
1616{
1617 FIXME("%s %s %p\n", debugstr_w(pszFile1), debugstr_w(pszFile2),achPath );
1618 return 0;
1619}
1620
1621/*************************************************************************
1622 * PathCompactPathA [SHLWAPI.@]
1623 */
1624BOOL WINAPI PathCompactPathA(HDC hDC, LPSTR pszPath, UINT dx)
1625{
1626 FIXME("0x%08x %s 0x%08x\n", hDC, pszPath, dx);
1627 return FALSE;
1628}
1629
1630/*************************************************************************
1631 * PathCompactPathW [SHLWAPI.@]
1632 */
1633BOOL WINAPI PathCompactPathW(HDC hDC, LPWSTR pszPath, UINT dx)
1634{
1635 FIXME("0x%08x %s 0x%08x\n", hDC, debugstr_w(pszPath), dx);
1636 return FALSE;
1637}
1638
1639/*************************************************************************
1640 * PathGetCharTypeA [SHLWAPI.@]
1641 */
1642UINT WINAPI PathGetCharTypeA(UCHAR ch)
1643{
1644 UINT flags = 0;
1645
1646 TRACE("%c\n", ch);
1647
1648 /* We could use them in filenames, but this would confuse 'ls' */
1649 if (iscntrl(ch))
1650 return GCT_INVALID;
1651 if ((ch == '*') || (ch=='?'))
1652 return GCT_WILD;
1653 if ((ch == '\\') || (ch=='/'))
1654 return GCT_SEPARATOR;
1655 flags = 0;
1656 /* all normal characters, no lower case letters */
1657 if ((ch > ' ') && (ch < 0x7f) && !islower(ch))
1658 flags |= GCT_SHORTCHAR;
1659 /* All other characters are valid in long filenames, even umlauts */
1660 return flags | GCT_LFNCHAR;
1661}
1662
1663/*************************************************************************
1664 * PathGetCharTypeW [SHLWAPI.@]
1665 */
1666UINT WINAPI PathGetCharTypeW(WCHAR ch)
1667{
1668 FIXME("%c, using ascii version\n", ch);
1669 return PathGetCharTypeA(ch);
1670}
1671
1672/*************************************************************************
1673 * PathMakeSystemFolderA [SHLWAPI.@]
1674 */
1675BOOL WINAPI PathMakeSystemFolderA(LPCSTR pszPath)
1676{
1677 FIXME("%s\n", pszPath);
1678 return FALSE;
1679}
1680
1681/*************************************************************************
1682 * PathMakeSystemFolderW [SHLWAPI.@]
1683 */
1684BOOL WINAPI PathMakeSystemFolderW(LPCWSTR pszPath)
1685{
1686 FIXME("%s\n", debugstr_w(pszPath));
1687 return FALSE;
1688}
1689
1690/*************************************************************************
1691 * PathRenameExtensionA [SHLWAPI.@]
1692 */
1693BOOL WINAPI PathRenameExtensionA(LPSTR pszPath, LPCSTR pszExt)
1694{
1695 FIXME("%s %s\n", pszPath, pszExt);
1696 return FALSE;
1697}
1698
1699/*************************************************************************
1700 * PathRenameExtensionW [SHLWAPI.@]
1701 */
1702BOOL WINAPI PathRenameExtensionW(LPWSTR pszPath, LPCWSTR pszExt)
1703{
1704 FIXME("%s %s\n", debugstr_w(pszPath), debugstr_w(pszExt));
1705 return FALSE;
1706}
1707
1708/*************************************************************************
1709 * PathSearchAndQualifyA [SHLWAPI.@]
1710 */
1711BOOL WINAPI PathSearchAndQualifyA(
1712 LPCSTR pszPath,
1713 LPSTR pszBuf,
1714 UINT cchBuf)
1715{
1716 FIXME("%s %s 0x%08x\n", pszPath, pszBuf, cchBuf);
1717 return FALSE;
1718}
1719
1720/*************************************************************************
1721 * PathSearchAndQualifyW [SHLWAPI.@]
1722 */
1723BOOL WINAPI PathSearchAndQualifyW(
1724 LPCWSTR pszPath,
1725 LPWSTR pszBuf,
1726 UINT cchBuf)
1727{
1728 FIXME("%s %s 0x%08x\n", debugstr_w(pszPath), debugstr_w(pszBuf), cchBuf);
1729 return FALSE;
1730}
1731
1732#ifndef __WIN32OS2__
1733/*************************************************************************
1734 * PathSkipRootA [SHLWAPI.@]
1735 */
1736LPSTR WINAPI PathSkipRootA(LPCSTR pszPath)
1737{
1738 FIXME("%s\n", pszPath);
1739 return (LPSTR)pszPath;
1740}
1741
1742/*************************************************************************
1743 * PathSkipRootW [SHLWAPI.@]
1744 */
1745LPWSTR WINAPI PathSkipRootW(LPCWSTR pszPath)
1746{
1747 FIXME("%s\n", debugstr_w(pszPath));
1748 return (LPWSTR)pszPath;
1749}
1750#endif
1751
1752/*************************************************************************
1753 * PathCreateFromUrlA [SHLWAPI.@]
1754 */
1755HRESULT WINAPI PathCreateFromUrlA(
1756 LPCSTR pszUrl,
1757 LPSTR pszPath,
1758 LPDWORD pcchPath,
1759 DWORD dwFlags)
1760{
1761 FIXME("%s %p %p 0x%08lx\n",
1762 pszUrl, pszPath, pcchPath, dwFlags);
1763 return S_OK;
1764}
1765
1766/*************************************************************************
1767 * PathCreateFromUrlW [SHLWAPI.@]
1768 */
1769HRESULT WINAPI PathCreateFromUrlW(
1770 LPCWSTR pszUrl,
1771 LPWSTR pszPath,
1772 LPDWORD pcchPath,
1773 DWORD dwFlags)
1774{
1775 FIXME("%s %p %p 0x%08lx\n",
1776 debugstr_w(pszUrl), pszPath, pcchPath, dwFlags);
1777 return S_OK;
1778}
1779
1780/*************************************************************************
1781 * PathRelativePathToA [SHLWAPI.@]
1782 */
1783BOOL WINAPI PathRelativePathToA(
1784 LPSTR pszPath,
1785 LPCSTR pszFrom,
1786 DWORD dwAttrFrom,
1787 LPCSTR pszTo,
1788 DWORD dwAttrTo)
1789{
1790 FIXME("%s %s 0x%08lx %s 0x%08lx\n",
1791 pszPath, pszFrom, dwAttrFrom, pszTo, dwAttrTo);
1792 return FALSE;
1793}
1794
1795/*************************************************************************
1796 * PathRelativePathToW [SHLWAPI.@]
1797 */
1798BOOL WINAPI PathRelativePathToW(
1799 LPWSTR pszPath,
1800 LPCWSTR pszFrom,
1801 DWORD dwAttrFrom,
1802 LPCWSTR pszTo,
1803 DWORD dwAttrTo)
1804{
1805 FIXME("%s %s 0x%08lx %s 0x%08lx\n",
1806 debugstr_w(pszPath), debugstr_w(pszFrom), dwAttrFrom, debugstr_w(pszTo), dwAttrTo);
1807 return FALSE;
1808}
1809
1810/*************************************************************************
1811 * PathUnmakeSystemFolderA [SHLWAPI.@]
1812 */
1813BOOL WINAPI PathUnmakeSystemFolderA(LPCSTR pszPath)
1814{
1815 FIXME("%s\n", pszPath);
1816 return FALSE;
1817}
1818
1819/*************************************************************************
1820 * PathUnmakeSystemFolderW [SHLWAPI.@]
1821 */
1822BOOL WINAPI PathUnmakeSystemFolderW(LPCWSTR pszPath)
1823{
1824 FIXME("%s\n", debugstr_w(pszPath));
1825 return FALSE;
1826}
1827
1828/*
1829 ########## special ##########
1830*/
1831
1832/*************************************************************************
1833 * PathSetDlgItemPathA [SHLWAPI.@]
1834 *
1835 * NOTES
1836 * use PathCompactPath to make sure, the path fits into the control
1837 */
1838BOOL WINAPI PathSetDlgItemPathA(HWND hDlg, int id, LPCSTR pszPath)
1839{ TRACE("%x %x %s\n",hDlg, id, pszPath);
1840 return SetDlgItemTextA(hDlg, id, pszPath);
1841}
1842
1843/*************************************************************************
1844 * PathSetDlgItemPathW [SHLWAPI.@]
1845 */
1846BOOL WINAPI PathSetDlgItemPathW(HWND hDlg, int id, LPCWSTR pszPath)
1847{ TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
1848 return SetDlgItemTextW(hDlg, id, pszPath);
1849}
Note: See TracBrowser for help on using the repository browser.