Leaked source code of windows server 2003
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.

3295 lines
94 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: transmit.cxx
  7. //
  8. // Contents: Support for Windows/OLE data types for oleprx32.dll.
  9. // Used to be transmit_as routines, now user_marshal routines.
  10. //
  11. // Functions: HGLOBAL_UserSize
  12. // HGLOBAL_UserMarshal
  13. // HGLOBAL_UserUnmarshal
  14. // HGLOBAL_UserFree
  15. // HMETAFILEPICT_UserSize
  16. // HMETAFILEPICT_UserMarshal
  17. // HMETAFILEPICT_UserUnmarshal
  18. // HMETAFILEPICT_UserFree
  19. // HENHMETAFILE_UserSize
  20. // HENHMETAFILE_UserMarshal
  21. // HENHMETAFILE_UserUnmarshal
  22. // HENHMETAFILE_UserFree
  23. // HBITMAP_UserSize
  24. // HBITMAP_UserMarshal
  25. // HBITMAP_UserUnmarshal
  26. // HBITMAP_UserFree
  27. // HBRUSH_UserSize
  28. // HBRUSH_UserMarshal
  29. // HBRUSH_UserUnmarshal
  30. // HBRUSH_UserFree
  31. // STGMEDIUM_UserSize
  32. // STGMEDIUM_UserMarshal
  33. // STGMEDIUM_UserUnmarshal
  34. // STGMEDIUM_UserFree
  35. // HACCEL_UserSize
  36. // HACCEL_UserMarshal
  37. // HACCEL_UserUnmarshal
  38. // HACCEL_UserFree
  39. // HWND_UserSize
  40. // HWND_UserMarshal
  41. // HWND_UserUnmarshal
  42. // HWND_UserFree
  43. // HMENU_UserSize
  44. // HMENU_UserMarshal
  45. // HMENU_UserUnmarshal
  46. // HMENU_UserFree
  47. //
  48. // History: 24-Aug-93 ShannonC Created
  49. // 24-Nov-93 ShannonC Added HGLOBAL
  50. // 14-May-94 DavePl Added HENHMETAFILE
  51. // 18-May-94 ShannonC Added HACCEL, UINT, WPARAM
  52. // 19-May-94 DavePl Added HENHMETAFILE to STGMEDIUM code
  53. // May-95 Ryszardk Wrote all the _User* routines
  54. //
  55. //--------------------------------------------------------------------------
  56. #include "stdrpc.hxx"
  57. #pragma hdrstop
  58. #include <oleauto.h>
  59. #include <objbase.h>
  60. #include "transmit.h"
  61. #include <rpcwdt.h>
  62. WINOLEAPI_(void) ReleaseStgMedium(LPSTGMEDIUM pStgMed);
  63. #pragma code_seg(".orpc")
  64. EXTERN_C const CLSID CLSID_MyPSFactoryBuffer = {0x6f11fe5c,0x2fc5,0x101b,{0x9e,0x45,0x00,0x00,0x0b,0x65,0xc7,0xef}};
  65. //+-------------------------------------------------------------------------
  66. //
  67. // class: CPunkForRelease
  68. //
  69. // purpose: special IUnknown for remoted STGMEDIUMs
  70. //
  71. // history: 02-Mar-94 Rickhi Created
  72. //
  73. // notes: This class is used to do the cleanup correctly when certain
  74. // types of storages are passed between processes or machines
  75. // in Nt and Chicago.
  76. //
  77. // On NT, GLOBAL, GDI, and BITMAP handles cannot be passed between
  78. // processes, so we actually copy the whole data and create a
  79. // new handle in the receiving process. However, STGMEDIUMs have
  80. // this weird behaviour where if PunkForRelease is non-NULL then
  81. // the sender is responsible for cleanup, not the receiver. Since
  82. // we create a new handle in the receiver, we would leak handles
  83. // if we didnt do some special processing. So, we do the
  84. // following...
  85. //
  86. // During STGMEDIUM_UserUnmarshal, if there is a pUnkForRelease
  87. // replace it with a CPunkForRelease. When Release is called
  88. // on the CPunkForRelease, do the necessary cleanup work,
  89. // then call the real PunkForRelease.
  90. //
  91. //+-------------------------------------------------------------------------
  92. class CPunkForRelease : public IUnknown
  93. {
  94. public:
  95. CPunkForRelease( STGMEDIUM *pStgMed, ulong fTopLayerOnly);
  96. // IUnknown Methods
  97. STDMETHOD(QueryInterface)(REFIID riid, void **ppunk);
  98. STDMETHOD_(ULONG, AddRef)(void);
  99. STDMETHOD_(ULONG, Release)(void);
  100. private:
  101. ~CPunkForRelease(void);
  102. ULONG _cRefs; // reference count
  103. ULONG _fTopLayerMFP:1; // optimisation flag for Chicago
  104. STGMEDIUM _stgmed; // storage medium
  105. IUnknown * _pUnkForRelease; // real pUnkForRelease
  106. };
  107. inline CPunkForRelease::CPunkForRelease(
  108. STGMEDIUM * pStgMed,
  109. ulong fTopLayerMFPict
  110. ) :
  111. _cRefs(1),
  112. _fTopLayerMFP( fTopLayerMFPict),
  113. _stgmed(*pStgMed)
  114. {
  115. // NOTE: we assume the caller has verified pStgMed is not NULL,
  116. // and the pUnkForRelease is non-null, otherwise there is no
  117. // point in constructing this object. The tymed must also be
  118. // one of the special ones.
  119. UserNdrAssert(pStgMed);
  120. UserNdrAssert(pStgMed->tymed == TYMED_HGLOBAL ||
  121. pStgMed->tymed == TYMED_GDI ||
  122. pStgMed->tymed == TYMED_MFPICT ||
  123. pStgMed->tymed == TYMED_ENHMF);
  124. _pUnkForRelease = pStgMed->pUnkForRelease;
  125. }
  126. inline CPunkForRelease::~CPunkForRelease()
  127. {
  128. // since we really have our own copies of these handles' data, just
  129. // pretend like the callee is responsible for the release, and
  130. // recurse into ReleaseStgMedium to do the cleanup.
  131. _stgmed.pUnkForRelease = NULL;
  132. // There is this weird optimized case of Chicago MFPICT when we have two
  133. // layers with a HENHMETAFILE handle inside. Top layer is an HGLOBAL.
  134. if ( _fTopLayerMFP )
  135. GlobalFree( _stgmed.hGlobal );
  136. else
  137. ReleaseStgMedium( &_stgmed );
  138. // release the callers punk
  139. _pUnkForRelease->Release();
  140. }
  141. STDMETHODIMP_(ULONG) CPunkForRelease::AddRef(void)
  142. {
  143. InterlockedIncrement((LONG *)&_cRefs);
  144. return _cRefs;
  145. }
  146. STDMETHODIMP_(ULONG) CPunkForRelease::Release(void)
  147. {
  148. long Ref = _cRefs - 1;
  149. UserNdrAssert( _cRefs );
  150. if (InterlockedDecrement((LONG *)&_cRefs) == 0)
  151. {
  152. // null out the vtable.
  153. long * p = (long *)this;
  154. *p = 0;
  155. delete this;
  156. return 0;
  157. }
  158. else
  159. return Ref;
  160. }
  161. STDMETHODIMP CPunkForRelease::QueryInterface(REFIID riid, void **ppv)
  162. {
  163. if (IsEqualIID(riid, IID_IUnknown))
  164. {
  165. *ppv = (void *)(IUnknown *) this;
  166. AddRef();
  167. return S_OK;
  168. }
  169. else
  170. {
  171. *ppv = NULL;
  172. return E_NOINTERFACE;
  173. }
  174. }
  175. // These methods are needed as the object is used for interface marshaling.
  176. /***************************************************************************/
  177. STDMETHODIMP_(ULONG) CStreamOnMessage::AddRef( THIS )
  178. {
  179. return ref_count += 1;
  180. }
  181. /***************************************************************************/
  182. STDMETHODIMP CStreamOnMessage::Clone(THIS_ IStream * *ppstm)
  183. {
  184. return ResultFromScode(E_NOTIMPL);
  185. }
  186. /***************************************************************************/
  187. STDMETHODIMP CStreamOnMessage::Commit(THIS_ DWORD grfCommitFlags)
  188. {
  189. return ResultFromScode(E_NOTIMPL);
  190. }
  191. /***************************************************************************/
  192. STDMETHODIMP CStreamOnMessage::CopyTo(THIS_ IStream *pstm,
  193. ULARGE_INTEGER cb,
  194. ULARGE_INTEGER *pcbRead,
  195. ULARGE_INTEGER *pcbWritten)
  196. {
  197. return ResultFromScode(E_NOTIMPL);
  198. }
  199. /***************************************************************************/
  200. CStreamOnMessage::CStreamOnMessage(unsigned char **ppMessageBuffer)
  201. : ref_count(1), ppBuffer(ppMessageBuffer), cbMaxStreamLength(0xFFFFFFFF)
  202. {
  203. pStartOfStream = *ppMessageBuffer;
  204. }
  205. /***************************************************************************/
  206. STDMETHODIMP CStreamOnMessage::LockRegion(THIS_ ULARGE_INTEGER libOffset,
  207. ULARGE_INTEGER cb,
  208. DWORD dwLockType)
  209. {
  210. return ResultFromScode(E_NOTIMPL);
  211. }
  212. /***************************************************************************/
  213. STDMETHODIMP CStreamOnMessage::QueryInterface( REFIID riid, LPVOID FAR* ppvObj)
  214. {
  215. if (IsEqualIID(riid, IID_IUnknown))
  216. {
  217. *ppvObj = (IUnknown *) this;
  218. ref_count += 1;
  219. return ResultFromScode(S_OK);
  220. }
  221. else if (IsEqualIID(riid, IID_IStream))
  222. {
  223. *ppvObj = (IStream *) this;
  224. ref_count += 1;
  225. return ResultFromScode(S_OK);
  226. }
  227. else
  228. return ResultFromScode(E_NOINTERFACE);
  229. }
  230. /***************************************************************************/
  231. STDMETHODIMP CStreamOnMessage::Read(THIS_ VOID HUGEP *pv,
  232. ULONG cb, ULONG *pcbRead)
  233. {
  234. memcpy( pv, *ppBuffer, cb );
  235. *ppBuffer += cb;
  236. if (pcbRead != NULL)
  237. *pcbRead = cb;
  238. return ResultFromScode(S_OK);
  239. }
  240. /***************************************************************************/
  241. STDMETHODIMP_(ULONG) CStreamOnMessage::Release( THIS )
  242. {
  243. ref_count -= 1;
  244. if (ref_count == 0)
  245. {
  246. delete this;
  247. return 0;
  248. }
  249. else
  250. return ref_count;
  251. }
  252. /***************************************************************************/
  253. STDMETHODIMP CStreamOnMessage::Revert(THIS)
  254. {
  255. return ResultFromScode(E_NOTIMPL);
  256. }
  257. /***************************************************************************/
  258. STDMETHODIMP CStreamOnMessage::Seek(THIS_ LARGE_INTEGER dlibMove,
  259. DWORD dwOrigin,
  260. ULARGE_INTEGER *plibNewPosition)
  261. {
  262. ULONG pos;
  263. // Verify that the offset isn't out of range.
  264. if (dlibMove.HighPart != 0)
  265. return ResultFromScode( E_FAIL );
  266. // Determine the new seek pointer.
  267. switch (dwOrigin)
  268. {
  269. case STREAM_SEEK_SET:
  270. pos = dlibMove.LowPart;
  271. break;
  272. case STREAM_SEEK_CUR:
  273. /* Must use signed math here. */
  274. pos = *ppBuffer - pStartOfStream;
  275. if ((long) dlibMove.LowPart < 0 &&
  276. pos < (unsigned long) - (long) dlibMove.LowPart)
  277. return ResultFromScode( E_FAIL );
  278. pos += (long) dlibMove.LowPart;
  279. break;
  280. case STREAM_SEEK_END:
  281. return ResultFromScode(E_NOTIMPL);
  282. break;
  283. default:
  284. return ResultFromScode( E_FAIL );
  285. }
  286. // Set the seek pointer.
  287. *ppBuffer = pStartOfStream + pos;
  288. if (plibNewPosition != NULL)
  289. {
  290. plibNewPosition->LowPart = pos;
  291. plibNewPosition->HighPart = 0;
  292. }
  293. return ResultFromScode(S_OK);
  294. }
  295. /***************************************************************************/
  296. STDMETHODIMP CStreamOnMessage::SetSize(THIS_ ULARGE_INTEGER libNewSize)
  297. {
  298. return ResultFromScode(E_NOTIMPL);
  299. }
  300. /***************************************************************************/
  301. STDMETHODIMP CStreamOnMessage::Stat(THIS_ STATSTG *pstatstg, DWORD grfStatFlag)
  302. {
  303. return ResultFromScode(E_NOTIMPL);
  304. }
  305. /***************************************************************************/
  306. STDMETHODIMP CStreamOnMessage::UnlockRegion(THIS_ ULARGE_INTEGER libOffset,
  307. ULARGE_INTEGER cb,
  308. DWORD dwLockType)
  309. {
  310. return ResultFromScode(E_NOTIMPL);
  311. }
  312. /***************************************************************************/
  313. STDMETHODIMP CStreamOnMessage::Write(THIS_ VOID const HUGEP *pv,
  314. ULONG cb,
  315. ULONG *pcbWritten)
  316. {
  317. // Write the data.
  318. memcpy( *ppBuffer, pv, cb );
  319. if (pcbWritten != NULL)
  320. *pcbWritten = cb;
  321. *ppBuffer += cb;
  322. return ResultFromScode(S_OK);
  323. }
  324. //+-------------------------------------------------------------------------
  325. //
  326. // Function: SNB_UserSize
  327. //
  328. // Synopsis: Sizes an SNB.
  329. //
  330. // Derivation: An array of strings in one block of memory.
  331. //
  332. // history: June-95 Ryszardk Created, based on SNB_*_xmit.
  333. //
  334. //--------------------------------------------------------------------------
  335. unsigned long __RPC_USER
  336. SNB_UserSize (
  337. unsigned long * pFlags,
  338. unsigned long Offset,
  339. SNB * pSnb )
  340. {
  341. if ( ! pSnb )
  342. return Offset;
  343. // calculate the number of strings and characters (with their terminators)
  344. ULONG ulCntStr = 0;
  345. ULONG ulCntChar = 0;
  346. if (pSnb && *pSnb)
  347. {
  348. SNB snb = *pSnb;
  349. WCHAR *psz = *snb;
  350. while (psz)
  351. {
  352. ulCntChar += wcslen(psz) + 1;
  353. ulCntStr++;
  354. snb++;
  355. psz = *snb;
  356. }
  357. }
  358. // The wire size is: conf size, 2 fields and the wchars.
  359. LENGTH_ALIGN( Offset, 3 );
  360. return ( Offset + 3 * sizeof(long) + ulCntChar * sizeof( WCHAR ) );
  361. }
  362. //+-------------------------------------------------------------------------
  363. //
  364. // Function: SNB_UserMarshall
  365. //
  366. // Synopsis: Marshalls an SNB into the RPC buffer.
  367. //
  368. // Derivation: An array of strings in one block of memory.
  369. //
  370. // history: June-95 Ryszardk Created, based on SNB_*_xmit.
  371. //
  372. //--------------------------------------------------------------------------
  373. unsigned char __RPC_FAR * __RPC_USER
  374. SNB_UserMarshal (
  375. unsigned long * pFlags,
  376. unsigned char * pBuffer,
  377. SNB * pSnb )
  378. {
  379. UserNdrDebugOut((UNDR_FORCE, "SNB_UserMarshal\n"));
  380. if ( ! pSnb )
  381. return pBuffer;
  382. // calculate the number of strings and characters (with their terminators)
  383. ULONG ulCntStr = 0;
  384. ULONG ulCntChar = 0;
  385. if (pSnb && *pSnb)
  386. {
  387. SNB snb = *pSnb;
  388. WCHAR *psz = *snb;
  389. while (psz)
  390. {
  391. ulCntChar += wcslen(psz) + 1;
  392. ulCntStr++;
  393. snb++;
  394. psz = *snb;
  395. }
  396. }
  397. // conformant size
  398. ALIGN( pBuffer, 3 );
  399. *( PULONG_LV_CAST pBuffer)++ = ulCntChar;
  400. // fields
  401. *( PULONG_LV_CAST pBuffer)++ = ulCntStr;
  402. *( PULONG_LV_CAST pBuffer)++ = ulCntChar;
  403. // actual strings only
  404. if ( pSnb && *pSnb )
  405. {
  406. // There is a NULL string pointer to mark the end of the pointer array.
  407. // However, the strings don't have to follow tightly.
  408. // Hence, we have to copy one string at a time.
  409. SNB snb = *pSnb;
  410. WCHAR *pszSrc;
  411. while (pszSrc = *snb++)
  412. {
  413. ULONG ulCopyLen = (wcslen(pszSrc) + 1) * sizeof(WCHAR);
  414. WdtpMemoryCopy( pBuffer, pszSrc, ulCopyLen );
  415. pBuffer += ulCopyLen;
  416. }
  417. }
  418. return pBuffer;
  419. }
  420. //+-------------------------------------------------------------------------
  421. //
  422. // Function: SNB_UserUnmarshall
  423. //
  424. // Synopsis: Unmarshalls an SNB from the RPC buffer.
  425. //
  426. // Derivation: An array of strings in one block of memory.
  427. //
  428. // history: June-95 Ryszardk Created, based on SNB_*_xmit.
  429. //
  430. //--------------------------------------------------------------------------
  431. unsigned char __RPC_FAR * __RPC_USER
  432. SNB_UserUnmarshal (
  433. unsigned long * pFlags,
  434. unsigned char * pBuffer,
  435. SNB * pSnb )
  436. {
  437. UserNdrDebugOut((UNDR_FORCE, "SNB_UserUnmarshal\n"));
  438. ALIGN( pBuffer, 3 );
  439. // conf size
  440. unsigned long ulCntChar = *( PULONG_LV_CAST pBuffer)++;
  441. // fields
  442. unsigned long ulCntStr = *( PULONG_LV_CAST pBuffer)++;
  443. pBuffer += sizeof(long);
  444. // no reusage of pSNB.
  445. if ( *pSnb )
  446. WdtpFree( pFlags, *pSnb );
  447. if ( ulCntStr == 0 )
  448. {
  449. *pSnb = NULL;
  450. return pBuffer;
  451. }
  452. // construct the SNB.
  453. SNB Snb = (SNB) WdtpAllocate( pFlags,
  454. ( (ulCntStr + 1) * sizeof(WCHAR *) +
  455. ulCntChar * sizeof(WCHAR)) );
  456. *pSnb = Snb;
  457. if (Snb)
  458. {
  459. // create the pointer array within the SNB.
  460. WCHAR *pszSrc = (WCHAR *) pBuffer;
  461. WCHAR *pszTgt = (WCHAR *) (Snb + ulCntStr + 1); // right behind array
  462. for (ULONG i = ulCntStr; i > 0; i--)
  463. {
  464. *Snb++ = pszTgt;
  465. ULONG ulLen = wcslen(pszSrc) + 1;
  466. pszSrc += ulLen;
  467. pszTgt += ulLen;
  468. }
  469. *Snb++ = NULL;
  470. // Copy the actual strings.
  471. // We can do a block copy here as we packed them tight in the buffer.
  472. // Snb points right behind the lastarray of pointers within the SNB.
  473. WdtpMemoryCopy( Snb, pBuffer, ulCntChar * sizeof(WCHAR) );
  474. pBuffer += ulCntChar * sizeof(WCHAR);
  475. }
  476. return pBuffer;
  477. }
  478. //+-------------------------------------------------------------------------
  479. //
  480. // Function: SNB_UserFree
  481. //
  482. // Synopsis: Frees an SNB.
  483. //
  484. // Derivation: An array of strings in one block of memory.
  485. //
  486. // history: June-95 Ryszardk Created, based on SNB_*_xmit.
  487. //
  488. //--------------------------------------------------------------------------
  489. void __RPC_USER
  490. SNB_UserFree(
  491. unsigned long * pFlags,
  492. SNB * pSnb )
  493. {
  494. if ( pSnb && *pSnb )
  495. WdtpFree( pFlags, *pSnb );
  496. }
  497. //+-------------------------------------------------------------------------
  498. //
  499. // Function: WdtpVoidStar_UserSize
  500. //
  501. // Synopsis: Sizes a remotable void star as ulong.
  502. //
  503. // history: June-95 Ryszardk Created.
  504. //
  505. //--------------------------------------------------------------------------
  506. unsigned long __RPC_USER
  507. WdtpVoidStar_UserSize (
  508. unsigned long * pFlags,
  509. unsigned long Offset,
  510. unsigned long * pVoid )
  511. {
  512. if ( !pVoid )
  513. return Offset;
  514. LENGTH_ALIGN( Offset, 3 );
  515. return( Offset + 4 ) ;
  516. }
  517. //+-------------------------------------------------------------------------
  518. //
  519. // Function: WdtpVoidStar_UserMarshall
  520. //
  521. // Synopsis: Marshalls a remotable void star as ulong.
  522. //
  523. // history: June-95 Ryszardk Created.
  524. //
  525. //--------------------------------------------------------------------------
  526. unsigned char __RPC_FAR * __RPC_USER
  527. WdtpVoidStar_UserMarshal (
  528. unsigned long * pFlags,
  529. unsigned char * pBuffer,
  530. unsigned long * pVoid )
  531. {
  532. if ( !pVoid )
  533. return pBuffer;
  534. ALIGN( pBuffer, 3 );
  535. *( PULONG_LV_CAST pBuffer)++ = *pVoid;
  536. return( pBuffer );
  537. }
  538. //+-------------------------------------------------------------------------
  539. //
  540. // Function: WdtpVoidStaer_UserUnmarshall
  541. //
  542. // Synopsis: Unmarshalls a remotable void star as ulong.
  543. //
  544. // history: June-95 Ryszardk Created.
  545. //
  546. //--------------------------------------------------------------------------
  547. unsigned char __RPC_FAR * __RPC_USER
  548. WdtpVoidStar_UserUnmarshal (
  549. unsigned long * pFlags,
  550. unsigned char * pBuffer,
  551. unsigned long * pVoid )
  552. {
  553. ALIGN( pBuffer, 3 );
  554. *pVoid= *( PULONG_LV_CAST pBuffer)++;
  555. return( pBuffer );
  556. }
  557. //+-------------------------------------------------------------------------
  558. //
  559. // Function: WdtpVoidStar_UserFree
  560. //
  561. //--------------------------------------------------------------------------
  562. void __RPC_USER
  563. WdtpVoidStar_UserFree(
  564. unsigned long * pFlags,
  565. unsigned long * pVoid )
  566. {
  567. }
  568. //+-------------------------------------------------------------------------
  569. //
  570. // Function: HWND_UserSize
  571. //
  572. // Synopsis: Sizes an HWND handle.
  573. //
  574. //--------------------------------------------------------------------------
  575. unsigned long __RPC_USER
  576. HWND_UserSize (
  577. unsigned long * pFlags,
  578. unsigned long Offset,
  579. HWND * pH )
  580. {
  581. return WdtpVoidStar_UserSize( pFlags, Offset, (ulong*)pH );
  582. }
  583. //+-------------------------------------------------------------------------
  584. //
  585. // Function: HWND_UserMarshall
  586. //
  587. // Synopsis: Marshalls an HWND handle into the RPC buffer.
  588. //
  589. //--------------------------------------------------------------------------
  590. unsigned char __RPC_FAR * __RPC_USER
  591. HWND_UserMarshal (
  592. unsigned long * pFlags,
  593. unsigned char * pBuffer,
  594. HWND * pH )
  595. {
  596. return WdtpVoidStar_UserMarshal( pFlags, pBuffer, (ulong*)pH );
  597. }
  598. //+-------------------------------------------------------------------------
  599. //
  600. // Function: HWND_UserUnmarshall
  601. //
  602. // Synopsis: Unmarshalls an HWND handle from the RPC buffer.
  603. //
  604. //--------------------------------------------------------------------------
  605. unsigned char __RPC_FAR * __RPC_USER
  606. HWND_UserUnmarshal (
  607. unsigned long * pFlags,
  608. unsigned char * pBuffer,
  609. HWND * pH )
  610. {
  611. return WdtpVoidStar_UserUnmarshal( pFlags, pBuffer, (ulong*)pH );
  612. }
  613. //+-------------------------------------------------------------------------
  614. //
  615. // Function: HWND_UserFree
  616. //
  617. // Synopsis: Shouldn't be called.
  618. //
  619. //--------------------------------------------------------------------------
  620. void __RPC_USER
  621. HWND_UserFree(
  622. unsigned long * pFlags,
  623. HWND * pH )
  624. {
  625. }
  626. //+-------------------------------------------------------------------------
  627. //
  628. // Function: HMENU_UserSize
  629. //
  630. // Synopsis: Sizes an HMENU handle.
  631. //
  632. //--------------------------------------------------------------------------
  633. unsigned long __RPC_USER
  634. HMENU_UserSize (
  635. unsigned long * pFlags,
  636. unsigned long Offset,
  637. HMENU * pH )
  638. {
  639. return WdtpVoidStar_UserSize( pFlags, Offset, (ulong*)pH );
  640. }
  641. //+-------------------------------------------------------------------------
  642. //
  643. // Function: HMENU_UserMarshall
  644. //
  645. // Synopsis: Marshalls an HMENU handle into the RPC buffer.
  646. //
  647. //--------------------------------------------------------------------------
  648. unsigned char __RPC_FAR * __RPC_USER
  649. HMENU_UserMarshal (
  650. unsigned long * pFlags,
  651. unsigned char * pBuffer,
  652. HMENU * pH )
  653. {
  654. return WdtpVoidStar_UserMarshal( pFlags, pBuffer, (ulong*)pH );
  655. }
  656. //+-------------------------------------------------------------------------
  657. //
  658. // Function: HMENU_UserUnmarshall
  659. //
  660. // Synopsis: Unmarshalls an HMENU handle from the RPC buffer.
  661. //
  662. //--------------------------------------------------------------------------
  663. unsigned char __RPC_FAR * __RPC_USER
  664. HMENU_UserUnmarshal (
  665. unsigned long * pFlags,
  666. unsigned char * pBuffer,
  667. HMENU * pH )
  668. {
  669. return WdtpVoidStar_UserUnmarshal( pFlags, pBuffer, (ulong*)pH );
  670. }
  671. //+-------------------------------------------------------------------------
  672. //
  673. // Function: HMENU_UserFree
  674. //
  675. // Synopsis: Free an HMENU.
  676. //
  677. //--------------------------------------------------------------------------
  678. void __RPC_USER
  679. HMENU_UserFree(
  680. unsigned long * pFlags,
  681. HMENU * pH )
  682. {
  683. }
  684. //+-------------------------------------------------------------------------
  685. //
  686. // Function: HACCEL_UserSize
  687. //
  688. // Synopsis: Sizes an HACCEL handle.
  689. //
  690. //--------------------------------------------------------------------------
  691. unsigned long __RPC_USER
  692. HACCEL_UserSize (
  693. unsigned long * pFlags,
  694. unsigned long Offset,
  695. HACCEL * pH )
  696. {
  697. return WdtpVoidStar_UserSize( pFlags, Offset, (ulong*)pH );
  698. }
  699. //+-------------------------------------------------------------------------
  700. //
  701. // Function: HACCEL_UserMarshall
  702. //
  703. // Synopsis: Marshalls an HACCEL handle into the RPC buffer.
  704. //
  705. //--------------------------------------------------------------------------
  706. unsigned char __RPC_FAR * __RPC_USER
  707. HACCEL_UserMarshal (
  708. unsigned long * pFlags,
  709. unsigned char * pBuffer,
  710. HACCEL * pH )
  711. {
  712. return WdtpVoidStar_UserMarshal( pFlags, pBuffer, (ulong*)pH );
  713. }
  714. //+-------------------------------------------------------------------------
  715. //
  716. // Function: HACCEL_UserUnmarshall
  717. //
  718. // Synopsis: Unmarshalls an HACCEL handle from the RPC buffer.
  719. //
  720. //--------------------------------------------------------------------------
  721. unsigned char __RPC_FAR * __RPC_USER
  722. HACCEL_UserUnmarshal (
  723. unsigned long * pFlags,
  724. unsigned char * pBuffer,
  725. HACCEL * pH )
  726. {
  727. return WdtpVoidStar_UserUnmarshal( pFlags, pBuffer, (ulong*)pH );
  728. }
  729. //+-------------------------------------------------------------------------
  730. //
  731. // Function: HACCEL_UserFree
  732. //
  733. // Synopsis: Free an HACCEL.
  734. //
  735. //--------------------------------------------------------------------------
  736. void __RPC_USER
  737. HACCEL_UserFree(
  738. unsigned long * pFlags,
  739. HACCEL * pH )
  740. {
  741. }
  742. //+-------------------------------------------------------------------------
  743. //
  744. // Function: HBRUSH_UserSize
  745. //
  746. // Synopsis: Sizes an HBRUSH handle.
  747. //
  748. //--------------------------------------------------------------------------
  749. unsigned long __RPC_USER
  750. HBRUSH_UserSize (
  751. unsigned long * pFlags,
  752. unsigned long Offset,
  753. HBRUSH * pH )
  754. {
  755. return WdtpVoidStar_UserSize( pFlags, Offset, (ulong*)pH );
  756. }
  757. //+-------------------------------------------------------------------------
  758. //
  759. // Function: HBRUSH_UserMarshall
  760. //
  761. // Synopsis: Marshalls an HBRUSH handle into the RPC buffer.
  762. //
  763. //--------------------------------------------------------------------------
  764. unsigned char __RPC_FAR * __RPC_USER
  765. HBRUSH_UserMarshal (
  766. unsigned long * pFlags,
  767. unsigned char * pBuffer,
  768. HBRUSH * pH )
  769. {
  770. return WdtpVoidStar_UserMarshal( pFlags, pBuffer, (ulong*)pH );
  771. }
  772. //+-------------------------------------------------------------------------
  773. //
  774. // Function: HBRUSH_UserUnmarshall
  775. //
  776. // Synopsis: Unmarshalls an HBRUSH handle from the RPC buffer.
  777. //
  778. //--------------------------------------------------------------------------
  779. unsigned char __RPC_FAR * __RPC_USER
  780. HBRUSH_UserUnmarshal (
  781. unsigned long * pFlags,
  782. unsigned char * pBuffer,
  783. HBRUSH * pH )
  784. {
  785. return WdtpVoidStar_UserUnmarshal( pFlags, pBuffer, (ulong*)pH );
  786. }
  787. //+-------------------------------------------------------------------------
  788. //
  789. // Function: HBRUSH_UserFree
  790. //
  791. // Synopsis: Free an HBRUSH.
  792. //
  793. //--------------------------------------------------------------------------
  794. void __RPC_USER
  795. HBRUSH_UserFree(
  796. unsigned long * pFlags,
  797. HBRUSH * pH )
  798. {
  799. }
  800. // #########################################################################
  801. //
  802. // HGLOBAL.
  803. // See transmit.h for explanation of strict data/handle passing.
  804. //
  805. // #########################################################################
  806. //+-------------------------------------------------------------------------
  807. //
  808. // Function: HGLOBAL_UserSize
  809. //
  810. // Synopsis: Get the wire size the HGLOBAL handle and data.
  811. //
  812. // Derivation: Conformant struct with a flag field:
  813. // align + 12 + data size.
  814. //
  815. // history: May-95 Ryszardk Created.
  816. //
  817. //--------------------------------------------------------------------------
  818. unsigned long __RPC_USER
  819. HGLOBAL_UserSize (
  820. unsigned long * pFlags,
  821. unsigned long Offset,
  822. HGLOBAL * pGlobal)
  823. {
  824. if ( !pGlobal )
  825. return Offset;
  826. // userHGLOBAL: the encapsulated union.
  827. // Discriminant and then handle or pointer from the union arm.
  828. LENGTH_ALIGN( Offset, 3 );
  829. Offset += sizeof(long) + sizeof(void*);
  830. if ( ! *pGlobal )
  831. return Offset;
  832. if ( HGLOBAL_DATA_PASSING(*pFlags) )
  833. {
  834. unsigned long ulDataSize = GlobalSize( *pGlobal );
  835. Offset += 3 * sizeof(long) + ulDataSize;
  836. }
  837. return( Offset );
  838. }
  839. //+-------------------------------------------------------------------------
  840. //
  841. // Function: HGLOBAL_UserMarshall
  842. //
  843. // Synopsis: Marshalls an HGLOBAL object into the RPC buffer.
  844. //
  845. // Derivation: Conformant struct with a flag field:
  846. // align, size, null flag, size, data (bytes, if any)
  847. //
  848. // history: May-95 Ryszardk Created.
  849. //
  850. //--------------------------------------------------------------------------
  851. unsigned char __RPC_FAR * __RPC_USER
  852. HGLOBAL_UserMarshal (
  853. unsigned long * pFlags,
  854. unsigned char * pBuffer,
  855. HGLOBAL * pGlobal)
  856. {
  857. if ( !pGlobal )
  858. return pBuffer;
  859. // We marshal a null handle, too.
  860. UserNdrDebugOut((UNDR_OUT4, "HGLOBAL_UserMarshal\n"));
  861. ALIGN( pBuffer, 3 );
  862. // Discriminant of the encapsulated union and union arm.
  863. if ( HGLOBAL_DATA_PASSING(*pFlags) )
  864. {
  865. unsigned long ulDataSize;
  866. // userHGLOBAL
  867. *( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER;
  868. *( PULONG_LV_CAST pBuffer)++ = (ulong) *pGlobal;
  869. if ( ! *pGlobal )
  870. return pBuffer;
  871. // FLAGGED_BYTE_BLOB
  872. ulDataSize = GlobalSize( *pGlobal );
  873. *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
  874. // Handle is the non-null flag
  875. *( PULONG_LV_CAST pBuffer)++ = (ulong)*pGlobal;
  876. *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
  877. if( ulDataSize )
  878. {
  879. void * pData = GlobalLock( *pGlobal);
  880. memcpy( pBuffer, pData, ulDataSize );
  881. GlobalUnlock( *pGlobal);
  882. }
  883. pBuffer += ulDataSize;
  884. }
  885. else
  886. {
  887. // Sending a handle.
  888. *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE_MARKER;
  889. *( PULONG_LV_CAST pBuffer)++ = (ulong) *pGlobal;
  890. }
  891. return( pBuffer );
  892. }
  893. //+-------------------------------------------------------------------------
  894. //
  895. // Function: WdtpGlobalUnmarshal
  896. //
  897. // Synopsis: Unmarshalls an HGLOBAL object from the RPC buffer.
  898. //
  899. // Derivation: Conformant struct with a flag field:
  900. // align, size, null flag, size, data (bytes, if any)
  901. //
  902. // Note: Reallocation is forbidden when the hglobal is part of
  903. // an [in,out] STGMEDIUM in IDataObject::GetDataHere.
  904. // This affects only data passing with old handles being
  905. // non null.
  906. //
  907. // history: May-95 Ryszardk Created.
  908. //
  909. //--------------------------------------------------------------------------
  910. unsigned char __RPC_FAR * __RPC_USER
  911. WdtpGlobalUnmarshal (
  912. unsigned long * pFlags,
  913. unsigned char * pBuffer,
  914. HGLOBAL * pGlobal,
  915. BOOL fCanReallocate )
  916. {
  917. unsigned long ulDataSize, fHandle, UnionDisc;
  918. HGLOBAL hGlobal;
  919. ALIGN( pBuffer, 3 );
  920. UnionDisc = *( PULONG_LV_CAST pBuffer)++;
  921. hGlobal = (HGLOBAL) *( PULONG_LV_CAST pBuffer)++;
  922. if ( IS_DATA_MARKER( UnionDisc) )
  923. {
  924. if ( ! hGlobal )
  925. {
  926. if ( *pGlobal )
  927. GlobalFree( *pGlobal );
  928. *pGlobal = NULL;
  929. return pBuffer;
  930. }
  931. // There is a handle data on wire.
  932. ulDataSize = *( PULONG_LV_CAST pBuffer)++;
  933. // fhandle and data size again.
  934. pBuffer += 8;
  935. if ( *pGlobal )
  936. {
  937. // Check for reallocation
  938. if ( GlobalSize( *pGlobal ) == ulDataSize )
  939. hGlobal = *pGlobal;
  940. else
  941. {
  942. if ( fCanReallocate )
  943. {
  944. // hGlobal = GlobalReAlloc( *pGlobal, ulDataSize, GMEM_MOVEABLE );
  945. GlobalFree( *pGlobal );
  946. hGlobal = GlobalAlloc( GMEM_MOVEABLE, ulDataSize );
  947. }
  948. else
  949. {
  950. if ( GlobalSize(*pGlobal) < ulDataSize )
  951. RpcRaiseException( STG_E_MEDIUMFULL );
  952. else
  953. hGlobal = *pGlobal;
  954. }
  955. }
  956. }
  957. else
  958. {
  959. // allocate a new block
  960. hGlobal = GlobalAlloc( GMEM_MOVEABLE, ulDataSize );
  961. }
  962. if ( hGlobal == NULL )
  963. RpcRaiseException(E_OUTOFMEMORY);
  964. else
  965. {
  966. void * pData = GlobalLock( hGlobal);
  967. memcpy( pData, pBuffer, ulDataSize );
  968. pBuffer += ulDataSize;
  969. GlobalUnlock( hGlobal);
  970. }
  971. }
  972. else
  973. {
  974. // Sending a handle only.
  975. // Reallocation problem doesn't apply to handle passing.
  976. if ( *pGlobal != hGlobal && *pGlobal )
  977. GlobalFree( *pGlobal );
  978. }
  979. *pGlobal = hGlobal;
  980. return( pBuffer );
  981. }
  982. //+-------------------------------------------------------------------------
  983. //
  984. // Function: HGLOBAL_UserUnmarshall
  985. //
  986. // Synopsis: Unmarshalls an HGLOBAL object from the RPC buffer.
  987. //
  988. // Derivation: Conformant struct with a flag field:
  989. // align, size, null flag, size, data (bytes, if any)
  990. //
  991. // history: May-95 Ryszardk Created.
  992. //
  993. //--------------------------------------------------------------------------
  994. unsigned char __RPC_FAR * __RPC_USER
  995. HGLOBAL_UserUnmarshal (
  996. unsigned long * pFlags,
  997. unsigned char * pBuffer,
  998. HGLOBAL * pGlobal)
  999. {
  1000. return( WdtpGlobalUnmarshal( pFlags,
  1001. pBuffer,
  1002. pGlobal,
  1003. TRUE ) ); // reallocation possible
  1004. }
  1005. //+-------------------------------------------------------------------------
  1006. //
  1007. // Function: HGLOBAL_UserFree
  1008. //
  1009. // Synopsis: Free an HGLOBAL.
  1010. //
  1011. // history: May-95 Ryszardk Created.
  1012. //
  1013. //--------------------------------------------------------------------------
  1014. void __RPC_USER
  1015. HGLOBAL_UserFree(
  1016. unsigned long * pFlags,
  1017. HGLOBAL * pGlobal)
  1018. {
  1019. if( pGlobal && *pGlobal )
  1020. {
  1021. if ( HGLOBAL_DATA_PASSING(*pFlags) )
  1022. GlobalFree( *pGlobal);
  1023. }
  1024. }
  1025. // #########################################################################
  1026. //
  1027. // HMETAFILEPICT
  1028. // See transmit.h for explanation of strict vs. lax data/handle passing.
  1029. //
  1030. // #########################################################################
  1031. //+-------------------------------------------------------------------------
  1032. //
  1033. // Function: HMETAFILEPICT_UserSize
  1034. //
  1035. // Synopsis: Get the wire size the HMETAFILEPICT handle and data.
  1036. //
  1037. // Derivation: Union of a long and the meta file pict handle.
  1038. // Then struct with top layer (and a hmetafile handle).
  1039. // The the representation of the metafile.
  1040. //
  1041. // history: May-95 Ryszardk Created.
  1042. //
  1043. //--------------------------------------------------------------------------
  1044. unsigned long __RPC_USER
  1045. HMETAFILEPICT_UserSize (
  1046. unsigned long * pFlags,
  1047. unsigned long Offset,
  1048. HMETAFILEPICT * pHMetaFilePict )
  1049. {
  1050. if ( !pHMetaFilePict )
  1051. return Offset;
  1052. LENGTH_ALIGN( Offset, 3 );
  1053. // Discriminant of the encapsulated union and the union arm.
  1054. Offset += 8;
  1055. if ( ! *pHMetaFilePict )
  1056. return Offset;
  1057. if ( HGLOBAL_HANDLE_PASSING(*pFlags) )
  1058. return Offset;
  1059. // Now, this is a two layer object with HGLOBAL on top.
  1060. // Upper layer - hglobal part - needs to be sent as data.
  1061. METAFILEPICT *
  1062. pMFP = (METAFILEPICT*) GlobalLock( *(HANDLE *)pHMetaFilePict );
  1063. if ( pMFP == NULL )
  1064. RpcRaiseException( E_OUTOFMEMORY );
  1065. // Upper layer: 3 long fields + handle
  1066. Offset += 3 * sizeof(long) + sizeof(void*);
  1067. // The lower part is a metafile handle.
  1068. if ( HGLOBAL_DATA_PASSING( *pFlags) )
  1069. {
  1070. ulong ulDataSize = GetMetaFileBitsEx( pMFP->hMF, 0 , NULL );
  1071. Offset += 12 + ulDataSize;
  1072. }
  1073. GlobalUnlock( *(HANDLE *)pHMetaFilePict );
  1074. return( Offset ) ;
  1075. }
  1076. //+-------------------------------------------------------------------------
  1077. //
  1078. // Function: HMETAFILEPICT_UserMarshal
  1079. //
  1080. // Synopsis: Marshalls an HMETAFILEPICT object into the RPC buffer.
  1081. //
  1082. // history: May-95 Ryszardk Created.
  1083. //
  1084. //--------------------------------------------------------------------------
  1085. unsigned char __RPC_FAR * __RPC_USER
  1086. HMETAFILEPICT_UserMarshal (
  1087. unsigned long * pFlags,
  1088. unsigned char * pBuffer,
  1089. HMETAFILEPICT * pHMetaFilePict )
  1090. {
  1091. if ( !pHMetaFilePict )
  1092. return pBuffer;
  1093. UserNdrDebugOut((UNDR_OUT4, "HMETAFILEPICT_UserMarshal\n"));
  1094. ALIGN( pBuffer, 3 );
  1095. if ( HGLOBAL_HANDLE_PASSING(*pFlags) )
  1096. {
  1097. // Sending only the top level global handle.
  1098. *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE_MARKER;
  1099. *( PULONG_LV_CAST pBuffer)++ = (ulong)*(HANDLE*)pHMetaFilePict;
  1100. return pBuffer;
  1101. }
  1102. // userHMETAFILEPICT
  1103. // We need to send the data from the top (hglobal) layer.
  1104. *( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER;
  1105. *( PULONG_LV_CAST pBuffer)++ = (ulong)*pHMetaFilePict;
  1106. if ( ! *pHMetaFilePict )
  1107. return pBuffer;
  1108. // remoteHMETAFILEPICT
  1109. METAFILEPICT * pMFP = (METAFILEPICT*) GlobalLock(
  1110. *(HANDLE *)pHMetaFilePict );
  1111. if ( pMFP == NULL )
  1112. RpcRaiseException( E_OUTOFMEMORY );
  1113. *( PULONG_LV_CAST pBuffer)++ = pMFP->mm;
  1114. *( PULONG_LV_CAST pBuffer)++ = pMFP->xExt;
  1115. *( PULONG_LV_CAST pBuffer)++ = pMFP->yExt;
  1116. *( PULONG_LV_CAST pBuffer)++ = (ulong) pMFP->hMF;
  1117. // See if the HMETAFILE needs to be sent as data, too.
  1118. if ( pMFP->hMF && HGLOBAL_DATA_PASSING(*pFlags) )
  1119. {
  1120. ulong ulDataSize = GetMetaFileBitsEx( pMFP->hMF, 0 , NULL );
  1121. // conformant size then the size field
  1122. *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
  1123. *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
  1124. GetMetaFileBitsEx( pMFP->hMF, ulDataSize , pBuffer );
  1125. pBuffer += ulDataSize;
  1126. }
  1127. GlobalUnlock( *(HANDLE *)pHMetaFilePict );
  1128. return( pBuffer );
  1129. }
  1130. //+-------------------------------------------------------------------------
  1131. //
  1132. // Function: HMETAFILEPICT_UserUnmarshal
  1133. //
  1134. // Synopsis: Unmarshalls an HMETAFILEPICT object from the RPC buffer.
  1135. //
  1136. // history: May-95 Ryszardk Created.
  1137. //
  1138. //--------------------------------------------------------------------------
  1139. unsigned char __RPC_FAR * __RPC_USER
  1140. HMETAFILEPICT_UserUnmarshal (
  1141. unsigned long * pFlags,
  1142. unsigned char * pBufferStart,
  1143. HMETAFILEPICT * pHMetaFilePict )
  1144. {
  1145. unsigned long ulDataSize, fHandle;
  1146. unsigned char * pBuffer;
  1147. HMETAFILEPICT hMetaFilePict;
  1148. UserNdrDebugOut((UNDR_OUT4, "HMETAFILEPICT_UserUnmarshal\n"));
  1149. pBuffer = pBufferStart;
  1150. ALIGN( pBuffer, 3 );
  1151. unsigned long UnionDisc = *( PULONG_LV_CAST pBuffer)++;
  1152. hMetaFilePict = (HMETAFILEPICT) *( PULONG_LV_CAST pBuffer)++;
  1153. if ( IS_DATA_MARKER( UnionDisc) && hMetaFilePict )
  1154. {
  1155. HGLOBAL hGlobal = GlobalAlloc( GMEM_MOVEABLE, sizeof(METAFILEPICT) );
  1156. hMetaFilePict = (HMETAFILEPICT) hGlobal;
  1157. if ( hMetaFilePict == NULL )
  1158. RpcRaiseException( E_OUTOFMEMORY );
  1159. METAFILEPICT * pMFP = (METAFILEPICT*) GlobalLock(
  1160. (HANDLE) hMetaFilePict );
  1161. if ( pMFP == NULL )
  1162. RpcRaiseException( E_OUTOFMEMORY );
  1163. pMFP->mm = *( PULONG_LV_CAST pBuffer)++;
  1164. pMFP->xExt = *( PULONG_LV_CAST pBuffer)++;
  1165. pMFP->yExt = *( PULONG_LV_CAST pBuffer)++;
  1166. pMFP->hMF = (HMETAFILE) *( PULONG_LV_CAST pBuffer)++;
  1167. if ( pMFP->hMF && HGLOBAL_DATA_PASSING(*pFlags) )
  1168. {
  1169. // conformant size then the size field
  1170. ulong ulDataSize = *( PULONG_LV_CAST pBuffer)++;
  1171. pBuffer += 4;
  1172. pMFP->hMF = SetMetaFileBitsEx( ulDataSize, (uchar*)pBuffer );
  1173. pBuffer += ulDataSize;
  1174. }
  1175. GlobalUnlock( (HANDLE) hMetaFilePict );
  1176. }
  1177. // no reusage, just release the previous one.
  1178. if ( *pHMetaFilePict )
  1179. {
  1180. // This may happen on the client only and doesn't depend on
  1181. // how the other one was passed.
  1182. METAFILEPICT *
  1183. pMFP = (METAFILEPICT*) GlobalLock( *(HANDLE *)pHMetaFilePict );
  1184. if ( pMFP == NULL )
  1185. RpcRaiseException( E_OUTOFMEMORY );
  1186. if ( pMFP->hMF )
  1187. DeleteMetaFile( pMFP->hMF );
  1188. GlobalUnlock( *pHMetaFilePict );
  1189. GlobalFree( *pHMetaFilePict );
  1190. }
  1191. *pHMetaFilePict = hMetaFilePict;
  1192. return( pBuffer );
  1193. }
  1194. //+-------------------------------------------------------------------------
  1195. //
  1196. // Function: HMETAFILEPICT_UserFree
  1197. //
  1198. // Synopsis: Free an HMETAFILEPICT.
  1199. //
  1200. // history: May-95 Ryszardk Created.
  1201. //
  1202. //--------------------------------------------------------------------------
  1203. void __RPC_USER
  1204. HMETAFILEPICT_UserFree(
  1205. unsigned long * pFlags,
  1206. HMETAFILEPICT * pHMetaFilePict )
  1207. {
  1208. UserNdrDebugOut((UNDR_FORCE, "HMETAFILEPICT_UserFree\n"));
  1209. if( pHMetaFilePict && *pHMetaFilePict )
  1210. {
  1211. if ( HGLOBAL_HANDLE_PASSING(*pFlags) )
  1212. return;
  1213. // Need to free the upper hglobal part.
  1214. METAFILEPICT *
  1215. pMFP = (METAFILEPICT*) GlobalLock( *(HANDLE *)pHMetaFilePict );
  1216. if ( pMFP == NULL )
  1217. RpcRaiseException( E_OUTOFMEMORY );
  1218. // See if we need to free the hglobal, too.
  1219. if ( pMFP->hMF && HGLOBAL_DATA_PASSING(*pFlags) )
  1220. DeleteMetaFile( pMFP->hMF );
  1221. GlobalUnlock( *pHMetaFilePict );
  1222. GlobalFree( *pHMetaFilePict );
  1223. }
  1224. }
  1225. // #########################################################################
  1226. //
  1227. // HENHMETAFILE
  1228. // See transmit.h for explanation of lax data/handle passing.
  1229. //
  1230. // #########################################################################
  1231. //+-------------------------------------------------------------------------
  1232. //
  1233. // Function: HENHMETAFILE_UserSize
  1234. //
  1235. // Synopsis: Get the wire size the HENHMETAFILE handle and data.
  1236. //
  1237. // Derivation: Union of a long and the meta file handle and then struct.
  1238. //
  1239. // history: May-95 Ryszardk Created.
  1240. //
  1241. //--------------------------------------------------------------------------
  1242. unsigned long __RPC_USER
  1243. HENHMETAFILE_UserSize (
  1244. unsigned long * pFlags,
  1245. unsigned long Offset,
  1246. HENHMETAFILE * pHEnhMetafile )
  1247. {
  1248. if ( !pHEnhMetafile )
  1249. return Offset;
  1250. LENGTH_ALIGN( Offset, 3 );
  1251. // The encapsulated union.
  1252. // Discriminant and then handle or pointer from the union arm.
  1253. Offset += sizeof(long) + sizeof(void*);
  1254. if ( ! *pHEnhMetafile )
  1255. return Offset;
  1256. if ( GDI_DATA_PASSING(*pFlags) )
  1257. {
  1258. // Pointee of the union arm for the remote case.
  1259. // Byte blob : conformant size, size field, data
  1260. Offset += 2 * sizeof(long);
  1261. ulong ulDataSize = GetEnhMetaFileBits( *pHEnhMetafile, 0, NULL );
  1262. Offset += ulDataSize;
  1263. }
  1264. return( Offset );
  1265. }
  1266. //+-------------------------------------------------------------------------
  1267. //
  1268. // Function: HENHMETAFILE_UserMarshall
  1269. //
  1270. // Synopsis: Marshalls an HENHMETAFILE object into the RPC buffer.
  1271. //
  1272. // history: May-95 Ryszardk Created.
  1273. //
  1274. //--------------------------------------------------------------------------
  1275. unsigned char __RPC_FAR * __RPC_USER
  1276. HENHMETAFILE_UserMarshal (
  1277. unsigned long * pFlags,
  1278. unsigned char * pBuffer,
  1279. HENHMETAFILE * pHEnhMetafile )
  1280. {
  1281. if ( !pHEnhMetafile )
  1282. return pBuffer;
  1283. UserNdrDebugOut((UNDR_OUT4, "HENHMETAFILE_UserMarshal\n"));
  1284. ALIGN( pBuffer, 3 );
  1285. // Discriminant of the encapsulated union and union arm.
  1286. if ( GDI_DATA_PASSING(*pFlags) )
  1287. {
  1288. // userHENHMETAFILE
  1289. *( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER;
  1290. *( PULONG_LV_CAST pBuffer)++ = (ulong) *pHEnhMetafile;
  1291. if ( !*pHEnhMetafile )
  1292. return pBuffer;
  1293. // BYTE_BLOB: conformant size, size field, data
  1294. ulong ulDataSize = GetEnhMetaFileBits( *pHEnhMetafile, 0, NULL );
  1295. *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
  1296. *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
  1297. if ( 0 == GetEnhMetaFileBits( *pHEnhMetafile,
  1298. ulDataSize,
  1299. (uchar*)pBuffer ) )
  1300. RpcRaiseException( HRESULT_FROM_WIN32(GetLastError()));
  1301. pBuffer += ulDataSize;
  1302. }
  1303. else
  1304. {
  1305. // Sending a handle.
  1306. *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE_MARKER;
  1307. *( PULONG_LV_CAST pBuffer)++ = (ulong) *(HANDLE *)pHEnhMetafile;
  1308. }
  1309. return( pBuffer );
  1310. }
  1311. //+-------------------------------------------------------------------------
  1312. //
  1313. // Function: HENHMETAFILE_UserUnmarshall
  1314. //
  1315. // Synopsis: Unmarshalls an HENHMETAFILE object from the RPC buffer.
  1316. //
  1317. // history: May-95 Ryszardk Created.
  1318. //
  1319. //--------------------------------------------------------------------------
  1320. unsigned char __RPC_FAR * __RPC_USER
  1321. HENHMETAFILE_UserUnmarshal (
  1322. unsigned long * pFlags,
  1323. unsigned char * pBuffer,
  1324. HENHMETAFILE * pHEnhMetafile )
  1325. {
  1326. HENHMETAFILE hEnhMetafile;
  1327. UserNdrDebugOut((UNDR_OUT4, "HENHMETAFILE_UserUnmarshal\n"));
  1328. ALIGN( pBuffer, 3 );
  1329. unsigned long UnionDisc = *( PULONG_LV_CAST pBuffer)++;
  1330. hEnhMetafile = (HENHMETAFILE) *( PULONG_LV_CAST pBuffer)++;
  1331. if ( IS_DATA_MARKER( UnionDisc) )
  1332. {
  1333. if ( hEnhMetafile )
  1334. {
  1335. // Byte blob : conformant size, size field, data
  1336. ulong ulDataSize = *(ulong*)pBuffer;
  1337. pBuffer += 8;
  1338. hEnhMetafile = SetEnhMetaFileBits( ulDataSize, (uchar*) pBuffer );
  1339. pBuffer += ulDataSize;
  1340. }
  1341. }
  1342. // No reusage of the old object.
  1343. if (*pHEnhMetafile)
  1344. DeleteEnhMetaFile( *pHEnhMetafile );
  1345. *pHEnhMetafile = hEnhMetafile;
  1346. return( pBuffer );
  1347. }
  1348. //+-------------------------------------------------------------------------
  1349. //
  1350. // Function: HENHMETAFILE_UserFree
  1351. //
  1352. // Synopsis: Free an HENHMETAFILE.
  1353. //
  1354. // history: May-95 Ryszardk Created.
  1355. //
  1356. //--------------------------------------------------------------------------
  1357. void __RPC_USER
  1358. HENHMETAFILE_UserFree(
  1359. unsigned long * pFlags,
  1360. HENHMETAFILE * pHEnhMetafile )
  1361. {
  1362. UserNdrDebugOut((UNDR_FORCE, "HENHMETAFILE_UserFree\n"));
  1363. if( pHEnhMetafile && *pHEnhMetafile )
  1364. {
  1365. if ( GDI_DATA_PASSING(*pFlags) )
  1366. {
  1367. DeleteEnhMetaFile( *pHEnhMetafile );
  1368. }
  1369. }
  1370. }
  1371. // #########################################################################
  1372. //
  1373. // HBITMAP
  1374. // See transmit.h for explanation of lax data/handle passing.
  1375. //
  1376. // #########################################################################
  1377. //+-------------------------------------------------------------------------
  1378. //
  1379. // Function: HBITMAP_UserSize
  1380. //
  1381. // Synopsis: Get the wire size the HBITMAP handle and data.
  1382. //
  1383. // Derivation: Union of a long and the bitmap handle and then struct.
  1384. //
  1385. // history: May-95 Ryszardk Created.
  1386. //
  1387. //--------------------------------------------------------------------------
  1388. unsigned long __RPC_USER
  1389. HBITMAP_UserSize (
  1390. unsigned long * pFlags,
  1391. unsigned long Offset,
  1392. HBITMAP * pHBitmap )
  1393. {
  1394. if ( !pHBitmap )
  1395. return Offset;
  1396. BITMAP bm;
  1397. HBITMAP hBitmap = *pHBitmap;
  1398. LENGTH_ALIGN( Offset, 3 );
  1399. // The encapsulated union.
  1400. // Discriminant and then handle or pointer from the union arm.
  1401. Offset += sizeof(long) + sizeof(void*);
  1402. if ( ! *pHBitmap )
  1403. return Offset;
  1404. if ( GDI_DATA_PASSING(*pFlags) )
  1405. {
  1406. // Pointee of the union arm for the remote case.
  1407. // Conformat size, 6 fields, size, conf array.
  1408. Offset += 4 + 4 * sizeof(LONG) + 2 * sizeof(WORD) + 4;
  1409. // Get information about the bitmap
  1410. #if defined(_CHICAGO_)
  1411. if (FALSE == GetObjectA(hBitmap, sizeof(BITMAP), &bm))
  1412. #else
  1413. if (FALSE == GetObject(hBitmap, sizeof(BITMAP), &bm))
  1414. #endif
  1415. {
  1416. RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
  1417. }
  1418. ULONG ulDataSize = bm.bmPlanes * bm.bmHeight * bm.bmWidthBytes;
  1419. Offset += ulDataSize;
  1420. }
  1421. return( Offset ) ;
  1422. }
  1423. //+-------------------------------------------------------------------------
  1424. //
  1425. // Function: HBITMAP_UserMarshall
  1426. //
  1427. // Synopsis: Marshalls an HBITMAP object into the RPC buffer.
  1428. //
  1429. // history: May-95 Ryszardk Created.
  1430. //
  1431. //--------------------------------------------------------------------------
  1432. unsigned char __RPC_FAR * __RPC_USER
  1433. HBITMAP_UserMarshal (
  1434. unsigned long * pFlags,
  1435. unsigned char * pBuffer,
  1436. HBITMAP * pHBitmap )
  1437. {
  1438. if ( !pHBitmap )
  1439. return pBuffer;
  1440. UserNdrDebugOut((UNDR_OUT4, "HBITMAP_UserMarshal\n"));
  1441. ALIGN( pBuffer, 3 );
  1442. // Discriminant of the encapsulated union and union arm.
  1443. if ( GDI_DATA_PASSING(*pFlags) )
  1444. {
  1445. // userHBITMAP
  1446. *( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER;
  1447. *( PULONG_LV_CAST pBuffer)++ = (ulong) *pHBitmap;
  1448. if ( ! *pHBitmap )
  1449. return pBuffer;
  1450. // Get information about the bitmap
  1451. BITMAP bm;
  1452. HBITMAP hBitmap = *pHBitmap;
  1453. #if defined(_CHICAGO_)
  1454. if (FALSE == GetObjectA(hBitmap, sizeof(BITMAP), &bm))
  1455. #else
  1456. if (FALSE == GetObject(hBitmap, sizeof(BITMAP), &bm))
  1457. #endif
  1458. {
  1459. RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
  1460. }
  1461. DWORD dwCount = bm.bmPlanes * bm.bmHeight * bm.bmWidthBytes;
  1462. *( PULONG_LV_CAST pBuffer)++ = dwCount;
  1463. // Get the bm structure fields.
  1464. ulong ulBmSize = 4 * sizeof(LONG) + 2 * sizeof( WORD );
  1465. memcpy( pBuffer, (void *) &bm, ulBmSize );
  1466. pBuffer += ulBmSize;
  1467. // Get the raw bits.
  1468. if (0 == GetBitmapBits( hBitmap, dwCount, pBuffer ) )
  1469. {
  1470. RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
  1471. }
  1472. pBuffer += dwCount;
  1473. }
  1474. else
  1475. {
  1476. // Sending a handle.
  1477. *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE_MARKER;
  1478. *( PULONG_LV_CAST pBuffer)++ = (ulong) *(HANDLE *)pHBitmap;
  1479. }
  1480. return( pBuffer );
  1481. }
  1482. //+-------------------------------------------------------------------------
  1483. //
  1484. // Function: HBITMAP_UserUnmarshall
  1485. //
  1486. // Synopsis: Unmarshalls an HBITMAP object from the RPC buffer.
  1487. //
  1488. // history: May-95 Ryszardk Created.
  1489. //
  1490. //--------------------------------------------------------------------------
  1491. unsigned char __RPC_FAR * __RPC_USER
  1492. HBITMAP_UserUnmarshal (
  1493. unsigned long * pFlags,
  1494. unsigned char * pBuffer,
  1495. HBITMAP * pHBitmap )
  1496. {
  1497. HBITMAP hBitmap;
  1498. UserNdrDebugOut((UNDR_OUT4, "HBITMAP_UserUnmarshal\n"));
  1499. ALIGN( pBuffer, 3 );
  1500. unsigned long UnionDisc = *( PULONG_LV_CAST pBuffer)++;
  1501. hBitmap = (HBITMAP) *( PULONG_LV_CAST pBuffer)++;
  1502. if ( IS_DATA_MARKER( UnionDisc) )
  1503. {
  1504. if ( hBitmap )
  1505. {
  1506. DWORD dwCount = *( PULONG_LV_CAST pBuffer)++;
  1507. BITMAP * pBm = (BITMAP *) pBuffer;
  1508. ulong ulBmSize = 4 * sizeof(LONG) + 2 * sizeof( WORD );
  1509. pBuffer += ulBmSize;
  1510. // Create a bitmap based on the BITMAP structure and the raw bits in
  1511. // the transmission buffer
  1512. hBitmap = CreateBitmap( pBm->bmWidth,
  1513. pBm->bmHeight,
  1514. pBm->bmPlanes,
  1515. pBm->bmBitsPixel,
  1516. pBuffer );
  1517. pBuffer += dwCount;
  1518. }
  1519. }
  1520. // A new bitmap handle is ready, destroy the old one, if needed.
  1521. if ( *pHBitmap )
  1522. DeleteObject( *pHBitmap );
  1523. *pHBitmap = hBitmap;
  1524. return( pBuffer );
  1525. }
  1526. //+-------------------------------------------------------------------------
  1527. //
  1528. // Function: HBITMAP_UserFree
  1529. //
  1530. // Synopsis: Free an HBITMAP.
  1531. //
  1532. // history: May-95 Ryszardk Created.
  1533. //
  1534. //--------------------------------------------------------------------------
  1535. void __RPC_USER
  1536. HBITMAP_UserFree(
  1537. unsigned long * pFlags,
  1538. HBITMAP * pHBitmap )
  1539. {
  1540. UserNdrDebugOut((UNDR_OUT4, "HBITMAP_UserFree\n"));
  1541. if( pHBitmap && *pHBitmap )
  1542. {
  1543. if ( GDI_DATA_PASSING(*pFlags) )
  1544. {
  1545. DeleteObject( *pHBitmap );
  1546. }
  1547. }
  1548. }
  1549. // #########################################################################
  1550. //
  1551. // HPALETTE
  1552. // See transmit.h for explanation of lax data/handle passing.
  1553. //
  1554. // #########################################################################
  1555. //+-------------------------------------------------------------------------
  1556. //
  1557. // Function: HPALETTE_UserSize
  1558. //
  1559. // Synopsis: Get the wire size the HPALETTE handle and data.
  1560. //
  1561. // Derivation: Union of a long and the hpalette handle.
  1562. // Then the struct represents hpalette.
  1563. //
  1564. // history: May-95 Ryszardk Created.
  1565. //
  1566. //--------------------------------------------------------------------------
  1567. unsigned long __RPC_USER
  1568. HPALETTE_UserSize (
  1569. unsigned long * pFlags,
  1570. unsigned long Offset,
  1571. HPALETTE * pHPalette )
  1572. {
  1573. if ( !pHPalette )
  1574. return Offset;
  1575. BITMAP bm;
  1576. LENGTH_ALIGN( Offset, 3 );
  1577. // The encapsulated union.
  1578. // Discriminant and then handle or pointer from the union arm.
  1579. Offset += sizeof(long) + sizeof(void*);
  1580. if ( ! *pHPalette )
  1581. return Offset;
  1582. if ( GDI_DATA_PASSING(*pFlags) )
  1583. {
  1584. // Conformat struct with version and size and conf array of entries.
  1585. Offset += sizeof(long) + 2 * sizeof(short);
  1586. // Determine the number of color entries in the palette
  1587. DWORD cEntries = GetPaletteEntries(*pHPalette, 0, 0, NULL);
  1588. Offset += cEntries * sizeof(PALETTEENTRY);
  1589. }
  1590. return( Offset ) ;
  1591. }
  1592. //+-------------------------------------------------------------------------
  1593. //
  1594. // Function: HPALETTE_UserMarshall
  1595. //
  1596. // Synopsis: Marshalls an HPALETTE object into the RPC buffer.
  1597. //
  1598. // history: May-95 Ryszardk Created.
  1599. //
  1600. //--------------------------------------------------------------------------
  1601. unsigned char __RPC_FAR * __RPC_USER
  1602. HPALETTE_UserMarshal (
  1603. unsigned long * pFlags,
  1604. unsigned char * pBuffer,
  1605. HPALETTE * pHPalette )
  1606. {
  1607. if ( !pHPalette )
  1608. return pBuffer;
  1609. UserNdrDebugOut((UNDR_OUT4, "HPALETTE_UserMarshal\n"));
  1610. ALIGN( pBuffer, 3 );
  1611. // Discriminant of the encapsulated union and union arm.
  1612. if ( GDI_DATA_PASSING(*pFlags) )
  1613. {
  1614. // userHPALETTE
  1615. *( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER;
  1616. *( PULONG_LV_CAST pBuffer)++ = (ulong) *pHPalette;
  1617. if ( ! *pHPalette )
  1618. return pBuffer;
  1619. // rpcLOGPALETTE
  1620. // Logpalette is a conformant struct with a version field,
  1621. // size filed and conformant array of palentries.
  1622. // Determine the number of color entries in the palette
  1623. DWORD cEntries = GetPaletteEntries(*pHPalette, 0, 0, NULL);
  1624. // Conformant size
  1625. *( PULONG_LV_CAST pBuffer)++ = cEntries;
  1626. // Fields: both are short!
  1627. // The old code was just setting the version number.
  1628. // They say it has to be that way.
  1629. *( PUSHORT_LV_CAST pBuffer)++ = (ushort) 0x300;
  1630. *( PUSHORT_LV_CAST pBuffer)++ = (ushort) cEntries;
  1631. // Entries: each entry is a struct with 4 bytes.
  1632. // Calculate the resultant data size
  1633. DWORD cbData = cEntries * sizeof(PALETTEENTRY);
  1634. if (cbData)
  1635. {
  1636. if (0 == GetPaletteEntries( *pHPalette,
  1637. 0,
  1638. cEntries,
  1639. (PALETTEENTRY *)pBuffer ) )
  1640. {
  1641. RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
  1642. }
  1643. pBuffer += cbData;
  1644. }
  1645. }
  1646. else
  1647. {
  1648. // Sending a handle.
  1649. *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE_MARKER;
  1650. *( PULONG_LV_CAST pBuffer)++ = (ulong) *(HANDLE *)pHPalette;
  1651. }
  1652. return( pBuffer );
  1653. }
  1654. //+-------------------------------------------------------------------------
  1655. //
  1656. // Function: HPALETTE_UserUnmarshall
  1657. //
  1658. // Synopsis: Unmarshalls an HPALETTE object from the RPC buffer.
  1659. //
  1660. // history: May-95 Ryszardk Created.
  1661. //
  1662. //--------------------------------------------------------------------------
  1663. unsigned char __RPC_FAR * __RPC_USER
  1664. HPALETTE_UserUnmarshal (
  1665. unsigned long * pFlags,
  1666. unsigned char * pBuffer,
  1667. HPALETTE * pHPalette )
  1668. {
  1669. HPALETTE hPalette;
  1670. UserNdrDebugOut((UNDR_OUT4, "HPALETTE_UserUnmarshal\n"));
  1671. ALIGN( pBuffer, 3 );
  1672. unsigned long UnionDisc = *( PULONG_LV_CAST pBuffer)++;
  1673. hPalette = (HPALETTE) *( PULONG_LV_CAST pBuffer)++;
  1674. if ( IS_DATA_MARKER( UnionDisc) )
  1675. {
  1676. if ( hPalette )
  1677. {
  1678. // Get the conformant size.
  1679. DWORD cEntries = *( PULONG_LV_CAST pBuffer)++;
  1680. LOGPALETTE * pLogPal;
  1681. // If there are 0 color entries, we need to allocate the LOGPALETTE
  1682. // structure with the one dummy entry (it's a variably sized struct).
  1683. // Otherwise, we need to allocate enough space for the extra n-1
  1684. // entries at the tail of the structure
  1685. if (0 == cEntries)
  1686. {
  1687. pLogPal = (LOGPALETTE *) WdtpAllocate( pFlags,
  1688. sizeof(LOGPALETTE));
  1689. }
  1690. else
  1691. {
  1692. pLogPal = (LOGPALETTE *)
  1693. WdtpAllocate( pFlags,
  1694. sizeof(LOGPALETTE) +
  1695. (cEntries - 1) * sizeof(PALETTEENTRY));
  1696. }
  1697. pLogPal->palVersion = *( PUSHORT_LV_CAST pBuffer)++;
  1698. pLogPal->palNumEntries = *( PUSHORT_LV_CAST pBuffer)++;
  1699. // If there are entries, move them into out LOGPALETTE structure
  1700. if (cEntries)
  1701. {
  1702. memcpy( &(pLogPal->palPalEntry[0]),
  1703. pBuffer,
  1704. cEntries * sizeof(PALETTEENTRY) );
  1705. pBuffer += cEntries * sizeof(PALETTEENTRY);
  1706. }
  1707. // Attempt to create the palette
  1708. hPalette = CreatePalette(pLogPal);
  1709. // Success or failure, we're done with the LOGPALETTE structure
  1710. WdtpFree( pFlags, pLogPal );
  1711. // If the creation failed, raise an exception
  1712. if (NULL == hPalette)
  1713. {
  1714. RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
  1715. }
  1716. }
  1717. }
  1718. // A new palette is ready, destroy the old one, if needed.
  1719. if ( *pHPalette )
  1720. DeleteObject( *pHPalette );
  1721. *pHPalette = hPalette;
  1722. return( pBuffer );
  1723. }
  1724. //+-------------------------------------------------------------------------
  1725. //
  1726. // Function: HPALETTE_UserFree
  1727. //
  1728. // Synopsis: Free an HPALETTE.
  1729. //
  1730. // history: May-95 Ryszardk Created.
  1731. //
  1732. //--------------------------------------------------------------------------
  1733. void __RPC_USER
  1734. HPALETTE_UserFree(
  1735. unsigned long * pFlags,
  1736. HPALETTE * pHPalette )
  1737. {
  1738. UserNdrDebugOut((UNDR_OUT4, "HPALETTE_UserFree\n"));
  1739. if( pHPalette && *pHPalette )
  1740. {
  1741. if ( GDI_DATA_PASSING(*pFlags) )
  1742. {
  1743. DeleteObject( *pHPalette );
  1744. }
  1745. }
  1746. }
  1747. // #########################################################################
  1748. //
  1749. // NON REMOTABLE GDI and other HANDLES
  1750. //
  1751. // #########################################################################
  1752. //+-------------------------------------------------------------------------
  1753. //
  1754. // Function: WdtpNonRemotableHandle_UserSize
  1755. //
  1756. // Synopsis: Get the wire size for a non remotable GDI handle.
  1757. //
  1758. // Derivation: Union of a long and nothing.
  1759. // It is union just in case some remoting is needed.
  1760. //
  1761. // history: May-95 Ryszardk Created.
  1762. //
  1763. //--------------------------------------------------------------------------
  1764. unsigned long __RPC_USER
  1765. WdtpNonRemotableHandle_UserSize (
  1766. unsigned long * pFlags,
  1767. unsigned long Offset,
  1768. HANDLE * pHandle )
  1769. {
  1770. if ( !pHandle || *pHandle == NULL )
  1771. return Offset;
  1772. if ( HGLOBAL_DATA_PASSING(*pFlags) )
  1773. RpcRaiseException(E_INVALIDARG );
  1774. LENGTH_ALIGN( Offset, 3 );
  1775. // The encapsulated union.
  1776. // No remote case on any platform.
  1777. return( Offset + 8 ) ;
  1778. }
  1779. //+-------------------------------------------------------------------------
  1780. //
  1781. // Function: WdtpNonRemotableHandle_UserMarshal
  1782. //
  1783. // Synopsis: Marshalls a non-remotable handle into the RPC buffer.
  1784. //
  1785. // history: May-95 Ryszardk Created.
  1786. //
  1787. //--------------------------------------------------------------------------
  1788. unsigned char __RPC_FAR * __RPC_USER
  1789. WdtpNonRemotableHandle_UserMarshal (
  1790. unsigned long * pFlags,
  1791. unsigned char * pBuffer,
  1792. HANDLE * pHandle )
  1793. {
  1794. if ( !pHandle || *pHandle == NULL )
  1795. return pBuffer;
  1796. ALIGN( pBuffer, 3 );
  1797. // Discriminant of the encapsulated union and union arm.
  1798. if ( HGLOBAL_DATA_PASSING(*pFlags) )
  1799. {
  1800. RpcRaiseException(E_INVALIDARG );
  1801. }
  1802. else
  1803. {
  1804. // Sending a handle.
  1805. *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE_MARKER;
  1806. *( PULONG_LV_CAST pBuffer)++ = (ulong) *(HANDLE *)pHandle;
  1807. }
  1808. return( pBuffer );
  1809. }
  1810. //+-------------------------------------------------------------------------
  1811. //
  1812. // Function: WdtpNonRemotableHandle_UserUnmarshal
  1813. //
  1814. // Synopsis: Unmarshalls a non-remotable handle from the RPC buffer.
  1815. //
  1816. // history: May-95 Ryszardk Created.
  1817. //
  1818. //--------------------------------------------------------------------------
  1819. unsigned char __RPC_FAR * __RPC_USER
  1820. WdtpNonRemotableHandle_UserUnmarshal (
  1821. unsigned long * pFlags,
  1822. unsigned char * pBuffer,
  1823. HANDLE * pHandle )
  1824. {
  1825. ALIGN( pBuffer, 3 );
  1826. unsigned long UnionDisc = *( PULONG_LV_CAST pBuffer)++;
  1827. if ( IS_DATA_MARKER( UnionDisc) )
  1828. {
  1829. RpcRaiseException(E_INVALIDARG );
  1830. }
  1831. else
  1832. {
  1833. // Sending a handle.
  1834. *pHandle = (HANDLE) *( PULONG_LV_CAST pBuffer)++;
  1835. }
  1836. return( pBuffer );
  1837. }
  1838. //+-------------------------------------------------------------------------
  1839. //
  1840. // Function: WdtpNonRemotableHandle_UserFree
  1841. //
  1842. // Synopsis: Nothing to free.
  1843. //
  1844. //--------------------------------------------------------------------------
  1845. void __RPC_USER
  1846. WdtpNonRemotableGdiHandle_UserFree(
  1847. unsigned long * pFlags,
  1848. HANDLE * pHandle )
  1849. {
  1850. }
  1851. // #########################################################################
  1852. //
  1853. // Interface pointers.
  1854. //
  1855. // #########################################################################
  1856. //+-------------------------------------------------------------------------
  1857. //
  1858. // Function: WdtpInterfacePointer_UserSize
  1859. //
  1860. // Synopsis: Get the wire size for an interface pointer.
  1861. //
  1862. // history: May-95 Ryszardk Created.
  1863. //
  1864. //--------------------------------------------------------------------------
  1865. unsigned long __RPC_USER
  1866. WdtpInterfacePointer_UserSize (
  1867. USER_MARSHAL_CB * pContext,
  1868. unsigned long Flags,
  1869. unsigned long Offset,
  1870. IUnknown * pIf,
  1871. const IID & IId )
  1872. {
  1873. if ( pIf )
  1874. {
  1875. LENGTH_ALIGN( Offset, 3 );
  1876. //Leave space for array bounds and length
  1877. Offset += 2 * sizeof(long);
  1878. HRESULT hr;
  1879. unsigned long cbSize = 0;
  1880. hr = CoGetMarshalSizeMax( &cbSize,
  1881. IId,
  1882. pIf,
  1883. USER_CALL_CTXT_MASK( Flags ),
  1884. pContext->pStubMsg->pvDestContext,
  1885. MSHLFLAGS_NORMAL );
  1886. if ( FAILED(hr) )
  1887. RpcRaiseException( hr );
  1888. Offset += cbSize;
  1889. }
  1890. return( Offset ) ;
  1891. }
  1892. //+-------------------------------------------------------------------------
  1893. //
  1894. // Function: WdtpInterfacePointer_UserMarshal
  1895. //
  1896. // Synopsis: Marshalls an interface pointer.
  1897. //
  1898. // history: May-95 Ryszardk Created.
  1899. //
  1900. //--------------------------------------------------------------------------
  1901. unsigned char __RPC_FAR * __RPC_USER
  1902. WdtpInterfacePointer_UserMarshal (
  1903. USER_MARSHAL_CB * pContext,
  1904. unsigned long Flags,
  1905. unsigned char * pBuffer,
  1906. IUnknown * pIf,
  1907. const IID & IId )
  1908. {
  1909. unsigned long * pMaxCount, *pSize;
  1910. unsigned long cbData = 0;
  1911. UserNdrDebugOut((UNDR_OUT1, "WdtpInterface_PointerMarshal\n"));
  1912. if ( pIf )
  1913. {
  1914. // Always marshaled because of the apartment model.
  1915. CStreamOnMessage MemStream( (unsigned char **) &pBuffer );
  1916. ALIGN( pBuffer, 3 );
  1917. pMaxCount = (unsigned long *) pBuffer;
  1918. pBuffer += 4;
  1919. // Leave space for length
  1920. pSize = (unsigned long *) pBuffer;
  1921. pBuffer += 4;
  1922. HRESULT hr;
  1923. unsigned char * pBufferMark = pBuffer;
  1924. hr = CoMarshalInterface( &MemStream,
  1925. IId,
  1926. pIf,
  1927. USER_CALL_CTXT_MASK( Flags ),
  1928. pContext->pStubMsg->pvDestContext,
  1929. MSHLFLAGS_NORMAL );
  1930. if( FAILED(hr) )
  1931. {
  1932. RpcRaiseException(hr);
  1933. }
  1934. // Calculate the size of the data written
  1935. DWORD cbData = pBuffer - pBufferMark;
  1936. // Update the array bounds.
  1937. *pMaxCount = cbData;
  1938. *pSize = cbData;
  1939. }
  1940. return( pBuffer );
  1941. }
  1942. //+-------------------------------------------------------------------------
  1943. //
  1944. // Function: WdtpInterfacePointer_UserUnmarshal
  1945. //
  1946. // Synopsis: Unmarshalls an interface pointer from the RPC buffer.
  1947. //
  1948. // history: May-95 Ryszardk Created.
  1949. //
  1950. //--------------------------------------------------------------------------
  1951. unsigned char __RPC_FAR * __RPC_USER
  1952. WdtpInterfacePointer_UserUnmarshal (
  1953. USER_MARSHAL_CB * pContext,
  1954. unsigned char * pBuffer,
  1955. IUnknown ** ppIf,
  1956. const IID & IId )
  1957. {
  1958. unsigned long *pMaxCount, *pSize;
  1959. unsigned long cbData = 0;
  1960. UserNdrDebugOut((UNDR_OUT1, "WdtpInterfacePointerUnmarshal\n"));
  1961. // Always unmarshaled because of the apartment model.
  1962. CStreamOnMessage MemStream((unsigned char **) &pBuffer);
  1963. ALIGN( pBuffer, 3 );
  1964. pMaxCount = (unsigned long *) pBuffer;
  1965. pBuffer += sizeof(long);
  1966. //Unmarshal count
  1967. pSize = (unsigned long *) pBuffer;
  1968. pBuffer += sizeof(long);
  1969. // Release the old pointer after unmarshalling the new one
  1970. // to prevent object from getting released too early.
  1971. // Then release the old one only when successful.
  1972. IUnknown * punkTemp = 0;
  1973. HRESULT hr = CoUnmarshalInterface( &MemStream,
  1974. IId,
  1975. (void **) &punkTemp );
  1976. if(FAILED(hr))
  1977. RpcRaiseException(hr);
  1978. else
  1979. {
  1980. // On the client side, release the [in,out] interface pointer.
  1981. // The pointer may be different from NULL only on the client side.
  1982. if ( (IId == IID_IStorage || IId == IID_IStream ) && *ppIf )
  1983. {
  1984. // This may happen only on the client side.
  1985. // Throw away a new one when coming back to the client !!
  1986. // This is a pecularity of DocFile custom marshalling:
  1987. // pointer identity is broken.
  1988. if ( punkTemp )
  1989. punkTemp->Release();
  1990. // keep the old one
  1991. }
  1992. else
  1993. {
  1994. // release the old one, keep the new one.
  1995. if ( *ppIf )
  1996. (*ppIf)->Release();
  1997. *ppIf = punkTemp;
  1998. }
  1999. }
  2000. return( pBuffer );
  2001. }
  2002. //+-------------------------------------------------------------------------
  2003. //
  2004. // Function: WdtpInterfacePointer_UserFree
  2005. //
  2006. // Synopsis: Releases an interface pointer.
  2007. //
  2008. // history: May-95 Ryszardk Created.
  2009. //
  2010. //--------------------------------------------------------------------------
  2011. void __RPC_USER
  2012. WdtpInterfacePointer_UserFree(
  2013. IUnknown * pIf )
  2014. {
  2015. UserNdrDebugOut((UNDR_OUT1, "WdtpInterfacePointer_UserFree\n"));
  2016. if( pIf )
  2017. {
  2018. pIf->Release();
  2019. }
  2020. }
  2021. //+-------------------------------------------------------------------------
  2022. //
  2023. // Function: STGMEDIUM_UserSize
  2024. //
  2025. // Synopsis: Sizes a stgmedium pbject for RPC marshalling.
  2026. //
  2027. // history: May-95 Ryszardk Created.
  2028. //
  2029. //--------------------------------------------------------------------------
  2030. unsigned long __RPC_USER
  2031. STGMEDIUM_UserSize(
  2032. unsigned long * pFlags,
  2033. unsigned long Offset,
  2034. STGMEDIUM * pStgmed )
  2035. {
  2036. if ( ! pStgmed )
  2037. return Offset;
  2038. LENGTH_ALIGN( Offset, 3 );
  2039. if ( pStgmed->tymed == TYMED_NULL )
  2040. Offset += sizeof(void*) + sizeof(long); // pointer, switch only
  2041. else
  2042. Offset += sizeof(void*) + sizeof(long) + sizeof(void*); // same + handle
  2043. // Pointee of the union arm.
  2044. // Only if the handle/pointer field is non-null.
  2045. if ( pStgmed->hGlobal )
  2046. {
  2047. switch( pStgmed->tymed )
  2048. {
  2049. case TYMED_NULL:
  2050. break;
  2051. case TYMED_MFPICT:
  2052. Offset = HMETAFILEPICT_UserSize( pFlags,
  2053. Offset,
  2054. &pStgmed->hMetaFilePict );
  2055. break;
  2056. case TYMED_ENHMF:
  2057. Offset = HENHMETAFILE_UserSize( pFlags,
  2058. Offset,
  2059. &pStgmed->hEnhMetaFile );
  2060. break;
  2061. case TYMED_GDI:
  2062. // A GDI object is not necesarrily a BITMAP. Therefore, we handle
  2063. // those types we know about based on the object type, and reject
  2064. // those which we do not support.
  2065. // switch for object type.
  2066. Offset += sizeof(long);
  2067. switch( GetObjectType( (HGDIOBJ)pStgmed->hBitmap ) )
  2068. {
  2069. case OBJ_BITMAP:
  2070. Offset = HBITMAP_UserSize( pFlags,
  2071. Offset,
  2072. &pStgmed->hBitmap );
  2073. break;
  2074. case OBJ_PAL:
  2075. Offset = HPALETTE_UserSize( pFlags,
  2076. Offset,
  2077. (HPALETTE *) & pStgmed->hBitmap );
  2078. break;
  2079. default:
  2080. RpcRaiseException(DV_E_TYMED);
  2081. break;
  2082. }
  2083. break;
  2084. case TYMED_HGLOBAL:
  2085. Offset = HGLOBAL_UserSize( pFlags,
  2086. Offset,
  2087. &pStgmed->hGlobal );
  2088. break;
  2089. case TYMED_FILE:
  2090. {
  2091. ulong ulDataSize = wcslen(pStgmed->lpszFileName) + 1;
  2092. Offset += 3 * sizeof(long); // [string]
  2093. Offset += ulDataSize * sizeof(wchar_t);
  2094. }
  2095. break;
  2096. case TYMED_ISTREAM:
  2097. case TYMED_ISTORAGE:
  2098. // Note, that we have to set the local flag for backward
  2099. // compatibility.
  2100. Offset = WdtpInterfacePointer_UserSize(
  2101. (USER_MARSHAL_CB *)pFlags,
  2102. MSHCTX_LOCAL,
  2103. Offset,
  2104. pStgmed->pstg,
  2105. ((pStgmed->tymed == TYMED_ISTREAM) ? IID_IStream
  2106. : IID_IStorage));
  2107. break;
  2108. default:
  2109. break;
  2110. }
  2111. }
  2112. // pUnkForRelease, if not null.
  2113. if ( pStgmed->pUnkForRelease )
  2114. Offset = WdtpInterfacePointer_UserSize( (USER_MARSHAL_CB *)pFlags,
  2115. *pFlags,
  2116. Offset,
  2117. pStgmed->pUnkForRelease,
  2118. IID_IUnknown );
  2119. return( Offset );
  2120. }
  2121. //+-------------------------------------------------------------------------
  2122. //
  2123. // Function: STGMEDIUM_UserMarshal
  2124. //
  2125. // Synopsis: Marshals a stgmedium pbject for RPC.
  2126. //
  2127. // history: May-95 Ryszardk Created.
  2128. //
  2129. //--------------------------------------------------------------------------
  2130. unsigned char __RPC_FAR * __RPC_USER
  2131. STGMEDIUM_UserMarshal(
  2132. unsigned long * pFlags,
  2133. unsigned char * pBufferStart,
  2134. STGMEDIUM * pStgmed )
  2135. {
  2136. unsigned char * pBuffer;
  2137. unsigned char * pUnionArmMark;
  2138. if ( ! pStgmed )
  2139. return pBufferStart;
  2140. UserNdrDebugOut((UNDR_FORCE, "--STGMEDIUM_UserMarshal: %s\n", WdtpGetStgmedName(pStgmed)));
  2141. pBuffer = pBufferStart;
  2142. ALIGN( pBuffer, 3 );
  2143. // userSTGMEDIUM: if pointer, switch, union arm, .
  2144. *( PULONG_LV_CAST pBuffer)++ = (ulong)pStgmed->pUnkForRelease;
  2145. *( PULONG_LV_CAST pBuffer)++ = pStgmed->tymed;
  2146. pUnionArmMark = pBuffer;
  2147. if ( pStgmed->tymed != TYMED_NULL )
  2148. {
  2149. // hGlobal stands for any of these handles.
  2150. *( PULONG_LV_CAST pBuffer)++ = (ulong)pStgmed->hGlobal;
  2151. }
  2152. // Now the pointee of the union arm.
  2153. // We need to marshal only if the handle/pointer field is non null.
  2154. // Otherwise it is already in the buffer.
  2155. if ( pStgmed->hGlobal )
  2156. {
  2157. switch( pStgmed->tymed )
  2158. {
  2159. case TYMED_NULL:
  2160. break;
  2161. case TYMED_MFPICT:
  2162. pBuffer = HMETAFILEPICT_UserMarshal( pFlags,
  2163. pBuffer,
  2164. &pStgmed->hMetaFilePict );
  2165. break;
  2166. case TYMED_ENHMF:
  2167. pBuffer = HENHMETAFILE_UserMarshal( pFlags,
  2168. pBuffer,
  2169. &pStgmed->hEnhMetaFile );
  2170. break;
  2171. case TYMED_GDI:
  2172. {
  2173. // A GDI object is not necesarrily a BITMAP. Therefore, we handle
  2174. // those types we know about based on the object type, and reject
  2175. // those which we do not support.
  2176. ulong GdiObjectType = GetObjectType( (HGDIOBJ)pStgmed->hBitmap );
  2177. // GDI_OBJECT
  2178. *( PULONG_LV_CAST pBuffer)++ = GdiObjectType;
  2179. switch( GdiObjectType )
  2180. {
  2181. case OBJ_BITMAP:
  2182. pBuffer = HBITMAP_UserMarshal( pFlags,
  2183. pBuffer,
  2184. &pStgmed->hBitmap );
  2185. break;
  2186. case OBJ_PAL:
  2187. pBuffer = HPALETTE_UserMarshal( pFlags,
  2188. pBuffer,
  2189. (HPALETTE *) & pStgmed->hBitmap );
  2190. break;
  2191. default:
  2192. RpcRaiseException(DV_E_TYMED);
  2193. }
  2194. }
  2195. break;
  2196. case TYMED_HGLOBAL:
  2197. pBuffer = HGLOBAL_UserMarshal( pFlags,
  2198. pBuffer,
  2199. & pStgmed->hGlobal );
  2200. break;
  2201. case TYMED_FILE:
  2202. {
  2203. // We marshal it as a [string].
  2204. ulong Count = (pStgmed->lpszFileName)
  2205. ? wcslen(pStgmed->lpszFileName) + 1
  2206. : 0;
  2207. *( PULONG_LV_CAST pBuffer)++ = Count;
  2208. *( PULONG_LV_CAST pBuffer)++ = 0;
  2209. *( PULONG_LV_CAST pBuffer)++ = Count;
  2210. memcpy( pBuffer, pStgmed->lpszFileName, Count * sizeof(wchar_t) );
  2211. pBuffer += Count * sizeof(wchar_t);
  2212. }
  2213. break;
  2214. case TYMED_ISTREAM:
  2215. case TYMED_ISTORAGE:
  2216. // Note, that we have to set the local flag for backward compatibility.
  2217. pBuffer = WdtpInterfacePointer_UserMarshal(
  2218. ((USER_MARSHAL_CB *)pFlags),
  2219. MSHCTX_LOCAL,
  2220. pBuffer,
  2221. pStgmed->pstg,
  2222. ((pStgmed->tymed == TYMED_ISTREAM) ? IID_IStream
  2223. : IID_IStorage));
  2224. break;
  2225. default:
  2226. break;
  2227. }
  2228. }
  2229. // Marker for this pointer is already in the buffer.
  2230. if ( pStgmed->pUnkForRelease )
  2231. pBuffer = WdtpInterfacePointer_UserMarshal( ((USER_MARSHAL_CB *)pFlags),
  2232. *pFlags,
  2233. pBuffer,
  2234. pStgmed->pUnkForRelease,
  2235. IID_IUnknown );
  2236. return( pBuffer );
  2237. }
  2238. //+-------------------------------------------------------------------------
  2239. //
  2240. // Function: STGMEDIUM_UserUnmarshal
  2241. //
  2242. // Synopsis: Unmarshals a stgmedium object for RPC.
  2243. //
  2244. // history: May-95 Ryszardk Created.
  2245. //
  2246. //--------------------------------------------------------------------------
  2247. unsigned char __RPC_FAR * __RPC_USER
  2248. STGMEDIUM_UserUnmarshal(
  2249. unsigned long * pFlags,
  2250. unsigned char * pBuffer,
  2251. STGMEDIUM * pStgmed )
  2252. {
  2253. unsigned long fUnkForRelease;
  2254. unsigned long Handle = 0;
  2255. // if pointer, switch, union arm.
  2256. ALIGN( pBuffer, 3 );
  2257. // pUnkForRelease pointer marker.
  2258. fUnkForRelease = *( PULONG_LV_CAST pBuffer)++;
  2259. pStgmed->tymed = *( PULONG_LV_CAST pBuffer)++;
  2260. UserNdrDebugOut((UNDR_FORCE, "--STGMEDIUM_UserUnmarshal: %s\n", WdtpGetStgmedName(pStgmed) ));
  2261. if ( pStgmed->tymed != TYMED_NULL )
  2262. {
  2263. // handle or interface pointer (marker) from the buffer
  2264. Handle = *( PULONG_LV_CAST pBuffer)++;
  2265. }
  2266. // First pointee
  2267. // Union arm pointee.
  2268. // We need to unmarshal only if the handle/pointer field was not NULL.
  2269. if ( Handle )
  2270. {
  2271. switch( pStgmed->tymed )
  2272. {
  2273. case TYMED_NULL:
  2274. break;
  2275. case TYMED_MFPICT:
  2276. pBuffer = HMETAFILEPICT_UserUnmarshal( pFlags,
  2277. pBuffer,
  2278. &pStgmed->hMetaFilePict );
  2279. break;
  2280. case TYMED_ENHMF:
  2281. pBuffer = HENHMETAFILE_UserUnmarshal( pFlags,
  2282. pBuffer,
  2283. &pStgmed->hEnhMetaFile );
  2284. break;
  2285. case TYMED_GDI:
  2286. {
  2287. // A GDI object is not necesarrily a BITMAP. Therefore, we handle
  2288. // those types we know about based on the object type, and reject
  2289. // those which we do not support.
  2290. DWORD GdiObjectType = *( PULONG_LV_CAST pBuffer)++;
  2291. switch( GdiObjectType )
  2292. {
  2293. case OBJ_BITMAP:
  2294. pBuffer = HBITMAP_UserUnmarshal( pFlags,
  2295. pBuffer,
  2296. &pStgmed->hBitmap );
  2297. break;
  2298. case OBJ_PAL:
  2299. pBuffer = HPALETTE_UserUnmarshal( pFlags,
  2300. pBuffer,
  2301. (HPALETTE *) & pStgmed->hBitmap );
  2302. break;
  2303. default:
  2304. RpcRaiseException(DV_E_TYMED);
  2305. }
  2306. }
  2307. break;
  2308. case TYMED_HGLOBAL:
  2309. // reallocation is forbidden for [in-out] hglobal in STGMEDIUM.
  2310. pBuffer = WdtpGlobalUnmarshal( pFlags,
  2311. pBuffer,
  2312. & pStgmed->hGlobal,
  2313. FALSE ); // realloc flag
  2314. break;
  2315. case TYMED_FILE:
  2316. {
  2317. // We marshal it as a [string].
  2318. ulong Count = *( PULONG_LV_CAST pBuffer)++;
  2319. pBuffer += 8;
  2320. if ( ! pStgmed->lpszFileName )
  2321. pStgmed->lpszFileName = (LPOLESTR)
  2322. WdtpAllocate( pFlags,
  2323. Count * sizeof(wchar_t) );
  2324. memcpy( pStgmed->lpszFileName, pBuffer, Count * sizeof(wchar_t) );
  2325. pBuffer += Count * sizeof(wchar_t);
  2326. }
  2327. break;
  2328. case TYMED_ISTREAM:
  2329. case TYMED_ISTORAGE:
  2330. // Non null pointer, retrieve the interface pointer
  2331. pBuffer = WdtpInterfacePointer_UserUnmarshal(
  2332. (USER_MARSHAL_CB *)pFlags,
  2333. pBuffer,
  2334. (IUnknown **) &pStgmed->pstm,
  2335. ((pStgmed->tymed == TYMED_ISTREAM)
  2336. ? IID_IStream
  2337. : IID_IStorage));
  2338. break;
  2339. default:
  2340. break;
  2341. }
  2342. }
  2343. else
  2344. {
  2345. // New handle/pointer field is null, so release the previous one
  2346. // if it wasn't null.
  2347. if ( pStgmed->hGlobal )
  2348. {
  2349. // This should never happen for GetDataHere.
  2350. // Note, that we release the handle field, not the stgmedium itself.
  2351. // Accordingly, we don't follow punkForRelease.
  2352. UserNdrDebugOut((UNDR_FORCE, "--STGMEDIUM_UserUnmarshal: %s: NULL in, freeing old one\n", WdtpGetStgmedName(pStgmed)));
  2353. STGMEDIUM TmpStg = *pStgmed;
  2354. TmpStg.pUnkForRelease = NULL;
  2355. if ( pStgmed->tymed == TYMED_HGLOBAL )
  2356. {
  2357. // Cannot reallocate.
  2358. RpcRaiseException(DV_E_TYMED);
  2359. }
  2360. else
  2361. {
  2362. ReleaseStgMedium( &TmpStg );
  2363. }
  2364. }
  2365. pStgmed->hGlobal = 0;
  2366. }
  2367. if ( fUnkForRelease )
  2368. {
  2369. // There is an interface pointer on the wire.
  2370. pBuffer = WdtpInterfacePointer_UserUnmarshal( (USER_MARSHAL_CB *)pFlags,
  2371. pBuffer,
  2372. &pStgmed->pUnkForRelease,
  2373. IID_IUnknown );
  2374. }
  2375. if ( pStgmed->pUnkForRelease )
  2376. {
  2377. // Replace the app's punkForRelease with our custom release
  2378. // handler for special situations.
  2379. // The special situation is when a handle is remoted with data
  2380. // and so we have to clean up a side effect of having a data copy
  2381. // around. UserFree does it properly but we need that for the callee.
  2382. // When the callee releases a stgmed, it would invoke
  2383. // ReleaseStgMedium and this API doesn't do anything for handles
  2384. // when the punkForRelease is not NULL.
  2385. ULONG fHandleWithData = 0;
  2386. ULONG fTopLevelOnly = 0;
  2387. switch ( pStgmed->tymed )
  2388. {
  2389. case TYMED_HGLOBAL:
  2390. fHandleWithData = HGLOBAL_DATA_PASSING( *pFlags );
  2391. break;
  2392. case TYMED_ENHMF:
  2393. case TYMED_GDI:
  2394. fHandleWithData = GDI_DATA_PASSING( *pFlags );
  2395. break;
  2396. case TYMED_MFPICT:
  2397. fHandleWithData = HGLOBAL_DATA_PASSING( *pFlags );
  2398. fTopLevelOnly = fHandleWithData &&
  2399. ! GDI_DATA_PASSING( *pFlags );
  2400. break;
  2401. default:
  2402. break;
  2403. }
  2404. if ( fHandleWithData )
  2405. {
  2406. IUnknown *
  2407. punkTmp = (IUnknown *) new CPunkForRelease( pStgmed,
  2408. fTopLevelOnly );
  2409. if (!punkTmp)
  2410. {
  2411. RpcRaiseException(E_OUTOFMEMORY);
  2412. }
  2413. pStgmed->pUnkForRelease = punkTmp;
  2414. }
  2415. }
  2416. return( pBuffer );
  2417. }
  2418. //+-------------------------------------------------------------------------
  2419. //
  2420. // Function: STGMEDIUM_UserFree
  2421. //
  2422. // Synopsis: Frees a stgmedium object for RPC.
  2423. //
  2424. // history: May-95 Ryszardk Created.
  2425. //
  2426. // Note: This routine is called from the freeing walk at server
  2427. // or from the SetData *proxy*, when ownership has been passed.
  2428. //
  2429. //--------------------------------------------------------------------------
  2430. EXTERN_C
  2431. void NukeHandleAndReleasePunk(
  2432. STGMEDIUM * pStgmed )
  2433. {
  2434. pStgmed->hGlobal = NULL;
  2435. pStgmed->tymed = TYMED_NULL;
  2436. if (pStgmed->pUnkForRelease)
  2437. {
  2438. pStgmed->pUnkForRelease->Release();
  2439. pStgmed->pUnkForRelease = 0;
  2440. }
  2441. }
  2442. void __RPC_USER
  2443. STGMEDIUM_UserFree(
  2444. unsigned long * pFlags,
  2445. STGMEDIUM * pStgmed )
  2446. {
  2447. UserNdrDebugOut((UNDR_FORCE, "--STGMEDIUM_UserFree: %s\n", WdtpGetStgmedName(pStgmed)));
  2448. if( pStgmed )
  2449. {
  2450. switch ( pStgmed->tymed )
  2451. {
  2452. case TYMED_FILE:
  2453. WdtpFree( pFlags, pStgmed->lpszFileName);
  2454. NukeHandleAndReleasePunk( pStgmed );
  2455. break;
  2456. case TYMED_NULL:
  2457. case TYMED_ISTREAM:
  2458. case TYMED_ISTORAGE:
  2459. ReleaseStgMedium( pStgmed );
  2460. break;
  2461. case TYMED_GDI:
  2462. case TYMED_ENHMF:
  2463. if ( GDI_HANDLE_PASSING(*pFlags) )
  2464. {
  2465. NukeHandleAndReleasePunk( pStgmed );
  2466. }
  2467. else
  2468. {
  2469. // Handle w/data: there is a side effect to clean up.
  2470. // For punk !=0, this will go to our CPunk object.
  2471. ReleaseStgMedium( pStgmed );
  2472. }
  2473. break;
  2474. case TYMED_HGLOBAL:
  2475. if ( HGLOBAL_HANDLE_PASSING(*pFlags) )
  2476. {
  2477. NukeHandleAndReleasePunk( pStgmed );
  2478. }
  2479. else
  2480. {
  2481. // Handle w/data: there is a side effect to clean up.
  2482. // For punk ==0, this will just release the data.
  2483. // For punk !=0, this will go to our CPunk object,
  2484. // release the data, and then call the original punk.
  2485. ReleaseStgMedium( pStgmed );
  2486. }
  2487. break;
  2488. case TYMED_MFPICT:
  2489. if ( HGLOBAL_HANDLE_PASSING(*pFlags) )
  2490. {
  2491. NukeHandleAndReleasePunk( pStgmed );
  2492. }
  2493. else if ( GDI_HANDLE_PASSING(*pFlags) )
  2494. {
  2495. if ( pStgmed->hGlobal )
  2496. GlobalFree( pStgmed->hGlobal );
  2497. NukeHandleAndReleasePunk( pStgmed );
  2498. }
  2499. else
  2500. {
  2501. // Handle w/data: there is a side effect to clean up.
  2502. // For punk !=0, this will go to our CPunk object.
  2503. ReleaseStgMedium( pStgmed );
  2504. }
  2505. break;
  2506. default:
  2507. RpcRaiseException( E_INVALIDARG );
  2508. break;
  2509. }
  2510. }
  2511. }
  2512. //+-------------------------------------------------------------------------
  2513. //
  2514. // Function: FLAG_STGMEDIUM_UserSize
  2515. //
  2516. // Synopsis: Sizes a wrapper for stgmedium.
  2517. //
  2518. // history: May-95 Ryszardk Created.
  2519. //
  2520. //--------------------------------------------------------------------------
  2521. unsigned long __RPC_USER
  2522. FLAG_STGMEDIUM_UserSize(
  2523. unsigned long * pFlags,
  2524. unsigned long Offset,
  2525. FLAG_STGMEDIUM* pFlagStgmed )
  2526. {
  2527. if ( ! pFlagStgmed )
  2528. return Offset;
  2529. LENGTH_ALIGN( Offset, 3 );
  2530. Offset += sizeof(long);
  2531. Offset = STGMEDIUM_UserSize( pFlags, Offset, & pFlagStgmed->Stgmed );
  2532. return( Offset );
  2533. }
  2534. //+-------------------------------------------------------------------------
  2535. //
  2536. // Function: FLAG_STGMEDIUM_UserMarshal
  2537. //
  2538. // Synopsis: Marshals a wrapper for stgmedium. Used in SetData.
  2539. //
  2540. // history: May-95 Ryszardk Created.
  2541. //
  2542. //--------------------------------------------------------------------------
  2543. unsigned char __RPC_FAR * __RPC_USER
  2544. FLAG_STGMEDIUM_UserMarshal(
  2545. unsigned long * pFlags,
  2546. unsigned char * pBuffer,
  2547. FLAG_STGMEDIUM* pFlagStgmed )
  2548. {
  2549. if ( ! pFlagStgmed )
  2550. return pBuffer;
  2551. ALIGN( pBuffer, 3 );
  2552. // Flags: we need them when freeing in the client call_as routine
  2553. pFlagStgmed->ContextFlags = *pFlags;
  2554. *( PULONG_LV_CAST pBuffer)++ = *pFlags;
  2555. *( PULONG_LV_CAST pBuffer)++ = pFlagStgmed->fPassOwnership;
  2556. pBuffer = STGMEDIUM_UserMarshal( pFlags,
  2557. pBuffer,
  2558. & pFlagStgmed->Stgmed );
  2559. return( pBuffer );
  2560. }
  2561. //+-------------------------------------------------------------------------
  2562. //
  2563. // Function: FLAG_STGMEDIUM_UserUnmarshal
  2564. //
  2565. // Synopsis: Unmarshals a wrapper for stgmedium.
  2566. //
  2567. // history: May-95 Ryszardk Created.
  2568. //
  2569. //--------------------------------------------------------------------------
  2570. unsigned char __RPC_FAR * __RPC_USER
  2571. FLAG_STGMEDIUM_UserUnmarshal(
  2572. unsigned long * pFlags,
  2573. unsigned char * pBuffer,
  2574. FLAG_STGMEDIUM* pFlagStgmed )
  2575. {
  2576. ALIGN( pBuffer, 3 );
  2577. // Flags and buffer marker
  2578. pFlagStgmed->ContextFlags = *( PULONG_LV_CAST pBuffer)++;
  2579. // We need that in the Proxy, when we call the user free routine.
  2580. pFlagStgmed->fPassOwnership = *( PULONG_LV_CAST pBuffer)++;
  2581. pFlagStgmed->ContextFlags = *pFlags;
  2582. // We always unmarshal a FLAG_STGMEDIUM object.
  2583. // The engine will always free the FLAG_STGMEDIUM object later.
  2584. // Adjustments for passing the ownership are done within SetData_Stub.
  2585. pBuffer = STGMEDIUM_UserUnmarshal( pFlags,
  2586. pBuffer,
  2587. & pFlagStgmed->Stgmed );
  2588. return( pBuffer );
  2589. }
  2590. //+-------------------------------------------------------------------------
  2591. //
  2592. // Function: FLAG_STGMEDIUM_UserFree
  2593. //
  2594. // Synopsis: Freess a wrapper for stgmedium.
  2595. //
  2596. // history: May-95 Ryszardk Created.
  2597. //
  2598. //--------------------------------------------------------------------------
  2599. void __RPC_USER
  2600. FLAG_STGMEDIUM_UserFree(
  2601. unsigned long * pFlags,
  2602. FLAG_STGMEDIUM* pFlagsStgmed )
  2603. {
  2604. if ( ! pFlagsStgmed->fPassOwnership )
  2605. STGMEDIUM_UserFree( pFlags, & pFlagsStgmed->Stgmed );
  2606. // else the callee is supposed to release the stg medium.
  2607. }
  2608. #if (DBG==1)
  2609. //+-------------------------------------------------------------------------
  2610. //
  2611. // Function: WdtpGetStgmedName
  2612. //
  2613. // Synopsis: Debug support
  2614. //
  2615. // history: May-95 Ryszardk Created.
  2616. //
  2617. //--------------------------------------------------------------------------
  2618. char *
  2619. WdtpGetStgmedName( STGMEDIUM * pStgmed)
  2620. {
  2621. char * Name;
  2622. if ( pStgmed )
  2623. {
  2624. switch (pStgmed->tymed)
  2625. {
  2626. case TYMED_NULL:
  2627. Name = "TYMED_NULL";
  2628. break;
  2629. case TYMED_MFPICT:
  2630. Name = "TYMED_MFPICT";
  2631. break;
  2632. case TYMED_ENHMF:
  2633. Name = "TYMED_ENHMF";
  2634. break;
  2635. case TYMED_GDI:
  2636. Name = "TYMED_GDI";
  2637. break;
  2638. case TYMED_HGLOBAL:
  2639. Name = "TYMED_HGLOBAL";
  2640. break;
  2641. case TYMED_FILE:
  2642. Name = "TYMED_FILE";
  2643. break;
  2644. case TYMED_ISTREAM:
  2645. Name = "TYMED_ISTREAM";
  2646. break;
  2647. case TYMED_ISTORAGE:
  2648. Name = "TYMED_ISTORAGE";
  2649. break;
  2650. default:
  2651. Name = "TYMED invalid";
  2652. break;
  2653. }
  2654. return Name;
  2655. }
  2656. else
  2657. return "STGMED * is null";
  2658. }
  2659. #endif
  2660.