[PATCH 2/2] wininet: Add a new common module information struct

Morten Rønne morten.roenne at tdcadsl.dk
Mon Apr 16 15:03:16 CDT 2012


Add a new common module information struct for urlcache and functions to 
do initialization of the struct. This is intended to be a new way to 
more easily create Ansi and Unicode version of the functions, by doing a 
Ansi/Unicode preamble code that calls a common worker function that do 
the real work. Will also simplify parameter passing internal to the module.
Reimplement CommitUrlCacheEntryA/W with the new module struct.

Reimplementation of all functions will follow once this patch is accepted.

Best Regards
Morten Rønne
-------------- next part --------------
>From 757abe90fcb5411ab0ed608ccd23141f5a786768 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Morten=20R=C3=B8nne?= <morten.roenne at tdcadsl.dk>
Date: Wed, 11 Apr 2012 13:48:11 +0200
Subject: [PATCH 2/2] wininet: Add a new common module information struct for
 urlcache and functions to do initialization of the
 struct. This is intended to be a new way to more easily
 create Ansi and Unicode version of the functions, by
 doing a Ansi/Unicode preamble code that calls a common
 worker function that do the real work. Will also
 simplify parameter passing internal to the module.
 Reimplement CommitUrlCacheEntryA/W with the new module
 struct.

---
 dlls/wininet/urlcache.c |  669 ++++++++++++++++++++++++++++++++---------------
 1 files changed, 460 insertions(+), 209 deletions(-)

diff --git a/dlls/wininet/urlcache.c b/dlls/wininet/urlcache.c
index d4ad98f..84d760c 100644
--- a/dlls/wininet/urlcache.c
+++ b/dlls/wininet/urlcache.c
@@ -95,7 +95,7 @@ typedef struct _CACHEFILE_ENTRY
 /*      CHAR szSignature[4];
     };*/
     DWORD dwBlocksUsed; /* number of 128byte blocks used by this entry */
-} CACHEFILE_ENTRY;
+} CACHEFILE_ENTRY, *LPCACHEFILE_ENTRY;
 
 typedef struct _URL_CACHEFILE_ENTRY
 {
@@ -132,21 +132,21 @@ typedef struct _URL_CACHEFILE_ENTRY
     /* CHAR szLocalFileName[]; (local file name excluding path) */
     /* packing to dword align start of next field */
     /* CHAR szHeaderInfo[]; (header info) */
-} URL_CACHEFILE_ENTRY;
+} URL_CACHEFILE_ENTRY, *LPURL_CACHEFILE_ENTRY;
 
-struct _HASH_ENTRY
+typedef struct _HASH_ENTRY
 {
     DWORD dwHashKey;
     DWORD dwOffsetEntry;
-};
+} HASH_ENTRY, *LPHASH_ENTRY;
 
 typedef struct _HASH_CACHEFILE_ENTRY
 {
     CACHEFILE_ENTRY CacheFileEntry;
     DWORD dwAddressNext;
     DWORD dwHashTableNumber;
-    struct _HASH_ENTRY HashTable[HASHTABLE_SIZE];
-} HASH_CACHEFILE_ENTRY;
+    HASH_ENTRY HashTable[HASHTABLE_SIZE];
+} HASH_CACHEFILE_ENTRY, *LPHASH_CACHEFILE_ENTRY;
 
 typedef struct _DIRECTORY_DATA
 {
@@ -187,13 +187,56 @@ typedef struct _URLCACHECONTAINER
     HANDLE hMapping; /* handle of file mapping */
     DWORD file_size; /* size of file when mapping was opened */
     HANDLE hMutex; /* handle of mutex */
-} URLCACHECONTAINER;
+} URLCACHECONTAINER, *LPURLCACHECONTAINER;
 
+/*
+ *    URLCACHE_MODULE_INFO
+ *      This struct is used internally in this module to keep various
+ *      information together and to reuse converted version data elements
+ *      in Ansi (A) and Unicode (W) versions.
+ *      Flags is used to keep track of which strings are heap allocated.
+ */
+
+typedef struct _URLCACHE_MODULE_INFO
+{
+    DWORD                       Flags;
+    DWORD                       HeaderSize;
+    DWORD                       UrlHashValue;
+    LPURLCACHECONTAINER         pContainer;
+    LPURLCACHE_HEADER           pHeader;
+    LPCSTR                      pUrlA;
+    LPCWSTR                     pUrlW;
+    LPCSTR                      pExtensionA;
+    LPCWSTR                     pExtensionW;
+    LPBYTE                      pHeaderInfoA;
+    LPCSTR                      pOriginalUrlA;
+    LPCWSTR                     pOriginalUrlW;
+    LPCWSTR                     pFileNameW;
+    LPHASH_ENTRY                pHashEntry;
+    LPHASH_ENTRY                pFreeEntry;
+    LPHASH_CACHEFILE_ENTRY      pHashTable;
+    union {
+        LPCACHEFILE_ENTRY       pBase;
+        LPURL_CACHEFILE_ENTRY   pUrl;
+    } Entry;
+} URLCACHE_MODULE_INFO, *LPURLCACHE_MODULE_INFO;
+
+#define MODULE_INFO_URLA_HEAP         0x00000001
+#define MODULE_INFO_URLW_HEAP         0x00000002
+#define MODULE_INFO_EXTA_HEAP         0x00000004
+#define MODULE_INFO_EXTW_HEAP         0x00000008
+#define MODULE_INFO_ORGURLA_HEAP      0x00000010
+#define MODULE_INFO_ORGURLW_HEAP      0x00000020
+#define MODULE_INFO_FILENAMEW_HEAP    0x00000040
+#define MODULE_INFO_HEADERA_HEAP      0x00000080
+#define MODULE_INFO_HEAP_FLAGS        0x000000FF
 
 /* List of all containers available */
 static struct list UrlContainers = LIST_INIT(UrlContainers);
 
 static DWORD URLCache_CreateHashTable(LPURLCACHE_HEADER pHeader, HASH_CACHEFILE_ENTRY *pPrevHash, HASH_CACHEFILE_ENTRY **ppHash);
+static BOOL IsUrlCacheEntryExpiredInternal(const URL_CACHEFILE_ENTRY *pUrlEntry,
+    FILETIME *pftLastModified);
 
 /***********************************************************************
  *           URLCache_PathToObjectName (Internal)
@@ -788,6 +831,31 @@ static DWORD URLCacheContainer_CleanIndex(URLCACHECONTAINER *container, URLCACHE
 #endif
 
 /***********************************************************************
+ *           URLCache_FormatFileTimeDebug (Internal)
+ *
+ *  Format a FILETIME stamp for debug output
+ *  Sometime we need to output more than 1 stamp, so we have several
+ *  buffers to use.
+ */
+static const CHAR *URLCache_FormatFileTimeDebug(FILETIME ft, WORD index)
+{
+    static CHAR Buffer0[22];
+    static CHAR Buffer1[22];
+    CHAR *Buf;
+    SYSTEMTIME  sys;
+
+    if (index == 0) Buf = Buffer0;
+    else if (index == 1) Buf = Buffer1;
+    else return "";
+
+    FileTimeToSystemTime(&ft, &sys);
+    sprintf(Buf, "%d-%02d-%02d %02d:%02d:%02d",
+        sys.wYear, sys.wMonth, sys.wDay,
+        sys.wHour, sys.wMinute, sys.wSecond);
+    return Buf;
+}
+
+/***********************************************************************
  *           URLCache_Allocation_BlockIsFree (Internal)
  *
  *  Is the specified block number free?
@@ -1460,6 +1528,274 @@ static DWORD URLCache_CreateHashTable(LPURLCACHE_HEADER pHeader, HASH_CACHEFILE_
 }
 
 /***********************************************************************
+ *           URLCache_AcquireIndex (Internal)
+ *
+ *  Common code for AcquireIndexA/W
+ *
+ *  RETURNS
+ *    TRUE   If successful
+ *    FALSE  If failed, with LastError set.
+ */
+
+static BOOL URLCache_AcquireIndex(LPURLCACHE_MODULE_INFO pInfo, BOOL doFindHash)
+{
+    DWORD error;
+
+    if (!pInfo->pContainer)
+    {
+        error = URLCacheContainers_FindContainerW(pInfo->pUrlW, &pInfo->pContainer);
+        if (error != ERROR_SUCCESS)
+        {
+            SetLastError(error);
+            return FALSE;
+        }
+    }
+
+    if (!pInfo->pHeader)
+    {
+        error = URLCacheContainer_OpenIndex(pInfo->pContainer, MIN_BLOCK_NO);
+        if (error != ERROR_SUCCESS)
+        {
+            SetLastError(error);
+            return FALSE;
+        }
+
+        if (!(pInfo->pHeader = URLCacheContainer_LockIndex(pInfo->pContainer)))
+            return FALSE;
+    }
+
+    if (doFindHash)
+    {
+        URLCache_FindHash(pInfo->pHeader, pInfo->pUrlA, &pInfo->pHashEntry);
+        if (pInfo->pHashEntry)
+            pInfo->Entry.pBase = (LPCACHEFILE_ENTRY)((LPBYTE)pInfo->pHeader + pInfo->pHashEntry->dwOffsetEntry);
+    }
+
+    return TRUE;
+}
+
+/***********************************************************************
+ *           URLCache_AcquireIndexA (Internal)
+ *
+ *  Find, open and lock the cache for system-wide exclusive access.
+ *  Will update MODULE_INFO struct with values, if unset before this
+ *  function is called.
+ *
+ *  RETURNS
+ *    TRUE   If successful
+ *    FALSE  If failed, with LastError set.
+ */
+
+static BOOL URLCache_AcquireIndexA(LPCSTR Url, LPURLCACHE_MODULE_INFO pInfo, BOOL doFindHash)
+{
+    pInfo->pUrlA = Url;
+    pInfo->pUrlW = heap_strdupAtoW(Url);
+    pInfo->Flags = MODULE_INFO_URLW_HEAP;
+
+    return URLCache_AcquireIndex(pInfo, doFindHash);
+}
+
+/***********************************************************************
+ *           URLCache_AcquireIndexW (Internal)
+ *
+ *  Find, open and lock the cache for system-wide exclusive access.
+ *  Will update MODULE_INFO struct with values, if unset before this
+ *  function is called.
+ *
+ *  RETURNS
+ *    TRUE   If successful
+ *    FALSE  If failed, with LastError set.
+ */
+
+static BOOL URLCache_AcquireIndexW(LPCWSTR Url, LPURLCACHE_MODULE_INFO pInfo, BOOL doFindHash)
+{
+    pInfo->pUrlW = Url;
+    pInfo->pUrlA = heap_strdupWtoA(Url);
+    pInfo->Flags = MODULE_INFO_URLA_HEAP;
+
+    return URLCache_AcquireIndex(pInfo, doFindHash);
+}
+
+/***********************************************************************
+ *           URLCache_ReleaseIndex (Internal)
+ *
+ *  Frees all things allocated and unlocks the index.
+ *
+ *  RETURNS
+ *    NOTHING
+ */
+static void URLCache_ReleaseIndex(LPURLCACHE_MODULE_INFO pInfo)
+{
+    if (pInfo->Flags & MODULE_INFO_HEAP_FLAGS)
+    {
+        if (pInfo->Flags & MODULE_INFO_URLA_HEAP)
+            heap_free((LPVOID)pInfo->pUrlA);
+
+        if (pInfo->Flags & MODULE_INFO_URLW_HEAP)
+            heap_free((LPVOID)pInfo->pUrlW);
+
+        if (pInfo->Flags & MODULE_INFO_EXTA_HEAP)
+            heap_free((LPVOID)pInfo->pExtensionA);
+
+        if (pInfo->Flags & MODULE_INFO_EXTW_HEAP)
+            heap_free((LPVOID)pInfo->pExtensionW);
+
+        if (pInfo->Flags & MODULE_INFO_ORGURLA_HEAP)
+            heap_free((LPVOID)pInfo->pOriginalUrlA);
+
+        if (pInfo->Flags & MODULE_INFO_ORGURLW_HEAP)
+            heap_free((LPVOID)pInfo->pOriginalUrlW);
+
+        if (pInfo->Flags & MODULE_INFO_FILENAMEW_HEAP)
+            heap_free((LPVOID)pInfo->pFileNameW);
+
+        if (pInfo->Flags & MODULE_INFO_HEADERA_HEAP)
+            heap_free((LPVOID)pInfo->pHeaderInfoA);
+    }
+
+    if (pInfo->pHeader)
+        URLCacheContainer_UnlockIndex(pInfo->pContainer, pInfo->pHeader);
+
+    ZeroMemory(pInfo, sizeof(URLCACHE_MODULE_INFO));
+}
+
+/***********************************************************************
+ *           URLCache_ExtendedInfoA (Internal)
+ *
+ *   Fills out values in Information struct about extended data.
+ *
+ *   RETURNS:
+ *       TRUE   if all is well
+ *       FALSE  if not enough memory
+ *              LastError set to ERROR_OUTOFMEMORY
+ */
+
+static BOOL URLCache_ExtendedInfoA(
+    LPURLCACHE_MODULE_INFO pInfo,
+    LPCSTR lpszLocalFileName,
+    DWORD HeaderSize,
+    LPBYTE lpHeaderInfo,
+    LPCSTR lpszFileExtension,
+    LPCSTR lpszOriginalUrl
+)
+{
+    if (lpszLocalFileName)
+    {
+        pInfo->pFileNameW = heap_strdupAtoW(lpszLocalFileName);
+        if (!pInfo->pFileNameW)
+        {
+            SetLastError(ERROR_OUTOFMEMORY);
+            return FALSE;
+        }
+        pInfo->Flags |= MODULE_INFO_FILENAMEW_HEAP;
+    }
+
+    if (lpszFileExtension)
+    {
+        pInfo->pExtensionA = lpszFileExtension;
+        pInfo->pExtensionW = heap_strdupAtoW(lpszFileExtension);
+        if (!pInfo->pExtensionW)
+        {
+            SetLastError(ERROR_OUTOFMEMORY);
+            return FALSE;
+        }
+        pInfo->Flags |= MODULE_INFO_EXTW_HEAP;
+    }
+
+    if (lpszOriginalUrl)
+    {
+        pInfo->pOriginalUrlA = lpszOriginalUrl;
+        pInfo->pOriginalUrlW = heap_strdupAtoW(lpszOriginalUrl);
+        if (!pInfo->pOriginalUrlW)
+        {
+            SetLastError(ERROR_OUTOFMEMORY);
+            return FALSE;
+        }
+        pInfo->Flags |= MODULE_INFO_ORGURLW_HEAP;
+    }
+
+    pInfo->HeaderSize = HeaderSize;
+    pInfo->pHeaderInfoA = lpHeaderInfo;
+
+    return TRUE;
+}
+
+/***********************************************************************
+ *           URLCache_ExtendedInfoW (Internal)
+ *
+ *   Fills out values in Information struct about extended data.
+ *
+ *   RETURNS:
+ *       TRUE   if all is well
+ *       FALSE  if not enough memory
+ *              LastError set to ERROR_OUTOFMEMORY
+ */
+
+static BOOL URLCache_ExtendedInfoW(
+    LPURLCACHE_MODULE_INFO pInfo,
+    LPCWSTR lpszLocalFileName,
+    DWORD HeaderSize,
+    LPCWSTR lpHeaderInfo,
+    LPCWSTR lpszFileExtension,
+    LPCWSTR lpszOriginalUrl
+)
+{
+    if (lpszLocalFileName)
+    {
+        pInfo->pFileNameW = lpszLocalFileName;
+/*
+        pInfo->pAnsiFileName = heap_strdupWtoA(lpszLocalFileName);
+        if (!pInfo->pAnsiFileName)
+        {
+            SetLastError(ERROR_OUTOFMEMORY);
+            return FALSE;
+        }
+        pInfo->Flags |= MODULE_INFO_ANSI_FILE_HEAP;
+*/
+    }
+
+    if (lpszFileExtension)
+    {
+        pInfo->pExtensionW = lpszFileExtension;
+        pInfo->pExtensionA = heap_strdupWtoA(lpszFileExtension);
+        if (!pInfo->pExtensionA)
+        {
+            SetLastError(ERROR_OUTOFMEMORY);
+            return FALSE;
+        }
+        pInfo->Flags |= MODULE_INFO_EXTA_HEAP;
+    }
+
+    if (lpszOriginalUrl)
+    {
+        pInfo->pOriginalUrlW = lpszOriginalUrl;
+        pInfo->pOriginalUrlA = heap_strdupWtoA(lpszOriginalUrl);
+        if (!pInfo->pOriginalUrlA)
+        {
+            SetLastError(ERROR_OUTOFMEMORY);
+            return FALSE;
+        }
+        pInfo->Flags |= MODULE_INFO_ORGURLA_HEAP;
+    }
+
+    if (lpHeaderInfo)
+    {
+        DWORD size = WideCharToMultiByte(CP_ACP, 0, lpHeaderInfo, HeaderSize, NULL, 0, NULL, NULL);
+        pInfo->pHeaderInfoA = heap_alloc(size);
+        if (!pInfo->pHeaderInfoA)
+        {
+            SetLastError(ERROR_OUTOFMEMORY);
+            return FALSE;
+        }
+        WideCharToMultiByte(CP_ACP, 0, lpHeaderInfo, HeaderSize, (LPSTR)pInfo->pHeaderInfoA, size, NULL, NULL);
+        pInfo->Flags |= MODULE_INFO_HEADERA_HEAP;
+        pInfo->HeaderSize = size;
+    }
+
+    return TRUE;
+}
+
+/***********************************************************************
  *           URLCache_EnumHashTables (Internal)
  *
  *  Enumerates the hash tables in a container.
@@ -2629,143 +2965,100 @@ BOOL WINAPI CreateUrlCacheEntryW(
  *
  */
 static BOOL CommitUrlCacheEntryInternal(
-    IN LPCWSTR lpszUrlName,
-    IN LPCWSTR lpszLocalFileName,
-    IN FILETIME ExpireTime,
-    IN FILETIME LastModifiedTime,
-    IN DWORD CacheEntryType,
-    IN LPBYTE lpHeaderInfo,
-    IN DWORD dwHeaderSize,
-    IN LPCWSTR lpszFileExtension,
-    IN LPCWSTR lpszOriginalUrl
+    LPURLCACHE_MODULE_INFO pInfo,
+    FILETIME ExpireTime,
+    FILETIME LastModifiedTime,
+    DWORD CacheEntryType
     )
 {
-    URLCACHECONTAINER * pContainer;
-    LPURLCACHE_HEADER pHeader;
-    struct _HASH_ENTRY * pHashEntry;
     CACHEFILE_ENTRY * pEntry;
     URL_CACHEFILE_ENTRY * pUrlEntry;
     DWORD url_entry_offset;
-    DWORD dwBytesNeeded = DWORD_ALIGN(sizeof(*pUrlEntry));
+    DWORD dwSpaceNeeded = DWORD_ALIGN(sizeof(URLCACHE_HEADER));
     DWORD dwOffsetLocalFileName = 0;
     DWORD dwOffsetHeader = 0;
     DWORD dwOffsetFileExtension = 0;
     LARGE_INTEGER file_size;
     BYTE cDirectory = 0;
-    char achFile[MAX_PATH];
-    LPSTR lpszUrlNameA = NULL;
-    LPSTR lpszFileExtensionA = NULL;
-    char *pchLocalFileName = 0;
+    char achFile[MAX_PATH + 1];
+    char *pchLocalFileName = NULL;
+    LPCWSTR lpszLocalFileName = NULL;
     DWORD error;
 
-    TRACE("(%s, %s, ..., ..., %x, %p, %d, %s, %s)\n",
-        debugstr_w(lpszUrlName),
-        debugstr_w(lpszLocalFileName),
-        CacheEntryType,
-        lpHeaderInfo,
-        dwHeaderSize,
-        debugstr_w(lpszFileExtension),
-        debugstr_w(lpszOriginalUrl));
-
-    if (CacheEntryType & STICKY_CACHE_ENTRY && !lpszLocalFileName)
+    /* Verify: If commit a second time, CacheEntryType from input may be
+               ignored. So does this test apply to input or the used
+               value?
+    */
+    if (CacheEntryType & STICKY_CACHE_ENTRY && !pInfo->pFileNameW)
     {
         SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
-    if (lpszOriginalUrl)
-        WARN(": lpszOriginalUrl ignored\n");
+
+    if (pInfo->pOriginalUrlA)
+        WARN("OriginalUrl ignored\n");
+
+    if (pInfo->pHashEntry)
+    {
+        FILETIME last;
+
+        if (pInfo->Entry.pUrl->dwUseCount > 0 &&
+            !IsUrlCacheEntryExpiredInternal(pInfo->Entry.pUrl, &last))
+        {
+            SetLastError(ERROR_FILE_NOT_FOUND);
+            return FALSE;
+        }
+
+        FIXME("entry already in cache - don't know what to do!\n");
+        return TRUE;
+    }
 
     file_size.QuadPart = 0;
-    if (lpszLocalFileName)
+    if (pInfo->pFileNameW)
     {
+        BOOL bFound = FALSE;
         HANDLE hFile;
+        DWORD path_len;
 
-        hFile = CreateFileW(lpszLocalFileName, FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL);
+        lpszLocalFileName = pInfo->pFileNameW;
+        hFile = CreateFileW(lpszLocalFileName, FILE_READ_ATTRIBUTES,
+            FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
+            OPEN_EXISTING, 0, NULL);
         if (hFile == INVALID_HANDLE_VALUE)
         {
-            ERR("couldn't open file %s (error is %d)\n", debugstr_w(lpszLocalFileName), GetLastError());
+            ERR("couldn't open file %s (error is %d)\n",
+                debugstr_w(lpszLocalFileName), GetLastError());
             return FALSE;
         }
 
         /* Get file size */
         if (!GetFileSizeEx(hFile, &file_size))
         {
-            ERR("couldn't get file size (error is %d)\n", GetLastError());
+            ERR("couldn't get file size for %s (error is %d)\n",
+                debugstr_w(lpszLocalFileName), GetLastError());
             CloseHandle(hFile);
             return FALSE;
         }
 
         CloseHandle(hFile);
-    }
-
-    error = URLCacheContainers_FindContainerW(lpszUrlName, &pContainer);
-    if (error != ERROR_SUCCESS)
-    {
-        SetLastError(error);
-        return FALSE;
-    }
-
-    error = URLCacheContainer_OpenIndex(pContainer, MIN_BLOCK_NO);
-    if (error != ERROR_SUCCESS)
-    {
-        SetLastError(error);
-        return FALSE;
-    }
-
-    if (!(pHeader = URLCacheContainer_LockIndex(pContainer)))
-        return FALSE;
 
-    lpszUrlNameA = heap_strdupWtoA(lpszUrlName);
-    if (!lpszUrlNameA)
-    {
-        error = GetLastError();
-        goto cleanup;
-    }
-
-    if (lpszFileExtension && !(lpszFileExtensionA = heap_strdupWtoA(lpszFileExtension)))
-    {
-        error = GetLastError();
-        goto cleanup;
-    }
-
-    if (URLCache_FindHash(pHeader, lpszUrlNameA, &pHashEntry))
-    {
-        if ((pHashEntry->dwHashKey & ((1<<HASHTABLE_FLAG_BITS)-1)) == HASHTABLE_LOCK)
-        {
-            /* FIXME: implement timeout object unlocking */
-            FIXME("Trying to overwrite locked entry\n");
-            SetLastError(ERROR_SHARING_VIOLATION);
-            goto cleanup;
-        }
-
-        FIXME("entry already in cache - don't know what to do!\n");
-/*
- *        SetLastError(ERROR_FILE_NOT_FOUND);
- *        return FALSE;
- */
-        goto cleanup;
-    }
-
-    if (lpszLocalFileName)
-    {
-        BOOL bFound = FALSE;
-
-        if (strncmpW(lpszLocalFileName, pContainer->path, lstrlenW(pContainer->path)))
+        path_len = lstrlenW(pInfo->pContainer->path);
+        if (strncmpW(lpszLocalFileName, pInfo->pContainer->path, path_len))
         {
-            ERR("path %s must begin with cache content path %s\n", debugstr_w(lpszLocalFileName), debugstr_w(pContainer->path));
-            error = ERROR_INVALID_PARAMETER;
-            goto cleanup;
+            ERR("path %s must begin with cache content path %s\n", debugstr_w(lpszLocalFileName), debugstr_w(pInfo->pContainer->path));
+            SetLastError(ERROR_INVALID_PARAMETER);
+            return FALSE;
         }
 
         /* skip container path prefix */
-        lpszLocalFileName += lstrlenW(pContainer->path);
+        lpszLocalFileName += path_len;
 
         WideCharToMultiByte(CP_ACP, 0, lpszLocalFileName, -1, achFile, MAX_PATH, NULL, NULL);
 	pchLocalFileName = achFile;
 
-        for (cDirectory = 0; cDirectory < pHeader->DirectoryCount; cDirectory++)
+        for (cDirectory = 0; cDirectory < pInfo->pHeader->DirectoryCount; cDirectory++)
         {
-            if (!strncmp(pHeader->directory_data[cDirectory].filename, pchLocalFileName, DIR_LENGTH))
+            if (!strncmp(pInfo->pHeader->directory_data[cDirectory].filename, pchLocalFileName, DIR_LENGTH))
             {
                 bFound = TRUE;
                 break;
@@ -2775,55 +3068,59 @@ static BOOL CommitUrlCacheEntryInternal(
         if (!bFound)
         {
             ERR("cache directory not found in path %s\n", debugstr_w(lpszLocalFileName));
-            error = ERROR_INVALID_PARAMETER;
-            goto cleanup;
+            SetLastError(ERROR_INVALID_PARAMETER);
+            return FALSE;
         }
 
         lpszLocalFileName += DIR_LENGTH + 1;
         pchLocalFileName += DIR_LENGTH + 1;
     }
 
-    dwBytesNeeded = DWORD_ALIGN(dwBytesNeeded + strlen(lpszUrlNameA) + 1);
+    dwSpaceNeeded = DWORD_ALIGN(dwSpaceNeeded + strlen(pInfo->pUrlA) + 1);
     if (lpszLocalFileName)
     {
-        dwOffsetLocalFileName = dwBytesNeeded;
-        dwBytesNeeded = DWORD_ALIGN(dwBytesNeeded + strlen(pchLocalFileName) + 1);
+        dwOffsetLocalFileName = dwSpaceNeeded;
+        dwSpaceNeeded = DWORD_ALIGN(dwSpaceNeeded + strlen(pchLocalFileName) + 1);
     }
-    if (lpHeaderInfo)
+    if (pInfo->HeaderSize)
     {
-        dwOffsetHeader = dwBytesNeeded;
-        dwBytesNeeded = DWORD_ALIGN(dwBytesNeeded + dwHeaderSize);
+        dwOffsetHeader = dwSpaceNeeded;
+        dwSpaceNeeded = DWORD_ALIGN(dwSpaceNeeded + pInfo->HeaderSize);
     }
-    if (lpszFileExtensionA)
+    else if (pInfo->pHeaderInfoA)
     {
-        dwOffsetFileExtension = dwBytesNeeded;
-        dwBytesNeeded = DWORD_ALIGN(dwBytesNeeded + strlen(lpszFileExtensionA) + 1);
+        SetLastError(ERROR_OUTOFMEMORY);
+        return FALSE;
     }
-
-    /* round up to next block */
-    if (dwBytesNeeded % BLOCKSIZE)
+    if (pInfo->pExtensionA)
     {
-        dwBytesNeeded -= dwBytesNeeded % BLOCKSIZE;
-        dwBytesNeeded += BLOCKSIZE;
+        dwOffsetFileExtension = dwSpaceNeeded;
+        dwSpaceNeeded = DWORD_ALIGN(dwSpaceNeeded + strlen(pInfo->pExtensionA) + 1);
     }
 
-    error = URLCache_FindFirstFreeEntry(pHeader, dwBytesNeeded / BLOCKSIZE, &pEntry);
+    /* Convert to blocks needed */
+    dwSpaceNeeded = (dwSpaceNeeded + BLOCKSIZE - 1) / BLOCKSIZE;
+
+    error = URLCache_FindFirstFreeEntry(pInfo->pHeader, dwSpaceNeeded, &pEntry);
     while (error == ERROR_HANDLE_DISK_FULL)
     {
-        error = URLCacheContainer_CleanIndex(pContainer, &pHeader);
+        error = URLCacheContainer_CleanIndex(pInfo->pContainer, &pInfo->pHeader);
         if (error == ERROR_SUCCESS)
-            error = URLCache_FindFirstFreeEntry(pHeader, dwBytesNeeded / BLOCKSIZE, &pEntry);
+            error = URLCache_FindFirstFreeEntry(pInfo->pHeader, dwSpaceNeeded, &pEntry);
     }
     if (error != ERROR_SUCCESS)
-        goto cleanup;
+    {
+        SetLastError(error);
+        return FALSE;
+    }
 
     /* FindFirstFreeEntry fills in blocks used */
     pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry;
-    url_entry_offset = (LPBYTE)pUrlEntry - (LPBYTE)pHeader;
+    url_entry_offset = (LPBYTE)pUrlEntry - (LPBYTE)(pInfo->pHeader);
     pUrlEntry->CacheFileEntry.dwSignature = URL_SIGNATURE;
     pUrlEntry->CacheDir = cDirectory;
     pUrlEntry->CacheEntryType = CacheEntryType;
-    pUrlEntry->dwHeaderInfoSize = dwHeaderSize;
+    pUrlEntry->dwHeaderInfoSize = pInfo->HeaderSize;
     if (CacheEntryType & STICKY_CACHE_ENTRY)
     {
         /* Sticky entries have a default exempt time of one day */
@@ -2855,52 +3152,45 @@ static BOOL CommitUrlCacheEntryInternal(
     pUrlEntry->dwUnknown8 = 0;
 
 
-    strcpy((LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, lpszUrlNameA);
+    strcpy((LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl, pInfo->pUrlA);
     if (dwOffsetLocalFileName)
         strcpy((LPSTR)((LPBYTE)pUrlEntry + dwOffsetLocalFileName), pchLocalFileName);
     if (dwOffsetHeader)
-        memcpy((LPBYTE)pUrlEntry + dwOffsetHeader, lpHeaderInfo, dwHeaderSize);
+        memcpy((LPBYTE)pUrlEntry + dwOffsetHeader, pInfo->pHeaderInfoA, pInfo->HeaderSize);
     if (dwOffsetFileExtension)
-        strcpy((LPSTR)((LPBYTE)pUrlEntry + dwOffsetFileExtension), lpszFileExtensionA);
+        strcpy((LPSTR)((LPBYTE)pUrlEntry + dwOffsetFileExtension), pInfo->pExtensionA);
 
-    error = URLCache_AddEntryToHash(pHeader, lpszUrlNameA, url_entry_offset, HASHTABLE_URL);
+    error = URLCache_AddEntryToHash(pInfo->pHeader, pInfo->pUrlA, url_entry_offset, HASHTABLE_URL);
     while (error == ERROR_HANDLE_DISK_FULL)
     {
-        error = URLCacheContainer_CleanIndex(pContainer, &pHeader);
+        error = URLCacheContainer_CleanIndex(pInfo->pContainer, &(pInfo->pHeader));
         if (error == ERROR_SUCCESS)
         {
-            pUrlEntry = (URL_CACHEFILE_ENTRY *)((LPBYTE)pHeader + url_entry_offset);
-            error = URLCache_AddEntryToHash(pHeader, lpszUrlNameA,
+            error = URLCache_AddEntryToHash(pInfo->pHeader, pInfo->pUrlA,
                     url_entry_offset, HASHTABLE_URL);
         }
     }
+    pUrlEntry = (URL_CACHEFILE_ENTRY *)((LPBYTE)(pInfo->pHeader) + url_entry_offset);
     if (error != ERROR_SUCCESS)
-        URLCache_DeleteEntry(pHeader, &pUrlEntry->CacheFileEntry);
-    else
     {
-        if (pUrlEntry->CacheDir < pHeader->DirectoryCount)
-            pHeader->directory_data[pUrlEntry->CacheDir].dwNumFiles++;
-        if (CacheEntryType & STICKY_CACHE_ENTRY)
-            pHeader->ExemptUsage.QuadPart += file_size.QuadPart;
-        else
-            pHeader->CacheUsage.QuadPart += file_size.QuadPart;
-        if (pHeader->CacheUsage.QuadPart + pHeader->ExemptUsage.QuadPart >
-            pHeader->CacheLimit.QuadPart)
-            FIXME("file of size %s bytes fills cache\n", wine_dbgstr_longlong(file_size.QuadPart));
+        URLCache_DeleteEntry(pInfo->pHeader, &pUrlEntry->CacheFileEntry);
+        SetLastError(error);
+        return FALSE;
     }
 
-cleanup:
-    URLCacheContainer_UnlockIndex(pContainer, pHeader);
-    heap_free(lpszUrlNameA);
-    heap_free(lpszFileExtensionA);
+    if (pUrlEntry->CacheDir < pInfo->pHeader->DirectoryCount)
+        pInfo->pHeader->directory_data[pUrlEntry->CacheDir].dwNumFiles++;
 
-    if (error == ERROR_SUCCESS)
-        return TRUE;
+    if (CacheEntryType & STICKY_CACHE_ENTRY)
+        pInfo->pHeader->ExemptUsage.QuadPart += file_size.QuadPart;
     else
-    {
-        SetLastError(error);
-        return FALSE;
-    }
+        pInfo->pHeader->CacheUsage.QuadPart += file_size.QuadPart;
+
+    if (pInfo->pHeader->CacheUsage.QuadPart + pInfo->pHeader->ExemptUsage.QuadPart >
+        pInfo->pHeader->CacheLimit.QuadPart)
+        FIXME("file of size %s bytes fills cache\n", wine_dbgstr_longlong(file_size.QuadPart));
+
+    return TRUE;
 }
 
 /***********************************************************************
@@ -2919,53 +3209,26 @@ BOOL WINAPI CommitUrlCacheEntryA(
     IN LPCSTR lpszOriginalUrl
     )
 {
-    WCHAR *url_name = NULL;
-    WCHAR *local_file_name = NULL;
-    WCHAR *original_url = NULL;
-    WCHAR *file_extension = NULL;
     BOOL bSuccess = FALSE;
+    URLCACHE_MODULE_INFO  Info;
 
-    TRACE("(%s, %s, ..., ..., %x, %p, %d, %s, %s)\n",
+    TRACE("(%s, %s, %s, %s, %x, %p, %d, %s, %s)\n",
         debugstr_a(lpszUrlName),
         debugstr_a(lpszLocalFileName),
+        URLCache_FormatFileTimeDebug(ExpireTime, 0),
+        URLCache_FormatFileTimeDebug(LastModifiedTime, 1),
         CacheEntryType,
         lpHeaderInfo,
         dwHeaderSize,
         debugstr_a(lpszFileExtension),
         debugstr_a(lpszOriginalUrl));
 
-    url_name = heap_strdupAtoW(lpszUrlName);
-    if (!url_name)
-        goto cleanup;
-
-    if (lpszLocalFileName)
-    {
-        local_file_name = heap_strdupAtoW(lpszLocalFileName);
-        if (!local_file_name)
-            goto cleanup;
-    }
-    if (lpszFileExtension)
-    {
-        file_extension = heap_strdupAtoW(lpszFileExtension);
-        if (!file_extension)
-            goto cleanup;
-    }
-    if (lpszOriginalUrl)
-    {
-        original_url = heap_strdupAtoW(lpszOriginalUrl);
-        if (!original_url)
-            goto cleanup;
-    }
-
-    bSuccess = CommitUrlCacheEntryInternal(url_name, local_file_name, ExpireTime, LastModifiedTime,
-                                           CacheEntryType, lpHeaderInfo, dwHeaderSize,
-                                           file_extension, original_url);
-
-cleanup:
-    heap_free(original_url);
-    heap_free(file_extension);
-    heap_free(local_file_name);
-    heap_free(url_name);
+    ZeroMemory(&Info, sizeof(Info));
+    if (URLCache_AcquireIndexA(lpszUrlName, &Info, TRUE) &&
+        URLCache_ExtendedInfoA(&Info, lpszLocalFileName, dwHeaderSize,
+            lpHeaderInfo, lpszFileExtension, lpszOriginalUrl))
+        bSuccess = CommitUrlCacheEntryInternal(&Info, ExpireTime, LastModifiedTime, CacheEntryType);
+    URLCache_ReleaseIndex(&Info);
     return bSuccess;
 }
 
@@ -2985,38 +3248,26 @@ BOOL WINAPI CommitUrlCacheEntryW(
     IN LPCWSTR lpszOriginalUrl
     )
 {
-    DWORD dwError = 0;
     BOOL bSuccess = FALSE;
-    DWORD len = 0;
-    CHAR *header_info = NULL;
+    URLCACHE_MODULE_INFO  Info;
 
-    TRACE("(%s, %s, ..., ..., %x, %p, %d, %s, %s)\n",
+    TRACE("(%s, %s, %s, %s, %x, %p, %d, %s, %s)\n",
         debugstr_w(lpszUrlName),
         debugstr_w(lpszLocalFileName),
+        URLCache_FormatFileTimeDebug(ExpireTime, 0),
+        URLCache_FormatFileTimeDebug(LastModifiedTime, 1),
         CacheEntryType,
         lpHeaderInfo,
         dwHeaderSize,
         debugstr_w(lpszFileExtension),
         debugstr_w(lpszOriginalUrl));
 
-    if (!lpHeaderInfo || (header_info = heap_strdupWtoA(lpHeaderInfo)))
-    {
-	if (CommitUrlCacheEntryInternal(lpszUrlName, lpszLocalFileName, ExpireTime, LastModifiedTime,
-				CacheEntryType, (LPBYTE)header_info, len, lpszFileExtension, lpszOriginalUrl))
-	{
-		bSuccess = TRUE;
-	}
-	else
-	{
-		dwError = GetLastError();
-	}
-	if (header_info)
-	{
-	    heap_free(header_info);
-	    if (!bSuccess)
-		SetLastError(dwError);
-	}
-    }
+    ZeroMemory(&Info, sizeof(Info));
+    if (URLCache_AcquireIndexW(lpszUrlName, &Info, TRUE) &&
+        URLCache_ExtendedInfoW(&Info, lpszLocalFileName, dwHeaderSize,
+            lpHeaderInfo, lpszFileExtension, lpszOriginalUrl))
+        bSuccess = CommitUrlCacheEntryInternal(&Info, ExpireTime, LastModifiedTime, CacheEntryType);
+    URLCache_ReleaseIndex(&Info);
     return bSuccess;
 }
 
-- 
1.7.5.4



More information about the wine-patches mailing list