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

📄 url.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 == L'+') ||
		 (*start == L'-') ||
		 (*start == L'.')) {
		start++;
		(*size)++;
	    }
	    else
		cont = FALSE;
	}
        break;

    case USERPASS:
	while (cont) {
	    if ( isalphaW(*start) ||
		 isdigitW(*start) ||
		 /* user/password only characters */
		 (*start == L';') ||
		 (*start == L'?') ||
		 (*start == L'&') ||
		 (*start == L'=') ||
		 /* *extra* characters */
		 (*start == L'!') ||
		 (*start == L'*') ||
		 (*start == L'\'') ||
		 (*start == L'(') ||
		 (*start == L')') ||
		 (*start == L',') ||
		 /* *safe* characters */
		 (*start == L'$') ||
		 (*start == L'_') ||
		 (*start == L'+') ||
		 (*start == L'-') ||
		 (*start == L'.')) {
		start++;
		(*size)++;
	    } else if (*start == L'%') {
		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 == L'-') ||
		(*start == L'.') ) {
		start++;
		(*size)++;
	    }
	    else
		cont = FALSE;
	}
	break;
    default:
	FIXME("unknown type %d\n", type);
	return (LPWSTR)&alwayszero;
    }
    /* TRACE("scanned %ld 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 != L':')) goto ErrorExit;
    work++;
    if ((*work != L'/') || (*(work+1) != L'/')) goto ErrorExit;
    pl->pUserName = work + 2;
    work = URL_ScanID(pl->pUserName, &pl->szUserName, USERPASS);
    if (*work == L':' ) {
	/* parse password */
	work++;
	pl->pPassword = work;
	work = URL_ScanID(pl->pPassword, &pl->szPassword, USERPASS);
	if (*work != L'@') {
	    /* 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 == L'@') {
	/* no password */
	pl->szPassword = 0;
	pl->pPassword = 0;
    } else if (!*work || (*work == L'/') || (*work == L'.')) {
	/* 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 == L':') {
	/* parse port */
	work++;
	pl->pPort = work;
	work = URL_ScanID(pl->pPort, &pl->szPort, PORT);
    }
    if (*work == L'/') {
	/* see if query string */
	pl->pQuery = strchrW(work, L'?');
	if (pl->pQuery) pl->szQuery = strlenW(pl->pQuery);
    }
    TRACE("parse successful: scheme=%p(%ld), user=%p(%ld), pass=%p(%ld), host=%p(%ld), port=%p(%ld), query=%p(%ld)\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(%ld) %08lx %08lx)\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=%ld %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 (base.nScheme != URL_SCHEME_INVALID);
}

/*************************************************************************
 * PathIsURLW	[SHLWAPI.@]
 *
 * See PathIsURLA.
 */
BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
{
    PARSEDURLW base;
    DWORD res1;

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

    /* get protocol        */
    base.cbSize = sizeof(base);
    res1 = ParseURLW(lpstrPath, &base);
    return (base.nScheme != URL_SCHEME_INVALID);
}

/*************************************************************************
 *      UrlCreateFromPathA  	[SHLWAPI.@]
 * 
 * See UrlCreateFromPathW
 */
HRESULT WINAPI UrlCreateFromPathA(LPCSTR pszPath, LPSTR pszUrl, LPDWORD pcchUrl, DWORD dwReserved)
{
    WCHAR bufW[INTERNET_MAX_URL_LENGTH];
    WCHAR *urlW = bufW;
    UNICODE_STRING pathW;
    HRESULT ret;
    DWORD lenW = sizeof(bufW)/sizeof(WCHAR), lenA;

    if(!RtlCreateUnicodeStringFromAsciiz(&pathW, pszPath))
        return E_INVALIDARG;
    if((ret = UrlCreateFromPathW(pathW.Buffer, urlW, &lenW, dwReserved)) == E_POINTER) {
        urlW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
        ret = UrlCreateFromPathW(pathW.Buffer, urlW, &lenW, dwReserved);
    }
    if(ret == S_OK || ret == S_FALSE) {
        RtlUnicodeToMultiByteSize(&lenA, urlW, lenW * sizeof(WCHAR));
        if(*pcchUrl > lenA) {
            RtlUnicodeToMultiByteN(pszUrl, *pcchUrl - 1, &lenA, urlW, lenW * sizeof(WCHAR));
            pszUrl[lenA] = 0;
            *pcchUrl = lenA;
        } else {
            *pcchUrl = lenA + 1;
            ret = E_POINTER;
        }
    }
    if(urlW != bufW) HeapFree(GetProcessHeap(), 0, urlW);
    RtlFreeUnicodeString(&pathW);
    return ret;
}

/*************************************************************************
 *      UrlCreateFromPathW  	[SHLWAPI.@]
 *
 * Create a Url from a file path.
 *
 * PARAMS
 *  pszPath [I]    Path to convert
 *  pszUrl  [O]    Destination for the converted Url
 *  pcchUrl [I/O]  Length of pszUrl
 *  dwReserved [I] Reserved, must be 0
 *
 * RETURNS
 *  Success: S_OK pszUrl contains the converted path, S_FALSE if the path is already a Url
 *  Failure: An HRESULT error code.
 */
HRESULT WINAPI UrlCreateFromPathW(LPCWSTR pszPath, LPWSTR pszUrl, LPDWORD pcchUrl, DWORD dwReserved)
{
    DWORD needed;
    HRESULT

⌨️ 快捷键说明

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