[1/2] wininet: Partially implement FreeUrlCacheSpaceW.

Alexander Scott-Johns alexander.scott.johns at googlemail.com
Sun Mar 6 19:32:16 CST 2011


To help fix http://bugs.winehq.org/show_bug.cgi?id=23876
-------------- next part --------------
From d9c73fab745ea95bcd4c77bc659f139ca10866ad Mon Sep 17 00:00:00 2001
From: Alexander Scott-Johns <alexander.scott.johns at googlemail.com>
Date: Wed, 2 Mar 2011 18:35:27 +0000
Subject: wininet: Partially implement FreeUrlCacheSpaceW.

---
 dlls/wininet/resource.h |    2 +
 dlls/wininet/urlcache.c |  131 ++++++++++++++++++++++++++++++++++++++++++----
 dlls/wininet/wininet.rc |    2 +
 include/wininet.h       |   10 ++++
 4 files changed, 133 insertions(+), 12 deletions(-)

diff --git a/dlls/wininet/resource.h b/dlls/wininet/resource.h
index 256a374..e7f61a2 100644
--- a/dlls/wininet/resource.h
+++ b/dlls/wininet/resource.h
@@ -38,3 +38,5 @@
 #define IDS_CERT_DATE_INVALID 0x502
 #define IDS_CERT_CN_INVALID   0x503
 #define IDS_CERT_ERRORS       0x504
+#define IDS_CACHE_IN_USE      0x505
+#define IDS_WARNING           0x506
diff --git a/dlls/wininet/urlcache.c b/dlls/wininet/urlcache.c
index 40e4840..be2102b 100644
--- a/dlls/wininet/urlcache.c
+++ b/dlls/wininet/urlcache.c
@@ -48,10 +48,13 @@
 #include "wininet.h"
 #include "winineti.h"
 #include "winerror.h"
-#include "internet.h"
 #include "winreg.h"
 #include "shlwapi.h"
 #include "shlobj.h"
+#include "shellapi.h"
+
+#include "internet.h"
+#include "resource.h"
 
 #include "wine/unicode.h"
 #include "wine/debug.h"
@@ -208,6 +211,8 @@ static void URLCache_PathToObjectName(LPWSTR lpszPath, WCHAR replace)
     }
 }
 
+static const WCHAR wszIndex[] = {'i','n','d','e','x','.','d','a','t',0};
+
 /***********************************************************************
  *           URLCacheContainer_OpenIndex (Internal)
  *
@@ -223,8 +228,6 @@ static DWORD URLCacheContainer_OpenIndex(URLCACHECONTAINER * pContainer)
     HANDLE hFile;
     WCHAR wszFilePath[MAX_PATH];
     DWORD dwFileSize;
-
-    static const WCHAR wszIndex[] = {'i','n','d','e','x','.','d','a','t',0};
     static const WCHAR wszMappingFormat[] = {'%','s','%','s','_','%','l','u',0};
 
     if (pContainer->hMapping)
@@ -1449,28 +1452,132 @@ static BOOL URLCache_EnumHashTableEntries(LPCURLCACHE_HEADER pHeader, const HASH
 }
 
 /***********************************************************************
- *           FreeUrlCacheSpaceA (WININET.@)
+ *           URLCache_DeleteCacheDirectory (Internal)
+ *
+ *  Erase a directory containing an URL cache.
+ *
+ * RETURNS
+ *    TRUE success, FALSE failure/aborted.
  *
  */
-BOOL WINAPI FreeUrlCacheSpaceA(LPCSTR lpszCachePath, DWORD dwSize, DWORD dwFilter)
+static BOOL URLCache_DeleteCacheDirectory(LPCWSTR lpszPath)
 {
-    FIXME("stub!\n");
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    DWORD path_len;
+    WCHAR path[MAX_PATH + 1];
+    HANDLE file;
+    WCHAR message[128];
+    SHFILEOPSTRUCTW shfos;
+    int ret;
+
+    /* get path to Content.IE5 directory */
+    path_len = strlenW(lpszPath);
+    if (path_len + (sizeof(wszIndex)/sizeof(*wszIndex)) >= MAX_PATH)
+        return FALSE;
+    strcpyW(path, lpszPath);
+
+    /* check if Content.IE5\index.dat file isn't locked by another process */
+    strcatW(path + path_len, wszIndex);
+    file = CreateFileW(path, DELETE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    if (file == INVALID_HANDLE_VALUE)
+    {
+        if (GetLastError() == ERROR_SHARING_VIOLATION)
+        {
+            WCHAR title[128];
+            LoadStringW(WININET_hModule, IDS_CACHE_IN_USE, message, sizeof(message)/sizeof(*message));
+            LoadStringW(WININET_hModule, IDS_WARNING, title, sizeof(title)/sizeof(*title));
+            MessageBoxW(NULL, message, title, MB_OK);
+        }
+    }
+    else
+        CloseHandle(file);
+
+    /* double-NUL-terminate path to Content.IE5 directory */
+    path[path_len]     = 0;
+    path[path_len + 1] = 0;
+
+    /* recursively delete Content.IE5 directory */
+    shfos.hwnd = NULL;
+    shfos.wFunc = FO_DELETE;
+    shfos.pFrom = path;
+    shfos.pTo = NULL;
+    shfos.fFlags = 0;
+    shfos.fAnyOperationsAborted = FALSE;
+    ret = SHFileOperationW(&shfos);
+    if (ret && ret != ERROR_PATH_NOT_FOUND)  /* get this instead of ERROR_SHARING_VIOLATION */
+    {
+        FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, ret, 0, message,
+                         sizeof(message)/sizeof(*message), NULL);
+        MessageBoxW(NULL, message, NULL, MB_OK);
+    }
+    return !(ret || shfos.fAnyOperationsAborted);
 }
 
