Piotr Caban : wininet: Added support for leaked urlcache entries handling.

Alexandre Julliard julliard at winehq.org
Wed Sep 19 13:39:46 CDT 2012


Module: wine
Branch: master
Commit: b7010348cfc53674913733b72033ee16a6868f99
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=b7010348cfc53674913733b72033ee16a6868f99

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Wed Sep 19 15:30:03 2012 +0200

wininet: Added support for leaked urlcache entries handling.

---

 dlls/wininet/urlcache.c |  170 ++++++++++++++++++++++++++++++-----------------
 1 files changed, 109 insertions(+), 61 deletions(-)

diff --git a/dlls/wininet/urlcache.c b/dlls/wininet/urlcache.c
index 04ecd80..3a028b5 100644
--- a/dlls/wininet/urlcache.c
+++ b/dlls/wininet/urlcache.c
@@ -82,6 +82,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(wininet);
 
 #define PENDING_DELETE_CACHE_ENTRY  0x00400000
 
+#define CACHE_HEADER_DATA_ROOT_LEAK_OFFSET 0x16
+
 #define DWORD_SIG(a,b,c,d)  (a | (b << 8) | (c << 16) | (d << 24))
 #define URL_SIGNATURE   DWORD_SIG('U','R','L',' ')
 #define REDR_SIGNATURE  DWORD_SIG('R','E','D','R')
@@ -752,44 +754,6 @@ static BOOL URLCacheContainer_UnlockIndex(URLCACHECONTAINER * pContainer, LPURLC
     return UnmapViewOfFile(pHeader);
 }
 
-/***********************************************************************
- *           URLCacheContainer_CleanIndex (Internal)
- *
- * This function is meant to make place in index file by removing old
- * entries and resizing the file.
- *
- * CAUTION: file view may get mapped to new memory
- * TODO: implement entries cleaning
- *
- * RETURNS
- *     ERROR_SUCCESS when new memory is available
- *     error code otherwise
- */
-static DWORD URLCacheContainer_CleanIndex(URLCACHECONTAINER *container, URLCACHE_HEADER **file_view)
-{
-    URLCACHE_HEADER *header = *file_view;
-    DWORD ret;
-
-    FIXME("(%s %s) semi-stub\n", debugstr_w(container->cache_prefix), debugstr_w(container->path));
-
-    if(header->dwFileSize >= ALLOCATION_TABLE_SIZE*8*BLOCKSIZE + ENTRY_START_OFFSET) {
-        WARN("index file has maximal size\n");
-        return ERROR_NOT_ENOUGH_MEMORY;
-    }
-
-    URLCacheContainer_CloseIndex(container);
-    ret = URLCacheContainer_OpenIndex(container, header->dwIndexCapacityInBlocks*2);
-    if(ret != ERROR_SUCCESS)
-        return ret;
-    header = MapViewOfFile(container->hMapping, FILE_MAP_WRITE, 0, 0, 0);
-    if(!header)
-        return GetLastError();
-
-    UnmapViewOfFile(*file_view);
-    *file_view = header;
-    return ERROR_SUCCESS;
-}
-
 #ifndef CHAR_BIT
 #define CHAR_BIT    (8 * sizeof(CHAR))
 #endif
@@ -996,6 +960,107 @@ static BOOL URLCache_LocalFileNameToPathA(
     return FALSE;
 }
 
