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

VxWorks

开发平台:

C/C++

  1. /* StdMarshaler.cpp - COM/DCOM StdMarshaler class implementation */
  2. /* Copyright (c) 1999 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01y,17dec01,nel  Add include symbol for diab.
  7. 01x,13jul01,dbs  fix up includes
  8. 01w,16jul99,aim  replace resolverAddressGet => rpcAddressFormat
  9. 01v,09jul99,dbs  change to new ObjectExporter naming
  10. 01u,29jun99,dbs  make StdStub a member of ObjectTableEntry
  11. 01t,17jun99,aim  uses new SCM
  12. 01s,10jun99,dbs  remove op new and delete
  13. 01r,03jun99,dbs  no return value from mutex lock
  14. 01q,03jun99,dbs  remove refs to comSyncLib
  15. 01p,03jun99,dbs  remove reliance on TLS from CoMarshalInterface
  16. 01o,24may99,dbs  ask SCM for local object exporter
  17. 01n,20may99,dbs  move NDR phase into streams
  18. 01m,18may99,dbs  remove old marshaling scheme
  19. 01l,11may99,dbs  rename VXCOM to VXDCOM
  20. 01k,07may99,dbs  fix up call to SCM method
  21. 01j,30apr99,dbs  change name of ComSCM to SCM
  22. 01i,29apr99,dbs  fix -Wall warnings
  23. 01h,28apr99,dbs  use COM_MEM_ALLOC for all classes
  24. 01g,27apr99,dbs  use new allocation calls
  25. 01f,27apr99,dbs  add mem-pool to class
  26. 01e,26apr99,aim  added TRACE_CALL
  27. 01d,23apr99,dbs  use NEW() to create objects
  28. 01c,22apr99,dbs  tidy up potential leaks
  29. 01b,21apr99,dbs  add length arg to orpcDSAFormat()
  30. 01a,20apr99,dbs  created during Grand Renaming
  31. */
  32. /*
  33.   DESCRIPTION:
  34.   StdMarshaler -- 
  35. */
  36. #include "StdMarshaler.h"
  37. #include "RemoteActivation.h"
  38. #include "ObjectExporter.h"
  39. #include "StdStub.h"
  40. #include "SCM.h"
  41. #include "dcomProxy.h"
  42. #include "orpcLib.h"
  43. #include "private/comMisc.h"
  44. #include "NdrStreams.h"
  45. /* Include symbol for diab */
  46. extern "C" int include_vxdcom_StdMarshaler (void)
  47.     {
  48.     return 0;
  49.     }
  50. //////////////////////////////////////////////////////////////////////////
  51. //
  52. // GetUnmarshalClass - for the std proxy, the unmarshaling class is
  53. // always CLSID_StdMarshal, for the supported interface types...
  54. //
  55. HRESULT VxStdMarshaler::GetUnmarshalClass
  56.     (
  57.     REFIID riid,
  58.     void* pv,
  59.     DWORD  dwDestContext,
  60.     void* pvDestContext,
  61.     DWORD mshlflags,
  62.     CLSID* pClsid
  63.     )
  64.     {
  65.     TRACE_CALL;
  66.     if ((riid == IID_IUnknown) ||
  67. (riid == IID_IClassFactory))
  68. {
  69. *pClsid = CLSID_StdMarshal;
  70. return S_OK;
  71. }
  72.     return E_NOTIMPL;
  73.     }
  74. //////////////////////////////////////////////////////////////////////////
  75. //
  76. // GetMarshalSizeMax - returns max size of std marshaling packet...
  77. //
  78. HRESULT VxStdMarshaler::GetMarshalSizeMax
  79.     (
  80.     REFIID riid,
  81.     void* pv,
  82.     DWORD dwDestContext,
  83.     void* pvDestContext,
  84.     DWORD mshlflags,
  85.     DWORD* pSize
  86.     )
  87.     {
  88.     TRACE_CALL;
  89.     *pSize = OBJREF_MAX;
  90.     return S_OK;
  91.     }
  92.         
  93. //////////////////////////////////////////////////////////////////////////
  94. //
  95. // MarshalInterface - does the real business of marshaling into the
  96. // given stream enough information to construct a proxy in the client
  97. // process. This means creating an RPC channel object, and writing its
  98. // identifier into the stream (the VxWorks single address space
  99. // architecture ensures that the interface ptr is still valid in the
  100. // client task).
  101. //
  102. // Then, an entry is made into the GOT (Global Object Table), which
  103. // will be used when unmarshaling. This entry pre-dates the entry
  104. // that will be made by CoMarshalInterface anyway, and so if that
  105. // function finds there is already an entry it will be re-used...
  106. //
  107. // The std marshaling packet looks like:-
  108. //   1. OBJREF of marshaled interface
  109. //   2. mshlflags
  110. //
  111. // Note that the RPC-channel for the server is not created until 
  112. // a client tries to connect to the object-exporter exporting that
  113. // object.
  114. //
  115. HRESULT VxStdMarshaler::MarshalInterface
  116.     (
  117.     IStream* pStm,
  118.     REFIID riid,
  119.     void* pvInterface,
  120.     DWORD dwDestContext,
  121.     void* pvDestContext,
  122.     DWORD mshlflags
  123.     )
  124.     {
  125.     TRACE_CALL;
  126.     OBJREF* pObjRef = 0;
  127.     IPID        ipidNew = GUID_NULL;
  128.     BSTR        bsResAddr;
  129.     OLECHAR bsSecInfo [] = { 0x0A, 0xFFFF, 0 };
  130.     const int   cRefs = 5;
  131.     // Get 'SCM addesss binding.
  132.     HRESULT hr = SCM::theSCM ()->addressBinding (&bsResAddr);
  133.     if (FAILED (hr))
  134. return hr;
  135.     
  136.     // Find OXID of our exporter
  137.     ObjectExporter* px = SCM::objectExporter ();
  138.     OXID oxid = px->oxid ();
  139.     // Update the Exporters object-table...
  140.     ObjectTableEntry* pOTE = px->objectFindByOid (m_oid);
  141.     if (pOTE)
  142. {
  143. pOTE->stdStub.adopt (reinterpret_cast<IUnknown*> (pvInterface),
  144.      m_oid);
  145. hr = pOTE->stdStub.interfaceAdd (riid, cRefs, &ipidNew);
  146. if (FAILED (hr))
  147.     return hr;
  148. }
  149.     
  150.     // Fill in the OBJREF for this object...
  151.     const DWORD dsaLen = sizeof (DUALSTRINGARRAY) +
  152.  (2 * SysStringLen (bsResAddr)) +
  153.  (2 * vxcom_wcslen (bsSecInfo)) +
  154.  16;
  155.        
  156.     pObjRef = (OBJREF*) malloc (sizeof (OBJREF) + dsaLen);
  157.     if (! pObjRef)
  158. return E_OUTOFMEMORY;
  159.     pObjRef->signature = OBJREF_SIGNATURE;
  160.     pObjRef->flags = OBJREF_STANDARD;
  161.     pObjRef->iid = riid;
  162.     pObjRef->u_objref.u_standard.std.flags = 0;
  163.     pObjRef->u_objref.u_standard.std.cPublicRefs = cRefs;
  164.     pObjRef->u_objref.u_standard.std.oxid = oxid;
  165.     pObjRef->u_objref.u_standard.std.oid = m_oid;
  166.     pObjRef->u_objref.u_standard.std.ipid = ipidNew;
  167.     // Fill in the DSA with the address info from the resolver...
  168.     hr = orpcDSAFormat (&pObjRef->u_objref.u_standard.saResAddr,
  169. dsaLen,
  170. bsResAddr,
  171. bsSecInfo);
  172.     // Now marshal the OBJREF into the marshaling packet, so it can be
  173.     // accessed by the proxy...
  174.     NdrMarshalStream ms (NdrPhase::PROXY_MSHL,
  175.  VXDCOM_DREP_LITTLE_ENDIAN);
  176.     
  177.     hr = ndrMarshalOBJREF (&ms, pObjRef);
  178.     if (FAILED (hr))
  179. return hr;
  180.     hr = pStm->Write (ms.begin (), ms.size (), 0);
  181.     if (FAILED (hr))
  182. return hr;
  183.     
  184.     // Tidy up
  185.     free (pObjRef);
  186.     SysFreeString (bsResAddr);
  187.     return hr;
  188.     }
  189. //////////////////////////////////////////////////////////////////////////
  190. //
  191. // VxStdMarshaler::AddRef - add a reference
  192. //
  193. ULONG VxStdMarshaler::AddRef ()
  194.     {
  195.     TRACE_CALL;
  196.     m_mutex.lock ();
  197.     ++m_dwRefCount;
  198.     m_mutex.unlock ();
  199.     return m_dwRefCount;
  200.     }
  201. //////////////////////////////////////////////////////////////////////////
  202. //
  203. // VxStdMarshaler::Release - remove a reference, destroy if no refs
  204. // remain extant...
  205. //
  206. ULONG VxStdMarshaler::Release ()
  207.     {
  208.     TRACE_CALL;
  209.     m_mutex.lock ();
  210.     DWORD n = --m_dwRefCount;
  211.     m_mutex.unlock ();
  212.     if (n == 0)
  213. delete this;
  214.     return n;
  215.     }
  216. //////////////////////////////////////////////////////////////////////////
  217. //
  218. // QueryInterface - implements QI functionality for the standard
  219. // marshaler object, which only supports IUnknown and IMarshal...
  220. //
  221. HRESULT VxStdMarshaler::QueryInterface
  222.     (
  223.     REFIID riid,
  224.     void** ppv
  225.     )
  226.     {
  227.     TRACE_CALL;
  228.     // Is it one of our own interfaces?
  229.     if ((riid == IID_IUnknown) || (riid == IID_IMarshal))
  230. {
  231. *ppv = this;
  232.         AddRef ();
  233. return S_OK;
  234. }
  235.     return E_NOINTERFACE;
  236.     }