📄 url.c
字号:
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, '#');
}
/*************************************************************************
* 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);
if (pszUrl1[len1-1] == '/') len1--;
len2 = strlen(pszUrl2);
if (pszUrl2[len2-1] == '/') len2--;
if (len1 == len2)
return strncmp(pszUrl1, pszUrl2, len1);
len = min(len1, len2);
ret = strncmp(pszUrl1, pszUrl2, len);
if (ret) return ret;
if (len1 > len2) return 1;
return -1;
}
/*************************************************************************
* UrlCompareW [SHLWAPI.@]
*
* See UrlCompareA.
*/
INT WINAPI UrlCompareW(
LPCWSTR pszUrl1,
LPCWSTR pszUrl2,
BOOL fIgnoreSlash)
{
INT ret;
size_t len, len1, len2;
if (!fIgnoreSlash)
return strcmpW(pszUrl1, pszUrl2);
len1 = strlenW(pszUrl1);
if (pszUrl1[len1-1] == '/') len1--;
len2 = strlenW(pszUrl2);
if (pszUrl2[len2-1] == '/') len2--;
if (len1 == len2)
return strncmpW(pszUrl1, pszUrl2, len1);
len = min(len1, len2);
ret = strncmpW(pszUrl1, pszUrl2, len);
if (ret) return ret;
if (len1 > len2) return 1;
return -1;
}
/*************************************************************************
* HashData [SHLWAPI.@]
*
* Hash an input block into a variable sized digest.
*
* PARAMS
* lpSrc [I] Input block
* nSrcLen [I] Length of lpSrc
* lpDest [I] Output for hash digest
* nDestLen [I] Length of lpDest
*
* RETURNS
* Success: TRUE. lpDest is filled with the computed hash value.
* Failure: FALSE, if any argument is invalid.
*/
HRESULT WINAPI HashData(const unsigned char *lpSrc, DWORD nSrcLen,
unsigned char *lpDest, DWORD nDestLen)
{
INT srcCount = nSrcLen - 1, destCount = nDestLen - 1;
if (IsBadReadPtr(lpSrc, nSrcLen) ||
IsBadWritePtr(lpDest, nDestLen))
return E_INVALIDARG;
while (destCount >= 0)
{
lpDest[destCount] = (destCount & 0xff);
destCount--;
}
while (srcCount >= 0)
{
destCount = nDestLen - 1;
while (destCount >= 0)
{
lpDest[destCount] = HashDataLookup[lpSrc[srcCount] ^ lpDest[destCount]];
destCount--;
}
srcCount--;
}
return S_OK;
}
/*************************************************************************
* UrlHashA [SHLWAPI.@]
*
* Produce a Hash from a Url.
*
* PARAMS
* pszUrl [I] Url to hash
* lpDest [O] Destinationh for hash
* nDestLen [I] Length of lpDest
*
* RETURNS
* Success: S_OK. lpDest is filled with the computed hash value.
* Failure: E_INVALIDARG, if any argument is invalid.
*/
HRESULT WINAPI UrlHashA(LPCSTR pszUrl, unsigned char *lpDest, DWORD nDestLen)
{
if (IsBadStringPtrA(pszUrl, -1) || IsBadWritePtr(lpDest, nDestLen))
return E_INVALIDARG;
HashData((const BYTE*)pszUrl, (int)strlen(pszUrl), lpDest, nDestLen);
return S_OK;
}
/*************************************************************************
* UrlHashW [SHLWAPI.@]
*
* See UrlHashA.
*/
HRESULT WINAPI UrlHashW(LPCWSTR pszUrl, unsigned char *lpDest, DWORD nDestLen)
{
char szUrl[MAX_PATH];
TRACE("(%s,%p,%d)\n",debugstr_w(pszUrl), lpDest, nDestLen);
if (IsBadStringPtrW(pszUrl, -1) || IsBadWritePtr(lpDest, nDestLen))
return E_INVALIDARG;
/* Win32 hashes the data as an ASCII string, presumably so that both A+W
* return the same digests for the same URL.
*/
WideCharToMultiByte(0, 0, pszUrl, -1, szUrl, MAX_PATH, 0, 0);
HashData((const BYTE*)szUrl, (int)strlen(szUrl), lpDest, nDestLen);
return S_OK;
}
/*************************************************************************
* UrlApplySchemeA [SHLWAPI.@]
*
* Apply a scheme to a Url.
*
* PARAMS
* pszIn [I] Url to apply scheme to
* pszOut [O] Destination for modified Url
* pcchOut [I/O] Length of pszOut/destination for length of pszOut
* dwFlags [I] URL_ flags from "shlwapi.h"
*
* RETURNS
* Success: S_OK: pszOut contains the modified Url, pcchOut contains its length.
* Failure: An HRESULT error code describing the error.
*/
HRESULT WINAPI UrlApplySchemeA(LPCSTR pszIn, LPSTR pszOut, LPDWORD pcchOut, DWORD dwFlags)
{
LPWSTR in, out;
DWORD ret, len, len2;
TRACE("(in %s, out size %d, flags %08x) using W version\n",
debugstr_a(pszIn), *pcchOut, dwFlags);
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 = UrlApplySchemeW(in, out, &len, dwFlags);
if ((ret != S_OK) && (ret != S_FALSE)) {
HeapFree(GetProcessHeap(), 0, in);
return ret;
}
len2 = WideCharToMultiByte(0, 0, out, len+1, 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 ret;
}
static HRESULT URL_GuessScheme(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut)
{
HKEY newkey;
BOOL j;
INT index;
DWORD value_len, data_len, dwType, i;
WCHAR reg_path[MAX_PATH];
WCHAR value[MAX_PATH], data[MAX_PATH];
WCHAR Wxx, Wyy;
MultiByteToWideChar(0, 0,
"Software\\Microsoft\\Windows\\CurrentVersion\\URL\\Prefixes",
-1, reg_path, MAX_PATH);
RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, 1, &newkey);
index = 0;
while(value_len = data_len = MAX_PATH,
RegEnumValueW(newkey, index, value, &value_len,
0, &dwType, (LPVOID)data, &data_len) == 0) {
TRACE("guess %d %s is %s\n",
index, debugstr_w(value), debugstr_w(data));
j = FALSE;
for(i=0; i<value_len; i++) {
Wxx = pszIn[i];
Wyy = value[i];
/* remember that TRUE is not-equal */
j = ChrCmpIW(Wxx, Wyy);
if (j) break;
}
if ((i == value_len) && !j) {
if (strlenW(data) + strlenW(pszIn) + 1 > *pcchOut) {
*pcchOut = strlenW(data) + strlenW(pszIn) + 1;
RegCloseKey(newkey);
return E_POINTER;
}
strcpyW(pszOut, data);
strcatW(pszOut, pszIn);
*pcchOut = strlenW(pszOut);
TRACE("matched and set to %s\n", debugstr_w(pszOut));
RegCloseKey(newkey);
return S_OK;
}
index++;
}
RegCloseKey(newkey);
return -1;
}
static HRESULT URL_ApplyDefault(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut)
{
HKEY newkey;
DWORD data_len, dwType;
WCHAR reg_path[MAX_PATH];
WCHAR value[MAX_PATH], data[MAX_PATH];
/* get and prepend default */
MultiByteToWideChar(0, 0,
"Software\\Microsoft\\Windows\\CurrentVersion\\URL\\DefaultPrefix",
-1, reg_path, MAX_PATH);
RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, 1, &newkey);
data_len = MAX_PATH;
value[0] = '@';
value[1] = '\0';
RegQueryValueExW(newkey, value, 0, &dwType, (LPBYTE)data, &data_len);
RegCloseKey(newkey);
if (strlenW(data) + strlenW(pszIn) + 1 > *pcchOut) {
*pcchOut = strlenW(data) + strlenW(pszIn) + 1;
return E_POINTER;
}
strcpyW(pszOut, data);
strcatW(pszOut, pszIn);
*pcchOut = strlenW(pszOut);
TRACE("used default %s\n", debugstr_w(pszOut));
return S_OK;
}
/*************************************************************************
* UrlApplySchemeW [SHLWAPI.@]
*
* See UrlApplySchemeA.
*/
HRESULT WINAPI UrlApplySchemeW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut, DWORD dwFlags)
{
PARSEDURLW in_scheme;
DWORD res1;
HRESULT ret;
TRACE("(in %s, out size %d, flags %08x)\n",
debugstr_w(pszIn), *pcchOut, dwFlags);
if (dwFlags & URL_APPLY_GUESSFILE) {
FIXME("(%s %p %p(%d) 0x%08x): stub URL_APPLY_GUESSFILE not implemented\n",
debugstr_w(pszIn), pszOut, pcchOut, *pcchOut, dwFlags);
strcpyW(pszOut, pszIn);
*pcchOut = strlenW(pszOut);
return S_FALSE;
}
in_scheme.cbSize = sizeof(in_scheme);
/* See if the base has a scheme */
res1 = ParseURLW(pszIn, &in_scheme);
if (res1) {
/* no scheme in input, need to see if we need to guess */
if (dwFlags & URL_APPLY_GUESSSCHEME) {
if ((ret = URL_GuessScheme(pszIn, pszOut, pcchOut)) != -1)
return ret;
}
}
else {
/* we have a scheme, see if valid (known scheme) */
if (in_scheme.nScheme) {
/* have valid scheme, so just copy and exit */
if (strlenW(pszIn) + 1 > *pcchOut) {
*pcchOut = strlenW(pszIn) + 1;
return E_POINTER;
}
strcpyW(pszOut, pszIn);
*pcchOut = strlenW(pszOut);
TRACE("valid scheme, returning copy\n");
return S_OK;
}
}
/* If we are here, then either invalid scheme,
* or no scheme and can't/failed guess.
*/
if ( ( ((res1 == 0) && (dwFlags & URL_APPLY_FORCEAPPLY)) ||
((res1 != 0)) ) &&
(dwFlags & URL_APPLY_DEFAULT)) {
/* find and apply default scheme */
return URL_ApplyDefault(pszIn, pszOut, pcchOut);
}
/* just copy and give proper return code */
if (strlenW(pszIn) + 1 > *pcchOut) {
*pcchOut = strlenW(pszIn) + 1;
return E_POINTER;
}
strcpyW(pszOut, pszIn);
*pcchOut = strlenW(pszOut);
TRACE("returning copy, left alone\n");
return S_FALSE;
}
/*************************************************************************
* UrlIsA [SHLWAPI.@]
*
* Determine if a Url is of a certain class.
*
* PARAMS
* pszUrl [I] Url to check
* Urlis [I] URLIS_ constant from "shlwapi.h"
*
* RETURNS
* TRUE if pszUrl belongs to the class type in Urlis.
* FALSE Otherwise.
*/
BOOL WINAPI UrlIsA(LPCSTR pszUrl, URLIS Urlis)
{
PARSEDURLA base;
DWORD res1;
LPCSTR last;
TRACE("(%s %d)\n", debugstr_a(pszUrl), Urlis);
switch (Urlis) {
case URLIS_OPAQUE:
base.cbSize = sizeof(base);
res1 = ParseURLA(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 !StrCmpNA("file:", pszUrl, 5);
case URLIS_DIRECTORY:
last = pszUrl + strlen(pszUrl) - 1;
return (last >= pszUrl && (*last == '/' || *last == '\\' ));
case URLIS_URL:
return PathIsURLA(pszUrl);
case URLIS_NOHISTORY:
case URLIS_APPLIABLE:
case URLIS_HASQUERY:
default:
FIXME("(%s %d): stub\n", debugstr_a(pszUrl), Urlis);
}
return FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -