Cleaning up W->A calls

James Hawkins truiken at comcast.net
Tue Jun 29 20:34:47 CDT 2004


I recently decided to help with the development of Wine, and seeing as
how I am new to the process, I have chosen menial tasks to take on. 
This way I can learn more about Wine while contributing.
 
 I am currently working on the janitorial task of getting rid of W->A
calls and I have a few questions about how I should implement these
changes.
 
 I'll start the question with an example:
 
 dlls/advapi32/crypt.c line 255, 482
 
 BOOL WINAPI CryptAcquireContextA (HCRYPTPROV *phProv, LPCSTR
pszContainer,
 LPCSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
 {
 ... complete implementation
 }
 
 BOOL WINAPI CryptAcquireContextW (HCRYPTPROV *phProv, LPCWSTR
pszContainer, LPCWSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
 {
 PSTR pProvider = NULL, pContainer = NULL;
 BOOL ret = FALSE;
 
 TRACE("(%p, %s, %s, %ld, %08lx)\n", phProv, debugstr_w(pszContainer),
 debugstr_w(pszProvider), dwProvType, dwFlags);
 
 if ( !CRYPT_UnicodeToANSI(pszContainer, &pContainer, -1) )
 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
 if ( !CRYPT_UnicodeToANSI(pszProvider, &pProvider, -1) )
 {
 CRYPT_Free(pContainer);
 CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
 }
 
 ret = CryptAcquireContextA(phProv, pContainer, pProvider,   
dwProvType, dwFlags);
 
 if (pContainer)
 CRYPT_Free(pContainer);
 if (pProvider)
 CRYPT_Free(pProvider);
 
 return ret;
 }
 
 Initially CryptAcquireContextW converts all of its arguments to ansi
then calls CryptAcquireContextA (which is intuitively not what we're
wanting and thus the cleanup.)  
 
 The question is, what exactly is the best way to clean this up?
 
 It seems to me that there are two main options as to what can be done: 
 
 A) convert the W->A calls in the wide-char functions to A->W calls in
the asci functions and implement the wide-char functions instead, or 
 
 B) implement both asci and wide-char functions separately ie asci
functions only call asci functions etc.
 
 If we are to choose plan A, I have seen several different methods of
converting asci to wide-char, and I am wondering which method is best. 
for example:
 
 dlls/advapi32/crypt.c lines 133-141
 
 wcount = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
 wcount = wcount < wstrsize/sizeof(WCHAR) ? wcount :
wstrsize/sizeof(WCHAR);
 if (wstrsize == -1)
 *wstr = CRYPT_Alloc(wcount * sizeof(WCHAR));
 if (*wstr)
 {
 MultiByteToWideChar(CP_ACP, 0, str, -1, *wstr, wcount);
 return TRUE;
 }
 
 and,
 
 dlls/advapi32/registry.c lines 1626-1636
 
 LONG WINAPI RegSaveKeyA( HKEY hkey, LPCSTR file, 
 LPSECURITY_ATTRIBUTES sa )
 {
     UNICODE_STRING *fileW = &NtCurrentTeb()->StaticUnicodeString;
     NTSTATUS status;
     STRING fileA;
 
     RtlInitAnsiString(&fileA, file);
     if ((status = RtlAnsiStringToUnicodeString(fileW, &fileA, FALSE)))
         return RtlNtStatusToDosError( status );
     return RegSaveKeyW(hkey, fileW->Buffer, sa);
 }
 
 Which method is better/more efficient?
 
 I would have to argue that implementing both the asci functions and
wide-char functions separately would be the most efficient way to solve
the W->A problem.  Throughout all the wine libs, many conversion calls
are being made from W->A and A->W, when most of these calls could be
left out.  I think performance would improve without all of the
conversion calls.  Granted the size of the code would increase, but
speed would also increase.
 
 There are a couple snags when it comes to implementing asci and
wide-char functions independently, but that can be discussed later.
 
 If I'm totally off the mark, let me know, and if there are other jobs I
could be doing, let me know as well because I would like to contribute,
but I'm not exactly sure what to do yet.  Thankyou for your time.
 
 James Hawkins
 truiken at comcast.net




More information about the wine-devel mailing list