#include "winternl.h"
#define NO_SHLWAPI_STREAM
#include "shlwapi.h"
+#include "intshcut.h"
#include "wine/debug.h"
HMODULE WINAPI MLLoadLibraryW(LPCWSTR,HMODULE,DWORD);
static DWORD get_scheme_code(LPCWSTR scheme, DWORD scheme_len)
{
- int i;
+ unsigned int i;
for(i=0; i < sizeof(shlwapi_schemes)/sizeof(shlwapi_schemes[0]); i++) {
if(scheme_len == strlenW(shlwapi_schemes[i].scheme_name)
return URL_SCHEME_UNKNOWN;
}
-static BOOL URL_JustLocation(LPCWSTR str)
-{
- while(*str && (*str == '/')) str++;
- if (*str) {
- while (*str && ((*str == '-') ||
- (*str == '.') ||
- isalnumW(*str))) str++;
- if (*str == '/') return FALSE;
- }
- return TRUE;
-}
-
-
/*************************************************************************
* @ [SHLWAPI.1]
*
HRESULT WINAPI ParseURLA(LPCSTR x, PARSEDURLA *y)
{
WCHAR scheme[INTERNET_MAX_SCHEME_LENGTH];
- DWORD cnt, len;
+ const char *ptr = x;
+ int len;
- y->nScheme = URL_SCHEME_INVALID;
- if (y->cbSize != sizeof(*y)) return E_INVALIDARG;
- /* FIXME: leading white space generates error of 0x80041001 which
- * is undefined
- */
- if (*x <= ' ') return 0x80041001;
- cnt = 0;
- y->cchProtocol = 0;
- y->pszProtocol = x;
- while (*x) {
- if (*x == ':') {
- y->cchProtocol = cnt;
- cnt = -1;
- y->pszSuffix = x+1;
- break;
- }
- x++;
- cnt++;
- }
+ TRACE("%s %p\n", debugstr_a(x), y);
+
+ if(y->cbSize != sizeof(*y))
+ return E_INVALIDARG;
- /* check for no scheme in string start */
- /* (apparently schemes *must* be larger than a single character) */
- if ((*x == '\0') || (y->cchProtocol <= 1)) {
- y->pszProtocol = NULL;
- return 0x80041001;
+ while(*ptr && (isalnum(*ptr) || *ptr == '-'))
+ ptr++;
+
+ if (*ptr != ':' || ptr <= x+1) {
+ y->pszProtocol = NULL;
+ return URL_E_INVALID_SYNTAX;
}
- /* found scheme, set length of remainder */
- y->cchSuffix = lstrlenA(y->pszSuffix);
+ y->pszProtocol = x;
+ y->cchProtocol = ptr-x;
+ y->pszSuffix = ptr+1;
+ y->cchSuffix = strlen(y->pszSuffix);
- len = MultiByteToWideChar(CP_ACP, 0, y->pszProtocol, y->cchProtocol,
- scheme, sizeof(scheme)/sizeof(WCHAR));
+ len = MultiByteToWideChar(CP_ACP, 0, x, ptr-x,
+ scheme, sizeof(scheme)/sizeof(WCHAR));
y->nScheme = get_scheme_code(scheme, len);
return S_OK;
*/
HRESULT WINAPI ParseURLW(LPCWSTR x, PARSEDURLW *y)
{
- DWORD cnt;
+ const WCHAR *ptr = x;
- y->nScheme = URL_SCHEME_INVALID;
- if (y->cbSize != sizeof(*y)) return E_INVALIDARG;
- /* FIXME: leading white space generates error of 0x80041001 which
- * is undefined
- */
- if (*x <= ' ') return 0x80041001;
- cnt = 0;
- y->cchProtocol = 0;
- y->pszProtocol = x;
- while (*x) {
- if (*x == ':') {
- y->cchProtocol = cnt;
- cnt = -1;
- y->pszSuffix = x+1;
- break;
- }
- x++;
- cnt++;
- }
+ TRACE("%s %p\n", debugstr_w(x), y);
- /* check for no scheme in string start */
- /* (apparently schemes *must* be larger than a single character) */
- if ((*x == '\0') || (y->cchProtocol <= 1)) {
- y->pszProtocol = NULL;
- return 0x80041001;
+ if(y->cbSize != sizeof(*y))
+ return E_INVALIDARG;
+
+ while(*ptr && (isalnumW(*ptr) || *ptr == '-'))
+ ptr++;
+
+ if (*ptr != ':' || ptr <= x+1) {
+ y->pszProtocol = NULL;
+ return URL_E_INVALID_SYNTAX;
}
- /* found scheme, set length of remainder */
- y->cchSuffix = lstrlenW(y->pszSuffix);
- y->nScheme = get_scheme_code(y->pszProtocol, y->cchProtocol);
+ y->pszProtocol = x;
+ y->cchProtocol = ptr-x;
+ y->pszSuffix = ptr+1;
+ y->cchSuffix = strlenW(y->pszSuffix);
+ y->nScheme = get_scheme_code(x, ptr-x);
return S_OK;
}
HRESULT hr = S_OK;
DWORD EscapeFlags;
LPWSTR lpszUrlCpy, wk1, wk2, mp, mp2, root;
- INT nByteLen, state;
- DWORD nLen, nWkLen;
+ INT state;
+ DWORD nByteLen, nLen, nWkLen;
WCHAR slash = '/';
static const WCHAR wszFile[] = {'f','i','l','e',':'};
+ static const WCHAR wszRes[] = {'r','e','s',':'};
+ static const WCHAR wszLocalhost[] = {'l','o','c','a','l','h','o','s','t'};
TRACE("(%s, %p, %p, 0x%08x) *pcchCanonicalized: %d\n", debugstr_w(pszUrl), pszCanonicalized,
pcchCanonicalized, dwFlags, pcchCanonicalized ? *pcchCanonicalized : -1);
return S_OK;
}
- nByteLen = (lstrlenW(pszUrl) + 1) * sizeof(WCHAR); /* length in bytes */
+ nByteLen = (strlenW(pszUrl) + 1) * sizeof(WCHAR); /* length in bytes */
lpszUrlCpy = HeapAlloc(GetProcessHeap(), 0,
INTERNET_MAX_URL_LENGTH * sizeof(WCHAR));
&& !memcmp(wszFile, pszUrl, sizeof(wszFile)))
slash = '\\';
+ if(nByteLen >= sizeof(wszRes) && !memcmp(wszRes, pszUrl, sizeof(wszRes))) {
+ dwFlags &= ~URL_FILE_USE_PATHURL;
+ slash = '\0';
+ }
+
/*
* state =
* 0 initial 1,3
if (*wk1++ == ':') state = 2;
break;
case 2:
- if (*wk1 != '/') {state = 3; break;}
*wk2++ = *wk1++;
if (*wk1 != '/') {state = 6; break;}
*wk2++ = *wk1++;
+ if((dwFlags & URL_FILE_USE_PATHURL) && nByteLen >= sizeof(wszLocalhost)
+ && !strncmpW(wszFile, pszUrl, sizeof(wszFile)/sizeof(WCHAR))
+ && !memcmp(wszLocalhost, wk1, sizeof(wszLocalhost))){
+ wk1 += sizeof(wszLocalhost)/sizeof(WCHAR);
+ while(*wk1 == '\\' && (dwFlags & URL_FILE_USE_PATHURL))
+ wk1++;
+ }
if(*wk1 == '/' && (dwFlags & URL_FILE_USE_PATHURL))
wk1++;
state = 4;
wk1 += nWkLen;
wk2 += nWkLen;
- while(mp < wk2) {
- if(*mp == '/' || *mp == '\\')
- *mp = slash;
- mp++;
+ if(slash) {
+ while(mp < wk2) {
+ if(*mp == '/' || *mp == '\\')
+ *mp = slash;
+ mp++;
+ }
}
break;
case 4:
while(isalnumW(*wk1) || (*wk1 == '-') || (*wk1 == '.') || (*wk1 == ':'))
*wk2++ = *wk1++;
state = 5;
- if (!*wk1)
- *wk2++ = slash;
+ if (!*wk1) {
+ if(slash)
+ *wk2++ = slash;
+ else
+ *wk2++ = '/';
+ }
break;
case 5:
if (*wk1 != '/' && *wk1 != '\\') {state = 3; break;}
while(*wk1 == '/' || *wk1 == '\\') {
- *wk2++ = slash;
+ if(slash)
+ *wk2++ = slash;
+ else
+ *wk2++ = *wk1;
wk1++;
}
state = 6;
wk2 += nLen;
wk1 += nLen;
}
- *wk2++ = slash;
+ if(slash)
+ *wk2++ = slash;
+ else
+ *wk2++ = *wk1;
wk1++;
if (*wk1 == '.') {
/* case /../ -> need to backup wk2 */
TRACE("found '/../'\n");
*(wk2-1) = '\0'; /* set end of string */
- mp = strrchrW(root, slash);
+ mp = strrchrW(root, '/');
+ mp2 = strrchrW(root, '\\');
+ if(mp2 && (!mp || mp2 < mp))
+ mp = mp2;
if (mp && (mp >= root)) {
/* found valid backup point */
wk2 = mp + 1;
debugstr_w(pszUrl), debugstr_w(lpszUrlCpy));
}
nLen = lstrlenW(lpszUrlCpy);
- while ((nLen > 0) && ((lpszUrlCpy[nLen-1] == '\r')||(lpszUrlCpy[nLen-1] == '\n')))
+ while ((nLen > 0) && ((lpszUrlCpy[nLen-1] <= ' ')))
lpszUrlCpy[--nLen]=0;
if(dwFlags & (URL_UNESCAPE | URL_FILE_USE_PATHURL))
DWORD len, res1, res2, process_case = 0;
LPWSTR work, preliminary, mbase, mrelative;
static const WCHAR myfilestr[] = {'f','i','l','e',':','/','/','/','\0'};
- static const WCHAR single_slash[] = {'/','\0'};
HRESULT ret;
TRACE("(base %s, Relative %s, Combine size %d, flags %08x)\n",
process_case = 1;
}
else do {
+ BOOL manual_search = FALSE;
+
/* mk is a special case */
if(base.nScheme == URL_SCHEME_MK) {
static const WCHAR wsz[] = {':',':',0};
base.pszSuffix += delta;
base.cchSuffix -= delta;
}
+ }else {
+ /* get size of location field (if it exists) */
+ work = (LPWSTR)base.pszSuffix;
+ sizeloc = 0;
+ if (*work++ == '/') {
+ if (*work++ == '/') {
+ /* At this point have start of location and
+ * it ends at next '/' or end of string.
+ */
+ while(*work && (*work != '/')) work++;
+ sizeloc = (DWORD)(work - base.pszSuffix);
+ }
+ }
}
- /* get size of location field (if it exists) */
- work = (LPWSTR)base.pszSuffix;
- sizeloc = 0;
- if (*work++ == '/') {
- if (*work++ == '/') {
- /* At this point have start of location and
- * it ends at next '/' or end of string.
- */
- while(*work && (*work != '/')) work++;
- sizeloc = (DWORD)(work - base.pszSuffix);
- }
- }
+ /* If there is a '#' and the characters immediately preceeding it are
+ * ".htm[l]", then begin looking for the last leaf starting from
+ * the '#'. Otherwise the '#' is not meaningful and just start
+ * looking from the end. */
+ if ((work = strchrW(base.pszSuffix + sizeloc, '#'))) {
+ const WCHAR htmlW[] = {'.','h','t','m','l',0};
+ const int len_htmlW = 5;
+ const WCHAR htmW[] = {'.','h','t','m',0};
+ const int len_htmW = 4;
+
+ if (work - base.pszSuffix > len_htmW * sizeof(WCHAR)) {
+ work -= len_htmW;
+ if (strncmpiW(work, htmW, len_htmW) == 0)
+ manual_search = TRUE;
+ work += len_htmW;
+ }
- /* Change .sizep2 to not have the last leaf in it,
- * Note: we need to start after the location (if it exists)
- */
- work = strrchrW((base.pszSuffix+sizeloc), '/');
- if (work) {
- len = (DWORD)(work - base.pszSuffix + 1);
- base.cchSuffix = len;
- }
+ if (!manual_search &&
+ work - base.pszSuffix > len_htmlW * sizeof(WCHAR)) {
+ work -= len_htmlW;
+ if (strncmpiW(work, htmlW, len_htmlW) == 0)
+ manual_search = TRUE;
+ work += len_htmlW;
+ }
+ }
+
+ if (manual_search) {
+ /* search backwards starting from the current position */
+ while (*work != '/' && work > base.pszSuffix + sizeloc)
+ --work;
+ if (work > base.pszSuffix + sizeloc)
+ base.cchSuffix = work - base.pszSuffix + 1;
+ }else {
+ /* search backwards starting from the end of the string */
+ work = strrchrW((base.pszSuffix+sizeloc), '/');
+ if (work) {
+ len = (DWORD)(work - base.pszSuffix + 1);
+ base.cchSuffix = len;
+ }
+ }
/*
* At this point:
process_case = 4;
break;
}
- process_case = (*base.pszSuffix == '/') ? 5 : 3;
+ process_case = (*base.pszSuffix == '/' || base.nScheme == URL_SCHEME_MK) ? 5 : 3;
break;
}
strcatW(preliminary, mrelative);
break;
- case 2: /*
- * Same as case 1, but if URL_PLUGGABLE_PROTOCOL was specified
- * and pszRelative starts with "//", then append a "/"
- */
+ case 2: /* case where pszRelative replaces scheme, and location */
strcpyW(preliminary, mrelative);
- if (!(dwFlags & URL_PLUGGABLE_PROTOCOL) &&
- URL_JustLocation(relative.pszSuffix))
- strcatW(preliminary, single_slash);
break;
case 3: /*
TRACE("(%s, %p, %p, 0x%08x)\n", debugstr_a(pszUrl), pszUnescaped,
pcchUnescaped, dwFlags);
- if(!pszUrl || (!pszUnescaped && !(dwFlags & URL_UNESCAPE_INPLACE)) || !pcchUnescaped)
- return E_INVALIDARG;
+ if (!pszUrl) return E_INVALIDARG;
if(dwFlags & URL_UNESCAPE_INPLACE)
dst = pszUrl;
else
+ {
+ if (!pszUnescaped || !pcchUnescaped) return E_INVALIDARG;
dst = pszUnescaped;
+ }
for(src = pszUrl, needed = 0; *src; src++, needed++) {
if(dwFlags & URL_DONT_UNESCAPE_EXTRA_INFO &&
TRACE("(%s, %p, %p, 0x%08x)\n", debugstr_w(pszUrl), pszUnescaped,
pcchUnescaped, dwFlags);
- if(!pszUrl || (!pszUnescaped && !(dwFlags & URL_UNESCAPE_INPLACE))|| !pcchUnescaped)
- return E_INVALIDARG;
+ if(!pszUrl) return E_INVALIDARG;
if(dwFlags & URL_UNESCAPE_INPLACE)
dst = pszUrl;
else
+ {
+ if (!pszUnescaped || !pcchUnescaped) return E_INVALIDARG;
dst = pszUnescaped;
+ }
for(src = pszUrl, needed = 0; *src; src++, needed++) {
if(dwFlags & URL_DONT_UNESCAPE_EXTRA_INFO &&
{
INT srcCount = nSrcLen - 1, destCount = nDestLen - 1;
- if (IsBadReadPtr(lpSrc, nSrcLen) ||
- IsBadWritePtr(lpDest, nDestLen))
+ if (!lpSrc || !lpDest)
return E_INVALIDARG;
while (destCount >= 0)
HRESULT WINAPI UrlApplySchemeA(LPCSTR pszIn, LPSTR pszOut, LPDWORD pcchOut, DWORD dwFlags)
{
LPWSTR in, out;
- DWORD ret, len, len2;
+ HRESULT ret;
+ DWORD len;
+
+ TRACE("(%s, %p, %p:out size %d, 0x%08x)\n", debugstr_a(pszIn),
+ pszOut, pcchOut, pcchOut ? *pcchOut : 0, dwFlags);
- TRACE("(in %s, out size %d, flags %08x) using W version\n",
- debugstr_a(pszIn), *pcchOut, dwFlags);
+ if (!pszIn || !pszOut || !pcchOut) return E_INVALIDARG;
in = HeapAlloc(GetProcessHeap(), 0,
- (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
+ (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
out = in + INTERNET_MAX_URL_LENGTH;
- MultiByteToWideChar(0, 0, pszIn, -1, in, INTERNET_MAX_URL_LENGTH);
+ MultiByteToWideChar(CP_ACP, 0, pszIn, -1, in, INTERNET_MAX_URL_LENGTH);
len = INTERNET_MAX_URL_LENGTH;
ret = UrlApplySchemeW(in, out, &len, dwFlags);
- if ((ret != S_OK) && (ret != S_FALSE)) {
- HeapFree(GetProcessHeap(), 0, in);
- return ret;
+ if (ret != S_OK) {
+ HeapFree(GetProcessHeap(), 0, in);
+ return ret;
}
- len2 = WideCharToMultiByte(0, 0, out, len+1, 0, 0, 0, 0);
- if (len2 > *pcchOut) {
- *pcchOut = len2;
- HeapFree(GetProcessHeap(), 0, in);
- return E_POINTER;
+ len = WideCharToMultiByte(CP_ACP, 0, out, -1, NULL, 0, NULL, NULL);
+ if (len > *pcchOut) {
+ ret = E_POINTER;
+ goto cleanup;
}
- WideCharToMultiByte(0, 0, out, len+1, pszOut, *pcchOut, 0, 0);
- *pcchOut = len2;
+
+ WideCharToMultiByte(CP_ACP, 0, out, -1, pszOut, *pcchOut, NULL, NULL);
+ len--;
+
+cleanup:
+ *pcchOut = len;
HeapFree(GetProcessHeap(), 0, in);
return ret;
}
index++;
}
RegCloseKey(newkey);
- return -1;
+ return E_FAIL;
}
static HRESULT URL_ApplyDefault(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut)
{
HKEY newkey;
DWORD data_len, dwType;
- WCHAR value[MAX_PATH], data[MAX_PATH];
+ WCHAR data[MAX_PATH];
static const WCHAR prefix_keyW[] =
{'S','o','f','t','w','a','r','e',
/* get and prepend default */
RegOpenKeyExW(HKEY_LOCAL_MACHINE, prefix_keyW, 0, 1, &newkey);
- data_len = MAX_PATH;
- value[0] = '@';
- value[1] = '\0';
- RegQueryValueExW(newkey, value, 0, &dwType, (LPBYTE)data, &data_len);
+ data_len = sizeof(data);
+ RegQueryValueExW(newkey, NULL, 0, &dwType, (LPBYTE)data, &data_len);
RegCloseKey(newkey);
if (strlenW(data) + strlenW(pszIn) + 1 > *pcchOut) {
- *pcchOut = strlenW(data) + strlenW(pszIn) + 1;
- return E_POINTER;
+ *pcchOut = strlenW(data) + strlenW(pszIn) + 1;
+ return E_POINTER;
}
strcpyW(pszOut, data);
strcatW(pszOut, pszIn);
DWORD res1;
HRESULT ret;
- TRACE("(in %s, out size %d, flags %08x)\n",
- debugstr_w(pszIn), *pcchOut, dwFlags);
+ TRACE("(%s, %p, %p:out size %d, 0x%08x)\n", debugstr_w(pszIn),
+ pszOut, pcchOut, pcchOut ? *pcchOut : 0, dwFlags);
+
+ if (!pszIn || !pszOut || !pcchOut) return E_INVALIDARG;
if (dwFlags & URL_APPLY_GUESSFILE) {
FIXME("(%s %p %p(%d) 0x%08x): stub URL_APPLY_GUESSFILE not implemented\n",
if (res1) {
/* no scheme in input, need to see if we need to guess */
if (dwFlags & URL_APPLY_GUESSSCHEME) {
- if ((ret = URL_GuessScheme(pszIn, pszOut, pcchOut)) != -1)
+ if ((ret = URL_GuessScheme(pszIn, pszOut, pcchOut)) != E_FAIL)
return ret;
}
}
return URL_ApplyDefault(pszIn, pszOut, pcchOut);
}
- /* just copy and give proper return code */
- if (strlenW(pszIn) + 1 > *pcchOut) {
- *pcchOut = strlenW(pszIn) + 1;
- return E_POINTER;
- }
- strcpyW(pszOut, pszIn);
- *pcchOut = strlenW(pszOut);
- TRACE("returning copy, left alone\n");
return S_FALSE;
}
(*start == '_') ||
(*start == '+') ||
(*start == '-') ||
- (*start == '.')) {
+ (*start == '.') ||
+ (*start == ' ')) {
start++;
(*size)++;
} else if (*start == '%') {
while (cont) {
if (isalnumW(*start) ||
(*start == '-') ||
- (*start == '.') ) {
+ (*start == '.') ||
+ (*start == ' ') ) {
start++;
(*size)++;
}
work = URL_ScanID(pl->pScheme, &pl->szScheme, SCHEME);
if (!*work || (*work != ':')) goto ErrorExit;
work++;
- if ((*work != '/') || (*(work+1) != '/')) goto ErrorExit;
+ if ((*work != '/') || (*(work+1) != '/')) goto SuccessExit;
pl->pUserName = work + 2;
work = URL_ScanID(pl->pUserName, &pl->szUserName, USERPASS);
if (*work == ':' ) {
pl->pQuery = strchrW(work, '?');
if (pl->pQuery) pl->szQuery = strlenW(pl->pQuery);
}
+ SuccessExit:
TRACE("parse successful: scheme=%p(%d), user=%p(%d), pass=%p(%d), host=%p(%d), port=%p(%d), query=%p(%d)\n",
pl->pScheme, pl->szScheme,
pl->pUserName, pl->szUserName,
LPWSTR in, out;
DWORD ret, len, len2;
+ if(!pszIn || !pszOut || !pcchOut || *pcchOut <= 0)
+ return E_INVALIDARG;
+
in = HeapAlloc(GetProcessHeap(), 0,
(2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
out = in + INTERNET_MAX_URL_LENGTH;
len = INTERNET_MAX_URL_LENGTH;
ret = UrlGetPartW(in, out, &len, dwPart, dwFlags);
- if (ret != S_OK) {
+ if (FAILED(ret)) {
HeapFree(GetProcessHeap(), 0, in);
return ret;
}
len2 = WideCharToMultiByte(0, 0, out, len, 0, 0, 0, 0);
if (len2 > *pcchOut) {
- *pcchOut = len2;
+ *pcchOut = len2+1;
HeapFree(GetProcessHeap(), 0, in);
return E_POINTER;
}
- WideCharToMultiByte(0, 0, out, len+1, pszOut, *pcchOut, 0, 0);
- *pcchOut = len2;
+ len2 = WideCharToMultiByte(0, 0, out, len+1, pszOut, *pcchOut, 0, 0);
+ *pcchOut = len2-1;
HeapFree(GetProcessHeap(), 0, in);
- return S_OK;
+ return ret;
}
/*************************************************************************
{
WINE_PARSE_URL pl;
HRESULT ret;
- DWORD size, schsize;
+ DWORD scheme, size, schsize;
LPCWSTR addr, schaddr;
TRACE("(%s %p %p(%d) %08x %08x)\n",
debugstr_w(pszIn), pszOut, pcchOut, *pcchOut, dwPart, dwFlags);
+ if(!pszIn || !pszOut || !pcchOut || *pcchOut <= 0)
+ return E_INVALIDARG;
+
+ *pszOut = '\0';
+
+ addr = strchrW(pszIn, ':');
+ if(!addr)
+ scheme = URL_SCHEME_UNKNOWN;
+ else
+ scheme = get_scheme_code(pszIn, addr-pszIn);
+
ret = URL_ParseUrl(pszIn, &pl);
- if (!ret) {
- schaddr = pl.pScheme;
- schsize = pl.szScheme;
switch (dwPart) {
case URL_PART_SCHEME:
- if (!pl.szScheme) return E_INVALIDARG;
+ if (!pl.szScheme || scheme == URL_SCHEME_UNKNOWN) {
+ *pcchOut = 0;
+ return S_FALSE;
+ }
addr = pl.pScheme;
size = pl.szScheme;
break;
case URL_PART_HOSTNAME:
- if (!pl.szHostName) return E_INVALIDARG;
+ switch(scheme) {
+ case URL_SCHEME_FTP:
+ case URL_SCHEME_HTTP:
+ case URL_SCHEME_GOPHER:
+ case URL_SCHEME_TELNET:
+ case URL_SCHEME_FILE:
+ case URL_SCHEME_HTTPS:
+ break;
+ default:
+ *pcchOut = 0;
+ return E_FAIL;
+ }
+
+ if(scheme==URL_SCHEME_FILE && (!pl.szHostName ||
+ (pl.szHostName==1 && *(pl.pHostName+1)==':'))) {
+ *pcchOut = 0;
+ return S_FALSE;
+ }
+
+ if (!pl.szHostName) {
+ *pcchOut = 0;
+ return S_FALSE;
+ }
addr = pl.pHostName;
size = pl.szHostName;
break;
case URL_PART_USERNAME:
- if (!pl.szUserName) return E_INVALIDARG;
+ if (!pl.szUserName) {
+ *pcchOut = 0;
+ return S_FALSE;
+ }
addr = pl.pUserName;
size = pl.szUserName;
break;
case URL_PART_PASSWORD:
- if (!pl.szPassword) return E_INVALIDARG;
+ if (!pl.szPassword) {
+ *pcchOut = 0;
+ return S_FALSE;
+ }
addr = pl.pPassword;
size = pl.szPassword;
break;
case URL_PART_PORT:
- if (!pl.szPort) return E_INVALIDARG;
+ if (!pl.szPort) {
+ *pcchOut = 0;
+ return S_FALSE;
+ }
addr = pl.pPort;
size = pl.szPort;
break;
case URL_PART_QUERY:
- if (!pl.szQuery) return E_INVALIDARG;
+ if (!pl.szQuery) {
+ *pcchOut = 0;
+ return S_FALSE;
+ }
addr = pl.pQuery;
size = pl.szQuery;
break;
default:
+ *pcchOut = 0;
return E_INVALIDARG;
}
if (dwFlags == URL_PARTFLAG_KEEPSCHEME) {
+ if(!pl.pScheme || !pl.szScheme) {
+ *pcchOut = 0;
+ return E_FAIL;
+ }
+ schaddr = pl.pScheme;
+ schsize = pl.szScheme;
if (*pcchOut < schsize + size + 2) {
*pcchOut = schsize + size + 2;
- return E_POINTER;
- }
+ return E_POINTER;
+ }
memcpy(pszOut, schaddr, schsize*sizeof(WCHAR));
pszOut[schsize] = ':';
memcpy(pszOut+schsize+1, addr, size*sizeof(WCHAR));
*pcchOut = size;
}
TRACE("len=%d %s\n", *pcchOut, debugstr_w(pszOut));
- }
+
return ret;
}
BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
{
PARSEDURLA base;
+ HRESULT hres;
TRACE("%s\n", debugstr_a(lpstrPath));
/* get protocol */
base.cbSize = sizeof(base);
- ParseURLA(lpstrPath, &base);
- return (base.nScheme != URL_SCHEME_INVALID);
+ hres = ParseURLA(lpstrPath, &base);
+ return hres == S_OK && (base.nScheme != URL_SCHEME_INVALID);
}
/*************************************************************************
BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
{
PARSEDURLW base;
+ HRESULT hres;
TRACE("%s\n", debugstr_w(lpstrPath));
/* get protocol */
base.cbSize = sizeof(base);
- ParseURLW(lpstrPath, &base);
- return (base.nScheme != URL_SCHEME_INVALID);
+ hres = ParseURLW(lpstrPath, &base);
+ return hres == S_OK && (base.nScheme != URL_SCHEME_INVALID);
}
/*************************************************************************
*/
HRESULT WINAPI SHAutoComplete(HWND hwndEdit, DWORD dwFlags)
{
- FIXME("SHAutoComplete stub\n");
+ FIXME("stub\n");
return S_FALSE;
}
dwResLen = strlenW(lpszRes) + 1;
if (dwDestLen >= dwResLen + 1)
{
- lpszDest[szResLen + dwPathLen + dwResLen] = '/';
+ lpszDest[szResLen + dwPathLen-1] = '/';
memcpy(lpszDest + szResLen + dwPathLen, lpszRes, dwResLen * sizeof(WCHAR));
hRet = S_OK;
}
}
return hRet;
}
+
+/***********************************************************************
+ * UrlFixupW [SHLWAPI.462]
+ *
+ * Checks the scheme part of a URL and attempts to correct misspellings.
+ *
+ * PARAMS
+ * lpszUrl [I] Pointer to the URL to be corrected
+ * lpszTranslatedUrl [O] Pointer to a buffer to store corrected URL
+ * dwMaxChars [I] Maximum size of corrected URL
+ *
+ * RETURNS
+ * success: S_OK if URL corrected or already correct
+ * failure: S_FALSE if unable to correct / COM error code if other error
+ *
+ */
+HRESULT WINAPI UrlFixupW(LPCWSTR url, LPWSTR translatedUrl, DWORD maxChars)
+{
+ DWORD srcLen;
+
+ FIXME("(%s,%p,%d) STUB\n", debugstr_w(url), translatedUrl, maxChars);
+
+ if (!url)
+ return E_FAIL;
+
+ srcLen = lstrlenW(url) + 1;
+
+ /* For now just copy the URL directly */
+ lstrcpynW(translatedUrl, url, (maxChars < srcLen) ? maxChars : srcLen);
+
+ return S_OK;
+}