Commit 1685e8c6 authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

Rewrite PathCreateFromUrl.

parent d062924f
......@@ -32,6 +32,7 @@
#include "wingdi.h"
#include "winuser.h"
#include "winreg.h"
#include "winternl.h"
#define NO_SHLWAPI_STREAM
#include "shlwapi.h"
#include "wine/debug.h"
......@@ -3205,6 +3206,42 @@ LPWSTR WINAPI PathSkipRootW(LPCWSTR lpszPath)
/*************************************************************************
* 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
*
* PARAMS
......@@ -3217,79 +3254,66 @@ LPWSTR WINAPI PathSkipRootW(LPCWSTR lpszPath)
* Success: S_OK. lpszPath contains the URL in path format,
* Failure: An HRESULT error code such as E_INVALIDARG.
*/
HRESULT WINAPI PathCreateFromUrlA(LPCSTR lpszUrl, LPSTR lpszPath,
LPDWORD pcchPath, DWORD dwFlags)
HRESULT WINAPI PathCreateFromUrlW(LPCWSTR pszUrl, LPWSTR pszPath,
LPDWORD pcchPath, DWORD dwReserved)
{
LPSTR pszPathPart;
TRACE("(%s,%p,%p,0x%08lx)\n", debugstr_a(lpszUrl), lpszPath, pcchPath, dwFlags);
static const WCHAR file_colon[] = { 'f','i','l','e',':',0 };
HRESULT hr;
DWORD nslashes = 0;
WCHAR *ptr;
if (!lpszUrl || !lpszPath || !pcchPath || !*pcchPath)
return E_INVALIDARG;
TRACE("(%s,%p,%p,0x%08lx)\n", debugstr_w(pszUrl), pszPath, pcchPath, dwReserved);
pszPathPart = StrChrA(lpszUrl, ':');
if ((((pszPathPart - lpszUrl) == 1) && isalpha(*lpszUrl)) ||
!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
*/
if (!pszUrl || !pszPath || !pcchPath || !*pcchPath)
return E_INVALIDARG;
return E_INVALIDARG;
}
/*************************************************************************
* PathCreateFromUrlW [SHLWAPI.@]
*
* 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;
if (strncmpW(pszUrl, file_colon, 5))
return E_INVALIDARG;
pszUrl += 5;
TRACE("(%s,%p,%p,0x%08lx)\n", debugstr_w(lpszUrl), lpszPath, pcchPath, dwFlags);
while(*pszUrl == '/' || *pszUrl == '\\') {
nslashes++;
pszUrl++;
}
if (!lpszUrl || !lpszPath || !pcchPath || !*pcchPath)
return E_INVALIDARG;
if(isalphaW(*pszUrl) && (pszUrl[1] == ':' || pszUrl[1] == '|') && (pszUrl[2] == '/' || pszUrl[2] == '\\'))
nslashes = 0;
/* Path of the form file:///... */
if (!strncmpW(lpszUrl, stemp, 8))
{
lpszUrl += 8;
}
/* Path of the form file://... */
else if (!strncmpW(lpszUrl, stemp, 7))
{
lpszUrl += 7;
}
/* Path of the form file:... */
else if (!strncmpW(lpszUrl, stemp, 5))
{
lpszUrl += 5;
}
switch(nslashes) {
case 2:
pszUrl -= 2;
break;
case 0:
break;
default:
pszUrl -= 1;
break;
}
/* Ensure that path is of the form c:... or c|... */
if (lpszUrl[1] != ':' && lpszUrl[1] != '|' && isalphaW(*lpszUrl))
return E_INVALIDARG;
hr = UrlUnescapeW((LPWSTR)pszUrl, pszPath, pcchPath, 0);
if(hr != S_OK) return hr;
hr = UrlUnescapeW((LPWSTR) lpszUrl, lpszPath, pcchPath, dwFlags);
if (lpszPath[1] == '|')
lpszPath[1] = ':';
for(ptr = pszPath; *ptr; ptr++)
if(*ptr == '/') *ptr = '\\';
while(*pszPath == '\\')
pszPath++;
if(isalphaW(*pszPath) && pszPath[1] == '|' && pszPath[2] == '\\') /* c|\ -> c:\ */
pszPath[1] = ':';
for (pwszPathPart = lpszPath; *pwszPathPart; pwszPathPart++)
if (*pwszPathPart == '/')
*pwszPathPart = '\\';
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)--;
}
}
TRACE("Returning %s\n",debugstr_w(lpszPath));
TRACE("Returning %s\n",debugstr_w(pszPath));
return hr;
return hr;
}
/*************************************************************************
......
......@@ -336,6 +336,10 @@ int WINAPI PathCommonPrefixA(LPCSTR,LPCSTR,LPSTR);
int WINAPI PathCommonPrefixW(LPCWSTR,LPCWSTR,LPWSTR);
#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 PathFileExistsW(LPCWSTR);
#define PathFileExists WINELIB_NAME_AW(PathFileExists)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment