⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 url.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
			    /* case of /./ -> skip the ./ */
			    wk1 += 2;
			}
                        else if (wk1[1] == '.') {
			    /* found /..  look for next / */
			    TRACE("found '/..'\n");
                            if (wk1[2] == '/' || wk1[2] == '\\' ||wk1[2] == '?'
                                    || wk1[2] == '#' || !wk1[2]) {
				/* case /../ -> need to backup wk2 */
				TRACE("found '/../'\n");
				*(wk2-1) = L'\0';  /* set end of string */
                                mp = strrchrW(root, slash);
				if (mp && (mp >= root)) {
				    /* found valid backup point */
				    wk2 = mp + 1;
                                    if(wk1[2] != '/' && wk1[2] != '\\')
				        wk1 += 2;
				    else
				        wk1 += 3;
				}
				else {
                                    /* did not find point, restore '/' */
                                    *(wk2-1) = slash;
				}
			    }
			}
		    }
		}
		*wk2 = L'\0';
		break;
	    default:
		FIXME("how did we get here - state=%d\n", state);
                HeapFree(GetProcessHeap(), 0, lpszUrlCpy);
		return E_INVALIDARG;
	    }
	}
	*wk2 = L'\0';
	TRACE("Simplified, orig <%s>, simple <%s>\n",
	      debugstr_w(pszUrl), debugstr_w(lpszUrlCpy));
    }
    nLen = lstrlenW(lpszUrlCpy);
    while ((nLen > 0) && ((lpszUrlCpy[nLen-1] == '\r')||(lpszUrlCpy[nLen-1] == '\n')))
        lpszUrlCpy[--nLen]=0;

    if(dwFlags & (URL_UNESCAPE | URL_FILE_USE_PATHURL))
        UrlUnescapeW(lpszUrlCpy, NULL, &nLen, URL_UNESCAPE_INPLACE);

    if((EscapeFlags = dwFlags & (URL_ESCAPE_UNSAFE |
                                 URL_ESCAPE_SPACES_ONLY |
                                 URL_ESCAPE_PERCENT |
                                 URL_DONT_ESCAPE_EXTRA_INFO |
				 URL_ESCAPE_SEGMENT_ONLY ))) {
	EscapeFlags &= ~URL_ESCAPE_UNSAFE;
	hr = UrlEscapeW(lpszUrlCpy, pszCanonicalized, pcchCanonicalized,
			EscapeFlags);
    } else { /* No escaping needed, just copy the string */
        nLen = lstrlenW(lpszUrlCpy);
	if(nLen < *pcchCanonicalized)
	    memcpy(pszCanonicalized, lpszUrlCpy, (nLen + 1)*sizeof(WCHAR));
	else {
	    hr = E_POINTER;
	    nLen++;
	}
	*pcchCanonicalized = nLen;
    }

    HeapFree(GetProcessHeap(), 0, lpszUrlCpy);

    if (hr == S_OK)
	TRACE("result %s\n", debugstr_w(pszCanonicalized));

    return hr;
}

/*************************************************************************
 *        UrlCombineA     [SHLWAPI.@]
 *
 * Combine two Urls.
 *
 * PARAMS
 *  pszBase      [I] Base Url
 *  pszRelative  [I] Url to combine with pszBase
 *  pszCombined  [O] Destination for combined Url
 *  pcchCombined [O] Destination for length of pszCombined
 *  dwFlags      [I] URL_ flags from "shlwapi.h"
 *
 * RETURNS
 *  Success: S_OK. pszCombined contains the combined Url, pcchCombined
 *           contains its length.
 *  Failure: An HRESULT error code indicating the error.
 */
