Implemented CreateUrlCacheEntryW and DeleteUrlCacheEntryW

Robert Shearman rob at codeweavers.com
Thu Dec 23 13:55:36 CST 2004


Jacek Caban wrote:

> Changelog:
>    Implemented CreateUrlCacheEntryW and DeleteUrlCacheEntryW
>
>------------------------------------------------------------------------
>
>Index: dlls/wininet/urlcache.c
>===================================================================
>RCS file: /home/wine/wine/dlls/wininet/urlcache.c,v
>retrieving revision 1.22
>diff -u -p -r1.22 urlcache.c
>--- dlls/wininet/urlcache.c	3 Sep 2004 18:30:28 -0000	1.22
>+++ dlls/wininet/urlcache.c	23 Dec 2004 11:08:39 -0000
>@@ -616,14 +616,14 @@ static BOOL URLCache_DeleteEntry(CACHEFI
> static BOOL URLCache_LocalFileNameToPathW(
>     const URLCACHECONTAINER * pContainer,
>     LPCURLCACHE_HEADER pHeader,
>-    LPCSTR szLocalFileName,
>+    LPCWSTR szLocalFileName,
>     BYTE Directory,
>     LPWSTR wszPath,
>     LPLONG lpBufferSize)
> {
>     LONG nRequired;
>     int path_len = strlenW(pContainer->path);
>-    int file_name_len = MultiByteToWideChar(CP_ACP, 0, szLocalFileName, -1, NULL, 0);
>+    int file_name_len = lstrlenW(szLocalFileName);
>  
>

MultiByteWideChar returns the number of characters, including the NULL 
terminator. lstrlenW does not. Also, since the local file name can only 
ever be stored in ANSI, there is very little benefit in converting that 
function to Unicode. In fact, there is very little benefit in making the 
ANSI API functions convert everything to Unicode strings, only for them 
to be immediately converted back to ANSI for storage on disk.

>     if (Directory >= pHeader->DirectoryCount)
>     {
>         *lpBufferSize = 0;
>@@ -638,7 +638,7 @@ static BOOL URLCache_LocalFileNameToPath
>         memcpy(wszPath, pContainer->path, path_len * sizeof(WCHAR));
>         dir_len = MultiByteToWideChar(CP_ACP, 0, pHeader->directory_data[Directory].filename, DIR_LENGTH, wszPath + path_len, DIR_LENGTH);
>         wszPath[dir_len + path_len] = '\\';
>-        MultiByteToWideChar(CP_ACP, 0, szLocalFileName, -1, wszPath + dir_len + path_len + 1, file_name_len);
>+        memcpy(wszPath + dir_len + path_len + 1, szLocalFileName, file_name_len*sizeof(WCHAR));
>         *lpBufferSize = nRequired;
>         return TRUE;
>     }
>@@ -762,9 +762,18 @@ static BOOL URLCache_CopyEntry(
>         LPSTR lpszLocalFileName;
>         lpszLocalFileName = (LPSTR)lpCacheEntryInfo + dwRequiredSize;
>         nLocalFilePathSize = *lpdwBufferSize - dwRequiredSize;
>-        if ((bUnicode && URLCache_LocalFileNameToPathW(pContainer, pHeader, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetLocalName, pUrlEntry->CacheDir, (LPWSTR)lpszLocalFileName, &nLocalFilePathSize)) ||
>-            URLCache_LocalFileNameToPathA(pContainer, pHeader, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetLocalName, pUrlEntry->CacheDir, lpszLocalFileName, &nLocalFilePathSize))
>-        {
>+        if (bUnicode) {
>+            LPWSTR tmpstrw;
>+            int len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetLocalName, -1, NULL, 0);
>+            tmpstrw = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
>+            MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetLocalName, -1, tmpstrw, len);
>+            if(URLCache_LocalFileNameToPathW(pContainer, pHeader, tmpstrw, pUrlEntry->CacheDir,
>+                                            (LPWSTR)lpszLocalFileName, &nLocalFilePathSize)) {
>+                lpCacheEntryInfo->lpszLocalFileName = lpszLocalFileName;
>+            }
>+            HeapFree(GetProcessHeap(), 0, tmpstrw);
>+        }else if(URLCache_LocalFileNameToPathA(pContainer, pHeader, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetLocalName,
>+                                               pUrlEntry->CacheDir, lpszLocalFileName, &nLocalFilePathSize)) {
>             lpCacheEntryInfo->lpszLocalFileName = lpszLocalFileName;
>         }
>         dwRequiredSize += nLocalFilePathSize;
>@@ -1550,36 +1559,38 @@ BOOL WINAPI UnlockUrlCacheEntryFileA(
> }
> 
> /***********************************************************************
>- *           CreateUrlCacheEntryA (WININET.@)
>+ *           CreateUrlCacheEntryW (WININET.@)
>  *
>  */
>-BOOL WINAPI CreateUrlCacheEntryA(
>-    IN LPCSTR lpszUrlName,
>+BOOL WINAPI CreateUrlCacheEntryW(
>+    IN LPCWSTR lpszUrlName,
>     IN DWORD dwExpectedFileSize,
>-    IN LPCSTR lpszFileExtension,
>-    OUT LPSTR lpszFileName,
>+    IN LPCWSTR lpszFileExtension,
>+    OUT LPWSTR lpszFileName,
>     IN DWORD dwReserved
> )
> {
>     URLCACHECONTAINER * pContainer;
>     LPURLCACHE_HEADER pHeader;
>-    CHAR szFile[MAX_PATH];
>-    CHAR szExtension[MAX_PATH];
>-    LPCSTR lpszUrlPart;
>-    LPCSTR lpszUrlEnd;
>-    LPCSTR lpszFileNameExtension;
>-    LPSTR lpszFileNameNoPath;
>+    WCHAR szFile[MAX_PATH];
>+    WCHAR szExtension[MAX_PATH];
>+    LPCWSTR lpszUrlPart;
>+    LPCWSTR lpszUrlEnd;
>+    LPCWSTR lpszFileNameExtension;
>+    LPWSTR lpszFileNameNoPath;
>     int i;
>     int countnoextension;
>     BYTE CacheDir;
>     LONG lBufferSize;
>     BOOL bFound = FALSE;
>     int count;
>+    static const WCHAR strWWW[] = {'w','w','w',0};
>+    static const WCHAR strFormat[] = {'[','%','u',']','%','s',0};
>  
>

No need to pollute an already congested function header with something 
that can be put into the appropriate block below. Also, "wsz" is the 
prefix usually used for Wide Character string constants.

> 
>     TRACE("(%s, 0x%08lx, %s, %p, 0x%08lx)\n",
>-        debugstr_a(lpszUrlName),
>+        debugstr_w(lpszUrlName),
>         dwExpectedFileSize,
>-        debugstr_a(lpszFileExtension),
>+        debugstr_w(lpszFileExtension),
>         lpszFileName,
>         dwReserved);
> 
>@@ -1607,16 +1618,14 @@ BOOL WINAPI CreateUrlCacheEntryA(
>             break;
>         }
>     }
>-    if (!strcmp(lpszUrlPart, "www"))
>-    {
>-        lpszUrlPart += strlen("www");
>-    }
>+    if (!lstrcmpW(lpszUrlPart, strWWW))
>+        lpszUrlPart += sizeof(strWWW)/sizeof(WCHAR) -1;
> 
>     count = lpszUrlEnd - lpszUrlPart;
> 
>     if (bFound && (count < MAX_PATH))
>     {
>-        memcpy(szFile, lpszUrlPart, count * sizeof(CHAR));
>+        memcpy(szFile, lpszUrlPart, count * sizeof(WCHAR));
>         szFile[count] = '\0';
>         /* FIXME: get rid of illegal characters like \, / and : */
>     }
>@@ -1625,9 +1634,9 @@ BOOL WINAPI CreateUrlCacheEntryA(
>         FIXME("need to generate a random filename\n");
>     }
> 
>-    TRACE("File name: %s\n", szFile);
>+    TRACE("File name: %s\n", debugstr_w(szFile));
> 
>-    if (!URLCacheContainers_FindContainerA(lpszUrlName, &pContainer))
>+    if (!URLCacheContainers_FindContainerW(lpszUrlName, &pContainer))
>         return FALSE;
> 
>     if (!URLCacheContainer_OpenIndex(pContainer))
>@@ -1638,32 +1647,33 @@ BOOL WINAPI CreateUrlCacheEntryA(
> 
>     CacheDir = (BYTE)(rand() % pHeader->DirectoryCount);
> 
>-    lBufferSize = MAX_PATH * sizeof(CHAR);
>-    URLCache_LocalFileNameToPathA(pContainer, pHeader, szFile, CacheDir, lpszFileName, &lBufferSize);
>+    lBufferSize = MAX_PATH * sizeof(WCHAR);
>+    URLCache_LocalFileNameToPathW(pContainer, pHeader, szFile, CacheDir, lpszFileName, &lBufferSize);
> 
>     URLCacheContainer_UnlockIndex(pContainer, pHeader);
> 
>-    lpszFileNameNoPath = lpszFileName + lBufferSize / sizeof(CHAR) + DIR_LENGTH + 1;
>+    lpszFileNameNoPath = lpszFileName + lBufferSize / sizeof(WCHAR) + DIR_LENGTH + 1;
> 
>-    countnoextension = strlen(lpszFileNameNoPath);
>-    lpszFileNameExtension = PathFindExtensionA(lpszFileNameNoPath);
>+    countnoextension = lstrlenW(lpszFileNameNoPath);
>+    lpszFileNameExtension = PathFindExtensionW(lpszFileNameNoPath);
>     if (lpszFileNameExtension)
>-        countnoextension -= strlen(lpszFileNameExtension);
>+        countnoextension -= lstrlenW(lpszFileNameExtension);
>     *szExtension = '\0';
> 
>     if (lpszFileExtension)
>     {
>         szExtension[0] = '.';
>-        strcpy(szExtension+1, lpszFileExtension);
>+        lstrcpyW(szExtension+1, lpszFileExtension);
>     }
> 
>     for (i = 0; i < 255; i++)
>     {
>         HANDLE hFile;
>-        strncpy(lpszFileNameNoPath, szFile, countnoextension);
>-        sprintf(lpszFileNameNoPath + countnoextension, "[%u]%s", i, szExtension);
>-        TRACE("Trying: %s\n", lpszFileName);
>-        hFile = CreateFileA(lpszFileName, GENERIC_READ, 0, NULL, CREATE_NEW, 0, NULL);
>+        int len = lstrlenW(szFile)+1;
>+        memcpy(lpszFileNameNoPath, szFile, (len<countnoextension ? len : countnoextension)*sizeof(WCHAR));
>  
>

The strncpyW function exists for a reason. Also, it is better to use 
strlenW than lstrlenW.

>+        wsprintfW(lpszFileNameNoPath + countnoextension, strFormat, i, szExtension);
>+        TRACE("Trying: %s\n", debugstr_w(lpszFileName));
>+        hFile = CreateFileW(lpszFileName, GENERIC_READ, 0, NULL, CREATE_NEW, 0, NULL);
>         if (hFile != INVALID_HANDLE_VALUE)
>         {
>             CloseHandle(hFile);
>@@ -1674,6 +1684,45 @@ BOOL WINAPI CreateUrlCacheEntryA(
>     return FALSE;
> }
> 
>+
>+/***********************************************************************
>+ *           CreateUrlCacheEntryA (WININET.@)
>+ *
>+ */
>+BOOL WINAPI CreateUrlCacheEntryA(
>+    IN LPCSTR lpszUrlName,
>+    IN DWORD dwExpectedFileSize,
>+    IN LPCSTR lpszFileExtension,
>+    OUT LPSTR lpszFileName,
>+    IN DWORD dwReserved
>+)
>+{
>+    int len;
>+    BOOL ret;
>+    LPWSTR lpszUrlNamew = NULL;
>+    LPWSTR lpszFileExtensionw = NULL;
>+    WCHAR lpszFileNamew[MAX_PATH+1];
>+
>+    if(lpszUrlName) {
>+        len = MultiByteToWideChar(CP_ACP, 0, lpszUrlName, -1, NULL, 0);
>+        lpszUrlNamew = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
>+        MultiByteToWideChar(CP_ACP, 0, lpszUrlName, -1, lpszUrlNamew, len);
>+    }
>+
>+    if(lpszFileExtension) {
>+        len = MultiByteToWideChar(CP_ACP, 0, lpszFileExtension, -1, NULL, 0);
>+        lpszFileExtensionw = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
>+        MultiByteToWideChar(CP_ACP, 0, lpszFileExtension, -1, lpszFileExtensionw, len);
>+    }
>+
>+    ret = CreateUrlCacheEntryW(lpszUrlNamew, dwExpectedFileSize, lpszFileExtensionw, lpszFileNamew, 0);
>+
>+    WideCharToMultiByte(CP_ACP, 0, lpszFileNamew, -1, lpszFileName, -1, 0, 0);
>+    HeapFree(GetProcessHeap(), 0, lpszUrlNamew);
>+    HeapFree(GetProcessHeap(), 0, lpszFileExtensionw);
>+    return ret;
>+}
>+
> /***********************************************************************
>  *           CommitUrlCacheEntryA (WININET.@)
>  *
>@@ -1999,12 +2048,11 @@ BOOL WINAPI UnlockUrlCacheEntryStream(
>     return TRUE;
> }
> 
>-
> /***********************************************************************
>- *           DeleteUrlCacheEntryA (WININET.@)
>+ *           DeleteUrlCacheEntryAW (internal)
>  
>

Bad name for the function. This convention is used in shell32 to 
indicate a function that is implemented as ANSI only on Win9x and 
Unicode on WinNT.

>  *
>  */
>-BOOL WINAPI DeleteUrlCacheEntryA(LPCSTR lpszUrlName)
>+BOOL WINAPI DeleteUrlCacheEntryAW(LPCWSTR lpszUrlName, BOOL bUnicode)
> {
>     URLCACHECONTAINER * pContainer;
>     LPURLCACHE_HEADER pHeader;
>@@ -2012,11 +2060,15 @@ BOOL WINAPI DeleteUrlCacheEntryA(LPCSTR 
>     DWORD dwStartBlock;
>     DWORD dwBlock;
>     BYTE * AllocationTable;
>+    LPSTR lpszUrlNamea = NULL;
> 
>-    TRACE("(%s)\n", debugstr_a(lpszUrlName));
>-
>-    if (!URLCacheContainers_FindContainerA(lpszUrlName, &pContainer))
>-        return FALSE;
>+    if(bUnicode) {
>+        if (!URLCacheContainers_FindContainerW(lpszUrlName, &pContainer))
>+            return FALSE;
>+    } else {
>+        if (!URLCacheContainers_FindContainerA((LPSTR)lpszUrlName, &pContainer))
>+            return FALSE;
>+    }
> 
>     if (!URLCacheContainer_OpenIndex(pContainer))
>         return FALSE;
>@@ -2024,11 +2076,20 @@ BOOL WINAPI DeleteUrlCacheEntryA(LPCSTR 
>     if (!(pHeader = URLCacheContainer_LockIndex(pContainer)))
>         return FALSE;
> 
>-    if (!URLCache_FindEntryInHash(pHeader, lpszUrlName, &pEntry))
>+    if(bUnicode) {
>+        lpszUrlNamea = (LPSTR)lpszUrlName;
>+    } else {
>+        int len = WideCharToMultiByte(CP_ACP, 0, lpszUrlName, -1, NULL, -1, 0, 0);
>+        WideCharToMultiByte(CP_ACP, 0, lpszUrlName, -1, lpszUrlNamea, len, 0, 0);
>+    }
>+
>+    if (!URLCache_FindEntryInHash(pHeader, lpszUrlNamea, &pEntry))
>     {
>         URLCacheContainer_UnlockIndex(pContainer, pHeader);
>-        TRACE("entry %s not found!\n", lpszUrlName);
>+        TRACE("entry not found!\n");
>         SetLastError(ERROR_FILE_NOT_FOUND);
>+        if(bUnicode)
>+            HeapFree(GetProcessHeap(), 0, lpszUrlNamea);
>         return FALSE;
>     }
> 
>@@ -2041,11 +2102,34 @@ BOOL WINAPI DeleteUrlCacheEntryA(LPCSTR 
> 
>     URLCache_DeleteEntry(pEntry);
> 
>-    URLCache_DeleteEntryFromHash(pHeader, lpszUrlName);
>+    URLCache_DeleteEntryFromHash(pHeader, lpszUrlNamea);
> 
>     URLCacheContainer_UnlockIndex(pContainer, pHeader);
> 
>+    if(bUnicode)
>+        HeapFree(GetProcessHeap(), 0, lpszUrlNamea);
>+
>     return TRUE;
>+}
>+
>+/***********************************************************************
>+ *           DeleteUrlCacheEntryA (WININET.@)
>+ *
>+ */
>+BOOL WINAPI DeleteUrlCacheEntryA(LPCSTR lpszUrlName)
>+{
>+    TRACE("(%s)\n", debugstr_a(lpszUrlName));
>+    return DeleteUrlCacheEntryAW((LPCWSTR)lpszUrlName, FALSE);
>+}
>+
>+/***********************************************************************
>+ *           DeleteUrlCacheEntryW (WININET.@)
>+ *
>+ */
>+BOOL WINAPI DeleteUrlCacheEntryW(LPCWSTR lpszUrlName)
>+{
>+    TRACE("(%s)\n", debugstr_w(lpszUrlName));
>+    return DeleteUrlCacheEntryAW(lpszUrlName, TRUE);
> }
> 
> /***********************************************************************
>  
>

Rob



More information about the wine-devel mailing list