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

📄 url.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:

	case '?':
	    if (int_flags & WINE_URL_ESCAPE_QUESTION) return TRUE;
            return FALSE;

        case '#':
            if (int_flags & WINE_URL_ESCAPE_HASH) return TRUE;
            return FALSE;

	default:
	    return FALSE;
	}
    }
}


/*************************************************************************
 *      UrlEscapeW	[SHLWAPI.@]
 *
 * Converts unsafe characters in a Url into escape sequences.
 *
 * PARAMS
 *  pszUrl      [I]   Url to modify
 *  pszEscaped  [O]   Destination for modified Url
 *  pcchEscaped [I/O] Length of pszUrl, destination for length of pszEscaped
 *  dwFlags     [I]   URL_ flags from "shlwapi.h"
 *
 * RETURNS
 *  Success: S_OK. pszEscaped contains the escaped Url, pcchEscaped
 *           contains its length.
 *  Failure: E_POINTER, if pszEscaped is not large enough. In this case
 *           pcchEscaped is set to the required length.
 *
 * Converts unsafe characters into their escape sequences.
 *
 * NOTES
 * - By default this function stops converting at the first '?' or
 *  '#' character.
 * - If dwFlags contains URL_ESCAPE_SPACES_ONLY then only spaces are
 *   converted, but the conversion continues past a '?' or '#'.
 * - Note that this function did not work well (or at all) in shlwapi version 4.
 *
 * BUGS
 *  Only the following flags are implemented:
 *|     URL_ESCAPE_SPACES_ONLY
 *|     URL_DONT_ESCAPE_EXTRA_INFO
 *|     URL_ESCAPE_SEGMENT_ONLY
 *|     URL_ESCAPE_PERCENT
 */
