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; }