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