+/***********************************************************************
+ *           URLCache_DeleteFile (Internal)
+ */
+static DWORD URLCache_DeleteFile(const URLCACHECONTAINER *container,
+        URLCACHE_HEADER *header, URL_CACHEFILE_ENTRY *url_entry)
+{
+    WCHAR path[MAX_PATH];
+    LONG path_size = sizeof(path);
+    DWORD err;
+
+    if(!url_entry->dwOffsetLocalName)
+        goto succ;
+
+    if(!URLCache_LocalFileNameToPathW(container, header,
+                (LPCSTR)url_entry+url_entry->dwOffsetLocalName,
+                url_entry->CacheDir, path, &path_size))
+        goto succ;
+
+    err = (DeleteFileW(path) ? ERROR_SUCCESS : GetLastError());
+    if(err == ERROR_ACCESS_DENIED || err == ERROR_SHARING_VIOLATION)
+        return err;
+
+succ:
+    if (url_entry->CacheDir < header->DirectoryCount)
+    {
+        if (header->directory_data[url_entry->CacheDir].dwNumFiles)
+            header->directory_data[url_entry->CacheDir].dwNumFiles--;
+    }
+    if (url_entry->CacheEntryType & STICKY_CACHE_ENTRY)
+    {
+        if (url_entry->size.QuadPart < header->ExemptUsage.QuadPart)
+            header->ExemptUsage.QuadPart -= url_entry->size.QuadPart;
+        else
+            header->ExemptUsage.QuadPart = 0;
+    }
+    else
+    {
+        if (url_entry->size.QuadPart < header->CacheUsage.QuadPart)
+            header->CacheUsage.QuadPart -= url_entry->size.QuadPart;
+        else
+            header->CacheUsage.QuadPart = 0;
+    }
+
+    return ERROR_SUCCESS;
+}
+
+/***********************************************************************
+ *           URLCacheContainer_CleanIndex (Internal)
+ *
+ * This function is meant to make place in index file by removing leaked
+ * files entries and resizing the file.
+ *
+ * CAUTION: file view may get mapped to new memory
+ *
+ * RETURNS
+ *     ERROR_SUCCESS when new memory is available
+ *     error code otherwise
+ */
+static DWORD URLCacheContainer_CleanIndex(URLCACHECONTAINER *container, URLCACHE_HEADER **file_view)
+{
+    URLCACHE_HEADER *header = *file_view;
+    DWORD ret;
+    DWORD *leak_off;
+    BOOL freed = FALSE;
+
+    TRACE("(%s %s)\n", debugstr_w(container->cache_prefix), debugstr_w(container->path));
+
+    leak_off = &(*file_view)->options[CACHE_HEADER_DATA_ROOT_LEAK_OFFSET];
+    while(*leak_off) {
+        URL_CACHEFILE_ENTRY *url_entry = (URL_CACHEFILE_ENTRY*)((LPBYTE)(*file_view) + *leak_off);
+
+        if(SUCCEEDED(URLCache_DeleteFile(container, *file_view, url_entry))) {
+            *leak_off = url_entry->dwExemptDelta;
+            URLCache_DeleteEntry(*file_view, &url_entry->CacheFileEntry);
+            freed = TRUE;
+        }else {
+            leak_off = &url_entry->dwExemptDelta;
+        }
+    }
+
+    if(freed)
+        return ERROR_SUCCESS;
+
+    if(header->dwFileSize >= ALLOCATION_TABLE_SIZE*8*BLOCKSIZE + ENTRY_START_OFFSET) {
+        WARN("index file has maximal size\n");
+        return ERROR_NOT_ENOUGH_MEMORY;
+    }
+
+    URLCacheContainer_CloseIndex(container);
+    ret = URLCacheContainer_OpenIndex(container, header->dwIndexCapacityInBlocks*2);
+    if(ret != ERROR_SUCCESS)
+        return ret;
+    header = MapViewOfFile(container->hMapping, FILE_MAP_WRITE, 0, 0, 0);
+    if(!header)
+        return GetLastError();
+
+    UnmapViewOfFile(*file_view);
+    *file_view = header;
+    return ERROR_SUCCESS;
+}
+
 /* Just like DosDateTimeToFileTime, except that it also maps the special
  * case of a DOS date/time of (0,0) to a filetime of (0,0).
  */
@@ -2218,8 +2283,6 @@ static BOOL DeleteUrlCacheEntryInternal(const URLCACHECONTAINER * pContainer,
 {
     CACHEFILE_ENTRY * pEntry;
     URL_CACHEFILE_ENTRY * pUrlEntry;
-    WCHAR path[MAX_PATH];
-    LONG path_size = sizeof(path);
 
     pEntry = (CACHEFILE_ENTRY *)((LPBYTE)pHeader + pHashEntry->dwOffsetEntry);
     if (pEntry->dwSignature != URL_SIGNATURE)
@@ -2239,33 +2302,18 @@ static BOOL DeleteUrlCacheEntryInternal(const URLCACHECONTAINER * pContainer,
         return FALSE;
     }
 
-    if (pUrlEntry->CacheDir < pHeader->DirectoryCount)
+    if(!URLCache_DeleteFile(pContainer, pHeader, pUrlEntry))
     {
-        if (pHeader->directory_data[pUrlEntry->CacheDir].dwNumFiles)
-            pHeader->directory_data[pUrlEntry->CacheDir].dwNumFiles--;
-    }
-    if (pUrlEntry->CacheEntryType & STICKY_CACHE_ENTRY)
-    {
-        if (pUrlEntry->size.QuadPart < pHeader->ExemptUsage.QuadPart)
-            pHeader->ExemptUsage.QuadPart -= pUrlEntry->size.QuadPart;
-        else
-            pHeader->ExemptUsage.QuadPart = 0;
+        URLCache_DeleteEntry(pHeader, pEntry);
     }
     else
     {
-        if (pUrlEntry->size.QuadPart < pHeader->CacheUsage.QuadPart)
-            pHeader->CacheUsage.QuadPart -= pUrlEntry->size.QuadPart;
-        else
-            pHeader->CacheUsage.QuadPart = 0;
-    }
-
-    if (pUrlEntry->dwOffsetLocalName && URLCache_LocalFileNameToPathW(pContainer, pHeader,
-                (LPCSTR)pUrlEntry+pUrlEntry->dwOffsetLocalName, pUrlEntry->CacheDir, path, &path_size))
-    {
-        DeleteFileW(path);
+        /* Add entry to leaked files list */
+        pUrlEntry->CacheFileEntry.dwSignature = LEAK_SIGNATURE;
+        pUrlEntry->dwExemptDelta = pHeader->options[CACHE_HEADER_DATA_ROOT_LEAK_OFFSET];
+        pHeader->options[CACHE_HEADER_DATA_ROOT_LEAK_OFFSET] = pHashEntry->dwOffsetEntry;
     }
 
-    URLCache_DeleteEntry(pHeader, pEntry);
     URLCache_DeleteEntryFromHash(pHashEntry);
     return TRUE;
 }




More information about the wine-cvs mailing list