Commit 819eb528 authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

wininet: Reimplement IsUrlCacheEntryExpired.

parent 1bff3599
......@@ -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());
}
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)
{
HANDLE file;
......@@ -336,6 +447,7 @@ static void test_urlcacheA(void)
test_GetUrlCacheEntryInfoExA();
test_RetrieveUrlCacheEntryA();
test_IsUrlCacheEntryExpiredA();
if (pDeleteUrlCacheEntryA)
{
......
......@@ -3649,6 +3649,24 @@ DWORD WINAPI DeleteIE3Cache(HWND hWnd, HINSTANCE hInst, LPSTR lpszCmdLine, int n
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.@)
*
......@@ -3664,51 +3682,57 @@ BOOL WINAPI IsUrlCacheEntryExpiredA( LPCSTR url, DWORD dwFlags, FILETIME* pftLas
const CACHEFILE_ENTRY * pEntry;
const URL_CACHEFILE_ENTRY * pUrlEntry;
URLCACHECONTAINER * pContainer;
DWORD error;
BOOL expired;
TRACE("(%s, %08x, %p)\n", debugstr_a(url), dwFlags, pftLastModified);
error = URLCacheContainers_FindContainerA(url, &pContainer);
if (error != ERROR_SUCCESS)
if (!url || !pftLastModified)
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);
return FALSE;
memset(pftLastModified, 0, sizeof(*pftLastModified));
return TRUE;
}
error = URLCacheContainer_OpenIndex(pContainer);
if (error != ERROR_SUCCESS)
if (URLCacheContainer_OpenIndex(pContainer))
{
SetLastError(error);
return FALSE;
memset(pftLastModified, 0, sizeof(*pftLastModified));
return TRUE;
}
if (!(pHeader = URLCacheContainer_LockIndex(pContainer)))
return FALSE;
{
memset(pftLastModified, 0, sizeof(*pftLastModified));
return TRUE;
}
if (!URLCache_FindHash(pHeader, url, &pHashEntry))
{
URLCacheContainer_UnlockIndex(pContainer, pHeader);
memset(pftLastModified, 0, sizeof(*pftLastModified));
TRACE("entry %s not found!\n", url);
SetLastError(ERROR_FILE_NOT_FOUND);
return FALSE;
return TRUE;
}
pEntry = (const CACHEFILE_ENTRY *)((LPBYTE)pHeader + pHashEntry->dwOffsetEntry);
if (pEntry->dwSignature != URL_SIGNATURE)
{
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)));
SetLastError(ERROR_FILE_NOT_FOUND);
return FALSE;
return TRUE;
}
pUrlEntry = (const URL_CACHEFILE_ENTRY *)pEntry;
URLCache_DosDateTimeToFileTime(pUrlEntry->wExpiredDate, pUrlEntry->wExpiredTime, pftLastModified);
expired = IsUrlCacheEntryExpiredInternal(pUrlEntry, pftLastModified);
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 URL_CACHEFILE_ENTRY * pUrlEntry;
URLCACHECONTAINER * pContainer;
DWORD error;
BOOL expired;
TRACE("(%s, %08x, %p)\n", debugstr_w(url), dwFlags, pftLastModified);
error = URLCacheContainers_FindContainerW(url, &pContainer);
if (error != ERROR_SUCCESS)
if (!url || !pftLastModified)
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);
return FALSE;
memset(pftLastModified, 0, sizeof(*pftLastModified));
return TRUE;
}
error = URLCacheContainer_OpenIndex(pContainer);
if (error != ERROR_SUCCESS)
if (URLCacheContainer_OpenIndex(pContainer))
{
SetLastError(error);
return FALSE;
memset(pftLastModified, 0, sizeof(*pftLastModified));
return TRUE;
}
if (!(pHeader = URLCacheContainer_LockIndex(pContainer)))
return FALSE;
{
memset(pftLastModified, 0, sizeof(*pftLastModified));
return TRUE;
}
if (!URLCache_FindHashW(pHeader, url, &pHashEntry))
{
URLCacheContainer_UnlockIndex(pContainer, pHeader);
memset(pftLastModified, 0, sizeof(*pftLastModified));
TRACE("entry %s not found!\n", debugstr_w(url));
SetLastError(ERROR_FILE_NOT_FOUND);
return FALSE;
return TRUE;
}
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);
if (pEntry->dwSignature != URL_SIGNATURE)
{
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)));
SetLastError(ERROR_FILE_NOT_FOUND);
return FALSE;
return TRUE;
}
pUrlEntry = (const URL_CACHEFILE_ENTRY *)pEntry;
URLCache_DosDateTimeToFileTime(pUrlEntry->wExpiredDate, pUrlEntry->wExpiredTime, pftLastModified);
expired = IsUrlCacheEntryExpiredInternal(pUrlEntry, pftLastModified);
URLCacheContainer_UnlockIndex(pContainer, pHeader);
return TRUE;
return expired;
}
/***********************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment