📄 urlcache.c
字号:
/***********************************************************************
* URLCache_FindEntryInHash (Internal)
*
* Searches all the hash tables in the index for the given URL and
* returns the entry, if it was found, in ppEntry
*
* RETURNS
* TRUE if the entry was found
* FALSE if the entry could not be found
*
*/
static BOOL URLCache_FindEntryInHash(LPCURLCACHE_HEADER pHeader, LPCSTR lpszUrl, CACHEFILE_ENTRY ** ppEntry)
{
struct _HASH_ENTRY * pHashEntry;
if (URLCache_FindHash(pHeader, lpszUrl, &pHashEntry))
{
*ppEntry = (CACHEFILE_ENTRY *)((LPBYTE)pHeader + pHashEntry->dwOffsetEntry);
return TRUE;
}
return FALSE;
}
/***********************************************************************
* URLCache_HashEntrySetUse (Internal)
*
* Searches all the hash tables in the index for the given URL and
* sets the use count (stored or'ed with key)
*
* RETURNS
* TRUE if the entry was found
* FALSE if the entry could not be found
*
*/
static BOOL URLCache_HashEntrySetUse(LPCURLCACHE_HEADER pHeader, LPCSTR lpszUrl, DWORD dwUseCount)
{
struct _HASH_ENTRY * pHashEntry;
if (URLCache_FindHash(pHeader, lpszUrl, &pHashEntry))
{
pHashEntry->dwHashKey = dwUseCount | (DWORD)(pHashEntry->dwHashKey / HASHTABLE_NUM_ENTRIES) * HASHTABLE_NUM_ENTRIES;
return TRUE;
}
return FALSE;
}
/***********************************************************************
* URLCache_DeleteEntryFromHash (Internal)
*
* Searches all the hash tables in the index for the given URL and
* then if found deletes the entry.
*
* RETURNS
* TRUE if the entry was found
* FALSE if the entry could not be found
*
*/
static BOOL URLCache_DeleteEntryFromHash(LPCURLCACHE_HEADER pHeader, LPCSTR lpszUrl)
{
struct _HASH_ENTRY * pHashEntry;
if (URLCache_FindHash(pHeader, lpszUrl, &pHashEntry))
{
pHashEntry->dwHashKey = HASHTABLE_FREE;
pHashEntry->dwOffsetEntry = HASHTABLE_FREE;
return TRUE;
}
return FALSE;
}
/***********************************************************************
* URLCache_AddEntryToHash (Internal)
*
* Searches all the hash tables for a free slot based on the offset
* generated from the hash key. If a free slot is found, the offset and
* key are entered into the hash table.
*
* RETURNS
* TRUE if the entry was added
* FALSE if the entry could not be added
*
*/
static BOOL URLCache_AddEntryToHash(LPURLCACHE_HEADER pHeader, LPCSTR lpszUrl, DWORD dwOffsetEntry)
{
/* see URLCache_FindEntryInHash for structure of hash tables */
DWORD key = URLCache_HashKey(lpszUrl);
DWORD offset = (key % HASHTABLE_NUM_ENTRIES) * sizeof(struct _HASH_ENTRY);
HASH_CACHEFILE_ENTRY * pHashEntry;
DWORD dwHashTableNumber = 0;
key = (DWORD)(key / HASHTABLE_NUM_ENTRIES) * HASHTABLE_NUM_ENTRIES;
for (pHashEntry = URLCache_HashEntryFromOffset(pHeader, pHeader->dwOffsetFirstHashTable);
((DWORD)((LPBYTE)pHashEntry - (LPBYTE)pHeader) >= ENTRY_START_OFFSET) && ((DWORD)((LPBYTE)pHashEntry - (LPBYTE)pHeader) < pHeader->dwFileSize);
pHashEntry = URLCache_HashEntryFromOffset(pHeader, pHashEntry->dwAddressNext))
{
int i;
if (pHashEntry->dwHashTableNumber != dwHashTableNumber++)
{
ERR("not right hash table number (%ld) expected %ld\n", pHashEntry->dwHashTableNumber, dwHashTableNumber);
break;
}
/* make sure that it is in fact a hash entry */
if (pHashEntry->CacheFileEntry.dwSignature != HASH_SIGNATURE)
{
ERR("not right signature (\"%.4s\") - expected \"HASH\"\n", (LPCSTR)&pHashEntry->CacheFileEntry.dwSignature);
break;
}
for (i = 0; i < HASHTABLE_BLOCKSIZE; i++)
{
struct _HASH_ENTRY * pHashElement = &pHashEntry->HashTable[offset + i];
if (pHashElement->dwHashKey == HASHTABLE_FREE) /* if the slot is free */
{
pHashElement->dwHashKey = key;
pHashElement->dwOffsetEntry = dwOffsetEntry;
return TRUE;
}
}
}
pHashEntry = URLCache_CreateHashTable(pHeader, pHashEntry);
if (!pHashEntry)
return FALSE;
pHashEntry->HashTable[offset].dwHashKey = key;
pHashEntry->HashTable[offset].dwOffsetEntry = dwOffsetEntry;
return TRUE;
}
static HASH_CACHEFILE_ENTRY *URLCache_CreateHashTable(LPURLCACHE_HEADER pHeader, HASH_CACHEFILE_ENTRY *pPrevHash)
{
HASH_CACHEFILE_ENTRY *pHash;
DWORD dwOffset;
int i;
if (!URLCache_FindFirstFreeEntry(pHeader, 0x20, (CACHEFILE_ENTRY **)&pHash))
{
FIXME("no free space for hash table\n");
SetLastError(ERROR_DISK_FULL);
return NULL;
}
dwOffset = (BYTE *)pHash - (BYTE *)pHeader;
if (pPrevHash)
pPrevHash->dwAddressNext = dwOffset;
else
pHeader->dwOffsetFirstHashTable = dwOffset;
pHash->CacheFileEntry.dwSignature = HASH_SIGNATURE;
pHash->CacheFileEntry.dwBlocksUsed = 0x20;
pHash->dwHashTableNumber = pPrevHash ? pPrevHash->dwHashTableNumber + 1 : 0;
for (i = 0; i < HASHTABLE_SIZE; i++)
{
pHash->HashTable[i].dwOffsetEntry = 0;
pHash->HashTable[i].dwHashKey = HASHTABLE_FREE;
}
return pHash;
}
/***********************************************************************
* GetUrlCacheEntryInfoExA (WININET.@)
*
*/
BOOL WINAPI GetUrlCacheEntryInfoExA(
LPCSTR lpszUrl,
LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo,
LPDWORD lpdwCacheEntryInfoBufSize,
LPSTR lpszReserved,
LPDWORD lpdwReserved,
LPVOID lpReserved,
DWORD dwFlags)
{
TRACE("(%s, %p, %p, %p, %p, %p, %lx)\n",
debugstr_a(lpszUrl),
lpCacheEntryInfo,
lpdwCacheEntryInfoBufSize,
lpszReserved,
lpdwReserved,
lpReserved,
dwFlags);
if ((lpszReserved != NULL) ||
(lpdwReserved != NULL) ||
(lpReserved != NULL))
{
ERR("Reserved value was not 0\n");
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (dwFlags != 0)
FIXME("Undocumented flag(s): %lx\n", dwFlags);
return GetUrlCacheEntryInfoA(lpszUrl, lpCacheEntryInfo, lpdwCacheEntryInfoBufSize);
}
/***********************************************************************
* GetUrlCacheEntryInfoA (WININET.@)
*
*/
BOOL WINAPI GetUrlCacheEntryInfoA(
IN LPCSTR lpszUrlName,
IN LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo,
IN OUT LPDWORD lpdwCacheEntryInfoBufferSize
)
{
LPURLCACHE_HEADER pHeader;
CACHEFILE_ENTRY * pEntry;
URL_CACHEFILE_ENTRY * pUrlEntry;
URLCACHECONTAINER * pContainer;
TRACE("(%s, %p, %p)\n", debugstr_a(lpszUrlName), lpCacheEntryInfo, lpdwCacheEntryInfoBufferSize);
if (!URLCacheContainers_FindContainerA(lpszUrlName, &pContainer))
return FALSE;
if (!URLCacheContainer_OpenIndex(pContainer))
return FALSE;
if (!(pHeader = URLCacheContainer_LockIndex(pContainer)))
return FALSE;
if (!URLCache_FindEntryInHash(pHeader, lpszUrlName, &pEntry))
{
URLCacheContainer_UnlockIndex(pContainer, pHeader);
WARN("entry %s not found!\n", debugstr_a(lpszUrlName));
SetLastError(ERROR_FILE_NOT_FOUND);
return FALSE;
}
if (pEntry->dwSignature != URL_SIGNATURE)
{
URLCacheContainer_UnlockIndex(pContainer, pHeader);
FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD)));
SetLastError(ERROR_FILE_NOT_FOUND);
return FALSE;
}
pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry;
TRACE("Found URL: %s\n", debugstr_a(pUrlEntry->szSourceUrlName));
if (pUrlEntry->dwOffsetHeaderInfo)
TRACE("Header info: %s\n", debugstr_a((LPSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo));
if (!URLCache_CopyEntry(
pContainer,
pHeader,
lpCacheEntryInfo,
lpdwCacheEntryInfoBufferSize,
pUrlEntry,
FALSE /* ANSI */))
{
URLCacheContainer_UnlockIndex(pContainer, pHeader);
return FALSE;
}
TRACE("Local File Name: %s\n", debugstr_a(lpCacheEntryInfo->lpszLocalFileName));
URLCacheContainer_UnlockIndex(pContainer, pHeader);
return TRUE;
}
/***********************************************************************
* GetUrlCacheEntryInfoW (WININET.@)
*
*/
BOOL WINAPI GetUrlCacheEntryInfoW(LPCWSTR lpszUrl,
LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo,
LPDWORD lpdwCacheEntryInfoBufferSize)
{
LPURLCACHE_HEADER pHeader;
CACHEFILE_ENTRY * pEntry;
URL_CACHEFILE_ENTRY * pUrlEntry;
URLCACHECONTAINER * pContainer;
LPSTR lpszUrlA;
int url_len;
TRACE("(%s, %p, %p)\n", debugstr_w(lpszUrl), lpCacheEntryInfo, lpdwCacheEntryInfoBufferSize);
url_len = WideCharToMultiByte(CP_ACP, 0, lpszUrl, -1, NULL, 0, NULL, NULL);
lpszUrlA = HeapAlloc(GetProcessHeap(), 0, url_len * sizeof(CHAR));
if (!lpszUrlA)
{
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
WideCharToMultiByte(CP_ACP, 0, lpszUrl, -1, lpszUrlA, url_len, NULL, NULL);
if (!URLCacheContainers_FindContainerW(lpszUrl, &pContainer))
{
HeapFree(GetProcessHeap(), 0, lpszUrlA);
return FALSE;
}
if (!URLCacheContainer_OpenIndex(pContainer))
{
HeapFree(GetProcessHeap(), 0, lpszUrlA);
return FALSE;
}
if (!(pHeader = URLCacheContainer_LockIndex(pContainer)))
{
HeapFree(GetProcessHeap(), 0, lpszUrlA);
return FALSE;
}
if (!URLCache_FindEntryInHash(pHeader, lpszUrlA, &pEntry))
{
URLCacheContainer_UnlockIndex(pContainer, pHeader);
WARN("entry %s not found!\n", debugstr_a(lpszUrlA));
HeapFree(GetProcessHeap(), 0, lpszUrlA);
SetLastError(ERROR_FILE_NOT_FOUND);
return FALSE;
}
HeapFree(GetProcessHeap(), 0, lpszUrlA);
if (pEntry->dwSignature != URL_SIGNATURE)
{
URLCacheContainer_UnlockIndex(pContainer, pHeader);
FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD)));
SetLastError(ERROR_FILE_NOT_FOUND);
return FALSE;
}
pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry;
TRACE("Found URL: %s\n", debugstr_a(pUrlEntry->szSourceUrlName));
TRACE("Header info: %s\n", debugstr_a((LPSTR)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo));
if (!URLCache_CopyEntry(
pContainer,
pHeader,
(LPINTERNET_CACHE_ENTRY_INFOA)lpCacheEntryInfo,
lpdwCacheEntryInfoBufferSize,
pUrlEntry,
TRUE /* UNICODE */))
{
URLCacheContainer_UnlockIndex(pContainer, pHeader);
return FALSE;
}
TRACE("Local File Name: %s\n", debugstr_w(lpCacheEntryInfo->lpszLocalFileName));
URLCacheContainer_UnlockIndex(pContainer, pHeader);
return TRUE;
}
/***********************************************************************
* GetUrlCacheEntryInfoExW (WININET.@)
*
*/
BOOL WINAPI GetUrlCacheEntryInfoExW(
LPCWSTR lpszUrl,
LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo,
LPDWORD lpdwCacheEntryInfoBufSize,
LPWSTR lpszReserved,
LPDWORD lpdwReserved,
LPVOID lpReserved,
DWORD dwFlags)
{
TRACE("(%s, %p, %p, %p, %p, %p, %lx)\n",
debugstr_w(lpszUrl),
lpCacheEntryInfo,
lpdwCacheEntryInfoBufSize,
lpszReserved,
lpdwReserved,
lpReserved,
dwFlags);
if ((lpszReserved != NULL) ||
(lpdwReserved != NULL) ||
(lpReserved != NULL))
{
ERR("Reserved value was not 0\n");
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (dwFlags != 0)
FIXME("Undocumented flag(s): %lx\n", dwFlags);
return GetUrlCacheEntryInfoW(lpszUrl, lpCacheEntryInfo, lpdwCacheEntryInfoBufSize);
}
/***********************************************************************
* SetUrlCacheEntryInfoA (WININET.@)
*/
BOOL WINAPI SetUrlCacheEntryInfoA(
LPCSTR lpszUrlName,
LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo,
DWORD dwFieldControl)
{
LPURLCACHE_HEADER pHeader;
CACHEFILE_ENTRY * pEntry;
URLCACHECONTAINER * pContainer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -