wininet: Reimplement IsUrlCacheEntryExpired.
This commit is contained in:
parent
1bff3599ce
commit
819eb52866
|
@ -181,6 +181,117 @@ static void test_RetrieveUrlCacheEntryA(void)
|
||||||
ok(GetLastError() == ERROR_INVALID_PARAMETER, "RetrieveUrlCacheEntryFile should have set last error to ERROR_INVALID_PARAMETER instead of %d\n", GetLastError());
|
ok(GetLastError() == ERROR_INVALID_PARAMETER, "RetrieveUrlCacheEntryFile should have set last error to ERROR_INVALID_PARAMETER instead of %d\n", GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_IsUrlCacheEntryExpiredA(void)
|
||||||
|
{
|
||||||
|
static const char uncached_url[] =
|
||||||
|
"What's the airspeed velocity of an unladen swallow?";
|
||||||
|
BOOL ret;
|
||||||
|
FILETIME ft;
|
||||||
|
DWORD size;
|
||||||
|
LPINTERNET_CACHE_ENTRY_INFO info;
|
||||||
|
ULARGE_INTEGER exp_time;
|
||||||
|
|
||||||
|
/* The function returns TRUE when the output time is NULL or the tested URL
|
||||||
|
* is NULL.
|
||||||
|
*/
|
||||||
|
ret = IsUrlCacheEntryExpiredA(NULL, 0, NULL);
|
||||||
|
ok(ret, "expected TRUE\n");
|
||||||
|
ft.dwLowDateTime = 0xdeadbeef;
|
||||||
|
ft.dwHighDateTime = 0xbaadf00d;
|
||||||
|
ret = IsUrlCacheEntryExpiredA(NULL, 0, &ft);
|
||||||
|
ok(ret, "expected TRUE\n");
|
||||||
|
ok(ft.dwLowDateTime == 0xdeadbeef && ft.dwHighDateTime == 0xbaadf00d,
|
||||||
|
"expected time to be unchanged, got (%u,%u)\n",
|
||||||
|
ft.dwLowDateTime, ft.dwHighDateTime);
|
||||||
|
ret = IsUrlCacheEntryExpiredA(TEST_URL, 0, NULL);
|
||||||
|
ok(ret, "expected TRUE\n");
|
||||||
|
|
||||||
|
/* The return value should indicate whether the URL is expired,
|
||||||
|
* and the filetime indicates the last modified time, but a cache entry
|
||||||
|
* with a zero expire time is "not expired".
|
||||||
|
*/
|
||||||
|
ft.dwLowDateTime = 0xdeadbeef;
|
||||||
|
ft.dwHighDateTime = 0xbaadf00d;
|
||||||
|
ret = IsUrlCacheEntryExpiredA(TEST_URL, 0, &ft);
|
||||||
|
ok(!ret, "expected FALSE\n");
|
||||||
|
ok(!ft.dwLowDateTime && !ft.dwHighDateTime,
|
||||||
|
"expected time (0,0), got (%u,%u)\n",
|
||||||
|
ft.dwLowDateTime, ft.dwHighDateTime);
|
||||||
|
|
||||||
|
/* Same behavior with bogus flags. */
|
||||||
|
ft.dwLowDateTime = 0xdeadbeef;
|
||||||
|
ft.dwHighDateTime = 0xbaadf00d;
|
||||||
|
ret = IsUrlCacheEntryExpiredA(TEST_URL, 0xffffffff, &ft);
|
||||||
|
ok(!ret, "expected FALSE\n");
|
||||||
|
ok(!ft.dwLowDateTime && !ft.dwHighDateTime,
|
||||||
|
"expected time (0,0), got (%u,%u)\n",
|
||||||
|
ft.dwLowDateTime, ft.dwHighDateTime);
|
||||||
|
|
||||||
|
/* Set the expire time to a point in the past.. */
|
||||||
|
ret = GetUrlCacheEntryInfo(TEST_URL, NULL, &size);
|
||||||
|
ok(!ret, "GetUrlCacheEntryInfo should have failed\n");
|
||||||
|
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
|
||||||
|
"expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
|
||||||
|
info = HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
|
ret = GetUrlCacheEntryInfo(TEST_URL, info, &size);
|
||||||
|
GetSystemTimeAsFileTime(&info->ExpireTime);
|
||||||
|
exp_time.LowPart = info->ExpireTime.dwLowDateTime;
|
||||||
|
exp_time.HighPart = info->ExpireTime.dwHighDateTime;
|
||||||
|
exp_time.QuadPart -= 10 * 60 * (ULONGLONG)10000000;
|
||||||
|
info->ExpireTime.dwLowDateTime = exp_time.LowPart;
|
||||||
|
info->ExpireTime.dwHighDateTime = exp_time.HighPart;
|
||||||
|
ret = SetUrlCacheEntryInfo(TEST_URL, info, CACHE_ENTRY_EXPTIME_FC);
|
||||||
|
ok(ret, "SetUrlCacheEntryInfo failed: %d\n", GetLastError());
|
||||||
|
ft.dwLowDateTime = 0xdeadbeef;
|
||||||
|
ft.dwHighDateTime = 0xbaadf00d;
|
||||||
|
/* and the entry should be expired. */
|
||||||
|
ret = IsUrlCacheEntryExpiredA(TEST_URL, 0, &ft);
|
||||||
|
ok(ret, "expected TRUE\n");
|
||||||
|
/* The modified time returned is 0. */
|
||||||
|
ok(!ft.dwLowDateTime && !ft.dwHighDateTime,
|
||||||
|
"expected time (0,0), got (%u,%u)\n",
|
||||||
|
ft.dwLowDateTime, ft.dwHighDateTime);
|
||||||
|
/* Set the expire time to a point in the future.. */
|
||||||
|
exp_time.QuadPart += 20 * 60 * (ULONGLONG)10000000;
|
||||||
|
info->ExpireTime.dwLowDateTime = exp_time.LowPart;
|
||||||
|
info->ExpireTime.dwHighDateTime = exp_time.HighPart;
|
||||||
|
ret = SetUrlCacheEntryInfo(TEST_URL, info, CACHE_ENTRY_EXPTIME_FC);
|
||||||
|
ok(ret, "SetUrlCacheEntryInfo failed: %d\n", GetLastError());
|
||||||
|
ft.dwLowDateTime = 0xdeadbeef;
|
||||||
|
ft.dwHighDateTime = 0xbaadf00d;
|
||||||
|
/* and the entry should no longer be expired. */
|
||||||
|
ret = IsUrlCacheEntryExpiredA(TEST_URL, 0, &ft);
|
||||||
|
ok(!ret, "expected FALSE\n");
|
||||||
|
/* The modified time returned is still 0. */
|
||||||
|
ok(!ft.dwLowDateTime && !ft.dwHighDateTime,
|
||||||
|
"expected time (0,0), got (%u,%u)\n",
|
||||||
|
ft.dwLowDateTime, ft.dwHighDateTime);
|
||||||
|
/* Set the modified time... */
|
||||||
|
GetSystemTimeAsFileTime(&info->LastModifiedTime);
|
||||||
|
ret = SetUrlCacheEntryInfo(TEST_URL, info, CACHE_ENTRY_MODTIME_FC);
|
||||||
|
ok(ret, "SetUrlCacheEntryInfo failed: %d\n", GetLastError());
|
||||||
|
/* and the entry should still be unexpired.. */
|
||||||
|
ret = IsUrlCacheEntryExpiredA(TEST_URL, 0, &ft);
|
||||||
|
ok(!ret, "expected FALSE\n");
|
||||||
|
/* but the modified time returned is the last modified time just set. */
|
||||||
|
ok(ft.dwLowDateTime == info->LastModifiedTime.dwLowDateTime &&
|
||||||
|
ft.dwHighDateTime == info->LastModifiedTime.dwHighDateTime,
|
||||||
|
"expected time (%u,%u), got (%u,%u)\n",
|
||||||
|
info->LastModifiedTime.dwLowDateTime,
|
||||||
|
info->LastModifiedTime.dwHighDateTime,
|
||||||
|
ft.dwLowDateTime, ft.dwHighDateTime);
|
||||||
|
HeapFree(GetProcessHeap(), 0, info);
|
||||||
|
|
||||||
|
/* An uncached URL is implicitly expired, but with unknown time. */
|
||||||
|
ft.dwLowDateTime = 0xdeadbeef;
|
||||||
|
ft.dwHighDateTime = 0xbaadf00d;
|
||||||
|
ret = IsUrlCacheEntryExpiredA(uncached_url, 0, &ft);
|
||||||
|
ok(ret, "expected TRUE\n");
|
||||||
|
ok(!ft.dwLowDateTime && !ft.dwHighDateTime,
|
||||||
|
"expected time (0,0), got (%u,%u)\n",
|
||||||
|
ft.dwLowDateTime, ft.dwHighDateTime);
|
||||||
|
}
|
||||||
|
|
||||||
static void _check_file_exists(LONG l, LPCSTR filename)
|
static void _check_file_exists(LONG l, LPCSTR filename)
|
||||||
{
|
{
|
||||||
HANDLE file;
|
HANDLE file;
|
||||||
|
@ -336,6 +447,7 @@ static void test_urlcacheA(void)
|
||||||
|
|
||||||
test_GetUrlCacheEntryInfoExA();
|
test_GetUrlCacheEntryInfoExA();
|
||||||
test_RetrieveUrlCacheEntryA();
|
test_RetrieveUrlCacheEntryA();
|
||||||
|
test_IsUrlCacheEntryExpiredA();
|
||||||
|
|
||||||
if (pDeleteUrlCacheEntryA)
|
if (pDeleteUrlCacheEntryA)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3649,6 +3649,24 @@ DWORD WINAPI DeleteIE3Cache(HWND hWnd, HINSTANCE hInst, LPSTR lpszCmdLine, int n
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL IsUrlCacheEntryExpiredInternal(const URL_CACHEFILE_ENTRY *pUrlEntry,
|
||||||
|
FILETIME *pftLastModified)
|
||||||
|
{
|
||||||
|
BOOL ret;
|
||||||
|
FILETIME now, expired;
|
||||||
|
|
||||||
|
*pftLastModified = pUrlEntry->LastModifiedTime;
|
||||||
|
GetSystemTimeAsFileTime(&now);
|
||||||
|
URLCache_DosDateTimeToFileTime(pUrlEntry->wExpiredDate,
|
||||||
|
pUrlEntry->wExpiredTime, &expired);
|
||||||
|
/* If the expired time is 0, it's interpreted as not expired */
|
||||||
|
if (!expired.dwLowDateTime && !expired.dwHighDateTime)
|
||||||
|
ret = FALSE;
|
||||||
|
else
|
||||||
|
ret = CompareFileTime(&expired, &now) < 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* IsUrlCacheEntryExpiredA (WININET.@)
|
* IsUrlCacheEntryExpiredA (WININET.@)
|
||||||
*
|
*
|
||||||
|
@ -3664,51 +3682,57 @@ BOOL WINAPI IsUrlCacheEntryExpiredA( LPCSTR url, DWORD dwFlags, FILETIME* pftLas
|
||||||
const CACHEFILE_ENTRY * pEntry;
|
const CACHEFILE_ENTRY * pEntry;
|
||||||
const URL_CACHEFILE_ENTRY * pUrlEntry;
|
const URL_CACHEFILE_ENTRY * pUrlEntry;
|
||||||
URLCACHECONTAINER * pContainer;
|
URLCACHECONTAINER * pContainer;
|
||||||
DWORD error;
|
BOOL expired;
|
||||||
|
|
||||||
TRACE("(%s, %08x, %p)\n", debugstr_a(url), dwFlags, pftLastModified);
|
TRACE("(%s, %08x, %p)\n", debugstr_a(url), dwFlags, pftLastModified);
|
||||||
|
|
||||||
error = URLCacheContainers_FindContainerA(url, &pContainer);
|
if (!url || !pftLastModified)
|
||||||
if (error != ERROR_SUCCESS)
|
return TRUE;
|
||||||
|
if (dwFlags)
|
||||||
|
FIXME("unknown flags 0x%08x\n", dwFlags);
|
||||||
|
|
||||||
|
/* Any error implies that the URL is expired, i.e. not in the cache */
|
||||||
|
if (URLCacheContainers_FindContainerA(url, &pContainer))
|
||||||
{
|
{
|
||||||
SetLastError(error);
|
memset(pftLastModified, 0, sizeof(*pftLastModified));
|
||||||
return FALSE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = URLCacheContainer_OpenIndex(pContainer);
|
if (URLCacheContainer_OpenIndex(pContainer))
|
||||||
if (error != ERROR_SUCCESS)
|
|
||||||
{
|
{
|
||||||
SetLastError(error);
|
memset(pftLastModified, 0, sizeof(*pftLastModified));
|
||||||
return FALSE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(pHeader = URLCacheContainer_LockIndex(pContainer)))
|
if (!(pHeader = URLCacheContainer_LockIndex(pContainer)))
|
||||||
return FALSE;
|
{
|
||||||
|
memset(pftLastModified, 0, sizeof(*pftLastModified));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (!URLCache_FindHash(pHeader, url, &pHashEntry))
|
if (!URLCache_FindHash(pHeader, url, &pHashEntry))
|
||||||
{
|
{
|
||||||
URLCacheContainer_UnlockIndex(pContainer, pHeader);
|
URLCacheContainer_UnlockIndex(pContainer, pHeader);
|
||||||
|
memset(pftLastModified, 0, sizeof(*pftLastModified));
|
||||||
TRACE("entry %s not found!\n", url);
|
TRACE("entry %s not found!\n", url);
|
||||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
return TRUE;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pEntry = (const CACHEFILE_ENTRY *)((LPBYTE)pHeader + pHashEntry->dwOffsetEntry);
|
pEntry = (const CACHEFILE_ENTRY *)((LPBYTE)pHeader + pHashEntry->dwOffsetEntry);
|
||||||
if (pEntry->dwSignature != URL_SIGNATURE)
|
if (pEntry->dwSignature != URL_SIGNATURE)
|
||||||
{
|
{
|
||||||
URLCacheContainer_UnlockIndex(pContainer, pHeader);
|
URLCacheContainer_UnlockIndex(pContainer, pHeader);
|
||||||
|
memset(pftLastModified, 0, sizeof(*pftLastModified));
|
||||||
FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPCSTR)&pEntry->dwSignature, sizeof(DWORD)));
|
FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPCSTR)&pEntry->dwSignature, sizeof(DWORD)));
|
||||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
return TRUE;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pUrlEntry = (const URL_CACHEFILE_ENTRY *)pEntry;
|
pUrlEntry = (const URL_CACHEFILE_ENTRY *)pEntry;
|
||||||
|
expired = IsUrlCacheEntryExpiredInternal(pUrlEntry, pftLastModified);
|
||||||
URLCache_DosDateTimeToFileTime(pUrlEntry->wExpiredDate, pUrlEntry->wExpiredTime, pftLastModified);
|
|
||||||
|
|
||||||
URLCacheContainer_UnlockIndex(pContainer, pHeader);
|
URLCacheContainer_UnlockIndex(pContainer, pHeader);
|
||||||
|
|
||||||
return TRUE;
|
return expired;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -3726,51 +3750,65 @@ BOOL WINAPI IsUrlCacheEntryExpiredW( LPCWSTR url, DWORD dwFlags, FILETIME* pftLa
|
||||||
const CACHEFILE_ENTRY * pEntry;
|
const CACHEFILE_ENTRY * pEntry;
|
||||||
const URL_CACHEFILE_ENTRY * pUrlEntry;
|
const URL_CACHEFILE_ENTRY * pUrlEntry;
|
||||||
URLCACHECONTAINER * pContainer;
|
URLCACHECONTAINER * pContainer;
|
||||||
DWORD error;
|
BOOL expired;
|
||||||
|
|
||||||
TRACE("(%s, %08x, %p)\n", debugstr_w(url), dwFlags, pftLastModified);
|
TRACE("(%s, %08x, %p)\n", debugstr_w(url), dwFlags, pftLastModified);
|
||||||
|
|
||||||
error = URLCacheContainers_FindContainerW(url, &pContainer);
|
if (!url || !pftLastModified)
|
||||||
if (error != ERROR_SUCCESS)
|
return TRUE;
|
||||||
|
if (dwFlags)
|
||||||
|
FIXME("unknown flags 0x%08x\n", dwFlags);
|
||||||
|
|
||||||
|
/* Any error implies that the URL is expired, i.e. not in the cache */
|
||||||
|
if (URLCacheContainers_FindContainerW(url, &pContainer))
|
||||||
{
|
{
|
||||||
SetLastError(error);
|
memset(pftLastModified, 0, sizeof(*pftLastModified));
|
||||||
return FALSE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = URLCacheContainer_OpenIndex(pContainer);
|
if (URLCacheContainer_OpenIndex(pContainer))
|
||||||
if (error != ERROR_SUCCESS)
|
|
||||||
{
|
{
|
||||||
SetLastError(error);
|
memset(pftLastModified, 0, sizeof(*pftLastModified));
|
||||||
return FALSE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(pHeader = URLCacheContainer_LockIndex(pContainer)))
|
if (!(pHeader = URLCacheContainer_LockIndex(pContainer)))
|
||||||
return FALSE;
|
{
|
||||||
|
memset(pftLastModified, 0, sizeof(*pftLastModified));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (!URLCache_FindHashW(pHeader, url, &pHashEntry))
|
if (!URLCache_FindHashW(pHeader, url, &pHashEntry))
|
||||||
{
|
{
|
||||||
URLCacheContainer_UnlockIndex(pContainer, pHeader);
|
URLCacheContainer_UnlockIndex(pContainer, pHeader);
|
||||||
|
memset(pftLastModified, 0, sizeof(*pftLastModified));
|
||||||
TRACE("entry %s not found!\n", debugstr_w(url));
|
TRACE("entry %s not found!\n", debugstr_w(url));
|
||||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
return TRUE;
|
||||||
return FALSE;
|
}
|
||||||
|
|
||||||
|
if (!URLCache_FindHashW(pHeader, url, &pHashEntry))
|
||||||
|
{
|
||||||
|
URLCacheContainer_UnlockIndex(pContainer, pHeader);
|
||||||
|
memset(pftLastModified, 0, sizeof(*pftLastModified));
|
||||||
|
TRACE("entry %s not found!\n", debugstr_w(url));
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pEntry = (const CACHEFILE_ENTRY *)((LPBYTE)pHeader + pHashEntry->dwOffsetEntry);
|
pEntry = (const CACHEFILE_ENTRY *)((LPBYTE)pHeader + pHashEntry->dwOffsetEntry);
|
||||||
if (pEntry->dwSignature != URL_SIGNATURE)
|
if (pEntry->dwSignature != URL_SIGNATURE)
|
||||||
{
|
{
|
||||||
URLCacheContainer_UnlockIndex(pContainer, pHeader);
|
URLCacheContainer_UnlockIndex(pContainer, pHeader);
|
||||||
|
memset(pftLastModified, 0, sizeof(*pftLastModified));
|
||||||
FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPCSTR)&pEntry->dwSignature, sizeof(DWORD)));
|
FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPCSTR)&pEntry->dwSignature, sizeof(DWORD)));
|
||||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
return TRUE;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pUrlEntry = (const URL_CACHEFILE_ENTRY *)pEntry;
|
pUrlEntry = (const URL_CACHEFILE_ENTRY *)pEntry;
|
||||||
|
expired = IsUrlCacheEntryExpiredInternal(pUrlEntry, pftLastModified);
|
||||||
URLCache_DosDateTimeToFileTime(pUrlEntry->wExpiredDate, pUrlEntry->wExpiredTime, pftLastModified);
|
|
||||||
|
|
||||||
URLCacheContainer_UnlockIndex(pContainer, pHeader);
|
URLCacheContainer_UnlockIndex(pContainer, pHeader);
|
||||||
|
|
||||||
return TRUE;
|
return expired;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
Loading…
Reference in New Issue