Implemented SHCreateShellFolderViewEx.
[wine.git] / dlls / shell32 / shellpath.c
blobb75297f7302f409f3b421aea044512b9e0291390
1 /*
2 * Path Functions
4 * Many of this functions are in SHLWAPI.DLL also
6 */
7 #include <string.h>
8 #include <ctype.h>
9 #include "debugtools.h"
10 #include "winnls.h"
11 #include "winversion.h"
13 #include "shlobj.h"
14 #include "shell32_main.h"
16 DEFAULT_DEBUG_CHANNEL(shell)
18 /*************************************************************************
19 * PathIsRoot [SHELL32.29]
21 BOOL WINAPI PathIsRootA(LPCSTR x)
22 { TRACE("%s\n",x);
23 if (*(x+1)==':' && *(x+2)=='\\') /* "X:\" */
24 return 1;
25 if (*x=='\\') /* "\" */
26 return 0;
27 if (x[0]=='\\' && x[1]=='\\') /* UNC "\\<xx>\" */
28 { int foundbackslash = 0;
29 x=x+2;
30 while (*x)
31 { if (*x++=='\\')
32 foundbackslash++;
34 if (foundbackslash<=1) /* max 1 \ more ... */
35 return 1;
37 return 0;
39 BOOL WINAPI PathIsRootW(LPCWSTR x)
40 { TRACE("%s\n",debugstr_w(x));
41 if (*(x+1)==':' && *(x+2)=='\\') /* "X:\" */
42 return 1;
43 if (*x == (WCHAR) '\\') /* "\" */
44 return 0;
45 if (x[0]==(WCHAR)'\\' && x[1]==(WCHAR)'\\') /* UNC "\\<xx>\" */
46 { int foundbackslash = 0;
47 x=x+2;
48 while (*x)
49 { if (*x++==(WCHAR)'\\')
50 foundbackslash++;
52 if (foundbackslash<=1) /* max 1 \ more ... */
53 return 1;
55 return 0;
57 BOOL WINAPI PathIsRootAW(LPCVOID x)
58 { if (VERSION_OsIsUnicode())
59 return PathIsRootW(x);
60 return PathIsRootA(x);
63 /*************************************************************************
64 * PathBuildRoot [SHELL32.30]
66 LPSTR WINAPI PathBuildRootA(LPSTR root,BYTE drive) {
67 TRACE("%p %i\n",root, drive);
68 strcpy(root,"A:\\");
69 root[0]+=drive;
70 return root;
73 /*************************************************************************
74 * PathFindExtension [SHELL32.31]
76 * NOTES
77 * returns pointer to last . in last pathcomponent or at \0.
79 LPCSTR WINAPI PathFindExtensionA(LPCSTR path)
80 { LPCSTR lastpoint = NULL;
81 TRACE("%p %s\n",path,path);
82 while (*path)
83 { if (*path=='\\'||*path==' ')
84 lastpoint=NULL;
85 if (*path=='.')
86 lastpoint=path;
87 path++;
89 return lastpoint?lastpoint:path;
91 LPCWSTR WINAPI PathFindExtensionW(LPCWSTR path)
92 { LPCWSTR lastpoint = NULL;
93 TRACE("%p L%s\n",path,debugstr_w(path));
94 while (*path)
95 { if (*path==(WCHAR)'\\'||*path==(WCHAR)' ')
96 lastpoint=NULL;
97 if (*path==(WCHAR)'.')
98 lastpoint=path;
99 path++;
101 return lastpoint?lastpoint:path;
103 LPCVOID WINAPI PathFindExtensionAW(LPCVOID path)
104 { if (VERSION_OsIsUnicode())
105 return PathFindExtensionW(path);
106 return PathFindExtensionA(path);
110 /*************************************************************************
111 * PathAddBackslash [SHELL32.32]
113 * NOTES
114 * append \ if there is none
116 LPSTR WINAPI PathAddBackslashA(LPSTR path)
117 { int len;
118 TRACE("%p->%s\n",path,path);
120 len = strlen(path);
121 if (len && path[len-1]!='\\')
122 { path[len] = '\\';
123 path[len+1]= 0x00;
124 return path+len+1;
126 return path+len;
128 LPWSTR WINAPI PathAddBackslashW(LPWSTR path)
129 { int len;
130 TRACE("%p->%s\n",path,debugstr_w(path));
132 len = lstrlenW(path);
133 if (len && path[len-1]!=(WCHAR)'\\')
134 { path[len] = (WCHAR)'\\';
135 path[len+1]= 0x00;
136 return path+len+1;
138 return path+len;
140 LPVOID WINAPI PathAddBackslashAW(LPVOID path)
141 { if(VERSION_OsIsUnicode())
142 return PathAddBackslashW(path);
143 return PathAddBackslashA(path);
146 /*************************************************************************
147 * PathRemoveBlanks [SHELL32.33]
149 * NOTES
150 * remove spaces from beginning and end of passed string
152 LPSTR WINAPI PathRemoveBlanksA(LPSTR str)
153 { LPSTR x = str;
154 TRACE("%s\n",str);
155 while (*x==' ') x++;
156 if (x!=str)
157 strcpy(str,x);
158 if (!*str)
159 return str;
160 x=str+strlen(str)-1;
161 while (*x==' ')
162 x--;
163 if (*x==' ')
164 *x='\0';
165 return x;
167 LPWSTR WINAPI PathRemoveBlanksW(LPWSTR str)
168 { LPWSTR x = str;
169 TRACE("%s\n",debugstr_w(str));
170 while (*x==' ') x++;
171 if (x!=str)
172 lstrcpyW(str,x);
173 if (!*str)
174 return str;
175 x=str+lstrlenW(str)-1;
176 while (*x==' ')
177 x--;
178 if (*x==' ')
179 *x='\0';
180 return x;
182 LPVOID WINAPI PathRemoveBlanksAW(LPVOID str)
183 { if(VERSION_OsIsUnicode())
184 return PathRemoveBlanksW(str);
185 return PathRemoveBlanksA(str);
190 /*************************************************************************
191 * PathFindFilename [SHELL32.34]
193 * NOTES
194 * basename(char *fn);
196 LPCSTR WINAPI PathFindFilenameA(LPCSTR aptr)
197 { LPCSTR aslash;
198 aslash = aptr;
200 TRACE("%s\n",aslash);
201 while (aptr[0])
202 { if (((aptr[0]=='\\') || (aptr[0]==':')) && aptr[1] && aptr[1]!='\\')
203 aslash = aptr+1;
204 aptr++;
206 return aslash;
209 LPCWSTR WINAPI PathFindFilenameW(LPCWSTR wptr)
210 { LPCWSTR wslash;
211 wslash = wptr;
213 TRACE("L%s\n",debugstr_w(wslash));
214 while (wptr[0])
215 { if (((wptr[0]=='\\') || (wptr[0]==':')) && wptr[1] && wptr[1]!='\\')
216 wslash = wptr+1;
217 wptr++;
219 return wslash;
221 LPCVOID WINAPI PathFindFilenameAW(LPCVOID fn)
223 if(VERSION_OsIsUnicode())
224 return PathFindFilenameW(fn);
225 return PathFindFilenameA(fn);
228 /*************************************************************************
229 * PathRemoveFileSpec [SHELL32.35]
231 * NOTES
232 * bool getpath(char *pathname); truncates passed argument to a valid path
233 * returns if the string was modified or not.
234 * "\foo\xx\foo"-> "\foo\xx"
235 * "\" -> "\"
236 * "a:\foo" -> "a:\"
238 DWORD WINAPI PathRemoveFileSpecA(LPSTR fn) {
239 LPSTR x,cutplace;
240 TRACE("%s\n",fn);
241 if (!fn[0])
242 return 0;
243 x=fn;
244 cutplace = fn;
245 while (*x) {
246 if (*x=='\\') {
247 cutplace=x++;
248 continue;
250 if (*x==':') {
251 x++;
252 if (*x=='\\')
253 cutplace=++x;
254 continue; /* already x++ed */
256 x++;
258 if (!*cutplace)
259 return 0;
260 if (cutplace==fn) {
261 if (fn[0]=='\\') {
262 if (!fn[1])
263 return 0;
264 fn[0]='\0';
265 return 1;
268 *cutplace='\0';
269 return 1;
272 /*************************************************************************
273 * PathAppend [SHELL32.36]
275 * NOTES
276 * concat_paths(char*target,const char*add);
277 * concats "target\\add" and writes them to target
279 LPSTR WINAPI PathAppendA(LPSTR x1,LPSTR x2) {
280 TRACE("%s %s\n",x1,x2);
281 while (x2[0]=='\\') x2++;
282 return PathCombineA(x1,x1,x2);
285 /*************************************************************************
286 * PathCombine [SHELL32.37]
288 * NOTES
289 * if lpszFile='.' skip it
290 * szDest can be equal to lpszFile. Thats why we use sTemp
292 LPSTR WINAPI PathCombineA(LPSTR szDest, LPCSTR lpszDir, LPCSTR lpszFile)
293 { char sTemp[MAX_PATH];
294 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, lpszDir, lpszFile, lpszFile);
297 if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
298 { strcpy(szDest,lpszDir);
299 return szDest;
302 /* if lpszFile is a complete path don't care about lpszDir */
303 if (PathIsRootA(lpszFile))
304 { strcpy(szDest,lpszFile);
306 else
307 { strcpy(sTemp,lpszDir);
308 PathAddBackslashA(sTemp);
309 strcat(sTemp,lpszFile);
310 strcpy(szDest,sTemp);
312 return szDest;
314 LPWSTR WINAPI PathCombineW(LPWSTR szDest, LPCWSTR lpszDir, LPCWSTR lpszFile)
315 { WCHAR sTemp[MAX_PATH];
316 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, debugstr_w(lpszDir),
317 lpszFile, debugstr_w(lpszFile));
320 if (!lpszFile || !lpszFile[0] || (lpszFile[0]==(WCHAR)'.' && !lpszFile[1]) )
321 { lstrcpyW(szDest,lpszDir);
322 return szDest;
325 /* if lpszFile is a complete path don't care about lpszDir */
326 if (PathIsRootW(lpszFile))
327 { lstrcpyW(szDest,lpszFile);
329 else
330 { lstrcpyW(sTemp,lpszDir);
331 PathAddBackslashW(sTemp);
332 lstrcatW(sTemp,lpszFile);
333 lstrcpyW(szDest,sTemp);
335 return szDest;
337 LPVOID WINAPI PathCombineAW(LPVOID szDest, LPCVOID lpszDir, LPCVOID lpszFile)
338 { if (VERSION_OsIsUnicode())
339 return PathCombineW( szDest, lpszDir, lpszFile );
340 return PathCombineA( szDest, lpszDir, lpszFile );
343 /*************************************************************************
344 * PathIsUNC [SHELL32.39]
346 * NOTES
347 * PathIsUNC(char*path);
349 BOOL WINAPI PathIsUNCA(LPCSTR path)
350 { TRACE("%s\n",path);
352 if ((path[0]=='\\') && (path[1]=='\\'))
353 return TRUE;
354 return FALSE;
356 BOOL WINAPI PathIsUNCW(LPCWSTR path)
357 { TRACE("%s\n",debugstr_w(path));
359 if ((path[0]=='\\') && (path[1]=='\\'))
360 return TRUE;
361 return FALSE;
363 BOOL WINAPI PathIsUNCAW (LPCVOID path)
364 { if (VERSION_OsIsUnicode())
365 return PathIsUNCW( path );
366 return PathIsUNCA( path );
368 /*************************************************************************
369 * PathIsRelativ [SHELL32.40]
372 BOOL WINAPI PathIsRelativeA (LPCSTR path)
373 { TRACE("path=%s\n",path);
375 if (path && (path[0]!='\\' && path[1]==':'))
376 return TRUE;
377 return FALSE;
379 BOOL WINAPI PathIsRelativeW (LPCWSTR path)
380 { TRACE("path=%s\n",debugstr_w(path));
382 if (path && (path[0]!='\\' && path[1]==':'))
383 return TRUE;
384 return FALSE;
386 BOOL WINAPI PathIsRelativeAW (LPCVOID path)
387 { if (VERSION_OsIsUnicode())
388 return PathIsRelativeW( path );
389 return PathIsRelativeA( path );
391 /*************************************************************************
392 * PathIsExe [SHELL32.43]
395 BOOL WINAPI PathIsExeA (LPCSTR path)
396 { FIXME("path=%s\n",path);
397 return FALSE;
399 BOOL WINAPI PathIsExeW (LPCWSTR path)
400 { FIXME("path=%s\n",debugstr_w(path));
401 return FALSE;
403 BOOL WINAPI PathIsExeAW (LPCVOID path)
404 { if (VERSION_OsIsUnicode())
405 return PathIsExeW (path);
406 return PathIsExeA(path);
409 /*************************************************************************
410 * PathFileExists [SHELL32.45]
412 * NOTES
413 * file_exists(char *fn);
415 BOOL WINAPI PathFileExistsA(LPSTR fn) {
416 TRACE("%s\n",fn);
417 if (GetFileAttributesA(fn)==-1)
418 return FALSE;
419 else
420 return TRUE;
422 /*************************************************************************
423 * PathMatchSpec [SHELL32.46]
425 * NOTES
426 * used from COMDLG32
429 BOOL WINAPI PathMatchSpecA(LPCSTR name, LPCSTR mask)
430 { LPCSTR _name;
432 TRACE("%s %s stub\n",name,mask);
434 _name = name;
435 while (*_name && *mask)
436 { if (*mask ==';')
437 { mask++;
438 _name = name;
440 else if (*mask == '*')
441 { mask++;
442 while (*mask == '*') mask++; /* Skip consecutive '*' */
443 if (!*mask || *mask==';') return TRUE; /* '*' matches everything */
444 while (*_name && (toupper(*_name) != toupper(*mask))) _name++;
445 if (!*_name)
446 { while ( *mask && *mask != ';') mask++;
447 _name = name;
450 else if ( (*mask == '?') || (toupper(*mask) == toupper(*_name)) )
451 { mask++;
452 _name++;
454 else
455 { while ( *mask && *mask != ';') mask++;
458 return (!*_name && (!*mask || *mask==';'));
460 BOOL WINAPI PathMatchSpecW(LPCWSTR name, LPCWSTR mask)
461 { WCHAR stemp[4];
462 LPCWSTR _name;
464 TRACE("%s %s stub\n",debugstr_w(name),debugstr_w(mask));
466 lstrcpyAtoW(stemp,"*.*");
467 if (!lstrcmpW( mask, stemp )) return 1;
469 _name = name;
470 while (*_name && *mask)
471 { if (*mask ==';')
472 { mask++;
473 _name = name;
475 else if (*mask == '*')
476 { mask++;
477 while (*mask == '*') mask++; /* Skip consecutive '*' */
478 if (!*mask || *mask==';') return TRUE; /* '*' matches everything */
479 while (*_name && (towupper(*_name) != towupper(*mask))) _name++;
480 if (!*_name)
481 { while ( *mask && *mask != ';') mask++;
482 _name = name;
485 else if ( (*mask == '?') || (towupper(*mask) == towupper(*_name)) )
486 { mask++;
487 _name++;
489 else
490 { while ( *mask && *mask != ';') mask++;
493 return (!*_name && (!*mask || *mask==';'));
495 BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
496 { if (VERSION_OsIsUnicode())
497 return PathMatchSpecW( name, mask );
498 return PathMatchSpecA( name, mask );
500 /*************************************************************************
501 * PathSetDlgItemPathAW [SHELL32.48]
502 * NOTES
503 * use PathCompactPath to make sure, the path fits into the control
506 BOOL WINAPI PathSetDlgItemPathA(HWND hDlg, int id, LPCSTR pszPath)
507 { TRACE("%x %x %s\n",hDlg, id, pszPath);
508 return SetDlgItemTextA(hDlg, id, pszPath);
510 BOOL WINAPI PathSetDlgItemPathW(HWND hDlg, int id, LPCWSTR pszPath)
511 { TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
512 return SetDlgItemTextW(hDlg, id, pszPath);
514 BOOL WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
515 { if (VERSION_OsIsUnicode())
516 return PathSetDlgItemPathW(hDlg, id, pszPath);
517 return PathSetDlgItemPathA(hDlg, id, pszPath);
520 /*************************************************************************
521 * PathQualifyAW [SHELL32.49]
524 BOOL WINAPI PathQualifyA(LPCSTR pszPath)
525 { TRACE("%s\n",pszPath);
526 return 0;
528 BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
529 { TRACE("%s\n",debugstr_w(pszPath));
530 return 0;
532 BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
533 { if (VERSION_OsIsUnicode())
534 return PathQualifyW(pszPath);
535 return PathQualifyA(pszPath);
538 /*************************************************************************
539 * PathResolve [SHELL32.51]
541 DWORD WINAPI PathResolve(LPCSTR s,DWORD x2,DWORD x3) {
542 FIXME("(%s,0x%08lx,0x%08lx),stub!\n",s,x2,x3);
543 return 0;
546 /*************************************************************************
547 * PathGetArgs [SHELL32.52]
549 * NOTES
550 * look for next arg in string. handle "quoted" strings
551 * returns pointer to argument *AFTER* the space. Or to the \0.
553 LPCSTR WINAPI PathGetArgsA(LPCSTR cmdline)
554 { BOOL qflag = FALSE;
556 TRACE("%s\n",cmdline);
558 while (*cmdline)
559 { if ((*cmdline==' ') && !qflag)
560 return cmdline+1;
561 if (*cmdline=='"')
562 qflag=!qflag;
563 cmdline++;
565 return cmdline;
568 LPCWSTR WINAPI PathGetArgsW(LPCWSTR cmdline)
569 { BOOL qflag = FALSE;
571 TRACE("%sL\n",debugstr_w(cmdline));
573 while (*cmdline)
574 { if ((*cmdline==' ') && !qflag)
575 return cmdline+1;
576 if (*cmdline=='"')
577 qflag=!qflag;
578 cmdline++;
580 return cmdline;
582 LPCVOID WINAPI PathGetArgsAW(LPVOID cmdline)
583 { if (VERSION_OsIsUnicode())
584 return PathGetArgsW(cmdline);
585 return PathGetArgsA(cmdline);
587 /*************************************************************************
588 * PathQuoteSpaces [SHELL32.55]
590 * NOTES
591 * basename(char *fn);
593 LPSTR WINAPI PathQuoteSpacesA(LPCSTR aptr)
594 { FIXME("%s\n",aptr);
595 return 0;
598 LPWSTR WINAPI PathQuoteSpacesW(LPCWSTR wptr)
599 { FIXME("L%s\n",debugstr_w(wptr));
600 return 0;
602 LPVOID WINAPI PathQuoteSpacesAW (LPCVOID fn)
603 { if(VERSION_OsIsUnicode())
604 return PathQuoteSpacesW(fn);
605 return PathQuoteSpacesA(fn);
609 /*************************************************************************
610 * PathUnquoteSpaces [SHELL32.56]
612 * NOTES
613 * unquote string (remove ")
615 VOID WINAPI PathUnquoteSpacesA(LPSTR str)
616 { DWORD len = lstrlenA(str);
617 TRACE("%s\n",str);
618 if (*str!='"')
619 return;
620 if (str[len-1]!='"')
621 return;
622 str[len-1]='\0';
623 lstrcpyA(str,str+1);
624 return;
626 VOID WINAPI PathUnquoteSpacesW(LPWSTR str)
627 { DWORD len = lstrlenW(str);
629 TRACE("%s\n",debugstr_w(str));
631 if (*str!='"')
632 return;
633 if (str[len-1]!='"')
634 return;
635 str[len-1]='\0';
636 lstrcpyW(str,str+1);
637 return;
639 VOID WINAPI PathUnquoteSpacesAW(LPVOID str)
640 { if(VERSION_OsIsUnicode())
641 PathUnquoteSpacesW(str);
642 PathUnquoteSpacesA(str);
646 /*************************************************************************
647 * PathGetDriveNumber32 [SHELL32.57]
650 HRESULT WINAPI PathGetDriveNumber(LPSTR u)
651 { FIXME("%s stub\n",debugstr_a(u));
652 return 0;
655 /*************************************************************************
656 * PathYetAnotherMakeUniqueName [SHELL32.75]
658 * NOTES
659 * exported by ordinal
661 BOOL WINAPI PathYetAnotherMakeUniqueNameA(LPDWORD x,LPDWORD y) {
662 FIXME("(%p,%p):stub.\n",x,y);
663 return TRUE;
666 /*************************************************************************
667 * IsLFNDrive [SHELL32.119]
669 * NOTES
670 * exported by ordinal Name
672 BOOL WINAPI IsLFNDriveA(LPCSTR path) {
673 DWORD fnlen;
675 if (!GetVolumeInformationA(path,NULL,0,NULL,&fnlen,NULL,NULL,0))
676 return FALSE;
677 return fnlen>12;
679 /*************************************************************************
680 * PathFindOnPath [SHELL32.145]
682 BOOL WINAPI PathFindOnPathA(LPSTR sFile, LPCSTR sOtherDirs)
683 { FIXME("%s %s\n",sFile, sOtherDirs);
684 return FALSE;
686 BOOL WINAPI PathFindOnPathW(LPWSTR sFile, LPCWSTR sOtherDirs)
687 { FIXME("%s %s\n",debugstr_w(sFile), debugstr_w(sOtherDirs));
688 return FALSE;
690 BOOL WINAPI PathFindOnPathAW(LPVOID sFile, LPCVOID sOtherDirs)
691 { if (VERSION_OsIsUnicode())
692 return PathFindOnPathW(sFile, sOtherDirs);
693 return PathFindOnPathA(sFile, sOtherDirs);
696 /*************************************************************************
697 * PathGetExtension [SHELL32.158]
699 * NOTES
700 * exported by ordinal
702 LPCSTR WINAPI PathGetExtensionA(LPCSTR path,DWORD y,DWORD z)
703 { TRACE("(%s,%08lx,%08lx)\n",path,y,z);
704 path = PathFindExtensionA(path);
705 return *path?(path+1):path;
707 LPCWSTR WINAPI PathGetExtensionW(LPCWSTR path,DWORD y,DWORD z)
708 { TRACE("(L%s,%08lx,%08lx)\n",debugstr_w(path),y,z);
709 path = PathFindExtensionW(path);
710 return *path?(path+1):path;
712 LPCVOID WINAPI PathGetExtensionAW(LPCVOID path,DWORD y,DWORD z)
713 { if (VERSION_OsIsUnicode())
714 return PathGetExtensionW(path,y,z);
715 return PathGetExtensionA(path,y,z);
718 /*************************************************************************
719 * SheGetDirW [SHELL32.281]
722 HRESULT WINAPI SheGetDirW(LPWSTR u, LPWSTR v)
723 { FIXME("%p %p stub\n",u,v);
724 return 0;
727 /*************************************************************************
728 * SheChangeDirW [SHELL32.274]
731 HRESULT WINAPI SheChangeDirW(LPWSTR u)
732 { FIXME("(%s),stub\n",debugstr_w(u));
733 return 0;
736 /*************************************************************************
737 * PathProcessCommand [SHELL32.653]
739 HRESULT WINAPI PathProcessCommandA (LPSTR lpCommand, LPSTR v, DWORD w, DWORD x)
741 FIXME("%p(%s) %p 0x%04lx 0x%04lx stub\n",
742 lpCommand, lpCommand, v, w,x );
743 return 0;
746 HRESULT WINAPI PathProcessCommandW (LPWSTR lpCommand, LPSTR v, DWORD w, DWORD x)
748 FIXME("%p(%s) %p 0x%04lx 0x%04lx stub\n",
749 lpCommand, debugstr_w(lpCommand), v, w,x );
750 return 0;
753 HRESULT WINAPI PathProcessCommandAW (LPVOID lpCommand, LPSTR v, DWORD w, DWORD x)
755 if (VERSION_OsIsUnicode())
756 return PathProcessCommandW(lpCommand, v, w, x);
757 return PathProcessCommandA(lpCommand, v, w, x);
760 /*************************************************************************
761 * SHGetSpecialFolderPath [SHELL32.175]
763 * converts csidl to path
766 BOOL WINAPI SHGetSpecialFolderPathA (DWORD x1,LPSTR szPath,DWORD csidl,DWORD x4)
767 { LPITEMIDLIST pidl;
769 WARN("(0x%04lx,%p,csidl=%lu,0x%04lx) semi-stub\n", x1,szPath,csidl,x4);
771 SHGetSpecialFolderLocation(0, csidl, &pidl);
772 SHGetPathFromIDListA (pidl, szPath);
773 SHFree (pidl);
774 return TRUE;
776 BOOL WINAPI SHGetSpecialFolderPathW (DWORD x1,LPWSTR szPath, DWORD csidl,DWORD x4)
777 { LPITEMIDLIST pidl;
779 WARN("(0x%04lx,%p,csidl=%lu,0x%04lx) semi-stub\n", x1,szPath,csidl,x4);
781 SHGetSpecialFolderLocation(0, csidl, &pidl);
782 SHGetPathFromIDListW (pidl, szPath);
783 SHFree (pidl);
784 return TRUE;
786 BOOL WINAPI SHGetSpecialFolderPath (DWORD x1,LPVOID szPath,DWORD csidl,DWORD x4)
787 { if (VERSION_OsIsUnicode())
788 return SHGetSpecialFolderPathW ( x1, szPath, csidl, x4);
789 return SHGetSpecialFolderPathA ( x1, szPath, csidl, x4);