//----------------------------------------------------------------------------
// ObjectComponents
// Copyright (c) 1994, 1996 by Borland International, All Rights Reserved
/// \file
/// TServedObject implementation and OLE Type library generation
//----------------------------------------------------------------------------
#include <ocf/pch.h>
#include <ocf/appdesc.h>
#include <ocf/occtrl.h>
#include <owl/filename.h>
#define OLE_TYPELIB_FILE L"stdole32.tlb"
namespace ocf {
using namespace owl;
//____________________________________________________________________________
//
// TypeLibrary generation
//____________________________________________________________________________
/// local class to hold ICreateTypeLib interface pointers for each class
struct TOleCreateInfo {
int FuncCount;
int VarCount;
int ImplCount;
TYPEKIND TypeKind;
ITypeInfo* OurTypeInfo; // our type info implementation
ITypeInfo* OleTypeInfo; // type info obtained from ICreatTypeInfo
ICreateTypeInfo* CreateInfo; // interface obtained from ICreateTypeLib
TOleCreateInfo() : OurTypeInfo(0), OleTypeInfo(0), CreateInfo(0) {}
~TOleCreateInfo();
};
TOleCreateInfo::~TOleCreateInfo()
{
if (OurTypeInfo)
OurTypeInfo->Release();
if (OleTypeInfo)
OleTypeInfo->Release();
if (CreateInfo)
CreateInfo->Release();
}
struct TOleCreateList {
int Count;
ITypeLib* TypeLib;
LPCTSTR FileName;
TOleCreateInfo* List;
ITypeLib* OleLib;
ITypeComp* OleComp;
ITypeInfo* OleInfo;
ICreateTypeLib* CreateLib;
TLIBATTR * LibAttr;
TYPEATTR * TypeAttr;
ITypeInfo* AttrTypeInfo; // valid only when TypeAttr!=0, not refcnt'd
TBSTR* FuncNames; // temporary transfer of BSTR name arrays
TOleCreateList(ITypeLib* typeLib, LPCTSTR fileName);
void FixupTypeDescRef(int typeIndex, TYPEDESC & typeDesc);
void Close(LPCTSTR helpDir);
void Clear();
~TOleCreateList() {Clear();}
};
TOleCreateList::TOleCreateList(ITypeLib* typeLib, LPCTSTR fileName)
:
TypeLib(typeLib),
FileName(fileName),
OleLib(0), OleComp(0), OleInfo(0),
CreateLib(0), TypeAttr(0), LibAttr(0), List(0), FuncNames(0)
{
TBSTR libName;
TBSTR libDoc;
TBSTR helpFile;
ulong helpId;
TypeLib->AddRef();
OLECALL(::LoadTypeLib(OLE_TYPELIB_FILE, &OleLib), _T("Load stdole.tlb"));
OLECALL(OleLib->GetTypeComp(&OleComp), _T("GetTypeComp"));
ITypeComp* tempComp; // required as reference arg, but always set to 0
OLECALL(
OleComp->BindType(
const_cast<LPOLESTR>(OleText("IDispatch")),
::LHashValOfName(0, OleText("IDispatch")),
&OleInfo,
&tempComp
),
_T("BindType"));
OLECALL(TypeLib->GetLibAttr(&LibAttr), _T("GetLibAttr"));
OLECALL(TypeLib->GetDocumentation(-1, libName, libDoc, &helpId, helpFile),
_T("GetDocumentation for library"));
OLECALL(::CreateTypeLib(LibAttr->syskind, OleStr((LPTSTR)FileName), &CreateLib), _T("CreateTypeLib"));
OLECALL(CreateLib->SetGuid(LibAttr->guid), _T("Set TypeLib GUID"));
OLECALL(CreateLib->SetLcid(LibAttr->lcid), _T("Set TypeLib language"));
OLECALL(CreateLib->SetLibFlags(LibAttr->wLibFlags), _T("Set TypeLib flags"));
if (!!libName)
OLECALL(CreateLib->SetName(libName), _T("Set TypeLib name"));
if (!!libDoc)
OLECALL(CreateLib->SetDocString(libDoc), _T("Set TypeLib doc"));
if (!!helpFile)
{
OLECALL(CreateLib->SetHelpFileName(helpFile), _T("SetHelpFileName"));
OLECALL(CreateLib->SetHelpContext(helpId), _T("HelpContext"));
}
OLECALL(CreateLib->SetVersion(LibAttr->wMajorVerNum,
LibAttr->wMinorVerNum), _T("Set TypeLib version"));
// allocate all ITypeInfo's upfront to force consistent references
Count = TypeLib->GetTypeInfoCount();
List = new TOleCreateInfo[Count];
for (int nInfo = 0; nInfo < Count; nInfo++) {
TOleCreateInfo& info = List[nInfo];
ICreateTypeInfo* newInfo;
OLECALL(TypeLib->GetTypeInfo(nInfo, &AttrTypeInfo), _T("GetTypeInfo"));
info.OurTypeInfo = AttrTypeInfo;
OLECALL(info.OurTypeInfo->GetTypeAttr(&TypeAttr), _T("GetTypeAttr"));
OLECALL(TypeLib->GetDocumentation(nInfo,libName,libDoc,&helpId,helpFile),
_T("GetDocumentation for TypeInfo"));
OLECALL(CreateLib->CreateTypeInfo(libName, TypeAttr->typekind, &newInfo),
_T("Create CreateTypeInfo"));
info.CreateInfo = newInfo;
OLECALL(newInfo->QueryInterface(IID_ITypeInfo,
(void **)&info.OleTypeInfo), _T("QueryInterface for ITypeInfo"));
if (!!libDoc)
OLECALL(newInfo->SetDocString(libDoc), _T("Set TypeInfo doc"));
OLECALL(newInfo->SetHelpContext(helpId), _T("SetHelpContext"));
OLECALL(newInfo->SetVersion(TypeAttr->wMajorVerNum,
TypeAttr->wMinorVerNum),_T("Set TypeInfo version"));
OLECALL(newInfo->SetGuid(TypeAttr->guid), _T("SetTypeInfo GUID"));
OLECALL(newInfo->SetTypeFlags(TypeAttr->wTypeFlags), _T("SetTypeFlags"));
if (TypeAttr->typekind == TKIND_DISPATCH) {
HREFTYPE hreftype;
OLECALL(newInfo->AddRefTypeInfo(OleInfo, &hreftype), _T("AddRefTypeInfo"));
OLECALL(newInfo->AddImplType(0, hreftype), _T("AddImplType"));
}
info.TypeKind = TypeAttr->typekind;
info.FuncCount = TypeAttr->cFuncs;
info.VarCount = TypeAttr->cVars;
info.ImplCount = TypeAttr->cImplTypes;
info.OurTypeInfo->ReleaseTypeAttr(TypeAttr), TypeAttr = 0;
}
}
void TOleCreateList::Close(LPCTSTR helpDir)
{
OLECALL(CreateLib->SaveAllChanges(), _T("Write and close TypeLib file"));
CreateLib->Release();
CreateLib = 0;
OLECALL(::RegisterTypeLib(TypeLib,
OleStr((LPTSTR)FileName),
OleStr((LPTSTR)helpDir)),
_T("Register type library"));
}
void TOleCreateList::Clear()
{
delete[] List; // releases all interface pointers
delete[] FuncNames; // in case exception thrown while in use
if (LibAttr)
TypeLib->ReleaseTLibAttr(LibAttr);
if (TypeAttr)
AttrTypeInfo->ReleaseTypeAttr(TypeAttr);
if (OleInfo)
OleInfo->Release();
if (OleComp)
OleComp->Release();
if (OleLib)
OleLib->Release();
if (CreateLib)
CreateLib->Release();
TypeLib->Release(); // finally release typelib called at constructor
}
void
TOleCreateList::FixupTypeDescRef(int typeIndex, TYPEDESC & typeDesc)
{
if (typeDesc.vt == VT_USERDEFINED) {
ITypeInfo* refInfo;
OLECALL(List[typeIndex].OurTypeInfo->GetRefTypeInfo(typeDesc.hreftype,
&refInfo), _T("GetRefTypeInfo"));
refInfo->Release(); // ok to release here, we're only using its pointer
for (int nInfo = 0; nInfo < Count; nInfo++) {
if (List[nInfo].OurTypeInfo == refInfo) {
OLECALL(List[typeIndex].CreateInfo->AddRefTypeInfo(List[nInfo].OleTypeInfo,
&typeDesc.hreftype), _T("AddRefTypeInfo"));
return;
}
}
OLECALL(HR_TYPE_ELEMENTNOTFOUND, _T("Unknown reference type"));
}
}
void
TAppDescriptor::WriteTypeLibrary(TLangId lang, LPCTSTR file)
{
TServedObject* servedObject;
TBSTR libName;
TBSTR libDoc;
ulong helpId;
FUNCDESC * funcDesc = 0;
VARDESC * varDesc = 0;
TOleCreateList typeList(new TTypeLibrary(*this, lang), file);
for (int nInfo = 0; nInfo < typeList.Count; nInfo++) {
TOleCreateInfo& curInfo = typeList.List[nInfo];
ITypeInfo* typeInfo = curInfo.OurTypeInfo;
ICreateTypeInfo* newInfo = curInfo.CreateInfo;
int index;
for (index = 0; index < curInfo.FuncCount; index++) {
OLECALL(typeInfo->GetFuncDesc(index, &funcDesc), _T("GetFuncDesc"));
// Using the GetDocumentation call fails when creating a typelib, so attempt to
// use the function GetFuncDocFromIndex to get around this problem
servedObject = dynamic_cast<TServedObject*>(typeInfo);
if (servedObject)
OLECALL(servedObject->GetFuncDocFromIndex(index, libName, libDoc,
&helpId, 0), _T("Get method name and doc"));
else
OLECALL(typeInfo->GetDocumentation(funcDesc->memid, libName, libDoc,
&helpId, 0), _T("Get method name and doc"));
for (int nArg = funcDesc->cParams; nArg-- >=0; ) {
ELEMDESC * elem = nArg < 0 ? &funcDesc->elemdescFunc
: &funcDesc->lprgelemdescParam[nArg];
typeList.FixupTypeDescRef(nInfo, elem->tdesc);
}
OLECALL(newInfo->AddFuncDesc(index, funcDesc), _T("AddFuncDesc"));
unsigned nNames = funcDesc->cParams + 1;
typeList.FuncNames = new TBSTR[nNames];
OLECALL(typeInfo->GetNames(funcDesc->memid, (BSTR*)typeList.FuncNames,
nNames, &nNames), _T("Get method parameter names"));
OLECALL(newInfo->SetFuncAndParamNames(index, (BSTR*)typeList.FuncNames,
nNames), _T("Set method parameter names"));
delete[] typeList.FuncNames;
typeList.FuncNames = 0;
if (!!libDoc)
OLECALL(newInfo->SetFuncDocString(index, libDoc),_T("Set method doc"));
OLECALL(newInfo->SetFuncHelpContext(index, helpId), _T("HelpContext"));
typeInfo->ReleaseFuncDesc(funcDesc), funcDesc = 0;
}
for (index = 0; index < curInfo.VarCount; index++) {
OLECALL(typeInfo->GetVarDesc(index, &varDesc), _T("GetVarDesc"));
// Using the GetDocumentation call fails when creating a typelib, so attempt to
// use the function GetVarDocFromIndex to get around this problem
servedObject = dynamic_cast<TServedObject*>(typeInfo);
if (servedObject)
OLECALL(servedObject->GetVarDocFromIndex(index, libName, libDoc,
&helpId, 0), _T("Get propery name and doc"));
else
OLECALL(typeInfo->GetDocumentation(varDesc->memid, libName, libDoc,
&helpId, 0), _T("Get propery name and doc"));
typeList.FixupTypeDescRef(nInfo, varDesc->elemdescVar.tdesc);
OLECALL(newInfo->AddVarDesc(index, varDesc), _T("AddVarDesc"));
OLECALL(newInfo->SetVarName(index, libName),_T("Set property name"));
if (!!libDoc)
OLECALL(newInfo->SetVarDocString(index, libDoc),_T("Set property doc"));
OLECALL(newInfo->SetVarHelpContext(index, helpId), _T("HelpContext"));
typeInfo->ReleaseVarDesc(varDesc), varDesc = 0;
}
if (curInfo.TypeKind == TKIND_COCLASS) {
for (index = 0; index < curInfo.ImplCount; index++) {
HREFTYPE hreftype;
ITypeInfo* refInfo;
OLECALL(typeInfo->GetRefTypeOfImplType(index, &hreftype),_T("GetCoClassRef"));
OLECALL(typeInfo->GetRefTypeInfo(hreftype, &refInfo), _T("GetCoClassTypeInfo"));
refInfo->Release(); // ok to release here, only using its pointer
for (int iInfo = 0; iInfo < typeList.Count; iInfo++) {
if (typeList.List[iInfo].OurTypeInfo == refInfo) {
OLECALL(newInfo->AddRefTypeInfo(typeList.List[iInfo].OleTypeInfo, &hreftype), _T("AddRefTypeInfo"));
OLECALL(newInfo->AddImplType(index, hreftype), _T("AddImplType"));
int implflags;
OLECALL(typeInfo->GetImplTypeFlags(index, &implflags), _T("GetImplTypeFlags"));
OLECALL(newInfo->SetImplTypeFlags(index, implflags), _T("SetImplTypeFlags"));
}
}
}
}
OLECALL(newInfo->LayOut(), _T("Layout typeinfo"));
}
tstring helpDir = RegInfo.Lookup("helpdir");
if (helpDir.empty()){
_TCHAR path [_MAX_PATH];
Module->GetModuleFileName(path, sizeof(path));
helpDir = TFileName(path).GetParts(TFileName::Server|TFileName::Device|TFileName::Path);
}
typeList.Close(helpDir.c_str());
int iGuid = 0; // first pass for app, second for debug app if present
do {
_TCHAR buf[80];
_tcscpy(buf, _T("CLSID\\"));
_tcscat(buf, AppClassId[iGuid]);
_tcscat(buf, _T("\\TypeLib"));
TRegKey::GetClassesRoot().SetValue(buf,REG_SZ, (uint8*)(LPCTSTR)AppClassId[LibGuidOffset], 0);
iGuid ^= DebugGuidOffset; // remains 0 if no debug guid assigned
} while (iGuid);
}
//____________________________________________________________________________
//
// TTypeLibrary implementation
//____________________________________________________________________________
TTypeLibrary::TTypeLibrary(TAppDescriptor& appDesc, TLangId lang)
: AppDesc(appDesc), Lang(lang), RefCnt(0)
{
CoClassFlags = 0;
CoClassImplCount = 0;
TAutoClass::TAutoClassRef* ref = AppDesc.ClassList;
for (int index = 0; index < AppDesc.ClassCount; index++, ref++) {
TAutoClass* cls = ref->Class;
int implFlags = cls->GetImplTypeFlags();
uint16 typeFlags = cls->GetCoClassFlags();
if (implFlags != 0 || typeFlags != 0) {
CoClassImplCount++;
CoClassFlags |= typeFlags;
}
}
}
TTypeLibrary::~TTypeLibrary()
{
if (AppDesc.TypeLib == this)
AppDesc.TypeLib = 0; // remove pointer to this
if (RefCnt > 0)
::CoDisconnectObject(this,0); // should not normally happen
}
ITypeInfo*
TTypeLibrary::CreateCoClassInfo()
{
ITypeInfo* ifc = new TCoClassInfo(AppDesc, CoClassFlags, CoClassImplCount);
ifc->AddRef();
return ifc;
}
HRESULT _IFUNC
TTypeLibrary::QueryInterface(const IID & riid, void * * retIface)
{
if (riid == IID_IUnknown || riid == IID_ITypeLib) {
AddRef();
*retIface = (IUnknown*)this;
return HR_NOERROR;
}
*retIface = 0;
return HR_NOINTERFACE;
}
unsigned long _IFUNC
TTypeLibrary::AddRef()
{
return ++RefCnt;
}
unsigned long _IFUNC
TTypeLibrary::Release()
{
if (--RefCnt != 0)
return RefCnt;
delete this;
return 0;
}
unsigned int _IFUNC
TTypeLibrary::GetTypeInfoCount()
{
return AppDesc.GetClassCount() + (CoClassImplCount > 0); // +1 for CoClass
}
HRESULT _IFUNC
TTypeLibrary::GetTypeInfo(unsigned index, ITypeInfo* * retInfo)
{
if (CoClassImplCount > 0 && index == (uint)AppDesc.GetClassCount()) {
*retInfo = CreateCoClassInfo();
}
else {
TAutoClass* cls = AppDesc.GetAutoClass(index);
if (!cls)
return HR_TYPE_ELEMENTNOTFOUND;
*retInfo = AppDesc.CreateITypeInfo(*cls);
}
return HR_NOERROR;
}
HRESULT _IFUNC
TTypeLibrary::GetTypeInfoType(unsigned index, TYPEKIND * retKind)
{
unsigned int count = AppDesc.GetClassCount();
if (index > count)
return HR_TYPE_ELEMENTNOTFOUND;
*retKind = (index == count ? TKIND_COCLASS : TKIND_DISPATCH);
return HR_NOERROR;
}
HRESULT _IFUNC
TTypeLibrary::GetTypeInfoOfGuid(const GUID & guid, ITypeInfo* * retInfo)
{
if (AppDesc.AppClassId.GetOffset(guid) == 0) {
*retInfo = CreateCoClassInfo();
} else {
TAutoClass* cls = AppDesc.GetAutoClass(guid);
if (!cls)
return HR_TYPE_ELEMENTNOTFOUND;
*retInfo = AppDesc.CreateITypeInfo(*cls);
}
return HR_NOERROR;
}
HRESULT _IFUNC
TTypeLibrary::GetLibAttr(TLIBATTR * * retAttr)
{
TLIBATTR* libAttr = new TLIBATTR;
memset(libAttr, 0, sizeof(TLIBATTR));
libAttr->syskind = SYS_WIN32;
libAttr->lcid = Lang;
AppDesc.GetClassId(0, libAttr->guid);
libAttr->wMajorVerNum = AppDesc.GetVersionField(0);
libAttr->wMinorVerNum = AppDesc.GetVersionField(1);
*retAttr = libAttr;
return HR_NOERROR;
}
void _IFUNC
TTypeLibrary::ReleaseTLibAttr(TLIBATTR * attr)
{
delete attr;
}
HRESULT _IFUNC
TTypeLibrary::GetTypeComp(ITypeComp* * /*retComp*/)
{
return HR_TYPE_UNSUPFORMAT;
}
HRESULT _IFUNC
TTypeLibrary::GetDocumentation(int index, BSTR * retName,
BSTR * retDoc,
ulong * retHelpContext,
BSTR * retHelpFile)
{
if (retHelpFile)
*retHelpFile = TOleAuto::SysAllocString((const OLECHAR *)AppDesc.GetHelpFile(Lang));
if (retHelpContext)
*retHelpContext = 0;
if (index == -1 || index == AppDesc.GetClassCount()) { // library itself
if (retName)
*retName = TOleAuto::SysAllocString((const OLECHAR *)AppDesc.GetAppName(Lang));
if (retDoc)
*retDoc = TOleAuto::SysAllocString((const OLECHAR *)AppDesc.GetAppDoc(Lang));
if (retHelpContext)
*retHelpContext = 0;
} else {
TAutoClass* cls = AppDesc.GetAutoClass(index);
if (!cls)
return HR_TYPE_ELEMENTNOTFOUND;
if (retName)
*retName = TOleAuto::SysAllocString((const OLECHAR *)cls->GetName(Lang));
if (retDoc)
*retDoc = TOleAuto::SysAllocString((const OLECHAR *)cls->GetDoc(Lang));
if (retHelpContext)
*retHelpContext = cls->GetHelpId();
}
return HR_NOERROR;
}
HRESULT _IFUNC
TTypeLibrary::IsName(OLECHAR * nameBuf, ulong /*hashVal*/, int * retFound)
{
TAutoClass::TAutoClassRef* ref = AppDesc.ClassList;
for (int index = 0; index < AppDesc.ClassCount; index++, ref++) {
TAutoClass* cls = ref->Class;
// not clear from doc if we should check names of classes as well as members
long id;
TAutoSymbol* sym = cls->Lookup(OleStr(nameBuf), Lang, asOleType, id);
if (sym) {
lstrcpyW(nameBuf, OleStr(sym->Name));
*retFound = 1;
return HR_NOERROR;
}
}
return ResultFromScode(TYPE_E_ELEMENTNOTFOUND);
}
HRESULT _IFUNC
TTypeLibrary::FindName(OLECHAR * nameBuf, ulong /*lHashVal*/,
ITypeInfo* * retInfo, MEMBERID * retId,
unsigned short * inoutCount)
{
unsigned short found = 0;
TAutoClass::TAutoClassRef* ref = AppDesc.ClassList;
for (int index = 0; index < AppDesc.ClassCount && found < *inoutCount;
index++, ref++) {
TAutoClass* cls = ref->Class;
long id;
TAutoSymbol* sym = cls->Lookup(OleStr(nameBuf), Lang, asOleType, id);
if (sym) {
retId[found] = id;
retInfo[found] = AppDesc.CreateITypeInfo(*cls);
found++;
}
}
*inoutCount = found;
return found ? HR_NOERROR : HR_TYPE_ELEMENTNOTFOUND;
}
//____________________________________________________________________________
//
// TCoClassInfo implementation
//____________________________________________________________________________
TCoClassInfo::TCoClassInfo(TAppDescriptor& appDesc, uint16 typeFlags, int implCount)
: AppDesc(appDesc), RefCnt(0), TypeFlags(typeFlags), ImplCount(implCount)
{
ImplList = new unsigned[implCount];
TAutoClass::TAutoClassRef* ref = AppDesc.ClassList;
int iapp = -1;
int ievent = -1;
Default = -1;
DefaultEvent = -1;
int iclass = 0;
for (int index = 0; iclass < implCount; index++, ref++) {
TAutoClass* cls = ref->Class;
int implFlags = cls->GetImplTypeFlags();
uint16 typeFlags = cls->GetCoClassFlags();
if (implFlags || typeFlags) {
if (implFlags & IMPLTYPEFLAG_FSOURCE) {
ievent = iclass;
if (implFlags & IMPLTYPEFLAG_FDEFAULT)
DefaultEvent = iclass;
} else {
if (typeFlags & TYPEFLAG_FAPPOBJECT)
iapp = iclass;
if (implFlags & IMPLTYPEFLAG_FDEFAULT)
Default = iclass;
}
ImplList[iclass++] = index;
}
}
if (Default == -1)
Default = iapp;
if (DefaultEvent == -1)
DefaultEvent = ievent;
}
TCoClassInfo::~TCoClassInfo()
{
delete ImplList;
}
HRESULT _IFUNC
TCoClassInfo::QueryInterface(const IID & riid, void * * retIface)
{
if (riid == IID_IUnknown || riid == IID_ITypeInfo) {
AddRef();
*retIface = (IUnknown*)this;
return HR_NOERROR;
}
*retIface = 0;
return HR_NOINTERFACE;
}
unsigned long _IFUNC
TCoClassInfo::AddRef()
{
return ++RefCnt;
}
unsigned long _IFUNC
TCoClassInfo::Release()
{
if (--RefCnt != 0)
return RefCnt;
delete this;
return 0;
}
HRESULT _IFUNC
TCoClassInfo::GetTypeAttr(TYPEATTR * * retTypeAttr)
{
TYPEATTR* ta = (TYPEATTR*)new uint8[sizeof(TYPEATTR)];
memset(ta, 0, sizeof(TYPEATTR));
ta->guid = AppDesc.AppClassId;
ta->lcid = AppDesc.GetAppLang();
ta->typekind = TKIND_COCLASS;
ta->cImplTypes = (unsigned short)ImplCount;
ta->wMajorVerNum = AppDesc.GetVersionField(0);
ta->wMinorVerNum = AppDesc.GetVersionField(1);
ta->wTypeFlags = TypeFlags;
*retTypeAttr = ta;
return HR_NOERROR;
}
void _IFUNC
TCoClassInfo::ReleaseTypeAttr(TYPEATTR * ptypeattr)
{
delete [] (uint8*)ptypeattr;
}
HRESULT _IFUNC
TCoClassInfo::GetDocumentation(MEMBERID memid,
BSTR * retName, BSTR * retDoc,
ulong * retHelpContext,
BSTR * retHelpFile)
{
if (retHelpFile)
*retHelpFile = TOleAuto::SysAllocString((const OLECHAR *)AppDesc.GetHelpFile(AppDesc.GetAppLang()));
if (memid == -1) { // request info on type library itself
if (retName)
*retName = TOleAuto::SysAllocString((const OLECHAR *)AppDesc.GetAppName(AppDesc.GetAppLang()));
if (retDoc)
*retDoc = TOleAuto::SysAllocString((const OLECHAR *)AppDesc.GetAppDoc(AppDesc.GetAppLang()));
if (retHelpContext)
*retHelpContext = 0;
} else {
return HR_TYPE_WRONGTYPEKIND;
}
return HR_NOERROR;
}
HRESULT _IFUNC
TCoClassInfo::CreateInstance(IUnknown* /*punkOuter*/, const IID & /*riid*/,
void * * /*ppvObj*/)
{
return HR_TYPE_WRONGTYPEKIND;
}
HRESULT _IFUNC
TCoClassInfo::GetContainingTypeLib(ITypeLib* * retLib,
unsigned int * retIndex)
{
*retLib = AppDesc.GetTypeLibrary();
if (retIndex)
*retIndex = AppDesc.GetClassCount();
return HR_NOERROR;
}
HRESULT _IFUNC
TCoClassInfo::GetRefTypeInfo(HREFTYPE hreftype, ITypeInfo* * retInfo)
{
TAutoClass* cls = (TAutoClass*)hreftype;
if (AppDesc.GetClassIndex(cls) == -1) // validate pointer to avoid crash
return HR_TYPE_WRONGTYPEKIND;
*retInfo = AppDesc.CreateITypeInfo(*cls);
return HR_NOERROR;
}
HRESULT _IFUNC
TCoClassInfo::GetImplTypeFlags(unsigned int index, int * retflags)
{
TAutoClass* cls = index < (uint)ImplCount ?
AppDesc.GetAutoClass(ImplList[index]) : 0;
if (!cls)
return HR_TYPE_ELEMENTNOTFOUND;
int implFlags = cls->GetImplTypeFlags();
if (implFlags & IMPLTYPEFLAG_FSOURCE) {
if (index == (uint)DefaultEvent)
implFlags |= IMPLTYPEFLAG_FDEFAULT;
}
else {
if (index == (uint)Default)
implFlags |= IMPLTYPEFLAG_FDEFAULT;
}
*retflags = implFlags;
return HR_NOERROR;
}
HRESULT _IFUNC
TCoClassInfo::GetRefTypeOfImplType(unsigned int index,
HREFTYPE * retreftype)
{
TAutoClass* cls = index < (uint)ImplCount ?
AppDesc.GetAutoClass(ImplList[index]):0;
*retreftype = (HREFTYPE)cls;
return cls ? HR_NOERROR : HR_TYPE_ELEMENTNOTFOUND;
}
// The following methods of ITypeInfo are not relevant for a COCLASS typeinfo
HRESULT _IFUNC
TCoClassInfo::GetFuncDesc(unsigned int, FUNCDESC * *)
{
return HR_TYPE_WRONGTYPEKIND;
}
void _IFUNC
TCoClassInfo::ReleaseFuncDesc(FUNCDESC *)
{
}
HRESULT _IFUNC
TCoClassInfo::GetVarDesc(unsigned int, VARDESC * *)
{
return HR_TYPE_WRONGTYPEKIND;
}
void _IFUNC
TCoClassInfo::ReleaseVarDesc(VARDESC *)
{
}
HRESULT _IFUNC
TCoClassInfo::GetNames(MEMBERID, BSTR *, unsigned int, unsigned int *)
{
return HR_TYPE_WRONGTYPEKIND;
}
HRESULT _IFUNC
TCoClassInfo::GetIDsOfNames(OLECHAR * *, uint, MEMBERID *)
{
return HR_TYPE_WRONGTYPEKIND;
}
HRESULT _IFUNC
TCoClassInfo::Invoke(void *, MEMBERID, unsigned short, DISPPARAMS *,
VARIANT *, EXCEPINFO *, unsigned int *)
{
return HR_TYPE_WRONGTYPEKIND;
}
HRESULT _IFUNC
TCoClassInfo::GetTypeComp(ITypeComp* *)
{
return HR_TYPE_LIBNOTREGISTERED;
}
HRESULT _IFUNC
TCoClassInfo::GetMops(MEMBERID, BSTR *)
{
return HR_TYPE_WRONGTYPEKIND;
}
HRESULT _IFUNC
TCoClassInfo::GetDllEntry(MEMBERID, INVOKEKIND, BSTR *, BSTR *,
unsigned short *)
{
return HR_TYPE_WRONGTYPEKIND;
}
HRESULT _IFUNC
TCoClassInfo::AddressOfMember(MEMBERID, INVOKEKIND, void * *)
{
return HR_TYPE_WRONGTYPEKIND;
}
} // OCF namespace
//==============================================================================
↑ V205 Explicit conversion of pointer type to 32-bit integer type: (HREFTYPE) cls
↑ V611 The memory was allocated using 'new T[]' operator but was released using the 'delete' operator. Consider inspecting this code. It's probably better to use 'delete [] ImplList;'. Check lines: 546, 513.
↑ V730 Not all members of a class are initialized inside the constructor. Consider inspecting: FuncCount, VarCount, ImplCount, TypeKind.