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

📄 url.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
            while (*wk1) {
                mp = strchrW(wk1, '/');
                mp2 = strchrW(wk1, '\\');
                if(mp2 && (!mp || mp2 < mp))
                    mp = mp2;
                if (!mp) {
                    nWkLen = strlenW(wk1);
                    memcpy(wk2, wk1, (nWkLen + 1) * sizeof(WCHAR));
                    wk1 += nWkLen;
                    wk2 += nWkLen;
                    continue;
                }
                nLen = mp - wk1;
                if(nLen) {
                    memcpy(wk2, wk1, nLen * sizeof(WCHAR));
                    wk2 += nLen;
                    wk1 += nLen;
                }
                *wk2++ = slash;
                wk1++;

                if (*wk1 == '.') {
                    TRACE("found '/.'\n");
                    if (wk1[1] == '/' || wk1[1] == '\\') {
                        /* 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) = '\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 = '\0';
            break;
        default:
            FIXME("how did we get here - state=%d\n", state);
            HeapFree(GetProcessHeap(), 0, lpszUrlCpy);
            return E_INVALIDARG;
        }
        *wk2 = '\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 %d, flags %08x) 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 %d, flags %08x)\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 = '\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 {
        /* mk is a special case */
        if(base.nScheme == URL_SCHEME_MK) {
            static const WCHAR wsz[] = {':',':',0};

            WCHAR *ptr = strstrW(base.pszSuffix, wsz);
            if(ptr) {
                int delta;

                ptr += 2;
                delta = ptr-base.pszSuffix;
                base.cchProtocol += delta;
                base.pszSuffix += delta;
                base.cchSuffix -= delta;
            }
        }

	/* 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);
	    }
	}

	/* 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;
	}

	/*
	 * 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  == ':') {
		/* 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) == ':')) {
		/* case that becomes "file:///" */
		strcpyW(preliminary, myfilestr);
		process_case = 1;
		break;
	    }
            if ((*mrelative == '/') && (*(mrelative+1) == '/')) {
		/* pszRelative has location and rest */
		process_case = 3;
		break;
	    }
            if (*mrelative == '/') {
		/* case where pszRelative is root to location */
		process_case = 4;
		break;
	    }
            process_case = (*base.pszSuffix == '/') ? 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 == '/') && (*(relative.pszSuffix+1) == '/')) {
		/* case where pszRelative replaces location and following */
		process_case = 3;
		break;
	    }
            if (*relative.pszSuffix == '/') {
		/* 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 == '/') && (*(relative.pszSuffix+1) == '/')) {
	    /* 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++) = '/';
	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++ != '/')
            *(work++) = '/';
	strcpyW(work, relative.pszSuffix);
	break;

    default:
	FIXME("How did we get here????? process_case=%d\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 & ~URL_FILE_USE_PATHURL));
	if(SUCCEEDED(ret) && pszCombined) {
	    lstrcpyW(pszCombined, mrelative);
	}
	TRACE("return-%d len=%d, %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(pszEscaped && *pcchEscaped > lenA) {
            RtlUnicodeToMultiByteN(pszEscaped, *pcchEscaped - 1, &lenA, escapedW, lenW * sizeof(WCHAR));
            pszEscaped[lenA] = 0;
            *pcchEscaped = lenA;
        } else {
            *pcchEscaped = lenA + 1;
            ret = E_INVALIDARG;
        }
    }
    if(escapedW != bufW) HeapFree(GetProcessHeap(), 0, escapedW);
    RtlFreeUnicodeString(&urlW);
    return ret;
}

⌨️ 快捷键说明

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