📄 comcorelib.c
字号:
/* comCoreLib.c - core COM support *//* Copyright (c) 2001 Wind River Systems, Inc. *//*modification history--------------------01n,10dec01,dbs diab build01m,06dec01,nel Correct man pages.01l,02nov01,nel SPR#71427. Correct error in comAddRegistry when null terminator wasn't being copied into registry entry.01k,09aug01,dbs check args to comClassObjectGet01j,07aug01,dbs return multiple interfaces during creation01i,06aug01,dbs add registry-show capability01h,20jul01,dbs add self-initialisation01g,28jun01,dbs add interlocked inc/dec funcs01f,27jun01,dbs ensure registry init01e,25jun01,dbs change WIDL vtable macro name to COM_xxx01d,22jun01,dbs add vtable-format symbol01c,22jun01,dbs add const to args for comGuidCmp01b,21jun01,nel Add comGuidCmp function.01a,20jun01,dbs written*//*DESCRIPTIONThis library provides basic COM support in VxWorks. It implements anextensible registry model, and provides functions to create instancesof classes via their class objects. Support for the basic COMinterfaces IUnknown and IClassFactory is present, and it can be usedeither from C or C++. The vtable format used for COM interfaces isdefined by the C/C++ compiler and is detailed in comBase.h where eachof the known compilers is enumerated and macros are defined forgenerating vtable structures, and filling in vtable instances.The registration of coclasses is handled by a table of registryinstances within this library. When comCoreLib is asked to create aninstance of a coclass, it searches the table of known registries (eachof which is itself a COM object, exposing the IRegistry interface),asking each in turn if it has the requested coclass (identified byCLSID) registered. If so, it will then ask the registry to create aninstance of the coclass.*//* includes */#include <stdlib.h>#include <string.h>#include <stdio.h>#include "taskLib.h"#include "comCoreLib.h"#include "comErr.h"#include "private/comRegistry.h"/* defines */#define COM_CORE_MAX_REGISTRIES 8#define COM_CORE_LIB_INIT() \ if (comCoreLibInitFlag == 0) \ { comCoreLibInit (); }/* globals *//* This flag records whether comCoreLib has been initialized. Since it * is possible that some of the API functions (particularly the * registration functions) may be called during program * initialisation, it is important that this library allows those * calls to succeed even if its init routine hasn't been called by the * normal startup (in VxWorks, at least). Subsequent calls to the init * routine simply return OK and carry on as normal. */static int comCoreLibInitFlag = 0;/* This causes a special symbol, whose name is derived from the vtable * format determined by the WIDL_XXX macros in comBase.h, to be * declared at this point as a global. In all other modules it will be * defined as an external and so will only link if all the modules in * the program are compiled with the same vtable format defined. */DECLARE_COM_VTBL_SYMBOL_HERE;/* * This global is here to supply a default for the DCOM priority * propagation feature, when building coclasses with WOTL. */int g_defaultServerPriority = 100;/* Array of reg-entries */static struct _comCoreRegEntry { char * regName; /* name of registry */ DWORD dwClsCtx; /* inproc/local/remote */ IRegistry * pRegistry; /* registry interface */ } comCoreRegistries [COM_CORE_MAX_REGISTRIES];/**************************************************************************** comCoreLibInit - Initialize the comCore library** Initialize the comCore library.** RETURNS: OK if init succeeded, ERROR if not*/STATUS comCoreLibInit (void) { if (comCoreLibInitFlag == 0) { ++comCoreLibInitFlag; return comRegistryInit (); } return OK; }/**************************************************************************** comCreateAny - creates an instance of a class or class-object** This function scans the registry table, looking for a registry* instance with the right class-context (inproc, local or remote) and* which has the class ID <clsid> registered.** RETURNS: S_OK on success, some other failure code otherwise.** NOMANUAL*/static HRESULT comCreateAny ( REFCLSID clsid, /* class ID */ IUnknown * pUnkOuter, /* aggregating interface */ DWORD dwClsCtx, /* class context */ const char * hint, /* service hint */ int classMode, /* get class object? */ ULONG cMQIs, /* number of MQIs */ MULTI_QI * pMQIs /* MQI array */ ) { HRESULT hr = REGDB_E_CLASSNOTREG; int i; IRegistry * pReg; /* Make sure the library is initialized... */ COM_CORE_LIB_INIT (); /* Work backwards through the table of known registries, ensuring * we catch the most-recently added registry first. */ for (i = COM_CORE_MAX_REGISTRIES-1; i >= 0; --i) { if ((comCoreRegistries[i].pRegistry != NULL) && ((comCoreRegistries[i].dwClsCtx & dwClsCtx) != 0)) { pReg = comCoreRegistries[i].pRegistry; /* Is the class registered? */ hr = IRegistry_IsClassRegistered (pReg, clsid); if (SUCCEEDED (hr)) { /* Create instance or Class-object? */ if (classMode) { hr = IRegistry_GetClassObject (pReg, clsid, pMQIs[0].pIID, dwClsCtx, hint, &pMQIs[0].pItf); } else { hr = IRegistry_CreateInstance (pReg, clsid, pUnkOuter, dwClsCtx, hint, cMQIs, pMQIs); } /* We can just exit the loop, and return whatever * result came back from the registry... */ break; } } } return hr; }/**************************************************************************** comInstanceCreate - creates an instance of a coclass** This function returns an instance of the coclass identified by* <clsid>, asking for the interface <iid>. It may be being aggregated,* in which case the argument <pUnkOuter> holds the controlling* IUnknown interface of the aggregating object.** RETURNS: S_OK on success, or an error indication if failure occurs* for some reason.*/HRESULT comInstanceCreate ( REFCLSID clsid, /* class ID */ IUnknown * pUnkOuter, /* aggregating interface */ DWORD dwClsCtx, /* class context */ const char * hint, /* service hint */ ULONG cMQIs, /* number of MQIs */ MULTI_QI * pMQIs /* MQI array */ ) { return comCreateAny (clsid, pUnkOuter, dwClsCtx, hint, FALSE, cMQIs, pMQIs); }/**************************************************************************** comClassObjectGet - returns a class object instance** This function returns the class-object for the coclass identified by* <clsid>, and asks for the interface <iid> which will usually, but* not always, be IClassFactory.** RETURNS:* \is* \i E_POINTER* ppvClsObj doesn't point to a valid piece of memory.* \i E_NOINTERFACE* The requested interface doesn't exist.* \i S_OK* On success* \ie*/HRESULT comClassObjectGet ( REFCLSID clsid, /* class ID */ DWORD dwClsCtx, /* class context */ const char * hint, /* service hint */ REFIID iid, /* class-obj IID */ void ** ppvClsObj /* resulting interface ptr */ ) { HRESULT hr;#ifdef __DCC__ MULTI_QI mqi[1]; mqi[0].pIID = iid; mqi[0].pItf = NULL; mqi[0].hr = S_OK;#else MULTI_QI mqi[] = { { iid, NULL, S_OK } };#endif if (! ppvClsObj) return E_POINTER; hr = comCreateAny (clsid, NULL, dwClsCtx,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -