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

📄 url.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
}

/*************************************************************************
 *      UrlIsW  	[SHLWAPI.@]
 *
 * See UrlIsA.
 */
BOOL WINAPI UrlIsW(LPCWSTR pszUrl, URLIS Urlis)
{
    static const WCHAR stemp[] = { 'f','i','l','e',':',0 };
    PARSEDURLW base;
    DWORD res1;
    LPCWSTR last;

    TRACE("(%s %d)\n", debugstr_w(pszUrl), Urlis);

    switch (Urlis) {

    case URLIS_OPAQUE:
	base.cbSize = sizeof(base);
	res1 = ParseURLW(pszUrl, &base);
	if (res1) return FALSE;  /* invalid scheme */
	switch (base.nScheme)
	{
	case URL_SCHEME_MAILTO:
	case URL_SCHEME_SHELL:
	case URL_SCHEME_JAVASCRIPT:
	case URL_SCHEME_VBSCRIPT:
	case URL_SCHEME_ABOUT:
	    return TRUE;
	}
	return FALSE;

    case URLIS_FILEURL:
        return !strncmpW(stemp, pszUrl, 5);

    case URLIS_DIRECTORY:
        last = pszUrl + strlenW(pszUrl) - 1;
        return (last >= pszUrl && (*last == '/' || *last == '\\'));

    case URLIS_URL:
        return PathIsURLW(pszUrl);

    case URLIS_NOHISTORY:
    case URLIS_APPLIABLE:
    case URLIS_HASQUERY:
    default:
	FIXME("(%s %d): stub\n", debugstr_w(pszUrl), Urlis);
    }
    return FALSE;
}

/*************************************************************************
 *      UrlIsNoHistoryA  	[SHLWAPI.@]
 *
 * Determine if a Url should not be stored in the users history list.
 *
 * PARAMS
 *  pszUrl [I] Url to check
 *
 * RETURNS
 *  TRUE, if pszUrl should be excluded from the history list,
 *  FALSE otherwise.
 */
BOOL WINAPI UrlIsNoHistoryA(LPCSTR pszUrl)
{
    return UrlIsA(pszUrl, URLIS_NOHISTORY);
}

/*************************************************************************
 *      UrlIsNoHistoryW  	[SHLWAPI.@]
 *
 * See UrlIsNoHistoryA.
 */
BOOL WINAPI UrlIsNoHistoryW(LPCWSTR pszUrl)
{
    return UrlIsW(pszUrl, URLIS_NOHISTORY);
}

/*************************************************************************
 *      UrlIsOpaqueA  	[SHLWAPI.@]
 *
 * Determine if a Url is opaque.
 *
 * PARAMS
 *  pszUrl [I] Url to check
 *
 * RETURNS
 *  TRUE if pszUrl is opaque,
 *  FALSE Otherwise.
 *
 * NOTES
 *  An opaque Url is one that does not start with "<protocol>://".
 */
BOOL WINAPI UrlIsOpaqueA(LPCSTR pszUrl)
{
    return UrlIsA(pszUrl, URLIS_OPAQUE);
}

/*************************************************************************
 *      UrlIsOpaqueW  	[SHLWAPI.@]
 *
 * See UrlIsOpaqueA.
 */
BOOL WINAPI UrlIsOpaqueW(LPCWSTR pszUrl)
{
    return UrlIsW(pszUrl, URLIS_OPAQUE);
}

/*************************************************************************
 *  Scans for characters of type "type" and when not matching found,
 *  returns pointer to it and length in size.
 *
 * Characters tested based on RFC 1738
 */
static LPCWSTR  URL_ScanID(LPCWSTR start, LPDWORD size, WINE_URL_SCAN_TYPE type)
{
    static DWORD alwayszero = 0;
    BOOL cont = TRUE;

    *size = 0;

    switch(type){

    case SCHEME:
	while (cont) {
	    if ( (islowerW(*start) && isalphaW(*start)) ||
		 isdigitW(*start) ||
                 (*start == '+') ||
                 (*start == '-') ||
                 (*start == '.')) {
		start++;
		(*size)++;
	    }
	    else
		cont = FALSE;
	}
        break;

    case USERPASS:
	while (cont) {
	    if ( isalphaW(*start) ||
		 isdigitW(*start) ||
		 /* user/password only characters */
                 (*start == ';') ||
                 (*start == '?') ||
                 (*start == '&') ||
                 (*start == '=') ||
		 /* *extra* characters */
                 (*start == '!') ||
                 (*start == '*') ||
                 (*start == '\'') ||
                 (*start == '(') ||
                 (*start == ')') ||
                 (*start == ',') ||
		 /* *safe* characters */
                 (*start == '$') ||
                 (*start == '_') ||
                 (*start == '+') ||
                 (*start == '-') ||
                 (*start == '.')) {
		start++;
		(*size)++;
            } else if (*start == '%') {
		if (isxdigitW(*(start+1)) &&
		    isxdigitW(*(start+2))) {
		    start += 3;
		    *size += 3;
		} else
		    cont = FALSE;
	    } else
		cont = FALSE;
	}
	break;

    case PORT:
	while (cont) {
	    if (isdigitW(*start)) {
		start++;
		(*size)++;
	    }
	    else
		cont = FALSE;
	}
	break;

    case HOST:
	while (cont) {
	    if (isalnumW(*start) ||
                (*start == '-') ||
                (*start == '.') ) {
		start++;
		(*size)++;
	    }
	    else
		cont = FALSE;
	}
	break;
    default:
	FIXME("unknown type %d\n", type);
	return (LPWSTR)&alwayszero;
    }
    /* TRACE("scanned %d characters next char %p<%c>\n",
     *size, start, *start); */
    return start;
}

/*************************************************************************
 *  Attempt to parse URL into pieces.
 */
static LONG URL_ParseUrl(LPCWSTR pszUrl, WINE_PARSE_URL *pl)
{
    LPCWSTR work;

    memset(pl, 0, sizeof(WINE_PARSE_URL));
    pl->pScheme = pszUrl;
    work = URL_ScanID(pl->pScheme, &pl->szScheme, SCHEME);
    if (!*work || (*work != ':')) goto ErrorExit;
    work++;
    if ((*work != '/') || (*(work+1) != '/')) goto ErrorExit;
    pl->pUserName = work + 2;
    work = URL_ScanID(pl->pUserName, &pl->szUserName, USERPASS);
    if (*work == ':' ) {
	/* parse password */
	work++;
	pl->pPassword = work;
	work = URL_ScanID(pl->pPassword, &pl->szPassword, USERPASS);
        if (*work != '@') {
	    /* what we just parsed must be the hostname and port
	     * so reset pointers and clear then let it parse */
	    pl->szUserName = pl->szPassword = 0;
	    work = pl->pUserName - 1;
	    pl->pUserName = pl->pPassword = 0;
	}
    } else if (*work == '@') {
	/* no password */
	pl->szPassword = 0;
	pl->pPassword = 0;
    } else if (!*work || (*work == '/') || (*work == '.')) {
	/* what was parsed was hostname, so reset pointers and let it parse */
	pl->szUserName = pl->szPassword = 0;
	work = pl->pUserName - 1;
	pl->pUserName = pl->pPassword = 0;
    } else goto ErrorExit;

    /* now start parsing hostname or hostnumber */
    work++;
    pl->pHostName = work;
    work = URL_ScanID(pl->pHostName, &pl->szHostName, HOST);
    if (*work == ':') {
	/* parse port */
	work++;
	pl->pPort = work;
	work = URL_ScanID(pl->pPort, &pl->szPort, PORT);
    }
    if (*work == '/') {
	/* see if query string */
        pl->pQuery = strchrW(work, '?');
	if (pl->pQuery) pl->szQuery = strlenW(pl->pQuery);
    }
    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,
	  pl->pPassword, pl->szPassword,
	  pl->pHostName, pl->szHostName,
	  pl->pPort, pl->szPort,
	  pl->pQuery, pl->szQuery);
    return S_OK;
  ErrorExit:
    FIXME("failed to parse %s\n", debugstr_w(pszUrl));
    return E_INVALIDARG;
}

/*************************************************************************
 *      UrlGetPartA  	[SHLWAPI.@]
 *
 * Retrieve part of a Url.
 *
 * PARAMS
 *  pszIn   [I]   Url to parse
 *  pszOut  [O]   Destination for part of pszIn requested
 *  pcchOut [I]   Size of pszOut
 *          [O]   length of pszOut string EXLUDING '\0' if S_OK, otherwise
 *                needed size of pszOut INCLUDING '\0'.
 *  dwPart  [I]   URL_PART_ enum from "shlwapi.h"
 *  dwFlags [I]   URL_ flags from "shlwapi.h"
 *
 * RETURNS
 *  Success: S_OK. pszOut contains the part requested, pcchOut contains its length.
 *  Failure: An HRESULT error code describing the error.
 */
HRESULT WINAPI UrlGetPartA(LPCSTR pszIn, LPSTR pszOut, LPDWORD pcchOut,
			   DWORD dwPart, DWORD dwFlags)
{
    LPWSTR in, out;
    DWORD ret, len, len2;

    in = HeapAlloc(GetProcessHeap(), 0,
			      (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
    out = in + INTERNET_MAX_URL_LENGTH;

    MultiByteToWideChar(0, 0, pszIn, -1, in, INTERNET_MAX_URL_LENGTH);

    len = INTERNET_MAX_URL_LENGTH;
    ret = UrlGetPartW(in, out, &len, dwPart, dwFlags);

    if (ret != S_OK) {
	HeapFree(GetProcessHeap(), 0, in);
	return ret;
    }

    len2 = WideCharToMultiByte(0, 0, out, len, 0, 0, 0, 0);
    if (len2 > *pcchOut) {
	*pcchOut = len2;
	HeapFree(GetProcessHeap(), 0, in);
	return E_POINTER;
    }
    WideCharToMultiByte(0, 0, out, len+1, pszOut, *pcchOut, 0, 0);
    *pcchOut = len2;
    HeapFree(GetProcessHeap(), 0, in);
    return S_OK;
}

/*************************************************************************
 *      UrlGetPartW  	[SHLWAPI.@]
 *
 * See UrlGetPartA.
 */
HRESULT WINAPI UrlGetPartW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut,
			   DWORD dwPart, DWORD dwFlags)
{
    WINE_PARSE_URL pl;
    HRESULT ret;
    DWORD size, schsize;
    LPCWSTR addr, schaddr;

    TRACE("(%s %p %p(%d) %08x %08x)\n",
	  debugstr_w(pszIn), pszOut, pcchOut, *pcchOut, dwPart, dwFlags);

    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;
	    addr = pl.pScheme;
	    size = pl.szScheme;
	    break;

	case URL_PART_HOSTNAME:
	    if (!pl.szHostName) return E_INVALIDARG;
	    addr = pl.pHostName;
	    size = pl.szHostName;
	    break;

	case URL_PART_USERNAME:
	    if (!pl.szUserName) return E_INVALIDARG;
	    addr = pl.pUserName;
	    size = pl.szUserName;
	    break;

	case URL_PART_PASSWORD:
	    if (!pl.szPassword) return E_INVALIDARG;
	    addr = pl.pPassword;
	    size = pl.szPassword;
	    break;

	case URL_PART_PORT:
	    if (!pl.szPort) return E_INVALIDARG;
	    addr = pl.pPort;
	    size = pl.szPort;
	    break;

	case URL_PART_QUERY:
	    if (!pl.szQuery) return E_INVALIDARG;
	    addr = pl.pQuery;
	    size = pl.szQuery;
	    break;

	default:
	    return E_INVALIDARG;
	}

	if (dwFlags == URL_PARTFLAG_KEEPSCHEME) {
            if (*pcchOut < schsize + size + 2) {
                *pcchOut = schsize + size + 2;
		return E_POINTER;
	    }
            memcpy(pszOut, schaddr, schsize*sizeof(WCHAR));
            pszOut[schsize] = ':';
            memcpy(pszOut+schsize+1, addr, size*sizeof(WCHAR));
            pszOut[schsize+1+size] = 0;
            *pcchOut = schsize + 1 + size;
	}
	else {
	    if (*pcchOut < size + 1) {*pcchOut = size+1; return E_POINTER;}
            memcpy(pszOut, addr, size*sizeof(WCHAR));
            pszOut[size] = 0;
	    *pcchOut = size;
	}
	TRACE("len=%d %s\n", *pcchOut, debugstr_w(pszOut));
    }
    return ret;
}

/*************************************************************************
 * PathIsURLA	[SHLWAPI.@]
 *
 * Check if the given path is a Url.
 *
 * PARAMS
 *  lpszPath [I] Path to check.
 *
 * RETURNS
 *  TRUE  if lpszPath is a Url.
 *  FALSE if lpszPath is NULL or not a Url.
 */
BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
{
    PARSEDURLA base;
    DWORD res1;

    if (!lpstrPath || !*lpstrPath) return FALSE;

    /* get protocol        */
    base.cbSize = sizeof(base);
    res1 = ParseURLA(lpstrPath, &base);
    return

⌨️ 快捷键说明

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