Rewrite PathCreateFromUrl.
This commit is contained in:
parent
d062924f66
commit
1685e8c65e
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue