[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