Stub PathIsDirectory.
[wine.git] / dlls / shell32 / shellpath.c
blob7fb63c0d7f1b51f74245c481cc4383a3ff3c7832
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"
12 #include "winreg.h"
13 #include "crtdll.h"
14 #include "tchar.h"
16 #include "shlobj.h"
17 #include "shell32_main.h"
18 #include "windef.h"
19 #include "options.h"
21 DEFAULT_DEBUG_CHANNEL(shell)
23 /* Supported protocols for PathIsURL */
24 LPSTR SupportedProtocol[] = {"http","https","ftp","gopher","file","mailto",""};
26 /*************************************************************************
27 * PathIsRoot [SHELL32.29]
29 BOOL WINAPI PathIsRootA(LPCSTR x)
30 { TRACE("%s\n",x);
31 if (*(x+1)==':' && *(x+2)=='\\') /* "X:\" */
32 return 1;
33 if (*x=='\\') /* "\" */
34 return 0;
35 if (x[0]=='\\' && x[1]=='\\') /* UNC "\\<xx>\" */
36 { int foundbackslash = 0;
37 x=x+2;
38 while (*x)
39 { if (*x++=='\\')
40 foundbackslash++;
42 if (foundbackslash<=1) /* max 1 \ more ... */
43 return 1;
45 return 0;
47 BOOL WINAPI PathIsRootW(LPCWSTR x)
48 { TRACE("%s\n",debugstr_w(x));
49 if (*(x+1)==':' && *(x+2)=='\\') /* "X:\" */
50 return 1;
51 if (*x == (WCHAR) '\\') /* "\" */
52 return 0;
53 if (x[0]==(WCHAR)'\\' && x[1]==(WCHAR)'\\') /* UNC "\\<xx>\" */
54 { int foundbackslash = 0;
55 x=x+2;
56 while (*x)
57 { if (*x++==(WCHAR)'\\')
58 foundbackslash++;
60 if (foundbackslash<=1) /* max 1 \ more ... */
61 return 1;
63 return 0;
65 BOOL WINAPI PathIsRootAW(LPCVOID x)
66 { if (VERSION_OsIsUnicode())
67 return PathIsRootW(x);
68 return PathIsRootA(x);
71 /*************************************************************************
72 * PathBuildRoot [SHELL32.30]
74 LPSTR WINAPI PathBuildRootA(LPSTR root,BYTE drive) {
75 TRACE("%p %i\n",root, drive);
76 strcpy(root,"A:\\");
77 root[0]+=drive;
78 return root;
81 /*************************************************************************
82 * PathFindExtension [SHELL32.31]
84 * NOTES
85 * returns pointer to last . in last pathcomponent or at \0.
87 LPCSTR WINAPI PathFindExtensionA(LPCSTR path)
88 { LPCSTR lastpoint = NULL;
89 TRACE("%p %s\n",path,path);
90 while (*path)
91 { if (*path=='\\'||*path==' ')
92 lastpoint=NULL;
93 if (*path=='.')
94 lastpoint=path;
95 path++;
97 return lastpoint?lastpoint:path;
99 LPCWSTR WINAPI PathFindExtensionW(LPCWSTR path)
100 { LPCWSTR lastpoint = NULL;
101 TRACE("(%p %s)\n",path,debugstr_w(path));
102 while (*path)
103 { if (*path==(WCHAR)'\\'||*path==(WCHAR)' ')
104 lastpoint=NULL;
105 if (*path==(WCHAR)'.')
106 lastpoint=path;
107 path++;
109 return lastpoint?lastpoint:path;
111 LPCVOID WINAPI PathFindExtensionAW(LPCVOID path)
112 { if (VERSION_OsIsUnicode())
113 return PathFindExtensionW(path);
114 return PathFindExtensionA(path);
118 /*************************************************************************
119 * PathAddBackslash [SHELL32.32]
121 * NOTES
122 * append \ if there is none
124 LPSTR WINAPI PathAddBackslashA(LPSTR path)
125 { int len;
126 TRACE("%p->%s\n",path,path);
128 len = strlen(path);
129 if (len && path[len-1]!='\\')
130 { path[len] = '\\';
131 path[len+1]= 0x00;
132 return path+len+1;
134 return path+len;
136 LPWSTR WINAPI PathAddBackslashW(LPWSTR path)
137 { int len;
138 TRACE("%p->%s\n",path,debugstr_w(path));
140 len = CRTDLL_wcslen(path);
141 if (len && path[len-1]!=(WCHAR)'\\')
142 { path[len] = (WCHAR)'\\';
143 path[len+1]= 0x00;
144 return path+len+1;
146 return path+len;
148 LPVOID WINAPI PathAddBackslashAW(LPVOID path)
149 { if(VERSION_OsIsUnicode())
150 return PathAddBackslashW(path);
151 return PathAddBackslashA(path);
154 /*************************************************************************
155 * PathRemoveBlanks [SHELL32.33]
157 * NOTES
158 * remove spaces from beginning and end of passed string
160 LPSTR WINAPI PathRemoveBlanksA(LPSTR str)
161 { LPSTR x = str;
162 TRACE("%s\n",str);
163 while (*x==' ') x++;
164 if (x!=str)
165 strcpy(str,x);
166 if (!*str)
167 return str;
168 x=str+strlen(str)-1;
169 while (*x==' ')
170 x--;
171 if (*x==' ')
172 *x='\0';
173 return x;
175 LPWSTR WINAPI PathRemoveBlanksW(LPWSTR str)
176 { LPWSTR x = str;
177 TRACE("%s\n",debugstr_w(str));
178 while (*x==' ') x++;
179 if (x!=str)
180 CRTDLL_wcscpy(str,x);
181 if (!*str)
182 return str;
183 x=str+CRTDLL_wcslen(str)-1;
184 while (*x==' ')
185 x--;
186 if (*x==' ')
187 *x='\0';
188 return x;
190 LPVOID WINAPI PathRemoveBlanksAW(LPVOID str)
191 { if(VERSION_OsIsUnicode())
192 return PathRemoveBlanksW(str);
193 return PathRemoveBlanksA(str);
198 /*************************************************************************
199 * PathFindFilename [SHELL32.34]
201 * NOTES
202 * basename(char *fn);
204 LPCSTR WINAPI PathFindFilenameA(LPCSTR aptr)
205 { LPCSTR aslash;
206 aslash = aptr;
208 TRACE("%s\n",aslash);
209 while (aptr[0])
210 { if (((aptr[0]=='\\') || (aptr[0]==':')) && aptr[1] && aptr[1]!='\\')
211 aslash = aptr+1;
212 aptr++;
214 return aslash;
217 LPCWSTR WINAPI PathFindFilenameW(LPCWSTR wptr)
218 { LPCWSTR wslash;
219 wslash = wptr;
221 TRACE("%s\n",debugstr_w(wslash));
222 while (wptr[0])
223 { if (((wptr[0]=='\\') || (wptr[0]==':')) && wptr[1] && wptr[1]!='\\')
224 wslash = wptr+1;
225 wptr++;
227 return wslash;
229 LPCVOID WINAPI PathFindFilenameAW(LPCVOID fn)
231 if(VERSION_OsIsUnicode())
232 return PathFindFilenameW(fn);
233 return PathFindFilenameA(fn);
236 /*************************************************************************
237 * PathRemoveFileSpec [SHELL32.35]
239 * NOTES
240 * bool getpath(char *pathname); truncates passed argument to a valid path
241 * returns if the string was modified or not.
242 * "\foo\xx\foo"-> "\foo\xx"
243 * "\" -> "\"
244 * "a:\foo" -> "a:\"
246 DWORD WINAPI PathRemoveFileSpecA(LPSTR fn) {
247 LPSTR x,cutplace;
248 TRACE("%s\n",fn);
249 if (!fn[0])
250 return 0;
251 x=fn;
252 cutplace = fn;
253 while (*x) {
254 if (*x=='\\') {
255 cutplace=x++;
256 continue;
258 if (*x==':') {
259 x++;
260 if (*x=='\\')
261 cutplace=++x;
262 continue; /* already x++ed */
264 x++;
266 if (!*cutplace)
267 return 0;
268 if (cutplace==fn) {
269 if (fn[0]=='\\') {
270 if (!fn[1])
271 return 0;
272 fn[0]='\0';
273 return 1;
276 *cutplace='\0';
277 return 1;
280 /*************************************************************************
281 * PathAppend [SHELL32.36]
283 * NOTES
284 * concat_paths(char*target,const char*add);
285 * concats "target\\add" and writes them to target
287 LPSTR WINAPI PathAppendA(LPSTR x1,LPSTR x2) {
288 TRACE("%s %s\n",x1,x2);
289 while (x2[0]=='\\') x2++;
290 return PathCombineA(x1,x1,x2);
293 /*************************************************************************
294 * PathCombine [SHELL32.37]
296 * NOTES
297 * if lpszFile='.' skip it
298 * szDest can be equal to lpszFile. Thats why we use sTemp
300 LPSTR WINAPI PathCombineA(LPSTR szDest, LPCSTR lpszDir, LPCSTR lpszFile)
301 { char sTemp[MAX_PATH];
302 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, lpszDir, lpszFile, lpszFile);
305 if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
306 { strcpy(szDest,lpszDir);
307 return szDest;
310 /* if lpszFile is a complete path don't care about lpszDir */
311 if (PathIsRootA(lpszFile))
312 { strcpy(szDest,lpszFile);
314 else
315 { strcpy(sTemp,lpszDir);
316 PathAddBackslashA(sTemp);
317 strcat(sTemp,lpszFile);
318 strcpy(szDest,sTemp);
320 return szDest;
322 LPWSTR WINAPI PathCombineW(LPWSTR szDest, LPCWSTR lpszDir, LPCWSTR lpszFile)
323 { WCHAR sTemp[MAX_PATH];
324 TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, debugstr_w(lpszDir),
325 lpszFile, debugstr_w(lpszFile));
328 if (!lpszFile || !lpszFile[0] || (lpszFile[0]==(WCHAR)'.' && !lpszFile[1]) )
329 { CRTDLL_wcscpy(szDest,lpszDir);
330 return szDest;
333 /* if lpszFile is a complete path don't care about lpszDir */
334 if (PathIsRootW(lpszFile))
335 { CRTDLL_wcscpy(szDest,lpszFile);
337 else
338 { CRTDLL_wcscpy(sTemp,lpszDir);
339 PathAddBackslashW(sTemp);
340 CRTDLL_wcscat(sTemp,lpszFile);
341 CRTDLL_wcscpy(szDest,sTemp);
343 return szDest;
345 LPVOID WINAPI PathCombineAW(LPVOID szDest, LPCVOID lpszDir, LPCVOID lpszFile)
346 { if (VERSION_OsIsUnicode())
347 return PathCombineW( szDest, lpszDir, lpszFile );
348 return PathCombineA( szDest, lpszDir, lpszFile );
351 /*************************************************************************
352 * PathIsUNC [SHELL32.39]
354 * NOTES
355 * PathIsUNC(char*path);
357 BOOL WINAPI PathIsUNCA(LPCSTR path)
358 { TRACE("%s\n",path);
360 if ((path[0]=='\\') && (path[1]=='\\'))
361 return TRUE;
362 return FALSE;
364 BOOL WINAPI PathIsUNCW(LPCWSTR path)
365 { TRACE("%s\n",debugstr_w(path));
367 if ((path[0]=='\\') && (path[1]=='\\'))
368 return TRUE;
369 return FALSE;
371 BOOL WINAPI PathIsUNCAW (LPCVOID path)
372 { if (VERSION_OsIsUnicode())
373 return PathIsUNCW( path );
374 return PathIsUNCA( path );
376 /*************************************************************************
377 * PathIsRelativ [SHELL32.40]
380 BOOL WINAPI PathIsRelativeA (LPCSTR path)
381 { TRACE("path=%s\n",path);
383 if (path && (path[0]!='\\' && path[1]==':'))
384 return TRUE;
385 return FALSE;
387 BOOL WINAPI PathIsRelativeW (LPCWSTR path)
388 { TRACE("path=%s\n",debugstr_w(path));
390 if (path && (path[0]!='\\' && path[1]==':'))
391 return TRUE;
392 return FALSE;
394 BOOL WINAPI PathIsRelativeAW (LPCVOID path)
395 { if (VERSION_OsIsUnicode())
396 return PathIsRelativeW( path );
397 return PathIsRelativeA( path );
399 /*************************************************************************
400 * PathIsExe [SHELL32.43]
403 BOOL WINAPI PathIsExeA (LPCSTR path)
404 { FIXME("path=%s\n",path);
405 return FALSE;
407 BOOL WINAPI PathIsExeW (LPCWSTR path)
408 { FIXME("path=%s\n",debugstr_w(path));
409 return FALSE;
411 BOOL WINAPI PathIsExeAW (LPCVOID path)
412 { if (VERSION_OsIsUnicode())
413 return PathIsExeW (path);
414 return PathIsExeA(path);
417 /*************************************************************************
418 * PathFileExists [SHELL32.45]
420 * NOTES
421 * file_exists(char *fn);
423 BOOL WINAPI PathFileExistsA(LPSTR fn) {
424 TRACE("%s\n",fn);
425 if (GetFileAttributesA(fn)==-1)
426 return FALSE;
427 else
428 return TRUE;
430 /*************************************************************************
431 * PathMatchSingleMask
433 * NOTES
434 * internal (used by PathMatchSpec)
436 static BOOL PathMatchSingleMaskA(LPCSTR name, LPCSTR mask)
438 while (*name && *mask && *mask!=';') {
439 if (*mask=='*') {
440 do {
441 if (PathMatchSingleMaskA(name,mask+1)) return 1; /* try substrings */
442 } while (*name++);
443 return 0;
445 if (toupper(*mask)!=toupper(*name) && *mask!='?') return 0;
446 name++;
447 mask++;
449 if (!*name) {
450 while (*mask=='*') mask++;
451 if (!*mask || *mask==';') return 1;
453 return 0;
455 static BOOL PathMatchSingleMaskW(LPCWSTR name, LPCWSTR mask)
457 while (*name && *mask && *mask!=';') {
458 if (*mask=='*') {
459 do {
460 if (PathMatchSingleMaskW(name,mask+1)) return 1; /* try substrings */
461 } while (*name++);
462 return 0;
464 if (towupper(*mask)!=towupper(*name) && *mask!='?') return 0;
465 name++;
466 mask++;
468 if (!*name) {
469 while (*mask=='*') mask++;
470 if (!*mask || *mask==';') return 1;
472 return 0;
474 /*************************************************************************
475 * PathMatchSpec [SHELL32.46]
477 * NOTES
478 * used from COMDLG32
480 BOOL WINAPI PathMatchSpecA(LPCSTR name, LPCSTR mask)
482 TRACE("%s %s\n",name,mask);
484 if (!lstrcmpA( mask, "*.*" )) return 1; /* we don't require a period */
486 while (*mask) {
487 if (PathMatchSingleMaskA(name,mask)) return 1; /* helper function */
488 while (*mask && *mask!=';') mask++;
489 if (*mask==';') {
490 mask++;
491 while (*mask==' ') mask++; /* masks may be separated by "; " */
494 return 0;
496 BOOL WINAPI PathMatchSpecW(LPCWSTR name, LPCWSTR mask)
498 WCHAR stemp[4];
499 TRACE("%s %s\n",debugstr_w(name),debugstr_w(mask));
501 lstrcpyAtoW(stemp,"*.*");
502 if (!lstrcmpW( mask, stemp )) return 1; /* we don't require a period */
504 while (*mask) {
505 if (PathMatchSingleMaskW(name,mask)) return 1; /* helper function */
506 while (*mask && *mask!=';') mask++;
507 if (*mask==';') {
508 mask++;
509 while (*mask==' ') mask++; /* masks may be separated by "; " */
512 return 0;
514 BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
515 { if (VERSION_OsIsUnicode())
516 return PathMatchSpecW( name, mask );
517 return PathMatchSpecA( name, mask );
519 /*************************************************************************
520 * PathSetDlgItemPathAW [SHELL32.48]
521 * NOTES
522 * use PathCompactPath to make sure, the path fits into the control
525 BOOL WINAPI PathSetDlgItemPathA(HWND hDlg, int id, LPCSTR pszPath)
526 { TRACE("%x %x %s\n",hDlg, id, pszPath);
527 return SetDlgItemTextA(hDlg, id, pszPath);
529 BOOL WINAPI PathSetDlgItemPathW(HWND hDlg, int id, LPCWSTR pszPath)
530 { TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
531 return SetDlgItemTextW(hDlg, id, pszPath);
533 BOOL WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
534 { if (VERSION_OsIsUnicode())
535 return PathSetDlgItemPathW(hDlg, id, pszPath);
536 return PathSetDlgItemPathA(hDlg, id, pszPath);
539 /*************************************************************************
540 * PathQualifyAW [SHELL32.49]
543 BOOL WINAPI PathQualifyA(LPCSTR pszPath)
544 { FIXME("%s\n",pszPath);
545 return 0;
547 BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
548 { FIXME("%s\n",debugstr_w(pszPath));
549 return 0;
551 BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
552 { if (VERSION_OsIsUnicode())
553 return PathQualifyW(pszPath);
554 return PathQualifyA(pszPath);
557 /*************************************************************************
558 * PathResolve [SHELL32.51]
560 DWORD WINAPI PathResolve(LPCSTR s,DWORD x2,DWORD x3) {
561 FIXME("(%s,0x%08lx,0x%08lx),stub!\n",s,x2,x3);
562 return 0;
565 /*************************************************************************
566 * PathGetArgs [SHELL32.52]
568 * NOTES
569 * look for next arg in string. handle "quoted" strings
570 * returns pointer to argument *AFTER* the space. Or to the \0.
572 LPCSTR WINAPI PathGetArgsA(LPCSTR cmdline)
573 { BOOL qflag = FALSE;
575 TRACE("%s\n",cmdline);
577 while (*cmdline)
578 { if ((*cmdline==' ') && !qflag)
579 return cmdline+1;
580 if (*cmdline=='"')
581 qflag=!qflag;
582 cmdline++;
584 return cmdline;
587 LPCWSTR WINAPI PathGetArgsW(LPCWSTR cmdline)
588 { BOOL qflag = FALSE;
590 TRACE("%s\n",debugstr_w(cmdline));
592 while (*cmdline)
593 { if ((*cmdline==' ') && !qflag)
594 return cmdline+1;
595 if (*cmdline=='"')
596 qflag=!qflag;
597 cmdline++;
599 return cmdline;
601 LPCVOID WINAPI PathGetArgsAW(LPVOID cmdline)
602 { if (VERSION_OsIsUnicode())
603 return PathGetArgsW(cmdline);
604 return PathGetArgsA(cmdline);
606 /*************************************************************************
607 * PathQuoteSpaces [SHELL32.55]
609 * NOTES
610 * basename(char *fn);
612 LPSTR WINAPI PathQuoteSpacesA(LPCSTR aptr)
613 { FIXME("%s\n",aptr);
614 return 0;
617 LPWSTR WINAPI PathQuoteSpacesW(LPCWSTR wptr)
618 { FIXME("%s\n",debugstr_w(wptr));
619 return 0;
621 LPVOID WINAPI PathQuoteSpacesAW (LPCVOID fn)
622 { if(VERSION_OsIsUnicode())
623 return PathQuoteSpacesW(fn);
624 return PathQuoteSpacesA(fn);
628 /*************************************************************************
629 * PathUnquoteSpaces [SHELL32.56]
631 * NOTES
632 * unquote string (remove ")
634 VOID WINAPI PathUnquoteSpacesA(LPSTR str)
635 { DWORD len = lstrlenA(str);
636 TRACE("%s\n",str);
637 if (*str!='"')
638 return;
639 if (str[len-1]!='"')
640 return;
641 str[len-1]='\0';
642 lstrcpyA(str,str+1);
643 return;
645 VOID WINAPI PathUnquoteSpacesW(LPWSTR str)
646 { DWORD len = CRTDLL_wcslen(str);
648 TRACE("%s\n",debugstr_w(str));
650 if (*str!='"')
651 return;
652 if (str[len-1]!='"')
653 return;
654 str[len-1]='\0';
655 CRTDLL_wcscpy(str,str+1);
656 return;
658 VOID WINAPI PathUnquoteSpacesAW(LPVOID str)
660 if(VERSION_OsIsUnicode())
661 PathUnquoteSpacesW(str);
662 else
663 PathUnquoteSpacesA(str);
667 /*************************************************************************
668 * PathGetDriveNumber32 [SHELL32.57]
671 HRESULT WINAPI PathGetDriveNumber(LPSTR u)
672 { FIXME("%s stub\n",debugstr_a(u));
673 return 0;
676 /*************************************************************************
677 * PathYetAnotherMakeUniqueName [SHELL32.75]
679 * NOTES
680 * exported by ordinal
682 BOOL WINAPI PathYetAnotherMakeUniqueNameA(LPDWORD x,LPDWORD y) {
683 FIXME("(%p,%p):stub.\n",x,y);
684 return TRUE;
687 /*************************************************************************
688 * IsLFNDrive [SHELL32.119]
690 * NOTES
691 * exported by ordinal Name
693 BOOL WINAPI IsLFNDriveA(LPCSTR path) {
694 DWORD fnlen;
696 if (!GetVolumeInformationA(path,NULL,0,NULL,&fnlen,NULL,NULL,0))
697 return FALSE;
698 return fnlen>12;
700 /*************************************************************************
701 * PathFindOnPath [SHELL32.145]
703 BOOL WINAPI PathFindOnPathA(LPSTR sFile, LPCSTR sOtherDirs)
704 { FIXME("%s %s\n",sFile, sOtherDirs);
705 return FALSE;
707 BOOL WINAPI PathFindOnPathW(LPWSTR sFile, LPCWSTR sOtherDirs)
708 { FIXME("%s %s\n",debugstr_w(sFile), debugstr_w(sOtherDirs));
709 return FALSE;
711 BOOL WINAPI PathFindOnPathAW(LPVOID sFile, LPCVOID sOtherDirs)
712 { if (VERSION_OsIsUnicode())
713 return PathFindOnPathW(sFile, sOtherDirs);
714 return PathFindOnPathA(sFile, sOtherDirs);
717 /*************************************************************************
718 * PathGetExtension [SHELL32.158]
720 * NOTES
721 * exported by ordinal
723 LPCSTR 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;
728 LPCWSTR WINAPI PathGetExtensionW(LPCWSTR path,DWORD y,DWORD z)
729 { TRACE("(%s, %08lx, %08lx)\n",debugstr_w(path),y,z);
730 path = PathFindExtensionW(path);
731 return *path?(path+1):path;
733 LPCVOID WINAPI PathGetExtensionAW(LPCVOID path,DWORD y,DWORD z)
734 { if (VERSION_OsIsUnicode())
735 return PathGetExtensionW(path,y,z);
736 return PathGetExtensionA(path,y,z);
739 /*************************************************************************
740 * PathCleanupSpec [SHELL32.171]
743 DWORD WINAPI PathCleanupSpecA(LPSTR x, LPSTR y)
745 FIXME("(%p %s, %p %s) stub\n",x,debugstr_a(x),y,debugstr_a(y));
746 return TRUE;
749 DWORD WINAPI PathCleanupSpecW(LPWSTR x, LPWSTR y)
751 FIXME("(%p %s, %p %s) stub\n",x,debugstr_w(x),y,debugstr_w(y));
752 return TRUE;
755 DWORD WINAPI PathCleanupSpecAW (LPVOID x, LPVOID y)
757 if (VERSION_OsIsUnicode())
758 return PathCleanupSpecW(x,y);
759 return PathCleanupSpecA(x,y);
762 /*************************************************************************
763 * SheGetDirW [SHELL32.281]
766 HRESULT WINAPI SheGetDirW(LPWSTR u, LPWSTR v)
767 { FIXME("%p %p stub\n",u,v);
768 return 0;
771 /*************************************************************************
772 * SheChangeDirW [SHELL32.274]
775 HRESULT WINAPI SheChangeDirW(LPWSTR u)
776 { FIXME("(%s),stub\n",debugstr_w(u));
777 return 0;
780 /*************************************************************************
781 * PathProcessCommand [SHELL32.653]
783 HRESULT WINAPI PathProcessCommandA (LPSTR lpCommand, LPSTR v, DWORD w, DWORD x)
785 FIXME("%p(%s) %p 0x%04lx 0x%04lx stub\n",
786 lpCommand, lpCommand, v, w,x );
787 lstrcpyA(v, lpCommand);
788 return 0;
791 HRESULT WINAPI PathProcessCommandW (LPWSTR lpCommand, LPSTR v, DWORD w, DWORD x)
793 FIXME("(%p %s, %p, 0x%04lx, 0x%04lx) stub\n",
794 lpCommand, debugstr_w(lpCommand), v, w,x );
795 return 0;
798 HRESULT WINAPI PathProcessCommandAW (LPVOID lpCommand, LPSTR v, DWORD w, DWORD x)
800 if (VERSION_OsIsUnicode())
801 return PathProcessCommandW(lpCommand, v, w, x);
802 return PathProcessCommandA(lpCommand, v, w, x);
805 /*************************************************************************
806 * SHGetSpecialFolderPath [SHELL32.175]
808 * converts csidl to path
812 static char * szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
814 BOOL WINAPI SHGetSpecialFolderPathA (
815 HWND hwndOwner,
816 LPSTR szPath,
817 DWORD csidl,
818 BOOL bCreate)
820 CHAR szValueName[MAX_PATH], szDefaultPath[MAX_PATH];
821 HKEY hRootKey, hKey;
822 BOOL bRelative = TRUE;
823 DWORD dwType, dwDisp, dwPathLen = MAX_PATH;
825 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
827 /* build default values */
828 switch(csidl)
830 case CSIDL_APPDATA:
831 hRootKey = HKEY_CURRENT_USER;
832 strcpy (szValueName, "AppData");
833 strcpy (szDefaultPath, "AppData");
834 break;
836 case CSIDL_COOKIES:
837 hRootKey = HKEY_CURRENT_USER;
838 strcpy (szValueName, "Cookies");
839 strcpy(szDefaultPath, "Cookies");
840 break;
842 case CSIDL_DESKTOPDIRECTORY:
843 hRootKey = HKEY_CURRENT_USER;
844 strcpy(szValueName, "Desktop");
845 strcpy(szDefaultPath, "Desktop");
846 break;
848 case CSIDL_COMMON_DESKTOPDIRECTORY:
849 hRootKey = HKEY_LOCAL_MACHINE;
850 strcpy(szValueName, "Common Desktop");
851 strcpy(szDefaultPath, "Desktop");
852 break;
854 case CSIDL_FAVORITES:
855 hRootKey = HKEY_CURRENT_USER;
856 strcpy(szValueName, "Favorites");
857 strcpy(szDefaultPath, "Favorites");
858 break;
860 case CSIDL_FONTS:
861 hRootKey = HKEY_CURRENT_USER;
862 strcpy(szValueName, "Fonts");
863 strcpy(szDefaultPath, "Fonts");
864 break;
866 case CSIDL_HISTORY:
867 hRootKey = HKEY_CURRENT_USER;
868 strcpy(szValueName, "History");
869 strcpy(szDefaultPath, "History");
870 break;
872 case CSIDL_NETHOOD:
873 hRootKey = HKEY_CURRENT_USER;
874 strcpy(szValueName, "NetHood");
875 strcpy(szDefaultPath, "NetHood");
876 break;
878 case CSIDL_INTERNET_CACHE:
879 hRootKey = HKEY_CURRENT_USER;
880 strcpy(szValueName, "Cache");
881 strcpy(szDefaultPath, "Temporary Internet Files");
882 break;
884 case CSIDL_PERSONAL:
885 hRootKey = HKEY_CURRENT_USER;
886 strcpy(szValueName, "Personal");
887 strcpy(szDefaultPath, "My Own Files");
888 bRelative = FALSE;
889 break;
891 case CSIDL_PRINTHOOD:
892 hRootKey = HKEY_CURRENT_USER;
893 strcpy(szValueName, "PrintHood");
894 strcpy(szDefaultPath, "PrintHood");
895 break;
897 case CSIDL_PROGRAMS:
898 hRootKey = HKEY_CURRENT_USER;
899 strcpy(szValueName, "Programs");
900 strcpy(szDefaultPath, "StartMenu\\Programs");
901 break;
903 case CSIDL_COMMON_PROGRAMS:
904 hRootKey = HKEY_LOCAL_MACHINE;
905 strcpy(szValueName, "Common Programs");
906 strcpy(szDefaultPath, "");
907 break;
909 case CSIDL_RECENT:
910 hRootKey = HKEY_CURRENT_USER;
911 strcpy(szValueName, "Recent");
912 strcpy(szDefaultPath, "Recent");
913 break;
915 case CSIDL_SENDTO:
916 hRootKey = HKEY_CURRENT_USER;
917 strcpy(szValueName, "SendTo");
918 strcpy(szDefaultPath, "SendTo");
919 break;
921 case CSIDL_STARTMENU:
922 hRootKey = HKEY_CURRENT_USER;
923 strcpy(szValueName, "StartMenu");
924 strcpy(szDefaultPath, "StartMenu");
925 break;
927 case CSIDL_COMMON_STARTMENU:
928 hRootKey = HKEY_LOCAL_MACHINE;
929 strcpy(szValueName, "Common StartMenu");
930 strcpy(szDefaultPath, "StartMenu");
931 break;
933 case CSIDL_STARTUP:
934 hRootKey = HKEY_CURRENT_USER;
935 strcpy(szValueName, "Startup");
936 strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
937 break;
939 case CSIDL_COMMON_STARTUP:
940 hRootKey = HKEY_LOCAL_MACHINE;
941 strcpy(szValueName, "Common Startup");
942 strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
943 break;
945 case CSIDL_TEMPLATES:
946 hRootKey = HKEY_CURRENT_USER;
947 strcpy(szValueName, "Templates");
948 strcpy(szDefaultPath, "ShellNew");
949 break;
951 default:
952 ERR("folder unknown or not allowed\n");
953 return FALSE;
956 if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hKey,&dwDisp))
958 return FALSE;
961 if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
963 /* value not existing */
964 if (bRelative)
966 GetWindowsDirectoryA(szPath, MAX_PATH);
967 PathAddBackslashA(szPath);
968 strcat(szPath, szDefaultPath);
970 else
972 strcpy(szPath, szDefaultPath);
974 if (bCreate)
976 CreateDirectoryA(szPath,NULL);
978 RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
980 RegCloseKey(hKey);
982 return TRUE;
984 BOOL WINAPI SHGetSpecialFolderPathW (
985 HWND hwndOwner,
986 LPWSTR szPath,
987 DWORD csidl,
988 BOOL bCreate)
990 char szTemp[MAX_PATH];
992 if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate))
994 lstrcpynAtoW(szPath, szTemp, MAX_PATH);
997 TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
999 return TRUE;
1001 BOOL WINAPI SHGetSpecialFolderPathAW (
1002 HWND hwndOwner,
1003 LPVOID szPath,
1004 DWORD csidl,
1005 BOOL bCreate)
1008 if (VERSION_OsIsUnicode())
1009 return SHGetSpecialFolderPathW (hwndOwner, szPath, csidl, bCreate);
1010 return SHGetSpecialFolderPathA (hwndOwner, szPath, csidl, bCreate);
1013 /* PathRemoveBackslash
1015 * If the path ends in a backslash it is replaced by a NULL
1016 * and the address of the NULL is returned
1017 * Otherwise
1018 * the address of the last character is returned.
1022 LPSTR WINAPI PathRemoveBackslashA( LPSTR lpPath )
1024 LPSTR p = lpPath;
1026 while (*lpPath) p = lpPath++;
1027 if ( *p == (CHAR)'\\') *p = (CHAR)'\0';
1028 return p;
1031 LPWSTR WINAPI PathRemoveBackslashW( LPWSTR lpPath )
1033 LPWSTR p = lpPath;
1035 while (*lpPath); p = lpPath++;
1036 if ( *p == (WCHAR)'\\') *p = (WCHAR)'\0';
1037 return p;
1040 BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
1042 LPSTR lpstrRes;
1043 char lpstrFileType[10] = "";
1044 int iSize;
1045 int i = 0;
1046 /* sanity check */
1047 if(!lpstrPath)
1048 return FALSE;
1050 /* get protocol */
1051 /* protocol://location */
1052 if(!(lpstrRes = strchr(lpstrPath,':')))
1054 return FALSE;
1056 iSize = lpstrRes - lpstrPath;
1057 if(iSize > sizeof(lpstrFileType))
1058 return FALSE;
1060 strncpy(lpstrFileType,lpstrPath,iSize);
1062 while(strlen(SupportedProtocol[i]))
1064 if(!_stricmp(lpstrFileType,SupportedProtocol[i++]))
1065 return TRUE;
1068 return FALSE;
1071 /*************************************************************************
1072 * PathIsDirectory
1075 BOOL WINAPI PathIsDirectoryA(LPCSTR pszPath)
1077 FIXME("%s\n", debugstr_a(pszPath));
1078 return TRUE;
1080 BOOL WINAPI PathIsDirectoryW(LPCWSTR pszPath)
1082 FIXME("%s\n", debugstr_w(pszPath));
1083 return TRUE;
1085 BOOL WINAPI PathIsDirectoryAW (LPCVOID pszPath)
1087 if (VERSION_OsIsUnicode())
1088 return PathIsDirectoryW (pszPath);
1089 return PathIsDirectoryA (pszPath);