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

Last change on this file since 2013 was 1553, checked in by phaller, 26 years ago

Add: update to wine/shell32 1999/11/02 #3

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