Problem with Access-mdb/DAO

Fabian Cenedese Cenedese at indel.ch
Thu Jan 8 04:12:17 CST 2004


>>If you have a string like "Nodes", then the BSTR DWORD value should be
>>5*sizeof(WCHAR) == 5*2 == 10, *NOT* 5.
>>
>>In other words, we don't have an even/odd division problem, but rather a
>>problem with the string length, since it should have been twice as much.
>>
>>Please try to find out which function created that BSTR with this wrong
>>length calculation and try to fix it.
>
>Actually that's a normal WINAPI function called SysAllocStringByteLen.
>It's used in the DAO stuff from MFC. A COleVariant is created with
>explicit type VT_BSTRT. This happens in the constructor:
>
>COleVariant::COleVariant(LPCTSTR lpszSrc, VARTYPE vtSrc)
>{
>        USES_CONVERSION;
>        ASSERT(vtSrc == VT_BSTR || vtSrc == VT_BSTRT);
>        UNUSED(vtSrc);
>
>        vt = VT_BSTR;
>        bstrVal = NULL;
>
>        if (lpszSrc != NULL)
>        {
>#ifndef _UNICODE
>                if (vtSrc == VT_BSTRT)
>                {
>                        int nLen = lstrlen(lpszSrc);
>                        bstrVal = ::SysAllocStringByteLen(lpszSrc, nLen);
>                }
>                else
>#endif
>                {
>                        bstrVal = ::SysAllocString(T2COLE(lpszSrc));
>                }
>
>                if (bstrVal == NULL)
>                        AfxThrowMemoryException();
>        }
>}
>
>So not every BSTR is really a wide char string. That's why MSDN says
>that SysStringLen has to give back the allocated length if the BSTR
>was created with SysAllocStringByteLen.
>
>I made a short test program:
>
>COleVariant v1;
>VariantInit(&v1);
>v1=COleVariant("Nodes", VT_BSTRT);
>cout << SysStringLen(v1.bstrVal) << " " << (char*)v1.bstrVal << endl;
>
>Output on Windows:
>2 Nodes
>
>Output on wine:
>2 Node
>
>(And you're right, the SysStringLen is ok, reports also 2 on Windows).
>
>The SysAllocStringByteLen is ok, but the variant assignment is done
>with VariantCopy which is definitely wrong. The source string is still
>ok but the dest string is only "Node". But this function is above my
>knowledge. I don't know if the allocation/copy is wrong or if it needs
>a new case for these special non-WCHAR BSTRs.
>
>(Another interesting test: What happens with one-char-strings...?)

Ok, I just tried and changed the code a bit. This now works with
normal wide char strings as well as binary data (may as well be an
ASCII string) with type BSTR. Though it works for me it may not
be the right solution.

bye  Fabi


Index: wine/dlls/oleaut32/variant.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/variant.c,v
retrieving revision 1.83
diff -u -r1.83 variant.c
--- wine/dlls/oleaut32/variant.c        6 Jan 2004 22:08:34 -0000       1.83
+++ wine/dlls/oleaut32/variant.c        8 Jan 2004 10:05:25 -0000
@@ -727,7 +727,7 @@
       {
         if (V_BSTR(pvargSrc))
         {
-          V_BSTR(pvargDest) = SysAllocStringLen(V_BSTR(pvargSrc), SysStringLen(V_BSTR(pvargSrc)));
+          V_BSTR(pvargDest) = SysAllocStringByteLen((char*)V_BSTR(pvargSrc), SysStringByteLen(V_BSTR(pvargSrc)));
           if (!V_BSTR(pvargDest))
             hres = E_OUTOFMEMORY;
         }





More information about the wine-devel mailing list