HRESULT WINAPI UrlEscapeW(
	LPCWSTR pszUrl,
	LPWSTR pszEscaped,
	LPDWORD pcchEscaped,
	DWORD dwFlags)
{
    LPCWSTR src;
    DWORD needed = 0, ret;
    BOOL stop_escaping = FALSE;
    WCHAR next[5], *dst = pszEscaped;
    INT len;
    PARSEDURLW parsed_url;
    DWORD int_flags;
    DWORD slashes = 0;
    static const WCHAR localhost[] = {'l','o','c','a','l','h','o','s','t',0};

    TRACE("(%s %p %p 0x%08lx)\n", debugstr_w(pszUrl), pszEscaped,
	  pcchEscaped, dwFlags);

    if(!pszUrl || !pszEscaped || !pcchEscaped)
	return E_INVALIDARG;

    if(dwFlags & ~(URL_ESCAPE_SPACES_ONLY |
		   URL_ESCAPE_SEGMENT_ONLY |
		   URL_DONT_ESCAPE_EXTRA_INFO |
		   URL_ESCAPE_PERCENT))
        FIXME("Unimplemented flags: %08lx\n", dwFlags);

    /* fix up flags */
    if (dwFlags & URL_ESCAPE_SPACES_ONLY)
	/* if SPACES_ONLY specified, reset the other controls */
	dwFlags &= ~(URL_DONT_ESCAPE_EXTRA_INFO |
		     URL_ESCAPE_PERCENT |
		     URL_ESCAPE_SEGMENT_ONLY);

    else
	/* if SPACES_ONLY *not* specified the assume DONT_ESCAPE_EXTRA_INFO */
	dwFlags |= URL_DONT_ESCAPE_EXTRA_INFO;


    int_flags = 0;
    if(dwFlags & URL_ESCAPE_SEGMENT_ONLY) {
        int_flags = WINE_URL_ESCAPE_QUESTION | WINE_URL_ESCAPE_HASH | WINE_URL_ESCAPE_SLASH;
    } else {
        parsed_url.cbSize = sizeof(parsed_url);
        if(ParseURLW(pszUrl, &parsed_url) != S_OK)
            parsed_url.nScheme = URL_SCHEME_INVALID;

        TRACE("scheme = %d (%s)\n", parsed_url.nScheme, debugstr_wn(parsed_url.pszProtocol, parsed_url.cchProtocol));

        if(dwFlags & URL_DONT_ESCAPE_EXTRA_INFO)
            int_flags = WINE_URL_STOP_ON_HASH | WINE_URL_STOP_ON_QUESTION;

        switch(parsed_url.nScheme) {
        case URL_SCHEME_FILE:
            int_flags |= WINE_URL_BASH_AS_SLASH | WINE_URL_COLLAPSE_SLASHES | WINE_URL_ESCAPE_HASH;
            int_flags &= ~WINE_URL_STOP_ON_HASH;
            break;

        case URL_SCHEME_HTTP:
        case URL_SCHEME_HTTPS:
            int_flags |= WINE_URL_BASH_AS_SLASH;
            if(parsed_url.pszSuffix[0] != '/' && parsed_url.pszSuffix[0] != '\\')
                int_flags |= WINE_URL_ESCAPE_SLASH;
            break;

        case URL_SCHEME_MAILTO:
            int_flags |= WINE_URL_ESCAPE_SLASH | WINE_URL_ESCAPE_QUESTION | WINE_URL_ESCAPE_HASH;
            int_flags &= ~(WINE_URL_STOP_ON_QUESTION | WINE_URL_STOP_ON_HASH);
            break;

        case URL_SCHEME_INVALID:
            break;

        case URL_SCHEME_FTP:
        default:
            if(parsed_url.pszSuffix[0] != '/')
                int_flags |= WINE_URL_ESCAPE_SLASH;
            break;
        }
    }

    for(src = pszUrl; *src; ) {
        WCHAR cur = *src;
        len = 0;
        
        if((int_flags & WINE_URL_COLLAPSE_SLASHES) && src == pszUrl + parsed_url.cchProtocol + 1) {
            int localhost_len = sizeof(localhost)/sizeof(WCHAR) - 1;
            while(cur == '/' || cur == '\\') {
                slashes++;
                cur = *++src;
            }
            if(slashes == 2 && !strncmpiW(src, localhost, localhost_len)) { /* file://localhost/ -> file:/// */
                if(*(src + localhost_len) == '/' || *(src + localhost_len) == '\\')
                src += localhost_len + 1;
                slashes = 3;
            }

            switch(slashes) {
            case 1:
            case 3:
                next[0] = next[1] = next[2] = '/';
                len = 3;
                break;
            case 0:
                len = 0;
                break;
            default:
                next[0] = next[1] = '/';
                len = 2;
                break;
            }
        }
        if(len == 0) {

            if(cur == '#' && (int_flags & WINE_URL_STOP_ON_HASH))
                stop_escaping = TRUE;

            if(cur == '?' && (int_flags & WINE_URL_STOP_ON_QUESTION))
                stop_escaping = TRUE;

            if(cur == '\\' && (int_flags & WINE_URL_BASH_AS_SLASH) && !stop_escaping) cur = '/';

            if(URL_NeedEscapeW(cur, dwFlags, int_flags) && stop_escaping == FALSE) {
                next[0] = L'%';
                next[1] = hexDigits[(cur >> 4) & 0xf];
                next[2] = hexDigits[cur & 0xf];
                len = 3;
            } else {
                next[0] = cur;
                len = 1;
            }
            src++;
        }

	if(needed + len <= *pcchEscaped) {
	    memcpy(dst, next, len*sizeof(WCHAR));
	    dst += len;
	}
	needed += len;
    }

    if(needed < *pcchEscaped) {
        *dst = '\0';
	ret = S_OK;
    } else {
        needed++; /* add one for the '\0' */
	ret = E_POINTER;
    }
    *pcchEscaped = needed;
    return ret;
}


