Complete cleanup, bugfixes.
New: PathStripPath, PathMakeUniqueName, PathStripToRoot,
PathGetShortPath, PathParseIconLocation, PathRemoveExtension,
PathRemoveArgs, PathAppend, PathBuildRoot, PathCanonicalize,
PathFindNextComponent, PathRemoveFileSpec.
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c
index ab96739..90375e1 100644
--- a/dlls/shell32/shellpath.c
+++ b/dlls/shell32/shellpath.c
@@ -11,192 +11,813 @@
#include "winversion.h"
#include "winreg.h"
#include "crtdll.h"
-#include "tchar.h"
#include "shlobj.h"
#include "shell32_main.h"
#include "windef.h"
#include "options.h"
+#include "wine/undocshell.h"
+#include "shlwapi.h"
DEFAULT_DEBUG_CHANNEL(shell)
-/* Supported protocols for PathIsURL */
-LPSTR SupportedProtocol[] = {"http","https","ftp","gopher","file","mailto",""};
+/*
+ Combining and Constructing paths
+*/
/*************************************************************************
- * PathIsRootA
+ * PathAppendA [SHLWAPI.@]
+ *
+ * NOTES
+ * concat path lpszPath2 onto lpszPath1
+ *
+ * FIXME
+ * the resulting path is also canonicalized
*/
-BOOL WINAPI PathIsRootA(LPCSTR x)
-{ TRACE("%s\n",x);
- if (*(x+1)==':' && *(x+2)=='\\') /* "X:\" */
- return 1;
- if (*x=='\\') /* "\" */
- return 0;
- if (x[0]=='\\' && x[1]=='\\') /* UNC "\\<xx>\" */
- { int foundbackslash = 0;
- x=x+2;
- while (*x)
- { if (*x++=='\\')
- foundbackslash++;
- }
- if (foundbackslash<=1) /* max 1 \ more ... */
- return 1;
+LPSTR WINAPI PathAppendA(
+ LPSTR lpszPath1,
+ LPCSTR lpszPath2)
+{
+ TRACE("%s %s\n",lpszPath1, lpszPath2);
+ while (lpszPath2[0]=='\\') lpszPath2++;
+ return PathCombineA(lpszPath1,lpszPath1,lpszPath2);
+}
+
+/*************************************************************************
+ * PathAppendW [SHLWAPI.@]
+ */
+LPSTR WINAPI PathAppendW(
+ LPWSTR lpszPath1,
+ LPCWSTR lpszPath2)
+{
+ FIXME("%s %s\n",debugstr_w(lpszPath1), debugstr_w(lpszPath2));
+ return NULL;
+}
+
+/*************************************************************************
+ * PathAppendAW [SHELL32.36]
+ */
+LPVOID WINAPI PathAppendAW(
+ LPVOID lpszPath1,
+ LPCVOID lpszPath2)
+{
+ if (VERSION_OsIsUnicode())
+ return PathAppendW(lpszPath1, lpszPath2);
+ return PathAppendA(lpszPath1, lpszPath2);
+}
+
+/*************************************************************************
+ * PathCombineA [SHLWAPI.@]
+ *
+ * NOTES
+ * if lpszFile='.' skip it
+ * szDest can be equal to lpszFile. Thats why we use sTemp
+ *
+ * FIXME
+ * the resulting path is also canonicalized
+ * If lpszSrcPath2 starts with a backslash it is appended
+ * to the root of lpszSrcPath1.
+ */
+LPSTR WINAPI PathCombineA(
+ LPSTR szDest,
+ LPCSTR lpszDir,
+ LPCSTR lpszFile)
+{
+ char sTemp[MAX_PATH];
+ TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, lpszDir, lpszFile, lpszFile);
+
+
+ if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
+ {
+ strcpy(szDest,lpszDir);
+ return szDest;
}
- return 0;
-}
-/*************************************************************************
- * PathIsRootW
- */
-BOOL WINAPI PathIsRootW(LPCWSTR x)
-{ TRACE("%s\n",debugstr_w(x));
- if (*(x+1)==':' && *(x+2)=='\\') /* "X:\" */
- return 1;
- if (*x == (WCHAR) '\\') /* "\" */
- return 0;
- if (x[0]==(WCHAR)'\\' && x[1]==(WCHAR)'\\') /* UNC "\\<xx>\" */
- { int foundbackslash = 0;
- x=x+2;
- while (*x)
- { if (*x++==(WCHAR)'\\')
- foundbackslash++;
- }
- if (foundbackslash<=1) /* max 1 \ more ... */
- return 1;
+ /* if lpszFile is a complete path don't care about lpszDir */
+ if (PathIsRootA(lpszFile))
+ {
+ strcpy(szDest,lpszFile);
}
- return 0;
+ else
+ {
+ strcpy(sTemp,lpszDir);
+ PathAddBackslashA(sTemp);
+ strcat(sTemp,lpszFile);
+ strcpy(szDest,sTemp);
+ }
+ return szDest;
}
/*************************************************************************
- * PathIsRoot [SHELL32.29]
+ * PathCombineW [SHLWAPI.@]
*/
-BOOL WINAPI PathIsRootAW(LPCVOID x)
-{ if (VERSION_OsIsUnicode())
- return PathIsRootW(x);
- return PathIsRootA(x);
+LPWSTR WINAPI PathCombineW(
+ LPWSTR szDest,
+ LPCWSTR lpszDir,
+ LPCWSTR lpszFile)
+{
+ WCHAR sTemp[MAX_PATH];
+ TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, debugstr_w(lpszDir),
+ lpszFile, debugstr_w(lpszFile));
+
+
+ if (!lpszFile || !lpszFile[0] || (lpszFile[0]==(WCHAR)'.' && !lpszFile[1]) )
+ {
+ CRTDLL_wcscpy(szDest,lpszDir);
+ return szDest;
+ }
+ /* if lpszFile is a complete path don't care about lpszDir */
+ if (PathIsRootW(lpszFile))
+ {
+ CRTDLL_wcscpy(szDest,lpszFile);
+ }
+ else
+ {
+ CRTDLL_wcscpy(sTemp,lpszDir);
+ PathAddBackslashW(sTemp);
+ CRTDLL_wcscat(sTemp,lpszFile);
+ CRTDLL_wcscpy(szDest,sTemp);
+ }
+ return szDest;
}
/*************************************************************************
- * PathBuildRootA [SHELL32.30]
+ * PathCombineAW [SHELL32.37]
*/
-LPSTR WINAPI PathBuildRootA(LPSTR root,BYTE drive) {
- TRACE("%p %i\n",root, drive);
- strcpy(root,"A:\\");
- root[0]+=drive;
- return root;
+LPVOID WINAPI PathCombineAW(
+ LPVOID szDest,
+ LPCVOID lpszDir,
+ LPCVOID lpszFile)
+{
+ if (VERSION_OsIsUnicode())
+ return PathCombineW( szDest, lpszDir, lpszFile );
+ return PathCombineA( szDest, lpszDir, lpszFile );
}
/*************************************************************************
- * PathFindExtensionA
+ * PathAddBackslashA [SHLWAPI.@]
*
* NOTES
- * returns pointer to last . in last pathcomponent or at \0.
+ * append \ if there is none
*/
-LPCSTR WINAPI PathFindExtensionA(LPCSTR path)
-{ LPCSTR lastpoint = NULL;
- TRACE("%p %s\n",path,path);
- while (*path)
- { if (*path=='\\'||*path==' ')
+LPSTR WINAPI PathAddBackslashA(LPSTR lpszPath)
+{
+ int len;
+ TRACE("%p->%s\n",lpszPath,lpszPath);
+
+ len = strlen(lpszPath);
+ if (len && lpszPath[len-1]!='\\')
+ {
+ lpszPath[len] = '\\';
+ lpszPath[len+1]= 0x00;
+ return lpszPath+len+1;
+ }
+ return lpszPath+len;
+}
+
+/*************************************************************************
+ * PathAddBackslashW [SHLWAPI.@]
+ */
+LPWSTR WINAPI PathAddBackslashW(LPWSTR lpszPath)
+{
+ int len;
+ TRACE("%p->%s\n",lpszPath,debugstr_w(lpszPath));
+
+ len = CRTDLL_wcslen(lpszPath);
+ if (len && lpszPath[len-1]!=(WCHAR)'\\')
+ {
+ lpszPath[len] = (WCHAR)'\\';
+ lpszPath[len+1]= 0x00;
+ return lpszPath+len+1;
+ }
+ return lpszPath+len;
+}
+
+/*************************************************************************
+ * PathAddBackslashAW [SHELL32.32]
+ */
+LPVOID WINAPI PathAddBackslashAW(LPVOID lpszPath)
+{
+ if(VERSION_OsIsUnicode())
+ return PathAddBackslashW(lpszPath);
+ return PathAddBackslashA(lpszPath);
+}
+
+/*************************************************************************
+ * PathBuildRootA [SHLWAPI.@]
+ */
+LPSTR WINAPI PathBuildRootA(LPSTR lpszPath, int drive)
+{
+ TRACE("%p %i\n",lpszPath, drive);
+
+ strcpy(lpszPath,"A:\\");
+ lpszPath[0]+=drive;
+ return lpszPath;
+}
+
+/*************************************************************************
+ * PathBuildRootW [SHLWAPI.@]
+ */
+LPWSTR WINAPI PathBuildRootW(LPWSTR lpszPath, int drive)
+{
+ TRACE("%p %i\n",debugstr_w(lpszPath), drive);
+
+ lstrcpyAtoW(lpszPath,"A:\\");
+ lpszPath[0]+=drive;
+ return lpszPath;
+}
+
+/*************************************************************************
+ * PathBuildRootAW [SHELL32.30]
+ */
+LPVOID WINAPI PathBuildRootAW(LPVOID lpszPath, int drive)
+{
+ if(VERSION_OsIsUnicode())
+ return PathBuildRootW(lpszPath, drive);
+ return PathBuildRootA(lpszPath, drive);
+}
+
+/*
+ Extracting Component Parts
+*/
+
+/*************************************************************************
+ * PathFindFileNameA [SHLWAPI.@]
+ */
+LPSTR WINAPI PathFindFileNameA(LPCSTR lpszPath)
+{
+ LPCSTR aslash;
+ aslash = lpszPath;
+
+ TRACE("%s\n",aslash);
+ while (lpszPath[0])
+ {
+ if (((lpszPath[0]=='\\') || (lpszPath[0]==':')) && lpszPath[1] && lpszPath[1]!='\\')
+ aslash = lpszPath+1;
+ lpszPath++;
+ }
+ return (LPSTR)aslash;
+
+}
+
+/*************************************************************************
+ * PathFindFileNameW [SHLWAPI.@]
+ */
+LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
+{
+ LPCWSTR wslash;
+ wslash = lpszPath;
+
+ TRACE("%s\n",debugstr_w(wslash));
+ while (lpszPath[0])
+ {
+ if (((lpszPath[0]=='\\') || (lpszPath[0]==':')) && lpszPath[1] && lpszPath[1]!='\\')
+ wslash = lpszPath+1;
+ lpszPath++;
+ }
+ return (LPWSTR)wslash;
+}
+
+/*************************************************************************
+ * PathFindFileNameAW [SHELL32.34]
+ */
+LPVOID WINAPI PathFindFileNameAW(LPCVOID lpszPath)
+{
+ if(VERSION_OsIsUnicode())
+ return PathFindFileNameW(lpszPath);
+ return PathFindFileNameA(lpszPath);
+}
+
+/*************************************************************************
+ * PathFindExtensionA [SHLWAPI.@]
+ *
+ * NOTES
+ * returns pointer to last . in last lpszPath component or at \0.
+ */
+
+LPSTR WINAPI PathFindExtensionA(LPCSTR lpszPath)
+{
+ LPCSTR lastpoint = NULL;
+
+ TRACE("%p %s\n",lpszPath,lpszPath);
+
+ while (*lpszPath)
+ {
+ if (*lpszPath=='\\'||*lpszPath==' ')
lastpoint=NULL;
- if (*path=='.')
- lastpoint=path;
- path++;
+ if (*lpszPath=='.')
+ lastpoint=lpszPath;
+ lpszPath++;
}
- return lastpoint?lastpoint:path;
+ return (LPSTR)(lastpoint?lastpoint:lpszPath);
}
/*************************************************************************
- * PathFindExtensionW
- *
- * NOTES
- * returns pointer to last . in last pathcomponent or at \0.
+ * PathFindExtensionW [SHLWAPI.@]
*/
-LPCWSTR WINAPI PathFindExtensionW(LPCWSTR path)
-{ LPCWSTR lastpoint = NULL;
- TRACE("(%p %s)\n",path,debugstr_w(path));
- while (*path)
- { if (*path==(WCHAR)'\\'||*path==(WCHAR)' ')
+LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
+{
+ LPCWSTR lastpoint = NULL;
+
+ TRACE("(%p %s)\n",lpszPath,debugstr_w(lpszPath));
+
+ while (*lpszPath)
+ {
+ if (*lpszPath==(WCHAR)'\\'||*lpszPath==(WCHAR)' ')
lastpoint=NULL;
- if (*path==(WCHAR)'.')
- lastpoint=path;
- path++;
+ if (*lpszPath==(WCHAR)'.')
+ lastpoint=lpszPath;
+ lpszPath++;
}
- return lastpoint?lastpoint:path;
+ return (LPWSTR)(lastpoint?lastpoint:lpszPath);
}
/*************************************************************************
- * PathFindExtension [SHELL32.31]
+ * PathFindExtensionAW [SHELL32.31]
+ */
+LPVOID WINAPI PathFindExtensionAW(LPCVOID lpszPath)
+{
+ if (VERSION_OsIsUnicode())
+ return PathFindExtensionW(lpszPath);
+ return PathFindExtensionA(lpszPath);
+
+}
+
+/*************************************************************************
+ * PathGetExtensionA [internal]
*
* NOTES
- * returns pointer to last . in last pathcomponent or at \0.
+ * exported by ordinal
+ * return value points to the first char after the dot
*/
-LPCVOID WINAPI PathFindExtensionAW(LPCVOID path)
-{ if (VERSION_OsIsUnicode())
- return PathFindExtensionW(path);
- return PathFindExtensionA(path);
+LPSTR WINAPI PathGetExtensionA(LPCSTR lpszPath)
+{
+ TRACE("(%s)\n",lpszPath);
+ lpszPath = PathFindExtensionA(lpszPath);
+ return (LPSTR)(*lpszPath?(lpszPath+1):lpszPath);
}
/*************************************************************************
- * PathAddBackslashA
- *
- * NOTES
- * append \ if there is none
+ * PathGetExtensionW [internal]
*/
-LPSTR WINAPI PathAddBackslashA(LPSTR path)
-{ int len;
- TRACE("%p->%s\n",path,path);
+LPWSTR WINAPI PathGetExtensionW(LPCWSTR lpszPath)
+{
+ TRACE("(%s)\n",debugstr_w(lpszPath));
- len = strlen(path);
- if (len && path[len-1]!='\\')
- { path[len] = '\\';
- path[len+1]= 0x00;
- return path+len+1;
+ lpszPath = PathFindExtensionW(lpszPath);
+ return (LPWSTR)(*lpszPath?(lpszPath+1):lpszPath);
+}
+
+/*************************************************************************
+ * PathGetExtensionAW [SHELL32.158]
+ */
+LPVOID WINAPI PathGetExtensionAW(LPCVOID lpszPath)
+{
+ if (VERSION_OsIsUnicode())
+ return PathGetExtensionW(lpszPath);
+ return PathGetExtensionA(lpszPath);
+}
+
+/*************************************************************************
+ * PathGetArgsA [SHLWAPI.@]
+ *
+ * NOTES
+ * look for next arg in string. handle "quoted" strings
+ * returns pointer to argument *AFTER* the space. Or to the \0.
+ *
+ * FIXME
+ * quoting by '\'
+ */
+LPSTR WINAPI PathGetArgsA(LPCSTR lpszPath)
+{
+ BOOL qflag = FALSE;
+
+ TRACE("%s\n",lpszPath);
+
+ while (*lpszPath)
+ {
+ if ((*lpszPath==' ') && !qflag)
+ return (LPSTR)lpszPath+1;
+ if (*lpszPath=='"')
+ qflag=!qflag;
+ lpszPath++;
}
- return path+len;
+ return (LPSTR)lpszPath;
+
}
/*************************************************************************
- * PathAddBackslashW
- *
- * NOTES
- * append \ if there is none
+ * PathGetArgsW [SHLWAPI.@]
*/
-LPWSTR WINAPI PathAddBackslashW(LPWSTR path)
-{ int len;
- TRACE("%p->%s\n",path,debugstr_w(path));
+LPWSTR WINAPI PathGetArgsW(LPCWSTR lpszPath)
+{
+ BOOL qflag = FALSE;
- len = CRTDLL_wcslen(path);
- if (len && path[len-1]!=(WCHAR)'\\')
- { path[len] = (WCHAR)'\\';
- path[len+1]= 0x00;
- return path+len+1;
+ TRACE("%s\n",debugstr_w(lpszPath));
+
+ while (*lpszPath)
+ {
+ if ((*lpszPath==' ') && !qflag)
+ return (LPWSTR)lpszPath+1;
+ if (*lpszPath=='"')
+ qflag=!qflag;
+ lpszPath++;
}
- return path+len;
+ return (LPWSTR)lpszPath;
}
/*************************************************************************
- * PathAddBackslash [SHELL32.32]
+ * PathGetArgsAW [SHELL32.52]
+ */
+LPVOID WINAPI PathGetArgsAW(LPVOID lpszPath)
+{
+ if (VERSION_OsIsUnicode())
+ return PathGetArgsW(lpszPath);
+ return PathGetArgsA(lpszPath);
+}
+
+/*************************************************************************
+ * PathGetDriveNumberA [SHLWAPI.@]
+ */
+int WINAPI PathGetDriveNumberA(LPCSTR lpszPath)
+{
+ int chr = tolower(lpszPath[0]);
+
+ TRACE ("%s\n",debugstr_a(lpszPath));
+
+ if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
+ return tolower(lpszPath[0]) - 'a' ;
+}
+
+/*************************************************************************
+ * PathGetDriveNumberW [SHLWAPI.@]
+ */
+int WINAPI PathGetDriveNumberW(LPCWSTR lpszPath)
+{
+ int chr = towlower(lpszPath[0]);
+
+ TRACE ("%s\n",debugstr_w(lpszPath));
+
+ if (!lpszPath || lpszPath[1]!=':' || chr < 'a' || chr > 'z') return -1;
+ return tolower(lpszPath[0]) - 'a' ;
+}
+
+/*************************************************************************
+ * PathGetDriveNumber [SHELL32.57]
+ */
+int WINAPI PathGetDriveNumberAW(LPVOID lpszPath)
+{
+ if (VERSION_OsIsUnicode())
+ return PathGetDriveNumberW(lpszPath);
+ return PathGetDriveNumberA(lpszPath);
+}
+
+/*************************************************************************
+ * PathRemoveFileSpecA [SHLWAPI.@]
*
* NOTES
- * append \ if there is none
+ * truncates passed argument to a valid path
+ * returns if the string was modified or not.
+ * "\foo\xx\foo"-> "\foo\xx"
+ * "\" -> "\"
+ * "a:\foo" -> "a:\"
*/
-LPVOID WINAPI PathAddBackslashAW(LPVOID path)
-{ if(VERSION_OsIsUnicode())
- return PathAddBackslashW(path);
- return PathAddBackslashA(path);
+BOOL WINAPI PathRemoveFileSpecA(LPSTR lpszPath)
+{
+ LPSTR cutplace;
+
+ TRACE("%s\n",lpszPath);
+
+ if (!lpszPath[0]) return 0;
+
+ cutplace = PathFindFileNameA(lpszPath);
+ if (cutplace)
+ {
+ *cutplace='\0';
+ if (PathIsRootA(lpszPath))
+ {
+ PathAddBackslashA(lpszPath);
+ }
+ else
+ {
+ PathRemoveBackslashA(lpszPath);
+ }
+ return TRUE;
+ }
+ return FALSE;
}
/*************************************************************************
- * PathRemoveBlanksA
+ * PathRemoveFileSpecW [SHLWAPI.@]
+ */
+BOOL WINAPI PathRemoveFileSpecW(LPWSTR lpszPath)
+{
+ LPWSTR cutplace;
+
+ TRACE("%s\n",debugstr_w(lpszPath));
+
+ if (!lpszPath[0]) return 0;
+ cutplace = PathFindFileNameW(lpszPath);
+ if (cutplace)
+ {
+ *cutplace='\0';
+ if (PathIsRootW(lpszPath))
+ {
+ PathAddBackslashW(lpszPath);
+ }
+ else
+ {
+ PathRemoveBackslashW(lpszPath);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*************************************************************************
+ * PathRemoveFileSpec [SHELL32.35]
+ */
+BOOL WINAPI PathRemoveFileSpecAW(LPVOID lpszPath)
+{
+ if (VERSION_OsIsUnicode())
+ return PathRemoveFileSpecW(lpszPath);
+ return PathRemoveFileSpecA(lpszPath);
+}
+
+/*************************************************************************
+ * PathStripPathA [SHELLWAPI.@]
+ *
+ * NOTES
+ * removes the path from the beginning of a filename
+ */
+void WINAPI PathStripPathA(LPSTR lpszPath)
+{
+ LPSTR lpszFileName = PathFindFileNameA(lpszPath);
+
+ TRACE("%s\n", lpszPath);
+
+ if(lpszFileName)
+ RtlMoveMemory(lpszPath, lpszFileName, strlen(lpszFileName));
+}
+
+/*************************************************************************
+ * PathStripPathW [SHELLWAPI.@]
+ */
+void WINAPI PathStripPathW(LPWSTR lpszPath)
+{
+ LPWSTR lpszFileName = PathFindFileNameW(lpszPath);
+
+ TRACE("%s\n", debugstr_w(lpszPath));
+ if(lpszFileName)
+ RtlMoveMemory(lpszPath, lpszFileName, lstrlenW(lpszFileName)*sizeof(WCHAR));
+}
+
+/*************************************************************************
+ * PathStripPathAW [SHELL32.38]
+ */
+void WINAPI PathStripPathAW(LPVOID lpszPath)
+{
+ if (VERSION_OsIsUnicode())
+ return PathStripPathW(lpszPath);
+ return PathStripPathA(lpszPath);
+}
+
+/*************************************************************************
+ * PathStripToRootA [SHLWAPI.@]
+ */
+BOOL WINAPI PathStripToRootA(LPSTR lpszPath)
+{
+ TRACE("%s\n", lpszPath);
+
+ /* X:\ */
+ if (lpszPath[1]==':' && lpszPath[2]=='\\')
+ {
+ lpszPath[3]='\0';
+ return TRUE;
+ }
+
+ /* "\" */
+ if (lpszPath[0]=='\\')
+ {
+ lpszPath[1]='\0';
+ return TRUE;
+ }
+
+ /* UNC "\\<computer>\<share>" */
+ if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
+ {
+ int foundbackslash = 0;
+ lpszPath += 2;
+ while (*lpszPath)
+ {
+ if (*lpszPath=='\\') foundbackslash++;
+ if (foundbackslash==2)
+ {
+ *lpszPath = '\0';
+ return TRUE;
+ }
+ lpszPath++;
+ }
+ }
+
+ return FALSE;
+}
+
+/*************************************************************************
+ * PathStripToRootW [SHLWAPI.@]
+ */
+BOOL WINAPI PathStripToRootW(LPWSTR lpszPath)
+{
+ TRACE("%s\n", debugstr_w(lpszPath));
+
+ /* X:\ */
+ if (lpszPath[1]==':' && lpszPath[2]=='\\')
+ {
+ lpszPath[3]='\0';
+ return TRUE;
+ }
+
+ /* "\" */
+ if (lpszPath[0]=='\\')
+ {
+ lpszPath[1]='\0';
+ return TRUE;
+ }
+
+ /* UNC "\\<computer>\<share>" */
+ if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
+ {
+ int foundbackslash = 0;
+ lpszPath += 2;
+ while (*lpszPath)
+ {
+ if (*lpszPath=='\\') foundbackslash++;
+ if (foundbackslash==2)
+ {
+ *lpszPath = '\0';
+ return TRUE;
+ }
+ lpszPath++;
+ }
+ }
+
+ return FALSE;
+}
+
+/*************************************************************************
+ * PathStripToRootAW [SHELL32.50]
+ */
+BOOL WINAPI PathStripToRootAW(LPVOID lpszPath)
+{
+ if (VERSION_OsIsUnicode())
+ return PathStripToRootW(lpszPath);
+ return PathStripToRootA(lpszPath);
+}
+
+/*************************************************************************
+ * PathRemoveArgsA [SHLWAPI.@]
+ */
+void WINAPI PathRemoveArgsA(LPSTR lpszPath)
+{
+ LPSTR lpszArgs = PathGetArgsA(lpszPath);
+
+ TRACE("%s\n", lpszPath);
+
+ if (lpszArgs) *(--lpszArgs)='\0';
+}
+
+/*************************************************************************
+ * PathRemoveArgsW [SHLWAPI.@]
+ */
+void WINAPI PathRemoveArgsW(LPWSTR lpszPath)
+{
+ LPWSTR lpszArgs = PathGetArgsW(lpszPath);
+
+ TRACE("%s\n", debugstr_w(lpszPath));
+
+ if (lpszArgs) *(--lpszArgs)='\0';
+}
+
+/*************************************************************************
+ * PathRemoveArgsAW [SHELL32.251]
+ */
+void WINAPI PathRemoveArgsAW(LPVOID lpszPath)
+{
+ if (VERSION_OsIsUnicode())
+ return PathRemoveArgsW(lpszPath);
+ return PathRemoveArgsA(lpszPath);
+}
+
+/*************************************************************************
+ * PathRemoveExtensionA [SHLWAPI.@]
+ */
+void WINAPI PathRemoveExtensionA(LPSTR lpszPath)
+{
+ LPSTR lpszExtension = PathFindExtensionA(lpszPath);
+
+ TRACE("%s\n", lpszPath);
+
+ if (lpszExtension) *lpszExtension='\0';
+}
+
+/*************************************************************************
+ * PathRemoveExtensionW [SHLWAPI.@]
+ */
+void WINAPI PathRemoveExtensionW(LPWSTR lpszPath)
+{
+ LPWSTR lpszExtension = PathFindExtensionW(lpszPath);
+
+ TRACE("%s\n", debugstr_w(lpszPath));
+
+ if (lpszExtension) *lpszExtension='\0';
+}
+
+/*************************************************************************
+ * PathRemoveExtensionAW [SHELL32.250]
+ */
+void WINAPI PathRemoveExtensionAW(LPVOID lpszPath)
+{
+ if (VERSION_OsIsUnicode())
+ return PathRemoveExtensionW(lpszPath);
+ return PathRemoveExtensionA(lpszPath);
+}
+
+/*************************************************************************
+ * PathRemoveBackslashA [SHLWAPI.@]
+ *
+ * If the path ends in a backslash it is replaced by a NULL
+ * and the address of the NULL is returned
+ * Otherwise
+ * the address of the last character is returned.
+ *
+ */
+LPSTR WINAPI PathRemoveBackslashA( LPSTR lpszPath )
+{
+ LPSTR p = lpszPath;
+
+ while (*lpszPath) p = lpszPath++;
+ if ( *p == (CHAR)'\\') *p = (CHAR)'\0';
+ return p;
+}
+
+/*************************************************************************
+ * PathRemoveBackslashW [SHLWAPI.@]
+ */
+LPWSTR WINAPI PathRemoveBackslashW( LPWSTR lpszPath )
+{
+ LPWSTR p = lpszPath;
+
+ while (*lpszPath); p = lpszPath++;
+ if ( *p == (WCHAR)'\\') *p = (WCHAR)'\0';
+ return p;
+}
+
+/*
+ Path Manipulations
+*/
+
+/*************************************************************************
+ * PathGetShortPathA [internal]
+ */
+LPSTR WINAPI PathGetShortPathA(LPSTR lpszPath)
+{
+ FIXME("%s stub\n", lpszPath);
+ return NULL;
+}
+
+/*************************************************************************
+ * PathGetShortPathW [internal]
+ */
+LPWSTR WINAPI PathGetShortPathW(LPWSTR lpszPath)
+{
+ FIXME("%s stub\n", debugstr_w(lpszPath));
+ return NULL;
+}
+
+/*************************************************************************
+ * PathGetShortPathAW [SHELL32.92]
+ */
+LPVOID WINAPI PathGetShortPathAW(LPVOID lpszPath)
+{
+ if(VERSION_OsIsUnicode())
+ return PathGetShortPathW(lpszPath);
+ return PathGetShortPathA(lpszPath);
+}
+
+/*************************************************************************
+ * PathRemoveBlanksA [SHLWAPI.@]
*
* NOTES
* remove spaces from beginning and end of passed string
*/
LPSTR WINAPI PathRemoveBlanksA(LPSTR str)
-{ LPSTR x = str;
+{
+ LPSTR x = str;
+
TRACE("%s\n",str);
+
while (*x==' ') x++;
if (x!=str)
strcpy(str,x);
@@ -211,14 +832,14 @@
}
/*************************************************************************
- * PathRemoveBlanksW
- *
- * NOTES
- * remove spaces from beginning and end of passed string
+ * PathRemoveBlanksW [SHLWAPI.@]
*/
LPWSTR WINAPI PathRemoveBlanksW(LPWSTR str)
-{ LPWSTR x = str;
+{
+ LPWSTR x = str;
+
TRACE("%s\n",debugstr_w(str));
+
while (*x==' ') x++;
if (x!=str)
CRTDLL_wcscpy(str,x);
@@ -233,586 +854,57 @@
}
/*************************************************************************
- * PathRemoveBlanks [SHELL32.33]
- *
- * NOTES
- * remove spaces from beginning and end of passed string
+ * PathRemoveBlanksAW [SHELL32.33]
*/
LPVOID WINAPI PathRemoveBlanksAW(LPVOID str)
-{ if(VERSION_OsIsUnicode())
+{
+ if(VERSION_OsIsUnicode())
return PathRemoveBlanksW(str);
return PathRemoveBlanksA(str);
}
/*************************************************************************
- * PathFindFilenameA
+ * PathQuoteSpacesA [SHLWAPI.@]
*
* NOTES
- * basename(char *fn);
*/
-LPCSTR WINAPI PathFindFilenameA(LPCSTR aptr)
-{ LPCSTR aslash;
- aslash = aptr;
-
- TRACE("%s\n",aslash);
- while (aptr[0])
- { if (((aptr[0]=='\\') || (aptr[0]==':')) && aptr[1] && aptr[1]!='\\')
- aslash = aptr+1;
- aptr++;
- }
- return aslash;
-
-}
-
-/*************************************************************************
- * PathFindFilenameW
- *
- * NOTES
- * basename(char *fn);
- */
-LPCWSTR WINAPI PathFindFilenameW(LPCWSTR wptr)
-{ LPCWSTR wslash;
- wslash = wptr;
-
- TRACE("%s\n",debugstr_w(wslash));
- while (wptr[0])
- { if (((wptr[0]=='\\') || (wptr[0]==':')) && wptr[1] && wptr[1]!='\\')
- wslash = wptr+1;
- wptr++;
- }
- return wslash;
-}
-
-/*************************************************************************
- * PathFindFilename [SHELL32.34]
- *
- * NOTES
- * basename(char *fn);
- */
-LPCVOID WINAPI PathFindFilenameAW(LPCVOID fn)
+LPSTR WINAPI PathQuoteSpacesA(LPCSTR lpszPath)
{
- if(VERSION_OsIsUnicode())
- return PathFindFilenameW(fn);
- return PathFindFilenameA(fn);
-}
-
-/*************************************************************************
- * PathRemoveFileSpecA [SHELL32.35]
- *
- * NOTES
- * bool getpath(char *pathname); truncates passed argument to a valid path
- * returns if the string was modified or not.
- * "\foo\xx\foo"-> "\foo\xx"
- * "\" -> "\"
- * "a:\foo" -> "a:\"
- */
-DWORD WINAPI PathRemoveFileSpecA(LPSTR fn) {
- LPSTR x,cutplace;
- TRACE("%s\n",fn);
- if (!fn[0])
- return 0;
- x=fn;
- cutplace = fn;
- while (*x) {
- if (*x=='\\') {
- cutplace=x++;
- continue;
- }
- if (*x==':') {
- x++;
- if (*x=='\\')
- cutplace=++x;
- continue; /* already x++ed */
- }
- x++;
- }
- if (!*cutplace)
- return 0;
- if (cutplace==fn) {
- if (fn[0]=='\\') {
- if (!fn[1])
- return 0;
- fn[0]='\0';
- return 1;
- }
- }
- *cutplace='\0';
- return 1;
-}
-
-/*************************************************************************
- * PathAppendA [SHELL32.36]
- *
- * NOTES
- * concat_paths(char*target,const char*add);
- * concats "target\\add" and writes them to target
- */
-LPSTR WINAPI PathAppendA(LPSTR x1,LPSTR x2) {
- TRACE("%s %s\n",x1,x2);
- while (x2[0]=='\\') x2++;
- return PathCombineA(x1,x1,x2);
-}
-
-/*************************************************************************
- * PathCombineA
- *
- * NOTES
- * if lpszFile='.' skip it
- * szDest can be equal to lpszFile. Thats why we use sTemp
- */
-LPSTR WINAPI PathCombineA(LPSTR szDest, LPCSTR lpszDir, LPCSTR lpszFile)
-{ char sTemp[MAX_PATH];
- TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, lpszDir, lpszFile, lpszFile);
-
-
- if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
- { strcpy(szDest,lpszDir);
- return szDest;
- }
-
- /* if lpszFile is a complete path don't care about lpszDir */
- if (PathIsRootA(lpszFile))
- { strcpy(szDest,lpszFile);
- }
- else
- { strcpy(sTemp,lpszDir);
- PathAddBackslashA(sTemp);
- strcat(sTemp,lpszFile);
- strcpy(szDest,sTemp);
- }
- return szDest;
-}
-
-/*************************************************************************
- * PathCombineW
- *
- * NOTES
- * if lpszFile='.' skip it
- * szDest can be equal to lpszFile. Thats why we use sTemp
- */
-LPWSTR WINAPI PathCombineW(LPWSTR szDest, LPCWSTR lpszDir, LPCWSTR lpszFile)
-{ WCHAR sTemp[MAX_PATH];
- TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, debugstr_w(lpszDir),
- lpszFile, debugstr_w(lpszFile));
-
-
- if (!lpszFile || !lpszFile[0] || (lpszFile[0]==(WCHAR)'.' && !lpszFile[1]) )
- { CRTDLL_wcscpy(szDest,lpszDir);
- return szDest;
- }
-
- /* if lpszFile is a complete path don't care about lpszDir */
- if (PathIsRootW(lpszFile))
- { CRTDLL_wcscpy(szDest,lpszFile);
- }
- else
- { CRTDLL_wcscpy(sTemp,lpszDir);
- PathAddBackslashW(sTemp);
- CRTDLL_wcscat(sTemp,lpszFile);
- CRTDLL_wcscpy(szDest,sTemp);
- }
- return szDest;
-}
-
-/*************************************************************************
- * PathCombine [SHELL32.37]
- *
- * NOTES
- * if lpszFile='.' skip it
- * szDest can be equal to lpszFile. Thats why we use sTemp
- */
-LPVOID WINAPI PathCombineAW(LPVOID szDest, LPCVOID lpszDir, LPCVOID lpszFile)
-{ if (VERSION_OsIsUnicode())
- return PathCombineW( szDest, lpszDir, lpszFile );
- return PathCombineA( szDest, lpszDir, lpszFile );
-}
-
-/*************************************************************************
- * PathIsUNCA
- *
- * NOTES
- * PathIsUNC(char*path);
- */
-BOOL WINAPI PathIsUNCA(LPCSTR path)
-{ TRACE("%s\n",path);
-
- if ((path[0]=='\\') && (path[1]=='\\'))
- return TRUE;
- return FALSE;
-}
-
-/*************************************************************************
- * PathIsUNCW
- *
- * NOTES
- * PathIsUNC(char*path);
- */
-BOOL WINAPI PathIsUNCW(LPCWSTR path)
-{ TRACE("%s\n",debugstr_w(path));
-
- if ((path[0]=='\\') && (path[1]=='\\'))
- return TRUE;
- return FALSE;
-}
-
-/*************************************************************************
- * PathIsUNC [SHELL32.39]
- *
- * NOTES
- * PathIsUNC(char*path);
- */
-BOOL WINAPI PathIsUNCAW (LPCVOID path)
-{ if (VERSION_OsIsUnicode())
- return PathIsUNCW( path );
- return PathIsUNCA( path );
-}
-
-/*************************************************************************
- * PathIsRelativeA
- *
- */
-BOOL WINAPI PathIsRelativeA (LPCSTR path)
-{ TRACE("path=%s\n",path);
-
- if (path && (path[0]!='\\' && path[1]==':'))
- return TRUE;
- return FALSE;
-}
-
-/*************************************************************************
- * PathIsRelativeW
- *
- */
-BOOL WINAPI PathIsRelativeW (LPCWSTR path)
-{ TRACE("path=%s\n",debugstr_w(path));
-
- if (path && (path[0]!='\\' && path[1]==':'))
- return TRUE;
- return FALSE;
-}
-
-/*************************************************************************
- * PathIsRelative [SHELL32.40]
- *
- */
-BOOL WINAPI PathIsRelativeAW (LPCVOID path)
-{ if (VERSION_OsIsUnicode())
- return PathIsRelativeW( path );
- return PathIsRelativeA( path );
-}
-
-/*************************************************************************
- * PathIsExeA
- *
- */
-BOOL WINAPI PathIsExeA (LPCSTR path)
-{ FIXME("path=%s\n",path);
- return FALSE;
-}
-
-/*************************************************************************
- * PathIsExeW
- *
- */
-BOOL WINAPI PathIsExeW (LPCWSTR path)
-{ FIXME("path=%s\n",debugstr_w(path));
- return FALSE;
-}
-
-/*************************************************************************
- * PathIsExe [SHELL32.43]
- *
- */
-BOOL WINAPI PathIsExeAW (LPCVOID path)
-{ if (VERSION_OsIsUnicode())
- return PathIsExeW (path);
- return PathIsExeA(path);
-}
-
-/*************************************************************************
- * PathFileExistsA [SHELL32.45]
- *
- * NOTES
- * file_exists(char *fn);
- */
-BOOL WINAPI PathFileExistsA(LPSTR fn) {
- TRACE("%s\n",fn);
- if (GetFileAttributesA(fn)==-1)
- return FALSE;
- else
- return TRUE;
-}
-/*************************************************************************
- * PathMatchSingleMask
- *
- * NOTES
- * internal (used by PathMatchSpec)
- */
-static BOOL PathMatchSingleMaskA(LPCSTR name, LPCSTR mask)
-{
- while (*name && *mask && *mask!=';') {
- if (*mask=='*') {
- do {
- if (PathMatchSingleMaskA(name,mask+1)) return 1; /* try substrings */
- } while (*name++);
- return 0;
- }
- if (toupper(*mask)!=toupper(*name) && *mask!='?') return 0;
- name++;
- mask++;
- }
- if (!*name) {
- while (*mask=='*') mask++;
- if (!*mask || *mask==';') return 1;
- }
- return 0;
-}
-static BOOL PathMatchSingleMaskW(LPCWSTR name, LPCWSTR mask)
-{
- while (*name && *mask && *mask!=';') {
- if (*mask=='*') {
- do {
- if (PathMatchSingleMaskW(name,mask+1)) return 1; /* try substrings */
- } while (*name++);
- return 0;
- }
- if (towupper(*mask)!=towupper(*name) && *mask!='?') return 0;
- name++;
- mask++;
- }
- if (!*name) {
- while (*mask=='*') mask++;
- if (!*mask || *mask==';') return 1;
- }
- return 0;
-}
-
-/*************************************************************************
- * PathMatchSpecA
- *
- * NOTES
- * used from COMDLG32
- */
-BOOL WINAPI PathMatchSpecA(LPCSTR name, LPCSTR mask)
-{
- TRACE("%s %s\n",name,mask);
-
- if (!lstrcmpA( mask, "*.*" )) return 1; /* we don't require a period */
-
- while (*mask) {
- if (PathMatchSingleMaskA(name,mask)) return 1; /* helper function */
- while (*mask && *mask!=';') mask++;
- if (*mask==';') {
- mask++;
- while (*mask==' ') mask++; /* masks may be separated by "; " */
- }
- }
- return 0;
-}
-
-/*************************************************************************
- * PathMatchSpecW
- *
- * NOTES
- * used from COMDLG32
- */
-BOOL WINAPI PathMatchSpecW(LPCWSTR name, LPCWSTR mask)
-{
- WCHAR stemp[4];
- TRACE("%s %s\n",debugstr_w(name),debugstr_w(mask));
-
- lstrcpyAtoW(stemp,"*.*");
- if (!lstrcmpW( mask, stemp )) return 1; /* we don't require a period */
-
- while (*mask) {
- if (PathMatchSingleMaskW(name,mask)) return 1; /* helper function */
- while (*mask && *mask!=';') mask++;
- if (*mask==';') {
- mask++;
- while (*mask==' ') mask++; /* masks may be separated by "; " */
- }
- }
- return 0;
-}
-
-/*************************************************************************
- * PathMatchSpec [SHELL32.46]
- *
- * NOTES
- * used from COMDLG32
- */
-BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
-{ if (VERSION_OsIsUnicode())
- return PathMatchSpecW( name, mask );
- return PathMatchSpecA( name, mask );
-}
-/*************************************************************************
- * PathSetDlgItemPathA
- * NOTES
- * use PathCompactPath to make sure, the path fits into the control
- */
-BOOL WINAPI PathSetDlgItemPathA(HWND hDlg, int id, LPCSTR pszPath)
-{ TRACE("%x %x %s\n",hDlg, id, pszPath);
- return SetDlgItemTextA(hDlg, id, pszPath);
-}
-
-/*************************************************************************
- * PathSetDlgItemPathW
- * NOTES
- * use PathCompactPath to make sure, the path fits into the control
- */
-BOOL WINAPI PathSetDlgItemPathW(HWND hDlg, int id, LPCWSTR pszPath)
-{ TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
- return SetDlgItemTextW(hDlg, id, pszPath);
-}
-
-/*************************************************************************
- * PathSetDlgItemPath [SHELL32.48]
- * NOTES
- * use PathCompactPath to make sure, the path fits into the control
- */
-BOOL WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
-{ if (VERSION_OsIsUnicode())
- return PathSetDlgItemPathW(hDlg, id, pszPath);
- return PathSetDlgItemPathA(hDlg, id, pszPath);
-}
-
-/*************************************************************************
- * PathQualifyA
- */
-BOOL WINAPI PathQualifyA(LPCSTR pszPath)
-{ FIXME("%s\n",pszPath);
+ FIXME("%s\n",lpszPath);
return 0;
}
/*************************************************************************
- * PathQualifyW
+ * PathQuoteSpacesW [SHLWAPI.@]
*/
-BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
-{ FIXME("%s\n",debugstr_w(pszPath));
- return 0;
-}
-
-/*************************************************************************
- * PathQualify [SHELL32.49]
- */
-BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
-{ if (VERSION_OsIsUnicode())
- return PathQualifyW(pszPath);
- return PathQualifyA(pszPath);
-}
-
-/*************************************************************************
- * PathResolve [SHELL32.51]
- */
-DWORD WINAPI PathResolve(LPCSTR s,DWORD x2,DWORD x3) {
- FIXME("(%s,0x%08lx,0x%08lx),stub!\n",s,x2,x3);
- return 0;
-}
-
-/*************************************************************************
- * PathGetArgsA
- *
- * NOTES
- * look for next arg in string. handle "quoted" strings
- * returns pointer to argument *AFTER* the space. Or to the \0.
- */
-LPCSTR WINAPI PathGetArgsA(LPCSTR cmdline)
-{ BOOL qflag = FALSE;
-
- TRACE("%s\n",cmdline);
-
- while (*cmdline)
- { if ((*cmdline==' ') && !qflag)
- return cmdline+1;
- if (*cmdline=='"')
- qflag=!qflag;
- cmdline++;
- }
- return cmdline;
-
-}
-
-/*************************************************************************
- * PathGetArgsW
- *
- * NOTES
- * look for next arg in string. handle "quoted" strings
- * returns pointer to argument *AFTER* the space. Or to the \0.
- */
-LPCWSTR WINAPI PathGetArgsW(LPCWSTR cmdline)
-{ BOOL qflag = FALSE;
-
- TRACE("%s\n",debugstr_w(cmdline));
-
- while (*cmdline)
- { if ((*cmdline==' ') && !qflag)
- return cmdline+1;
- if (*cmdline=='"')
- qflag=!qflag;
- cmdline++;
- }
- return cmdline;
-}
-
-/*************************************************************************
- * PathGetArgs [SHELL32.52]
- *
- * NOTES
- * look for next arg in string. handle "quoted" strings
- * returns pointer to argument *AFTER* the space. Or to the \0.
- */
-LPCVOID WINAPI PathGetArgsAW(LPVOID cmdline)
-{ if (VERSION_OsIsUnicode())
- return PathGetArgsW(cmdline);
- return PathGetArgsA(cmdline);
-}
-
-/*************************************************************************
- * PathQuoteSpacesA
- *
- * NOTES
- * basename(char *fn);
- */
-LPSTR WINAPI PathQuoteSpacesA(LPCSTR aptr)
-{ FIXME("%s\n",aptr);
- return 0;
-
-}
-
-/*************************************************************************
- * PathQuoteSpacesW
- *
- * NOTES
- * basename(char *fn);
- */
-LPWSTR WINAPI PathQuoteSpacesW(LPCWSTR wptr)
-{ FIXME("%s\n",debugstr_w(wptr));
+LPWSTR WINAPI PathQuoteSpacesW(LPCWSTR lpszPath)
+{
+ FIXME("%s\n",debugstr_w(lpszPath));
return 0;
}
/*************************************************************************
- * PathQuoteSpaces [SHELL32.55]
- *
- * NOTES
- * basename(char *fn);
+ * PathQuoteSpacesAW [SHELL32.55]
*/
-LPVOID WINAPI PathQuoteSpacesAW (LPCVOID fn)
-{ if(VERSION_OsIsUnicode())
- return PathQuoteSpacesW(fn);
- return PathQuoteSpacesA(fn);
+LPVOID WINAPI PathQuoteSpacesAW (LPCVOID lpszPath)
+{
+ if(VERSION_OsIsUnicode())
+ return PathQuoteSpacesW(lpszPath);
+ return PathQuoteSpacesA(lpszPath);
}
-
/*************************************************************************
- * PathUnquoteSpacesA
+ * PathUnquoteSpacesA [SHLWAPI.@]
*
* NOTES
* unquote string (remove ")
*/
VOID WINAPI PathUnquoteSpacesA(LPSTR str)
-{ DWORD len = lstrlenA(str);
+{
+ DWORD len = lstrlenA(str);
+
TRACE("%s\n",str);
+
if (*str!='"')
return;
if (str[len-1]!='"')
@@ -823,13 +915,11 @@
}
/*************************************************************************
- * PathUnquoteSpacesW
- *
- * NOTES
- * unquote string (remove ")
+ * PathUnquoteSpacesW [SHLWAPI.@]
*/
VOID WINAPI PathUnquoteSpacesW(LPWSTR str)
-{ DWORD len = CRTDLL_wcslen(str);
+{
+ DWORD len = CRTDLL_wcslen(str);
TRACE("%s\n",debugstr_w(str));
@@ -843,10 +933,7 @@
}
/*************************************************************************
- * PathUnquoteSpaces [SHELL32.56]
- *
- * NOTES
- * unquote string (remove ")
+ * PathUnquoteSpacesAW [SHELL32.56]
*/
VOID WINAPI PathUnquoteSpacesAW(LPVOID str)
{
@@ -857,32 +944,631 @@
}
/*************************************************************************
- * PathGetDriveNumberA [SHLWAPI.@]
- *
+ * PathParseIconLocationA [SHLWAPI.@]
*/
-HRESULT WINAPI PathGetDriveNumberA(LPSTR u)
-{ FIXME("%s stub\n",debugstr_a(u));
+int WINAPI PathParseIconLocationA(LPSTR lpszPath)
+{
+ LPSTR lpstrComma = strchr(lpszPath, ',');
+
+ FIXME("%s stub\n", debugstr_a(lpszPath));
+
+ if (lpstrComma && lpstrComma[1])
+ {
+ lpstrComma[0]='\0';
+/* return atoi(&lpstrComma[1]); FIXME */
+ }
return 0;
}
/*************************************************************************
- * PathGetDriveNumberW [SHLWAPI.@]
- *
+ * PathParseIconLocationW [SHLWAPI.@]
*/
-HRESULT WINAPI PathGetDriveNumberW(LPWSTR u)
-{ FIXME("%s stub\n",debugstr_w(u));
+int WINAPI PathParseIconLocationW(LPWSTR lpszPath)
+{
+ LPWSTR lpstrComma = CRTDLL_wcschr(lpszPath, ',');
+
+ FIXME("%s stub\n", debugstr_w(lpszPath));
+
+ if (lpstrComma && lpstrComma[1])
+ {
+ lpstrComma[0]='\0';
+/* return _wtoi(&lpstrComma[1]); FIXME */
+ }
return 0;
}
/*************************************************************************
- * PathGetDriveNumber [SHELL32.57]
- *
+ * PathParseIconLocationAW [SHELL32.249]
*/
-HRESULT WINAPI PathGetDriveNumberAW(LPVOID str)
+int WINAPI PathParseIconLocationAW (LPVOID lpszPath)
{
if(VERSION_OsIsUnicode())
- return PathGetDriveNumberW(str);
- return PathGetDriveNumberA(str);
+ return PathParseIconLocationW(lpszPath);
+ return PathParseIconLocationA(lpszPath);
+}
+
+/*
+ Path Testing
+*/
+/*************************************************************************
+ * PathIsUNCA [SHLWAPI.@]
+ *
+ * NOTES
+ * PathIsUNC(char*path);
+ */
+BOOL WINAPI PathIsUNCA(LPCSTR lpszPath)
+{
+ TRACE("%s\n",lpszPath);
+
+ return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
+}
+
+/*************************************************************************
+ * PathIsUNCW [SHLWAPI.@]
+ */
+BOOL WINAPI PathIsUNCW(LPCWSTR lpszPath)
+{
+ TRACE("%s\n",debugstr_w(lpszPath));
+
+ return (lpszPath && (lpszPath[0]=='\\') && (lpszPath[1]=='\\'));
+}
+
+/*************************************************************************
+ * PathIsUNCAW [SHELL32.39]
+ */
+BOOL WINAPI PathIsUNCAW (LPCVOID lpszPath)
+{
+ if (VERSION_OsIsUnicode())
+ return PathIsUNCW( lpszPath );
+ return PathIsUNCA( lpszPath );
+}
+
+/*************************************************************************
+ * PathIsRelativeA [SHLWAPI.@]
+ */
+BOOL WINAPI PathIsRelativeA (LPCSTR lpszPath)
+{
+ TRACE("lpszPath=%s\n",lpszPath);
+
+ return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
+}
+
+/*************************************************************************
+ * PathIsRelativeW [SHLWAPI.@]
+ */
+BOOL WINAPI PathIsRelativeW (LPCWSTR lpszPath)
+{
+ TRACE("lpszPath=%s\n",debugstr_w(lpszPath));
+
+ return (lpszPath && (lpszPath[0]!='\\' && lpszPath[1]!=':'));
+}
+
+/*************************************************************************
+ * PathIsRelativeAW [SHELL32.40]
+ */
+BOOL WINAPI PathIsRelativeAW (LPCVOID lpszPath)
+{
+ if (VERSION_OsIsUnicode())
+ return PathIsRelativeW( lpszPath );
+ return PathIsRelativeA( lpszPath );
+}
+
+/*************************************************************************
+ * PathIsRootA [SHLWAPI.@]
+ *
+ * notes
+ * TRUE if the path points to a root directory
+ */
+BOOL WINAPI PathIsRootA(LPCSTR lpszPath)
+{
+ TRACE("%s\n",lpszPath);
+
+ /* X:\ */
+ if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
+ return TRUE;
+
+ /* "\" */
+ if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
+ return TRUE;
+
+ /* UNC "\\<computer>\<share>" */
+ if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
+ {
+ int foundbackslash = 0;
+ lpszPath += 2;
+ while (*lpszPath)
+ {
+ if (*(lpszPath++)=='\\') foundbackslash++;
+ }
+ if (foundbackslash==1)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*************************************************************************
+ * PathIsRootW [SHLWAPI.@]
+ */
+BOOL WINAPI PathIsRootW(LPCWSTR lpszPath)
+{
+ TRACE("%s\n",debugstr_w(lpszPath));
+
+ /* X:\ */
+ if (lpszPath[1]==':' && lpszPath[2]=='\\' && lpszPath[3]=='\0')
+ return TRUE;
+
+ /* "\" */
+ if (lpszPath[0]=='\\' && lpszPath[1]=='\0')
+ return TRUE;
+
+ /* UNC "\\<computer>\<share>" */
+ if (lpszPath[0]=='\\' && lpszPath[1]=='\\')
+ {
+ int foundbackslash = 0;
+ lpszPath += 2;
+ while (*lpszPath)
+ {
+ if (*(lpszPath++)=='\\') foundbackslash++;
+ }
+ if (foundbackslash==1)
+ return TRUE;
+ }
+ return FALSE;
+
+}
+
+/*************************************************************************
+ * PathIsRootAW [SHELL32.29]
+ */
+BOOL WINAPI PathIsRootAW(LPCVOID lpszPath)
+{
+ if (VERSION_OsIsUnicode())
+ return PathIsRootW(lpszPath);
+ return PathIsRootA(lpszPath);
+}
+
+/*************************************************************************
+ * PathIsExeA [internal]
+ */
+BOOL WINAPI PathIsExeA (LPCSTR lpszPath)
+{
+ LPCSTR lpszExtension = PathGetExtensionA(lpszPath);
+ int i = 0;
+ static char * lpszExtensions[6] = {"exe", "com", "pid", "cmd", "bat", NULL };
+
+ TRACE("path=%s\n",lpszPath);
+
+ for(i=0; lpszExtensions[i]; i++)
+ if (!strcasecmp(lpszExtension,lpszExtensions[i])) return TRUE;
+
+ return FALSE;
+}
+
+/*************************************************************************
+ * PathIsExeW [internal]
+ */
+BOOL WINAPI PathIsExeW (LPCWSTR lpszPath)
+{
+ LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
+ int i = 0;
+ static WCHAR lpszExtensions[6][4] =
+ {{'e','x','e','\0'}, {'c','o','m','\0'}, {'p','i','d','\0'},
+ {'c','m','d','\0'}, {'b','a','t','\0'}, {'\0'} };
+
+ TRACE("path=%s\n",debugstr_w(lpszPath));
+
+ for(i=0; lpszExtensions[i]; i++)
+ if (!CRTDLL__wcsicmp(lpszExtension,lpszExtensions[i])) return TRUE;
+
+ return FALSE;
+}
+
+/*************************************************************************
+ * PathIsExeAW [SHELL32.43]
+ */
+BOOL WINAPI PathIsExeAW (LPCVOID path)
+{
+ if (VERSION_OsIsUnicode())
+ return PathIsExeW (path);
+ return PathIsExeA(path);
+}
+
+/*************************************************************************
+ * PathIsDirectoryA [SHLWAPI.@]
+ */
+BOOL WINAPI PathIsDirectoryA(LPCSTR lpszPath)
+{
+ HANDLE hFile;
+ WIN32_FIND_DATAA stffile;
+
+ TRACE("%s\n", debugstr_a(lpszPath));
+
+ hFile = FindFirstFileA(lpszPath, &stffile);
+
+ if ( hFile != INVALID_HANDLE_VALUE )
+ {
+ FindClose (hFile);
+ return (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
+ }
+
+ return FALSE;
+}
+
+/*************************************************************************
+ * PathIsDirectoryW [SHLWAPI.@]
+ */
+BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
+{
+ HANDLE hFile;
+ WIN32_FIND_DATAW stffile;
+
+ TRACE("%s\n", debugstr_w(lpszPath));
+
+ hFile = FindFirstFileW(lpszPath, &stffile);
+
+ if ( hFile != INVALID_HANDLE_VALUE )
+ {
+ FindClose (hFile);
+ return (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
+ }
+
+ return FALSE;
+}
+
+/*************************************************************************
+ * PathIsDirectoryAW [SHELL32.159]
+ */
+BOOL WINAPI PathIsDirectoryAW (LPCVOID lpszPath)
+{
+ if (VERSION_OsIsUnicode())
+ return PathIsDirectoryW (lpszPath);
+ return PathIsDirectoryA (lpszPath);
+}
+
+/*************************************************************************
+ * PathFileExistsA [SHLWAPI.@]
+ *
+ * NOTES
+ * file_exists(char *fn);
+ */
+BOOL WINAPI PathFileExistsA(LPCSTR lpszPath)
+{
+ TRACE("%s\n",lpszPath);
+ return (GetFileAttributesA(lpszPath)!=-1);
+}
+
+/*************************************************************************
+ * PathFileExistsW [SHLWAPI.@]
+ */
+BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
+{
+ TRACE("%s\n",debugstr_w(lpszPath));
+ return (GetFileAttributesW(lpszPath)!=-1);
+}
+
+/*************************************************************************
+ * PathFileExistsAW [SHELL32.45]
+ */
+BOOL WINAPI PathFileExistsAW (LPCVOID lpszPath)
+{
+ if (VERSION_OsIsUnicode())
+ return PathFileExistsW (lpszPath);
+ return PathFileExistsA (lpszPath);
+}
+
+/*************************************************************************
+ * PathMatchSingleMaskA [internal]
+ *
+ * NOTES
+ * internal (used by PathMatchSpec)
+ */
+static BOOL PathMatchSingleMaskA(LPCSTR name, LPCSTR mask)
+{
+ while (*name && *mask && *mask!=';')
+ {
+ if (*mask=='*')
+ {
+ do
+ {
+ if (PathMatchSingleMaskA(name,mask+1)) return 1; /* try substrings */
+ } while (*name++);
+ return 0;
+ }
+ if (toupper(*mask)!=toupper(*name) && *mask!='?') return 0;
+ name++;
+ mask++;
+ }
+ if (!*name)
+ {
+ while (*mask=='*') mask++;
+ if (!*mask || *mask==';') return 1;
+ }
+ return 0;
+}
+
+/*************************************************************************
+ * PathMatchSingleMaskW [internal]
+ */
+static BOOL PathMatchSingleMaskW(LPCWSTR name, LPCWSTR mask)
+{
+ while (*name && *mask && *mask!=';')
+ {
+ if (*mask=='*')
+ {
+ do
+ {
+ if (PathMatchSingleMaskW(name,mask+1)) return 1; /* try substrings */
+ } while (*name++);
+ return 0;
+ }
+ if (towupper(*mask)!=towupper(*name) && *mask!='?') return 0;
+ name++;
+ mask++;
+ }
+ if (!*name)
+ {
+ while (*mask=='*') mask++;
+ if (!*mask || *mask==';') return 1;
+ }
+ return 0;
+}
+/*************************************************************************
+ * PathMatchSpecA [SHLWAPI.@]
+ *
+ * NOTES
+ * used from COMDLG32
+ */
+BOOL WINAPI PathMatchSpecA(LPCSTR name, LPCSTR mask)
+{
+ TRACE("%s %s\n",name,mask);
+
+ if (!lstrcmpA( mask, "*.*" )) return 1; /* we don't require a period */
+
+ while (*mask)
+ {
+ if (PathMatchSingleMaskA(name,mask)) return 1; /* helper function */
+ while (*mask && *mask!=';') mask++;
+ if (*mask==';')
+ {
+ mask++;
+ while (*mask==' ') mask++; /* masks may be separated by "; " */
+ }
+ }
+ return 0;
+}
+
+/*************************************************************************
+ * PathMatchSpecW [SHLWAPI.@]
+ */
+BOOL WINAPI PathMatchSpecW(LPCWSTR name, LPCWSTR mask)
+{
+ WCHAR stemp[4];
+ TRACE("%s %s\n",debugstr_w(name),debugstr_w(mask));
+
+ lstrcpyAtoW(stemp,"*.*");
+ if (!lstrcmpW( mask, stemp )) return 1; /* we don't require a period */
+
+ while (*mask)
+ {
+ if (PathMatchSingleMaskW(name,mask)) return 1; /* helper function */
+ while (*mask && *mask!=';') mask++;
+ if (*mask==';')
+ {
+ mask++;
+ while (*mask==' ') mask++; /* masks may be separated by "; " */
+ }
+ }
+ return 0;
+}
+
+/*************************************************************************
+ * PathMatchSpecAW [SHELL32.46]
+ */
+BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
+{
+ if (VERSION_OsIsUnicode())
+ return PathMatchSpecW( name, mask );
+ return PathMatchSpecA( name, mask );
+}
+
+/*************************************************************************
+ * PathIsSameRootA [SHLWAPI.@]
+ *
+ * FIXME
+ * what to do with "\path" ??
+ */
+BOOL WINAPI PathIsSameRootA(LPCSTR lpszPath1, LPCSTR lpszPath2)
+{
+ TRACE("%s %s\n", lpszPath1, lpszPath2);
+
+ if (PathIsRelativeA(lpszPath1) || PathIsRelativeA(lpszPath2)) return FALSE;
+
+ /* usual path */
+ if ( toupper(lpszPath1[0])==toupper(lpszPath2[0]) &&
+ lpszPath1[1]==':' && lpszPath2[1]==':' &&
+ lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
+ return TRUE;
+
+ /* UNC */
+ if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
+ lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
+ {
+ int pos=2, bsfound=0;
+ while (lpszPath1[pos] && lpszPath2[pos] &&
+ (lpszPath1[pos] == lpszPath2[pos]))
+ {
+ if (lpszPath1[pos]=='\\') bsfound++;
+ if (bsfound == 2) return TRUE;
+ pos++;
+ }
+ return (lpszPath1[pos] == lpszPath2[pos]);
+ }
+ return FALSE;
+}
+
+/*************************************************************************
+ * PathIsSameRootW [SHLWAPI.@]
+ */
+BOOL WINAPI PathIsSameRootW(LPCWSTR lpszPath1, LPCWSTR lpszPath2)
+{
+ TRACE("%s %s\n", debugstr_w(lpszPath1), debugstr_w(lpszPath2));
+
+ if (PathIsRelativeW(lpszPath1) || PathIsRelativeW(lpszPath2)) return FALSE;
+
+ /* usual path */
+ if ( towupper(lpszPath1[0])==towupper(lpszPath2[0]) &&
+ lpszPath1[1]==':' && lpszPath2[1]==':' &&
+ lpszPath1[2]=='\\' && lpszPath2[2]=='\\')
+ return TRUE;
+
+ /* UNC */
+ if (lpszPath1[0]=='\\' && lpszPath2[0]=='\\' &&
+ lpszPath1[1]=='\\' && lpszPath2[1]=='\\')
+ {
+ int pos=2, bsfound=0;
+ while (lpszPath1[pos] && lpszPath2[pos] &&
+ (lpszPath1[pos] == lpszPath2[pos]))
+ {
+ if (lpszPath1[pos]=='\\') bsfound++;
+ if (bsfound == 2) return TRUE;
+ pos++;
+ }
+ return (lpszPath1[pos] == lpszPath2[pos]);
+ }
+ return FALSE;
+}
+
+/*************************************************************************
+ * PathIsSameRootAW [SHELL32.650]
+ */
+BOOL WINAPI PathIsSameRootAW(LPCVOID lpszPath1, LPCVOID lpszPath2)
+{
+ if (VERSION_OsIsUnicode())
+ return PathIsSameRootW(lpszPath1, lpszPath2);
+ return PathIsSameRootA(lpszPath1, lpszPath2);
+}
+
+/*************************************************************************
+ * PathIsURLA
+ */
+BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
+{
+ LPSTR lpstrRes;
+ int iSize, i=0;
+ static LPSTR SupportedProtocol[] =
+ {"http","https","ftp","gopher","file","mailto",NULL};
+
+ if(!lpstrPath) return FALSE;
+
+ /* get protocol */
+ lpstrRes = strchr(lpstrPath,':');
+ if(!lpstrRes) return FALSE;
+ iSize = lpstrRes - lpstrPath;
+
+ while(SupportedProtocol[i])
+ {
+ if (iSize == strlen(SupportedProtocol[i]))
+ if(!strncasecmp(lpstrPath, SupportedProtocol[i], iSize));
+ return TRUE;
+ i++;
+ }
+
+ return FALSE;
+}
+
+/*************************************************************************
+ * PathIsURLW
+ */
+BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
+{
+ LPWSTR lpstrRes;
+ int iSize, i=0;
+ static WCHAR SupportedProtocol[7][7] =
+ {{'h','t','t','p','\0'},{'h','t','t','p','s','\0'},{'f','t','p','\0'},
+ {'g','o','p','h','e','r','\0'},{'f','i','l','e','\0'},
+ {'m','a','i','l','t','o','\0'},{0}};
+
+ if(!lpstrPath) return FALSE;
+
+ /* get protocol */
+ lpstrRes = CRTDLL_wcschr(lpstrPath,':');
+ if(!lpstrRes) return FALSE;
+ iSize = lpstrRes - lpstrPath;
+
+ while(SupportedProtocol[i])
+ {
+ if (iSize == CRTDLL_wcslen(SupportedProtocol[i]))
+ if(!CRTDLL__wcsnicmp(lpstrPath, SupportedProtocol[i], iSize));
+ return TRUE;
+ i++;
+ }
+
+ return FALSE;
+}
+
+/*************************************************************************
+ * IsLFNDriveA [SHELL32.119]
+ *
+ * NOTES
+ * exported by ordinal Name
+ */
+BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath)
+{
+ DWORD fnlen;
+
+ if (!GetVolumeInformationA(lpszPath,NULL,0,NULL,&fnlen,NULL,NULL,0))
+ return FALSE;
+ return fnlen>12;
+}
+
+/*
+ Creating Something Unique
+*/
+/*************************************************************************
+ * PathMakeUniqueNameA [internal]
+ */
+BOOL WINAPI PathMakeUniqueNameA(
+ LPSTR lpszBuffer,
+ DWORD dwBuffSize,
+ LPCSTR lpszShortName,
+ LPCSTR lpszLongName,
+ LPCSTR lpszPathName)
+{
+ FIXME("%p %lu %s %s %s stub\n",
+ lpszBuffer, dwBuffSize, debugstr_a(lpszShortName),
+ debugstr_a(lpszLongName), debugstr_a(lpszPathName));
+ return TRUE;
+}
+
+/*************************************************************************
+ * PathMakeUniqueNameW [internal]
+ */
+BOOL WINAPI PathMakeUniqueNameW(
+ LPWSTR lpszBuffer,
+ DWORD dwBuffSize,
+ LPCWSTR lpszShortName,
+ LPCWSTR lpszLongName,
+ LPCWSTR lpszPathName)
+{
+ FIXME("%p %lu %s %s %s stub\n",
+ lpszBuffer, dwBuffSize, debugstr_w(lpszShortName),
+ debugstr_w(lpszLongName), debugstr_w(lpszPathName));
+ return TRUE;
+}
+
+/*************************************************************************
+ * PathMakeUniqueNameAW [SHELL32.47]
+ */
+BOOL WINAPI PathMakeUniqueNameAW(
+ LPVOID lpszBuffer,
+ DWORD dwBuffSize,
+ LPCVOID lpszShortName,
+ LPCVOID lpszLongName,
+ LPCVOID lpszPathName)
+{
+ if (VERSION_OsIsUnicode())
+ return PathMakeUniqueNameW(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
+ return PathMakeUniqueNameA(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName);
}
/*************************************************************************
@@ -891,75 +1577,52 @@
* NOTES
* exported by ordinal
*/
-BOOL WINAPI PathYetAnotherMakeUniqueNameA(LPDWORD x,LPDWORD y) {
- FIXME("(%p,%p):stub.\n",x,y);
+BOOL WINAPI PathYetAnotherMakeUniqueNameA(
+ LPSTR lpszBuffer,
+ LPCSTR lpszPathName,
+ LPCSTR lpszShortName,
+ LPCSTR lpszLongName)
+{
+ FIXME("(%p,%p, %p ,%p):stub.\n",
+ lpszBuffer, lpszPathName, lpszShortName, lpszLongName);
return TRUE;
}
-/*************************************************************************
- * IsLFNDriveA [SHELL32.119]
- *
- * NOTES
- * exported by ordinal Name
+
+/*
+ cleaning and resolving paths
*/
-BOOL WINAPI IsLFNDriveA(LPCSTR path) {
- DWORD fnlen;
-
- if (!GetVolumeInformationA(path,NULL,0,NULL,&fnlen,NULL,NULL,0))
- return FALSE;
- return fnlen>12;
-}
/*************************************************************************
- * PathFindOnPathA
+ * PathFindOnPathA [SHELL32.145]
*/
BOOL WINAPI PathFindOnPathA(LPSTR sFile, LPCSTR sOtherDirs)
-{ FIXME("%s %s\n",sFile, sOtherDirs);
+{
+ FIXME("%s %s\n",sFile, sOtherDirs);
return FALSE;
}
/*************************************************************************
- * PathFindOnPathW
+ * PathFindOnPathW [SHELL32]
*/
BOOL WINAPI PathFindOnPathW(LPWSTR sFile, LPCWSTR sOtherDirs)
-{ FIXME("%s %s\n",debugstr_w(sFile), debugstr_w(sOtherDirs));
+{
+ FIXME("%s %s\n",debugstr_w(sFile), debugstr_w(sOtherDirs));
return FALSE;
}
/*************************************************************************
- * PathFindOnPath [SHELL32.145]
+ * PathFindOnPathAW [SHELL32]
*/
BOOL WINAPI PathFindOnPathAW(LPVOID sFile, LPCVOID sOtherDirs)
-{ if (VERSION_OsIsUnicode())
+{
+ if (VERSION_OsIsUnicode())
return PathFindOnPathW(sFile, sOtherDirs);
return PathFindOnPathA(sFile, sOtherDirs);
}
/*************************************************************************
- * PathGetExtension [SHELL32.158]
- *
- * NOTES
- * exported by ordinal
- */
-LPCSTR WINAPI PathGetExtensionA(LPCSTR path,DWORD y,DWORD z)
-{ TRACE("(%s,%08lx,%08lx)\n",path,y,z);
- path = PathFindExtensionA(path);
- return *path?(path+1):path;
-}
-LPCWSTR WINAPI PathGetExtensionW(LPCWSTR path,DWORD y,DWORD z)
-{ TRACE("(%s, %08lx, %08lx)\n",debugstr_w(path),y,z);
- path = PathFindExtensionW(path);
- return *path?(path+1):path;
-}
-LPCVOID WINAPI PathGetExtensionAW(LPCVOID path,DWORD y,DWORD z)
-{ if (VERSION_OsIsUnicode())
- return PathGetExtensionW(path,y,z);
- return PathGetExtensionA(path,y,z);
-}
-
-/*************************************************************************
- * PathCleanupSpec [SHELL32.171]
- *
+ * PathCleanupSpecA [SHELL32.171]
*/
DWORD WINAPI PathCleanupSpecA(LPSTR x, LPSTR y)
{
@@ -967,12 +1630,18 @@
return TRUE;
}
+/*************************************************************************
+ * PathCleanupSpecA [SHELL32]
+ */
DWORD WINAPI PathCleanupSpecW(LPWSTR x, LPWSTR y)
{
FIXME("(%p %s, %p %s) stub\n",x,debugstr_w(x),y,debugstr_w(y));
return TRUE;
}
+/*************************************************************************
+ * PathCleanupSpecAW [SHELL32]
+ */
DWORD WINAPI PathCleanupSpecAW (LPVOID x, LPVOID y)
{
if (VERSION_OsIsUnicode())
@@ -981,56 +1650,158 @@
}
/*************************************************************************
- * SheGetDirW [SHELL32.281]
- *
+ * PathQualifyA [SHELL32]
*/
-HRESULT WINAPI SheGetDirW(LPWSTR u, LPWSTR v)
-{ FIXME("%p %p stub\n",u,v);
+BOOL WINAPI PathQualifyA(LPCSTR pszPath)
+{
+ FIXME("%s\n",pszPath);
return 0;
}
/*************************************************************************
- * SheChangeDirW [SHELL32.274]
- *
+ * PathQualifyW [SHELL32]
*/
-HRESULT WINAPI SheChangeDirW(LPWSTR u)
-{ FIXME("(%s),stub\n",debugstr_w(u));
+BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
+{
+ FIXME("%s\n",debugstr_w(pszPath));
return 0;
}
/*************************************************************************
-* PathProcessCommand [SHELL32.653]
-*/
-HRESULT WINAPI PathProcessCommandA (LPSTR lpCommand, LPSTR v, DWORD w, DWORD x)
-{
- FIXME("%p(%s) %p 0x%04lx 0x%04lx stub\n",
- lpCommand, lpCommand, v, w,x );
- lstrcpyA(v, lpCommand);
- return 0;
-}
-
-HRESULT WINAPI PathProcessCommandW (LPWSTR lpCommand, LPSTR v, DWORD w, DWORD x)
-{
- FIXME("(%p %s, %p, 0x%04lx, 0x%04lx) stub\n",
- lpCommand, debugstr_w(lpCommand), v, w,x );
- return 0;
-}
-
-HRESULT WINAPI PathProcessCommandAW (LPVOID lpCommand, LPSTR v, DWORD w, DWORD x)
+ * PathQualifyAW [SHELL32]
+ */
+BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
{
if (VERSION_OsIsUnicode())
- return PathProcessCommandW(lpCommand, v, w, x);
- return PathProcessCommandA(lpCommand, v, w, x);
+ return PathQualifyW(pszPath);
+ return PathQualifyA(pszPath);
}
/*************************************************************************
- * SHGetSpecialFolderPathA
+ * PathResolveA [SHELL32.51]
+ */
+BOOL WINAPI PathResolveA(
+ LPSTR lpszPath,
+ LPCSTR *alpszPaths,
+ DWORD dwFlags)
+{
+ FIXME("(%s,%p,0x%08lx),stub!\n",
+ lpszPath, *alpszPaths, dwFlags);
+ return 0;
+}
+
+/*************************************************************************
+ * PathResolveW [SHELL32]
+ */
+BOOL WINAPI PathResolveW(
+ LPWSTR lpszPath,
+ LPCWSTR *alpszPaths,
+ DWORD dwFlags)
+{
+ FIXME("(%s,%p,0x%08lx),stub!\n",
+ debugstr_w(lpszPath), debugstr_w(*alpszPaths), dwFlags);
+ return 0;
+}
+
+/*************************************************************************
+ * PathResolveAW [SHELL32]
+ */
+BOOL WINAPI PathResolveAW(
+ LPVOID lpszPath,
+ LPCVOID *alpszPaths,
+ DWORD dwFlags)
+{
+ if (VERSION_OsIsUnicode())
+ return PathResolveW(lpszPath, (LPCWSTR*)alpszPaths, dwFlags);
+ return PathResolveA(lpszPath, (LPCSTR*)alpszPaths, dwFlags);
+}
+
+/*************************************************************************
+* PathProcessCommandA [SHELL32.653]
+*/
+HRESULT WINAPI PathProcessCommandA (
+ LPCSTR lpszPath,
+ LPSTR lpszBuff,
+ DWORD dwBuffSize,
+ DWORD dwFlags)
+{
+ FIXME("%s %p 0x%04lx 0x%04lx stub\n",
+ lpszPath, lpszBuff, dwBuffSize, dwFlags);
+ lstrcpyA(lpszBuff, lpszPath);
+ return 0;
+}
+
+/*************************************************************************
+* PathProcessCommandW
+*/
+HRESULT WINAPI PathProcessCommandW (
+ LPCWSTR lpszPath,
+ LPWSTR lpszBuff,
+ DWORD dwBuffSize,
+ DWORD dwFlags)
+{
+ FIXME("(%s, %p, 0x%04lx, 0x%04lx) stub\n",
+ debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags);
+ lstrcpyW(lpszBuff, lpszPath);
+ return 0;
+}
+
+/*************************************************************************
+* PathProcessCommandAW
+*/
+HRESULT WINAPI PathProcessCommandAW (
+ LPCVOID lpszPath,
+ LPVOID lpszBuff,
+ DWORD dwBuffSize,
+ DWORD dwFlags)
+{
+ if (VERSION_OsIsUnicode())
+ return PathProcessCommandW(lpszPath, lpszBuff, dwBuffSize, dwFlags);
+ return PathProcessCommandA(lpszPath, lpszBuff, dwBuffSize, dwFlags);
+}
+
+/*
+ special
+*/
+
+/*************************************************************************
+ * PathSetDlgItemPathA
+ *
+ * NOTES
+ * use PathCompactPath to make sure, the path fits into the control
+ */
+BOOL WINAPI PathSetDlgItemPathA(HWND hDlg, int id, LPCSTR pszPath)
+{ TRACE("%x %x %s\n",hDlg, id, pszPath);
+ return SetDlgItemTextA(hDlg, id, pszPath);
+}
+
+/*************************************************************************
+ * PathSetDlgItemPathW
+ */
+BOOL WINAPI PathSetDlgItemPathW(HWND hDlg, int id, LPCWSTR pszPath)
+{ TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
+ return SetDlgItemTextW(hDlg, id, pszPath);
+}
+
+/*************************************************************************
+ * PathSetDlgItemPathAW
+ */
+BOOL WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
+{ if (VERSION_OsIsUnicode())
+ return PathSetDlgItemPathW(hDlg, id, pszPath);
+ return PathSetDlgItemPathA(hDlg, id, pszPath);
+}
+
+
+/*************************************************************************
+ * SHGetSpecialFolderPathA [SHELL32.175]
*
* converts csidl to path
*
*/
static char * szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
+static char * szSHUserFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
BOOL WINAPI SHGetSpecialFolderPathA (
HWND hwndOwner,
@@ -1174,40 +1945,46 @@
return FALSE;
}
- if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hKey,&dwDisp))
- {
- return FALSE;
- }
+ /* user shell folders */
+ if (RegCreateKeyExA(hRootKey,szSHUserFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
{
- /* value not existing */
- if (bRelative)
+ RegCloseKey(hKey);
+
+ /* shell folders */
+ if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE;
+
+ if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
{
- GetWindowsDirectoryA(szPath, MAX_PATH);
- PathAddBackslashA(szPath);
- strcat(szPath, szDefaultPath);
+
+ /* value not existing */
+ if (bRelative)
+ {
+ GetWindowsDirectoryA(szPath, MAX_PATH);
+ PathAddBackslashA(szPath);
+ strcat(szPath, szDefaultPath);
+ }
+ else
+ {
+ strcpy(szPath, "C:\\"); /* fixme ??? */
+ strcat(szPath, szDefaultPath);
+ }
+ RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
}
- else
- {
- strcpy(szPath, szDefaultPath);
- }
- if (bCreate)
- {
- CreateDirectoryA(szPath,NULL);
- }
- RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
}
RegCloseKey(hKey);
+ if (bCreate && CreateDirectoryA(szPath,NULL))
+ {
+ MESSAGE("Created not existing system directory '%s'\n", szPath);
+ }
+
return TRUE;
}
/*************************************************************************
* SHGetSpecialFolderPathW
- *
- * converts csidl to path
- *
*/
BOOL WINAPI SHGetSpecialFolderPathW (
HWND hwndOwner,
@@ -1228,10 +2005,7 @@
}
/*************************************************************************
- * SHGetSpecialFolderPath [SHELL32.175]
- *
- * converts csidl to path
- *
+ * SHGetSpecialFolderPathAW
*/
BOOL WINAPI SHGetSpecialFolderPathAW (
HWND hwndOwner,
@@ -1246,97 +2020,171 @@
}
/*************************************************************************
- * PathRemoveBackslashA
+ * PathCanonicalizeA
*
- * If the path ends in a backslash it is replaced by a NULL
- * and the address of the NULL is returned
- * Otherwise
- * the address of the last character is returned.
- *
+ * FIXME
+ * returnvalue
*/
-LPSTR WINAPI PathRemoveBackslashA( LPSTR lpPath )
+
+BOOL WINAPI PathCanonicalizeA(LPSTR pszBuf, LPCSTR pszPath)
{
- LPSTR p = lpPath;
+ int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = strlen(pszPath);
+ BOOL bModifyed = FALSE;
+
+ TRACE("%p %s\n", pszBuf, pszPath);
- while (*lpPath) p = lpPath++;
- if ( *p == (CHAR)'\\') *p = (CHAR)'\0';
- return p;
-}
+ pszBuf[OffsetDst]='\0';
-/*************************************************************************
- * PathRemoveBackslashW
- *
- */
-LPWSTR WINAPI PathRemoveBackslashW( LPWSTR lpPath )
-{
- LPWSTR p = lpPath;
+ /* keep the root of the path */
+ if( LenSrc && (pszPath[OffsetSrc]=='\\'))
+ {
+ pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
+ }
+ else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
+ {
+ pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
+ pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
+ if (LenSrc && (pszPath[OffsetSrc] == '\\'))
+ {
+ pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
+ if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
+ {
+ /* C:\. */
+ OffsetSrc++; LenSrc--; bModifyed = TRUE;
+ }
+ else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
+ {
+ /* C:\.. */
+ OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
+ }
+ }
+ }
- while (*lpPath); p = lpPath++;
- if ( *p == (WCHAR)'\\') *p = (WCHAR)'\0';
- return p;
+ /* ".\" at the beginning of the path */
+ if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
+ {
+ OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
+ }
+
+ while ( LenSrc )
+ {
+ if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
+ {
+ /* "\.." found, go one deeper */
+ while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
+ OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
+ if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
+ pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
+ }
+ else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
+ {
+ /* "\." found, skip it */
+ OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
+ }
+ else
+ {
+ pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
+ }
+ }
+ pszBuf[OffsetDst] = '\0';
+ TRACE("-- %s %u\n", pszBuf, bModifyed);
+ return bModifyed;
+}
+
+
+/*************************************************************************
+ * PathCanonicalizeW
+ *
+ * FIXME
+ * returnvalue
+ */
+BOOL WINAPI PathCanonicalizeW(LPWSTR pszBuf, LPCWSTR pszPath)
+{
+ int OffsetMin = 0, OffsetSrc = 0, OffsetDst = 0, LenSrc = lstrlenW(pszPath);
+ BOOL bModifyed = FALSE;
+
+ TRACE("%p %s\n", pszBuf, debugstr_w(pszPath));
+
+ pszBuf[OffsetDst]='\0';
+
+ /* keep the root of the path */
+ if( LenSrc && (pszPath[OffsetSrc]=='\\'))
+ {
+ pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
+ }
+ else if ( (LenSrc >= 2) && (pszPath[OffsetSrc+1] == ':'))
+ {
+ pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
+ pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
+ if (LenSrc && (pszPath[OffsetSrc] == '\\'))
+ {
+ pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; OffsetMin++; LenSrc--;
+ if (LenSrc == 1 && pszPath[OffsetSrc]=='.')
+ {
+ /* C:\. */
+ OffsetSrc++; LenSrc--; bModifyed = TRUE;
+ }
+ else if (LenSrc == 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='.')
+ {
+ /* C:\.. */
+ OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
+ }
+ }
+ }
+
+ /* ".\" at the beginning of the path */
+ if (LenSrc >= 2 && pszPath[OffsetSrc]=='.' && pszPath[OffsetSrc+1]=='\\')
+ {
+ OffsetSrc+=2; LenSrc-=2; bModifyed = TRUE;
+ }
+
+ while ( LenSrc )
+ {
+ if((LenSrc>=3) && (pszPath[OffsetSrc]=='\\') && (pszPath[OffsetSrc+1]=='.') && (pszPath[OffsetSrc+2]=='.'))
+ {
+ /* "\.." found, go one deeper */
+ while((OffsetDst > OffsetMin) && (pszBuf[OffsetDst]!='\\')) OffsetDst--;
+ OffsetSrc += 3; LenSrc -= 3; bModifyed = TRUE;
+ if(OffsetDst == OffsetMin && pszPath[OffsetSrc]=='\\') OffsetSrc++;
+ pszBuf[OffsetDst] = '\0'; /* important for \..\.. */
+ }
+ else if(LenSrc>=2 && pszPath[OffsetSrc]=='\\' && pszPath[OffsetSrc+1]=='.' )
+ {
+ /* "\." found, skip it */
+ OffsetSrc += 2; LenSrc-=2; bModifyed = TRUE;
+ }
+ else
+ {
+ pszBuf[OffsetDst++] = pszPath[OffsetSrc++]; LenSrc--;
+ }
+ }
+ pszBuf[OffsetDst] = '\0';
+ TRACE("-- %s %u\n", debugstr_w(pszBuf), bModifyed);
+ return bModifyed;
}
/*************************************************************************
- * PathIsURLA
- *
+ * PathFindNextComponentA
*/
-BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
+LPSTR WINAPI PathFindNextComponentA(LPCSTR pszPath)
{
- LPSTR lpstrRes;
- char lpstrFileType[10] = "";
- int iSize;
- int i = 0;
- /* sanity check */
- if(!lpstrPath)
- return FALSE;
-
- /* get protocol */
- /* protocol://location */
- if(!(lpstrRes = strchr(lpstrPath,':')))
- {
- return FALSE;
- }
- iSize = lpstrRes - lpstrPath;
- if(iSize > sizeof(lpstrFileType))
- return FALSE;
-
- strncpy(lpstrFileType,lpstrPath,iSize);
-
- while(strlen(SupportedProtocol[i]))
- {
- if(!_stricmp(lpstrFileType,SupportedProtocol[i++]))
- return TRUE;
- }
-
- return FALSE;
-}
-
-/*************************************************************************
- * PathIsDirectoryA
- *
- */
-BOOL WINAPI PathIsDirectoryA(LPCSTR pszPath)
-{
- FIXME("%s\n", debugstr_a(pszPath));
- return TRUE;
+ while( *pszPath )
+ {
+ if(*pszPath++=='\\')
+ return (LPSTR)((*pszPath)? pszPath : NULL);
+ }
+ return NULL;
}
/*************************************************************************
- * PathIsDirectoryW
- *
+ * PathFindNextComponentW
*/
-BOOL WINAPI PathIsDirectoryW(LPCWSTR pszPath)
+LPWSTR WINAPI PathFindNextComponentW(LPCWSTR pszPath)
{
- FIXME("%s\n", debugstr_w(pszPath));
- return TRUE;
-}
-/*************************************************************************
- * PathIsDirectory
- *
- */
-BOOL WINAPI PathIsDirectoryAW (LPCVOID pszPath)
-{
- if (VERSION_OsIsUnicode())
- return PathIsDirectoryW (pszPath);
- return PathIsDirectoryA (pszPath);
+ while( *pszPath )
+ {
+ if(*pszPath++=='\\')
+ return (LPWSTR)((*pszPath)? pszPath : NULL);
+ }
+ return NULL;
}