From ee1fdbf24604c5e1c5c8b96e68b12d1e12ce7d21 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Thu, 7 Mar 2013 13:50:14 +0100 Subject: [PATCH] wininet: Added better urlcache index file validation on first open. index.dat file may get broken when computer is switched off incorrectly or when application crashes --- dlls/wininet/urlcache.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/dlls/wininet/urlcache.c b/dlls/wininet/urlcache.c index 9d9f2e10a0..da20c685a9 100644 --- a/dlls/wininet/urlcache.c +++ b/dlls/wininet/urlcache.c @@ -385,6 +385,41 @@ static DWORD cache_container_set_size(URLCACHECONTAINER *container, HANDLE file, return ERROR_SUCCESS; } +static BOOL cache_container_is_valid(URLCACHE_HEADER *header, DWORD file_size) +{ + DWORD allocation_size, count_bits, i; + + if(file_size < FILE_SIZE(MIN_BLOCK_NO)) + return FALSE; + + if(file_size != header->dwFileSize) + return FALSE; + + if (!memcmp(header->szSignature, urlcache_ver_prefix, sizeof(urlcache_ver_prefix)-1) && + memcmp(header->szSignature+sizeof(urlcache_ver_prefix)-1, urlcache_ver, sizeof(urlcache_ver)-1)) + return FALSE; + + if(FILE_SIZE(header->dwIndexCapacityInBlocks) != file_size) + return FALSE; + + allocation_size = 0; + for(i=0; idwIndexCapacityInBlocks/8; i++) { + for(count_bits = header->allocation_table[i]; count_bits!=0; count_bits>>=1) { + if(count_bits & 1) + allocation_size++; + } + } + if(allocation_size != header->dwBlocksInUse) + return FALSE; + + for(; iallocation_table[i]) + return FALSE; + } + + return TRUE; +} + /*********************************************************************** * cache_container_open_index (Internal) * @@ -451,8 +486,7 @@ static DWORD cache_container_open_index(URLCACHECONTAINER *container, DWORD bloc if(container->hMapping && validate) { URLCACHE_HEADER *header = MapViewOfFile(container->hMapping, FILE_MAP_WRITE, 0, 0, 0); - if(header && !memcmp(header->szSignature, urlcache_ver_prefix, sizeof(urlcache_ver_prefix)-1) && - memcmp(header->szSignature+sizeof(urlcache_ver_prefix)-1, urlcache_ver, sizeof(urlcache_ver)-1)) { + if(header && !cache_container_is_valid(header, file_size)) { WARN("detected old or broken index.dat file\n"); UnmapViewOfFile(header); FreeUrlCacheSpaceW(container->path, 100, 0);