http://bugs.winehq.org/show_bug.cgi?id=6638
------- Additional Comments From a_villacis@palosanto.com 2006-09-11 16:50 ------- Created an attachment (id=4045) --> (http://bugs.winehq.org/attachment.cgi?id=4045&action=view) IDL of the ADODB typelib with the Attach method
This is the IDL of the typelib responsible for the crash.
One thing is apparent in close examination: There are really two methods.
There is an: [id(0x00000003)] void Append( [in] BSTR Name, [in] DataTypeEnum Type, [in, opt, hasdefault] ADO_LONGPTR DefinedSize, [in, opt, hasdefault] FieldAttributeEnum Attrib, [in, opt] VARIANT FieldValue);
And then, there is an:
void _stdcall _Append( [in] BSTR Name, [in] DataTypeEnum Type, [in, opt, hasdefault] ADO_LONGPTR DefinedSize, [in, opt, hasdefault] FieldAttributeEnum Attrib);
The key differences between the two methods (apart from the underscore) is that
1) Append and _Append differ only in the presence of the critical parameter FieldValue. Note that FieldValue is declared as [in, opt], but does not have a hasdefault attribute. 2) _Append does not have an ID for the IDispatch interface. If I understand the code correctly, this means it cannot be directly invoked through IDispatch.
I have a hypothesis, that native oleaut32 checks the number of parameters given to the Invoke method. The Invoke method was given the ID of the Append method, but in the 4-parameter case, _Append gets called instead, since its parameter list more closely matches the actual usage. So the general rule might be: if there are ommited parameters with [in, opt] attributes, but no hasdefault attribute, then check whether an underscore-prefixed version of the method exists which does not have the problematic parameter, and call that instead.
This obviously requires a testcase, but this seems sensible to me, at least in principle. The underscore might then work as a kind of crude method overloading. Builtin oleaut32 does not follow this rule, and ends up invoking the wrong version of the method, with the exception explained earlier.