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

VxWorks

开发平台:

C/C++

  1. /* RpcProxyMsg.cpp - VxDCOM RpcProxyMsg class implementation */
  2. /* Copyright (c) 1999 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 02c,17dec01,nel  Add include symbol for diab build.
  7. 02b,01oct01,nel  SPR#69557. Add extra padding bytes to make VT_BOOL type work.
  8. 02a,25sep01,nel  Correct prototype error under test harness build.
  9. 01z,02aug01,dbs  use simplified Thread API
  10. 01y,25jul01,dbs  simplify interface proxy system
  11. 01x,20jul01,dbs  fix include path of vxdcomGlobals.h
  12. 01w,13jul01,dbs  fix up includes
  13. 01v,29feb00,dbs  fix ORPC_EXTENT so its still inscope when marshaled
  14. 01u,28feb00,dbs  use correct ThreadOS method to get/set priority
  15. 01t,15feb00,dbs  fix addition of extent to ORPC msg
  16. 01s,19jan00,nel  Fix include of taskLib.h in Solaris build
  17. 01r,17nov99,nel  Include taskLib.h
  18. 01q,19aug99,aim  change assert to VXDCOM_ASSERT
  19. 01p,13aug99,aim  moved globals to vxdcomGlobals.h
  20. 01o,05aug99,dbs  change to byte instead of char
  21. 01n,30jul99,dbs  add client fake prio in Solaris
  22. 01m,29jul99,drm  Adding code to conditionally send client priority.
  23. 01l,09jul99,drm  Adding code to add a VXDCOM_EXTENT to an ORPCTHIS.
  24. 01k,09jul99,dbs  remove references to obsolete files
  25. 01j,06jul99,aim  change from RpcBinding to RpcIfClient
  26. 01i,25jun99,dbs  add auth-trailer to stub-msg
  27. 01h,17jun99,aim  changed assert to assert
  28. 01g,17jun99,dbs  change to COM_MEM_ALLOC
  29. 01f,20may99,dbs  move NDR phase into streams
  30. 01e,19may99,dbs  fix up priority encoding
  31. 01d,19may99,dbs  fix ORPCTHIS insertion to marshal correctly
  32. 01c,18may99,dbs  add proxy/stub marshaling phase to NDR-streams
  33. 01b,17may99,dbs  fix DCE usage of class
  34. 01a,12may99,dbs  created
  35. */
  36. /*
  37.   DESCRIPTION:
  38. */
  39. #include "RpcProxyMsg.h"
  40. #include "orpcLib.h"
  41. #include "StdProxy.h"
  42. #include "vxdcomExtent.h"
  43. #include "private/vxdcomGlobals.h"
  44. #include "Syslog.h"
  45. #include "TraceCall.h"
  46. #include "RpcPduFactory.h"
  47. #include "InterfaceProxy.h"
  48. #include "taskLib.h"
  49. /* Include symbol for diab */
  50. extern "C" int include_vxdcom_RpcProxyMsg (void)
  51.     {
  52.     return 0;
  53.     }
  54. //////////////////////////////////////////////////////////////////////////
  55. //
  56. // RPC_STUB_MSG methods...
  57. //
  58. RPC_STUB_MSG::RPC_STUB_MSG
  59.     (
  60.     NdrUnmarshalStream* pus,
  61.     NdrMarshalStream* pms,
  62.     int channelId
  63.     )
  64.   : m_pUnmshlStrm (pus),
  65.     m_pMshlStrm (pms),
  66.     m_channelId (channelId)
  67.     {
  68.     TRACE_CALL;
  69.     }
  70. NdrMarshalStream* RPC_STUB_MSG::marshalStreamGet ()
  71.     {
  72.     TRACE_CALL;
  73.     COM_ASSERT(m_pMshlStrm);
  74.     return m_pMshlStrm;
  75.     }
  76. NdrUnmarshalStream* RPC_STUB_MSG::unmarshalStreamGet ()
  77.     {
  78.     TRACE_CALL;
  79.     COM_ASSERT(m_pUnmshlStrm);
  80.     return m_pUnmshlStrm;
  81.     }
  82. int RPC_STUB_MSG::channelIdGet ()
  83.     {
  84.     TRACE_CALL;
  85.     return m_channelId;
  86.     }
  87. //////////////////////////////////////////////////////////////////////////
  88. //
  89. // RPC_PROXY_MSG methods -- this wrapper-class is exposed to the user
  90. // in dcomProxy.h, but its internal implementation is provided by the
  91. // RpcProxyMsg class...
  92. //
  93. RPC_PROXY_MSG::RPC_PROXY_MSG
  94.     (
  95.     REFIID riid,
  96.     RpcMode::Mode_t mode,
  97.     ULONG opnum,
  98.     void* pv
  99.     )
  100.     {
  101.     TRACE_CALL;
  102.     m_pImpl = new RpcProxyMsg (riid, mode, opnum, pv);
  103.     }
  104. RPC_PROXY_MSG::~RPC_PROXY_MSG ()
  105.     {
  106.     TRACE_CALL;
  107.     if (m_pImpl)
  108. delete m_pImpl;
  109.     }
  110. HRESULT RPC_PROXY_MSG::SendReceive ()
  111.     {
  112.     TRACE_CALL;
  113.     COM_ASSERT(m_pImpl);
  114.     return m_pImpl->SendReceive ();
  115.     }
  116. NdrMarshalStream* RPC_PROXY_MSG::marshalStreamGet ()
  117.     {
  118.     TRACE_CALL;
  119.     COM_ASSERT(m_pImpl);
  120.     return m_pImpl->marshalStreamGet ();
  121.     }
  122. NdrUnmarshalStream* RPC_PROXY_MSG::unmarshalStreamGet ()
  123.     {
  124.     TRACE_CALL;
  125.     COM_ASSERT(m_pImpl);
  126.     return m_pImpl->unmarshalStreamGet ();
  127.     }
  128. //////////////////////////////////////////////////////////////////////////
  129. //
  130. // RpcProxyMsg::RpcProxyMsg -- ctor initialises rpc-mode and
  131. // marshaling streams. The argument 'punk' is NULL for DCE-mode
  132. // interface proxies, and must be non-NULL for OBJECT mode...
  133. //
  134. RpcProxyMsg::RpcProxyMsg
  135.     (
  136.     REFIID riid,
  137.     RpcMode::Mode_t mode,
  138.     ULONG opnum,
  139.     void* pv
  140.     )
  141.       : m_mode (mode),
  142. m_mshlStrm (NdrPhase::PROXY_MSHL, ORPC_WIRE_DREP),
  143. m_unmshlStrm (),
  144. m_punkItfPtr (0),
  145. m_iid (riid),
  146. m_opnum (opnum),
  147. m_pReply (0),
  148. m_pChannel (0)
  149.     {
  150.     // If this transaction is in object-mode, we need to add the
  151.     // ORPCTHIS info to the marshaling buffer before doing the
  152.     // argument marshaling...
  153.     if (mode == RpcMode::OBJECT)
  154. {
  155. bool addPrio = false;
  156. int  clientPriority=0;
  157. // Before we generate the ORPCTHIS, we need to see if we can
  158. // get the current thread's priority, so it can be propagated
  159. // to the server end...
  160.         if (g_clientPriorityPropagation &&
  161.             (::taskPriorityGet (::taskIdSelf (), &clientPriority)))
  162.             {
  163.     addPrio = true;
  164.             }
  165. // Now we declare all the ORPCTHIS-related variables, ready
  166. // for marshaling into the stream ahead of the method args...
  167. GUID causality = GUID_NULL;
  168. VXDCOM_EXTENT ext (clientPriority);
  169. ORPC_EXTENT* exts [2] = { &ext, 0 };
  170. ORPC_EXTENT_ARRAY extArray = { 2, 0, exts };
  171. ORPCTHIS orpcThis =
  172.     {
  173. {
  174.     RpcPduFactory::rpcMajorVersion (),
  175.     RpcPduFactory::rpcMinorVersion ()
  176. },
  177. ORPCF_NULL,
  178. 0,
  179. causality,
  180. addPrio ? &extArray : 0
  181.     };
  182. ndrMarshalORPCTHIS (&m_mshlStrm, &orpcThis);
  183. m_punkItfPtr = reinterpret_cast<IUnknown*> (pv);
  184. }
  185.     else
  186. {
  187.         // Non-object (DCE) mode, so the <pv> argument is actually the
  188.         // ORPC client channel...
  189. m_pChannel = reinterpret_cast<IOrpcClientChannel*> (pv);
  190. }
  191.     }
  192. //////////////////////////////////////////////////////////////////////////
  193. //
  194. // RpcProxyMsg::~RpcProxyMsg -- dtor
  195. //
  196. RpcProxyMsg::~RpcProxyMsg ()
  197.     {
  198.     TRACE_CALL;
  199.     if (m_pReply)
  200.         delete [] m_pReply;
  201.     }
  202. //////////////////////////////////////////////////////////////////////////
  203. //
  204. // RpcProxyMsg::SendReceive -- performs the actual (O)RPC transaction
  205. // over the wire. On entry, the stub-data has already been marshaled
  206. // into the marshaling stream, and we have been initialised with the
  207. // interface ID and IPID that we need...
  208. //
  209. HRESULT RpcProxyMsg::SendReceive ()
  210.     {
  211.     TRACE_CALL;
  212.     HRESULT hr = S_OK;
  213.     
  214.     // Get interface-ptr ID and RPC-binding if we are in object mode,
  215.     // and we don't yet have them. If we are in DCE mode we already
  216.     // have the info we need to perform the transaction...
  217.     if ((m_mode == RpcMode::OBJECT) && ! m_pChannel)
  218. {
  219.         // Remember (see InterfaceProxy.h) that the XXX_vxproxy
  220.         // functions generated by WIDL form the methods of the proxied
  221.         // interface -- in the 'standard marshaling' case this is
  222.         // always an instance of VxInterfaceProxy. Thus, we need to
  223.         // find our way back to that instance, in order to get hold of
  224.         // the necessary per-proxy information we need to dispatch the
  225.         // remote method. This info is basically the channel-pointer,
  226.         // plus the IPID which is required by the protocol...
  227.         VxInterfaceProxy* pItf = VxInterfaceProxy::safe_cast (m_punkItfPtr);
  228.         if (! pItf)
  229.             return E_UNEXPECTED;
  230.         // Now get the IPID and the client-channel...
  231.         hr = pItf->interfaceInfoGet (&m_ipid, &m_pChannel);
  232.         if (FAILED (hr))
  233.             return hr;
  234. }
  235.     // Add any extra pading required.
  236.     if (m_mshlStrm.getEndPadding () != 0)
  237.         {
  238.         BYTE b = 0xFF;
  239.         DWORD count;
  240.         for (count = 0; count < m_mshlStrm.getEndPadding (); count++)
  241.             {
  242.          m_mshlStrm.insert (sizeof (BYTE), &b, false);
  243.             }
  244.         }
  245.     // Now build a MSHL_BUFFER for the in-args...
  246.     MSHL_BUFFER inbuf = { m_mshlStrm.begin (),
  247.                           m_mshlStrm.size (),
  248.                           m_mshlStrm.drep () };
  249.                           
  250.     // And one for the returned args and result...
  251.     MSHL_BUFFER outbuf = { 0, 0, 0 };
  252.     // Invoke the method, saving the HRESULT for later...
  253.     hr = m_pChannel->InvokeMethod (m_iid,
  254.                                    m_mode == RpcMode::DCE ? 0 : &m_ipid,
  255.                                    m_opnum,
  256.                                    &inbuf,
  257.                                    &outbuf);
  258.     // @@@ FIXME multiple copies going on here -- NdrMarshalStream
  259.     // should inherit from MSHL_BUFFER perhaps?
  260.     
  261.     // Copy resulting stub-data to some local memory, which will stay
  262.     // around after this function returns...
  263.     COM_ASSERT(m_pReply == 0);
  264.     m_pReply = new byte [outbuf.len];
  265.     if (! m_pReply)
  266. return E_OUTOFMEMORY;
  267.     memcpy (m_pReply, outbuf.buf, outbuf.len);
  268.     // create a new unmarshal stream from the returned stub-data
  269.     m_unmshlStrm = NdrUnmarshalStream (NdrPhase::PROXY_UNMSHL,
  270.        outbuf.drep,
  271.        m_pReply,
  272.        outbuf.len);
  273.     // Release the MSHL_BUFFER...
  274.     m_pChannel->FreeBuffer (&outbuf);
  275.     // Finished with the channel for now...
  276.     m_pChannel = 0;
  277.     
  278.     // NOW check the HRESULT of the invocation, after having tidied
  279.     // up the marshaling buffers, etc...
  280.     if (FAILED (hr))
  281. return hr;
  282.     // extract the ORPCTHAT if in OBJECT mode
  283.     if (m_mode == RpcMode::OBJECT)
  284. hr = m_unmshlStrm.extract (sizeof (ORPCTHAT), 0, false);
  285.     // return and let the proxy handle the remaining unmarshaling
  286.     return hr;
  287.     }
  288. //////////////////////////////////////////////////////////////////////////
  289. //
  290. // RpcProxyMsg::marshalStreamGet -- returns the address of the
  291. // marshaling stream...
  292. //
  293. NdrMarshalStream* RpcProxyMsg::marshalStreamGet ()
  294.     {
  295.     return &m_mshlStrm;
  296.     }
  297. //////////////////////////////////////////////////////////////////////////
  298. //
  299. // RpcProxyMsg::unmarshalStreamGet -- returns the address of the
  300. // unmarshaling stream...
  301. //
  302. NdrUnmarshalStream* RpcProxyMsg::unmarshalStreamGet ()
  303.     {
  304.     return &m_unmshlStrm;
  305.     }