shlwapi: ParseURL
Huw D M Davies
h.davies1 at physics.ox.ac.uk
Wed Sep 29 09:22:22 CDT 2004
Huw Davies <huw at codeweavers.com>
ParseURL is now documented, so move it into shlwapi.h
--
Huw Davies
huw at codeweavers.com
Index: dlls/shlwapi/url.c
===================================================================
RCS file: /home/wine/wine/dlls/shlwapi/url.c,v
retrieving revision 1.38
diff -u -r1.38 url.c
--- dlls/shlwapi/url.c 22 Sep 2004 19:10:11 -0000 1.38
+++ dlls/shlwapi/url.c 29 Sep 2004 14:12:48 -0000
@@ -92,24 +92,6 @@
USERPASS,
} WINE_URL_SCAN_TYPE;
-typedef struct {
- INT size; /* [in] (always 0x18) */
- LPCSTR ap1; /* [out] start of scheme */
- INT sizep1; /* [out] size of scheme (until colon) */
- LPCSTR ap2; /* [out] pointer following first colon */
- INT sizep2; /* [out] size of remainder */
- INT fcncde; /* [out] function match of p1 (0 if unknown) */
-} UNKNOWN_SHLWAPI_1;
-
-typedef struct {
- INT size; /* [in] (always 0x18) */
- LPCWSTR ap1; /* [out] start of scheme */
- INT sizep1; /* [out] size of scheme (until colon) */
- LPCWSTR ap2; /* [out] pointer following first colon */
- INT sizep2; /* [out] size of remainder */
- INT fcncde; /* [out] function match of p1 (0 if unknown) */
-} UNKNOWN_SHLWAPI_2;
-
static const CHAR hexDigits[] = "0123456789ABCDEF";
static const WCHAR fileW[] = {'f','i','l','e','\0'};
@@ -252,25 +234,25 @@
* Success: S_OK. y contains the parsed Url details.
* Failure: An HRESULT error code.
*/
-DWORD WINAPI ParseURLA(LPCSTR x, UNKNOWN_SHLWAPI_1 *y)
+HRESULT WINAPI ParseURLA(LPCSTR x, PARSEDURLA *y)
{
DWORD cnt;
const SHL_2_inet_scheme *inet_pro;
- y->fcncde = URL_SCHEME_INVALID;
- if (y->size != 0x18) return E_INVALIDARG;
+ 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->sizep1 = 0;
- y->ap1 = x;
+ y->cchProtocol = 0;
+ y->pszProtocol = x;
while (*x) {
if (*x == ':') {
- y->sizep1 = cnt;
+ y->cchProtocol = cnt;
cnt = -1;
- y->ap2 = x+1;
+ y->pszSuffix = x+1;
break;
}
x++;
@@ -279,21 +261,21 @@
/* check for no scheme in string start */
/* (apparently schemes *must* be larger than a single character) */
- if ((*x == '\0') || (y->sizep1 <= 1)) {
- y->ap1 = 0;
+ if ((*x == '\0') || (y->cchProtocol <= 1)) {
+ y->pszProtocol = NULL;
return 0x80041001;
}
/* found scheme, set length of remainder */
- y->sizep2 = lstrlenA(y->ap2);
+ y->cchSuffix = lstrlenA(y->pszSuffix);
/* see if known scheme and return indicator number */
- y->fcncde = URL_SCHEME_UNKNOWN;
+ y->nScheme = URL_SCHEME_UNKNOWN;
inet_pro = shlwapi_schemes;
while (inet_pro->scheme_name) {
- if (!strncasecmp(inet_pro->scheme_name, y->ap1,
- min(y->sizep1, lstrlenA(inet_pro->scheme_name)))) {
- y->fcncde = inet_pro->scheme_number;
+ if (!strncasecmp(inet_pro->scheme_name, y->pszProtocol,
+ min(y->cchProtocol, lstrlenA(inet_pro->scheme_name)))) {
+ y->nScheme = inet_pro->scheme_number;
break;
}
inet_pro++;
@@ -306,27 +288,27 @@
*
* Unicode version of ParseURLA.
*/
-DWORD WINAPI ParseURLW(LPCWSTR x, UNKNOWN_SHLWAPI_2 *y)
+HRESULT WINAPI ParseURLW(LPCWSTR x, PARSEDURLW *y)
{
DWORD cnt;
const SHL_2_inet_scheme *inet_pro;
LPSTR cmpstr;
INT len;
- y->fcncde = URL_SCHEME_INVALID;
- if (y->size != 0x18) return E_INVALIDARG;
+ 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 <= L' ') return 0x80041001;
cnt = 0;
- y->sizep1 = 0;
- y->ap1 = x;
+ y->cchProtocol = 0;
+ y->pszProtocol = x;
while (*x) {
if (*x == L':') {
- y->sizep1 = cnt;
+ y->cchProtocol = cnt;
cnt = -1;
- y->ap2 = x+1;
+ y->pszSuffix = x+1;
break;
}
x++;
@@ -335,24 +317,24 @@
/* check for no scheme in string start */
/* (apparently schemes *must* be larger than a single character) */
- if ((*x == L'\0') || (y->sizep1 <= 1)) {
- y->ap1 = 0;
+ if ((*x == L'\0') || (y->cchProtocol <= 1)) {
+ y->pszProtocol = NULL;
return 0x80041001;
}
/* found scheme, set length of remainder */
- y->sizep2 = lstrlenW(y->ap2);
+ y->cchSuffix = lstrlenW(y->pszSuffix);
/* see if known scheme and return indicator number */
- len = WideCharToMultiByte(0, 0, y->ap1, y->sizep1, 0, 0, 0, 0);
+ len = WideCharToMultiByte(0, 0, y->pszProtocol, y->cchProtocol, 0, 0, 0, 0);
cmpstr = (LPSTR)HeapAlloc(GetProcessHeap(), 0, len);
- WideCharToMultiByte(0, 0, y->ap1, y->sizep1, cmpstr, len, 0, 0);
- y->fcncde = URL_SCHEME_UNKNOWN;
+ WideCharToMultiByte(0, 0, y->pszProtocol, y->cchProtocol, cmpstr, len, 0, 0);
+ y->nScheme = URL_SCHEME_UNKNOWN;
inet_pro = shlwapi_schemes;
while (inet_pro->scheme_name) {
if (!strncasecmp(inet_pro->scheme_name, cmpstr,
min(len, lstrlenA(inet_pro->scheme_name)))) {
- y->fcncde = inet_pro->scheme_number;
+ y->nScheme = inet_pro->scheme_number;
break;
}
inet_pro++;
@@ -661,7 +643,7 @@
LPWSTR pszCombined, LPDWORD pcchCombined,
DWORD dwFlags)
{
- UNKNOWN_SHLWAPI_2 base, relative;
+ PARSEDURLW base, relative;
DWORD myflags, sizeloc = 0;
DWORD len, res1, res2, process_case = 0;
LPWSTR work, preliminary, mbase, mrelative;
@@ -676,8 +658,8 @@
if(!pszBase || !pszRelative || !pcchCombined)
return E_INVALIDARG;
- base.size = 24;
- relative.size = 24;
+ base.cbSize = sizeof(base);
+ relative.cbSize = sizeof(relative);
/* Get space for duplicates of the input and the output */
preliminary = HeapAlloc(GetProcessHeap(), 0, (3*INTERNET_MAX_URL_LENGTH) *
@@ -705,7 +687,7 @@
else do {
/* get size of location field (if it exists) */
- work = (LPWSTR)base.ap2;
+ work = (LPWSTR)base.pszSuffix;
sizeloc = 0;
if (*work++ == L'/') {
if (*work++ == L'/') {
@@ -713,23 +695,23 @@
* it ends at next '/' or end of string.
*/
while(*work && (*work != L'/')) work++;
- sizeloc = (DWORD)(work - base.ap2);
+ sizeloc = (DWORD)(work - base.pszSuffix);
}
}
/* Change .sizep2 to not have the last leaf in it,
* Note: we need to start after the location (if it exists)
*/
- work = strrchrW((base.ap2+sizeloc), L'/');
+ work = strrchrW((base.pszSuffix+sizeloc), L'/');
if (work) {
- len = (DWORD)(work - base.ap2 + 1);
- base.sizep2 = len;
+ len = (DWORD)(work - base.pszSuffix + 1);
+ base.cchSuffix = len;
}
/*
* At this point:
- * .ap2 points to location (starting with '//')
- * .sizep2 length of location (above) and rest less the last
- * leaf (if any)
+ * .pszSuffix points to location (starting with '//')
+ * .cchSuffix length of location (above) and rest less the last
+ * leaf (if any)
* sizeloc length of location (above) up to but not including
* the last '/'
*/
@@ -738,8 +720,8 @@
if (res2) {
/* no scheme in pszRelative */
TRACE("no scheme detected in Relative\n");
- relative.ap2 = mrelative; /* case 3,4,5 depends on this */
- relative.sizep2 = strlenW(mrelative);
+ relative.pszSuffix = mrelative; /* case 3,4,5 depends on this */
+ relative.cchSuffix = strlenW(mrelative);
if (*pszRelative == L':') {
/* case that is either left alone or uses pszBase */
if (dwFlags & URL_PLUGGABLE_PROTOCOL) {
@@ -765,21 +747,21 @@
process_case = 4;
break;
}
- process_case = (*base.ap2 == L'/') ? 5 : 3;
+ process_case = (*base.pszSuffix == L'/') ? 5 : 3;
break;
}
/* handle cases where pszRelative has scheme */
- if ((base.sizep1 == relative.sizep1) &&
- (strncmpW(base.ap1, relative.ap1, base.sizep1) == 0)) {
+ if ((base.cchProtocol == relative.cchProtocol) &&
+ (strncmpW(base.pszProtocol, relative.pszProtocol, base.cchProtocol) == 0)) {
/* since the schemes are the same */
- if ((*relative.ap2 == L'/') && (*(relative.ap2+1) == L'/')) {
+ if ((*relative.pszSuffix == L'/') && (*(relative.pszSuffix+1) == L'/')) {
/* case where pszRelative replaces location and following */
process_case = 3;
break;
}
- if (*relative.ap2 == L'/') {
+ if (*relative.pszSuffix == L'/') {
/* case where pszRelative is root to location */
process_case = 4;
break;
@@ -788,7 +770,7 @@
process_case = 5;
break;
}
- if ((*relative.ap2 == L'/') && (*(relative.ap2+1) == L'/')) {
+ if ((*relative.pszSuffix == L'/') && (*(relative.pszSuffix+1) == L'/')) {
/* case where pszRelative replaces scheme, location,
* and following and handles PLUGGABLE
*/
@@ -816,7 +798,7 @@
*/
strcpyW(preliminary, mrelative);
if (!(dwFlags & URL_PLUGGABLE_PROTOCOL) &&
- URL_JustLocation(relative.ap2))
+ URL_JustLocation(relative.pszSuffix))
strcatW(preliminary, single_slash);
break;
@@ -824,11 +806,11 @@
* Return the pszBase scheme with pszRelative. Basically
* keeps the scheme and replaces the domain and following.
*/
- strncpyW(preliminary, base.ap1, base.sizep1 + 1);
- work = preliminary + base.sizep1 + 1;
- strcpyW(work, relative.ap2);
+ strncpyW(preliminary, base.pszProtocol, base.cchProtocol + 1);
+ work = preliminary + base.cchProtocol + 1;
+ strcpyW(work, relative.pszSuffix);
if (!(dwFlags & URL_PLUGGABLE_PROTOCOL) &&
- URL_JustLocation(relative.ap2))
+ URL_JustLocation(relative.pszSuffix))
strcatW(work, single_slash);
break;
@@ -837,22 +819,22 @@
* after the location is pszRelative. (Replace document
* from root on.)
*/
- strncpyW(preliminary, base.ap1, base.sizep1+1+sizeloc);
- work = preliminary + base.sizep1 + 1 + sizeloc;
+ strncpyW(preliminary, base.pszProtocol, base.cchProtocol+1+sizeloc);
+ work = preliminary + base.cchProtocol + 1 + sizeloc;
if (dwFlags & URL_PLUGGABLE_PROTOCOL)
*(work++) = L'/';
- strcpyW(work, relative.ap2);
+ strcpyW(work, relative.pszSuffix);
break;
case 5: /*
* Return the pszBase without its document (if any) and
* append pszRelative after its scheme.
*/
- strncpyW(preliminary, base.ap1, base.sizep1+1+base.sizep2);
- work = preliminary + base.sizep1+1+base.sizep2 - 1;
+ strncpyW(preliminary, base.pszProtocol, base.cchProtocol+1+base.cchSuffix);
+ work = preliminary + base.cchProtocol+1+base.cchSuffix - 1;
if (*work++ != L'/')
*(work++) = L'/';
- strcpyW(work, relative.ap2);
+ strcpyW(work, relative.pszSuffix);
break;
default:
@@ -1248,18 +1230,18 @@
LPCSTR WINAPI UrlGetLocationA(
LPCSTR pszUrl)
{
- UNKNOWN_SHLWAPI_1 base;
+ PARSEDURLA base;
DWORD res1;
- base.size = 24;
+ base.cbSize = sizeof(base);
res1 = ParseURLA(pszUrl, &base);
if (res1) return NULL; /* invalid scheme */
/* if scheme is file: then never return pointer */
- if (strncmp(base.ap1, "file", min(4,base.sizep1)) == 0) return NULL;
+ if (strncmp(base.pszProtocol, "file", min(4,base.cchProtocol)) == 0) return NULL;
/* Look for '#' and return its addr */
- return strchr(base.ap2, '#');
+ return strchr(base.pszSuffix, '#');
}
/*************************************************************************
@@ -1270,18 +1252,18 @@
LPCWSTR WINAPI UrlGetLocationW(
LPCWSTR pszUrl)
{
- UNKNOWN_SHLWAPI_2 base;
+ PARSEDURLW base;
DWORD res1;
- base.size = 24;
+ base.cbSize = sizeof(base);
res1 = ParseURLW(pszUrl, &base);
if (res1) return NULL; /* invalid scheme */
/* if scheme is file: then never return pointer */
- if (strncmpW(base.ap1, fileW, min(4,base.sizep1)) == 0) return NULL;
+ if (strncmpW(base.pszProtocol, fileW, min(4,base.cchProtocol)) == 0) return NULL;
/* Look for '#' and return its addr */
- return strchrW(base.ap2, L'#');
+ return strchrW(base.pszSuffix, L'#');
}
/*************************************************************************
@@ -1567,7 +1549,7 @@
*/
HRESULT WINAPI UrlApplySchemeW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut, DWORD dwFlags)
{
- UNKNOWN_SHLWAPI_2 in_scheme;
+ PARSEDURLW in_scheme;
DWORD res1;
HRESULT ret;
@@ -1582,7 +1564,7 @@
return S_FALSE;
}
- in_scheme.size = 24;
+ in_scheme.cbSize = sizeof(in_scheme);
/* See if the base has a scheme */
res1 = ParseURLW(pszIn, &in_scheme);
if (res1) {
@@ -1594,7 +1576,7 @@
}
else {
/* we have a scheme, see if valid (known scheme) */
- if (in_scheme.fcncde) {
+ if (in_scheme.nScheme) {
/* have valid scheme, so just copy and exit */
if (strlenW(pszIn) + 1 > *pcchOut) {
*pcchOut = strlenW(pszIn) + 1;
@@ -1643,17 +1625,17 @@
*/
BOOL WINAPI UrlIsA(LPCSTR pszUrl, URLIS Urlis)
{
- UNKNOWN_SHLWAPI_1 base;
+ PARSEDURLA base;
DWORD res1;
LPCSTR last;
switch (Urlis) {
case URLIS_OPAQUE:
- base.size = 24;
+ base.cbSize = sizeof(base);
res1 = ParseURLA(pszUrl, &base);
if (res1) return FALSE; /* invalid scheme */
- if ((*base.ap2 == '/') && (*(base.ap2+1) == '/'))
+ if ((*base.pszSuffix == '/') && (*(base.pszSuffix+1) == '/'))
/* has scheme followed by 2 '/' */
return FALSE;
return TRUE;
@@ -1683,17 +1665,17 @@
BOOL WINAPI UrlIsW(LPCWSTR pszUrl, URLIS Urlis)
{
static const WCHAR stemp[] = { 'f','i','l','e',':','/','/',0 };
- UNKNOWN_SHLWAPI_2 base;
+ PARSEDURLW base;
DWORD res1;
LPCWSTR last;
switch (Urlis) {
case URLIS_OPAQUE:
- base.size = 24;
+ base.cbSize = sizeof(base);
res1 = ParseURLW(pszUrl, &base);
if (res1) return FALSE; /* invalid scheme */
- if ((*base.ap2 == '/') && (*(base.ap2+1) == '/'))
+ if ((*base.pszSuffix == '/') && (*(base.pszSuffix+1) == '/'))
/* has scheme followed by 2 '/' */
return FALSE;
return TRUE;
@@ -2086,15 +2068,15 @@
*/
BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
{
- UNKNOWN_SHLWAPI_1 base;
+ PARSEDURLA base;
DWORD res1;
if (!lpstrPath || !*lpstrPath) return FALSE;
/* get protocol */
- base.size = sizeof(base);
+ base.cbSize = sizeof(base);
res1 = ParseURLA(lpstrPath, &base);
- return (base.fcncde > 0);
+ return (base.nScheme > 0);
}
/*************************************************************************
@@ -2104,15 +2086,15 @@
*/
BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
{
- UNKNOWN_SHLWAPI_2 base;
+ PARSEDURLW base;
DWORD res1;
if (!lpstrPath || !*lpstrPath) return FALSE;
/* get protocol */
- base.size = sizeof(base);
+ base.cbSize = sizeof(base);
res1 = ParseURLW(lpstrPath, &base);
- return (base.fcncde > 0);
+ return (base.nScheme > 0);
}
/*************************************************************************
Index: include/shlwapi.h
===================================================================
RCS file: /home/wine/wine/include/shlwapi.h,v
retrieving revision 1.49
diff -u -r1.49 shlwapi.h
--- include/shlwapi.h 22 Sep 2004 19:10:11 -0000 1.49
+++ include/shlwapi.h 29 Sep 2004 14:12:48 -0000
@@ -668,6 +668,28 @@
HRESULT WINAPI UrlCreateFromPathW(LPCWSTR,LPWSTR,LPDWORD,DWORD);
#define UrlCreateFromPath WINELIB_AW_NAME(UrlCreateFromPath)
+typedef struct tagPARSEDURLA {
+ DWORD cbSize;
+ LPCSTR pszProtocol;
+ UINT cchProtocol;
+ LPCSTR pszSuffix;
+ UINT cchSuffix;
+ UINT nScheme;
+} PARSEDURLA, *PPARSEDURLA;
+
+typedef struct tagPARSEDURLW {
+ DWORD cbSize;
+ LPCWSTR pszProtocol;
+ UINT cchProtocol;
+ LPCWSTR pszSuffix;
+ UINT cchSuffix;
+ UINT nScheme;
+} PARSEDURLW, *PPARSEDURLW;
+
+HRESULT WINAPI ParseURLA(LPCSTR pszUrl, PARSEDURLA *ppu);
+HRESULT WINAPI ParseURLW(LPCWSTR pszUrl, PARSEDURLW *ppu);
+#define ParseURL WINELIB_AW_NAME(ParseUrl)
+
#endif /* NO_SHLWAPI_PATH */
More information about the wine-patches
mailing list