Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

461 lines
9.5 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: CPKT.CXX
  7. //
  8. // Contents: CPkt implementation for RPC/LRPC
  9. //
  10. // Functions:
  11. //
  12. // History: 30-Mar-94 BobDay Adapted from 16-bit OLE2.0, CPKT.CPP
  13. //
  14. //--------------------------------------------------------------------------
  15. #include <headers.cxx>
  16. #pragma hdrstop
  17. #include <ole2ver.h>
  18. #include <ole2sp.h>
  19. #include "rpc16.hxx"
  20. #include "comlocal.hxx"
  21. //
  22. // Standard IUnknown method. Not used but need to be supported to comply
  23. // with the IUnknown.
  24. //
  25. STDMETHODIMP CPkt::QueryInterface(
  26. REFIID iidInterface,
  27. void FAR* FAR* ppvObj )
  28. {
  29. HRESULT hresult;
  30. // Three interfaces supported (each, and extension of the previous):
  31. // IUnknown, IStream, ICPkt
  32. if ( (iidInterface == IID_CPkt ||
  33. iidInterface == IID_IStream ||
  34. iidInterface == IID_IUnknown )) {
  35. m_refs++; // A pointer to this object is returned
  36. *ppvObj = this;
  37. hresult = NOERROR;
  38. }
  39. else { // Not accessible or unsupported interface
  40. *ppvObj = NULL;
  41. hresult = ResultFromScode(E_NOINTERFACE);
  42. }
  43. return hresult;
  44. }
  45. //
  46. // Called when CPkt is referenced by an additional pointer.
  47. //
  48. STDMETHODIMP_(ULONG) CPkt::AddRef(void)
  49. {
  50. return ++m_refs;
  51. }
  52. //
  53. // Called when a pointer to this CPkt is discarded
  54. //
  55. STDMETHODIMP_(ULONG) CPkt::Release(void)
  56. {
  57. if (--m_refs != 0) // Still used by others
  58. return m_refs;
  59. if (m_rom16.Buffer != NULL)
  60. {
  61. TaskFree(m_rom16.Buffer);
  62. }
  63. delete this; // Free storage
  64. return 0;
  65. }
  66. STDMETHODIMP CPkt::Read(void HUGEP* pb, ULONG cb, ULONG FAR* pcbRead)
  67. {
  68. HRESULT hresult = NOERROR;
  69. ULONG cbRead = cb;
  70. if (pcbRead != NULL)
  71. {
  72. *pcbRead = 0;
  73. }
  74. if (cbRead + m_pos > m_rom16.cbBuffer) {
  75. if (m_pos < m_rom16.cbBuffer)
  76. {
  77. cbRead = m_rom16.cbBuffer - m_pos;
  78. }
  79. else
  80. {
  81. cbRead = 0;
  82. }
  83. hresult = ResultFromScode(E_UNSPEC); // PKT (tried to read passed EOS)
  84. }
  85. if ( cbRead != 0 )
  86. {
  87. hmemcpy(pb,(LPSTR)m_rom16.Buffer + m_pos, cbRead);
  88. m_pos += cbRead;
  89. }
  90. if (pcbRead != NULL)
  91. {
  92. *pcbRead = cbRead;
  93. }
  94. return hresult;
  95. }
  96. STDMETHODIMP CPkt::Write(void const HUGEP* pb, ULONG cb, ULONG FAR* pcbWritten)
  97. {
  98. HRESULT hresult = NOERROR;
  99. ULONG cbWritten = cb;
  100. if (pcbWritten != NULL)
  101. {
  102. *pcbWritten = 0;
  103. }
  104. if (cbWritten + m_pos > m_rom16.cbBuffer)
  105. {
  106. ULARGE_INTEGER ularge_integer;
  107. ULISet32(ularge_integer,m_pos+cbWritten);
  108. hresult = SetSize(ularge_integer);
  109. if (hresult != NOERROR)
  110. {
  111. return hresult;
  112. }
  113. }
  114. if ( cbWritten != 0 )
  115. {
  116. hmemcpy((LPSTR)m_rom16.Buffer + m_pos,pb, cbWritten);
  117. m_pos += cbWritten;
  118. }
  119. if (pcbWritten != NULL)
  120. {
  121. *pcbWritten = cbWritten;
  122. }
  123. return hresult;
  124. }
  125. STDMETHODIMP CPkt::Seek(LARGE_INTEGER dlibMoveIn, DWORD dwOrigin, ULARGE_INTEGER FAR* plibNewPosition)
  126. {
  127. HRESULT hresult = NOERROR;
  128. LONG dlibMove = dlibMoveIn.LowPart;
  129. ULONG cbNewPos = dlibMove;
  130. if (plibNewPosition != NULL)
  131. {
  132. ULISet32(*plibNewPosition, m_pos);
  133. }
  134. switch(dwOrigin)
  135. {
  136. case STREAM_SEEK_SET:
  137. if (dlibMove >= 0)
  138. {
  139. m_pos = dlibMove;
  140. }
  141. else
  142. {
  143. hresult = ResultFromScode(E_UNSPEC); // PKT (Invalid seek)
  144. }
  145. break;
  146. case STREAM_SEEK_CUR:
  147. if (!(dlibMove < 0 && ((ULONG) -dlibMove) > m_pos))
  148. {
  149. m_pos += dlibMove;
  150. }
  151. else
  152. {
  153. hresult = ResultFromScode(E_UNSPEC); // PKT (Invalid seek)
  154. }
  155. break;
  156. case STREAM_SEEK_END:
  157. if (!(dlibMove < 0 && ((ULONG) -dlibMove) > m_rom16.cbBuffer))
  158. {
  159. m_pos = m_rom16.cbBuffer + dlibMove;
  160. }
  161. else
  162. {
  163. hresult = ResultFromScode(E_UNSPEC); // PKT (Invalid seek)
  164. }
  165. break;
  166. default:
  167. hresult = ResultFromScode(E_UNSPEC); // PKT (Invalid seek mode)
  168. }
  169. if (plibNewPosition != NULL)
  170. {
  171. ULISet32(*plibNewPosition,m_pos);
  172. }
  173. return hresult;
  174. }
  175. //
  176. // Note: if the cpkt data needs to be reallocate extra space
  177. //
  178. #define CBEXTRABYTES 128
  179. STDMETHODIMP CPkt::SetSize(ULARGE_INTEGER cb)
  180. {
  181. HRESULT hresult = NOERROR;
  182. ULONG ulNewSize;
  183. if (m_opd.cbSize && m_opd.cbSize > cb.LowPart) {
  184. m_rom16.cbBuffer = cb.LowPart;
  185. goto Exit;
  186. }
  187. if (m_rom16.cbBuffer == cb.LowPart)
  188. goto Exit;
  189. ulNewSize = cb.LowPart + CBEXTRABYTES;
  190. TaskFree(m_rom16.Buffer);
  191. m_rom16.Buffer = TaskAlloc(ulNewSize);
  192. if ( m_rom16.Buffer == NULL )
  193. {
  194. m_rom16.cbBuffer = 0;
  195. m_opd.cbSize = 0;
  196. hresult = ResultFromScode(S_OOM);
  197. goto Exit;
  198. }
  199. m_rom16.cbBuffer = cb.LowPart;
  200. m_opd.cbSize = ulNewSize;
  201. Exit:
  202. return hresult;
  203. }
  204. STDMETHODIMP CPkt::CopyTo(IStream FAR *pstm, ULARGE_INTEGER cb,
  205. ULARGE_INTEGER FAR * pcbRead, ULARGE_INTEGER FAR * pcbWritten)
  206. {
  207. return ResultFromScode(E_NOTIMPL);
  208. }
  209. STDMETHODIMP CPkt::Commit(DWORD grfCommitFlags)
  210. {
  211. return ResultFromScode(E_NOTIMPL);
  212. }
  213. STDMETHODIMP CPkt::Revert(void)
  214. {
  215. return ResultFromScode(E_NOTIMPL);
  216. }
  217. STDMETHODIMP CPkt::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER, DWORD dwLockType)
  218. {
  219. return ResultFromScode(E_NOTIMPL);
  220. }
  221. STDMETHODIMP CPkt::UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
  222. {
  223. return ResultFromScode(E_NOTIMPL);
  224. }
  225. STDMETHODIMP CPkt::Stat(STATSTG FAR *pstatstg, DWORD statflag)
  226. {
  227. return ResultFromScode(E_NOTIMPL);
  228. }
  229. STDMETHODIMP CPkt::Clone(THIS_ IStream FAR * FAR *ppstm)
  230. {
  231. return ResultFromScode(E_NOTIMPL);
  232. }
  233. //
  234. // Create untyped CPkt. Used by other create functions (is private)
  235. //
  236. CPkt FAR* CPkt::Create(IUnknown FAR *pUnk, DWORD cbExt)
  237. {
  238. CPkt FAR* pCPkt;
  239. pCPkt = new CPkt;
  240. if (pCPkt == NULL)
  241. return NULL;
  242. pCPkt->m_rom16.Buffer = TaskAlloc( cbExt );
  243. if ( pCPkt->m_rom16.Buffer == NULL )
  244. {
  245. delete pCPkt;
  246. return NULL;
  247. }
  248. pCPkt->m_rom16.cbBuffer = cbExt;
  249. pCPkt->m_opd.cbSize = cbExt;
  250. return pCPkt;
  251. }
  252. //
  253. // CPkt used to make a call
  254. //
  255. CPkt FAR* CPkt::CreateForCall(
  256. IUnknown FAR *pUnk,
  257. REFIID iid,
  258. int iMethod,
  259. BOOL fSend,
  260. BOOL fAsync,
  261. DWORD size )
  262. {
  263. CPkt FAR * pCPkt;
  264. if (fAsync && fSend) {
  265. fSend = FALSE;
  266. //Assert(0,"Async CPkt with fSend == TRUE not implemented");
  267. //return NULL;
  268. }
  269. pCPkt = CPkt::Create(pUnk, size);
  270. if (pCPkt == NULL)
  271. {
  272. return NULL;
  273. }
  274. pCPkt->m_opd.iid = iid;
  275. pCPkt->m_rom16.iMethod = iMethod;
  276. pCPkt->m_rom16.rpcFlags = 0;
  277. if ( fSend )
  278. {
  279. pCPkt->m_rom16.rpcFlags |= RPCFLG_INPUT_SYNCHRONOUS;
  280. }
  281. if ( fAsync )
  282. {
  283. pCPkt->m_rom16.rpcFlags |= RPCFLG_ASYNCHRONOUS;
  284. }
  285. return pCPkt;
  286. }
  287. //+---------------------------------------------------------------------------
  288. //
  289. // Function: SetRpcChannelBuffer, public
  290. //
  291. // Synopsis: Sets the RpcChannelBuffer to call when CallRpcChannelBuffer
  292. // is called.
  293. //
  294. // Arguments: [prcb] - IRpcChannelBuffer interface
  295. //
  296. // Returns: NOERROR always
  297. //
  298. // History: 30-Mar-94 BobDay Created
  299. //
  300. //----------------------------------------------------------------------------
  301. STDMETHODIMP CPkt::SetRpcChannelBuffer(
  302. CRpcChannelBuffer FAR * prcb )
  303. {
  304. m_prcb = prcb;
  305. return NOERROR;
  306. }
  307. //+---------------------------------------------------------------------------
  308. //
  309. // Function: CallRpcChannelBuffer, public
  310. //
  311. // Synopsis: Calls the RpcChannelBuffer with the parameters accumulated in
  312. // the CPkt buffer.
  313. //
  314. // Arguments: none
  315. //
  316. // Returns: HRESULT for success/failure of call or procedure
  317. //
  318. // History: 30-Mar-94 BobDay Created
  319. //
  320. //----------------------------------------------------------------------------
  321. STDMETHODIMP CPkt::CallRpcChannelBuffer( void )
  322. {
  323. HRESULT hresult;
  324. RPCOLEMESSAGE16 rom16;
  325. ULONG ulStatus;
  326. //
  327. // Allocate a buffer from the Channel
  328. //
  329. memset(&rom16, 0, sizeof(rom16)); // Zero out everything
  330. rom16.cbBuffer = m_rom16.cbBuffer; // Tell it how big we want it!
  331. rom16.rpcFlags = m_rom16.rpcFlags;
  332. rom16.iMethod = m_rom16.iMethod;
  333. hresult = m_prcb->GetBuffer( &rom16, m_opd.iid );
  334. if ( FAILED(hresult) )
  335. {
  336. return hresult;
  337. }
  338. //
  339. // For speed, we could get away without doing the copy here
  340. // by passing the buffer to the 32-bit world in the GetBuffer
  341. // call above.
  342. //
  343. hmemcpy( rom16.Buffer, m_rom16.Buffer, m_rom16.cbBuffer );
  344. //
  345. // Call the channel
  346. //
  347. ulStatus = 0;
  348. hresult = m_prcb->SendReceive( &rom16, &ulStatus );
  349. if ( SUCCEEDED(hresult) )
  350. {
  351. ULARGE_INTEGER ularge_integer;
  352. hresult = (HRESULT)ulStatus;
  353. //
  354. // Copy the buffer back!
  355. //
  356. ULISet32(ularge_integer,rom16.cbBuffer);
  357. SetSize( ularge_integer ); // Make it big enough!
  358. hmemcpy( m_rom16.Buffer, rom16.Buffer, rom16.cbBuffer );
  359. }
  360. //
  361. // Free up the buffer
  362. //
  363. m_prcb->FreeBuffer( &rom16 );
  364. return hresult;
  365. }