HRESULT WINAPI UrlCombineA(LPCSTR pszBase, LPCSTR pszRelative,
			   LPSTR pszCombined, LPDWORD pcchCombined,
			   DWORD dwFlags)
{
    LPWSTR base, relative, combined;
    DWORD ret, len, len2;

    TRACE("(base %s, Relative %s, Combine size %ld, flags %08lx) using W version\n",
	  debugstr_a(pszBase),debugstr_a(pszRelative),
	  pcchCombined?*pcchCombined:0,dwFlags);

    if(!pszBase || !pszRelative || !pcchCombined)
	return E_INVALIDARG;

    base = HeapAlloc(GetProcessHeap(), 0,
			      (3*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
    relative = base + INTERNET_MAX_URL_LENGTH;
    combined = relative + INTERNET_MAX_URL_LENGTH;

    MultiByteToWideChar(0, 0, pszBase, -1, base, INTERNET_MAX_URL_LENGTH);
    MultiByteToWideChar(0, 0, pszRelative, -1, relative, INTERNET_MAX_URL_LENGTH);
    len = *pcchCombined;

    ret = UrlCombineW(base, relative, pszCombined?combined:NULL, &len, dwFlags);
    if (ret != S_OK) {
	*pcchCombined = len;
	HeapFree(GetProcessHeap(), 0, base);
	return ret;
    }

    len2 = WideCharToMultiByte(0, 0, combined, len, 0, 0, 0, 0);
    if (len2 > *pcchCombined) {
	*pcchCombined = len2;
	HeapFree(GetProcessHeap(), 0, base);
	return E_POINTER;
    }
    WideCharToMultiByte(0, 0, combined, len+1, pszCombined, (*pcchCombined)+1,
			0, 0);
    *pcchCombined = len2;
    HeapFree(GetProcessHeap(), 0, base);
    return S_OK;
}

/*************************************************************************
 *        UrlCombineW     [SHLWAPI.@]
 *
 * See UrlCombineA.
 */
HRESULT WINAPI UrlCombineW(LPCWSTR pszBase, LPCWSTR pszRelative,
			   LPWSTR pszCombined, LPDWORD pcchCombined,
			   DWORD dwFlags)
{
    PARSEDURLW base, relative;
    DWORD myflags, sizeloc = 0;
    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 %ld, flags %08lx)\n",
	  debugstr_w(pszBase),debugstr_w(pszRelative),
	  pcchCombined?*pcchCombined:0,dwFlags);

    if(!pszBase || !pszRelative || !pcchCombined)
	return E_INVALIDARG;

    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) *
			    sizeof(WCHAR));
    mbase = preliminary + INTERNET_MAX_URL_LENGTH;
    mrelative = mbase + INTERNET_MAX_URL_LENGTH;
    *preliminary = L'\0';

    /* Canonicalize the base input prior to looking for the scheme */
    myflags = dwFlags & (URL_DONT_SIMPLIFY | URL_UNESCAPE);
    len = INTERNET_MAX_URL_LENGTH;
    ret = UrlCanonicalizeW(pszBase, mbase, &len, myflags);

    /* Canonicalize the relative input prior to looking for the scheme */
    len = INTERNET_MAX_URL_LENGTH;
    ret = UrlCanonicalizeW(pszRelative, mrelative, &len, myflags);

    /* See if the base has a scheme */
    res1 = ParseURLW(mbase, &base);
    if (res1) {
	/* if pszBase has no scheme, then return pszRelative */
	TRACE("no scheme detected in Base\n");
	process_case = 1;
    }
    else do {

	/* get size of location field (if it exists) */
	work = (LPWSTR)base.pszSuffix;
	sizeloc = 0;
	if (*work++ == L'/') {
	    if (*work++ == L'/') {
		/* At this point have start of location and
		 * it ends at next '/' or end of string.
		 */
		while(*work && (*work != L'/')) work++;
		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.pszSuffix+sizeloc), L'/');
	if (work) {
	    len = (DWORD)(work - base.pszSuffix + 1);
	    base.cchSuffix = len;
	}
	/*
	 * At this point:
	 *    .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 '/'
	 */

	res2 = ParseURLW(mrelative, &relative);
	if (res2) {
	    /* no scheme in pszRelative */
	    TRACE("no scheme detected in Relative\n");
	    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) {
		    process_case = 5;
		    break;
		}
		process_case = 1;
		break;
	    }
	    if (isalnum(*mrelative) && (*(mrelative + 1) == L':')) {
		/* case that becomes "file:///" */
		strcpyW(preliminary, myfilestr);
		process_case = 1;
		break;
	    }
	    if ((*mrelative == L'/') && (*(mrelative+1) == L'/')) {
		/* pszRelative has location and rest */
		process_case = 3;
		break;
	    }
	    if (*mrelative == L'/') {
		/* case where pszRelative is root to location */
		process_case = 4;
		break;
	    }
	    process_case = (*base.pszSuffix == L'/') ? 5 : 3;
	    break;
	}

	/* handle cases where pszRelative has scheme */
	if ((base.cchProtocol == relative.cchProtocol) &&
	    (strncmpW(base.pszProtocol, relative.pszProtocol, base.cchProtocol) == 0)) {

	    /* since the schemes are the same */
	    if ((*relative.pszSuffix == L'/') && (*(relative.pszSuffix+1) == L'/')) {
		/* case where pszRelative replaces location and following */
		process_case = 3;
		break;
	    }
	    if (*relative.pszSuffix == L'/') {
		/* case where pszRelative is root to location */
		process_case = 4;
		break;
	    }
	    /* case where scheme is followed by document path */
	    process_case = 5;
	    break;
	}
	if ((*relative.pszSuffix == L'/') && (*(relative.pszSuffix+1) == L'/')) {
	    /* case where pszRelative replaces scheme, location,
	     * and following and handles PLUGGABLE
	     */
	    process_case = 2;
	    break;
	}
	process_case = 1;
	break;
    } while(FALSE); /* a litte trick to allow easy exit from nested if's */


    ret = S_OK;
    switch (process_case) {

    case 1:  /*
	      * Return pszRelative appended to what ever is in pszCombined,
	      * (which may the string "file:///"
	      */
	strcatW(preliminary, mrelative);
	break;

    case 2:  /*
	      * Same as case 1, but if URL_PLUGGABLE_PROTOCOL was specified
	      * and pszRelative starts with "//", then append a "/"
	      */
	strcpyW(preliminary, mrelative);
	if (!(dwFlags & URL_PLUGGABLE_PROTOCOL) &&
	    URL_JustLocation(relative.pszSuffix))
	    strcatW(preliminary, single_slash);
	break;

    case 3:  /*
	      * Return the pszBase scheme with pszRelative. Basically
	      * keeps the scheme and replaces the domain and following.
	      */
        memcpy(preliminary, base.pszProtocol, (base.cchProtocol + 1)*sizeof(WCHAR));
	work = preliminary + base.cchProtocol + 1;
	strcpyW(work, relative.pszSuffix);
	if (!(dwFlags & URL_PLUGGABLE_PROTOCOL) &&
	    URL_JustLocation(relative.pszSuffix))
	    strcatW(work, single_slash);
	break;

    case 4:  /*
	      * Return the pszBase scheme and location but everything
	      * after the location is pszRelative. (Replace document
	      * from root on.)
	      */
        memcpy(preliminary, base.pszProtocol, (base.cchProtocol+1+sizeloc)*sizeof(WCHAR));
	work = preliminary + base.cchProtocol + 1 + sizeloc;
	if (dwFlags & URL_PLUGGABLE_PROTOCOL)
	    *(work++) = L'/';
	strcpyW(work, relative.pszSuffix);
	break;

    case 5:  /*
	      * Return the pszBase without its document (if any) and
	      * append pszRelative after its scheme.
	      */
        memcpy(preliminary, base.pszProtocol,
               (base.cchProtocol+1+base.cchSuffix)*sizeof(WCHAR));
	work = preliminary + base.cchProtocol+1+base.cchSuffix - 1;
	if (*work++ != L'/')
	    *(work++) = L'/';
	strcpyW(work, relative.pszSuffix);
	break;

    default:
	FIXME("How did we get here????? process_case=%ld\n", process_case);
	ret = E_INVALIDARG;
    }

    if (ret == S_OK) {
	/* Reuse mrelative as temp storage as its already allocated and not needed anymore */
	ret = UrlCanonicalizeW(preliminary, mrelative, pcchCombined, dwFlags);
	if(SUCCEEDED(ret) && pszCombined) {
	    lstrcpyW(pszCombined, mrelative);
	}
	TRACE("return-%ld len=%ld, %s\n",
	      process_case, *pcchCombined, debugstr_w(pszCombined));
    }
    HeapFree(GetProcessHeap(), 0, preliminary);
    return ret;
}

