Rewrite PathCreateFromUrl.

This commit is contained in:
Huw Davies 2004-10-05 18:07:14 +00:00 committed by Alexandre Julliard
parent d062924f66
commit 1685e8c65e
2 changed files with 88 additions and 60 deletions

View File

@ -32,6 +32,7 @@
#include "wingdi.h" #include "wingdi.h"
#include "winuser.h" #include "winuser.h"
#include "winreg.h" #include "winreg.h"
#include "winternl.h"
#define NO_SHLWAPI_STREAM #define NO_SHLWAPI_STREAM
#include "shlwapi.h" #include "shlwapi.h"
#include "wine/debug.h" #include "wine/debug.h"
@ -3205,6 +3206,42 @@ LPWSTR WINAPI PathSkipRootW(LPCWSTR lpszPath)
/************************************************************************* /*************************************************************************
* PathCreateFromUrlA [SHLWAPI.@] * PathCreateFromUrlA [SHLWAPI.@]
* *
* See PathCreateFromUrlW
*/
HRESULT WINAPI PathCreateFromUrlA(LPCSTR pszUrl, LPSTR pszPath,
LPDWORD pcchPath, DWORD dwReserved)
{
WCHAR bufW[MAX_PATH];
WCHAR *pathW = bufW;
UNICODE_STRING urlW;
HRESULT ret;
DWORD lenW = sizeof(bufW)/sizeof(WCHAR), lenA;
if(!RtlCreateUnicodeStringFromAsciiz(&urlW, pszUrl))
return E_INVALIDARG;
if((ret = PathCreateFromUrlW(urlW.Buffer, pathW, &lenW, dwReserved)) == E_POINTER) {
pathW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
ret = PathCreateFromUrlW(urlW.Buffer, pathW, &lenW, dwReserved);
}
if(ret == S_OK) {
RtlUnicodeToMultiByteSize(&lenA, pathW, lenW * sizeof(WCHAR));
if(*pcchPath > lenA) {
RtlUnicodeToMultiByteN(pszPath, *pcchPath - 1, &lenA, pathW, lenW * sizeof(WCHAR));
pszPath[lenA] = 0;
*pcchPath = lenA;
} else {
*pcchPath = lenA + 1;
ret = E_POINTER;
}
}
if(pathW != bufW) HeapFree(GetProcessHeap(), 0, pathW);
RtlFreeUnicodeString(&urlW);
return ret;
}
/*************************************************************************
* PathCreateFromUrlW [SHLWAPI.@]
*
* Create a path from a URL * Create a path from a URL
* *
* PARAMS * PARAMS
@ -3217,79 +3254,66 @@ LPWSTR WINAPI PathSkipRootW(LPCWSTR lpszPath)
* Success: S_OK. lpszPath contains the URL in path format, * Success: S_OK. lpszPath contains the URL in path format,
* Failure: An HRESULT error code such as E_INVALIDARG. * Failure: An HRESULT error code such as E_INVALIDARG.
*/ */
HRESULT WINAPI PathCreateFromUrlA(LPCSTR lpszUrl, LPSTR lpszPath, HRESULT WINAPI PathCreateFromUrlW(LPCWSTR pszUrl, LPWSTR pszPath,
LPDWORD pcchPath, DWORD dwFlags) LPDWORD pcchPath, DWORD dwReserved)
{ {
LPSTR pszPathPart; static const WCHAR file_colon[] = { 'f','i','l','e',':',0 };
TRACE("(%s,%p,%p,0x%08lx)\n", debugstr_a(lpszUrl), lpszPath, pcchPath, dwFlags); HRESULT hr;
DWORD nslashes = 0;
WCHAR *ptr;
if (!lpszUrl || !lpszPath || !pcchPath || !*pcchPath) TRACE("(%s,%p,%p,0x%08lx)\n", debugstr_w(pszUrl), pszPath, pcchPath, dwReserved);
return E_INVALIDARG;
pszPathPart = StrChrA(lpszUrl, ':'); if (!pszUrl || !pszPath || !pcchPath || !*pcchPath)
if ((((pszPathPart - lpszUrl) == 1) && isalpha(*lpszUrl)) || return E_INVALIDARG;
!lstrcmpA(lpszUrl, "file:"))
{
return UrlUnescapeA(pszPathPart, lpszPath, pcchPath, dwFlags);
}
/* extracts thing prior to : in pszURL and checks against:
* https
* shell
* local
* about - if match returns E_INVALIDARG
*/
return E_INVALIDARG;
}
/************************************************************************* if (strncmpW(pszUrl, file_colon, 5))
* PathCreateFromUrlW [SHLWAPI.@] return E_INVALIDARG;
* pszUrl += 5;
* See PathCreateFromUrlA.
*/
HRESULT WINAPI PathCreateFromUrlW(LPCWSTR lpszUrl, LPWSTR lpszPath,
LPDWORD pcchPath, DWORD dwFlags)
{
static const WCHAR stemp[] = { 'f','i','l','e',':','/','/','/',0 };
LPWSTR pwszPathPart;
HRESULT hr;
TRACE("(%s,%p,%p,0x%08lx)\n", debugstr_w(lpszUrl), lpszPath, pcchPath, dwFlags); while(*pszUrl == '/' || *pszUrl == '\\') {
nslashes++;
pszUrl++;
}
if (!lpszUrl || !lpszPath || !pcchPath || !*pcchPath) if(isalphaW(*pszUrl) && (pszUrl[1] == ':' || pszUrl[1] == '|') && (pszUrl[2] == '/' || pszUrl[2] == '\\'))
return E_INVALIDARG; nslashes = 0;
/* Path of the form file:///... */ switch(nslashes) {
if (!strncmpW(lpszUrl, stemp, 8)) case 2:
{ pszUrl -= 2;
lpszUrl += 8; break;
} case 0:
/* Path of the form file://... */ break;
else if (!strncmpW(lpszUrl, stemp, 7)) default:
{ pszUrl -= 1;
lpszUrl += 7; break;
} }
/* Path of the form file:... */
else if (!strncmpW(lpszUrl, stemp, 5))
{
lpszUrl += 5;
}
/* Ensure that path is of the form c:... or c|... */ hr = UrlUnescapeW((LPWSTR)pszUrl, pszPath, pcchPath, 0);
if (lpszUrl[1] != ':' && lpszUrl[1] != '|' && isalphaW(*lpszUrl)) if(hr != S_OK) return hr;
return E_INVALIDARG;
hr = UrlUnescapeW((LPWSTR) lpszUrl, lpszPath, pcchPath, dwFlags); for(ptr = pszPath; *ptr; ptr++)
if (lpszPath[1] == '|') if(*ptr == '/') *ptr = '\\';
lpszPath[1] = ':';
for (pwszPathPart = lpszPath; *pwszPathPart; pwszPathPart++) while(*pszPath == '\\')
if (*pwszPathPart == '/') pszPath++;
*pwszPathPart = '\\';
if(isalphaW(*pszPath) && pszPath[1] == '|' && pszPath[2] == '\\') /* c|\ -> c:\ */
pszPath[1] = ':';
TRACE("Returning %s\n",debugstr_w(lpszPath)); if(nslashes == 2 && (ptr = strchrW(pszPath, '\\'))) { /* \\host\c:\ -> \\hostc:\ */
ptr++;
if(isalphaW(*ptr) && (ptr[1] == ':' || ptr[1] == '|') && ptr[2] == '\\') {
memmove(ptr - 1, ptr, (strlenW(ptr) + 1) * sizeof(WCHAR));
(*pcchPath)--;
}
}
return hr; TRACE("Returning %s\n",debugstr_w(pszPath));
return hr;
} }
/************************************************************************* /*************************************************************************

View File

@ -336,6 +336,10 @@ int WINAPI PathCommonPrefixA(LPCSTR,LPCSTR,LPSTR);
int WINAPI PathCommonPrefixW(LPCWSTR,LPCWSTR,LPWSTR); int WINAPI PathCommonPrefixW(LPCWSTR,LPCWSTR,LPWSTR);
#define PathCommonPrefix WINELIB_NAME_AW(PathCommonPrefix) #define PathCommonPrefix WINELIB_NAME_AW(PathCommonPrefix)
HRESULT WINAPI PathCreateFromUrlA(LPCSTR pszUrl, LPSTR pszPath, LPDWORD pcchPath, DWORD dwReserved);
HRESULT WINAPI PathCreateFromUrlW(LPCWSTR pszUrl, LPWSTR pszPath, LPDWORD pcchPath, DWORD dwReserved);
#define PathCreateFromUrl WINELIB_NANE_AW(PathCreateFromUrl)
BOOL WINAPI PathFileExistsA(LPCSTR); BOOL WINAPI PathFileExistsA(LPCSTR);
BOOL WINAPI PathFileExistsW(LPCWSTR); BOOL WINAPI PathFileExistsW(LPCWSTR);
#define PathFileExists WINELIB_NAME_AW(PathFileExists) #define PathFileExists WINELIB_NAME_AW(PathFileExists)