source: trunk/src/shell32/shellpath.cpp@ 3313

Last change on this file since 3313 was 3257, checked in by cbratschi, 25 years ago

floppy name resource, release fix (don't use pdump)

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