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.

3150 lines
87 KiB

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