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

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

Fix: updated to current wine 19990913

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