4 * Many of this functions are in SHLWAPI.DLL also
11 #include "winversion.h"
14 #include "shell32_main.h"
16 DEFAULT_DEBUG_CHANNEL(shell
)
18 /*************************************************************************
19 * PathIsRoot [SHELL32.29]
21 BOOL WINAPI
PathIsRootA(LPCSTR x
)
22 { TRACE(shell
,"%s\n",x
);
23 if (*(x
+1)==':' && *(x
+2)=='\\') /* "X:\" */
25 if (*x
=='\\') /* "\" */
27 if (x
[0]=='\\' && x
[1]=='\\') /* UNC "\\<xx>\" */
28 { int foundbackslash
= 0;
34 if (foundbackslash
<=1) /* max 1 \ more ... */
39 BOOL WINAPI
PathIsRootW(LPCWSTR x
)
40 { TRACE(shell
,"%s\n",debugstr_w(x
));
41 if (*(x
+1)==':' && *(x
+2)=='\\') /* "X:\" */
43 if (*x
== (WCHAR
) '\\') /* "\" */
45 if (x
[0]==(WCHAR
)'\\' && x
[1]==(WCHAR
)'\\') /* UNC "\\<xx>\" */
46 { int foundbackslash
= 0;
49 { if (*x
++==(WCHAR
)'\\')
52 if (foundbackslash
<=1) /* max 1 \ more ... */
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(shell
,"%p %i\n",root
, drive
);
73 /*************************************************************************
74 * PathFindExtension [SHELL32.31]
77 * returns pointer to last . in last pathcomponent or at \0.
79 LPCSTR WINAPI
PathFindExtensionA(LPCSTR path
)
80 { LPCSTR lastpoint
= NULL
;
81 TRACE(shell
,"%p %s\n",path
,path
);
83 { if (*path
=='\\'||*path
==' ')
89 return lastpoint
?lastpoint
:path
;
91 LPCWSTR WINAPI
PathFindExtensionW(LPCWSTR path
)
92 { LPCWSTR lastpoint
= NULL
;
93 TRACE(shell
,"%p L%s\n",path
,debugstr_w(path
));
95 { if (*path
==(WCHAR
)'\\'||*path
==(WCHAR
)' ')
97 if (*path
==(WCHAR
)'.')
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]
114 * append \ if there is none
116 LPSTR WINAPI
PathAddBackslashA(LPSTR path
)
118 TRACE(shell
,"%p->%s\n",path
,path
);
121 if (len
&& path
[len
-1]!='\\')
128 LPWSTR WINAPI
PathAddBackslashW(LPWSTR path
)
130 TRACE(shell
,"%p->%s\n",path
,debugstr_w(path
));
132 len
= lstrlenW(path
);
133 if (len
&& path
[len
-1]!=(WCHAR
)'\\')
134 { path
[len
] = (WCHAR
)'\\';
140 LPVOID WINAPI
PathAddBackslashAW(LPVOID path
)
141 { if(VERSION_OsIsUnicode())
142 return PathAddBackslashW(path
);
143 return PathAddBackslashA(path
);
146 /*************************************************************************
147 * PathRemoveBlanks [SHELL32.33]
150 * remove spaces from beginning and end of passed string
152 LPSTR WINAPI
PathRemoveBlanksA(LPSTR str
)
154 TRACE(shell
,"%s\n",str
);
167 LPWSTR WINAPI
PathRemoveBlanksW(LPWSTR str
)
169 TRACE(shell
,"%s\n",debugstr_w(str
));
175 x
=str
+lstrlenW(str
)-1;
182 LPVOID WINAPI
PathRemoveBlanksAW(LPVOID str
)
183 { if(VERSION_OsIsUnicode())
184 return PathRemoveBlanksW(str
);
185 return PathRemoveBlanksA(str
);
190 /*************************************************************************
191 * PathFindFilename [SHELL32.34]
194 * basename(char *fn);
196 LPCSTR WINAPI
PathFindFilenameA(LPCSTR aptr
)
200 TRACE(shell
,"%s\n",aslash
);
202 { if (((aptr
[0]=='\\') || (aptr
[0]==':')) && aptr
[1] && aptr
[1]!='\\')
209 LPCWSTR WINAPI
PathFindFilenameW(LPCWSTR wptr
)
213 TRACE(shell
,"L%s\n",debugstr_w(wslash
));
215 { if (((wptr
[0]=='\\') || (wptr
[0]==':')) && wptr
[1] && wptr
[1]!='\\')
221 LPCVOID WINAPI
PathFindFilenameAW(LPCVOID fn
)
223 if(VERSION_OsIsUnicode())
224 return PathFindFilenameW(fn
);
225 return PathFindFilenameA(fn
);
228 /*************************************************************************
229 * PathRemoveFileSpec [SHELL32.35]
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"
238 DWORD WINAPI
PathRemoveFileSpecA(LPSTR fn
) {
240 TRACE(shell
,"%s\n",fn
);
254 continue; /* already x++ed */
272 /*************************************************************************
273 * PathAppend [SHELL32.36]
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(shell
,"%s %s\n",x1
,x2
);
281 while (x2
[0]=='\\') x2
++;
282 return PathCombineA(x1
,x1
,x2
);
285 /*************************************************************************
286 * PathCombine [SHELL32.37]
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(shell
,"%p %p->%s %p->%s\n",szDest
, lpszDir
, lpszDir
, lpszFile
, lpszFile
);
297 if (!lpszFile
|| !lpszFile
[0] || (lpszFile
[0]=='.' && !lpszFile
[1]) )
298 { strcpy(szDest
,lpszDir
);
302 /* if lpszFile is a complete path don't care about lpszDir */
303 if (PathIsRootA(lpszFile
))
304 { strcpy(szDest
,lpszFile
);
307 { strcpy(sTemp
,lpszDir
);
308 PathAddBackslashA(sTemp
);
309 strcat(sTemp
,lpszFile
);
310 strcpy(szDest
,sTemp
);
314 LPWSTR WINAPI
PathCombineW(LPWSTR szDest
, LPCWSTR lpszDir
, LPCWSTR lpszFile
)
315 { WCHAR sTemp
[MAX_PATH
];
316 TRACE(shell
,"%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
);
325 /* if lpszFile is a complete path don't care about lpszDir */
326 if (PathIsRootW(lpszFile
))
327 { lstrcpyW(szDest
,lpszFile
);
330 { lstrcpyW(sTemp
,lpszDir
);
331 PathAddBackslashW(sTemp
);
332 lstrcatW(sTemp
,lpszFile
);
333 lstrcpyW(szDest
,sTemp
);
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]
347 * PathIsUNC(char*path);
349 BOOL WINAPI
PathIsUNCA(LPCSTR path
)
350 { TRACE(shell
,"%s\n",path
);
352 if ((path
[0]=='\\') && (path
[1]=='\\'))
356 BOOL WINAPI
PathIsUNCW(LPCWSTR path
)
357 { TRACE(shell
,"%s\n",debugstr_w(path
));
359 if ((path
[0]=='\\') && (path
[1]=='\\'))
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(shell
,"path=%s\n",path
);
375 if (path
&& (path
[0]!='\\' && path
[1]==':'))
379 BOOL WINAPI
PathIsRelativeW (LPCWSTR path
)
380 { TRACE(shell
,"path=%s\n",debugstr_w(path
));
382 if (path
&& (path
[0]!='\\' && path
[1]==':'))
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(shell
,"path=%s\n",path
);
399 BOOL WINAPI
PathIsExeW (LPCWSTR path
)
400 { FIXME(shell
,"path=%s\n",debugstr_w(path
));
403 BOOL WINAPI
PathIsExeAW (LPCVOID path
)
404 { if (VERSION_OsIsUnicode())
405 return PathIsExeW (path
);
406 return PathIsExeA(path
);
409 /*************************************************************************
410 * PathFileExists [SHELL32.45]
413 * file_exists(char *fn);
415 BOOL WINAPI
PathFileExistsA(LPSTR fn
) {
416 TRACE(shell
,"%s\n",fn
);
417 if (GetFileAttributesA(fn
)==-1)
422 /*************************************************************************
423 * PathMatchSpec [SHELL32.46]
429 BOOL WINAPI
PathMatchSpecA(LPCSTR name
, LPCSTR mask
)
432 TRACE(shell
,"%s %s stub\n",name
,mask
);
435 while (*_name
&& *mask
)
440 else if (*mask
== '*')
442 while (*mask
== '*') mask
++; /* Skip consecutive '*' */
443 if (!*mask
|| *mask
==';') return TRUE
; /* '*' matches everything */
444 while (*_name
&& (toupper(*_name
) != toupper(*mask
))) _name
++;
446 { while ( *mask
&& *mask
!= ';') mask
++;
450 else if ( (*mask
== '?') || (toupper(*mask
) == toupper(*_name
)) )
455 { while ( *mask
&& *mask
!= ';') mask
++;
458 return (!*_name
&& (!*mask
|| *mask
==';'));
460 BOOL WINAPI
PathMatchSpecW(LPCWSTR name
, LPCWSTR mask
)
464 TRACE(shell
,"%s %s stub\n",debugstr_w(name
),debugstr_w(mask
));
466 lstrcpyAtoW(stemp
,"*.*");
467 if (!lstrcmpW( mask
, stemp
)) return 1;
470 while (*_name
&& *mask
)
475 else if (*mask
== '*')
477 while (*mask
== '*') mask
++; /* Skip consecutive '*' */
478 if (!*mask
|| *mask
==';') return TRUE
; /* '*' matches everything */
479 while (*_name
&& (towupper(*_name
) != towupper(*mask
))) _name
++;
481 { while ( *mask
&& *mask
!= ';') mask
++;
485 else if ( (*mask
== '?') || (towupper(*mask
) == towupper(*_name
)) )
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]
503 * use PathCompactPath to make sure, the path fits into the control
506 BOOL WINAPI
PathSetDlgItemPathA(HWND hDlg
, int id
, LPCSTR pszPath
)
507 { TRACE(shell
,"%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(shell
,"%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(shell
,"%s\n",pszPath
);
528 BOOL WINAPI
PathQualifyW(LPCWSTR pszPath
)
529 { TRACE(shell
,"%s\n",debugstr_w(pszPath
));
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(shell
,"(%s,0x%08lx,0x%08lx),stub!\n",s
,x2
,x3
);
546 /*************************************************************************
547 * PathGetArgs [SHELL32.52]
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(shell
,"%s\n",cmdline
);
559 { if ((*cmdline
==' ') && !qflag
)
568 LPCWSTR WINAPI
PathGetArgsW(LPCWSTR cmdline
)
569 { BOOL qflag
= FALSE
;
571 TRACE(shell
,"%sL\n",debugstr_w(cmdline
));
574 { if ((*cmdline
==' ') && !qflag
)
582 LPCVOID WINAPI
PathGetArgsAW(LPVOID cmdline
)
583 { if (VERSION_OsIsUnicode())
584 return PathGetArgsW(cmdline
);
585 return PathGetArgsA(cmdline
);
587 /*************************************************************************
588 * PathQuoteSpaces [SHELL32.55]
591 * basename(char *fn);
593 LPSTR WINAPI
PathQuoteSpacesA(LPCSTR aptr
)
594 { FIXME(shell
,"%s\n",aptr
);
598 LPWSTR WINAPI
PathQuoteSpacesW(LPCWSTR wptr
)
599 { FIXME(shell
,"L%s\n",debugstr_w(wptr
));
602 LPVOID WINAPI
PathQuoteSpacesAW (LPCVOID fn
)
603 { if(VERSION_OsIsUnicode())
604 return PathQuoteSpacesW(fn
);
605 return PathQuoteSpacesA(fn
);
609 /*************************************************************************
610 * PathUnquoteSpaces [SHELL32.56]
613 * unquote string (remove ")
615 VOID WINAPI
PathUnquoteSpacesA(LPSTR str
)
616 { DWORD len
= lstrlenA(str
);
617 TRACE(shell
,"%s\n",str
);
626 VOID WINAPI
PathUnquoteSpacesW(LPWSTR str
)
627 { DWORD len
= lstrlenW(str
);
629 TRACE(shell
,"%s\n",debugstr_w(str
));
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(shell
,"%s stub\n",debugstr_a(u
));
655 /*************************************************************************
656 * PathYetAnotherMakeUniqueName [SHELL32.75]
659 * exported by ordinal
661 BOOL WINAPI
PathYetAnotherMakeUniqueNameA(LPDWORD x
,LPDWORD y
) {
662 FIXME(shell
,"(%p,%p):stub.\n",x
,y
);
666 /*************************************************************************
667 * IsLFNDrive [SHELL32.119]
670 * exported by ordinal Name
672 BOOL WINAPI
IsLFNDriveA(LPCSTR path
) {
675 if (!GetVolumeInformationA(path
,NULL
,0,NULL
,&fnlen
,NULL
,NULL
,0))
679 /*************************************************************************
680 * PathFindOnPath [SHELL32.145]
682 BOOL WINAPI
PathFindOnPathA(LPSTR sFile
, LPCSTR sOtherDirs
)
683 { FIXME(shell
,"%s %s\n",sFile
, sOtherDirs
);
686 BOOL WINAPI
PathFindOnPathW(LPWSTR sFile
, LPCWSTR sOtherDirs
)
687 { FIXME(shell
,"%s %s\n",debugstr_w(sFile
), debugstr_w(sOtherDirs
));
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]
700 * exported by ordinal
702 LPCSTR WINAPI
PathGetExtensionA(LPCSTR path
,DWORD y
,DWORD z
)
703 { TRACE(shell
,"(%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(shell
,"(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(shell
,"%s %s stub\n",debugstr_w(u
),debugstr_w(v
) );
727 /*************************************************************************
728 * SheChangeDirW [SHELL32.274]
731 HRESULT WINAPI
SheChangeDirW(LPWSTR u
)
732 { FIXME(shell
,"(%s),stub\n",debugstr_w(u
));
736 /*************************************************************************
737 * PathProcessCommand [SHELL32.653]
739 HRESULT WINAPI
PathProcessCommand (DWORD u
, DWORD v
, DWORD w
, DWORD x
)
740 { FIXME(shell
,"0x%04lx 0x%04lx 0x%04lx 0x%04lx stub\n",u
,v
,w
,x
);
744 /*************************************************************************
745 * SHGetSpecialFolderPath [SHELL32.175]
747 * converts csidl to path
750 BOOL WINAPI
SHGetSpecialFolderPathA (DWORD x1
,LPSTR szPath
,DWORD csidl
,DWORD x4
)
753 WARN(shell
,"(0x%04lx,%p,csidl=%lu,0x%04lx) semi-stub\n", x1
,szPath
,csidl
,x4
);
755 SHGetSpecialFolderLocation(0, csidl
, &pidl
);
756 SHGetPathFromIDListA (pidl
, szPath
);
760 BOOL WINAPI
SHGetSpecialFolderPathW (DWORD x1
,LPWSTR szPath
, DWORD csidl
,DWORD x4
)
763 WARN(shell
,"(0x%04lx,%p,csidl=%lu,0x%04lx) semi-stub\n", x1
,szPath
,csidl
,x4
);
765 SHGetSpecialFolderLocation(0, csidl
, &pidl
);
766 SHGetPathFromIDListW (pidl
, szPath
);
770 BOOL WINAPI
SHGetSpecialFolderPath (DWORD x1
,LPVOID szPath
,DWORD csidl
,DWORD x4
)
771 { if (VERSION_OsIsUnicode())
772 return SHGetSpecialFolderPathW ( x1
, szPath
, csidl
, x4
);
773 return SHGetSpecialFolderPathA ( x1
, szPath
, csidl
, x4
);