static void get_interfacename( IUnknown *punk, VARIANT *vres ) { HRESULT hr; IDispatch *pDisp; ITypeInfo *pTI; BSTR bstr = NULL; hr = punk->QueryInterface( IID_IDispatch, (void **)&pDisp ); if ( SUCCEEDED(hr) && pDisp != NULL ) { hr = pDisp->GetTypeInfo( 0, LOCALE_USER_DEFAULT, &pTI ); if ( SUCCEEDED(hr) && pTI != NULL ) { hr = pTI->GetDocumentation( MEMBERID_NIL, &bstr, NULL, NULL, NULL ); pTI->Release(); } pDisp->Release(); } if ( bstr == NULL ) { bstr = SysAllocString( L"" ); } vres->bstrVal = bstr; vres->vt = VT_BSTR; }
// @pymethod |PyICreateTypeInfo|AddRefTypeInfo|Description of AddRefTypeInfo. PyObject *PyICreateTypeInfo::AddRefTypeInfo(PyObject *self, PyObject *args) { ICreateTypeInfo *pICTI = GetI(self); if ( pICTI == NULL ) return NULL; // @pyparm <o PyITypeInfo>|pTInfo||Description for pTInfo PyObject *obpTInfo; ITypeInfo * pTInfo; if ( !PyArg_ParseTuple(args, "O:AddRefTypeInfo", &obpTInfo) ) return NULL; BOOL bPythonIsHappy = TRUE; if (!PyCom_InterfaceFromPyInstanceOrObject(obpTInfo, IID_ITypeInfo, (void **)&pTInfo, TRUE /* bNoneOK */)) bPythonIsHappy = FALSE; if (!bPythonIsHappy) return NULL; HRESULT hr; HREFTYPE hRefType; PY_INTERFACE_PRECALL; hr = pICTI->AddRefTypeInfo( pTInfo, &hRefType ); if (pTInfo) pTInfo->Release(); PY_INTERFACE_POSTCALL; if ( FAILED(hr) ) return PyCom_BuildPyException(hr, pICTI, IID_ICreateTypeInfo); return PyInt_FromLong(hRefType); }
STDMETHODIMP CMediaPosition::Invoke( DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo, UINT * puArgErr) { // this parameter is a dead leftover from an earlier interface if (IID_NULL != riid) { return DISP_E_UNKNOWNINTERFACE; } ITypeInfo * pti; HRESULT hr = GetTypeInfo(0, lcid, &pti); if (FAILED(hr)) { return hr; } hr = pti->Invoke( (IMediaPosition *)this, dispidMember, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr); pti->Release(); return hr; }
static PyObject *PyRecord_reduce(PyObject *self, PyObject *args) { PyObject *ret = NULL; PyRecord *pyrec = (PyRecord *)self; PyObject *obModule = NULL, *obModDict = NULL, *obFunc = NULL; ITypeInfo *pti = NULL; TYPEATTR *pta = NULL; ULONG cb; HRESULT hr; GUID structguid; if (!PyArg_ParseTuple(args, ":reduce")) return NULL; hr = pyrec->pri->GetTypeInfo(&pti); if (FAILED(hr)||pti==NULL) { PyCom_BuildPyException(hr); goto done; } hr = pti->GetTypeAttr(&pta); if (FAILED(hr)||pta==NULL) { PyCom_BuildPyException(hr); goto done; } hr = pyrec->pri->GetGuid(&structguid); if (FAILED(hr)) { PyCom_BuildPyException(hr); goto done; } hr = pyrec->pri->GetSize(&cb); if (FAILED(hr)) { PyCom_BuildPyException(hr); goto done; } obModule = PyImport_ImportModule("pythoncom"); if (obModule) obModDict = PyModule_GetDict(obModule); // no ref added! if (obModDict) obFunc = PyDict_GetItemString(obModDict, "GetRecordFromGuids"); // no ref added! if (!obFunc) { PyErr_Clear(); PyErr_SetString(PyExc_RuntimeError, "pythoncom.GetRecordFromGuids() can't be located!"); goto done; } ret = Py_BuildValue("O(NHHiNN)", obFunc, PyWinObject_FromIID(pta->guid), pta->wMajorVerNum, pta->wMinorVerNum, pta->lcid, PyWinObject_FromIID(structguid), PyString_FromStringAndSize((char *)pyrec->pdata, cb)); done: if (pta&& pti) pti->ReleaseTypeAttr(pta); if (pti) pti->Release(); Py_XDECREF(obModule); // obModDict and obFunc have no new reference. return ret; }
static PyObject* ITypeCompBind( ITypeComp* pTC, OLECHAR* S, unsigned short w ) { ITypeInfo* pI; DESCKIND DK; BINDPTR BP; PyObject* ret; unsigned long hashval = 0; PY_INTERFACE_PRECALL; #ifndef MS_WINCE // appears in the headers for CE, but wont link!? hashval = LHashValOfNameSys(SYS_WIN32,LOCALE_USER_DEFAULT,S); #endif SCODE sc = pTC->Bind(S, hashval,w, &pI, &DK, &BP); PY_INTERFACE_POSTCALL; if (FAILED(sc)) return PyCom_BuildPyException(sc); switch(DK){ case DESCKIND_FUNCDESC: ret = PyObject_FromFUNCDESC(BP.lpfuncdesc); pI->ReleaseFuncDesc(BP.lpfuncdesc); break; case DESCKIND_VARDESC: ret = PyObject_FromVARDESC(BP.lpvardesc); pI->ReleaseVarDesc(BP.lpvardesc); break; case DESCKIND_TYPECOMP: ret = PyCom_PyObjectFromIUnknown(BP.lptcomp, IID_ITypeComp, FALSE); break; case DESCKIND_IMPLICITAPPOBJ: ITypeComp* pTC2; pI->GetTypeComp(&pTC2); ret = PyTuple_New(2); if (ret) { // NOTE: SET_ITEM consumes the refcounts. PyTuple_SET_ITEM( ret, 0, PyObject_FromVARDESC(BP.lpvardesc) ); PyTuple_SET_ITEM( ret, 1, ITypeCompBind(pTC2,S,w) ); } pTC2->Release(); pI->ReleaseVarDesc(BP.lpvardesc); break; case DESCKIND_NONE: default: Py_INCREF(Py_None); ret = Py_None; break; } if (pI) pI->Release(); if (ret == NULL) return NULL; PyObject *real_ret = PyTuple_New(2); if (real_ret==NULL) return NULL; // NOTE: SET_ITEM consumes the refcounts. PyTuple_SET_ITEM(real_ret, 0, PyInt_FromLong(DK) ); PyTuple_SET_ITEM(real_ret, 1, ret ); return real_ret; }
HRESULT PrintTInfo(ITypeInfo* pTinfo, int indentation){ TYPEATTR* pTypeAttr; HRESULT hr = pTinfo->GetTypeAttr(&pTypeAttr); COMRet(hr); for(int inden = 0; inden != indentation; ++inden) std::wcout<<TEXT(" "); LPOLESTR guid_str; hr = StringFromCLSID(pTypeAttr->guid, &guid_str); std::wcout<<guid_str<<std::endl; // Inherited Interfaces, therefore we recursively call PrintInfo for(int i = 0; i != pTypeAttr->cImplTypes; ++i){ HREFTYPE RefType; hr = pTinfo->GetRefTypeOfImplType(i, &RefType); COMRet(hr); ITypeInfo* pImplTinfo; hr = pTinfo->GetRefTypeInfo(RefType, &pImplTinfo); COMRet(hr); hr = PrintTInfo(pImplTinfo, indentation + 1); if(hr != S_OK && hr != TYPE_E_BADMODULEKIND) return hr; // Because this ITypeInfo is retrieved pImplTinfo->Release(); // directly from a .tlb file instead // of a .dll, AddressofMember fails } //member functions for(int i = 0; i != pTypeAttr->cFuncs; ++i){ FUNCDESC* pFuncDesc; hr = pTinfo->GetFuncDesc(i, &pFuncDesc); COMRet(hr); const UINT cMaxNames = 10; UINT cNames; BSTR rgBstrNames[cMaxNames]; hr = pTinfo->GetNames(pFuncDesc->memid, rgBstrNames, cMaxNames, &cNames); COMRet(hr); void* pv; hr = pTinfo->AddressOfMember(pFuncDesc->memid, pFuncDesc->invkind, &pv); if(hr != S_OK && hr != TYPE_E_BADMODULEKIND) return hr; for(int inden = 0; inden != indentation; ++inden) std::wcout<<TEXT(" "); std::wcout<<TEXT("Func memid = ")<<pFuncDesc->memid<<TEXT(" Name = ")<<*rgBstrNames<<TEXT(" DllAddress = ")<<pv<<std::endl; for(int j = 0; j != pFuncDesc->cParams; ++j){ TCHAR szBuffer[30]; wParamFlagsTranslate(pFuncDesc->lprgelemdescParam->paramdesc.wParamFlags, szBuffer, 30); for(int inden = 0; inden != indentation; ++inden) std::wcout<<TEXT(" "); std::wcout<<TEXT(" ")<<szBuffer<<TEXT(" ")<<*(rgBstrNames+j+1)<<TEXT(": ")<<std::endl; TExpandPointer(pFuncDesc->lprgelemdescParam->tdesc, 2); } pTinfo->ReleaseFuncDesc(pFuncDesc); } //member variables for(int i = 0; i != pTypeAttr->cVars; ++i){ VARDESC* pVarDesc; hr = pTinfo->GetVarDesc(i, &pVarDesc); COMRet(hr); for(int inden = 0; inden != indentation; ++inden) std::wcout<<TEXT(" "); std::wcout<<TEXT("Var memid = ")<<pVarDesc->memid<<TEXT("Varkind = ")<<pVarDesc->varkind<<std::endl; TCHAR szBuffer[30]; wParamFlagsTranslate(pVarDesc->elemdescVar.paramdesc.wParamFlags, szBuffer, 30); for(int inden = 0; inden != indentation; ++inden) std::wcout<<TEXT(" "); std::wcout<<" Variable wParamFlags: "<<szBuffer<<std::endl; TExpandPointer(pVarDesc->elemdescVar.tdesc, 1); pTinfo->ReleaseVarDesc(pVarDesc); } pTinfo->ReleaseTypeAttr(pTypeAttr); return hr; }
int _tmain(int argc, _TCHAR* argv[]){ const OLECHAR szFile[] = TEXT("testmidl.tlb");//TEXT("D:\\Desktop\\COM_Type_Library_Viewer\\COM_Type_Library_Viewer\\testmidl.tlb"); ITypeLib* p_tlib; ITypeInfo* pTinfo; HRESULT hr = LoadTypeLib(szFile, &p_tlib); //hr = p_tlib->GetTypeInfoOfGuid(IID_ISum, &pTinfo);//Succeeded //hr = p_tlib->GetTypeInfoOfGuid(LIBID_Component, &pTinfo); hr = p_tlib->GetTypeInfoOfGuid(CLSID_InsideCOM, &pTinfo);//Succeeded!! hr = PrintTInfo(pTinfo, 0); pTinfo->Release(); p_tlib->Release(); std::getchar(); return 1; }
STDMETHODIMP CJServer::GetIDsOfNames(REFIID riid , OLECHAR **rgszNames, UINT cNames, LCID lcid, DISPID *rgDispID) { HRESULT hr; ITypeInfo *pTI; if (IID_NULL!=riid) return ResultFromScode(DISP_E_UNKNOWNINTERFACE); //Get the right ITypeInfo for lcid. hr=GetTypeInfo(0, lcid, &pTI); if (SUCCEEDED(hr)) { hr=DispGetIDsOfNames(pTI, rgszNames, cNames, rgDispID); pTI->Release(); } return hr; }
STDMETHODIMP CJServer::Invoke(DISPID dispID, REFIID riid , LCID lcid, unsigned short wFlags, DISPPARAMS *pDispParams , VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HRESULT hr; ITypeInfo *pTI; LANGID langID=PRIMARYLANGID(lcid); if (IID_NULL!=riid) return DISP_E_UNKNOWNINTERFACE; hr=GetTypeInfo(0, lcid, &pTI); if (FAILED(hr)) return hr; //This is exactly what DispInvoke does--so skip the overhead. hr=pTI->Invoke((SERVERCLASS *)this, dispID, wFlags , pDispParams, pVarResult, pExcepInfo, puArgErr); //Exception handling is done within ITypeInfo::Invoke pTI->Release(); return hr; }
static void get_coclassname( IUnknown *punk, VARIANT *vres ) { HRESULT hr; IProvideClassInfo *pPCI; ITypeInfo *pTI; BSTR bstr = NULL; hr = punk->QueryInterface( IID_IProvideClassInfo, (void **)&pPCI ); if ( SUCCEEDED(hr) && pPCI != NULL ) { hr = pPCI->GetClassInfo( &pTI ); if ( SUCCEEDED(hr) && pTI != NULL ) { hr = pTI->GetDocumentation( MEMBERID_NIL, &bstr, NULL, NULL, NULL ); pTI->Release(); } pPCI->Release(); } if ( bstr == NULL ) { bstr = SysAllocString( L"" ); } vres->bstrVal = bstr; vres->vt = VT_BSTR; }
STDMETHODIMP CBaseDispatch::GetIDsOfNames( REFIID riid, OLECHAR ** rgszNames, UINT cNames, LCID lcid, DISPID * rgdispid) { // although the IDispatch riid is dead, we use this to pass from // the interface implementation class to us the iid we are talking about. ITypeInfo * pti; HRESULT hr = GetTypeInfo(riid, 0, lcid, &pti); if (SUCCEEDED(hr)) { hr = pti->GetIDsOfNames(rgszNames, cNames, rgdispid); pti->Release(); } return hr; }
CJSProxyObj::CJSProxyObj(CJSExtender* _pJSExtender, IDispatch *pDisp, const GUID iid, CString strPrefix) : m_dwCookie(0xFEFEFEFE), m_pDisp(pDisp), m_EventIID(iid) { m_pEventObj = nullptr; ITypeInfo* pTypeInfo = nullptr; m_pJSExtender = _pJSExtender; if (theApp.m_pEventProxy) { m_pEventObj = theApp.m_pEventProxy; theApp.m_pEventProxy = nullptr; } else { pDisp->GetTypeInfo(0, GetUserDefaultLCID(), &pTypeInfo); if (pTypeInfo) { CComPtr<ITypeLib> pTypeLib; UINT nIndex = 0; pTypeInfo->GetContainingTypeLib(&pTypeLib, &nIndex); pTypeLib->GetTypeInfoOfGuid(iid, &m_pTypeInfo); pTypeInfo->Release(); } } CString strName = strPrefix; auto it = m_pJSExtender->m_mapCloudJSObject.find(strName); if (it != m_pJSExtender->m_mapCloudJSObject.end()) { int nSize = m_pJSExtender->m_mapCloudJSObject.size(); CString s = _T(""); s.Format(_T("%s_%d_"), strName, nSize); strName = s; } m_bstrPrefix = CComBSTR(strName); SetEventNames(); m_pJSExtender->m_mapCloudJSObject[strName] = this; HRESULT hr = AtlAdvise(m_pDisp, this, m_EventIID, &m_dwCookie); }
void _AfxUnregisterInterfaces(ITypeLib* pTypeLib) { TCHAR szKey[128]; lstrcpy(szKey, _T("Interface\\")); LPTSTR pszGuid = szKey + lstrlen(szKey); int cTypeInfo = pTypeLib->GetTypeInfoCount(); for (int i = 0; i < cTypeInfo; i++) { TYPEKIND tk; if (SUCCEEDED(pTypeLib->GetTypeInfoType(i, &tk)) && (tk == TKIND_DISPATCH || tk == TKIND_INTERFACE)) { ITypeInfo* pTypeInfo = NULL; if (SUCCEEDED(pTypeLib->GetTypeInfo(i, &pTypeInfo))) { TYPEATTR* pTypeAttr; if (SUCCEEDED(pTypeInfo->GetTypeAttr(&pTypeAttr))) { #if defined(_UNICODE) || defined(OLE2ANSI) StringFromGUID2(pTypeAttr->guid, pszGuid, GUID_CCH); #else WCHAR wszGuid[39]; StringFromGUID2(pTypeAttr->guid, wszGuid, GUID_CCH); _wcstombsz(pszGuid, wszGuid, GUID_CCH); #endif _AfxRecursiveRegDeleteKey(HKEY_CLASSES_ROOT, szKey); pTypeInfo->ReleaseTypeAttr(pTypeAttr); } pTypeInfo->Release(); } } } }
ITypeInfo *tCOMUtil::GetDefaultInterfaceTypeInfo(ITypeInfo* pCoClassinfo, bool source) { ITypeInfo* typeinfo = NULL; //Use this to determine success TYPEATTR* pTA = NULL; HRESULT hr = S_OK; if (SUCCEEDED(pCoClassinfo->GetTypeAttr(&pTA))) { UINT i = 0; int iFlags = 0; for (i=0; i < pTA->cImplTypes; i++) { //Get the implementation type for this interface hr = pCoClassinfo->GetImplTypeFlags(i, &iFlags); if (FAILED(hr)) continue; if (iFlags & IMPLTYPEFLAG_FDEFAULT || pTA->cImplTypes == 1) { if(source == false && !(iFlags & IMPLTYPEFLAG_FSOURCE) || source == true && (iFlags & IMPLTYPEFLAG_FSOURCE)) { HREFTYPE hRefType=NULL; /* * This is the interface we want. Get a handle to * the type description from which we can then get * the ITypeInfo. */ pCoClassinfo->GetRefTypeOfImplType(i, &hRefType); hr = pCoClassinfo->GetRefTypeInfo(hRefType, &typeinfo); // gets typeattr info TYPEATTR *ptypeattr = NULL; GUID guid; TYPEKIND typekind; hr = typeinfo->GetTypeAttr(&ptypeattr); if(FAILED(hr)) { typeinfo->Release(); typeinfo = NULL; break; } guid = ptypeattr->guid; typekind = ptypeattr->typekind; typeinfo->ReleaseTypeAttr(ptypeattr); if(typekind == TKIND_DISPATCH) { // found! break; } } } } pCoClassinfo->ReleaseTypeAttr(pTA); } return typeinfo; }
bool tLuaCOM::getFUNCDESC(const char *name, FuncInfo& funcinfo) { // First, tries to see we have the FUNCDESC's cached long counter = 0; for(counter = 0; counter < MAX_FUNCINFOS; counter++) { // when .name is NULL, there is no further information if(pFuncInfo[counter].name == NULL) break; if(strcmp(name, pFuncInfo[counter].name) == 0) break; } // checks whether funcinfo was found if(counter < MAX_FUNCINFOS && pFuncInfo[counter].name != NULL) { funcinfo = pFuncInfo[counter]; return true; } // did not find, so gets type information through // ITypeComp HRESULT hr = S_OK; BINDPTR bindptr; DESCKIND desckind; BSTR wName; ITypeInfo *info = NULL; unsigned int dumb = 0; wName = tUtil::string2bstr(name); unsigned long lhashval = LHashValOfName(LOCALE_SYSTEM_DEFAULT, wName); hr = ptcomp->Bind(wName, lhashval, INVOKE_PROPERTYGET, &info, &desckind, &bindptr); if(FAILED(hr) || desckind == DESCKIND_NONE) funcinfo.propget = NULL; else { funcinfo.propget = bindptr.lpfuncdesc; info->Release(); } hr = ptcomp->Bind(wName, lhashval, INVOKE_FUNC, &info, &desckind, &bindptr); if(FAILED(hr) || desckind == DESCKIND_NONE) funcinfo.func = NULL; else { funcinfo.func = bindptr.lpfuncdesc; info->Release(); } hr = ptcomp->Bind(wName, lhashval, INVOKE_PROPERTYPUT, &info, &desckind, &bindptr); if(FAILED(hr) || desckind == DESCKIND_NONE) funcinfo.propput = NULL; else { funcinfo.propput = bindptr.lpfuncdesc; info->Release(); } // if there is not propertyput, then tries propputref if(funcinfo.propput == NULL) { hr = ptcomp->Bind(wName, lhashval, INVOKE_PROPERTYPUTREF, &info, &desckind, &bindptr); if(FAILED(hr) || desckind == DESCKIND_NONE) funcinfo.propput = NULL; else { funcinfo.propput = bindptr.lpfuncdesc; info->Release(); } } SysFreeString(wName); // If no type information found, returns NULL if(!funcinfo.propget && !funcinfo.propput && !funcinfo.func) return false; else if(counter < MAX_FUNCINFOS) { CHECKPRECOND(pFuncInfo[counter].name == NULL); pFuncInfo[counter].name = tUtil::strdup(name); pFuncInfo[counter].propget = funcinfo.propget; pFuncInfo[counter].propput = funcinfo.propput; pFuncInfo[counter].func = funcinfo.func; return true; } else return true; }
IDispatch* CItemHolder::GetDispatch(IActiveScriptSite* pSite, LPOLESTR pstrName, bool fSameApt) { IDispatchEx* pDispEx = m_pDispEx; IDispatch* pDisp = m_pDisp; ATLTRACE(_("CItemHolder::GetDispatch in Thread:%08X name=%ls sameptr=%d\n"), GetCurrentThreadId(), pstrName, fSameApt); #ifdef __IRubyWrapper_INTERFACE_DEFINED__ if (fSameApt) { #endif if (pDisp == NULL && pDispEx == NULL) { ATLTRACE(_("CItemHolder::GetDispatch in Thread:%08X\n"), GetCurrentThreadId()); IUnknown* pUnk = NULL; ITypeInfo* pTypeInfo = NULL; HRESULT hr = pSite->GetItemInfo(pstrName, SCRIPTINFO_IUNKNOWN, &pUnk, &pTypeInfo); if (hr == S_OK) { if (pTypeInfo) pTypeInfo->Release(); if (pUnk->QueryInterface(IID_IDispatchEx, (void**)&pDispEx) == S_OK) { #ifdef __IRubyWrapper_INTERFACE_DEFINED__ HRESULT hr = m_pGIPDispEx.Globalize(pDispEx); ATLTRACE(_T("Globalize Item = %08X\n"), hr); #endif m_pDispEx = pDispEx; } else { pDispEx = NULL; if (pUnk->QueryInterface(IID_IDispatch, (void**)&pDisp) == S_OK) { #ifdef __IRubyWrapper_INTERFACE_DEFINED__ HRESULT hr = m_pGIPDisp.Globalize(pDisp); ATLTRACE(_T("Globalize Item = %08X\n"), hr); #endif m_pDisp = pDisp; } } pUnk->Release(); } } if (pDispEx) { pDispEx->AddRef(); } else if (pDisp) { pDisp->AddRef(); } #ifdef __IRubyWrapper_INTERFACE_DEFINED__ } else { if (m_pGIPDisp.IsOK() == false && m_pGIPDispEx.IsOK() == false) { ATLTRACE(_("CItemHolder::GetDispatch in Thread:%08X\n"), GetCurrentThreadId()); IUnknown* pUnk = NULL; ITypeInfo* pTypeInfo = NULL; HRESULT hr = pSite->GetItemInfo(pstrName, SCRIPTINFO_IUNKNOWN, &pUnk, &pTypeInfo); if (hr == S_OK) { if (pTypeInfo) pTypeInfo->Release(); if (pUnk->QueryInterface(IID_IDispatchEx, (void**)&pDispEx) != S_OK) { pDispEx = NULL; if (pUnk->QueryInterface(IID_IDispatch, (void**)&pDisp) != S_OK) { pDisp = NULL; } } pUnk->Release(); } } if (m_pGIPDispEx.IsOK()) { IDispatchEx* p; HRESULT hr = m_pGIPDispEx.Localize(&p); ATLTRACE(_("Localize DispEx = %08X\n"), hr); return p; } if (m_pGIPDisp.IsOK()) { IDispatch* p; HRESULT hr = m_pGIPDisp.Localize(&p); ATLTRACE(_("Localize Disp = %08X\n"), hr); return p; } } #endif return (pDispEx) ? pDispEx : pDisp; }
STDMETHODIMP ESource::InitEvent(IDispatch *SourceDispatch, OrxScript *ORexxScript, FILE *LogFile) { ITypeInfo *SourceType; TYPEATTR *TypeAttributes; BSTR SourceName; unsigned int NameCount; int i; FUNCDESC *FuncDesc; char DispIDName[29]; PEMAP NewMap; HRESULT RetCode=S_OK; int EMCount; FPRINTF2(LogFile,"created a new Event Source. %p\n",this); FPRINTF2(DLLlogfile,"created a new Event Source.%p\n",this); EventType = AddScriptlet; Source = SourceDispatch; // Mimick the ParseProcedures "THIS" parameter by returning this pointer. Engine = ORexxScript; Connected = false; ConnectionPoint = NULL; Container = NULL; logfile = LogFile; RetCode = GetTypeInfo(&SourceType); if (SUCCEEDED(RetCode)) { RetCode = SourceType->GetTypeAttr(&TypeAttributes); memcpy(&SourceGUID,&TypeAttributes->guid,sizeof(GUID)); EMCount = TypeAttributes->cFuncs; SourceType->ReleaseTypeAttr(TypeAttributes); OLECHAR lGUID[50]; StringFromGUID2(SourceGUID,lGUID,sizeof(lGUID)); FPRINTF2(logfile,"The GUID is %S and there are %d functions.\n",lGUID,EMCount); /* For each entry in the type library, create an entry on the Event Map chain. * This is a many to one relation. Each of the different Source Disp ID's * will translate to the same Sink Disp ID. There is only one chunk of code * being bound to this Event that the Type Library is describing. So every * Source call must map to the same Sink. */ for (i=0; i<EMCount; i++) { SourceType->GetFuncDesc(i, &FuncDesc); // Despite what the documentation says, this returns Max Names, not Max Names - 1. // The first name is the function name, the remainder if they exist are parameters. SourceType->GetNames(FuncDesc->memid, &SourceName, 1, &NameCount); sprintf(DispIDName,"%d",FuncDesc->memid); // This creates the entry for the function with an invalid DispID to call. RetCode = AddMap(DispIDName,&NewMap); if (FAILED(RetCode)) return RetCode; FPRINTF2(logfile,"ESource::InitEvent - AddScriptlet \"%S\" \n",SourceName); NewMap->SourceEventName = SourceName; SourceType->ReleaseFuncDesc(FuncDesc); } SourceType->Release(); } else { FPRINTF2(logfile,"Could not obtain TypInfo for this event! HRESULT %08x\n",RetCode); } return RetCode; }
bool VariantInputFilter::getNext( ElementType& type, types::VariantConst& element) { AGAIN: VARIANT data; data.vt = VT_EMPTY; VARDESC* vardesc = 0; ITypeInfo* reftypeinfo = 0; try { if (m_stk.empty()) { if (!m_done) { element = types::VariantConst(); type = CloseTag; m_done = true; return true; } return false; } StackElem& cur = m_stk.back(); //< REMARK: 'cur' only valid till next m_stk.push_back()/pop_back(). Check that push/pop return or goto AGAIN ! switch (cur.state) { case VarOpen: { if ((cur.data.vt & VT_ARRAY) == VT_ARRAY) { if (1 != cur.data.parray->cDims) { throw std::runtime_error( "cannont handle multi dimensional arrays"); } if (cur.idx >= cur.data.parray->rgsabound->cElements) { m_stk.pop_back(); goto AGAIN; } cur.state = VarClose; if (((int)m_flags & serialize::Flags::SerializeWithIndices) != 0 || cur.name.empty()) { element = types::VariantConst( cur.idx+1); } else { element = types::VariantConst( m_elembuf = cur.name); } type = OpenTag; LONG idx = cur.idx++; VARTYPE elemvt = cur.data.vt - VT_ARRAY; if (comauto::isAtomicType( elemvt)) { data.vt = elemvt; WRAP( ::SafeArrayGetElement( cur.data.parray, &idx, const_cast<void*>(comauto::arithmeticTypeAddress( &data)))); cur.state = VarClose; m_stk.push_back( StackElem( "", 0, 0, data)); std::memset( &data, 0, sizeof(data)); data.vt = VT_EMPTY; } else if (comauto::isStringType( elemvt)) { std::memset( &data, 0, sizeof(data)); data.vt = elemvt; switch (elemvt) { case VT_LPSTR: WRAP( ::SafeArrayGetElement( cur.data.parray, &idx, &V_LPSTR( const_cast<VARIANT*>(&data)))); break; case VT_LPWSTR: WRAP( ::SafeArrayGetElement( cur.data.parray, &idx, &V_LPWSTR( const_cast<VARIANT*>(&data)))); break; case VT_BSTR: WRAP( ::SafeArrayGetElement( cur.data.parray, &idx, V_BSTR( const_cast<VARIANT*>(&data)))); break; default: throw std::logic_error("internal: unknown string type"); } cur.state = VarClose; m_stk.push_back( StackElem( "", 0, 0, data)); std::memset( &data, 0, sizeof(data)); data.vt = VT_EMPTY; } else if (elemvt == VT_RECORD) { std::memset( &data, 0, sizeof(data)); data.vt = elemvt; WRAP( ::SafeArrayGetRecordInfo( cur.data.parray, &data.pRecInfo)); if (!data.pRecInfo) throw std::runtime_error( "cannot iterate on result structure without record info"); data.pvRecord = data.pRecInfo->RecordCreate(); WRAP( ::SafeArrayGetElement( cur.data.parray, &idx, const_cast<void*>(data.pvRecord))); data.pRecInfo->GetTypeInfo( &reftypeinfo); cur.state = VarClose; m_stk.push_back( StackElem( "", data.pRecInfo, reftypeinfo, data)); std::memset( &data, 0, sizeof(data)); data.vt = VT_EMPTY; reftypeinfo->Release(); reftypeinfo = 0; } else { throw std::runtime_error(std::string("cannot handle this array element type in result: '") + comauto::typestr(elemvt)); } return true; } else if (comauto::isAtomicType( cur.data.vt) || comauto::isStringType( cur.data.vt)) { element = m_elembuf = comauto::getAtomicElement( cur.data); type = Value; m_stk.pop_back(); return true; } else if (cur.data.vt == VT_RECORD) { LONG idx = cur.idx++; cur.state = VarClose; if (idx >= cur.typeattr->cVars) { m_stk.pop_back(); goto AGAIN; } WRAP( cur.typeinfo->GetVarDesc( idx, &vardesc)); std::wstring varname( comauto::variablename_utf16( cur.typeinfo, vardesc)); cur.typeinfo->ReleaseVarDesc( vardesc); vardesc = 0; WRAP( const_cast<IRecordInfo*>(cur.recinfo)->GetField( cur.data.pvRecord, varname.c_str(), &data)); if ((data.vt & VT_ARRAY) == VT_ARRAY) { bool rt = false; std::string elemname; if (((int)m_flags & serialize::Flags::SerializeWithIndices) != 0) { type = OpenTag; element = types::VariantConst( m_elembuf = comauto::utf8string( varname)); cur.state = VarClose; rt = true; } else { elemname = comauto::utf8string(varname); cur.state = VarOpen; } m_stk.push_back( StackElem( elemname, 0, 0, data)); std::memset( &data, 0, sizeof(data)); data.vt = VT_EMPTY; if (rt) return true; goto AGAIN; } else if (data.vt == VT_RECORD) { if (!data.pRecInfo || !data.pvRecord) { throw std::runtime_error("cannot iterate through structure without record info"); } WRAP( data.pRecInfo->GetTypeInfo( &reftypeinfo)); m_stk.push_back( StackElem( "", data.pRecInfo, reftypeinfo, data)); reftypeinfo->Release(); reftypeinfo = 0; type = OpenTag; element = types::VariantConst( m_elembuf = comauto::utf8string( varname)); } else if (comauto::isAtomicType( data.vt) || comauto::isStringType( data.vt)) { m_stk.push_back( StackElem( "", 0, 0, data)); type = OpenTag; element = types::VariantConst( m_elembuf = comauto::utf8string( varname)); } else { throw std::runtime_error( std::string( "cannot handle this type in result structure '") + comauto::typestr(data.vt) + "'"); } std::memset( &data, 0, sizeof(data)); data.vt = VT_EMPTY; return true; } else { throw std::runtime_error( std::string("cannot handle this type of result '") + comauto::typestr(cur.data.vt) + "'"); } } case VarClose: { cur.state = VarOpen; element = types::VariantConst(); type = CloseTag; return true; } } } catch (const std::runtime_error& e) { if (vardesc) m_stk.back().typeinfo->ReleaseVarDesc( vardesc); if (reftypeinfo) reftypeinfo->Release(); throw e; } return false; }
void DumpComTypes(ITypeLib* pTypeLib) { // Dump out the types. USES_CONVERSION; pTypeLib->AddRef(); ULONG typeCount = pTypeLib->GetTypeInfoCount(); cout << "\n****** The COM Types ******" << endl; cout << "There are " << typeCount << " in this type lib" << endl << endl; for(ULONG typeIndex = 0; typeIndex < typeCount; typeIndex++) { ITypeInfo* pInfo = NULL; TYPEATTR* typeAtt; CComBSTR temp; ULONG index = 0; ULONG numbMembers = 0; pTypeLib->GetTypeInfo(typeIndex, &pInfo); pInfo->GetTypeAttr(&typeAtt); // Based on the kind of COM type, print out some information. switch(typeAtt->typekind) { case TKIND_COCLASS: // type is a coclass. cout << "(" << typeIndex << ")" << " Coclass with " << typeAtt->cImplTypes << " interface(s). ******" << endl; temp = typeAtt->guid; cout << "->CLSID: " << W2A(temp.Copy()) << endl; pInfo->GetDocumentation(-1, &temp, NULL, NULL, NULL); cout << "->Name: " << W2A(temp.Copy()) << endl; break; case TKIND_DISPATCH: // type is a IDispatch derived interface. cout << "(" << typeIndex << ")" << " IDispatch based interface with " << typeAtt->cFuncs << " method(s). ******" << endl; temp = typeAtt->guid; cout << "->IID: " << W2A(temp.Copy()) << endl; pInfo->GetDocumentation(-1, &temp, NULL, NULL, NULL); cout << "->Name: " << W2A(temp.Copy()) << endl; numbMembers = typeAtt->cFuncs; for(index = 0; index < numbMembers; index++) { FUNCDESC* fx; pInfo->GetFuncDesc(index, &fx); pInfo->GetDocumentation(fx->memid, &temp, NULL, NULL, NULL); cout << " ->" << W2A(temp.Copy()) << " has " << fx->cParams << " params" << endl; pInfo->ReleaseFuncDesc(fx); } break; case TKIND_INTERFACE: // Type is an IUnknown derived interface. cout << "(" << typeIndex << ")" << " IUnknown based interface with " << typeAtt->cFuncs << " method(s). ******" << endl; temp = typeAtt->guid; cout << "->IID: " << W2A(temp.Copy()) << endl; pInfo->GetDocumentation(-1, &temp, NULL, NULL, NULL); cout << "->Name: " << W2A(temp.Copy()) << endl; numbMembers = typeAtt->cFuncs; for(index = 0; index < numbMembers; index++) { FUNCDESC* fx; pInfo->GetFuncDesc(index, &fx); pInfo->GetDocumentation(fx->memid, &temp, NULL, NULL, NULL); cout << " ->" << W2A(temp.Copy()) << " has " << fx->cParams << " param(s)" << endl; pInfo->ReleaseFuncDesc(fx); } break; case TKIND_ENUM: // Type is an enum. cout << "(" << typeIndex << ")" << " Enum with " << typeAtt->cVars << " member(s). ******" << endl; pInfo->GetDocumentation(-1, &temp, NULL, NULL, NULL); cout << "->Name: " << W2A(temp.Copy()) << endl; numbMembers = typeAtt->cVars; for(index = 0; index < numbMembers; index++) { VARDESC* var; pInfo->GetVarDesc(index, &var); pInfo->GetDocumentation(var->memid, &temp, NULL, NULL, NULL); cout << " ->" << W2A(temp.Copy()) << endl; pInfo->ReleaseVarDesc(var); } break; default: cout << "Some other type I don't care about..." << endl; } cout << endl; pInfo->ReleaseTypeAttr(typeAtt); pInfo->Release(); } pTypeLib->Release(); }
QString qax_generateDocumentation(QAxBase *that) { that->metaObject(); if (that->isNull()) return QString(); ITypeInfo *typeInfo = 0; IDispatch *dispatch = 0; that->queryInterface(IID_IDispatch, (void**)&dispatch); if (dispatch) dispatch->GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, &typeInfo); QString docu; QTextStream stream(&docu, QIODevice::WriteOnly); const QMetaObject *mo = that->metaObject(); QString coClass = QLatin1String(mo->classInfo(mo->indexOfClassInfo("CoClass")).value()); stream << "<h1 align=center>" << coClass << " Reference</h1>" << endl; stream << "<p>The " << coClass << " COM object is a " << that->qObject()->metaObject()->className(); stream << " with the CLSID " << that->control() << ".</p>" << endl; stream << "<h3>Interfaces</h3>" << endl; stream << "<ul>" << endl; const char *inter = 0; int interCount = 1; while ((inter = mo->classInfo(mo->indexOfClassInfo("Interface " + QByteArray::number(interCount))).value())) { stream << "<li>" << inter << endl; interCount++; } stream << "</ul>" << endl; stream << "<h3>Event Interfaces</h3>" << endl; stream << "<ul>" << endl; interCount = 1; while ((inter = mo->classInfo(mo->indexOfClassInfo("Event Interface " + QByteArray::number(interCount))).value())) { stream << "<li>" << inter << endl; interCount++; } stream << "</ul>" << endl; QList<QString> methodDetails, propDetails; const int slotCount = mo->methodCount(); if (slotCount) { stream << "<h2>Public Slots:</h2>" << endl; stream << "<ul>" << endl; int defArgCount = 0; for (int islot = mo->methodOffset(); islot < slotCount; ++islot) { const QMetaMethod slot = mo->method(islot); if (slot.methodType() != QMetaMethod::Slot) continue; if (slot.attributes() & QMetaMethod::Cloned) { ++defArgCount; continue; } QByteArray returntype(slot.typeName()); if (returntype.isEmpty()) returntype = "void"; QByteArray prototype = namedPrototype(slot.parameterTypes(), slot.parameterNames(), defArgCount); QByteArray signature = slot.methodSignature(); QByteArray name = signature.left(signature.indexOf('(')); stream << "<li>" << returntype << " <a href=\"#" << name << "\"><b>" << name << "</b></a>" << prototype << ";</li>" << endl; prototype = namedPrototype(slot.parameterTypes(), slot.parameterNames()); QString detail = QString::fromLatin1("<h3><a name=") + QString::fromLatin1(name.constData()) + QLatin1String("></a>") + QLatin1String(returntype.constData()) + QLatin1Char(' ') + QLatin1String(name.constData()) + QLatin1Char(' ') + QString::fromLatin1(prototype.constData()) + QLatin1String("<tt> [slot]</tt></h3>\n"); prototype = namedPrototype(slot.parameterTypes(), QList<QByteArray>()); detail += docuFromName(typeInfo, QString::fromLatin1(name.constData())); detail += QLatin1String("<p>Connect a signal to this slot:<pre>\n"); detail += QString::fromLatin1("\tQObject::connect(sender, SIGNAL(someSignal") + QString::fromLatin1(prototype.constData()) + QLatin1String("), object, SLOT(") + QString::fromLatin1(name.constData()) + QString::fromLatin1(prototype.constData()) + QLatin1String("));"); detail += QLatin1String("</pre>\n"); if (1) { detail += QLatin1String("<p>Or call the function directly:<pre>\n"); bool hasParams = slot.parameterTypes().count() != 0; if (hasParams) detail += QLatin1String("\tQVariantList params = ...\n"); detail += QLatin1String("\t"); QByteArray functionToCall = "dynamicCall"; if (returntype == "IDispatch*" || returntype == "IUnknown*") { functionToCall = "querySubObject"; returntype = "QAxObject *"; } if (returntype != "void") detail += QLatin1String(returntype.constData()) + QLatin1String(" result = "); detail += QLatin1String("object->") + QLatin1String(functionToCall.constData()) + QLatin1String("(\"" + name + prototype + '\"'); if (hasParams) detail += QLatin1String(", params"); detail += QLatin1Char(')'); if (returntype != "void" && returntype != "QAxObject *" && returntype != "QVariant") detail += QLatin1Char('.') + QLatin1String(toType(returntype)); detail += QLatin1String(";</pre>\n"); } else { detail += QLatin1String("<p>This function has parameters of unsupported types and cannot be called directly."); } methodDetails << detail; defArgCount = 0; } stream << "</ul>" << endl; } int signalCount = mo->methodCount(); if (signalCount) { ITypeLib *typeLib = 0; if (typeInfo) { UINT index = 0; typeInfo->GetContainingTypeLib(&typeLib, &index); typeInfo->Release(); } typeInfo = 0; stream << "<h2>Signals:</h2>" << endl; stream << "<ul>" << endl; for (int isignal = mo->methodOffset(); isignal < signalCount; ++isignal) { const QMetaMethod signal(mo->method(isignal)); if (signal.methodType() != QMetaMethod::Signal) continue; QByteArray prototype = namedPrototype(signal.parameterTypes(), signal.parameterNames()); QByteArray signature = signal.methodSignature(); QByteArray name = signature.left(signature.indexOf('(')); stream << "<li>void <a href=\"#" << name << "\"><b>" << name << "</b></a>" << prototype << ";</li>" << endl; QString detail = QLatin1String("<h3><a name=") + QLatin1String(name.constData()) + QLatin1String("></a>void ") + QLatin1String(name.constData()) + QLatin1Char(' ') + QLatin1String(prototype.constData()) + QLatin1String("<tt> [signal]</tt></h3>\n"); if (typeLib) { interCount = 0; do { if (typeInfo) typeInfo->Release(); typeInfo = 0; typeLib->GetTypeInfo(++interCount, &typeInfo); QString typeLibDocu = docuFromName(typeInfo, QString::fromLatin1(name.constData())); if (!typeLibDocu.isEmpty()) { detail += typeLibDocu; break; } } while (typeInfo); } prototype = namedPrototype(signal.parameterTypes(), QList<QByteArray>()); detail += QLatin1String("<p>Connect a slot to this signal:<pre>\n"); detail += QLatin1String("\tQObject::connect(object, SIGNAL(") + QString::fromLatin1(name.constData()) + QString::fromLatin1(prototype.constData()) + QLatin1String("), receiver, SLOT(someSlot") + QString::fromLatin1(prototype.constData()) + QLatin1String("));"); detail += QLatin1String("</pre>\n"); methodDetails << detail; if (typeInfo) typeInfo->Release(); typeInfo = 0; } stream << "</ul>" << endl; if (typeLib) typeLib->Release(); } const int propCount = mo->propertyCount(); if (propCount) { if (dispatch) dispatch->GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, &typeInfo); stream << "<h2>Properties:</h2>" << endl; stream << "<ul>" << endl; for (int iprop = 0; iprop < propCount; ++iprop) { const QMetaProperty prop = mo->property(iprop); QByteArray name(prop.name()); QByteArray type(prop.typeName()); stream << "<li>" << type << " <a href=\"#" << name << "\"><b>" << name << "</b></a>;</li>" << endl; QString detail = QLatin1String("<h3><a name=") + QString::fromLatin1(name.constData()) + QLatin1String("></a>") + QLatin1String(type.constData()) + QLatin1Char(' ') + QLatin1String(name.constData()) + QLatin1String("</h3>\n"); detail += docuFromName(typeInfo, QString::fromLatin1(name)); QVariant::Type vartype = QVariant::nameToType(type); if (!prop.isReadable()) continue; if (prop.isEnumType()) vartype = QVariant::Int; if (vartype != QVariant::Invalid) { detail += QLatin1String("<p>Read this property's value using QObject::property:<pre>\n"); if (prop.isEnumType()) detail += QLatin1String("\tint val = "); else detail += QLatin1Char('\t') + QLatin1String(type.constData()) + QLatin1String(" val = "); detail += QLatin1String("object->property(\"") + QLatin1String(name.constData()) + QLatin1String("\").") + QLatin1String(toType(type).constData()) + QLatin1String(";\n"); detail += QLatin1String("</pre>\n"); } else if (type == "IDispatch*" || type == "IUnknown*") { detail += QLatin1String("<p>Get the subobject using querySubObject:<pre>\n"); detail += QLatin1String("\tQAxObject *") + QLatin1String(name.constData()) + QLatin1String(" = object->querySubObject(\"") + QLatin1String(name.constData()) + QLatin1String("\");\n"); detail += QLatin1String("</pre>\n"); } else { detail += QLatin1String("<p>This property is of an unsupported type.\n"); } if (prop.isWritable()) { detail += QLatin1String("Set this property' value using QObject::setProperty:<pre>\n"); if (prop.isEnumType()) { detail += QLatin1String("\tint newValue = ... // string representation of values also supported\n"); } else { detail += QLatin1String("\t") + QString::fromLatin1(type.constData()) + QLatin1String(" newValue = ...\n"); } detail += QLatin1String("\tobject->setProperty(\"") + QString::fromLatin1(name) + QLatin1String("\", newValue);\n"); detail += QLatin1String("</pre>\n"); detail += QLatin1String("Or using the "); QByteArray setterSlot; if (isupper(name.at(0))) { setterSlot = "Set" + name; } else { QByteArray nameUp = name; nameUp[0] = toupper(nameUp.at(0)); setterSlot = "set" + nameUp; } detail += QLatin1String("<a href=\"#") + QString::fromLatin1(setterSlot) + QLatin1String("\">") + QString::fromLatin1(setterSlot.constData()) + QLatin1String("</a> slot.\n"); } if (prop.isEnumType()) { detail += QLatin1String("<p>See also <a href=\"#") + QString::fromLatin1(type) + QLatin1String("\">") + QString::fromLatin1(type) + QLatin1String("</a>.\n"); } propDetails << detail; } stream << "</ul>" << endl; } const int enumCount = mo->enumeratorCount(); if (enumCount) { stream << "<hr><h2>Member Type Documentation</h2>" << endl; for (int i = 0; i < enumCount; ++i) { const QMetaEnum enumdata = mo->enumerator(i); stream << "<h3><a name=" << enumdata.name() << "></a>" << enumdata.name() << "</h3>" << endl; stream << "<ul>" << endl; for (int e = 0; e < enumdata.keyCount(); ++e) { stream << "<li>" << enumdata.key(e) << "\t=" << enumdata.value(e) << "</li>" << endl; } stream << "</ul>" << endl; } } if (methodDetails.count()) { stream << "<hr><h2>Member Function Documentation</h2>" << endl; for (int i = 0; i < methodDetails.count(); ++i) stream << methodDetails.at(i) << endl; } if (propDetails.count()) { stream << "<hr><h2>Property Documentation</h2>" << endl; for (int i = 0; i < propDetails.count(); ++i) stream << propDetails.at(i) << endl; } if (typeInfo) typeInfo->Release(); if (dispatch) dispatch->Release(); return docu; }
//////////////////////////////////////////////////////////////////////// // DllRegisterServer // // Registration of the OCX. // STDAPI DllRegisterServer() { HRESULT hr = S_OK; HKEY hk, hk2; DWORD dwret; CHAR szbuffer[256]; LPWSTR pwszModule; ITypeInfo* pti; // If we can't find the path to the DLL, we can't register... if (!FGetModuleFileName(v_hModule, &pwszModule)) return E_FAIL; // Setup the CLSID. This is the most important. If there is a critical failure, // we will set HR = GetLastError and return... if ((dwret = RegCreateKeyEx(HKEY_CLASSES_ROOT, "CLSID\\"DSOFRAMERCTL_CLSIDSTR, 0, NULL, 0, KEY_WRITE, NULL, &hk, NULL)) != ERROR_SUCCESS) { DsoMemFree(pwszModule); return HRESULT_FROM_WIN32(dwret); } lstrcpy(szbuffer, DSOFRAMERCTL_SHORTNAME); RegSetValueEx(hk, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer)); // Setup the InprocServer32 key... dwret = RegCreateKeyEx(hk, "InprocServer32", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL); if (dwret == ERROR_SUCCESS) { lstrcpy(szbuffer, "Apartment"); RegSetValueEx(hk2, "ThreadingModel", 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer)); // We call a wrapper function for this setting since the path should be // stored in Unicode to handle non-ANSI file path names on some systems. // This wrapper will convert the path to ANSI if we are running on Win9x. // The rest of the Reg calls should be OK in ANSI since they do not // contain non-ANSI/Unicode-specific characters... if (!FSetRegKeyValue(hk2, pwszModule)) hr = E_ACCESSDENIED; RegCloseKey(hk2); dwret = RegCreateKeyEx(hk, "ProgID", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL); if (dwret == ERROR_SUCCESS) { lstrcpy(szbuffer, DSOFRAMERCTL_PROGID); RegSetValueEx(hk2, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer)); RegCloseKey(hk2); } } else hr = HRESULT_FROM_WIN32(dwret); if (SUCCEEDED(hr)) { dwret = RegCreateKeyEx(hk, "Control", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL); if (dwret == ERROR_SUCCESS) { RegCloseKey(hk2); } else hr = HRESULT_FROM_WIN32(dwret); } // If we succeeded so far, andle the remaining (non-critical) reg keys... if (SUCCEEDED(hr)) { dwret = RegCreateKeyEx(hk, "ToolboxBitmap32", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL); if (dwret == ERROR_SUCCESS) { LPWSTR pwszT = DsoCopyStringCat(pwszModule, L",102"); if (pwszT) { FSetRegKeyValue(hk2, pwszT); DsoMemFree(pwszT); } RegCloseKey(hk2); } dwret = RegCreateKeyEx(hk, "TypeLib", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL); if (dwret == ERROR_SUCCESS) { lstrcpy(szbuffer, DSOFRAMERCTL_TLIBSTR); RegSetValueEx(hk2, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer)); RegCloseKey(hk2); } dwret = RegCreateKeyEx(hk, "Version", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL); if (dwret == ERROR_SUCCESS) { lstrcpy(szbuffer, DSOFRAMERCTL_VERSIONSTR); RegSetValueEx(hk2, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer)); RegCloseKey(hk2); } dwret = RegCreateKeyEx(hk, "MiscStatus", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL); if (dwret == ERROR_SUCCESS) { lstrcpy(szbuffer, "131473"); RegSetValueEx(hk2, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer)); RegCloseKey(hk2); } dwret = RegCreateKeyEx(hk, "DataFormats\\GetSet\\0", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL); if (dwret == ERROR_SUCCESS) { lstrcpy(szbuffer, "3,1,32,1"); RegSetValueEx(hk2, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer)); RegCloseKey(hk2); } } RegCloseKey(hk); DsoMemFree(pwszModule); // This should catch any critical failures during setup of CLSID... RETURN_ON_FAILURE(hr); // Setup the ProgID (non-critical)... if (RegCreateKeyEx(HKEY_CLASSES_ROOT, DSOFRAMERCTL_PROGID, 0, NULL, 0, KEY_WRITE, NULL, &hk, NULL) == ERROR_SUCCESS) { lstrcpy(szbuffer, DSOFRAMERCTL_FULLNAME); RegSetValueEx(hk, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer)); if (RegCreateKeyEx(hk, "CLSID", 0, NULL, 0, KEY_WRITE, NULL, &hk2, NULL) == ERROR_SUCCESS) { lstrcpy(szbuffer, DSOFRAMERCTL_CLSIDSTR); RegSetValueEx(hk2, NULL, 0, REG_SZ, (BYTE *)szbuffer, lstrlen(szbuffer)); RegCloseKey(hk2); } RegCloseKey(hk); } // Load the type info (this should register the lib once)... hr = DsoGetTypeInfoEx(LIBID_DSOFramer, 0, DSOFRAMERCTL_VERSION_MAJOR, DSOFRAMERCTL_VERSION_MINOR, v_hModule, CLSID_FramerControl, &pti); if (SUCCEEDED(hr)) pti->Release(); return hr; }
BOOL comauto::RecordInfo::IsMatchingType( IRecordInfo *pRecordInfo) { BOOL rt = TRUE; ITypeInfo* otypeinfo = 0; ITypeInfo* rectypeinfo = 0; ITypeInfo* orectypeinfo = 0; TYPEATTR* otypeattr = 0; VARDESC* vd = 0; VARDESC* ovd = 0; BSTR varname = NULL; BSTR ovarname = NULL; try { WRAP( pRecordInfo->GetTypeInfo( &otypeinfo)) WRAP( otypeinfo->GetTypeAttr( &otypeattr)) if (m_typeattr->guid == otypeattr->guid) goto Cleanup; if (m_typeattr->cVars != otypeattr->cVars) {rt=FALSE; goto Cleanup;} unsigned short ii; for (ii = 0; ii < m_typeattr->cVars; ++ii) { if (vd) { m_typeinfo->ReleaseVarDesc( vd); vd = NULL; } WRAP( m_typeinfo->GetVarDesc( ii, &vd)) if (ovd) { otypeinfo->ReleaseVarDesc( ovd); ovd = NULL; } WRAP( otypeinfo->GetVarDesc( ii, &ovd)) if (vd->elemdescVar.tdesc.vt != ovd->elemdescVar.tdesc.vt || vd->oInst != ovd->oInst) { rt=FALSE; goto Cleanup; } UINT nn; if (varname) { ::SysFreeString( varname); varname = NULL; } WRAP( m_typeinfo->GetNames( vd->memid, &varname, 1, &nn)) if (ovarname) { ::SysFreeString( ovarname); ovarname = NULL; } WRAP( otypeinfo->GetNames( ovd->memid, &ovarname, 1, &nn)) if (wcscmp( varname, ovarname) != 0) { rt=FALSE; goto Cleanup; } if (vd->elemdescVar.tdesc.vt == VT_USERDEFINED) { if (rectypeinfo) { rectypeinfo->Release(); rectypeinfo = 0; } WRAP( m_typeinfo->GetRefTypeInfo( vd->elemdescVar.tdesc.hreftype, &rectypeinfo)) if (orectypeinfo) { orectypeinfo->Release(); orectypeinfo = NULL; } WRAP( m_typeinfo->GetRefTypeInfo( ovd->elemdescVar.tdesc.hreftype, &orectypeinfo)) comauto::RecordInfo rec( rectypeinfo); comauto::RecordInfo orec( orectypeinfo); if (rec.IsMatchingType( &orec) == FALSE) { rt=FALSE; goto Cleanup; } } } } catch (...) { rt = FALSE; } Cleanup: if (vd) m_typeinfo->ReleaseVarDesc( vd); if (ovd) otypeinfo->ReleaseVarDesc( ovd); if (otypeattr) otypeinfo->ReleaseTypeAttr( otypeattr); if (rectypeinfo) rectypeinfo->Release(); if (orectypeinfo) orectypeinfo->Release(); if (otypeinfo) otypeinfo->Release(); if (varname) ::SysFreeString( varname); if (ovarname) ::SysFreeString( ovarname); return rt; }
HRESULT comauto::RecordInfo::RecordFill( PVOID pvNew, comauto::RecordInfo::InitType initType, bool doThrow, PVOID pvOld) { HRESULT hr; ITypeInfo* rectypeinfo = 0; if (initType == DefaultConstructorZero) { std::memset( pvNew, 0, m_typeattr->cbSizeInstance); initType = DefaultConstructor; } try { for (WORD iv = 0; iv < m_typeattr->cVars; ++iv) { char elemsize; VARDESC* vd; PVOID nfield; PVOID ofield; WRAP( m_typeinfo->GetVarDesc( iv, &vd)) nfield = (BYTE*)pvNew + vd->oInst; ofield = (BYTE*)pvOld + vd->oInst; if (vd->elemdescVar.tdesc.vt == VT_USERDEFINED) { RETURN_ON_ERROR( hr, m_typeinfo->GetRefTypeInfo( vd->elemdescVar.tdesc.hreftype, &rectypeinfo)) comauto::RecordInfo rec( rectypeinfo); WRAP( rec.RecordFill( nfield, initType, doThrow, pvOld)) rectypeinfo->Release(); rectypeinfo = 0; } else if (vd->elemdescVar.tdesc.vt == VT_BSTR) { switch (initType) { case ClearInit: if (*((BSTR*)nfield) != NULL) ::SysFreeString( *((BSTR*)nfield)); /*no break here!*/ case DefaultConstructor: *((BSTR*)nfield) = ::SysAllocString( L""); break; case CopyInit: if (*((BSTR*)nfield) != NULL) ::SysFreeString( *((BSTR*)nfield)); /*no break here!*/ case CopyConstructor: if (*((BSTR*)ofield)) { *((BSTR*)nfield) = ::SysAllocString( *((BSTR*)ofield)); } else { *((BSTR*)nfield) = ::SysAllocString( L""); } break; case DefaultConstructorZero: throw std::logic_error( "should not pass here !"); case Destructor: if (*((BSTR*)nfield) != NULL) { ::SysFreeString( *((BSTR*)nfield)); *(BSTR*)nfield = NULL; } break; } } else if (vd->elemdescVar.tdesc.vt == VT_LPWSTR) { switch (initType) { case ClearInit: if (*((LPWSTR*)nfield) != NULL) comauto::freeMem( *((LPWSTR*)nfield)); case DefaultConstructor: *((LPWSTR*)nfield) = NULL; break; case CopyInit: if (*((LPWSTR*)nfield) != NULL) comauto::freeMem( *((LPWSTR*)nfield)); case CopyConstructor: *((LPWSTR*)nfield) = comauto::createLPWSTR( *(LPWSTR*)ofield); break; case DefaultConstructorZero: throw std::logic_error( "should not pass here !"); case Destructor: if (*((LPWSTR*)nfield) != NULL) { comauto::freeMem( *((LPWSTR*)nfield)); *((LPWSTR*)nfield) = NULL; } break; } } else if (vd->elemdescVar.tdesc.vt == VT_LPSTR) { switch (initType) { case ClearInit: if (*((LPSTR*)nfield) != NULL) comauto::freeMem( *((LPSTR*)nfield)); case DefaultConstructor: *((LPSTR*)nfield) = NULL; break; case CopyInit: if (*((LPSTR*)nfield) != NULL) comauto::freeMem( *((LPSTR*)nfield)); case CopyConstructor: *((LPSTR*)nfield) = comauto::createLPSTR( *(LPSTR*)ofield); break; case DefaultConstructorZero: throw std::logic_error( "should not pass here !"); case Destructor: if (*((LPSTR*)nfield) != NULL) { comauto::freeMem( *((LPSTR*)nfield)); *((LPSTR*)nfield) = NULL; } break; } } else if ((elemsize=sizeofAtomicType( vd->elemdescVar.tdesc.vt)) > 0) { switch (initType) { case CopyInit: case CopyConstructor: //copy atomic type std::memcpy( nfield, ofield, elemsize); break; case ClearInit: case DefaultConstructor: case DefaultConstructorZero: // .... others are alread set to zero break; case Destructor: // .... no destructor break; } } else { throw std::runtime_error( "illegal type in POD IRecordInfo structure"); } } return S_OK; } catch (const std::runtime_error& e) { if (rectypeinfo) { rectypeinfo->Release(); rectypeinfo = 0; } if (doThrow) throw e; return E_INVALIDARG; } catch (const std::logic_error& e) { if (rectypeinfo) { rectypeinfo->Release(); rectypeinfo = 0; } if (doThrow) throw e; return E_INVALIDARG; } }