source: trunk/src/shlwapi/path.cpp@ 3546

Last change on this file since 3546 was 3546, checked in by phaller, 25 years ago

Fix: spelling of PathFindFileName

File size: 29.6 KB
Line 
1/* $Id: path.cpp,v 1.2 2000-05-16 20:17:30 phaller Exp $ */
2
3/*
4 * Win32 SHELL32 for OS/2
5 *
6 * Copyright 1997 Marcus Meissner
7 * Copyright 1999 Patrick Haller (haller@zebra.fh-weingarten.de)
8 * Project Odin Software License can be found in LICENSE.TXT
9 *
10 * Path Functions
11 *
12 * Many of this functions are in SHLWAPI.DLL also
13 *
14 * Corel WINE 20000324 level (without CRTDLL_* calls)
15 */
16
17/*****************************************************************************
18 * Remark *
19 *****************************************************************************
20
21 */
22
23
24/*****************************************************************************
25 * Includes *
26 *****************************************************************************/
27
28#include <odin.h>
29#include <odinwrap.h>
30#include <os2sel.h>
31
32#include <string.h>
33#include <ctype.h>
34#include <wctype.h>
35#include <wcstr.h>
36#define HAVE_WCTYPE_H
37
38#include "debugtools.h"
39
40#include <winreg.h>
41
42#include <heapstring.h>
43#include <misc.h>
44#include <win\shell.h>
45#include <win\winerror.h>
46#include <winversion.h>
47#include <winuser.h>
48
49#include "shlwapi.h"
50
51
52ODINDEBUGCHANNEL(SHLWAPI-SHELLPATH)
53
54
55/* Supported protocols for PathIsURL */
56LPSTR SupportedProtocol[] = {"http","https","ftp","gopher","file","mailto",""};
57
58/*************************************************************************
59 * PathIsRoot [SHELL32.29]
60 */
61ODINFUNCTION1(BOOL, PathIsRootA,
62 LPCSTR, x)
63{ TRACE("%s\n",x);
64 if (*(x+1)==':' && *(x+2)=='\\') /* "X:\" */
65 return 1;
66 if (*x=='\\' || *x=='/') /* "\" */
67 return 1;
68 if (x[0]=='\\' && x[1]=='\\') /* UNC "\\<xx>\" */
69 { int foundbackslash = 0;
70 x=x+2;
71 while (*x)
72 { if (*x++=='\\')
73 foundbackslash++;
74 }
75 if (foundbackslash<=1) /* max 1 \ more ... */
76 return 1;
77 }
78 return 0;
79}
80ODINFUNCTION1(BOOL, PathIsRootW,
81 LPCWSTR, x)
82{ TRACE("%s\n",debugstr_w(x));
83 if (*(x+1)==':' && *(x+2)=='\\') /* "X:\" */
84 return 1;
85 if (*x == (WCHAR) '\\' || *x == (WCHAR) '/') /* "\" */
86 return 1;
87 if (x[0]==(WCHAR)'\\' && x[1]==(WCHAR)'\\') /* UNC "\\<xx>\" */
88 { int foundbackslash = 0;
89 x=x+2;
90 while (*x)
91 { if (*x++==(WCHAR)'\\')
92 foundbackslash++;
93 }
94 if (foundbackslash<=1) /* max 1 \ more ... */
95 return 1;
96 }
97 return 0;
98}
99ODINFUNCTION1(BOOL, PathIsRootAW,
100 LPCVOID, x)
101{ if (VERSION_OsIsUnicode())
102 return PathIsRootW((LPWSTR)x);
103 return PathIsRootA((LPSTR)x);
104
105}
106/*************************************************************************
107 * PathBuildRoot [SHELL32.30]
108 */
109LPSTR WINAPI PathBuildRootA(LPSTR root, BYTE drive)
110{
111 TRACE("%p %i\n",root, drive);
112 strcpy(root,"A:\\");
113 root[0]+=drive;
114 return root;
115}
116
117/*************************************************************************
118 */
119LPWSTR WINAPI PathBuildRootW(LPWSTR root, BYTE drive)
120{
121 lstrcpyW(root, (LPWSTR)L"A:\\");
122 root[0]+=drive;
123 return root;
124}
125
126/*************************************************************************
127 * PathFindExtension [SHELL32.31]
128 *
129 * NOTES
130 * returns pointer to last . in last pathcomponent or at \0.
131 */
132ODINFUNCTION1(LPCSTR, PathFindExtensionA,
133 LPCSTR, path)
134{ LPCSTR lastpoint = NULL;
135 TRACE("%p %s\n",path,path);
136 while (*path)
137 { if (*path=='\\'||*path==' ')
138 lastpoint=NULL;
139 if (*path=='.')
140 lastpoint=path;
141 path++;
142 }
143 return lastpoint?lastpoint:path;
144}
145ODINFUNCTION1(LPCWSTR, PathFindExtensionW,
146 LPCWSTR, path)
147{ LPCWSTR lastpoint = NULL;
148 TRACE("%p L%s\n",path,debugstr_w(path));
149 while (*path)
150 { if (*path==(WCHAR)'\\'||*path==(WCHAR)' ')
151 lastpoint=NULL;
152 if (*path==(WCHAR)'.')
153 lastpoint=path;
154 path++;
155 }
156 return lastpoint?lastpoint:path;
157}
158ODINFUNCTION1(LPCVOID, PathFindExtensionAW,
159 LPCVOID, path)
160{ if (VERSION_OsIsUnicode())
161 return PathFindExtensionW((LPWSTR)path);
162 return PathFindExtensionA((LPSTR)path);
163
164}
165
166/*************************************************************************
167 * PathAddBackslash [SHELL32.32]
168 *
169 * NOTES
170 * append \ if there is none
171 */
172ODINFUNCTION1(LPSTR, PathAddBackslashA,
173 LPSTR, path)
174{ int len;
175 TRACE("%p->%s\n",path,path);
176
177 len = strlen(path);
178 if (len && path[len-1]!='\\')
179 { path[len] = '\\';
180 path[len+1]= 0x00;
181 return path+len+1;
182 }
183 return path+len;
184}
185ODINFUNCTION1(LPWSTR, PathAddBackslashW,
186 LPWSTR, path)
187{ int len;
188 TRACE("%p->%s\n",path,debugstr_w(path));
189
190 len = lstrlenW(path);
191 if (len && path[len-1]!=(WCHAR)'\\')
192 { path[len] = (WCHAR)'\\';
193 path[len+1]= 0x00;
194 return path+len+1;
195 }
196 return path+len;
197}
198ODINFUNCTION1(LPVOID, PathAddBackslashAW,
199 LPVOID, path)
200{ if(VERSION_OsIsUnicode())
201 return PathAddBackslashW((LPWSTR)path);
202 return PathAddBackslashA((LPSTR)path);
203}
204
205/*************************************************************************
206 * PathRemoveBlanks [SHELL32.33]
207 *
208 * NOTES
209 * remove spaces from beginning and end of passed string
210 */
211ODINFUNCTION1(LPSTR, PathRemoveBlanksA,
212 LPSTR, str)
213{ LPSTR x = str;
214 TRACE("%s\n",str);
215 while (*x==' ') x++;
216 if (x!=str)
217 strcpy(str,x);
218 if (!*str)
219 return str;
220 x=str+strlen(str)-1;
221 while (*x==' ')
222 x--;
223 if (*x==' ')
224 *x='\0';
225 return x;
226}
227ODINFUNCTION1(LPWSTR, PathRemoveBlanksW,
228 LPWSTR, str)
229{ LPWSTR x = str;
230 TRACE("%s\n",debugstr_w(str));
231 while (*x==' ') x++;
232 if (x!=str)
233 lstrcpyW(str,x);
234 if (!*str)
235 return str;
236 x=str+lstrlenW(str)-1;
237 while (*x==' ')
238 x--;
239 if (*x==' ')
240 *x='\0';
241 return x;
242}
243ODINFUNCTION1(LPVOID, PathRemoveBlanksAW,
244 LPVOID, str)
245{ if(VERSION_OsIsUnicode())
246 return PathRemoveBlanksW((LPWSTR)str);
247 return PathRemoveBlanksA((LPSTR)str);
248}
249
250
251
252/*************************************************************************
253 * PathFindFileName [SHELL32.34]
254 *
255 * NOTES
256 * basename(char *fn);
257 */
258ODINFUNCTION1(LPCSTR, PathFindFileNameA,
259 LPCSTR, aptr)
260{
261 int iLength = strlen(aptr);
262 LPSTR strSlash = (LPSTR)aptr + iLength - 1;
263
264 while (iLength--)
265 {
266 if ( (*strSlash == '/' ) ||
267 (*strSlash == '\\') )
268 return strSlash + 1;
269 }
270
271 // no slash found, look for ":"
272 if (aptr[1] == ':')
273 return aptr+2;
274
275 return aptr; // no slash and no drive found
276}
277
278ODINFUNCTION1(LPCWSTR, PathFindFileNameW,
279 LPCWSTR, wptr)
280{ LPCWSTR wslash;
281 wslash = wptr;
282
283 TRACE("L%s\n",debugstr_w(wslash));
284 while (wptr[0])
285 { if (((wptr[0]=='\\') || (wptr[0]==':')) && wptr[1] && wptr[1]!='\\')
286 wslash = wptr+1;
287 wptr++;
288 }
289 return wslash;
290}
291ODINFUNCTION1(LPCVOID, PathFindFileNameAW,
292 LPCVOID, fn)
293{
294 if(VERSION_OsIsUnicode())
295 return PathFindFileNameW((LPWSTR)fn);
296 return PathFindFileNameA((LPSTR)fn);
297}
298
299/*************************************************************************
300 * PathRemoveFileSpec [SHELL32.35]
301 *
302 * NOTES
303 * bool getpath(char *pathname); truncates passed argument to a valid path
304 * returns if the string was modified or not.
305 * "\foo\xx\foo"-> "\foo\xx"
306 * "\" -> "\"
307 * "a:\foo" -> "a:\"
308 */
309ODINFUNCTION1(DWORD, PathRemoveFileSpecA,
310 LPSTR, fn)
311{
312 LPSTR x,cutplace;
313 TRACE("%s\n",fn);
314 if (!fn[0])
315 return 0;
316 x=fn;
317 cutplace = fn;
318 while (*x) {
319 if (*x=='\\') {
320 cutplace=x++;
321 continue;
322 }
323 if (*x==':') {
324 x++;
325 if (*x=='\\')
326 cutplace=++x;
327 continue; /* already x++ed */
328 }
329 x++;
330 }
331 if (!*cutplace)
332 return 0;
333 if (cutplace==fn) {
334 if (fn[0]=='\\') {
335 if (!fn[1])
336 return 0;
337 fn[0]='\0';
338 return 1;
339 }
340 }
341 *cutplace='\0';
342 return 1;
343}
344
345/*************************************************************************
346 * PathAppend [SHELL32.36]
347 *
348 * NOTES
349 * concat_paths(char*target,const char*add);
350 * concats "target\\add" and writes them to target
351 */
352LPSTR WINAPI PathAppendA(LPSTR x1, LPSTR x2)
353{
354 TRACE("%s %s\n",x1,x2);
355 while (x2[0]=='\\') x2++;
356 return PathCombineA(x1,x1,x2);
357}
358
359/*************************************************************************
360 * PathAppend [SHELL32.36]
361 *
362 * NOTES
363 * concat_paths(char*target,const char*add);
364 * concats "target\\add" and writes them to target
365 */
366LPWSTR WINAPI PathAppendW(LPWSTR x1, LPWSTR x2)
367{
368 while (x2[0] == (WCHAR)'\\') x2++;
369 return PathCombineW(x1,x1,x2);
370}
371
372/*************************************************************************
373 * PathCombine [SHELL32.37]
374 *
375 * NOTES
376 * if lpszFile='.' skip it
377 * szDest can be equal to lpszFile. Thats why we use sTemp
378 */
379ODINFUNCTION3(LPSTR, PathCombineA,
380 LPSTR, szDest,
381 LPCSTR, lpszDir,
382 LPCSTR, lpszFile)
383{ char sTemp[MAX_PATH];
384 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, lpszDir, lpszFile, lpszFile);
385
386
387 if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
388 { strcpy(szDest,lpszDir);
389 return szDest;
390 }
391
392 /* if lpszFile is a complete path don't care about lpszDir */
393 if (PathIsRootA(lpszFile))
394 { strcpy(szDest,lpszFile);
395 }
396 else
397 { strcpy(sTemp,lpszDir);
398 PathAddBackslashA(sTemp);
399 strcat(sTemp,lpszFile);
400 strcpy(szDest,sTemp);
401 }
402 return szDest;
403}
404ODINFUNCTION3(LPWSTR, PathCombineW,
405 LPWSTR, szDest,
406 LPCWSTR, lpszDir,
407 LPCWSTR, lpszFile)
408{ WCHAR sTemp[MAX_PATH];
409 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, debugstr_w(lpszDir),
410 lpszFile, debugstr_w(lpszFile));
411
412
413 if (!lpszFile || !lpszFile[0] || (lpszFile[0]==(WCHAR)'.' && !lpszFile[1]) )
414 { lstrcpyW(szDest,lpszDir);
415 return szDest;
416 }
417
418 /* if lpszFile is a complete path don't care about lpszDir */
419 if (PathIsRootW(lpszFile))
420 { lstrcpyW(szDest,lpszFile);
421 }
422 else
423 { lstrcpyW(sTemp,lpszDir);
424 PathAddBackslashW(sTemp);
425 lstrcatW(sTemp,lpszFile);
426 lstrcpyW(szDest,sTemp);
427 }
428 return szDest;
429}
430ODINFUNCTION3(LPVOID, PathCombineAW,
431 LPVOID, szDest,
432 LPCVOID, lpszDir,
433 LPCVOID, lpszFile)
434{ if (VERSION_OsIsUnicode())
435 return PathCombineW( (LPWSTR)szDest, (LPWSTR)lpszDir, (LPWSTR)lpszFile );
436 return PathCombineA( (LPSTR)szDest, (LPSTR)lpszDir, (LPSTR)lpszFile );
437}
438
439/*************************************************************************
440 * PathIsUNC [SHELL32.39]
441 *
442 * NOTES
443 * PathIsUNC(char*path);
444 */
445ODINFUNCTION1(BOOL, PathIsUNCA,
446 LPCSTR, path)
447{ TRACE("%s\n",path);
448
449 if ((path[0]=='\\') && (path[1]=='\\'))
450 return TRUE;
451 return FALSE;
452}
453ODINFUNCTION1(BOOL, PathIsUNCW,
454 LPCWSTR, path)
455{ TRACE("%s\n",debugstr_w(path));
456
457 if ((path[0]=='\\') && (path[1]=='\\'))
458 return TRUE;
459 return FALSE;
460}
461ODINFUNCTION1(BOOL, PathIsUNCAW,
462 LPCVOID, path)
463{ if (VERSION_OsIsUnicode())
464 return PathIsUNCW( (LPWSTR)path );
465 return PathIsUNCA( (LPSTR)path );
466}
467/*************************************************************************
468 * PathIsRelativ [SHELL32.40]
469 *
470 */
471ODINFUNCTION1(BOOL, PathIsRelativeA,
472 LPCSTR, path)
473{ TRACE("path=%s\n",path);
474
475 if (path && (path[0]!='\\' && path[1]==':'))
476 return TRUE;
477 return FALSE;
478}
479ODINFUNCTION1(BOOL, PathIsRelativeW,
480 LPCWSTR, path)
481{ TRACE("path=%s\n",debugstr_w(path));
482
483 if (path && (path[0]!='\\' && path[1]==':'))
484 return TRUE;
485 return FALSE;
486}
487ODINFUNCTION1(BOOL, PathIsRelativeAW,
488 LPCVOID, path)
489{ if (VERSION_OsIsUnicode())
490 return PathIsRelativeW( (LPWSTR)path );
491 return PathIsRelativeA( (LPSTR)path );
492}
493/*************************************************************************
494 * PathIsExe [SHELL32.43]
495 *
496 */
497ODINFUNCTION1(BOOL, PathIsExeA,
498 LPCSTR, path)
499{ FIXME("path=%s\n",path);
500 return FALSE;
501}
502ODINFUNCTION1(BOOL, PathIsExeW,
503 LPCWSTR, path)
504{ FIXME("path=%s\n",debugstr_w(path));
505 return FALSE;
506}
507ODINFUNCTION1(BOOL, PathIsExeAW,
508 LPCVOID, path)
509{ if (VERSION_OsIsUnicode())
510 return PathIsExeW ((LPWSTR)path);
511 return PathIsExeA((LPSTR)path);
512}
513
514/*************************************************************************
515 * PathFileExists [SHELL32.45]
516 *
517 * NOTES
518 * file_exists(char *fn);
519 */
520ODINFUNCTION1(BOOL, PathFileExistsA,
521 LPSTR, fn)
522{
523 TRACE("%s\n",fn);
524 if (GetFileAttributesA(fn)==-1)
525 return FALSE;
526 else
527 return TRUE;
528}
529/*************************************************************************
530 * PathFileExists [SHELL32.45]
531 *
532 * NOTES
533 * file_exists(char *fn);
534 */
535ODINFUNCTION1(BOOL, PathFileExistsW,
536 LPWSTR, fn)
537{
538 if (GetFileAttributesW(fn)==-1)
539 return FALSE;
540 else
541 return TRUE;
542}
543/*************************************************************************
544 * PathMatchSingleMask
545 *
546 * NOTES
547 * internal (used by PathMatchSpec)
548 */
549static BOOL PathMatchSingleMaskA(LPCSTR name, LPCSTR mask)
550{
551 while (*name && *mask && *mask!=';') {
552 if (*mask=='*') {
553 do {
554 if (PathMatchSingleMaskA(name,mask+1)) return 1; /* try substrings */
555 } while (*name++);
556 return 0;
557 }
558 if (toupper(*mask)!=toupper(*name) && *mask!='?') return 0;
559 name++;
560 mask++;
561 }
562 if (!*name) {
563 while (*mask=='*') mask++;
564 if (!*mask || *mask==';') return 1;
565 }
566 return 0;
567}
568
569static BOOL PathMatchSingleMaskW(LPCWSTR name, LPCWSTR mask)
570{
571 while (*name && *mask && (*mask != ';'))
572 {
573 if (*mask == '*')
574 {
575 do
576 {
577 if (PathMatchSingleMaskW(name,mask+1)) return 1; /* try substrings */
578 } while (*name++);
579 return FALSE;
580 }
581 if ((towupper(*mask) != towupper(*name)) && (*mask != '?')) return 0;
582 name++;
583 mask++;
584 }
585 if (!*name)
586 {
587 while (*mask == '*') mask++;
588 if (!*mask || (*mask == ';')) return TRUE;
589 }
590
591 return FALSE;
592}
593/*************************************************************************
594 * PathMatchSpec [SHELL32.46]
595 *
596 * NOTES
597 * used from COMDLG32
598 */
599ODINFUNCTION2(BOOL, PathMatchSpecA,
600 LPCSTR, name,
601 LPCSTR, mask)
602{
603 TRACE("%s %s\n",name,mask);
604
605 if (!lstrcmpA( mask, "*.*" )) return TRUE; /* we don't require a period */
606
607 while (*mask)
608 {
609 if (PathMatchSingleMaskA(name,mask)) return TRUE; /* helper function */
610 while (*mask && *mask!=';') mask++;
611 if (*mask==';')
612 {
613 mask++;
614 while (*mask==' ') mask++; /* masks may be separated by "; " */
615 }
616 }
617
618 return FALSE;
619}
620
621ODINFUNCTION2(BOOL, PathMatchSpecW,
622 LPCWSTR, name,
623 LPCWSTR, mask)
624{
625 TRACE("%ls %ls\n",name,mask);
626
627 if (!lstrcmpW( mask, (WCHAR*)L"*.*" )) return TRUE; /* we don't require a period */
628
629 while (*mask)
630 {
631 if (PathMatchSingleMaskW(name,mask)) return TRUE; /* helper function */
632 while (*mask && (*mask != ';')) mask++;
633 if (*mask == ';')
634 {
635 mask++;
636 while (*mask==' ') mask++; /* masks may be separated by "; " */
637 }
638 }
639
640 return FALSE;
641}
642ODINFUNCTION2(BOOL, PathMatchSpecAW,
643 LPVOID, name,
644 LPVOID, mask)
645{
646 if (VERSION_OsIsUnicode())
647 return PathMatchSpecW( (LPWSTR)name, (LPWSTR)mask );
648 return PathMatchSpecA( (LPSTR)name, (LPSTR)mask );
649}
650/*************************************************************************
651 * PathSetDlgItemPathAW [SHELL32.48]
652 * NOTES
653 * use PathCompactPath to make sure, the path fits into the control
654 */
655
656ODINFUNCTION3(BOOL, PathSetDlgItemPathA,
657 HWND, hDlg,
658 int, id,
659 LPCSTR, pszPath)
660{ TRACE("%x %x %s\n",hDlg, id, pszPath);
661 return SetDlgItemTextA(hDlg, id, pszPath);
662}
663ODINFUNCTION3(BOOL, PathSetDlgItemPathW,
664 HWND, hDlg,
665 int, id,
666 LPCWSTR, pszPath)
667{ TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
668 return SetDlgItemTextW(hDlg, id, pszPath);
669}
670ODINFUNCTION3(BOOL, PathSetDlgItemPathAW,
671 HWND, hDlg,
672 int, id,
673 LPCVOID, pszPath)
674{ if (VERSION_OsIsUnicode())
675 return PathSetDlgItemPathW(hDlg, id, (LPWSTR)pszPath);
676 return PathSetDlgItemPathA(hDlg, id, (LPSTR)pszPath);
677}
678
679/*************************************************************************
680 * PathQualifyAW [SHELL32.49]
681 */
682
683ODINFUNCTION1(BOOL, PathQualifyA,
684 LPCSTR, pszPath)
685{ FIXME("%s\n",pszPath);
686 return 0;
687}
688ODINFUNCTION1(BOOL, PathQualifyW,
689 LPCWSTR, pszPath)
690{ FIXME("%s\n",debugstr_w(pszPath));
691 return 0;
692}
693ODINFUNCTION1(BOOL, PathQualifyAW,
694 LPCVOID, pszPath)
695{ if (VERSION_OsIsUnicode())
696 return PathQualifyW((LPWSTR)pszPath);
697 return PathQualifyA((LPSTR)pszPath);
698}
699
700/*************************************************************************
701 * PathResolve [SHELL32.51]
702 */
703ODINFUNCTION3(DWORD, PathResolve,
704 LPCSTR, s,
705 DWORD, x2,
706 DWORD, x3)
707{
708 FIXME("(%s,0x%08lx,0x%08lx),stub!\n",s,x2,x3);
709 return 0;
710}
711
712/*************************************************************************
713 * PathGetArgs [SHELL32.52]
714 *
715 * NOTES
716 * look for next arg in string. handle "quoted" strings
717 * returns pointer to argument *AFTER* the space. Or to the \0.
718 */
719ODINFUNCTION1(LPCSTR, PathGetArgsA,
720 LPCSTR, cmdline)
721{ BOOL qflag = FALSE;
722
723 TRACE("%s\n",cmdline);
724
725 while (*cmdline)
726 { if ((*cmdline==' ') && !qflag)
727 return cmdline+1;
728 if (*cmdline=='"')
729 qflag=!qflag;
730 cmdline++;
731 }
732 return cmdline;
733
734}
735ODINFUNCTION1(LPCWSTR, PathGetArgsW,
736 LPCWSTR, cmdline)
737{ BOOL qflag = FALSE;
738
739 TRACE("%sL\n",debugstr_w(cmdline));
740
741 while (*cmdline)
742 { if ((*cmdline==' ') && !qflag)
743 return cmdline+1;
744 if (*cmdline=='"')
745 qflag=!qflag;
746 cmdline++;
747 }
748 return cmdline;
749}
750ODINFUNCTION1(LPCVOID, PathGetArgsAW,
751 LPVOID, cmdline)
752{ if (VERSION_OsIsUnicode())
753 return PathGetArgsW((LPWSTR)cmdline);
754 return PathGetArgsA((LPSTR)cmdline);
755}
756/*************************************************************************
757 * PathQuoteSpaces [SHELL32.55]
758 *
759 * NOTES
760 * basename(char *fn);
761 */
762ODINFUNCTION1(LPSTR, PathQuoteSpacesA,
763 LPCSTR, aptr)
764{ FIXME("%s\n",aptr);
765 return 0;
766
767}
768ODINFUNCTION1(LPWSTR, PathQuoteSpacesW,
769 LPCWSTR, wptr)
770{ FIXME("L%s\n",debugstr_w(wptr));
771 return 0;
772}
773ODINFUNCTION1(LPVOID, PathQuoteSpacesAW,
774 LPCVOID, fn)
775{ if(VERSION_OsIsUnicode())
776 return PathQuoteSpacesW((LPWSTR)fn);
777 return PathQuoteSpacesA((LPSTR)fn);
778}
779
780
781/*************************************************************************
782 * PathUnquoteSpaces [SHELL32.56]
783 *
784 * NOTES
785 * unquote string (remove ")
786 */
787ODINPROCEDURE1(PathUnquoteSpacesA,
788 LPSTR, str)
789{ DWORD len = lstrlenA(str);
790 TRACE("%s\n",str);
791 if (*str!='"')
792 return;
793 if (str[len-1]!='"')
794 return;
795 str[len-1]='\0';
796 lstrcpyA(str,str+1);
797 return;
798}
799ODINPROCEDURE1(PathUnquoteSpacesW,
800 LPWSTR, str)
801{ DWORD len = lstrlenW(str);
802
803 TRACE("%s\n",debugstr_w(str));
804
805 if (*str!='"')
806 return;
807 if (str[len-1]!='"')
808 return;
809 str[len-1]='\0';
810 lstrcpyW(str,str+1);
811 return;
812}
813ODINPROCEDURE1(PathUnquoteSpacesAW,
814 LPVOID, str)
815{ if(VERSION_OsIsUnicode())
816 PathUnquoteSpacesW((LPWSTR)str);
817 PathUnquoteSpacesA((LPSTR)str);
818}
819
820
821/*************************************************************************
822 * PathGetDriveNumber32 [SHELL32.57]
823 *
824 */
825ODINFUNCTION1(HRESULT, PathGetDriveNumberAW,
826 LPSTR, u)
827{ FIXME("%s stub\n",debugstr_a(u));
828 return 0;
829}
830
831/*************************************************************************
832 * PathGetDriveNumber32 [SHELL32.57]
833 *
834 */
835ODINFUNCTION1(HRESULT, PathGetDriveNumberA,
836 LPSTR, u)
837{ FIXME("%s stub\n",debugstr_a(u));
838 return 0;
839}
840
841/*************************************************************************
842 * PathGetDriveNumber32 [SHELL32.57]
843 *
844 */
845ODINFUNCTION1(HRESULT, PathGetDriveNumberW,
846 LPWSTR, u)
847{ FIXME("%s stub\n",debugstr_a(u));
848 return 0;
849}
850
851/*************************************************************************
852 * PathYetAnotherMakeUniqueName [SHELL32.75]
853 *
854 * NOTES
855 * exported by ordinal
856 */
857ODINFUNCTION2(BOOL, PathYetAnotherMakeUniqueNameA,
858 LPDWORD, x,
859 LPDWORD, y)
860{
861 FIXME("(%p,%p):stub.\n",x,y);
862 return TRUE;
863}
864
865/*************************************************************************
866 * IsLFNDrive [SHELL32.119]
867 *
868 * NOTES
869 * exported by ordinal Name
870 */
871ODINFUNCTION1(BOOL, IsLFNDriveA,
872 LPCSTR, path)
873{
874 DWORD fnlen;
875
876 if (!GetVolumeInformationA(path,NULL,0,NULL,&fnlen,NULL,NULL,0))
877 return FALSE;
878 return fnlen>12;
879}
880/*************************************************************************
881 * PathFindOnPath [SHELL32.145]
882 */
883ODINFUNCTION2(BOOL, PathFindOnPathA,
884 LPSTR, sFile,
885 LPCSTR, sOtherDirs)
886{ FIXME("%s %s\n",sFile, sOtherDirs);
887 return FALSE;
888}
889ODINFUNCTION2(BOOL, PathFindOnPathW,
890 LPWSTR, sFile,
891 LPCWSTR, sOtherDirs)
892{ FIXME("%s %s\n",debugstr_w(sFile), debugstr_w(sOtherDirs));
893 return FALSE;
894}
895ODINFUNCTION2(BOOL, PathFindOnPathAW,
896 LPVOID, sFile,
897 LPCVOID, sOtherDirs)
898{ if (VERSION_OsIsUnicode())
899 return PathFindOnPathW((LPWSTR)sFile, (LPWSTR)sOtherDirs);
900 return PathFindOnPathA((LPSTR)sFile, (LPSTR)sOtherDirs);
901}
902
903/*************************************************************************
904 * PathGetExtension [SHELL32.158]
905 *
906 * NOTES
907 * exported by ordinal
908 */
909ODINFUNCTION3(LPCSTR, PathGetExtensionA,
910 LPCSTR, path,
911 DWORD, y,
912 DWORD, z)
913{ TRACE("(%s,%08lx,%08lx)\n",path,y,z);
914 path = PathFindExtensionA(path);
915 return *path?(path+1):path;
916}
917ODINFUNCTION3(LPCWSTR, PathGetExtensionW,
918 LPCWSTR, path,
919 DWORD, y,
920 DWORD, z)
921{ TRACE("(L%s,%08lx,%08lx)\n",debugstr_w(path),y,z);
922 path = PathFindExtensionW(path);
923 return *path?(path+1):path;
924}
925ODINFUNCTION3(LPCVOID, PathGetExtensionAW,
926 LPCVOID, path,
927 DWORD, y,
928 DWORD, z)
929{ if (VERSION_OsIsUnicode())
930 return PathGetExtensionW((LPWSTR)path,y,z);
931 return PathGetExtensionA((LPSTR)path,y,z);
932}
933
934/*************************************************************************
935 * PathCleanupSpec [SHELL32.171]
936 *
937 */
938ODINFUNCTION2(DWORD, PathCleanupSpecA,
939 LPSTR, x,
940 LPSTR, y)
941{
942 FIXME("%p(%s) %p(%s) stub\n",x,x,y,y);
943 return TRUE;
944}
945
946ODINFUNCTION2(DWORD, PathCleanupSpecW,
947 LPWSTR, x,
948 LPWSTR, y)
949{
950 FIXME("%p(%s) %p(%s) stub\n",x,debugstr_w(x),y,debugstr_w(y));
951 return TRUE;
952}
953
954ODINFUNCTION2(DWORD, PathCleanupSpecAW,
955 LPVOID, x,
956 LPVOID, y)
957{
958 if (VERSION_OsIsUnicode())
959 return PathCleanupSpecW((LPWSTR)x,(LPWSTR)y);
960 return PathCleanupSpecA((LPSTR)x,(LPSTR)y);
961}
962
963
964/*************************************************************************
965* PathProcessCommand [SHELL32.653]
966*/
967ODINFUNCTION4(HRESULT, PathProcessCommandA,
968 LPSTR, lpCommand,
969 LPSTR, v,
970 DWORD, w,
971 DWORD, x)
972{
973 FIXME("%p(%s) %p 0x%04lx 0x%04lx stub\n",
974 lpCommand, lpCommand, v, w,x );
975 lstrcpyA(v,lpCommand);
976 return 0;
977}
978
979ODINFUNCTION4(HRESULT, PathProcessCommandW,
980 LPWSTR, lpCommand,
981 LPSTR, v,
982 DWORD, w,
983 DWORD, x)
984{
985 FIXME("%p(%s) %p 0x%04lx 0x%04lx stub\n",
986 lpCommand, debugstr_w(lpCommand), v, w,x );
987 return 0;
988}
989
990ODINFUNCTION4(HRESULT, PathProcessCommandAW,
991 LPVOID, lpCommand,
992 LPSTR, v,
993 DWORD, w,
994 DWORD, x)
995{
996 if (VERSION_OsIsUnicode())
997 return PathProcessCommandW((LPWSTR)lpCommand, v, w, x);
998 return PathProcessCommandA((LPSTR)lpCommand, v, w, x);
999}
1000
1001
1002/* PathRemoveBackslash
1003 *
1004 * If the path ends in a backslash it is replaced by a NULL
1005 * and the address of the NULL is returned
1006 * Otherwise
1007 * the address of the last character is returned.
1008 *
1009 */
1010LPSTR WINAPI PathRemoveBackslashA(LPSTR lpPath)
1011{
1012 LPSTR temp = lpPath;
1013 LPSTR prev = lpPath;
1014
1015 while (*temp)
1016 {
1017 prev = temp++;
1018 }
1019 if ( *prev == (CHAR)'\\')
1020 {
1021 *prev = (CHAR)'\0';
1022 }
1023
1024 return prev;
1025}
1026
1027LPWSTR WINAPI PathRemoveBackslashW(LPWSTR lpPath)
1028{
1029 LPWSTR temp = lpPath;
1030 LPWSTR prev = lpPath;
1031
1032 while (*temp)
1033 {
1034 prev = temp++;
1035 }
1036 if ( *prev == (WCHAR)'\\')
1037 {
1038 *prev = (WCHAR)'\0';
1039 }
1040
1041 return prev;
1042}
1043
1044/*
1045 shlwapi functions that have found their way in because most of
1046 shlwapi is unimplemented and doesn't have a home.
1047
1048 FIXME: move to a more appropriate file( when one exists )
1049*/
1050
1051 /* SHGetValue: Gets a value from the registry */
1052
1053
1054BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
1055{
1056 LPSTR lpstrRes;
1057 char lpstrFileType[10] = "";
1058 int iSize;
1059 int i = 0;
1060 /* sanity check */
1061 if(!lpstrPath)
1062 return FALSE;
1063
1064 /* get protocol */
1065 /* protocol://location */
1066 if(!(lpstrRes = strchr(lpstrPath,':')))
1067 {
1068 return FALSE;
1069 }
1070 iSize = lpstrRes - lpstrPath;
1071 if(iSize > sizeof(lpstrFileType))
1072 return FALSE;
1073
1074 strncpy(lpstrFileType,lpstrPath,iSize);
1075
1076 while(strlen(SupportedProtocol[i]))
1077 {
1078 if(!stricmp(lpstrFileType,SupportedProtocol[i++]))
1079 return TRUE;
1080 }
1081
1082 return FALSE;
1083}
1084
1085
1086/*****************************************************************************
1087 * Name : LPSTR PathGetShortPathA
1088 * Purpose : unknown
1089 * Parameters: LPSTR lpszPath
1090 * Variables :
1091 * Result : unknown
1092 * Remark : SHLWAPI.??
1093 * Status : UNTESTED
1094 *
1095 * Author : Patrick Haller [Sun, 2000/05/14 01:02]
1096 *****************************************************************************/
1097
1098ODINFUNCTION1(LPSTR, PathGetShortPathA,
1099 LPSTR, lpszPath)
1100{
1101 dprintf(("stub: lpszPath=[%s]", lpszPath));
1102 return NULL;
1103}
1104
1105
1106/*****************************************************************************
1107 * Name : LPWSTR PathGetShortPathW
1108 * Purpose : unknown
1109 * Parameters: LPWSTR lpszPath
1110 * Variables :
1111 * Result : unknown
1112 * Remark : SHLWAPI.??
1113 * Status : UNTESTED
1114 *
1115 * Author : Patrick Haller [Sun, 2000/05/14 01:02]
1116 *****************************************************************************/
1117
1118ODINFUNCTION1(LPWSTR, PathGetShortPathW,
1119 LPWSTR, lpszPath)
1120{
1121 dprintf(("stub: lpszPath=[%08xh]", lpszPath));
1122 return NULL;
1123}
1124
1125
1126/*****************************************************************************
1127 * Name : LPVOID PathGetShortPathAW
1128 * Purpose : unknown
1129 * Parameters: LPVOID lpszPath
1130 * Variables :
1131 * Result : unknown
1132 * Remark : SHLWAPI.92
1133 * Status : UNTESTED
1134 *
1135 * Author : Patrick Haller [Sun, 2000/05/14 01:02]
1136 *****************************************************************************/
1137
1138ODINFUNCTION1(LPVOID, PathGetShortPathAW,
1139 LPVOID, lpszPath)
1140{
1141 if (VERSION_OsIsUnicode())
1142 return PathGetShortPathW((LPWSTR)lpszPath);
1143 else
1144 return PathGetShortPathA((LPSTR)lpszPath);
1145}
1146
1147
1148/*****************************************************************************
1149 * Name : PathStripToRootA
1150 * Purpose : return root (used by explorer.exe)
1151 * Parameters: Unknown (wrong)
1152 * Variables :
1153 * Result : Unknown
1154 * Remark :
1155 * Status : UNTESTED STUB
1156 *
1157 * Author : Christoph Bratschi [Wed, 2000/03/29 19:47]
1158 *****************************************************************************/
1159
1160ODINFUNCTION1(LPSTR,PathStripToRootA,LPSTR,pszPath)
1161{
1162 dprintf(("not implemented"));
1163
1164 return NULL;
1165}
1166
1167/*****************************************************************************
1168 * Name : PathStripToRootW
1169 * Purpose : return root (used by explorer.exe)
1170 * Parameters: Unknown (wrong)
1171 * Variables :
1172 * Result : Unknown
1173 * Remark :
1174 * Status : UNTESTED STUB
1175 *
1176 * Author : Christoph Bratschi [Wed, 2000/03/29 19:47]
1177 *****************************************************************************/
1178
1179ODINFUNCTION1(LPSTR,PathStripToRootW,LPSTR,pszPath)
1180{
1181 dprintf(("not implemented"));
1182
1183 return NULL;
1184}
1185
1186/*****************************************************************************
1187 * Name : LPSTR PathSkipRootA
1188 * Purpose : Parses a path, ignoring the drive letter or UNC server/share path parts.
1189 * Parameters: LPCSTR pszPath
1190 * Variables :
1191 * Result : unknown
1192 * Remark : SHLWAPI.PathSkipRootA
1193 * Status : UNTESTED
1194 *
1195 * Author : Patrick Haller [Mon, 2000/01/31 23:02]
1196 *****************************************************************************/
1197
1198ODINFUNCTION1(LPSTR, PathSkipRootA, LPCSTR, pszPath)
1199{
1200 // check if "driveletter:\"
1201 if (pszPath[1] == ':')
1202 return (LPSTR)(pszPath + 2);
1203
1204 // check if UNC-style path
1205 if ( (pszPath[0] == '\\') &&
1206 (pszPath[1] == '\\') )
1207 {
1208 LPSTR pszTemp = strchr(pszPath + 2, '\\');
1209 if (NULL != pszTemp)
1210 // return root part, skip server/share
1211 return (LPSTR)pszTemp++;
1212 else
1213 // UNC syntax validation, return pszPath
1214 return (LPSTR)pszTemp;
1215 }
1216
1217 // else ...
1218 return (LPSTR)pszPath;
1219}
1220
1221
1222/*****************************************************************************
1223 * Name : LPWSTR PathSkipRootW
1224 * Purpose : Parses a path, ignoring the drive letter or UNC server/share path parts.
1225 * Parameters: LPCWSTR pszPath
1226 * Variables :
1227 * Result : unknown
1228 * Remark : SHLWAPI.PathSkipRootW
1229 * Status : UNTESTED
1230 *
1231 * Author : Patrick Haller [Mon, 2000/01/31 23:02]
1232 *****************************************************************************/
1233
1234ODINFUNCTION1(LPWSTR, PathSkipRootW, LPCWSTR, pszPath)
1235{
1236 dprintf(("not implemented"));
1237
1238 return (LPWSTR)pszPath;
1239}
Note: See TracBrowser for help on using the repository browser.