/*************************************************************************
 *      UrlEscapeA	[SHLWAPI.@]
 */

HRESULT WINAPI UrlEscapeA(
	LPCSTR pszUrl,
	LPSTR pszEscaped,
	LPDWORD pcchEscaped,
	DWORD dwFlags)
{
    WCHAR bufW[INTERNET_MAX_URL_LENGTH];
    WCHAR *escapedW = bufW;
    UNICODE_STRING urlW;
    HRESULT ret;
    DWORD lenW = sizeof(bufW)/sizeof(WCHAR), lenA;

    if(!RtlCreateUnicodeStringFromAsciiz(&urlW, pszUrl))
        return E_INVALIDARG;
    if((ret = UrlEscapeW(urlW.Buffer, escapedW, &lenW, dwFlags)) == E_POINTER) {
        escapedW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
        ret = UrlEscapeW(urlW.Buffer, escapedW, &lenW, dwFlags);
    }
    if(ret == S_OK) {
        RtlUnicodeToMultiByteSize(&lenA, escapedW, lenW * sizeof(WCHAR));
        if(*pcchEscaped > lenA) {
            RtlUnicodeToMultiByteN(pszEscaped, *pcchEscaped - 1, &lenA, escapedW, lenW * sizeof(WCHAR));
            pszEscaped[lenA] = 0;
            *pcchEscaped = lenA;
        } else {
            *pcchEscaped = lenA + 1;
            ret = E_POINTER;
        }
    }
    if(escapedW != bufW) HeapFree(GetProcessHeap(), 0, escapedW);
    RtlFreeUnicodeString(&urlW);
    return ret;
}

