As of 2006-07-14, the CVS snapshot of Wine 0.9.17 broke MS Visual Basic collections, when they ask for the _NewEnum in the _Collection interface. This method is used for the For Each...Next language construct, when applied to collection interfaces implemented in external DLLs (that is, collections compiled inside the same EXE where they are used are not affected). After a little digging I found that a recent patch adds a FUNCFLAG_FRESTRICTED check when looking for appropriate methods in an interface:
(from dlls/oleaut32/typelib.c: 5223)
/* we do this instead of using GetFuncDesc since it will return a fake * FUNCDESC for dispinterfaces and we want the real function description */ for (pFuncInfo = This->funclist; pFuncInfo; pFuncInfo=pFuncInfo->next) if ((memid == pFuncInfo->funcdesc.memid) && (wFlags & pFuncInfo->funcdesc.invkind) && !(pFuncInfo->funcdesc.wFuncFlags & FUNCFLAG_FRESTRICTED)) <-- breaks VB collections break;
If the FUNCFLAG_FRESTRICTED check is removed, the problem is solved. I would normally send in a patch for this, but since this check was deliberately added, there must be some other reason why this check was deemed necessary, so I am sending this notice instead.
BTW, this is why the check breaks collections:
0009:trace:ole:dump_TypeInfo 0x7fe99a80 ref=2 0009:trace:ole:dump_TypeInfo L"_Collection" (null) 0009:trace:ole:dump_TypeInfo attr:{00000512-0000-0010-8000-00aa006d2ea4} 0009:trace:ole:dump_TypeInfo kind:TKIND_DISPATCH 0009:trace:ole:dump_TypeInfo fct:3 var:0 impl:1 0009:trace:ole:dump_TypeInfo wTypeFlags: 0x11c0 0009:trace:ole:dump_TypeInfo parent tlb:0x7fe81738 index in TLB:53 L"Count"(1) parm0: L"c" memid is 00000001 Param 0: tdesc.vartype 26 (ptr to VT_I4) u.paramdesc.wParamFlags PARAMFLAG_FOUT PARAMFLAG_FRETVAL u.paramdesc.lpex (nil) funckind: 1 (pure virtual) invkind: 2 (property get) callconv: 4 (stdcall) oVft: 28 cParamsOpt: 0 wFlags: 0 elemdescFunc (return value type): tdesc.vartype 25 (VT_HRESULT) u.paramdesc.wParamFlags PARAMFLAGS_NONE u.paramdesc.lpex (nil) helpstring: (null) entry: (null) L"_NewEnum"(1) parm0: L"ppvObject" memid is fffffffc Param 0: tdesc.vartype 26 (ptr to VT_UNKNOWN) u.paramdesc.wParamFlags PARAMFLAG_FOUT PARAMFLAG_FRETVAL u.paramdesc.lpex (nil) funckind: 1 (pure virtual) invkind: 1 (func) callconv: 4 (stdcall) oVft: 32 cParamsOpt: 0 wFlags: 1 elemdescFunc (return value type): tdesc.vartype 25 (VT_HRESULT) u.paramdesc.wParamFlags PARAMFLAGS_NONE u.paramdesc.lpex (nil) helpstring: (null) entry: (null) L"Refresh"(0) memid is 00000002 funckind: 1 (pure virtual) invkind: 1 (func) callconv: 4 (stdcall) oVft: 36 cParamsOpt: 0 wFlags: 0 elemdescFunc (return value type): tdesc.vartype 25 (VT_HRESULT) u.paramdesc.wParamFlags PARAMFLAGS_NONE u.paramdesc.lpex (nil) helpstring: (null) entry: (null)
Many VB programs (especially those dealing with DAO/ADO collections) ask for the _NewEnum method with index fffffffc. However, this method has the FUNCFLAG_FRESTRICTED flag set, as seen from the typelib dump.
Alex Villacís Lasso
a_villacis@palosanto.com wrote:
As of 2006-07-14, the CVS snapshot of Wine 0.9.17 broke MS Visual Basic collections, when they ask for the _NewEnum in the _Collection interface. This method is used for the For Each...Next language construct, when applied to collection interfaces implemented in external DLLs (that is, collections compiled inside the same EXE where they are used are not affected). After a little digging I found that a recent patch adds a FUNCFLAG_FRESTRICTED check when looking for appropriate methods in an interface:
(from dlls/oleaut32/typelib.c: 5223)
/* we do this instead of using GetFuncDesc since it will return a fake * FUNCDESC for dispinterfaces and we want the real function description */ for (pFuncInfo = This->funclist; pFuncInfo; pFuncInfo=pFuncInfo->next) if ((memid == pFuncInfo->funcdesc.memid) && (wFlags & pFuncInfo->funcdesc.invkind) && !(pFuncInfo->funcdesc.wFuncFlags & FUNCFLAG_FRESTRICTED)) <-- breaks VB collections break;
If the FUNCFLAG_FRESTRICTED check is removed, the problem is solved. I would normally send in a patch for this, but since this check was deliberately added, there must be some other reason why this check was deemed necessary, so I am sending this notice instead.
Yes, the change is obviously incorrect since it causes regressions. I think I should have been checking the restricted flag on the interface, rather than on the function.