comRegistry.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:9k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* comRegistry.c - COM core registry for in-memory coclasses */
  2. /* Copyright (c) 2001, Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01g,07aug01,dbs  return multiple interfaces during creation
  7. 01f,06aug01,dbs  add registry-show capability
  8. 01e,13jul01,dbs  fix warnings on IUnknown methods
  9. 01d,27jun01,dbs  fix include filenames
  10. 01c,25jun01,dbs  rename vtbl macros to COM_VTBL_XXX
  11. 01b,22jun01,dbs  remove commas from vtbl macros
  12. 01a,20jun01,dbs  written
  13. */
  14. #include <string.h>
  15. #include "private/comRegistry.h"
  16. #include "private/comSysLib.h"
  17. #define COM_REG_NAME "COM Core Registry"
  18. COM_VTABLE(IRegistry) _reg_vtbl = {
  19.     COM_VTBL_HEADER
  20.     /* IUnknown methods */
  21.     COM_VTBL_METHOD (&comRegistry_QueryInterface),
  22.     COM_VTBL_METHOD (&comRegistry_AddRef),
  23.     COM_VTBL_METHOD (&comRegistry_Release),
  24.     /* IRegistry methods */
  25.     COM_VTBL_METHOD (&comRegistry_RegisterClass),
  26.     COM_VTBL_METHOD (&comRegistry_IsClassRegistered),
  27.     COM_VTBL_METHOD (&comRegistry_CreateInstance),
  28.     COM_VTBL_METHOD (&comRegistry_GetClassObject),
  29.     COM_VTBL_METHOD (&comRegistry_GetClassID)
  30. };
  31. /**************************************************************************
  32. *
  33. * comRegistryInit - init function for this module
  34. *
  35. * This function must be called at system init time to add this
  36. * registry implementation to comCoreLib.
  37. *
  38. * RETURNS: 0 on success, -1 on failure
  39. *
  40. * NOMANUAL
  41. */
  42. int comRegistryInit (void)
  43.     {
  44.     COM_REG_CLASS *     pReg;
  45.     HRESULT             hr;
  46.     /* Create an instance of the registry class */
  47.     pReg = (COM_REG_CLASS*) comSysAlloc (sizeof (COM_REG_CLASS));
  48.     if (pReg == NULL)
  49.         return -1;
  50.     /* Initialize it */
  51.     pReg->lpVtbl = &_reg_vtbl;
  52.     pReg->dwRefCount = 0;
  53.     pReg->pEntries = NULL;
  54.     /* Register it with comCoreLib */
  55.     hr = comRegistryAdd (COM_REG_NAME,
  56.                          CLSCTX_INPROC_SERVER,
  57.                          (IRegistry*) pReg);
  58.     if (FAILED (hr))
  59.         return -1;
  60.     
  61.     return 0;
  62.     }
  63. /**************************************************************************
  64. *
  65. * RegisterClass - add get-class-object function to table
  66. *
  67. * RETURNS: S_OK always.
  68. *
  69. * NOMANUAL
  70. */
  71. HRESULT comRegistry_RegisterClass
  72.     (
  73.     IRegistry *         pReg,
  74.     REFCLSID            clsid,
  75.     void*               vpfnGetClassObject
  76.     )
  77.     {
  78.     COM_REG_CLASS *     pThis = (COM_REG_CLASS*) pReg;
  79.     COM_REG_ENTRY *     pEntry;
  80.     /* Create a new entry */
  81.     pEntry = (COM_REG_ENTRY*) comSysAlloc (sizeof (COM_REG_ENTRY));
  82.     if (pEntry == NULL)
  83.         return E_OUTOFMEMORY;
  84.     /* Fill it in */
  85.     memcpy (&pEntry->clsid, clsid, sizeof (CLSID));
  86.     pEntry->pfnGCO = (PFN_GETCLASSOBJECT) vpfnGetClassObject;
  87.     /* Link it into the list */
  88.     pEntry->pNext = pThis->pEntries;
  89.     pThis->pEntries = pEntry;
  90.     /* Done... */
  91.     return S_OK;
  92.     }
  93. /**************************************************************************
  94. *
  95. * IsClassRegistered - look for class ID in map
  96. *
  97. * RETURNS: S_OK if it is registered, REGDB_E_CLASSNOTREG if not.
  98. *
  99. * NOMANUAL
  100. */
  101. HRESULT comRegistry_IsClassRegistered
  102.     (
  103.     IRegistry *         pReg,
  104.     REFCLSID            clsid
  105.     )
  106.     {
  107.     COM_REG_CLASS *     pThis = (COM_REG_CLASS*) pReg;
  108.     COM_REG_ENTRY *     pEntry;
  109.     /* Iterate over the list looking for the CLSID */
  110.     for (pEntry = pThis->pEntries; pEntry != NULL; pEntry = pEntry->pNext)
  111.         {
  112.         if (comGuidCmp (&pEntry->clsid, clsid))
  113.             return S_OK;
  114.         }
  115.     /* Not found... */
  116.     return REGDB_E_CLASSNOTREG;
  117.     }
  118. /**************************************************************************
  119. *
  120. * CreateInstance - tries to create an instance of the coclass
  121. *
  122. * RETURNS: S_OK if the creation succeeded and all interfaces were
  123. *          present, or CO_S_NOTALLINTERFACES if some of the interfaces
  124. *          were not found.
  125. *
  126. * NOMANUAL
  127. */
  128. HRESULT comRegistry_CreateInstance
  129.     (
  130.     IRegistry *         pReg,
  131.     REFCLSID            clsid,
  132.     IUnknown*           pUnkOuter,
  133.     DWORD               dwClsCtx,
  134.     const char*         hint,
  135.     ULONG               cMQIs,
  136.     MULTI_QI *          pMQIs
  137.     )
  138.     {
  139.     IClassFactory *     pFactory = NULL;
  140.     HRESULT             hr;
  141.     HRESULT             hrTotal = S_OK;
  142.     IUnknown *          pUnk = NULL;
  143.     int                 i;
  144.     int                 n;
  145.     
  146.     /* Get class object... */
  147.     hr = comRegistry_GetClassObject (pReg,
  148.                                      clsid,
  149.                                      &IID_IClassFactory,
  150.                                      dwClsCtx,
  151.                                      hint,
  152.                                      (IUnknown**) &pFactory);
  153.     if (FAILED (hr))
  154.         return hr;
  155.     
  156.     /* Create an instance... */
  157.     hr = IClassFactory_CreateInstance (pFactory,
  158.                                        pUnkOuter,
  159.                                        &IID_IUnknown,
  160.                                        (void**) &pUnk);
  161.     if (FAILED (hr))
  162.         {
  163.         IUnknown_Release (pFactory);
  164.         return hr;
  165.         }
  166.     
  167.     /* Get the multiple interfaces... */
  168.     n = 0;
  169.     for (i=0; i < cMQIs; ++i)
  170.         {
  171.         hr = IUnknown_QueryInterface (pUnk,
  172.                                       pMQIs[i].pIID,
  173.                                       (void**) &pMQIs[i].pItf);
  174.         if (SUCCEEDED (hr))
  175.             ++n;
  176.         else
  177.             hrTotal = CO_S_NOTALLINTERFACES;
  178.         pMQIs[i].hr = hr;
  179.         }
  180.     /* Check we got some of the interfaces... */
  181.     if (n == 0)
  182.         hrTotal = E_NOINTERFACE;
  183.     
  184.     /* Release the IUnknown, and the factory, and return... */
  185.     IUnknown_Release (pUnk);
  186.     IUnknown_Release (pFactory);    
  187.     return hrTotal;
  188.     }
  189. /**************************************************************************
  190. *
  191. * GetClassObject - gets the class-object for the given coclass
  192. *
  193. * RETURNS: S_OK on success, one of other HRESULT codes on failure
  194. *
  195. * NOMANUAL
  196. */
  197. HRESULT comRegistry_GetClassObject
  198.     (
  199.     IRegistry *         pReg,
  200.     REFCLSID            clsid,
  201.     REFIID              iid,
  202.     DWORD               dwClsCtx,
  203.     const char*         hint,
  204.     IUnknown**          ppClsObj
  205.     )
  206.     {
  207.     COM_REG_CLASS *     pThis = (COM_REG_CLASS*) pReg;
  208.     COM_REG_ENTRY *     pEntry;
  209.     PFN_GETCLASSOBJECT  pfnGCO = NULL;
  210.     /* Validate args */
  211.     if (ppClsObj == NULL)
  212. return E_INVALIDARG;
  213.     if (dwClsCtx & (CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER))
  214. return E_NOTIMPL;
  215.     /* Search for the matching entry */
  216.     for (pEntry = pThis->pEntries; pEntry != NULL; pEntry = pEntry->pNext)
  217.         {
  218.         if (comGuidCmp (&pEntry->clsid, clsid))
  219.             {
  220.             /* Get GCO function pointer */
  221.             pfnGCO = pEntry->pfnGCO;
  222.             /* Return class-factory object... */
  223.             return (*pfnGCO) (clsid, iid, (void**) ppClsObj);
  224.             }
  225.         }
  226.     /* Not found... */
  227.     return REGDB_E_CLASSNOTREG;
  228.     }
  229. /**************************************************************************
  230. *
  231. */
  232. HRESULT comRegistry_GetClassID
  233.     (
  234.     IRegistry *         pReg,
  235.     DWORD               dwIndex,
  236.     LPCLSID             pclsid
  237.     )
  238.     {
  239.     COM_REG_CLASS *     pThis = (COM_REG_CLASS*) pReg;
  240.     COM_REG_ENTRY *     pEntry;
  241.     DWORD               ix = 0;
  242.     
  243.     /* Search for the N'th entry */
  244.     pEntry = pThis->pEntries;
  245.     while ((pEntry != NULL) && (ix < dwIndex))
  246.         {
  247.         pEntry = pEntry->pNext;
  248.         ++ix;
  249.         }
  250.     /* Did we find it? */
  251.     if ((pEntry == NULL) || (ix != dwIndex))
  252.         return E_FAIL;
  253.     /* We found it... */
  254.     memcpy (pclsid, &pEntry->clsid, sizeof (CLSID));
  255.     return S_OK;
  256.     }
  257. /**************************************************************************
  258. *
  259. */
  260. ULONG comRegistry_AddRef
  261.     (
  262.     IUnknown *          pReg
  263.     )
  264.     {
  265.     COM_REG_CLASS *     pThis = (COM_REG_CLASS*) pReg;
  266.     return ++pThis->dwRefCount;
  267.     }
  268. /**************************************************************************
  269. *
  270. */
  271. ULONG comRegistry_Release
  272.     (
  273.     IUnknown *          pReg
  274.     )
  275.     {
  276.     COM_REG_CLASS *     pThis = (COM_REG_CLASS*) pReg;
  277.     COM_REG_ENTRY *     pEntry;
  278.     DWORD               n;
  279.     n = --pThis->dwRefCount;
  280.     if (n == 0)
  281.         {
  282.         /* Destroy this object */
  283.         pEntry = pThis->pEntries;
  284.         while (pEntry != NULL)
  285.             {
  286.             COM_REG_ENTRY *p = pEntry;
  287.             pEntry = pEntry->pNext;
  288.             comSysFree (p);
  289.             }
  290.         comSysFree (pThis);
  291.         }
  292.     return n;
  293.     }
  294. /**************************************************************************
  295. *
  296. */
  297. HRESULT comRegistry_QueryInterface
  298.     (
  299.     IUnknown *          pReg,
  300.     REFIID         iid,
  301.     void**         ppv
  302.     )
  303.     {
  304.     /* Is it one of our own interfaces? */
  305.     if (comGuidCmp (iid, &IID_IUnknown) || comGuidCmp (iid, &IID_IRegistry))
  306. {
  307. *ppv = pReg;
  308.         IUnknown_AddRef (pReg);
  309. return S_OK;
  310. }
  311.     return E_NOINTERFACE;
  312.     }