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

Last change on this file since 2237 was 2237, checked in by sandervl, 26 years ago

added apis + exports for shlwapi

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