#define WINE_URL_BASH_AS_SLASH    0x01
#define WINE_URL_COLLAPSE_SLASHES 0x02
#define WINE_URL_ESCAPE_SLASH     0x04
#define WINE_URL_ESCAPE_HASH      0x08
#define WINE_URL_ESCAPE_QUESTION  0x10
#define WINE_URL_STOP_ON_HASH     0x20
#define WINE_URL_STOP_ON_QUESTION 0x40

static inline BOOL URL_NeedEscapeW(WCHAR ch, DWORD dwFlags, DWORD int_flags)
{

    if (isalnumW(ch))
        return FALSE;

    if(dwFlags & URL_ESCAPE_SPACES_ONLY) {
        if(ch == ' ')
	    return TRUE;
	else
	    return FALSE;
    }

    if ((dwFlags & URL_ESCAPE_PERCENT) && (ch == '%'))
	return TRUE;

    if (ch <= 31 || ch >= 127)
	return TRUE;

    else {
        switch (ch) {
	case ' ':
	case '<':
	case '>':
	case '\"':
	case '{':
	case '}':
	case '|':
	case '\\':
	case '^':
	case ']':
	case '[':
	case '`':
	case '&':
	    return TRUE;

	case '/':
            if (int_flags & WINE_URL_ESCAPE_SLASH) return TRUE;
            return FALSE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -