Hi
Who invented VB...? Ah yeah, right...
I'm trying (again) to run a VB app on wine. But it never shows up. Instead I only see a dialog with this Type mismatch error and then it quits. I tried to find the place where it goes wrong. Apparently it tries to parse a number from a string in VB notation. 0009:trace:ole:VarParseNumFromStr (L"&H8000",1024,0x00000000,0x408bdee0,0x408bdae0)
With my own debug messages I found that it bails out with this reason: ole:VarParseNumFromStr: Not all chars were consumed
This leads to a nice exception which is caught from the VB dll: 0009:Call kernel32.RaiseException(c000008f,00000001,00000002,408be0c8) ret=6a87479d 0009:trace:seh:EXC_RtlRaiseException code=c000008f flags=1 addr=0x404b9b30 0009:trace:seh:EXC_RtlRaiseException info[0]=deadcafe 0009:trace:seh:EXC_RtlRaiseException info[1]=deadcafe 0009:trace:seh:EXC_RtlRaiseException eax=408bdf70 ebx=4057691c ecx=00000000 edx=00000004 esi=408be0d0 edi=408bdf8c 0009:trace:seh:EXC_RtlRaiseException ebp=408bdfcc esp=408bdf70 cs=0023 ds=002b es=002b fs=1007 gs=0000 flags=00000212 0009:trace:seh:EXC_CallHandler calling handler at 0x11004246 code=c000008f flags=1 0009:CALL MSVBVM60.__vbaExceptHandler(<unknown, check return>(0x40340000,00000002,00000040): returning 42b4c020 ) ret=401cac8b
And this in return presents me the nice error dialog. 0009:trace:resource:LoadStringW L"Type mismatch" loaded !
Is this function VarParseNumFromStr supposed to understand VB notation as well? The docs from MS I found don't say anything about how the numbers have to be formed to be parsed well. In a small test program in C I only got the same result on Windows for these parameters. So the implementation seems ok so far. But then where did this string come from? Some property?
0009:Call oleaut32.SysAllocStringLen(42b4b70c L"FontColor",00000009) ret=6a939fac 0009:trace:heap:RtlAllocateHeap (0x40340000,00000002,00000018): returning 42b4b6a8 0009:Ret oleaut32.SysAllocStringLen() retval=42b4b6ac ret=6a939fac 0009:Call user32.CharUpperBuffW(42b4b6ac L"FontColor",0000000a) ret=6a934b66 0009:Ret user32.CharUpperBuffW() retval=0000000a ret=6a934b66 0009:RET MSVBVM60.rtcUpperCaseVar() retval=408be230 ret=1102ff69 0009:CALL MSVBVM60.__vbaVarTstEq(408be1e0,408be230) ret=1102ff8e 0009:Call oleaut32.VarCmp(408be230,408be1e0,00000000,00030001) ret=6a94f05b 0009:trace:ole:VarCmp (0x408be230->(VT_BSTR),0x408be1e0->(VT_BSTR|VT_HARDTYPE),0x00000000,0x00030001) 0009:trace:ole:VariantInit (0x408bdff8) 0009:trace:ole:VariantInit (0x408be008) 0009:Call kernel32.CompareStringW(00000000,00030001,42b4b6ac L"FONTCOLOR",ffffffff,1100b858 L"VALUE",ffffffff) ret=40c164be 0009:Ret kernel32.CompareStringW() retval=00000001 ret=40c164be 0009:Ret oleaut32.VarCmp() retval=00000000 ret=6a94f05b 0009:RET MSVBVM60.__vbaVarTstEq() retval=00000000 ret=1102ff8e 0009:CALL MSVBVM60.__vbaFreeVar() ret=1102ff96 0009:Call oleaut32.SysFreeString(42b4b6ac L"FONTCOLOR") ret=6a94f0df 0009:trace:heap:RtlFreeHeap (0x40340000,00000002,42b4b6a8): returning TRUE 0009:Ret oleaut32.SysFreeString() retval=00000001 ret=6a94f0df 0009:RET MSVBVM60.__vbaFreeVar() retval=00000001 ret=1102ff96 0009:CALL MSVBVM60.rtcMidCharVar(408be220,408be1f0,00000003,408be230) ret=1102ffff 0009:Call oleaut32.SysAllocStringByteLen(42b4bfb8,00000008) ret=6a8742d9 0009:trace:heap:RtlAllocateHeap (0x40340000,00000002,00000018): returning 42b4b6a8 0009:Ret oleaut32.SysAllocStringByteLen() retval=42b4b6ac ret=6a8742d9 0009:RET MSVBVM60.rtcMidCharVar() retval=408be220 ret=1102ffff 0009:CALL MSVBVM60.__vbaVarCat(408be210,408be220,408be1d0) ret=11030014 0009:Call oleaut32.VarCat(408be1d0,408be220,408be210) ret=6a938e10 0009:trace:ole:VarCat (0x408be1d0->(VT_BSTR),0x408be220->(VT_BSTR),0x408be210) 0009:trace:heap:RtlAllocateHeap (0x40340000,00000002,00000018): returning 42b4bfd0
VARIANT: VarCat: L"&H"+L"8000"=L"&H8000" and so on
I know that color properties can have standard system values which start with &H8000... But is this the reason? And why does this get into VarParseNumFromStr?
Thanks
bye Fabi
I'm trying (again) to run a VB app on wine. But it never shows up. Instead I only see a dialog with this Type mismatch error and then it quits. I tried to find the place where it goes wrong. Apparently it tries to parse a number from a string in VB notation. 0009:trace:ole:VarParseNumFromStr (L"&H8000",1024,0x00000000,0x408bdee0,0x408bdae0)
I found that this string "&H8000" comes from my code and it's intentional. In VB you can convert a string to a long by using i=CLng(str). But if the string number is in hex format it needs to be VB hex notation. This works on Windows and fails on wine. I now need to find out how CLng(str) converts the string and why this is different on wine.
bye Fabi
I'm trying (again) to run a VB app on wine. But it never shows up. Instead I only see a dialog with this Type mismatch error and then it quits. I tried to find the place where it goes wrong. Apparently it tries to parse a number from a string in VB notation. 0009:trace:ole:VarParseNumFromStr (L"&H8000",1024,0x00000000,0x408bdee0,0x408bdae0)
I found that this string "&H8000" comes from my code and it's intentional. In VB you can convert a string to a long by using i=CLng(str). But if the string number is in hex format it needs to be VB hex notation. This works on Windows and fails on wine. I now need to find out how CLng(str) converts the string and why this is different on wine.
Contrary to my first tests these API functions understand VB hex numbers quite well. There is no problem with these calls on Win2K:
OLECHAR test[]={'&', 'H', 'F', '0', '8', 'F', '\0'}; VarI4FromStr(test, LANG_NEUTRAL, NUMPRS_STD, &out); VarParseNumFromStr(test, LANG_NEUTRAL, NUMPRS_STD, &np, rgb);
So I implemented this in wine too. If anybody has a program (mostly VB) that uses hex numbers in strings please try it out. Without any other remarks I'll send it to wine-patches.
bye Fabi
Index: wine/dlls/oleaut32/variant.c =================================================================== RCS file: /home/wine/wine/dlls/oleaut32/variant.c,v retrieving revision 1.88 diff -u -r1.88 variant.c --- wine/dlls/oleaut32/variant.c 25 Feb 2004 01:35:01 -0000 1.88 +++ wine/dlls/oleaut32/variant.c 25 Feb 2004 08:00:10 -0000 @@ -1468,6 +1468,7 @@ #define B_EXPONENT_START 0x4 #define B_INEXACT_ZEROS 0x8 #define B_LEADING_ZERO 0x10 +#define B_PROCESSING_HEX 0x20
/********************************************************************** * VarParseNumFromStr [OLEAUT32.46] @@ -1698,6 +1699,33 @@ dwState |= B_NEGATIVE_EXPONENT; cchUsed++; } + else if ((*lpszStr == '&' && *(lpszStr+1) == 'H') && + pNumprs->dwInFlags & NUMPRS_HEX_OCT && + !(pNumprs->dwOutFlags & NUMPRS_EXPONENT)) + { + dwState |= B_PROCESSING_HEX; + pNumprs->dwOutFlags |= NUMPRS_HEX_OCT; + cchUsed=cchUsed+2; + lpszStr++; + } + else if (((*lpszStr >= 'a' && *lpszStr <= 'f') || + (*lpszStr >= 'A' && *lpszStr <= 'F')) && + dwState & B_PROCESSING_HEX) + { + if (pNumprs->cDig >= iMaxDigits) + { + return DISP_E_OVERFLOW; + } + else + { + if (*lpszStr >= 'a') + rgbTmp[pNumprs->cDig] = *lpszStr - 'a' + 10; + else + rgbTmp[pNumprs->cDig] = *lpszStr - 'A' + 10; + } + pNumprs->cDig++; + cchUsed++; + } else break; /* Stop at an unrecognised character */
@@ -1728,14 +1756,20 @@ /* cDig of X and writes X+Y where Y>=0 number of digits to rgbDig */ memcpy(rgbDig, rgbTmp, pNumprs->cDig * sizeof(BYTE));
- while (pNumprs->cDig > 1 && !rgbTmp[pNumprs->cDig - 1]) - { - if (pNumprs->dwOutFlags & NUMPRS_DECIMAL) - pNumprs->nPwr10--; - else - pNumprs->nPwr10++; + if (dwState & B_PROCESSING_HEX) { + /* hex number have always the same format */ + pNumprs->nPwr10=0; + pNumprs->nBaseShift=4; + } else { + while (pNumprs->cDig > 1 && !rgbTmp[pNumprs->cDig - 1]) + { + if (pNumprs->dwOutFlags & NUMPRS_DECIMAL) + pNumprs->nPwr10--; + else + pNumprs->nPwr10++;
- pNumprs->cDig--; + pNumprs->cDig--; + } } } else { @@ -1870,7 +1904,110 @@ if (pNumprs->nBaseShift) { /* nBaseShift indicates a hex or octal number */ - FIXME("nBaseShift=%d not yet implemented, returning overflow\n", pNumprs->nBaseShift); + ULONG64 ul64 = 0; + LONG64 l64; + int i; + + /* Convert the hex or octal number string into a UI64 */ + for (i = 0; i < pNumprs->cDig; i++) + { + if (ul64 > ((UI8_MAX>>pNumprs->nBaseShift) - rgbDig[i])) + { + TRACE("Overflow multiplying digits\n"); + return DISP_E_OVERFLOW; + } + ul64 = (ul64<<pNumprs->nBaseShift) + rgbDig[i]; + } + + /* also make a negative representation */ + l64=-ul64; + + /* Try signed and unsigned types in size order */ + if (dwVtBits & VTBIT_I1 && ((ul64 <= I1_MAX)||(l64 >= I1_MIN))) + { + V_VT(pVarDst) = VT_I1; + if (ul64 <= I1_MAX) + V_I1(pVarDst) = ul64; + else + V_I1(pVarDst) = l64; + return S_OK; + } + else if (dwVtBits & VTBIT_UI1 && ul64 <= UI1_MAX) + { + V_VT(pVarDst) = VT_UI1; + V_UI1(pVarDst) = ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_I2 && ((ul64 <= I2_MAX)||(l64 >= I2_MIN))) + { + V_VT(pVarDst) = VT_I2; + if (ul64 <= I2_MAX) + V_I2(pVarDst) = ul64; + else + V_I2(pVarDst) = l64; + return S_OK; + } + else if (dwVtBits & VTBIT_UI2 && ul64 <= UI2_MAX) + { + V_VT(pVarDst) = VT_UI2; + V_UI2(pVarDst) = ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_I4 && ((ul64 <= I4_MAX)||(l64 >= I4_MIN))) + { + V_VT(pVarDst) = VT_I4; + if (ul64 <= I4_MAX) + V_I4(pVarDst) = ul64; + else + V_I4(pVarDst) = l64; + return S_OK; + } + else if (dwVtBits & VTBIT_UI4 && ul64 <= UI4_MAX) + { + V_VT(pVarDst) = VT_UI4; + V_UI4(pVarDst) = ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_I8 && ((ul64 <= I4_MAX)||(l64>=I4_MIN))) + { + V_VT(pVarDst) = VT_I8; + V_I8(pVarDst) = ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_UI8) + { + V_VT(pVarDst) = VT_UI8; + V_UI8(pVarDst) = ul64; + return S_OK; + } + else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL) + { + V_VT(pVarDst) = VT_DECIMAL; + DEC_SIGNSCALE(&V_DECIMAL(pVarDst)) = SIGNSCALE(DECIMAL_POS,0); + DEC_HI32(&V_DECIMAL(pVarDst)) = 0; + DEC_LO64(&V_DECIMAL(pVarDst)) = ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_R4 && ((ul64 <= I4_MAX)||(l64 >= I4_MIN))) + { + V_VT(pVarDst) = VT_R4; + if (ul64 <= I4_MAX) + V_R4(pVarDst) = ul64; + else + V_R4(pVarDst) = l64; + return S_OK; + } + else if (dwVtBits & VTBIT_R8 && ((ul64 <= I4_MAX)||(l64 >= I4_MIN))) + { + V_VT(pVarDst) = VT_R8; + if (ul64 <= I4_MAX) + V_R8(pVarDst) = ul64; + else + V_R8(pVarDst) = l64; + return S_OK; + } + + TRACE("Overflow: possible return types: 0x%lx, value: %s\n", dwVtBits, wine_dbgstr_longlong(ul64)); return DISP_E_OVERFLOW; }
Index: wine/dlls/oleaut32/tests/vartest.c =================================================================== RCS file: /home/wine/wine/dlls/oleaut32/tests/vartest.c,v retrieving revision 1.23 diff -u -r1.23 vartest.c --- wine/dlls/oleaut32/tests/vartest.c 6 Feb 2004 05:23:48 -0000 1.23 +++ wine/dlls/oleaut32/tests/vartest.c 25 Feb 2004 08:00:13 -0000 @@ -789,6 +789,15 @@ EXPECTRGB(2,0); EXPECTRGB(3,FAILDIG);
+ /* VB hex */ + CONVERT("&HF800", NUMPRS_HEX_OCT); + EXPECT(4,NUMPRS_HEX_OCT,0x40,6,4,0); + EXPECTRGB(0,15); + EXPECTRGB(1,8); + EXPECTRGB(2,0); + EXPECTRGB(3,0); + EXPECTRGB(4,FAILDIG); + /** NUMPRS_PARENS **/
/* Empty parens = error */
On Wednesday 25 February 2004 04:15 am, Fabian Cenedese wrote:
Contrary to my first tests these API functions understand VB hex numbers quite well. There is no problem with these calls on Win2K:
OLECHAR test[]={'&', 'H', 'F', '0', '8', 'F', '\0'}; VarI4FromStr(test, LANG_NEUTRAL, NUMPRS_STD, &out); VarParseNumFromStr(test, LANG_NEUTRAL, NUMPRS_STD, &np, rgb);
So I implemented this in wine too. If anybody has a program (mostly VB) that uses hex numbers in strings please try it out. Without any other remarks I'll send it to wine-patches.
I believe "&O123" is a valid format also, which is how you specify an octal number in VB
Contrary to my first tests these API functions understand VB hex numbers quite well. There is no problem with these calls on Win2K:
OLECHAR test[]={'&', 'H', 'F', '0', '8', 'F', '\0'}; VarI4FromStr(test, LANG_NEUTRAL, NUMPRS_STD, &out); VarParseNumFromStr(test, LANG_NEUTRAL, NUMPRS_STD, &np, rgb);
So I implemented this in wine too. If anybody has a program (mostly VB) that uses hex numbers in strings please try it out. Without any other remarks I'll send it to wine-patches.
I believe "&O123" is a valid format also, which is how you specify an octal number in VB
Yes, octal is another valid format. I think I can squeeze it in this patch as well, most of it is already done. I also need to add another check as they even understand &h with lower case h.
bye Fabi