From 819eb52866e69a3c4f73b9a74817bd046c94fbe4 Mon Sep 17 00:00:00 2001 From: Juan Lang Date: Tue, 8 Mar 2011 10:39:37 -0800 Subject: [PATCH] wininet: Reimplement IsUrlCacheEntryExpired. --- dlls/wininet/tests/urlcache.c | 112 ++++++++++++++++++++++++++++++++++ dlls/wininet/urlcache.c | 106 +++++++++++++++++++++----------- 2 files changed, 184 insertions(+), 34 deletions(-) diff --git a/dlls/wininet/tests/urlcache.c b/dlls/wininet/tests/urlcache.c index 92bd2f02f2..e003293d78 100644 --- a/dlls/wininet/tests/urlcache.c +++ b/dlls/wininet/tests/urlcache.c @@ -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) { diff --git a/dlls/wininet/urlcache.c b/dlls/wininet/urlcache.c index 6e357b06a6..babf9f7d9b 100644 --- a/dlls/wininet/urlcache.c +++ b/dlls/wininet/urlcache.c @@ -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; } /*********************************************************************** -- 2.32.0.93.g670b81a890