RemoteRegistry.cpp
上传用户:baixin
上传日期:2008-03-13
资源大小:4795k
文件大小:8k
开发平台:

MultiPlatform

  1. /* RemoteRegistry.cpp - DCOM remote registry */
  2. /* Copyright (c) 2001 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01d,03jan02,nel  Remove T2OLE.
  7. 01c,17dec01,nel  Add include symbol for diab.
  8. 01b,16aug01,nel  Correct error code for invalid hint.
  9. 01a,07aug01,dbs  written
  10. */
  11. /*
  12. DESCRIPTION
  13. This class is used to create remote instances of COM classes. It takes
  14. the 'hint' parameter to IRegistry::CreateInstance() as being the
  15. remote server address, and so attempts to create an instance there.
  16. Since it is impossible to know whether the remote server exists, or if
  17. it does indeed have that class registered, this registry always
  18. responds with S_OK when asked IsClassRegistered(), even though it
  19. doesn't actually know.
  20. Then, when it asked to create an instance, or to get the class-object,
  21. it attempts to establish communication with the remote server via
  22. the IRemoteActivation DCE interface, and to get the requested object
  23. that way.
  24. */
  25. #include "RemoteRegistry.h"
  26. #include "RpcStringBinding.h"
  27. #include "orpc.h"
  28. #include "orpcLib.h"
  29. #include "SCM.h"
  30. #include "RemoteActivation.h"
  31. #include "RpcIfClient.h"
  32. /* Include symbol for diab */
  33. extern "C" int include_vxdcom_RemoteRegistry (void)
  34.     {
  35.     return 0;
  36.     }
  37. //////////////////////////////////////////////////////////////////////////
  38. //
  39. // dcomRemoteRegistryInit - initialize the remote-registry
  40. //
  41. int dcomRemoteRegistryInit ()
  42.     {
  43.     IRegistry* pReg;
  44.     HRESULT hr = RemoteRegistryClass::CreateInstance (0,
  45.                                                       IID_IRegistry,
  46.                                                       (void**) &pReg);
  47.     if (FAILED (hr))
  48.         return hr;
  49.     hr = comRegistryAdd ("Remote Registry",
  50.                          CLSCTX_REMOTE_SERVER,
  51.                          pReg);
  52.     pReg->Release ();
  53.     return hr;
  54.     }
  55. //////////////////////////////////////////////////////////////////////////
  56. //
  57. RemoteRegistry::RemoteRegistry ()
  58.     {
  59.     }
  60. //////////////////////////////////////////////////////////////////////////
  61. //
  62. RemoteRegistry::~RemoteRegistry ()
  63.     {
  64.     }
  65. //////////////////////////////////////////////////////////////////////////
  66. //
  67. // RegisterClass - add a class to the registry
  68. //
  69. // Since we don't actually keep track of remote classes, we don't need
  70. // to do anything.
  71. //
  72. HRESULT RemoteRegistry::RegisterClass
  73.     (
  74.     REFCLSID                clsid,
  75.     void *                  pfnGetClassObject
  76.     )
  77.     {
  78.     return S_OK;
  79.     }
  80. //////////////////////////////////////////////////////////////////////////
  81. //
  82. // IsClassRegistered - determine if the class is registered
  83. //
  84. // This method always returns S_OK, as it doesn't know if the class is
  85. // registered or not until it tries to contact the remote server.
  86. //
  87. HRESULT RemoteRegistry::IsClassRegistered
  88.     (
  89.     REFCLSID                clsid
  90.     )
  91.     {
  92.     return S_OK;
  93.     }
  94. //////////////////////////////////////////////////////////////////////////
  95. //
  96. // CreateInstance - creates a remote instance of the class
  97. //
  98. // 
  99. //
  100. HRESULT RemoteRegistry::CreateInstance
  101.     (
  102.     REFCLSID                clsid,
  103.     IUnknown *              pUnkOuter,
  104.     DWORD                   dwClsContext,
  105.     const char *            hint,
  106.     ULONG                   cMQIs,
  107.     MULTI_QI *              pMQIs
  108.     )
  109.     {
  110.     return instanceCreate (false,
  111.                            clsid,
  112.                            pUnkOuter,
  113.                            dwClsContext,
  114.                            hint,
  115.                            cMQIs,
  116.                            pMQIs);
  117.     }
  118. //////////////////////////////////////////////////////////////////////////
  119. //
  120. // GetClassObject - instantiate a remote class object
  121. //
  122. HRESULT RemoteRegistry::GetClassObject
  123.     (
  124.     REFCLSID                clsid,
  125.     REFIID                  iid,
  126.     DWORD                   dwClsContext,
  127.     const char *            hint,
  128.     IUnknown **             ppClsObj
  129.     )
  130.     {
  131.     MULTI_QI mqi[] = { { &iid, 0, S_OK } };
  132.     HRESULT hr = instanceCreate (true,
  133.                                  clsid,
  134.                                  0,
  135.                                  dwClsContext,
  136.                                  hint,
  137.                                  1,
  138.                                  mqi);
  139.     if (FAILED (hr))
  140.         return hr;
  141.     if (ppClsObj)
  142.         *ppClsObj = mqi[0].pItf;
  143.     return mqi[0].hr;
  144.     }
  145. //////////////////////////////////////////////////////////////////////////
  146. //
  147. // GetClassID - for iterating over all registered class IDs
  148. //
  149. // As we don't keep track of them, we don't have naything to return.
  150. //
  151. HRESULT RemoteRegistry::GetClassID
  152.     (
  153.     DWORD                   dwIndex,
  154.     LPCLSID                 pclsid
  155.     )
  156.     {
  157.     return E_FAIL;
  158.     }
  159.     
  160. //////////////////////////////////////////////////////////////////////////
  161. //
  162. // instanceCreate - create a remote instance of a server class
  163. //
  164. // This method is used to create remote instances of classes.
  165. //
  166. HRESULT RemoteRegistry::instanceCreate
  167.     (
  168.     bool                    classMode,
  169.     REFCLSID                clsid,
  170.     IUnknown *              pUnkOuter,
  171.     DWORD                   dwClsContext,
  172.     const char *            hint,
  173.     ULONG                   cMQIs,
  174.     MULTI_QI *              pMQIs
  175.     )
  176.     {
  177.     // Validate args...
  178.     if (pUnkOuter)
  179.         return CLASS_E_NOAGGREGATION;
  180.     if (!(dwClsContext & CLSCTX_REMOTE_SERVER))
  181.         return E_INVALIDARG;
  182.     if ((! hint) || (strlen (hint) == 0))
  183.         return REGDB_E_CLASSNOTREG;
  184.     // Create a string-binding representing the remote SCM...
  185.     RpcStringBinding sbRemoteScm (hint,
  186.   NCACN_IP_TCP,
  187.   VXDCOM_SCM_ENDPOINT);
  188.     // Get the formatted address of the remote SCM, with the protseq
  189.     // but no port-number...
  190.     LPWSTR remAddr = new OLECHAR [strlen (sbRemoteScm.formatted (false)) + 1];
  191.     
  192.     comAsciiToWide (remAddr,
  193.             sbRemoteScm.formatted (false),
  194.     strlen (sbRemoteScm.formatted (false)) + 1);
  195.     
  196.     // Copy IIDs into array...
  197.     IID iids [_ACTIVATION_MAX];
  198.     {
  199.     DWORD n;
  200.     for (n=0; n < cMQIs; ++n)
  201.         iids [n] = *(pMQIs[n].pIID);
  202.     }
  203.     // Results will be received here...
  204.     MInterfacePointer* pItfData [_ACTIVATION_MAX];
  205.     HRESULT hResults [_ACTIVATION_MAX];
  206.     // Find our local SCM...
  207.     SCM* pscm = SCM::theSCM ();
  208.     
  209.     // Ask SCM for indirect activation of remote server...
  210.     HRESULT hr = pscm->IndirectActivation (remAddr,
  211.                                            clsid,
  212.                                            classMode ? MODE_GET_CLASS_OBJECT : 0,
  213.                                            cMQIs,
  214.                                            iids,
  215.                                            pItfData,
  216.                                            hResults);
  217.     if (FAILED (hr))
  218. {
  219. delete []remAddr;
  220.         return hr;
  221. }
  222.     
  223.     // Unmarshal the interface pointers - for this we need an IStream
  224.     // implementation, supplied by VxRWMemStream...
  225.     ULONG j;
  226.     for (j=0; j < cMQIs; ++j)
  227.         {
  228.         if (pItfData [j])
  229.             {
  230.             VxRWMemStream   memStrm;
  231.             // make sure we don't try to delete it!
  232.             memStrm.AddRef ();
  233.             // Initialise stream from the MInterfacePointer...
  234.             memStrm.insert (pItfData [j]->abData,
  235.                             pItfData [j]->ulCntData);
  236.             memStrm.locationSet (0);
  237.             // Unmarshal the stream
  238.             pMQIs[j].hr = CoUnmarshalInterface (static_cast<IStream*> (&memStrm),
  239.                                                 *(pMQIs[j].pIID),
  240.                                                 (void**) &pMQIs[j].pItf);
  241.             if (FAILED (pMQIs[j].hr))
  242.                 {
  243.                 hr = pMQIs[j].hr;
  244.                 break;
  245.                 }
  246.             }
  247.         else
  248.             pMQIs[j].pItf = 0;
  249.         }
  250.     delete []remAddr;
  251.     return hr;
  252.     }