source: trunk/src/shell32/new/shellpath.cpp@ 797

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

.

File size: 23.4 KB
Line 
1/*
2 * Path Functions
3 *
4 * Many of this functions are in SHLWAPI.DLL also
5 *
6 */
7#include <string.h>
8#include <ctype.h>
9#include <odin.h>
10
11#define ICOM_CINTERFACE 1
12#define CINTERFACE 1
13
14#include "debugtools.h"
15#include "winnls.h"
16#include "winversion.h"
17#include "winreg.h"
18#include "crtdll.h"
19
20#include "shlobj.h"
21#include "shell32_main.h"
22
23#include <heapstring.h>
24#include <misc.h>
25
26DEFAULT_DEBUG_CHANNEL(shell)
27
28/*************************************************************************
29 * PathIsRoot [SHELL32.29]
30 */
31BOOL WINAPI PathIsRootA(LPCSTR x)
32{ TRACE("%s\n",x);
33 if (*(x+1)==':' && *(x+2)=='\\') /* "X:\" */
34 return 1;
35 if (*x=='\\') /* "\" */
36 return 0;
37 if (x[0]=='\\' && x[1]=='\\') /* UNC "\\<xx>\" */
38 { int foundbackslash = 0;
39 x=x+2;
40 while (*x)
41 { if (*x++=='\\')
42 foundbackslash++;
43 }
44 if (foundbackslash<=1) /* max 1 \ more ... */
45 return 1;
46 }
47 return 0;
48}
49BOOL WINAPI PathIsRootW(LPCWSTR x)
50{ TRACE("%s\n",debugstr_w(x));
51 if (*(x+1)==':' && *(x+2)=='\\') /* "X:\" */
52 return 1;
53 if (*x == (WCHAR) '\\') /* "\" */
54 return 0;
55 if (x[0]==(WCHAR)'\\' && x[1]==(WCHAR)'\\') /* UNC "\\<xx>\" */
56 { int foundbackslash = 0;
57 x=x+2;
58 while (*x)
59 { if (*x++==(WCHAR)'\\')
60 foundbackslash++;
61 }
62 if (foundbackslash<=1) /* max 1 \ more ... */
63 return 1;
64 }
65 return 0;
66}
67BOOL WINAPI PathIsRootAW(LPCVOID x)
68{ if (VERSION_OsIsUnicode())
69 return PathIsRootW((LPWSTR)x);
70 return PathIsRootA((LPSTR)x);
71
72}
73/*************************************************************************
74 * PathBuildRoot [SHELL32.30]
75 */
76LPSTR WINAPI PathBuildRootA(LPSTR root,BYTE drive) {
77 TRACE("%p %i\n",root, drive);
78 strcpy(root,"A:\\");
79 root[0]+=drive;
80 return root;
81}
82
83/*************************************************************************
84 * PathFindExtension [SHELL32.31]
85 *
86 * NOTES
87 * returns pointer to last . in last pathcomponent or at \0.
88 */
89LPCSTR WINAPI PathFindExtensionA(LPCSTR path)
90{ LPCSTR lastpoint = NULL;
91 TRACE("%p %s\n",path,path);
92 while (*path)
93 { if (*path=='\\'||*path==' ')
94 lastpoint=NULL;
95 if (*path=='.')
96 lastpoint=path;
97 path++;
98 }
99 return lastpoint?lastpoint:path;
100}
101LPCWSTR WINAPI PathFindExtensionW(LPCWSTR path)
102{ LPCWSTR lastpoint = NULL;
103 TRACE("%p L%s\n",path,debugstr_w(path));
104 while (*path)
105 { if (*path==(WCHAR)'\\'||*path==(WCHAR)' ')
106 lastpoint=NULL;
107 if (*path==(WCHAR)'.')
108 lastpoint=path;
109 path++;
110 }
111 return lastpoint?lastpoint:path;
112}
113LPCVOID WINAPI PathFindExtensionAW(LPCVOID path)
114{ if (VERSION_OsIsUnicode())
115 return PathFindExtensionW((LPWSTR)path);
116 return PathFindExtensionA((LPSTR)path);
117
118}
119
120/*************************************************************************
121 * PathAddBackslash [SHELL32.32]
122 *
123 * NOTES
124 * append \ if there is none
125 */
126LPSTR WINAPI PathAddBackslashA(LPSTR path)
127{ int len;
128 TRACE("%p->%s\n",path,path);
129
130 len = strlen(path);
131 if (len && path[len-1]!='\\')
132 { path[len] = '\\';
133 path[len+1]= 0x00;
134 return path+len+1;
135 }
136 return path+len;
137}
138LPWSTR WINAPI PathAddBackslashW(LPWSTR path)
139{ int len;
140 TRACE("%p->%s\n",path,debugstr_w(path));
141
142 len = lstrlenW(path);
143 if (len && path[len-1]!=(WCHAR)'\\')
144 { path[len] = (WCHAR)'\\';
145 path[len+1]= 0x00;
146 return path+len+1;
147 }
148 return path+len;
149}
150LPVOID WINAPI PathAddBackslashAW(LPVOID path)
151{ if(VERSION_OsIsUnicode())
152 return PathAddBackslashW((LPWSTR)path);
153 return PathAddBackslashA((LPSTR)path);
154}
155
156/*************************************************************************
157 * PathRemoveBlanks [SHELL32.33]
158 *
159 * NOTES
160 * remove spaces from beginning and end of passed string
161 */
162LPSTR WINAPI PathRemoveBlanksA(LPSTR str)
163{ LPSTR x = str;
164 TRACE("%s\n",str);
165 while (*x==' ') x++;
166 if (x!=str)
167 strcpy(str,x);
168 if (!*str)
169 return str;
170 x=str+strlen(str)-1;
171 while (*x==' ')
172 x--;
173 if (*x==' ')
174 *x='\0';
175 return x;
176}
177LPWSTR WINAPI PathRemoveBlanksW(LPWSTR str)
178{ LPWSTR x = str;
179 TRACE("%s\n",debugstr_w(str));
180 while (*x==' ') x++;
181 if (x!=str)
182 lstrcpyW(str,x);
183 if (!*str)
184 return str;
185 x=str+lstrlenW(str)-1;
186 while (*x==' ')
187 x--;
188 if (*x==' ')
189 *x='\0';
190 return x;
191}
192LPVOID WINAPI PathRemoveBlanksAW(LPVOID str)
193{ if(VERSION_OsIsUnicode())
194 return PathRemoveBlanksW((LPWSTR)str);
195 return PathRemoveBlanksA((LPSTR)str);
196}
197
198
199
200/*************************************************************************
201 * PathFindFilename [SHELL32.34]
202 *
203 * NOTES
204 * basename(char *fn);
205 */
206LPCSTR WINAPI PathFindFilenameA(LPCSTR aptr)
207{ LPCSTR aslash;
208 aslash = aptr;
209
210 TRACE("%s\n",aslash);
211 while (aptr[0])
212 { if (((aptr[0]=='\\') || (aptr[0]==':')) && aptr[1] && aptr[1]!='\\')
213 aslash = aptr+1;
214 aptr++;
215 }
216 return aslash;
217
218}
219LPCWSTR WINAPI PathFindFilenameW(LPCWSTR wptr)
220{ LPCWSTR wslash;
221 wslash = wptr;
222
223 TRACE("L%s\n",debugstr_w(wslash));
224 while (wptr[0])
225 { if (((wptr[0]=='\\') || (wptr[0]==':')) && wptr[1] && wptr[1]!='\\')
226 wslash = wptr+1;
227 wptr++;
228 }
229 return wslash;
230}
231LPCVOID WINAPI PathFindFilenameAW(LPCVOID fn)
232{
233 if(VERSION_OsIsUnicode())
234 return PathFindFilenameW((LPWSTR)fn);
235 return PathFindFilenameA((LPSTR)fn);
236}
237
238/*************************************************************************
239 * PathRemoveFileSpec [SHELL32.35]
240 *
241 * NOTES
242 * bool getpath(char *pathname); truncates passed argument to a valid path
243 * returns if the string was modified or not.
244 * "\foo\xx\foo"-> "\foo\xx"
245 * "\" -> "\"
246 * "a:\foo" -> "a:\"
247 */
248DWORD WINAPI PathRemoveFileSpecA(LPSTR fn) {
249 LPSTR x,cutplace;
250 TRACE("%s\n",fn);
251 if (!fn[0])
252 return 0;
253 x=fn;
254 cutplace = fn;
255 while (*x) {
256 if (*x=='\\') {
257 cutplace=x++;
258 continue;
259 }
260 if (*x==':') {
261 x++;
262 if (*x=='\\')
263 cutplace=++x;
264 continue; /* already x++ed */
265 }
266 x++;
267 }
268 if (!*cutplace)
269 return 0;
270 if (cutplace==fn) {
271 if (fn[0]=='\\') {
272 if (!fn[1])
273 return 0;
274 fn[0]='\0';
275 return 1;
276 }
277 }
278 *cutplace='\0';
279 return 1;
280}
281
282/*************************************************************************
283 * PathAppend [SHELL32.36]
284 *
285 * NOTES
286 * concat_paths(char*target,const char*add);
287 * concats "target\\add" and writes them to target
288 */
289LPSTR WINAPI PathAppendA(LPSTR x1,LPSTR x2) {
290 TRACE("%s %s\n",x1,x2);
291 while (x2[0]=='\\') x2++;
292 return PathCombineA(x1,x1,x2);
293}
294
295/*************************************************************************
296 * PathCombine [SHELL32.37]
297 *
298 * NOTES
299 * if lpszFile='.' skip it
300 * szDest can be equal to lpszFile. Thats why we use sTemp
301 */
302LPSTR WINAPI PathCombineA(LPSTR szDest, LPCSTR lpszDir, LPCSTR lpszFile)
303{ char sTemp[MAX_PATH];
304 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, lpszDir, lpszFile, lpszFile);
305
306
307 if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
308 { strcpy(szDest,lpszDir);
309 return szDest;
310 }
311
312 /* if lpszFile is a complete path don't care about lpszDir */
313 if (PathIsRootA(lpszFile))
314 { strcpy(szDest,lpszFile);
315 }
316 else
317 { strcpy(sTemp,lpszDir);
318 PathAddBackslashA(sTemp);
319 strcat(sTemp,lpszFile);
320 strcpy(szDest,sTemp);
321 }
322 return szDest;
323}
324LPWSTR WINAPI PathCombineW(LPWSTR szDest, LPCWSTR lpszDir, LPCWSTR lpszFile)
325{ WCHAR sTemp[MAX_PATH];
326 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, debugstr_w(lpszDir),
327 lpszFile, debugstr_w(lpszFile));
328
329
330 if (!lpszFile || !lpszFile[0] || (lpszFile[0]==(WCHAR)'.' && !lpszFile[1]) )
331 { lstrcpyW(szDest,lpszDir);
332 return szDest;
333 }
334
335 /* if lpszFile is a complete path don't care about lpszDir */
336 if (PathIsRootW(lpszFile))
337 { lstrcpyW(szDest,lpszFile);
338 }
339 else
340 { lstrcpyW(sTemp,lpszDir);
341 PathAddBackslashW(sTemp);
342 lstrcatW(sTemp,lpszFile);
343 lstrcpyW(szDest,sTemp);
344 }
345 return szDest;
346}
347LPVOID WINAPI PathCombineAW(LPVOID szDest, LPCVOID lpszDir, LPCVOID lpszFile)
348{ if (VERSION_OsIsUnicode())
349 return PathCombineW( (LPWSTR)szDest, (LPWSTR)lpszDir, (LPWSTR)lpszFile );
350 return PathCombineA( (LPSTR)szDest, (LPSTR)lpszDir, (LPSTR)lpszFile );
351}
352
353/*************************************************************************
354 * PathIsUNC [SHELL32.39]
355 *
356 * NOTES
357 * PathIsUNC(char*path);
358 */
359BOOL WINAPI PathIsUNCA(LPCSTR path)
360{ TRACE("%s\n",path);
361
362 if ((path[0]=='\\') && (path[1]=='\\'))
363 return TRUE;
364 return FALSE;
365}
366BOOL WINAPI PathIsUNCW(LPCWSTR path)
367{ TRACE("%s\n",debugstr_w(path));
368
369 if ((path[0]=='\\') && (path[1]=='\\'))
370 return TRUE;
371 return FALSE;
372}
373BOOL WINAPI PathIsUNCAW (LPCVOID path)
374{ if (VERSION_OsIsUnicode())
375 return PathIsUNCW( (LPWSTR)path );
376 return PathIsUNCA( (LPSTR)path );
377}
378/*************************************************************************
379 * PathIsRelativ [SHELL32.40]
380 *
381 */
382BOOL WINAPI PathIsRelativeA (LPCSTR path)
383{ TRACE("path=%s\n",path);
384
385 if (path && (path[0]!='\\' && path[1]==':'))
386 return TRUE;
387 return FALSE;
388}
389BOOL WINAPI PathIsRelativeW (LPCWSTR path)
390{ TRACE("path=%s\n",debugstr_w(path));
391
392 if (path && (path[0]!='\\' && path[1]==':'))
393 return TRUE;
394 return FALSE;
395}
396BOOL WINAPI PathIsRelativeAW (LPCVOID path)
397{ if (VERSION_OsIsUnicode())
398 return PathIsRelativeW( (LPWSTR)path );
399 return PathIsRelativeA( (LPSTR)path );
400}
401/*************************************************************************
402 * PathIsExe [SHELL32.43]
403 *
404 */
405BOOL WINAPI PathIsExeA (LPCSTR path)
406{ FIXME("path=%s\n",path);
407 return FALSE;
408}
409BOOL WINAPI PathIsExeW (LPCWSTR path)
410{ FIXME("path=%s\n",debugstr_w(path));
411 return FALSE;
412}
413BOOL WINAPI PathIsExeAW (LPCVOID path)
414{ if (VERSION_OsIsUnicode())
415 return PathIsExeW ((LPWSTR)path);
416 return PathIsExeA((LPSTR)path);
417}
418
419/*************************************************************************
420 * PathFileExists [SHELL32.45]
421 *
422 * NOTES
423 * file_exists(char *fn);
424 */
425BOOL WINAPI PathFileExistsA(LPSTR fn) {
426 TRACE("%s\n",fn);
427 if (GetFileAttributesA(fn)==-1)
428 return FALSE;
429 else
430 return TRUE;
431}
432/*************************************************************************
433 * PathMatchSpec [SHELL32.46]
434 *
435 * NOTES
436 * used from COMDLG32
437 */
438
439BOOL WINAPI PathMatchSpecA(LPCSTR name, LPCSTR mask)
440{ LPCSTR _name;
441
442 TRACE("%s %s stub\n",name,mask);
443
444 _name = name;
445 while (*_name && *mask)
446 { if (*mask ==';')
447 { mask++;
448 _name = name;
449 }
450 else if (*mask == '*')
451 { mask++;
452 while (*mask == '*') mask++; /* Skip consecutive '*' */
453 if (!*mask || *mask==';') return TRUE; /* '*' matches everything */
454 while (*_name && (toupper(*_name) != toupper(*mask))) _name++;
455 if (!*_name)
456 { while ( *mask && *mask != ';') mask++;
457 _name = name;
458 }
459 }
460 else if ( (*mask == '?') || (toupper(*mask) == toupper(*_name)) )
461 { mask++;
462 _name++;
463 }
464 else
465 { while ( *mask && *mask != ';') mask++;
466 }
467 }
468 return (!*_name && (!*mask || *mask==';'));
469}
470BOOL WINAPI PathMatchSpecW(LPCWSTR name, LPCWSTR mask)
471{ WCHAR stemp[4];
472 LPCWSTR _name;
473
474 TRACE("%s %s stub\n",debugstr_w(name),debugstr_w(mask));
475
476 lstrcpyAtoW(stemp,"*.*");
477 if (!lstrcmpW( mask, stemp )) return 1;
478
479 _name = name;
480 while (*_name && *mask)
481 { if (*mask ==';')
482 { mask++;
483 _name = name;
484 }
485 else if (*mask == '*')
486 { mask++;
487 while (*mask == '*') mask++; /* Skip consecutive '*' */
488 if (!*mask || *mask==';') return TRUE; /* '*' matches everything */
489 while (*_name && (towupper(*_name) != towupper(*mask))) _name++;
490 if (!*_name)
491 { while ( *mask && *mask != ';') mask++;
492 _name = name;
493 }
494 }
495 else if ( (*mask == '?') || (towupper(*mask) == towupper(*_name)) )
496 { mask++;
497 _name++;
498 }
499 else
500 { while ( *mask && *mask != ';') mask++;
501 }
502 }
503 return (!*_name && (!*mask || *mask==';'));
504}
505BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
506{ if (VERSION_OsIsUnicode())
507 return PathMatchSpecW( (LPWSTR)name, (LPWSTR)mask );
508 return PathMatchSpecA( (LPSTR)name, (LPSTR)mask );
509}
510/*************************************************************************
511 * PathSetDlgItemPathAW [SHELL32.48]
512 * NOTES
513 * use PathCompactPath to make sure, the path fits into the control
514 */
515
516BOOL WINAPI PathSetDlgItemPathA(HWND hDlg, int id, LPCSTR pszPath)
517{ TRACE("%x %x %s\n",hDlg, id, pszPath);
518 return SetDlgItemTextA(hDlg, id, pszPath);
519}
520BOOL WINAPI PathSetDlgItemPathW(HWND hDlg, int id, LPCWSTR pszPath)
521{ TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
522 return SetDlgItemTextW(hDlg, id, pszPath);
523}
524BOOL WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
525{ if (VERSION_OsIsUnicode())
526 return PathSetDlgItemPathW(hDlg, id, (LPWSTR)pszPath);
527 return PathSetDlgItemPathA(hDlg, id, (LPSTR)pszPath);
528}
529
530/*************************************************************************
531 * PathQualifyAW [SHELL32.49]
532 */
533
534BOOL WINAPI PathQualifyA(LPCSTR pszPath)
535{ FIXME("%s\n",pszPath);
536 return 0;
537}
538BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
539{ FIXME("%s\n",debugstr_w(pszPath));
540 return 0;
541}
542BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
543{ if (VERSION_OsIsUnicode())
544 return PathQualifyW((LPWSTR)pszPath);
545 return PathQualifyA((LPSTR)pszPath);
546}
547
548/*************************************************************************
549 * PathResolve [SHELL32.51]
550 */
551DWORD WINAPI PathResolve(LPCSTR s,DWORD x2,DWORD x3) {
552 FIXME("(%s,0x%08lx,0x%08lx),stub!\n",s,x2,x3);
553 return 0;
554}
555
556/*************************************************************************
557 * PathGetArgs [SHELL32.52]
558 *
559 * NOTES
560 * look for next arg in string. handle "quoted" strings
561 * returns pointer to argument *AFTER* the space. Or to the \0.
562 */
563LPCSTR WINAPI PathGetArgsA(LPCSTR cmdline)
564{ BOOL qflag = FALSE;
565
566 TRACE("%s\n",cmdline);
567
568 while (*cmdline)
569 { if ((*cmdline==' ') && !qflag)
570 return cmdline+1;
571 if (*cmdline=='"')
572 qflag=!qflag;
573 cmdline++;
574 }
575 return cmdline;
576
577}
578LPCWSTR WINAPI PathGetArgsW(LPCWSTR cmdline)
579{ BOOL qflag = FALSE;
580
581 TRACE("%sL\n",debugstr_w(cmdline));
582
583 while (*cmdline)
584 { if ((*cmdline==' ') && !qflag)
585 return cmdline+1;
586 if (*cmdline=='"')
587 qflag=!qflag;
588 cmdline++;
589 }
590 return cmdline;
591}
592LPCVOID WINAPI PathGetArgsAW(LPVOID cmdline)
593{ if (VERSION_OsIsUnicode())
594 return PathGetArgsW((LPWSTR)cmdline);
595 return PathGetArgsA((LPSTR)cmdline);
596}
597/*************************************************************************
598 * PathQuoteSpaces [SHELL32.55]
599 *
600 * NOTES
601 * basename(char *fn);
602 */
603LPSTR WINAPI PathQuoteSpacesA(LPCSTR aptr)
604{ FIXME("%s\n",aptr);
605 return 0;
606
607}
608LPWSTR WINAPI PathQuoteSpacesW(LPCWSTR wptr)
609{ FIXME("L%s\n",debugstr_w(wptr));
610 return 0;
611}
612LPVOID WINAPI PathQuoteSpacesAW (LPCVOID fn)
613{ if(VERSION_OsIsUnicode())
614 return PathQuoteSpacesW((LPWSTR)fn);
615 return PathQuoteSpacesA((LPSTR)fn);
616}
617
618
619/*************************************************************************
620 * PathUnquoteSpaces [SHELL32.56]
621 *
622 * NOTES
623 * unquote string (remove ")
624 */
625VOID WINAPI PathUnquoteSpacesA(LPSTR str)
626{ DWORD len = lstrlenA(str);
627 TRACE("%s\n",str);
628 if (*str!='"')
629 return;
630 if (str[len-1]!='"')
631 return;
632 str[len-1]='\0';
633 lstrcpyA(str,str+1);
634 return;
635}
636VOID WINAPI PathUnquoteSpacesW(LPWSTR str)
637{ DWORD len = lstrlenW(str);
638
639 TRACE("%s\n",debugstr_w(str));
640
641 if (*str!='"')
642 return;
643 if (str[len-1]!='"')
644 return;
645 str[len-1]='\0';
646 lstrcpyW(str,str+1);
647 return;
648}
649VOID WINAPI PathUnquoteSpacesAW(LPVOID str)
650{ if(VERSION_OsIsUnicode())
651 PathUnquoteSpacesW((LPWSTR)str);
652 PathUnquoteSpacesA((LPSTR)str);
653}
654
655
656/*************************************************************************
657 * PathGetDriveNumber32 [SHELL32.57]
658 *
659 */
660HRESULT WINAPI PathGetDriveNumber(LPSTR u)
661{ FIXME("%s stub\n",debugstr_a(u));
662 return 0;
663}
664
665/*************************************************************************
666 * PathYetAnotherMakeUniqueName [SHELL32.75]
667 *
668 * NOTES
669 * exported by ordinal
670 */
671BOOL WINAPI PathYetAnotherMakeUniqueNameA(LPDWORD x,LPDWORD y) {
672 FIXME("(%p,%p):stub.\n",x,y);
673 return TRUE;
674}
675
676/*************************************************************************
677 * IsLFNDrive [SHELL32.119]
678 *
679 * NOTES
680 * exported by ordinal Name
681 */
682BOOL WINAPI IsLFNDriveA(LPCSTR path) {
683 DWORD fnlen;
684
685 if (!GetVolumeInformationA(path,NULL,0,NULL,&fnlen,NULL,NULL,0))
686 return FALSE;
687 return fnlen>12;
688}
689/*************************************************************************
690 * PathFindOnPath [SHELL32.145]
691 */
692BOOL WINAPI PathFindOnPathA(LPSTR sFile, LPCSTR sOtherDirs)
693{ FIXME("%s %s\n",sFile, sOtherDirs);
694 return FALSE;
695}
696BOOL WINAPI PathFindOnPathW(LPWSTR sFile, LPCWSTR sOtherDirs)
697{ FIXME("%s %s\n",debugstr_w(sFile), debugstr_w(sOtherDirs));
698 return FALSE;
699}
700BOOL WINAPI PathFindOnPathAW(LPVOID sFile, LPCVOID sOtherDirs)
701{ if (VERSION_OsIsUnicode())
702 return PathFindOnPathW((LPWSTR)sFile, (LPWSTR)sOtherDirs);
703 return PathFindOnPathA((LPSTR)sFile, (LPSTR)sOtherDirs);
704}
705
706/*************************************************************************
707 * PathGetExtension [SHELL32.158]
708 *
709 * NOTES
710 * exported by ordinal
711 */
712LPCSTR WINAPI PathGetExtensionA(LPCSTR path,DWORD y,DWORD z)
713{ TRACE("(%s,%08lx,%08lx)\n",path,y,z);
714 path = PathFindExtensionA(path);
715 return *path?(path+1):path;
716}
717LPCWSTR WINAPI PathGetExtensionW(LPCWSTR path,DWORD y,DWORD z)
718{ TRACE("(L%s,%08lx,%08lx)\n",debugstr_w(path),y,z);
719 path = PathFindExtensionW(path);
720 return *path?(path+1):path;
721}
722LPCVOID WINAPI PathGetExtensionAW(LPCVOID path,DWORD y,DWORD z)
723{ if (VERSION_OsIsUnicode())
724 return PathGetExtensionW((LPWSTR)path,y,z);
725 return PathGetExtensionA((LPSTR)path,y,z);
726}
727
728/*************************************************************************
729 * PathCleanupSpec [SHELL32.171]
730 *
731 */
732DWORD WINAPI PathCleanupSpecA(LPSTR x, LPSTR y)
733{
734 FIXME("%p(%s) %p(%s) stub\n",x,x,y,y);
735 return TRUE;
736}
737
738DWORD WINAPI PathCleanupSpecW(LPWSTR x, LPWSTR y)
739{
740 FIXME("%p(%s) %p(%s) stub\n",x,debugstr_w(x),y,debugstr_w(y));
741 return TRUE;
742}
743
744DWORD WINAPI PathCleanupSpecAW (LPVOID x, LPVOID y)
745{
746 if (VERSION_OsIsUnicode())
747 return PathCleanupSpecW((LPWSTR)x,(LPWSTR)y);
748 return PathCleanupSpecA((LPSTR)x,(LPSTR)y);
749}
750
751/*************************************************************************
752 * SheGetDirW [SHELL32.281]
753 *
754 */
755HRESULT WINAPI SheGetDirW(LPWSTR u, LPWSTR v)
756{ FIXME("%p %p stub\n",u,v);
757 return 0;
758}
759
760/*************************************************************************
761 * SheChangeDirW [SHELL32.274]
762 *
763 */
764HRESULT WINAPI SheChangeDirW(LPWSTR u)
765{ FIXME("(%s),stub\n",debugstr_w(u));
766 return 0;
767}
768
769/*************************************************************************
770* PathProcessCommand [SHELL32.653]
771*/
772HRESULT WINAPI PathProcessCommandA (LPSTR lpCommand, LPSTR v, DWORD w, DWORD x)
773{
774 FIXME("%p(%s) %p 0x%04lx 0x%04lx stub\n",
775 lpCommand, lpCommand, v, w,x );
776 return 0;
777}
778
779HRESULT WINAPI PathProcessCommandW (LPWSTR lpCommand, LPSTR v, DWORD w, DWORD x)
780{
781 FIXME("%p(%s) %p 0x%04lx 0x%04lx stub\n",
782 lpCommand, debugstr_w(lpCommand), v, w,x );
783 return 0;
784}
785
786HRESULT WINAPI PathProcessCommandAW (LPVOID lpCommand, LPSTR v, DWORD w, DWORD x)
787{
788 if (VERSION_OsIsUnicode())
789 return PathProcessCommandW((LPWSTR)lpCommand, v, w, x);
790 return PathProcessCommandA((LPSTR)lpCommand, v, w, x);
791}
792
793/*************************************************************************
794 * SHGetSpecialFolderPath [SHELL32.175]
795 *
796 * converts csidl to path
797 *
798 */
799
800static char * szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
801
802BOOL WINAPI SHGetSpecialFolderPathA (
803 HWND hwndOwner,
804 LPSTR szPath,
805 DWORD csidl,
806 BOOL bCreate)
807{
808 CHAR szValueName[MAX_PATH], szDefaultPath[MAX_PATH];
809 HKEY hRootKey, hKey;
810 BOOL bRelative = TRUE;
811 DWORD dwType, dwDisp, dwPathLen = MAX_PATH;
812
813 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
814
815 /* build default values */
816 switch(csidl)
817 {
818 case CSIDL_APPDATA:
819 hRootKey = HKEY_CURRENT_USER;
820 strcpy (szValueName, "AppData");
821 strcpy (szDefaultPath, "AppData");
822 break;
823
824 case CSIDL_COOKIES:
825 hRootKey = HKEY_CURRENT_USER;
826 strcpy (szValueName, "Cookies");
827 strcpy(szDefaultPath, "Cookies");
828 break;
829
830 case CSIDL_DESKTOPDIRECTORY:
831 hRootKey = HKEY_CURRENT_USER;
832 strcpy(szValueName, "Desktop");
833 strcpy(szDefaultPath, "Desktop");
834 break;
835
836 case CSIDL_COMMON_DESKTOPDIRECTORY:
837 hRootKey = HKEY_LOCAL_MACHINE;
838 strcpy(szValueName, "Common Desktop");
839 strcpy(szDefaultPath, "Desktop");
840 break;
841
842 case CSIDL_FAVORITES:
843 hRootKey = HKEY_CURRENT_USER;
844 strcpy(szValueName, "Favorites");
845 strcpy(szDefaultPath, "Favorites");
846 break;
847
848 case CSIDL_FONTS:
849 hRootKey = HKEY_CURRENT_USER;
850 strcpy(szValueName, "Fonts");
851 strcpy(szDefaultPath, "Fonts");
852 break;
853
854 case CSIDL_HISTORY:
855 hRootKey = HKEY_CURRENT_USER;
856 strcpy(szValueName, "History");
857 strcpy(szDefaultPath, "History");
858 break;
859
860 case CSIDL_NETHOOD:
861 hRootKey = HKEY_CURRENT_USER;
862 strcpy(szValueName, "NetHood");
863 strcpy(szDefaultPath, "NetHood");
864 break;
865
866 case CSIDL_INTERNET_CACHE:
867 hRootKey = HKEY_CURRENT_USER;
868 strcpy(szValueName, "Cache");
869 strcpy(szDefaultPath, "Temporary Internet Files");
870 break;
871
872 case CSIDL_PERSONAL:
873 hRootKey = HKEY_CURRENT_USER;
874 strcpy(szValueName, "Personal");
875 strcpy(szDefaultPath, "My Own Files");
876 bRelative = FALSE;
877 break;
878
879 case CSIDL_PRINTHOOD:
880 hRootKey = HKEY_CURRENT_USER;
881 strcpy(szValueName, "PrintHood");
882 strcpy(szDefaultPath, "PrintHood");
883 break;
884
885 case CSIDL_PROGRAMS:
886 hRootKey = HKEY_CURRENT_USER;
887 strcpy(szValueName, "Programs");
888 strcpy(szDefaultPath, "StatrMenu\\Programs");
889 break;
890
891 case CSIDL_COMMON_PROGRAMS:
892 hRootKey = HKEY_LOCAL_MACHINE;
893 strcpy(szValueName, "Common Programs");
894 strcpy(szDefaultPath, "");
895 break;
896
897 case CSIDL_RECENT:
898 hRootKey = HKEY_CURRENT_USER;
899 strcpy(szValueName, "Recent");
900 strcpy(szDefaultPath, "Recent");
901 break;
902
903 case CSIDL_SENDTO:
904 hRootKey = HKEY_CURRENT_USER;
905 strcpy(szValueName, "SendTo");
906 strcpy(szDefaultPath, "SendTo");
907 break;
908
909 case CSIDL_STARTMENU:
910 hRootKey = HKEY_CURRENT_USER;
911 strcpy(szValueName, "StartMenu");
912 strcpy(szDefaultPath, "StartMenu");
913 break;
914
915 case CSIDL_COMMON_STARTMENU:
916 hRootKey = HKEY_LOCAL_MACHINE;
917 strcpy(szValueName, "Common StartMenu");
918 strcpy(szDefaultPath, "StartMenu");
919 break;
920
921 case CSIDL_STARTUP:
922 hRootKey = HKEY_CURRENT_USER;
923 strcpy(szValueName, "Startup");
924 strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
925 break;
926
927 case CSIDL_COMMON_STARTUP:
928 hRootKey = HKEY_LOCAL_MACHINE;
929 strcpy(szValueName, "Common Startup");
930 strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
931 break;
932
933 case CSIDL_TEMPLATES:
934 hRootKey = HKEY_CURRENT_USER;
935 strcpy(szValueName, "Templates");
936 strcpy(szDefaultPath, "ShellNew");
937 break;
938
939 default:
940 ERR("folder unknown or not allowed\n");
941 return FALSE;
942 }
943
944 if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hKey,&dwDisp))
945 {
946 return FALSE;
947 }
948
949 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
950 {
951 /* value not existing */
952 if (bRelative)
953 {
954 GetWindowsDirectoryA(szPath, MAX_PATH);
955 PathAddBackslashA(szPath);
956 strcat(szPath, szDefaultPath);
957 }
958 else
959 {
960 strcpy(szPath, szDefaultPath);
961 }
962 if (bCreate)
963 {
964 CreateDirectoryA(szPath,NULL);
965 }
966 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
967 }
968 RegCloseKey(hKey);
969
970 return TRUE;
971}
972BOOL WINAPI SHGetSpecialFolderPathW (
973 HWND hwndOwner,
974 LPWSTR szPath,
975 DWORD csidl,
976 BOOL bCreate)
977{
978 char szTemp[MAX_PATH];
979
980 if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate))
981 {
982 lstrcpynAtoW(szPath, szTemp, MAX_PATH);
983 }
984
985 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
986
987 return TRUE;
988}
989BOOL WINAPI SHGetSpecialFolderPathAW (
990 HWND hwndOwner,
991 LPVOID szPath,
992 DWORD csidl,
993 BOOL bCreate)
994
995{
996 if (VERSION_OsIsUnicode())
997 return SHGetSpecialFolderPathW (hwndOwner, (LPWSTR)szPath, csidl, bCreate);
998 return SHGetSpecialFolderPathA (hwndOwner, (LPSTR)szPath, csidl, bCreate);
999}
Note: See TracBrowser for help on using the repository browser.