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

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

Added $Id$

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