- /***********************************************************************
+/***********************************************************************
  *           FreeUrlCacheSpaceW (WININET.@)
  *
+ * Frees up some cache.
+ *
+ * PARAMETERS
+ *   lpszCachePath [I] Which volume to free up from, or NULL if you don't care.
+ *   dwSize        [I] How much space to free up.
+ *   dwSizeType    [I] How to interpret dwSize.
+ *
+ * RETURNS
+ *   TRUE success. FALSE failure.
+ *
+ * IMPLEMENTATION
+ *   This implementation just retrieves the path of the cache directory, and
+ *   deletes its contents from the filesystem. The correct approach would
+ *   probably be to implement and use {FindFirst,FindNext,Delete}UrlCacheGroup().
  */
-BOOL WINAPI FreeUrlCacheSpaceW(LPCWSTR lpszCachePath, DWORD dwSize, DWORD dwFilter)
+BOOL WINAPI FreeUrlCacheSpaceW(LPCWSTR lpszCachePath, DWORD dwSize, DWORD dwSizeType)
 {
-    FIXME("stub!\n");
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    URLCACHECONTAINER * pContainer;
+
+    if (lpszCachePath != NULL || dwSize != 100 || dwSizeType != FCS_PERCENT_CACHE_SPACE)
+    {
+        FIXME("(%s, %x, %x): partial stub!\n", debugstr_w(lpszCachePath), dwSize, dwSizeType);
+        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+        return FALSE;
+    }
+
+    LIST_FOR_EACH_ENTRY(pContainer, &UrlContainers, URLCACHECONTAINER, entry)
+    {
+        /* The URL cache has prefix L"" (unlike Cookies and History) */
+        if (pContainer->cache_prefix[0] == 0)
+        {
+            BOOL ret_del;
+            DWORD ret_open;
+            WaitForSingleObject(pContainer->hMutex, INFINITE);
+
+            /* unlock, delete, recreate and lock cache */
+            URLCacheContainer_CloseIndex(pContainer);
+            ret_del = URLCache_DeleteCacheDirectory(pContainer->path);
+            ret_open = URLCacheContainer_OpenIndex(pContainer);
+
+            ReleaseMutex(pContainer->hMutex);
+            return ret_del && (ret_open == ERROR_SUCCESS);
+        }
+    }
     return FALSE;
 }
 
 /***********************************************************************
+ *           FreeUrlCacheSpaceA (WININET.@)
+ *
+ * See FreeUrlCacheSpaceW.
+ */
+BOOL WINAPI FreeUrlCacheSpaceA(LPCSTR lpszCachePath, DWORD dwSize, DWORD dwSizeType)
+{
+    BOOL ret = FALSE;
+    LPWSTR path = heap_strdupAtoW(lpszCachePath);
+    if (lpszCachePath == NULL || path != NULL)
+        ret = FreeUrlCacheSpaceW(path, dwSize, dwSizeType);
+    heap_free(path);
+    return ret;
+}
+
+/***********************************************************************
  *           GetUrlCacheEntryInfoExA (WININET.@)
  *
  */
diff --git a/dlls/wininet/wininet.rc b/dlls/wininet/wininet.rc
index 8ef32e1..e2edd02 100644
--- a/dlls/wininet/wininet.rc
+++ b/dlls/wininet/wininet.rc
@@ -27,6 +27,8 @@ STRINGTABLE
   IDS_CERT_DATE_INVALID "The date on the certificate is invalid."
   IDS_CERT_CN_INVALID   "The name on the certificate does not match the site."
   IDS_CERT_ERRORS       "There is at least one unspecified security problem with this certificate."
+  IDS_CACHE_IN_USE  "The cache is currently in use: some files may be left over after deletion."
+  IDS_WARNING       "Warning"
 }
 
 #define WINE_FILEDESCRIPTION_STR "Wine Internet Connectivity"
diff --git a/include/wininet.h b/include/wininet.h
index 0cf453e..ce09821 100644
--- a/include/wininet.h
+++ b/include/wininet.h
@@ -1660,6 +1660,16 @@ BOOLAPI DeleteUrlCacheEntryA(LPCSTR);
 BOOLAPI DeleteUrlCacheEntryW(LPCWSTR);
 #define DeleteUrlCacheEntry  WINELIB_NAME_AW(DeleteUrlCacheEntry)
 
+/* FCS_ flags and FreeUrlCacheSpace are no longer documented */
+#define FCS_PERCENT_CACHE_SPACE  0  /* guessed value */
+#define FCS_PERCENT_DISK_SPACE   1  /* guessed value */
+#define FCS_ABSOLUTE_SIZE        2  /* guessed value */
+
+BOOLAPI FreeUrlCacheSpaceA(LPCSTR ,DWORD ,DWORD);
+BOOLAPI FreeUrlCacheSpaceW(LPCWSTR ,DWORD ,DWORD);
+#define FreeUrlCacheSpace  WINELIB_NAME_AW(FreeUrlCacheSpace)
+
+
 INTERNETAPI DWORD WINAPI InternetDialA(HWND ,LPSTR ,DWORD ,DWORD_PTR* ,DWORD);
 INTERNETAPI DWORD WINAPI InternetDialW(HWND ,LPWSTR ,DWORD ,DWORD_PTR* ,DWORD);
 #define InternetDial WINELIB_NAME_AW(InternetDial)
-- 
1.7.0.4


More information about the wine-patches mailing list