wininet: Reimplement IsUrlCacheEntryExpired.

This commit is contained in:
Juan Lang 2011-03-08 10:39:37 -08:00 committed by Alexandre Julliard
parent 1bff3599ce
commit 819eb52866
2 changed files with 184 additions and 34 deletions

View File

@ -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)
{ {

View File

@ -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;
} }
/*********************************************************************** /***********************************************************************