/*************************************************************************
 *      UrlUnescapeA	[SHLWAPI.@]
 *
 * Converts Url escape sequences back to ordinary characters.
 *
 * PARAMS
 *  pszUrl        [I/O]  Url to convert
 *  pszUnescaped  [O]    Destination for converted Url
 *  pcchUnescaped [I/O]  Size of output string
 *  dwFlags       [I]    URL_ESCAPE_ Flags from "shlwapi.h"
 *
 * RETURNS
 *  Success: S_OK. The converted value is in pszUnescaped, or in pszUrl if
 *           dwFlags includes URL_ESCAPE_INPLACE.
 *  Failure: E_POINTER if the converted Url is bigger than pcchUnescaped. In
 *           this case pcchUnescaped is set to the size required.
 * NOTES
 *  If dwFlags includes URL_DONT_ESCAPE_EXTRA_INFO, the conversion stops at
 *  the first occurrence of either a '?' or '#' character.
 */
HRESULT WINAPI UrlUnescapeA(
	LPSTR pszUrl,
	LPSTR pszUnescaped,
	LPDWORD pcchUnescaped,
	DWORD dwFlags)
{
    char *dst, next;
    LPCSTR src;
    HRESULT ret;
    DWORD needed;
    BOOL stop_unescaping = FALSE;

    TRACE("(%s, %p, %p, 0x%08lx)\n", debugstr_a(pszUrl), pszUnescaped,
	  pcchUnescaped, dwFlags);

    if(!pszUrl || !pszUnescaped || !pcchUnescaped)
	return E_INVALIDARG;

    if(dwFlags & URL_UNESCAPE_INPLACE)
        dst = pszUrl;
    else
        dst = pszUnescaped;

    for(src = pszUrl, needed = 0; *src; src++, needed++) {
        if(dwFlags & URL_DONT_UNESCAPE_EXTRA_INFO &&
	   (*src == '#' || *src == '?')) {
	    stop_unescaping = TRUE;
	    next = *src;
	} else if(*src == '%' && isxdigit(*(src + 1)) && isxdigit(*(src + 2))
		  && stop_unescaping == FALSE) {
	    INT ih;
	    char buf[3];
	    memcpy(buf, src + 1, 2);
	    buf[2] = '\0';
	    ih = strtol(buf, NULL, 16);
	    next = (CHAR) ih;
	    src += 2; /* Advance to end of escape */
	} else
	    next = *src;

	if(dwFlags & URL_UNESCAPE_INPLACE || needed < *pcchUnescaped)
	    *dst++ = next;
    }

    if(dwFlags & URL_UNESCAPE_INPLACE || needed < *pcchUnescaped) {
        *dst = '\0';
	ret = S_OK;
    } else {
        needed++; /* add one for the '\0' */
	ret = E_POINTER;
    }
    if(!(dwFlags & URL_UNESCAPE_INPLACE))
        *pcchUnescaped = needed;

    if (ret == S_OK) {
	TRACE("result %s\n", (dwFlags & URL_UNESCAPE_INPLACE) ?
	      debugstr_a(pszUrl) : debugstr_a(pszUnescaped));
    }

    return ret;
}

/*************************************************************************
 *      UrlUnescapeW	[SHLWAPI.@]
 *
 * See UrlUnescapeA.
 */
HRESULT WINAPI UrlUnescapeW(
	LPWSTR pszUrl,
	LPWSTR pszUnescaped,
	LPDWORD pcchUnescaped,
	DWORD dwFlags)
{
    WCHAR *dst, next;
    LPCWSTR src;
    HRESULT ret;
    DWORD needed;
    BOOL stop_unescaping = FALSE;

    TRACE("(%s, %p, %p, 0x%08lx)\n", debugstr_w(pszUrl), pszUnescaped,
	  pcchUnescaped, dwFlags);

    if(!pszUrl || (!pszUnescaped && !(dwFlags & URL_UNESCAPE_INPLACE))|| !pcchUnescaped)
	return E_INVALIDARG;

    if(dwFlags & URL_UNESCAPE_INPLACE)
        dst = pszUrl;
    else
        dst = pszUnescaped;

    for(src = pszUrl, needed = 0; *src; src++, needed++) {
        if(dwFlags & URL_DONT_UNESCAPE_EXTRA_INFO &&
	   (*src == L'#' || *src == L'?')) {
	    stop_unescaping = TRUE;
	    next = *src;
	} else if(*src == L'%' && isxdigitW(*(src + 1)) && isxdigitW(*(src + 2))
		  && stop_unescaping == FALSE) {
	    INT ih;
	    WCHAR buf[5] = {'0','x',0};
	    memcpy(buf + 2, src + 1, 2*sizeof(WCHAR));
	    buf[4] = 0;
	    StrToIntExW(buf, STIF_SUPPORT_HEX, &ih);
	    next = (WCHAR) ih;
	    src += 2; /* Advance to end of escape */
	} else
	    next = *src;

	if(dwFlags & URL_UNESCAPE_INPLACE || needed < *pcchUnescaped)
	    *dst++ = next;
    }

    if(dwFlags & URL_UNESCAPE_INPLACE || needed < *pcchUnescaped) {
        *dst = L'\0';
	ret = S_OK;
    } else {
        needed++; /* add one for the '\0' */
	ret = E_POINTER;
    }
    if(!(dwFlags & URL_UNESCAPE_INPLACE))
        *pcchUnescaped = needed;

    if (ret == S_OK) {
	TRACE("result %s\n", (dwFlags & URL_UNESCAPE_INPLACE) ?
	      debugstr_w(pszUrl) : debugstr_w(pszUnescaped));
    }

    return ret;
}

/*************************************************************************
 *      UrlGetLocationA 	[SHLWAPI.@]
 *
 * Get the location from a Url.
 *
 * PARAMS
 *  pszUrl [I] Url to get the location from
 *
 * RETURNS
 *  A pointer to the start of the location in pszUrl, or NULL if there is
 *  no location.
 *
 * NOTES
 *  - MSDN erroneously states that "The location is the segment of the Url
 *    starting with a '?' or '#' character". Neither V4 nor V5 of shlwapi.dll
 *    stop at '?' and always return a NULL in this case.
 *  - MSDN also erroneously states that "If a file URL has a query string,
 *    the returned string is the query string". In all tested cases, if the
 *    Url starts with "fi" then a NULL is returned. V5 gives the following results:
 *|       Result   Url
 *|       ------   ---
 *|       NULL     file://aa/b/cd#hohoh
 *|       #hohoh   http://aa/b/cd#hohoh
 *|       NULL     fi://aa/b/cd#hohoh
 *|       #hohoh   ff://aa/b/cd#hohoh
 */
LPCSTR WINAPI UrlGetLocationA(
	LPCSTR pszUrl)
{
    PARSEDURLA base;
    DWORD res1;

    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.pszProtocol, "file", min(4,base.cchProtocol)) == 0) return NULL;

    /* Look for '#' and return its addr */
    return strchr(base.pszSuffix, '#');
}

/*************************************************************************
 *      UrlGetLocationW 	[SHLWAPI.@]
 *
 * See UrlGetLocationA.
 */
LPCWSTR WINAPI UrlGetLocationW(
	LPCWSTR pszUrl)
{
    PARSEDURLW base;
    DWORD res1;

    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.pszProtocol, fileW, min(4,base.cchProtocol)) == 0) return NULL;

    /* Look for '#' and return its addr */
    return strchrW(base.pszSuffix, L'#');
}

/*************************************************************************
 *      UrlCompareA	[SHLWAPI.@]
 *
 * Compare two Urls.
 *
 * PARAMS
 *  pszUrl1      [I] First Url to compare
 *  pszUrl2      [I] Url to compare to pszUrl1
 *  fIgnoreSlash [I] TRUE = compare only up to a final slash
 *
 * RETURNS
 *  less than zero, zero, or greater than zero indicating pszUrl2 is greater
 *  than, equal to, or less than pszUrl1 respectively.
 */
INT WINAPI UrlCompareA(
	LPCSTR pszUrl1,
	LPCSTR pszUrl2,
	BOOL fIgnoreSlash)
{
    INT ret, len, len1, len2;

    if (!fIgnoreSlash)
	return strcmp(pszUrl1, pszUrl2);
    len1 = strlen(pszUrl1);

⌨️ 快捷键说明

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