Implemented CreateUrlCacheEntryW and DeleteUrlCacheEntryW

Jacek Caban jack at itma.pwr.wroc.pl
Fri Dec 24 06:55:39 CST 2004


Sorry, I forgot to CC this to wine-devel yesterday, so I incude it here. 
Also I made mistake: strlenW was ony my
bug. Existing code is correct. Attached is corrected version. Thanks.

Changelog:
   Implemented CreateUrlCacheEntryW and DeleteUrlCacheEntryW


Jacek Caban wrote:

> Hi.
>
> Robert Shearman wrote:
>
>> 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.
>
>
> Orginal code was wrong (my patch too). See next line:
> nRequired = (path_len + DIR_LENGTH + file_name_len + 1) * sizeof(WCHAR);
> It expects file_name_len without NULL terminator. My bug was that I 
> missed +1 in memcpy.
>
>> 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.
>
>
> Yes, I thought about this. But This function anyway did A->W 
> conversion and was called from two
> places. One of them I unicodified, in second I did conversion before 
> calling (there was another
> small bug I've also fixed).
>
>>>     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))
>>> -        {
>>
>>
> Here is a bug I've written about. If bUnicode was TRUE, but 
> URLCache_LocalFileNameToPathW returned FALSE,
> URLCache_LocalFileNameToPathA was called.
>
>>> +        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.
>
>
> What do you mean? Should I do something like:
> {
>     static const WCHAR wszWWW[] = {'w','w','w',0};
>     static const WCHAR wszFormat[] = {'[','%','u',']','%','s',0};
>      if (!lstrcmpW(lpszUrlPart, strWWW))
>          lpszUrlPart += sizeof(strWWW)/sizeof(WCHAR) -1;
> }
>
>> Also, "wsz" is the prefix usually used for Wide Character string 
>> constants.
>
>
> I'll fix this.
> <>
>
>>
>>     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.
> I'll fix it.
>
>>
>>> +        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.
>>
> I didn't know this. What is a good name? Is doDeleteUrlCacheEntry 
> acceptable?
>
>>>  *
>>>  */
>>> -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
>
>
>
> Thanks,
>    Jacek
>

-------------- next part --------------
A non-text attachment was scrubbed...
Name: urlcache2.diff
Type: text/x-patch
Size: 12544 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-patches/attachments/20041224/518f45b1/urlcache2.bin


More information about the wine-patches mailing list