working together on stdole.tlb and a end to dcom9x

Huw D M Davies h.davies1 at physics.ox.ac.uk
Sun Aug 29 07:33:55 CDT 2004


On Sat, Aug 28, 2004 at 05:59:39PM -0400, Nyef wrote:
> The ICreateTypeLib2 interface is used to create the new-style MSFT typelibs.
> The older ICreateTypeLib interface is used for the old-style typelibs. While
> the newer interface also implements the older one, when you ask for the old
> interface with CreateTypeLib() you get a completely different implementation.
> 
> I don't see why it necessarily follows that stdole32 wouldn't work as an MSFT
> typelib, but the implementation of ICreateTypeInfo2 is badly incomplete in
> places, and I would trust it to completely mess up any semi-complex type
> library you attempt to create with it. Specifically, any type library that
> involves functions or variables.

You're right, an MSFT stdole32 might work fine - I guess we should at
least try it.  So for fun I've attached the program we used to
generate CrossOver's stdole32.tlb (Actually you need to take the
generated file and wrap it up in a resource only dll, but that's a
detail).  Since it was designed to be compiled with MSVC, it uses the
L"" construct for olestrings - you can hack around this by compiling
with -fshort-wchar for now.

Huw.
-------------- next part --------------
/*
 * stdole32.tlb generator
 *
 * Copyright (C) 2003, 2004  Huw Davies
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include <windows.h>
#include <stdio.h>

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprevinst,LPSTR lpCmdLine,int nShowCmd)
{
	HRESULT hres;
	ICreateTypeLib *pCTL;
	ICreateTypeInfo *pCTI;
	VARDESC vdesc;
	FUNCDESC fdesc;
	char buf[100];
	ITypeInfo *pGUIDTI, *pIUnknownTI, *pDISPPARAMSTI, *pEXCEPINFOTI, *pIEnumVARIANTTI;
	ARRAYDESC adesc;
	TYPEDESC tdesc, tdesc2, tdesc3, tdesc4, tdesc5;
	ELEMDESC edesc[8]; /* 8's enough for IDispatch::Invoke */
	OLECHAR *olestr[9];/* 9's   "     "       "        "   */
	GUID GUID_Library = {0x00020430,0,0,{0xc0,0,0,0,0,0,0,0x46}};
	HREFTYPE hrefGUID, hrefIUnknown, hrefDISPPARAMS, hrefEXCEPINFO, hrefIEnumVARIANT;
	OleInitialize(NULL);

	hres = CreateTypeLib(SYS_WIN32,L"stdole32.tlb",&pCTL);
	if(!SUCCEEDED(hres)) MessageBox(0,"CreateTypeLib2 failed", "err", MB_OK);


	pCTL->lpVtbl->SetName(pCTL,L"stdole");
	pCTL->lpVtbl->SetVersion(pCTL,1,0);
	pCTL->lpVtbl->SetDocString(pCTL,L"OLE Automation");
	pCTL->lpVtbl->SetGuid(pCTL,&GUID_Library);
	pCTL->lpVtbl->SetLcid(pCTL,0);
	pCTL->lpVtbl->SetLibFlags(pCTL,LIBFLAG_FRESTRICTED);

	
	/* struct GUID */
	hres = pCTL->lpVtbl->CreateTypeInfo(pCTL, L"GUID",TKIND_RECORD,&pCTI);
	if(!SUCCEEDED(hres)) MessageBox(0,"CreateTypeInfo failed", "err", MB_OK);
	/* unsigned long Data1 */
	memset(&vdesc, 0, sizeof(vdesc));
	vdesc.memid = 0x40000000;
	vdesc.elemdescVar.tdesc.vt = VT_UI4;
	hres = pCTI->lpVtbl->AddVarDesc(pCTI,0,&vdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddVarDesc failed", "err", MB_OK);
	pCTI->lpVtbl->SetVarName(pCTI,0,L"Data1");
	/* unsigned short Data2 */
	memset(&vdesc, 0, sizeof(vdesc));
	vdesc.memid = 0x40000001;
	vdesc.elemdescVar.tdesc.vt = VT_UI2;
	hres = pCTI->lpVtbl->AddVarDesc(pCTI,1,&vdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddVarDesc failed", "err", MB_OK);
	hres = pCTI->lpVtbl->SetVarName(pCTI,1,L"Data2");
	if(!SUCCEEDED(hres)) MessageBox(0,"SetVarName failed", "err", MB_OK);
	/* unsigned short Data3 */
	memset(&vdesc, 0, sizeof(vdesc));
	vdesc.memid = 0x40000002;
	vdesc.elemdescVar.tdesc.vt = VT_UI2;
	hres = pCTI->lpVtbl->AddVarDesc(pCTI,2,&vdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddVarDesc failed", "err", MB_OK);
	pCTI->lpVtbl->SetVarName(pCTI,2,L"Data3");
	/* unsigned char Data4[8] */
	memset(&vdesc, 0, sizeof(vdesc));
	memset(&adesc, 0, sizeof(adesc));
	vdesc.memid = 0x40000003;
	vdesc.elemdescVar.tdesc.vt = VT_CARRAY;
	vdesc.elemdescVar.tdesc.lpadesc = &adesc;
	vdesc.elemdescVar.tdesc.lpadesc->cDims = 1;
	vdesc.elemdescVar.tdesc.lpadesc->tdescElem.vt = VT_UI1;
	vdesc.elemdescVar.tdesc.lpadesc->rgbounds[0].cElements = 8;
	hres = pCTI->lpVtbl->AddVarDesc(pCTI,3,&vdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddVarDesc failed", "err", MB_OK);
	pCTI->lpVtbl->SetVarName(pCTI,3,L"Data4");
	hres =pCTI->lpVtbl->LayOut(pCTI);
	if(!SUCCEEDED(hres)) MessageBox(0,"guid layout failed", "err", MB_OK);
	hres = pCTI->lpVtbl->QueryInterface(pCTI,&IID_ITypeInfo,(void**)&pGUIDTI);
	if(!SUCCEEDED(hres)) MessageBox(0,"qi typeinfo guid failed", "err", MB_OK);
	pCTI->lpVtbl->Release(pCTI);
	


	
	/* DISPPARMS */
	hres = pCTL->lpVtbl->CreateTypeInfo(pCTL, L"DISPPARAMS",TKIND_RECORD,&pCTI);
	if(!SUCCEEDED(hres)) MessageBox(0,"CreateTypeInfo failed", "err", MB_OK);
	/* VARIANT *rgvarg */
	memset(&vdesc, 0, sizeof(vdesc));
	memset(&tdesc, 0, sizeof(tdesc));
	vdesc.memid = 0x40000000;
	vdesc.elemdescVar.tdesc.vt = VT_PTR;
	vdesc.elemdescVar.tdesc.lptdesc = &tdesc;
	vdesc.elemdescVar.tdesc.lptdesc->vt = VT_VARIANT;
	hres = pCTI->lpVtbl->AddVarDesc(pCTI,0,&vdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddVarDesc failed", "err", MB_OK);
	pCTI->lpVtbl->SetVarName(pCTI,0,L"rgvarg");

	/* long *rgdispidNamedArgs */
	memset(&vdesc, 0, sizeof(vdesc));
	memset(&tdesc, 0, sizeof(tdesc));
	vdesc.memid = 0x40000001;
	vdesc.elemdescVar.tdesc.vt = VT_PTR;
	vdesc.elemdescVar.tdesc.lptdesc = &tdesc;
	vdesc.elemdescVar.tdesc.lptdesc->vt = VT_I4;
	hres = pCTI->lpVtbl->AddVarDesc(pCTI,1,&vdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddVarDesc failed", "err", MB_OK);
	pCTI->lpVtbl->SetVarName(pCTI,1,L"rgdispidNamedArgs");

	/* unsigned int cArgs */
	memset(&vdesc, 0, sizeof(vdesc));
	vdesc.memid = 0x40000002;
	vdesc.elemdescVar.tdesc.vt = VT_UINT;
	hres = pCTI->lpVtbl->AddVarDesc(pCTI,2,&vdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddVarDesc failed", "err", MB_OK);
	pCTI->lpVtbl->SetVarName(pCTI,2,L"cArgs");
	
	/* unsigned int cNamedArgs */
	memset(&vdesc, 0, sizeof(vdesc));
	vdesc.memid = 0x40000003;
	vdesc.elemdescVar.tdesc.vt = VT_UINT;
	hres = pCTI->lpVtbl->AddVarDesc(pCTI,3,&vdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddVarDesc failed", "err", MB_OK);
	pCTI->lpVtbl->SetVarName(pCTI,3,L"cNamedArgs");
	pCTI->lpVtbl->LayOut(pCTI);
	pCTI->lpVtbl->QueryInterface(pCTI,&IID_ITypeInfo,(void**)&pDISPPARAMSTI);
	pCTI->lpVtbl->Release(pCTI);


	/* EXCEPINFO */
	hres = pCTL->lpVtbl->CreateTypeInfo(pCTL, L"EXCEPINFO",TKIND_RECORD,&pCTI);
	if(!SUCCEEDED(hres)) MessageBox(0,"CreateTypeInfo failed", "err", MB_OK);
	/* unsigned short wCode */
	memset(&vdesc, 0, sizeof(vdesc));
	vdesc.memid = 0x40000000;
	vdesc.elemdescVar.tdesc.vt = VT_UI2;
	hres = pCTI->lpVtbl->AddVarDesc(pCTI,0,&vdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddVarDesc failed", "err", MB_OK);
	pCTI->lpVtbl->SetVarName(pCTI,0,L"wCode");

	/* unsigned short wReserved */
	memset(&vdesc, 0, sizeof(vdesc));
	vdesc.memid = 0x40000001;
	vdesc.elemdescVar.tdesc.vt = VT_UI2;
	hres = pCTI->lpVtbl->AddVarDesc(pCTI,1,&vdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddVarDesc failed", "err", MB_OK);
	pCTI->lpVtbl->SetVarName(pCTI,1,L"wReserved");
	
	/* BSTR bstrSource */
	memset(&vdesc, 0, sizeof(vdesc));
	vdesc.memid = 0x40000002;
	vdesc.elemdescVar.tdesc.vt = VT_BSTR;
	hres = pCTI->lpVtbl->AddVarDesc(pCTI,2,&vdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddVarDesc failed", "err", MB_OK);
	pCTI->lpVtbl->SetVarName(pCTI,2,L"bstrSource");
	
	/* BSTR bstrDescription */
	memset(&vdesc, 0, sizeof(vdesc));
	vdesc.memid = 0x40000003;
	vdesc.elemdescVar.tdesc.vt = VT_BSTR;
	hres = pCTI->lpVtbl->AddVarDesc(pCTI,3,&vdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddVarDesc failed", "err", MB_OK);
	pCTI->lpVtbl->SetVarName(pCTI,3,L"bstrDescription");
	
	/* BSTR bstrHelpFile */
	memset(&vdesc, 0, sizeof(vdesc));
	vdesc.memid = 0x40000004;
	vdesc.elemdescVar.tdesc.vt = VT_BSTR;
	hres = pCTI->lpVtbl->AddVarDesc(pCTI,4,&vdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddVarDesc failed", "err", MB_OK);
	pCTI->lpVtbl->SetVarName(pCTI,4,L"bstrHelpFile");
	
	/* unsigned long dwHelpContext */
	memset(&vdesc, 0, sizeof(vdesc));
	vdesc.memid = 0x40000005;
	vdesc.elemdescVar.tdesc.vt = VT_UI4;
	hres = pCTI->lpVtbl->AddVarDesc(pCTI,5,&vdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddVarDesc failed", "err", MB_OK);
	pCTI->lpVtbl->SetVarName(pCTI,5,L"dwHelpContext");

	/* void *pvReserved */
	memset(&vdesc, 0, sizeof(vdesc));
	memset(&tdesc, 0, sizeof(tdesc));
	vdesc.memid = 0x40000006;
	vdesc.elemdescVar.tdesc.vt = VT_PTR;
	vdesc.elemdescVar.tdesc.lptdesc = &tdesc;
	vdesc.elemdescVar.tdesc.lptdesc->vt = VT_VOID;
	hres = pCTI->lpVtbl->AddVarDesc(pCTI,6,&vdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddVarDesc failed", "err", MB_OK);
	pCTI->lpVtbl->SetVarName(pCTI,6,L"pvReserved");

	/* void *pvDeferredFillIn */
	memset(&vdesc, 0, sizeof(vdesc));
	memset(&tdesc, 0, sizeof(tdesc));
	vdesc.memid = 0x40000007;
	vdesc.elemdescVar.tdesc.vt = VT_PTR;
	vdesc.elemdescVar.tdesc.lptdesc = &tdesc;
	vdesc.elemdescVar.tdesc.lptdesc->vt = VT_VOID;
	hres = pCTI->lpVtbl->AddVarDesc(pCTI,7,&vdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddVarDesc failed", "err", MB_OK);
	pCTI->lpVtbl->SetVarName(pCTI,7,L"pvDeferredFillIn");

	/* SCODE scode */
	memset(&vdesc, 0, sizeof(vdesc));
	vdesc.memid = 0x40000008;
	vdesc.elemdescVar.tdesc.vt = VT_ERROR;
	hres = pCTI->lpVtbl->AddVarDesc(pCTI,8,&vdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddVarDesc failed", "err", MB_OK);
	pCTI->lpVtbl->SetVarName(pCTI,8,L"scode");

	pCTI->lpVtbl->LayOut(pCTI);
	pCTI->lpVtbl->QueryInterface(pCTI,&IID_ITypeInfo,(void**)&pEXCEPINFOTI);
	pCTI->lpVtbl->Release(pCTI);


	/* IUnknown */
	hres = pCTL->lpVtbl->CreateTypeInfo(pCTL, L"IUnknown",TKIND_INTERFACE,&pCTI);
	if(!SUCCEEDED(hres)) MessageBox(0,"CreateTypeInfo failed", "err", MB_OK);
	hres = pCTI->lpVtbl->SetGuid(pCTI,&IID_IUnknown);
	if(!SUCCEEDED(hres)) MessageBox(0,"SetGuid failed", "err", MB_OK);

	/* [restricted] HRESULT _stdcall QueryInterface([in] GUID *riid,
													[out] void **ppvObj) */

	hres = pCTI->lpVtbl->AddRefTypeInfo(pCTI,pGUIDTI, &hrefGUID);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddRefTypeInfo failed", "err", MB_OK);
	memset(&fdesc, 0, sizeof(fdesc));
	memset(&edesc, 0, sizeof(edesc));
	memset(&tdesc, 0, sizeof(tdesc));
	memset(&tdesc2, 0, sizeof(tdesc2));
	memset(&tdesc3, 0, sizeof(tdesc3));
	fdesc.memid = 0x60000000;
	fdesc.funckind = FUNC_PUREVIRTUAL;
	fdesc.invkind = INVOKE_FUNC;
	fdesc.callconv = CC_STDCALL;
	fdesc.cParams = 2;
	fdesc.cParamsOpt = 0;
	fdesc.oVft = 0;
	fdesc.wFuncFlags = FUNCFLAG_FRESTRICTED;
	fdesc.elemdescFunc.tdesc.vt = VT_HRESULT;
	fdesc.lprgelemdescParam = &edesc[0];
	fdesc.lprgelemdescParam[0].tdesc.vt = VT_PTR;
	fdesc.lprgelemdescParam[0].tdesc.lptdesc = &tdesc;
	fdesc.lprgelemdescParam[0].tdesc.lptdesc->vt = VT_USERDEFINED;
	fdesc.lprgelemdescParam[0].tdesc.lptdesc->hreftype = hrefGUID;
	fdesc.lprgelemdescParam[0].idldesc.wIDLFlags = IDLFLAG_FIN;
	fdesc.lprgelemdescParam[1].tdesc.vt = VT_PTR;
	fdesc.lprgelemdescParam[1].tdesc.lptdesc = &tdesc2;
	fdesc.lprgelemdescParam[1].tdesc.lptdesc->vt = VT_PTR;
	fdesc.lprgelemdescParam[1].tdesc.lptdesc->lptdesc = &tdesc3;
	fdesc.lprgelemdescParam[1].tdesc.lptdesc->lptdesc->vt = VT_VOID;
	fdesc.lprgelemdescParam[1].idldesc.wIDLFlags = IDLFLAG_FOUT;
	pCTI->lpVtbl->AddFuncDesc(pCTI,0,&fdesc);
	olestr[0] = L"QueryInterface";
	olestr[1] = L"riid";
	olestr[2] = L"ppvObj";
	pCTI->lpVtbl->SetFuncAndParamNames(pCTI,0,olestr,3);

	/* [restricted] unsigned long _stdcall AddRef() */
	fdesc.memid++;
	fdesc.cParams = 0;
	fdesc.oVft = 0;
	fdesc.elemdescFunc.tdesc.vt = VT_UI4;
	fdesc.lprgelemdescParam = NULL;
	hres = pCTI->lpVtbl->AddFuncDesc(pCTI,1,&fdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddFuncDesc failed", "err", MB_OK);
	olestr[0] = L"AddRef";
	olestr[1] = 0;
	hres = pCTI->lpVtbl->SetFuncAndParamNames(pCTI,1,olestr,1);

	/* [restricted] unsigned long _stdcall Release() */
	fdesc.memid++;
	fdesc.cParams = 0;
	fdesc.oVft = 0;
	fdesc.elemdescFunc.tdesc.vt = VT_UI4;
	fdesc.lprgelemdescParam = NULL;
	hres = pCTI->lpVtbl->AddFuncDesc(pCTI,2,&fdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddFuncDesc failed", "err", MB_OK);
	olestr[0] = L"Release";
	hres = pCTI->lpVtbl->SetFuncAndParamNames(pCTI,2,olestr,1);
	if(!SUCCEEDED(hres)) MessageBox(0,"SetFuncAndParamNames failed", "err", MB_OK);

	hres = pCTI->lpVtbl->LayOut(pCTI);
	if(!SUCCEEDED(hres)) {sprintf(buf, "Layout failed %08lx", hres); MessageBox(0, buf, "err", MB_OK);}
	hres = pCTI->lpVtbl->QueryInterface(pCTI,&IID_ITypeInfo,(void**)&pIUnknownTI);
	if(!SUCCEEDED(hres)) MessageBox(0,"QI failed", "err", MB_OK);
	pCTI->lpVtbl->Release(pCTI);


	/* interface IDispatch : IUnknown */
	pCTL->lpVtbl->CreateTypeInfo(pCTL, L"IDispatch",TKIND_INTERFACE,&pCTI);
	pCTI->lpVtbl->SetGuid(pCTI,&IID_IDispatch);
	pCTI->lpVtbl->AddRefTypeInfo(pCTI,pIUnknownTI, &hrefIUnknown);
	pCTI->lpVtbl->AddRefTypeInfo(pCTI,pGUIDTI, &hrefGUID);
	pCTI->lpVtbl->AddRefTypeInfo(pCTI,pDISPPARAMSTI, &hrefDISPPARAMS);
	pCTI->lpVtbl->AddRefTypeInfo(pCTI,pEXCEPINFOTI, &hrefEXCEPINFO);
	hres=pCTI->lpVtbl->AddImplType(pCTI,0,hrefIUnknown);
	sprintf(buf,"AddImplType failed hres = %08lx", hres);
	if(!SUCCEEDED(hres)) MessageBox(0,buf, "err", MB_OK);
	
	/* [restricted] HRESULT _stdcall GetTypeInfoCount([out]unsigned int *pctinfo) */
	fdesc.memid = 0x60010000;
	fdesc.cParams = 1;
	fdesc.oVft = 0;
	fdesc.elemdescFunc.tdesc.vt = VT_HRESULT;
	fdesc.lprgelemdescParam = &edesc[0];
	fdesc.lprgelemdescParam[0].tdesc.vt = VT_PTR;
	fdesc.lprgelemdescParam[0].tdesc.lptdesc = &tdesc;
	fdesc.lprgelemdescParam[0].tdesc.lptdesc->vt = VT_UINT;
	fdesc.lprgelemdescParam[0].idldesc.wIDLFlags = IDLFLAG_FOUT;
	hres=pCTI->lpVtbl->AddFuncDesc(pCTI,0,&fdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddFuncDesc failed", "err", MB_OK);
	olestr[0] = L"GetTypeInfoCount";
	olestr[1] = L"pctinfo";
	hres=pCTI->lpVtbl->SetFuncAndParamNames(pCTI,0,olestr,2);
	if(!SUCCEEDED(hres)) MessageBox(0,"SetNames failed", "err", MB_OK);


	/* [restricted] HRESULT _stdcall GetTypeInfo([in] unsigned int itinfo,
												 [in] unsigned long lcid,
												 [out] void **pptinfo) */
	fdesc.memid++;
	fdesc.cParams = 3;
	fdesc.oVft = 0;
	fdesc.elemdescFunc.tdesc.vt = VT_HRESULT;
	fdesc.lprgelemdescParam = &edesc[0];
	fdesc.lprgelemdescParam[0].tdesc.vt = VT_UINT;
	fdesc.lprgelemdescParam[0].idldesc.wIDLFlags = IDLFLAG_FIN;
	fdesc.lprgelemdescParam[1].tdesc.vt = VT_UI4;
	fdesc.lprgelemdescParam[1].idldesc.wIDLFlags = IDLFLAG_FIN;
	fdesc.lprgelemdescParam[2].tdesc.vt = VT_PTR;
	fdesc.lprgelemdescParam[2].tdesc.lptdesc = &tdesc;
	fdesc.lprgelemdescParam[2].tdesc.lptdesc->vt = VT_PTR;
	fdesc.lprgelemdescParam[2].tdesc.lptdesc->lptdesc = &tdesc2;
	fdesc.lprgelemdescParam[2].tdesc.lptdesc->lptdesc->vt = VT_VOID;
	fdesc.lprgelemdescParam[2].idldesc.wIDLFlags = IDLFLAG_FOUT;
	hres=pCTI->lpVtbl->AddFuncDesc(pCTI,1,&fdesc);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddFuncDesc failed", "err", MB_OK);
	olestr[0] = L"GetTypeInfo";
	olestr[1] = L"itinfo";
	olestr[2] = L"lcid";
	olestr[3] = L"pptinfo";
	hres=pCTI->lpVtbl->SetFuncAndParamNames(pCTI,1,olestr,4);
	if(!SUCCEEDED(hres)) MessageBox(0,"SetNames failed", "err", MB_OK);


	/* [restricted] HRESULT _stdcall GetIDsOfNames([in] GUID *riid,
												   [in] char **rgszNames,
												   [in] unsigned int cNames,
												   [in] unsigned long lcid,
												   [out] long *rgdispid) */
	fdesc.memid++;
	fdesc.cParams = 5;
	fdesc.elemdescFunc.tdesc.vt = VT_HRESULT;
	fdesc.lprgelemdescParam = &edesc[0];
	fdesc.lprgelemdescParam[0].tdesc.vt = VT_PTR;
	fdesc.lprgelemdescParam[0].tdesc.lptdesc = &tdesc;
	fdesc.lprgelemdescParam[0].tdesc.lptdesc->vt = VT_USERDEFINED;
	fdesc.lprgelemdescParam[0].tdesc.lptdesc->hreftype = hrefGUID;
	fdesc.lprgelemdescParam[0].idldesc.wIDLFlags = IDLFLAG_FIN;
	fdesc.lprgelemdescParam[1].tdesc.vt = VT_PTR;
	fdesc.lprgelemdescParam[1].tdesc.lptdesc = &tdesc2;
	fdesc.lprgelemdescParam[1].tdesc.lptdesc->vt = VT_PTR;
	fdesc.lprgelemdescParam[1].tdesc.lptdesc->lptdesc = &tdesc3;
	fdesc.lprgelemdescParam[1].tdesc.lptdesc->lptdesc->vt = VT_I1;;
	fdesc.lprgelemdescParam[1].idldesc.wIDLFlags = IDLFLAG_FIN;
	fdesc.lprgelemdescParam[2].tdesc.vt = VT_UINT;
	fdesc.lprgelemdescParam[2].idldesc.wIDLFlags = IDLFLAG_FIN;
	fdesc.lprgelemdescParam[3].tdesc.vt = VT_UI4;
	fdesc.lprgelemdescParam[3].idldesc.wIDLFlags = IDLFLAG_FIN;
	fdesc.lprgelemdescParam[4].tdesc.vt = VT_PTR;
	fdesc.lprgelemdescParam[4].tdesc.lptdesc = &tdesc4;
	fdesc.lprgelemdescParam[4].tdesc.lptdesc->vt = VT_I4;
	fdesc.lprgelemdescParam[4].idldesc.wIDLFlags = IDLFLAG_FOUT;
	pCTI->lpVtbl->AddFuncDesc(pCTI,2,&fdesc);
	olestr[0] = L"GetIDsOfNames";
	olestr[1] = L"riid";
	olestr[2] = L"rgszNames";
	olestr[3] = L"cNames";
	olestr[4] = L"lcid";
	olestr[5] = L"rgdispid";
	pCTI->lpVtbl->SetFuncAndParamNames(pCTI,2,olestr,6);

	/* [restricted] HRESULT _stdcall Invoke([in] long dispidMember,
											[in] GUID* riid, 
											[in] unsigned long lcid, 
											[in] unsigned short wFlags, 
											[in] DISPPARAMS* pdispparams, 
											[out] VARIANT* pvarResult, 
											[out] EXCEPINFO* pexcepinfo, 
											[out] unsigned int* puArgErr); */

	fdesc.memid++;
	fdesc.cParams = 8;
	fdesc.elemdescFunc.tdesc.vt = VT_HRESULT;
	fdesc.lprgelemdescParam = &edesc[0];
	fdesc.lprgelemdescParam[0].tdesc.vt = VT_I4;
	fdesc.lprgelemdescParam[0].idldesc.wIDLFlags = IDLFLAG_FIN;
	fdesc.lprgelemdescParam[1].tdesc.vt = VT_PTR;
	fdesc.lprgelemdescParam[1].tdesc.lptdesc = &tdesc;
	fdesc.lprgelemdescParam[1].tdesc.lptdesc->vt = VT_USERDEFINED;
	fdesc.lprgelemdescParam[1].tdesc.lptdesc->hreftype = hrefGUID;
	fdesc.lprgelemdescParam[1].idldesc.wIDLFlags = IDLFLAG_FIN;
	fdesc.lprgelemdescParam[2].tdesc.vt = VT_UI4;
	fdesc.lprgelemdescParam[2].idldesc.wIDLFlags = IDLFLAG_FIN;
	fdesc.lprgelemdescParam[3].tdesc.vt = VT_UI2;
	fdesc.lprgelemdescParam[3].idldesc.wIDLFlags = IDLFLAG_FIN;
	fdesc.lprgelemdescParam[4].tdesc.vt = VT_PTR;
	fdesc.lprgelemdescParam[4].tdesc.lptdesc = &tdesc2;
	fdesc.lprgelemdescParam[4].tdesc.lptdesc->vt = VT_USERDEFINED;
	fdesc.lprgelemdescParam[4].tdesc.lptdesc->hreftype = hrefDISPPARAMS;
	fdesc.lprgelemdescParam[4].idldesc.wIDLFlags = IDLFLAG_FIN;
	fdesc.lprgelemdescParam[5].tdesc.vt = VT_PTR;
	fdesc.lprgelemdescParam[5].tdesc.lptdesc = &tdesc3;
	fdesc.lprgelemdescParam[5].tdesc.lptdesc->vt = VT_VARIANT;
	fdesc.lprgelemdescParam[5].idldesc.wIDLFlags = IDLFLAG_FOUT;
	fdesc.lprgelemdescParam[6].tdesc.vt = VT_PTR;
	fdesc.lprgelemdescParam[6].tdesc.lptdesc = &tdesc4;
	fdesc.lprgelemdescParam[6].tdesc.lptdesc->vt = VT_USERDEFINED;
	fdesc.lprgelemdescParam[6].tdesc.lptdesc->hreftype = hrefEXCEPINFO;
	fdesc.lprgelemdescParam[6].idldesc.wIDLFlags = IDLFLAG_FOUT;
	fdesc.lprgelemdescParam[7].tdesc.vt = VT_PTR;
	fdesc.lprgelemdescParam[7].tdesc.lptdesc = &tdesc5;
	fdesc.lprgelemdescParam[7].tdesc.lptdesc->vt = VT_UINT;
	fdesc.lprgelemdescParam[7].idldesc.wIDLFlags = IDLFLAG_FOUT;
	pCTI->lpVtbl->AddFuncDesc(pCTI,3,&fdesc);
	olestr[0] = L"Invoke";
	olestr[1] = L"dispidMember";
	olestr[2] = L"riid";
	olestr[3] = L"lcid";
	olestr[4] = L"wFlags";
	olestr[5] = L"pdispparams";
	olestr[6] = L"pvarResult";
	olestr[7] = L"pexcepinfo";
	olestr[8] = L"puArgErr";
	pCTI->lpVtbl->SetFuncAndParamNames(pCTI,3,olestr,9);


	hres=pCTI->lpVtbl->LayOut(pCTI);
	if(!SUCCEEDED(hres)) MessageBox(0,"Layout failed", "err", MB_OK);
	pCTI->lpVtbl->Release(pCTI);


	
	/* interface IEnumVARIANT : IUnknown */
	pCTL->lpVtbl->CreateTypeInfo(pCTL, L"IEnumVARIANT",TKIND_INTERFACE,&pCTI);
	pCTI->lpVtbl->SetGuid(pCTI,&IID_IEnumVARIANT);
	pCTI->lpVtbl->AddRefTypeInfo(pCTI,pIUnknownTI, &hrefIUnknown);
	hres = pCTI->lpVtbl->AddImplType(pCTI,0,hrefIUnknown);
	if(!SUCCEEDED(hres)) MessageBox(0,"AddImplType failed", "err", MB_OK);

    /* HRESULT _stdcall Next([in] unsigned long celt, 
							 [in] VARIANT* rgvar, 
							 [out] unsigned long* pceltFetched) */
	fdesc.memid = 0x60010000;
	fdesc.wFuncFlags = 0;
	fdesc.cParams = 3;
	fdesc.elemdescFunc.tdesc.vt = VT_HRESULT;
	fdesc.lprgelemdescParam = &edesc[0];
	fdesc.lprgelemdescParam[0].tdesc.vt = VT_UI4;
	fdesc.lprgelemdescParam[0].idldesc.wIDLFlags = IDLFLAG_FIN;
	fdesc.lprgelemdescParam[1].tdesc.vt = VT_PTR;
	fdesc.lprgelemdescParam[1].tdesc.lptdesc = &tdesc;
	fdesc.lprgelemdescParam[1].tdesc.lptdesc->vt = VT_VARIANT;
	fdesc.lprgelemdescParam[1].idldesc.wIDLFlags = IDLFLAG_FIN;
	fdesc.lprgelemdescParam[2].tdesc.vt = VT_PTR;
	fdesc.lprgelemdescParam[2].tdesc.lptdesc = &tdesc2;
	fdesc.lprgelemdescParam[2].tdesc.lptdesc->vt = VT_UI4;
	fdesc.lprgelemdescParam[2].idldesc.wIDLFlags = IDLFLAG_FOUT;
	pCTI->lpVtbl->AddFuncDesc(pCTI,0,&fdesc);
	olestr[0] = L"Next";
	olestr[1] = L"celt";
	olestr[2] = L"rgvar";
	olestr[3] = L"pceltFetched";
	pCTI->lpVtbl->SetFuncAndParamNames(pCTI,0,olestr,4);

	/* HRESULT _stdcall Skip([in] unsigned long celt) */
	fdesc.memid++;
	fdesc.cParams = 1;
	fdesc.elemdescFunc.tdesc.vt = VT_HRESULT;
	fdesc.lprgelemdescParam = &edesc[0];
	fdesc.lprgelemdescParam[0].tdesc.vt = VT_UI4;
	fdesc.lprgelemdescParam[0].idldesc.wIDLFlags = IDLFLAG_FIN;
	pCTI->lpVtbl->AddFuncDesc(pCTI,1,&fdesc);
	olestr[0] = L"Skip";
	olestr[1] = L"celt";
	pCTI->lpVtbl->SetFuncAndParamNames(pCTI,1,olestr,2);

	/* HRESULT _stdcall Reset() */
	fdesc.memid++;
	fdesc.cParams = 0;
	fdesc.elemdescFunc.tdesc.vt = VT_HRESULT;
	fdesc.lprgelemdescParam = NULL;
	pCTI->lpVtbl->AddFuncDesc(pCTI,2,&fdesc);
	olestr[0] = L"Reset";
	pCTI->lpVtbl->SetFuncAndParamNames(pCTI,2,olestr,1);

	/* HRESULT _stdcall Clone([out] IEnumVARIANT** ppenum) */
	hres=pCTI->lpVtbl->QueryInterface(pCTI,&IID_ITypeInfo,(void**)&pIEnumVARIANTTI);
	hres=pCTI->lpVtbl->AddRefTypeInfo(pCTI,pIEnumVARIANTTI,&hrefIEnumVARIANT);
	fdesc.memid++;
	fdesc.cParams = 1;
	fdesc.elemdescFunc.tdesc.vt = VT_HRESULT;
	fdesc.lprgelemdescParam = &edesc[0];
	fdesc.lprgelemdescParam[0].tdesc.vt = VT_PTR;
	fdesc.lprgelemdescParam[0].tdesc.lptdesc = &tdesc;
	fdesc.lprgelemdescParam[0].tdesc.lptdesc->vt = VT_PTR;
	fdesc.lprgelemdescParam[0].tdesc.lptdesc->lptdesc = &tdesc2;
	fdesc.lprgelemdescParam[0].tdesc.lptdesc->lptdesc->vt = VT_USERDEFINED;
	fdesc.lprgelemdescParam[0].tdesc.lptdesc->lptdesc->hreftype = hrefIEnumVARIANT;
	fdesc.lprgelemdescParam[0].idldesc.wIDLFlags = IDLFLAG_FOUT;
	pCTI->lpVtbl->AddFuncDesc(pCTI,3,&fdesc);
	olestr[0] = L"Clone";
	olestr[1] = L"ppenum";
	pCTI->lpVtbl->SetFuncAndParamNames(pCTI,3,olestr,2);
	
	hres=pCTI->lpVtbl->LayOut(pCTI);
	if(!SUCCEEDED(hres)) MessageBox(0,"Layout failed", "err", MB_OK);
	pCTI->lpVtbl->Release(pCTI);

	/* save */
	pIUnknownTI->lpVtbl->Release(pIUnknownTI);
	pGUIDTI->lpVtbl->Release(pGUIDTI);
	pDISPPARAMSTI->lpVtbl->Release(pDISPPARAMSTI);
	pEXCEPINFOTI->lpVtbl->Release(pEXCEPINFOTI);
	hres=pCTL->lpVtbl->SaveAllChanges(pCTL);
	if(!SUCCEEDED(hres)) MessageBox(0,"SaveAllChanges failed", "err", MB_OK);
	return 0;
}


More information about the wine-devel mailing list