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

1669 lines
48 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 2000.
  5. //
  6. // File: metafile.cxx
  7. //
  8. // Contents: Support for Windows/OLE data types for oleprx32.dll.
  9. // Used to be transmit_as routines, now user_marshal routines.
  10. //
  11. // This file contains support for HMETAFILEPICT, HENHMETAFILE, and
  12. // HMETAFILE.
  13. //
  14. // Functions:
  15. // HMETAFILEPICT_UserSize
  16. // HMETAFILEPICT_UserMarshal
  17. // HMETAFILEPICT_UserUnmarshal
  18. // HMETAFILEPICT_UserFree
  19. // HMETAFILEPICT_UserSize64
  20. // HMETAFILEPICT_UserMarshal64
  21. // HMETAFILEPICT_UserUnmarshal64
  22. // HMETAFILEPICT_UserFree64
  23. // HENHMETAFILE_UserSize
  24. // HENHMETAFILE_UserMarshal
  25. // HENHMETAFILE_UserUnmarshal
  26. // HENHMETAFILE_UserFree
  27. // HENHMETAFILE_UserSize64
  28. // HENHMETAFILE_UserMarshal64
  29. // HENHMETAFILE_UserUnmarshal64
  30. // HENHMETAFILE_UserFree64
  31. // HMETAFILE_UserSize
  32. // HMETAFILE_UserMarshal
  33. // HMETAFILE_UserUnmarshal
  34. // HMETAFILE_UserFree
  35. // HMETAFILE_UserSize64
  36. // HMETAFILE_UserMarshal64
  37. // HMETAFILE_UserUnmarshal64
  38. // HMETAFILE_UserFree64
  39. //
  40. // History: 13-Dec-00 JohnDoty Migrated from transmit.cxx
  41. //
  42. //--------------------------------------------------------------------------
  43. #include "stdrpc.hxx"
  44. #pragma hdrstop
  45. #include <oleauto.h>
  46. #include <objbase.h>
  47. #include "transmit.hxx"
  48. #include <rpcwdt.h>
  49. #include <storext.h>
  50. #include "widewrap.h"
  51. #include <valid.h>
  52. #include <obase.h>
  53. #include <stream.hxx>
  54. #include "carefulreader.hxx"
  55. // #########################################################################
  56. //
  57. // HMETAFILEPICT
  58. // See transmit.h for explanation of hglobal vs. gdi data/handle passing.
  59. //
  60. // #########################################################################
  61. //+-------------------------------------------------------------------------
  62. //
  63. // Function: HMETAFILEPICT_UserSize
  64. //
  65. // Synopsis: Get the wire size the HMETAFILEPICT handle and data.
  66. //
  67. // Derivation: Union of a long and the meta file pict handle.
  68. // Then struct with top layer (and a hmetafile handle).
  69. // The the representation of the metafile.
  70. //
  71. // history: May-95 Ryszardk Created.
  72. //
  73. //--------------------------------------------------------------------------
  74. unsigned long __RPC_USER
  75. HMETAFILEPICT_UserSize (
  76. unsigned long * pFlags,
  77. unsigned long Offset,
  78. HMETAFILEPICT * pHMetaFilePict )
  79. {
  80. if ( !pHMetaFilePict )
  81. return Offset;
  82. LENGTH_ALIGN( Offset, 3 );
  83. // Discriminant of the encapsulated union and the union arm.
  84. // Union discriminant is 4 bytes + handle is represented by a long.
  85. Offset += 8;
  86. if ( ! *pHMetaFilePict )
  87. return Offset;
  88. if ( HGLOBAL_HANDLE_PASSING(*pFlags) )
  89. {
  90. #if defined(_WIN64)
  91. //Win64, inproc, we need a bit more space for the handle.
  92. Offset -= 4; //Get rid of that bogus long...
  93. LENGTH_ALIGN( Offset, 7 ); //Make sure alignment is right...
  94. Offset += 8; //And add in the real size of the handle...
  95. #endif
  96. return Offset;
  97. }
  98. // Now, this is a two layer object with HGLOBAL on top.
  99. // Upper layer - hglobal part - needs to be sent as data.
  100. METAFILEPICT *
  101. pMFP = (METAFILEPICT*) GlobalLock( *(HANDLE *)pHMetaFilePict );
  102. if ( pMFP == NULL )
  103. RAISE_RPC_EXCEPTION( E_OUTOFMEMORY );
  104. // Upper layer: 3 long fields + ptr marker + enc. union
  105. Offset += 4 * sizeof(long) + sizeof(userHMETAFILE);
  106. // The lower part is a metafile handle.
  107. if ( GDI_DATA_PASSING( *pFlags) )
  108. {
  109. ulong ulDataSize = GetMetaFileBitsEx( pMFP->hMF, 0 , NULL );
  110. Offset += 12 + ulDataSize;
  111. }
  112. GlobalUnlock( *(HANDLE *)pHMetaFilePict );
  113. return( Offset ) ;
  114. }
  115. //+-------------------------------------------------------------------------
  116. //
  117. // Function: HMETAFILEPICT_UserMarshal
  118. //
  119. // Synopsis: Marshalls an HMETAFILEPICT object into the RPC buffer.
  120. //
  121. // history: May-95 Ryszardk Created.
  122. //
  123. //--------------------------------------------------------------------------
  124. unsigned char __RPC_FAR * __RPC_USER
  125. HMETAFILEPICT_UserMarshal (
  126. unsigned long * pFlags,
  127. unsigned char * pBuffer,
  128. HMETAFILEPICT * pHMetaFilePict )
  129. {
  130. if ( !pHMetaFilePict )
  131. return pBuffer;
  132. UserNdrDebugOut((UNDR_OUT4, "HMETAFILEPICT_UserMarshal\n"));
  133. ALIGN( pBuffer, 3 );
  134. if ( HGLOBAL_HANDLE_PASSING(*pFlags) )
  135. {
  136. // Sending only the top level global handle.
  137. #if defined(_WIN64)
  138. *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE64_MARKER;
  139. ALIGN( pBuffer, 7 );
  140. *( PHYPER_LV_CAST pBuffer)++ = *(__int64 *)( pHMetaFilePict );
  141. #else
  142. *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE_MARKER;
  143. *( PLONG_LV_CAST pBuffer)++ = HandleToLong( *pHMetaFilePict );
  144. #endif
  145. return pBuffer;
  146. }
  147. // userHMETAFILEPICT
  148. // We need to send the data from the top (hglobal) layer.
  149. *( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER;
  150. *( PLONG_LV_CAST pBuffer)++ = HandleToLong( *pHMetaFilePict );
  151. if ( ! *pHMetaFilePict )
  152. return pBuffer;
  153. // remoteHMETAFILEPICT
  154. METAFILEPICT * pMFP = (METAFILEPICT*) GlobalLock(
  155. *(HANDLE *)pHMetaFilePict );
  156. if ( pMFP == NULL )
  157. RpcRaiseException( E_OUTOFMEMORY );
  158. *( PULONG_LV_CAST pBuffer)++ = pMFP->mm;
  159. *( PULONG_LV_CAST pBuffer)++ = pMFP->xExt;
  160. *( PULONG_LV_CAST pBuffer)++ = pMFP->yExt;
  161. *( PULONG_LV_CAST pBuffer)++ = USER_MARSHAL_MARKER;
  162. // See if the HMETAFILE needs to be sent as data, too.
  163. if ( GDI_DATA_PASSING(*pFlags) )
  164. {
  165. // userHMETAFILE
  166. *( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER;
  167. *( PLONG_LV_CAST pBuffer)++ = HandleToLong( pMFP->hMF );
  168. if ( pMFP->hMF )
  169. {
  170. ulong ulDataSize = GetMetaFileBitsEx( pMFP->hMF, 0 , NULL );
  171. // conformant size then the size field
  172. *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
  173. *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
  174. GetMetaFileBitsEx( pMFP->hMF, ulDataSize , pBuffer );
  175. pBuffer += ulDataSize;
  176. };
  177. }
  178. else
  179. {
  180. // Sending only an HMETAFILE handle.
  181. *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE_MARKER;
  182. *( PLONG_LV_CAST pBuffer)++ = HandleToLong( pMFP->hMF );
  183. }
  184. GlobalUnlock( *(HANDLE *)pHMetaFilePict );
  185. return( pBuffer );
  186. }
  187. //+-------------------------------------------------------------------------
  188. //
  189. // Function: HMETAFILEPICT_UserUnmarshalWorker
  190. //
  191. // Synopsis: Unmarshalls an HMETAFILEPICT object from the RPC buffer.
  192. //
  193. // history: Aug-99 JohnStra Created.
  194. //
  195. //--------------------------------------------------------------------------
  196. unsigned char __RPC_FAR * __RPC_USER
  197. HMETAFILEPICT_UserUnmarshalWorker (
  198. unsigned long * pFlags,
  199. unsigned char * pBuffer,
  200. HMETAFILEPICT * pHMetaFilePict,
  201. ULONG_PTR BufferSize )
  202. {
  203. unsigned long ulDataSize, fHandle;
  204. HMETAFILEPICT hMetaFilePict;
  205. // Align the buffer and save the fixup size.
  206. UCHAR* pBufferStart = pBuffer;
  207. ALIGN( pBuffer, 3 );
  208. ULONG_PTR cbFixup = (ULONG_PTR)(pBuffer - pBufferStart);
  209. // Check for EOB before accessing discriminant and handle.
  210. CHECK_BUFFER_SIZE( BufferSize, cbFixup + (2 * sizeof( ULONG )) );
  211. // Get the tag and handle from the buffer. Caller checked for EOB.
  212. unsigned long UnionDisc = *( PULONG_LV_CAST pBuffer)++;
  213. if (IS_HANDLE64_MARKER(UnionDisc))
  214. {
  215. ALIGN( pBuffer, 7 );
  216. hMetaFilePict = (HMETAFILEPICT)(*( PHYPER_LV_CAST pBuffer)++ );
  217. }
  218. else
  219. {
  220. hMetaFilePict = (HMETAFILEPICT)LongToHandle( *( PLONG_LV_CAST pBuffer)++ );
  221. }
  222. if ( IS_DATA_MARKER( UnionDisc ) )
  223. {
  224. if ( hMetaFilePict )
  225. {
  226. HGLOBAL hGlobal = GlobalAlloc( GMEM_MOVEABLE, sizeof(METAFILEPICT) );
  227. hMetaFilePict = (HMETAFILEPICT) hGlobal;
  228. if ( hMetaFilePict == NULL )
  229. RAISE_RPC_EXCEPTION( E_OUTOFMEMORY );
  230. METAFILEPICT * pMFP = (METAFILEPICT*) GlobalLock((HANDLE) hMetaFilePict );
  231. if ( pMFP == NULL )
  232. RAISE_RPC_EXCEPTION( E_OUTOFMEMORY );
  233. // Check for EOB before accessing metadata.
  234. CHECK_BUFFER_SIZE( BufferSize, cbFixup + (8 * sizeof( ULONG )) );
  235. pMFP->mm = *( PULONG_LV_CAST pBuffer)++;
  236. pMFP->xExt = *( PULONG_LV_CAST pBuffer)++;
  237. pMFP->yExt = *( PULONG_LV_CAST pBuffer)++;
  238. // validate marker.
  239. if ( *( PULONG_LV_CAST pBuffer)++ != USER_MARSHAL_MARKER )
  240. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  241. UnionDisc = *( PULONG_LV_CAST pBuffer)++;
  242. pMFP->hMF = (HMETAFILE) LongToHandle( *( PLONG_LV_CAST pBuffer)++ );
  243. ULONG ulExcept = 0;
  244. if ( pMFP->hMF )
  245. {
  246. if (IS_DATA_MARKER( UnionDisc ) )
  247. {
  248. // Check for EOB.
  249. if ( BufferSize < cbFixup + (10 * sizeof( ULONG )) )
  250. ulExcept = RPC_X_BAD_STUB_DATA;
  251. else
  252. {
  253. // Conformant size then the size field. These must be the same.
  254. ulong ulDataSize = *( PULONG_LV_CAST pBuffer)++;
  255. if ( ulDataSize == *( PULONG_LV_CAST pBuffer)++ )
  256. {
  257. // Check for EOB before accessing data.
  258. if ( BufferSize < cbFixup + (10 * sizeof(ULONG)) + ulDataSize )
  259. ulExcept = RPC_X_BAD_STUB_DATA;
  260. else
  261. {
  262. pMFP->hMF = SetMetaFileBitsEx( ulDataSize, (uchar*)pBuffer );
  263. pBuffer += ulDataSize;
  264. }
  265. }
  266. else
  267. ulExcept = RPC_X_BAD_STUB_DATA;
  268. }
  269. }
  270. else if ( !IS_HANDLE_MARKER( UnionDisc ) )
  271. {
  272. ulExcept = RPC_S_INVALID_TAG;
  273. }
  274. }
  275. GlobalUnlock( (HANDLE) hMetaFilePict );
  276. // wait until we've called GlobalUnlock before raising any exceptions.
  277. if ( ulExcept != 0 )
  278. {
  279. RAISE_RPC_EXCEPTION( ulExcept );
  280. }
  281. }
  282. }
  283. else if ( !(IS_HANDLE_MARKER( UnionDisc ) || IS_HANDLE64_MARKER( UnionDisc )) )
  284. {
  285. RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
  286. }
  287. // no reusage, just release the previous one.
  288. if ( *pHMetaFilePict )
  289. {
  290. // This may happen on the client only and doesn't depend on
  291. // how the other one was passed.
  292. METAFILEPICT *
  293. pMFP = (METAFILEPICT*) GlobalLock( *(HANDLE *)pHMetaFilePict );
  294. if ( pMFP == NULL )
  295. RAISE_RPC_EXCEPTION( E_OUTOFMEMORY );
  296. if ( pMFP->hMF )
  297. DeleteMetaFile( pMFP->hMF );
  298. GlobalUnlock( *pHMetaFilePict );
  299. GlobalFree( *pHMetaFilePict );
  300. }
  301. *pHMetaFilePict = hMetaFilePict;
  302. return( pBuffer );
  303. }
  304. //+-------------------------------------------------------------------------
  305. //
  306. // Function: HMETAFILEPICT_UserUnmarshal
  307. //
  308. // Synopsis: Unmarshalls an HMETAFILEPICT object from the RPC buffer.
  309. //
  310. // history: May-95 Ryszardk Created.
  311. // Aug-99 JohnStra Factored out bulk of work into a
  312. // worker routine in order to add
  313. // consistency checks.
  314. //
  315. //--------------------------------------------------------------------------
  316. unsigned char __RPC_FAR * __RPC_USER
  317. HMETAFILEPICT_UserUnmarshal (
  318. unsigned long * pFlags,
  319. unsigned char * pBuffer,
  320. HMETAFILEPICT * pHMetaFilePict )
  321. {
  322. UserNdrDebugOut((UNDR_OUT4, "HMETAFILEPICT_UserUnmarshal\n"));
  323. // Get the buffer size.
  324. CUserMarshalInfo MarshalInfo( pFlags, pBuffer );
  325. ULONG_PTR BufferSize = MarshalInfo.GetBufferSize();
  326. UCHAR* pBufferStart = MarshalInfo.GetBuffer();
  327. pBuffer = HMETAFILEPICT_UserUnmarshalWorker( pFlags,
  328. pBufferStart,
  329. pHMetaFilePict,
  330. BufferSize );
  331. return( pBuffer );
  332. }
  333. //+-------------------------------------------------------------------------
  334. //
  335. // Function: HMETAFILEPICT_UserFree
  336. //
  337. // Synopsis: Free an HMETAFILEPICT.
  338. //
  339. // history: May-95 Ryszardk Created.
  340. //
  341. //--------------------------------------------------------------------------
  342. void __RPC_USER
  343. HMETAFILEPICT_UserFree(
  344. unsigned long * pFlags,
  345. HMETAFILEPICT * pHMetaFilePict )
  346. {
  347. UserNdrDebugOut((UNDR_FORCE, "HMETAFILEPICT_UserFree\n"));
  348. if( pHMetaFilePict && *pHMetaFilePict )
  349. {
  350. if ( HGLOBAL_HANDLE_PASSING(*pFlags) )
  351. return;
  352. // Need to free the upper hglobal part.
  353. METAFILEPICT *
  354. pMFP = (METAFILEPICT*) GlobalLock( *(HANDLE *)pHMetaFilePict );
  355. if ( pMFP == NULL )
  356. RAISE_RPC_EXCEPTION( E_OUTOFMEMORY );
  357. // See if we need to free the hglobal, too.
  358. if ( pMFP->hMF && HGLOBAL_DATA_PASSING(*pFlags) )
  359. DeleteMetaFile( pMFP->hMF );
  360. GlobalUnlock( *pHMetaFilePict );
  361. GlobalFree( *pHMetaFilePict );
  362. }
  363. }
  364. //+-------------------------------------------------------------------------
  365. //
  366. // Function: HENHMETAFILE_UserSize
  367. //
  368. // Synopsis: Get the wire size the HENHMETAFILE handle and data.
  369. //
  370. // Derivation: Union of a long and the meta file handle and then struct.
  371. //
  372. // history: May-95 Ryszardk Created.
  373. //
  374. //--------------------------------------------------------------------------
  375. unsigned long __RPC_USER
  376. HENHMETAFILE_UserSize (
  377. unsigned long * pFlags,
  378. unsigned long Offset,
  379. HENHMETAFILE * pHEnhMetafile )
  380. {
  381. if ( !pHEnhMetafile )
  382. return Offset;
  383. LENGTH_ALIGN( Offset, 3 );
  384. // The encapsulated union.
  385. // Discriminant and then handle or pointer from the union arm.
  386. // Union discriminant is 4 bytes + handle is represented by a long.
  387. Offset += sizeof(long) + sizeof(long);
  388. if ( ! *pHEnhMetafile )
  389. return Offset;
  390. if ( GDI_DATA_PASSING(*pFlags) )
  391. {
  392. // Pointee of the union arm for the remote case.
  393. // Byte blob : conformant size, size field, data
  394. Offset += 2 * sizeof(long);
  395. ulong ulDataSize = GetEnhMetaFileBits( *pHEnhMetafile, 0, NULL );
  396. Offset += ulDataSize;
  397. }
  398. return( Offset );
  399. }
  400. //+-------------------------------------------------------------------------
  401. //
  402. // Function: HENHMETAFILE_UserMarshall
  403. //
  404. // Synopsis: Marshalls an HENHMETAFILE object into the RPC buffer.
  405. //
  406. // history: May-95 Ryszardk Created.
  407. //
  408. //--------------------------------------------------------------------------
  409. unsigned char __RPC_FAR * __RPC_USER
  410. HENHMETAFILE_UserMarshal (
  411. unsigned long * pFlags,
  412. unsigned char * pBuffer,
  413. HENHMETAFILE * pHEnhMetafile )
  414. {
  415. if ( !pHEnhMetafile )
  416. return pBuffer;
  417. UserNdrDebugOut((UNDR_OUT4, "HENHMETAFILE_UserMarshal\n"));
  418. ALIGN( pBuffer, 3 );
  419. // Discriminant of the encapsulated union and union arm.
  420. if ( GDI_DATA_PASSING(*pFlags) )
  421. {
  422. // userHENHMETAFILE
  423. *( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER;
  424. *( PLONG_LV_CAST pBuffer)++ = HandleToLong( *pHEnhMetafile );
  425. if ( !*pHEnhMetafile )
  426. return pBuffer;
  427. // BYTE_BLOB: conformant size, size field, data
  428. ulong ulDataSize = GetEnhMetaFileBits( *pHEnhMetafile, 0, NULL );
  429. *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
  430. *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
  431. if ( 0 == GetEnhMetaFileBits( *pHEnhMetafile,
  432. ulDataSize,
  433. (uchar*)pBuffer ) )
  434. RpcRaiseException( HRESULT_FROM_WIN32(GetLastError()));
  435. pBuffer += ulDataSize;
  436. }
  437. else
  438. {
  439. // Sending a handle.
  440. *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE_MARKER;
  441. *( PLONG_LV_CAST pBuffer)++ = HandleToLong(*(HANDLE *)pHEnhMetafile);
  442. }
  443. return( pBuffer );
  444. }
  445. //+-------------------------------------------------------------------------
  446. //
  447. // Function: HENHMETAFILE_UserUnmarshallWorker
  448. //
  449. // Synopsis: Unmarshalls an HENHMETAFILE object from the RPC buffer.
  450. //
  451. // history: Aug-99 JohnStra Created.
  452. //
  453. //--------------------------------------------------------------------------
  454. unsigned char __RPC_FAR * __RPC_USER
  455. HENHMETAFILE_UserUnmarshalWorker (
  456. unsigned long * pFlags,
  457. unsigned char * pBuffer,
  458. HENHMETAFILE * pHEnhMetafile,
  459. ULONG_PTR BufferSize )
  460. {
  461. HENHMETAFILE hEnhMetafile;
  462. // Align the buffer and save the fixup size.
  463. UCHAR* pBufferStart = pBuffer;
  464. ALIGN( pBuffer, 3 );
  465. ULONG_PTR cbFixup = (ULONG_PTR)(pBuffer - pBufferStart);
  466. // Check for EOB before accessing discriminant and handle.
  467. CHECK_BUFFER_SIZE( BufferSize, cbFixup + (2 * sizeof( ULONG )) );
  468. // Get the tag and handle. Caller checked for EOB.
  469. unsigned long UnionDisc = *( PULONG_LV_CAST pBuffer)++;
  470. hEnhMetafile = (HENHMETAFILE) LongToHandle( *( PLONG_LV_CAST pBuffer)++ );
  471. if ( IS_DATA_MARKER( UnionDisc) )
  472. {
  473. if ( hEnhMetafile )
  474. {
  475. // Check for EOB before accessing metadata.
  476. CHECK_BUFFER_SIZE( BufferSize, cbFixup + (4 * sizeof( ULONG )) );
  477. // Byte blob : conformant size, size field, data
  478. ulong ulDataSize = *( PULONG_LV_CAST pBuffer)++;
  479. if ( *( PULONG_LV_CAST pBuffer)++ != ulDataSize )
  480. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  481. // Check for EOB before accessing data.
  482. CHECK_BUFFER_SIZE( BufferSize, cbFixup + (4 * sizeof(ULONG)) + ulDataSize );
  483. hEnhMetafile = SetEnhMetaFileBits( ulDataSize, (uchar*) pBuffer );
  484. pBuffer += ulDataSize;
  485. }
  486. }
  487. else if ( !IS_HANDLE_MARKER( UnionDisc ) )
  488. {
  489. RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
  490. }
  491. // No reusage of the old object.
  492. if (*pHEnhMetafile)
  493. DeleteEnhMetaFile( *pHEnhMetafile );
  494. *pHEnhMetafile = hEnhMetafile;
  495. return( pBuffer );
  496. }
  497. //+-------------------------------------------------------------------------
  498. //
  499. // Function: HENHMETAFILE_UserUnmarshall
  500. //
  501. // Synopsis: Unmarshalls an HENHMETAFILE object from the RPC buffer.
  502. //
  503. // history: May-95 Ryszardk Created.
  504. // Aug-99 JohnStra Factored bulk of work out into a
  505. // worker routine in order to add
  506. // consistency checks.
  507. //
  508. //--------------------------------------------------------------------------
  509. unsigned char __RPC_FAR * __RPC_USER
  510. HENHMETAFILE_UserUnmarshal (
  511. unsigned long * pFlags,
  512. unsigned char * pBuffer,
  513. HENHMETAFILE * pHEnhMetafile )
  514. {
  515. UserNdrDebugOut((UNDR_OUT4, "HENHMETAFILE_UserUnmarshal\n"));
  516. // Get the buffer size and start of buffer.
  517. CUserMarshalInfo MarshalInfo( pFlags, pBuffer );
  518. ULONG_PTR BufferSize = MarshalInfo.GetBufferSize();
  519. UCHAR* pBufferStart = MarshalInfo.GetBuffer();
  520. pBuffer = HENHMETAFILE_UserUnmarshalWorker( pFlags,
  521. pBufferStart,
  522. pHEnhMetafile,
  523. BufferSize );
  524. return( pBuffer );
  525. }
  526. //+-------------------------------------------------------------------------
  527. //
  528. // Function: HENHMETAFILE_UserFree
  529. //
  530. // Synopsis: Free an HENHMETAFILE.
  531. //
  532. // history: May-95 Ryszardk Created.
  533. //
  534. //--------------------------------------------------------------------------
  535. void __RPC_USER
  536. HENHMETAFILE_UserFree(
  537. unsigned long * pFlags,
  538. HENHMETAFILE * pHEnhMetafile )
  539. {
  540. UserNdrDebugOut((UNDR_FORCE, "HENHMETAFILE_UserFree\n"));
  541. if( pHEnhMetafile && *pHEnhMetafile )
  542. {
  543. if ( GDI_DATA_PASSING(*pFlags) )
  544. {
  545. DeleteEnhMetaFile( *pHEnhMetafile );
  546. }
  547. }
  548. }
  549. // #########################################################################
  550. //
  551. // HMETAFILE
  552. // See transmit.h for explanation of gdi data/handle passing.
  553. //
  554. // #########################################################################
  555. //+-------------------------------------------------------------------------
  556. //
  557. // Function: HMETAFILE_UserSize
  558. //
  559. // Synopsis: Get the wire size the HMETAFILE handle and data.
  560. //
  561. // Derivation: Same wire layout as HENHMETAFILE
  562. //
  563. //--------------------------------------------------------------------------
  564. unsigned long __RPC_USER
  565. HMETAFILE_UserSize (
  566. unsigned long * pFlags,
  567. unsigned long Offset,
  568. HMETAFILE * pHMetafile )
  569. {
  570. if ( !pHMetafile )
  571. return Offset;
  572. LENGTH_ALIGN( Offset, 3 );
  573. // The encapsulated union.
  574. // Discriminant and then handle or pointer from the union arm.
  575. // Union discriminant is 4 bytes + handle is represented by a long.
  576. Offset += sizeof(long) + sizeof(long);
  577. if ( ! *pHMetafile )
  578. return Offset;
  579. if ( GDI_DATA_PASSING(*pFlags) )
  580. {
  581. // Pointee of the union arm for the remote case.
  582. // Byte blob : conformant size, size field, data
  583. Offset += 2 * sizeof(long);
  584. ulong ulDataSize = GetMetaFileBitsEx( *pHMetafile, 0, NULL );
  585. Offset += ulDataSize;
  586. }
  587. return( Offset );
  588. }
  589. //+-------------------------------------------------------------------------
  590. //
  591. // Function: HMETAFILE_UserMarshal
  592. //
  593. // Synopsis: Marshals an HMETAFILE object into the RPC buffer.
  594. //
  595. // Derivation: Same wire layout as HENHMETAFILE
  596. //
  597. //--------------------------------------------------------------------------
  598. unsigned char __RPC_FAR * __RPC_USER
  599. HMETAFILE_UserMarshal (
  600. unsigned long * pFlags,
  601. unsigned char * pBuffer,
  602. HMETAFILE * pHMetafile )
  603. {
  604. if ( !pHMetafile )
  605. return pBuffer;
  606. UserNdrDebugOut((UNDR_OUT4, "HMETAFILE_UserMarshal\n"));
  607. ALIGN( pBuffer, 3 );
  608. // Discriminant of the encapsulated union and union arm.
  609. if ( GDI_DATA_PASSING(*pFlags) )
  610. {
  611. // userHMETAFILE
  612. *( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER;
  613. *( PULONG_LV_CAST pBuffer)++ = PtrToUlong(*pHMetafile);
  614. if ( !*pHMetafile )
  615. return pBuffer;
  616. // BYTE_BLOB: conformant size, size field, data
  617. ulong ulDataSize = GetMetaFileBitsEx( *pHMetafile, 0, NULL );
  618. *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
  619. *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
  620. if ( 0 == GetMetaFileBitsEx( *pHMetafile,
  621. ulDataSize,
  622. (uchar*)pBuffer ) )
  623. RpcRaiseException( HRESULT_FROM_WIN32(GetLastError()));
  624. pBuffer += ulDataSize;
  625. }
  626. else
  627. {
  628. // Sending a handle.
  629. *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE_MARKER;
  630. *( PULONG_LV_CAST pBuffer)++ = PtrToUlong(*(HANDLE *)pHMetafile);
  631. }
  632. return( pBuffer );
  633. }
  634. //+-------------------------------------------------------------------------
  635. //
  636. // Function: HMETAFILE_UserUnmarshal
  637. //
  638. // Synopsis: Unmarshalls an HMETAFILE object from the RPC buffer.
  639. //
  640. // Derivation: Same wire layout as HENHMETAFILE
  641. //
  642. //--------------------------------------------------------------------------
  643. unsigned char __RPC_FAR * __RPC_USER
  644. HMETAFILE_UserUnmarshal (
  645. unsigned long * pFlags,
  646. unsigned char * pBuffer,
  647. HMETAFILE * pHMetafile )
  648. {
  649. HMETAFILE hMetafile;
  650. UserNdrDebugOut((UNDR_OUT4, "HMETAFILE_UserUnmarshal\n"));
  651. // Get the buffer size and the start of the buffer.
  652. CUserMarshalInfo MarshalInfo( pFlags, pBuffer );
  653. ULONG_PTR BufferSize = MarshalInfo.GetBufferSize();
  654. UCHAR* pBufferStart = MarshalInfo.GetBuffer();
  655. // Align the buffer and save the fixup size.
  656. ALIGN( pBuffer, 3 );
  657. ULONG_PTR cbFixup = (ULONG_PTR)(pBuffer - pBufferStart);
  658. // Check for EOB before accessing discriminant and handle.
  659. CHECK_BUFFER_SIZE( BufferSize, cbFixup + (2 * sizeof(ULONG)) );
  660. unsigned long UnionDisc = *( PULONG_LV_CAST pBuffer)++;
  661. hMetafile = (HMETAFILE) LongToHandle( *( PLONG_LV_CAST pBuffer)++ );
  662. if ( IS_DATA_MARKER( UnionDisc) )
  663. {
  664. if ( hMetafile )
  665. {
  666. // Check for EOB before accessing metadata.
  667. CHECK_BUFFER_SIZE( BufferSize, cbFixup + (4 * sizeof( ULONG )) );
  668. // Byte blob : conformant size, size field, data
  669. ulong ulDataSize = *( PULONG_LV_CAST pBuffer)++;
  670. if ( *( PULONG_LV_CAST pBuffer)++ != ulDataSize )
  671. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  672. // Check for EOB before accessing data.
  673. CHECK_BUFFER_SIZE( BufferSize,
  674. cbFixup + (4 * sizeof( ULONG )) + ulDataSize );
  675. hMetafile = SetMetaFileBitsEx( ulDataSize, (uchar*) pBuffer );
  676. pBuffer += ulDataSize;
  677. }
  678. }
  679. else if ( !IS_HANDLE_MARKER( UnionDisc ) )
  680. {
  681. RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
  682. }
  683. // No reusage of the old object.
  684. if (*pHMetafile)
  685. DeleteMetaFile( *pHMetafile );
  686. *pHMetafile = hMetafile;
  687. return( pBuffer );
  688. }
  689. //+-------------------------------------------------------------------------
  690. //
  691. // Function: HMETAFILE_UserFree
  692. //
  693. // Synopsis: Free an HMETAFILE.
  694. //
  695. //--------------------------------------------------------------------------
  696. void __RPC_USER
  697. HMETAFILE_UserFree(
  698. unsigned long * pFlags,
  699. HMETAFILE * pHMetafile )
  700. {
  701. UserNdrDebugOut((UNDR_FORCE, "HMETAFILE_UserFree\n"));
  702. if( pHMetafile && *pHMetafile )
  703. {
  704. if ( GDI_DATA_PASSING(*pFlags) )
  705. {
  706. DeleteMetaFile( *pHMetafile );
  707. }
  708. }
  709. }
  710. #if defined(_WIN64)
  711. //+-------------------------------------------------------------------------
  712. //
  713. // Function: HMETAFILEPICT_UserSize64
  714. //
  715. // Synopsis: Get the wire size the HMETAFILEPICT handle and data.
  716. //
  717. // Derivation: Union of a long and the meta file pict handle.
  718. // Then struct with top layer (and a hmetafile handle).
  719. // The the representation of the metafile.
  720. //
  721. // history: Dec-00 JohnDoty Created from 32bit functions.
  722. //
  723. //--------------------------------------------------------------------------
  724. unsigned long __RPC_USER
  725. HMETAFILEPICT_UserSize64 (
  726. unsigned long * pFlags,
  727. unsigned long Offset,
  728. HMETAFILEPICT * pHMetaFilePict )
  729. {
  730. if ( !pHMetaFilePict )
  731. return Offset;
  732. // Discriminant of the encapsulated union and the union arm.
  733. // Union discriminant is 4 bytes
  734. LENGTH_ALIGN( Offset, 7 );
  735. Offset += 4;
  736. LENGTH_ALIGN( Offset, 7 );
  737. // Rest of the upper layer:
  738. // (already aligned on 8)
  739. // pointer marker (or handle) 8
  740. Offset += 8;
  741. if ( HGLOBAL_HANDLE_PASSING(*pFlags) )
  742. {
  743. return Offset;
  744. }
  745. if ( ! *pHMetaFilePict )
  746. {
  747. return Offset;
  748. }
  749. // METAFILEPICT is a structure containing an HMETAFILE.
  750. // The structure is GlobalAlloc'd.
  751. METAFILEPICT *
  752. pMFP = (METAFILEPICT*) GlobalLock( *(HANDLE *)pHMetaFilePict );
  753. if ( pMFP == NULL )
  754. RAISE_RPC_EXCEPTION( E_OUTOFMEMORY );
  755. // 3xlong 12
  756. // (align on 8) 4
  757. // lower lev ptr. 8
  758. // Lower level:
  759. // (already aligned on 8)
  760. // discriminant 4
  761. // (align on 8) 4
  762. Offset += 32;
  763. // Lower layer: userHMETAFILE union...
  764. if ( GDI_DATA_PASSING( *pFlags) )
  765. {
  766. // pointer 8
  767. // BYTE_BLOB:
  768. // conformance 8
  769. // size 4
  770. // bytes ulDataSize
  771. ulong ulDataSize = GetMetaFileBitsEx( pMFP->hMF, 0 , NULL );
  772. if (0 == ulDataSize)
  773. RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
  774. Offset += 20 + ulDataSize;
  775. }
  776. else
  777. {
  778. // handle 8
  779. Offset += 8;
  780. }
  781. GlobalUnlock( *(HANDLE *)pHMetaFilePict );
  782. return( Offset ) ;
  783. }
  784. //+-------------------------------------------------------------------------
  785. //
  786. // Function: HMETAFILEPICT_UserMarshal64
  787. //
  788. // Synopsis: Marshalls an HMETAFILEPICT object into the RPC buffer.
  789. //
  790. // history: Dec-00 JohnDoty Created from 32bit functions.
  791. //
  792. //--------------------------------------------------------------------------
  793. unsigned char __RPC_FAR * __RPC_USER
  794. HMETAFILEPICT_UserMarshal64 (
  795. unsigned long * pFlags,
  796. unsigned char * pBuffer,
  797. HMETAFILEPICT * pHMetaFilePict )
  798. {
  799. if ( !pHMetaFilePict )
  800. return pBuffer;
  801. UserNdrDebugOut((UNDR_OUT4, "HMETAFILEPICT_UserMarshal64\n"));
  802. ALIGN( pBuffer, 7 );
  803. if ( HGLOBAL_HANDLE_PASSING(*pFlags) )
  804. {
  805. *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE64_MARKER;
  806. ALIGN( pBuffer, 7 );
  807. *( PHYPER_LV_CAST pBuffer)++ = *(__int64 *)( pHMetaFilePict );
  808. return pBuffer;
  809. }
  810. // userHMETAFILEPICT
  811. // We need to send the data from the top (hglobal) layer.
  812. *( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER;
  813. ALIGN( pBuffer, 7 );
  814. *( PHYPER_LV_CAST pBuffer)++ = *(__int64 *)( pHMetaFilePict );
  815. if ( ! *pHMetaFilePict )
  816. return pBuffer;
  817. // remoteHMETAFILEPICT
  818. METAFILEPICT * pMFP = (METAFILEPICT*)GlobalLock( *(HANDLE *)pHMetaFilePict );
  819. if ( pMFP == NULL )
  820. RpcRaiseException( E_OUTOFMEMORY );
  821. *( PULONG_LV_CAST pBuffer)++ = pMFP->mm;
  822. *( PULONG_LV_CAST pBuffer)++ = pMFP->xExt;
  823. *( PULONG_LV_CAST pBuffer)++ = pMFP->yExt;
  824. ALIGN( pBuffer, 7 );
  825. *( PHYPER_LV_CAST pBuffer)++ = USER_MARSHAL_MARKER;
  826. // See if the HMETAFILE needs to be sent as data, too.
  827. if ( GDI_DATA_PASSING(*pFlags) )
  828. {
  829. // userHMETAFILE
  830. *( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER;
  831. ALIGN( pBuffer, 7 );
  832. *( PHYPER_LV_CAST pBuffer)++ = (hyper)( pMFP->hMF );
  833. if ( pMFP->hMF )
  834. {
  835. ulong ulDataSize = GetMetaFileBitsEx( pMFP->hMF, 0 , NULL );
  836. if (0 == ulDataSize)
  837. {
  838. GlobalUnlock (*(HANDLE *)pHMetaFilePict);
  839. RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
  840. }
  841. // conformant size then the size field
  842. *( PHYPER_LV_CAST pBuffer)++ = ulDataSize;
  843. *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
  844. GetMetaFileBitsEx( pMFP->hMF, ulDataSize , pBuffer );
  845. pBuffer += ulDataSize;
  846. }
  847. }
  848. else
  849. {
  850. // Sending only an HMETAFILE handle.
  851. *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE64_MARKER;
  852. ALIGN( pBuffer, 7 );
  853. *( PHYPER_LV_CAST pBuffer)++ = (hyper)( pMFP->hMF );
  854. }
  855. GlobalUnlock( *(HANDLE *)pHMetaFilePict );
  856. return( pBuffer );
  857. }
  858. //+-------------------------------------------------------------------------
  859. //
  860. // Function: HMETAFILEPICT_UserUnmarshalWorker64
  861. //
  862. // Synopsis: Unmarshalls an HMETAFILEPICT object from the RPC buffer.
  863. //
  864. // history: Dec-00 JohnDoty Created from 32bit functions.
  865. //
  866. //--------------------------------------------------------------------------
  867. unsigned char __RPC_FAR * __RPC_USER
  868. HMETAFILEPICT_UserUnmarshalWorker64 (
  869. unsigned long * pFlags,
  870. unsigned char * pBuffer,
  871. HMETAFILEPICT * pHMetaFilePict,
  872. ULONG_PTR BufferSize )
  873. {
  874. CarefulBufferReader stream(pBuffer, BufferSize);
  875. unsigned long ulDataSize, fHandle;
  876. HMETAFILEPICT hMetaFilePict;
  877. stream.Align(8);
  878. unsigned long UnionDisc = stream.ReadULONGNA();
  879. hMetaFilePict = (HMETAFILEPICT)stream.ReadHYPER();
  880. if ( IS_DATA_MARKER( UnionDisc ) )
  881. {
  882. if ( hMetaFilePict )
  883. {
  884. HGLOBAL hGlobal = GlobalAlloc( GMEM_MOVEABLE, sizeof(METAFILEPICT) );
  885. hMetaFilePict = (HMETAFILEPICT) hGlobal;
  886. if ( hMetaFilePict == NULL )
  887. RAISE_RPC_EXCEPTION( E_OUTOFMEMORY );
  888. METAFILEPICT * pMFP = (METAFILEPICT*) GlobalLock((HANDLE) hMetaFilePict );
  889. if ( pMFP == NULL )
  890. RAISE_RPC_EXCEPTION( E_OUTOFMEMORY );
  891. RpcTryFinally
  892. {
  893. pMFP->mm = stream.ReadULONGNA();
  894. pMFP->xExt = stream.ReadULONGNA();
  895. pMFP->yExt = stream.ReadULONGNA();
  896. // validate marker.
  897. if ( stream.ReadHYPER() != USER_MARSHAL_MARKER )
  898. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  899. UnionDisc = stream.ReadULONGNA();
  900. pMFP->hMF = (HMETAFILE)stream.ReadHYPER();
  901. if ( pMFP->hMF )
  902. {
  903. if ( IS_DATA_MARKER( UnionDisc ) )
  904. {
  905. // Conformant size then the size field. These must be the same.
  906. ULONG ulDataSize = (ULONG)stream.ReadHYPERNA();
  907. if ( ulDataSize == stream.ReadULONGNA() )
  908. {
  909. stream.CheckSize(ulDataSize);
  910. pMFP->hMF = SetMetaFileBitsEx( ulDataSize,
  911. (uchar*)stream.GetBuffer() );
  912. if (NULL == pMFP->hMF)
  913. RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
  914. stream.Advance(ulDataSize);
  915. }
  916. else
  917. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  918. }
  919. else if ( !IS_HANDLE64_MARKER( UnionDisc ) )
  920. {
  921. RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
  922. }
  923. }
  924. }
  925. RpcFinally
  926. {
  927. GlobalUnlock( (HANDLE) hMetaFilePict );
  928. }
  929. RpcEndFinally;
  930. }
  931. }
  932. else if ( !IS_HANDLE64_MARKER( UnionDisc ) )
  933. {
  934. RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
  935. }
  936. // no reusage, just release the previous one.
  937. if ( *pHMetaFilePict )
  938. {
  939. // This may happen on the client only and doesn't depend on
  940. // how the other one was passed.
  941. METAFILEPICT *
  942. pMFP = (METAFILEPICT*) GlobalLock( *(HANDLE *)pHMetaFilePict );
  943. if ( pMFP == NULL )
  944. RAISE_RPC_EXCEPTION( E_OUTOFMEMORY );
  945. if ( pMFP->hMF )
  946. DeleteMetaFile( pMFP->hMF );
  947. GlobalUnlock( *pHMetaFilePict );
  948. GlobalFree( *pHMetaFilePict );
  949. }
  950. *pHMetaFilePict = hMetaFilePict;
  951. return( stream.GetBuffer() );
  952. }
  953. //+-------------------------------------------------------------------------
  954. //
  955. // Function: HMETAFILEPICT_UserUnmarshal64
  956. //
  957. // Synopsis: Unmarshalls an HMETAFILEPICT object from the RPC buffer.
  958. //
  959. // history: Dec-00 JohnDoty Created from 32bit functions.
  960. //
  961. //--------------------------------------------------------------------------
  962. unsigned char __RPC_FAR * __RPC_USER
  963. HMETAFILEPICT_UserUnmarshal64 (
  964. unsigned long * pFlags,
  965. unsigned char * pBuffer,
  966. HMETAFILEPICT * pHMetaFilePict )
  967. {
  968. UserNdrDebugOut((UNDR_OUT4, "HMETAFILEPICT_UserUnmarshal64\n"));
  969. // Get the buffer size.
  970. CUserMarshalInfo MarshalInfo( pFlags, pBuffer );
  971. ULONG_PTR BufferSize = MarshalInfo.GetBufferSize();
  972. UCHAR* pBufferStart = MarshalInfo.GetBuffer();
  973. pBuffer = HMETAFILEPICT_UserUnmarshalWorker64( pFlags,
  974. pBufferStart,
  975. pHMetaFilePict,
  976. BufferSize );
  977. return( pBuffer );
  978. }
  979. //+-------------------------------------------------------------------------
  980. //
  981. // Function: HMETAFILEPICT_UserFree64
  982. //
  983. // Synopsis: Free an HMETAFILEPICT.
  984. //
  985. // history: Dec-00 JohnDoty Created from 32bit functions.
  986. //
  987. //--------------------------------------------------------------------------
  988. void __RPC_USER
  989. HMETAFILEPICT_UserFree64 (
  990. unsigned long * pFlags,
  991. HMETAFILEPICT * pHMetaFilePict )
  992. {
  993. UserNdrDebugOut((UNDR_FORCE, "HMETAFILEPICT_UserFree64\n"));
  994. if( pHMetaFilePict && *pHMetaFilePict )
  995. {
  996. if ( HGLOBAL_HANDLE_PASSING(*pFlags) )
  997. return;
  998. // Need to free the upper hglobal part.
  999. METAFILEPICT *
  1000. pMFP = (METAFILEPICT*) GlobalLock( *(HANDLE *)pHMetaFilePict );
  1001. if ( pMFP == NULL )
  1002. RAISE_RPC_EXCEPTION( E_OUTOFMEMORY );
  1003. // See if we need to free the hglobal, too.
  1004. if ( pMFP->hMF && HGLOBAL_DATA_PASSING(*pFlags) )
  1005. DeleteMetaFile( pMFP->hMF );
  1006. GlobalUnlock( *pHMetaFilePict );
  1007. GlobalFree( *pHMetaFilePict );
  1008. }
  1009. }
  1010. //+-------------------------------------------------------------------------
  1011. //
  1012. // Function: HENHMETAFILE_UserSize64
  1013. //
  1014. // Synopsis: Get the wire size the HENHMETAFILE handle and data.
  1015. //
  1016. // Derivation: Union of a long and the meta file handle and then struct.
  1017. //
  1018. // history: Dec-00 JohnDoty Created from 32bit functions.
  1019. //
  1020. //--------------------------------------------------------------------------
  1021. unsigned long __RPC_USER
  1022. HENHMETAFILE_UserSize64 (
  1023. unsigned long * pFlags,
  1024. unsigned long Offset,
  1025. HENHMETAFILE * pHEnhMetafile )
  1026. {
  1027. if ( !pHEnhMetafile )
  1028. return Offset;
  1029. LENGTH_ALIGN( Offset, 7 );
  1030. // The encapsulated union.
  1031. // (aligned on 8)
  1032. // discriminant 4
  1033. // (align on 8) 4
  1034. // pointer or handle 8
  1035. Offset += 16;
  1036. if ( ! *pHEnhMetafile )
  1037. return Offset;
  1038. if ( GDI_DATA_PASSING(*pFlags) )
  1039. {
  1040. // BYTE_BLOB
  1041. // (aligned on 8)
  1042. // conformance 8
  1043. // size 4
  1044. // data ulDataSize
  1045. ulong ulDataSize = GetEnhMetaFileBits( *pHEnhMetafile, 0, NULL );
  1046. if (0 == ulDataSize)
  1047. RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
  1048. Offset += 12 + ulDataSize;
  1049. }
  1050. return( Offset );
  1051. }
  1052. //+-------------------------------------------------------------------------
  1053. //
  1054. // Function: HENHMETAFILE_UserMarshal64
  1055. //
  1056. // Synopsis: Marshalls an HENHMETAFILE object into the RPC buffer.
  1057. //
  1058. // history: Dec-00 JohnDoty Created from 32bit functions.
  1059. //
  1060. //--------------------------------------------------------------------------
  1061. unsigned char __RPC_FAR * __RPC_USER
  1062. HENHMETAFILE_UserMarshal64 (
  1063. unsigned long * pFlags,
  1064. unsigned char * pBuffer,
  1065. HENHMETAFILE * pHEnhMetafile )
  1066. {
  1067. if ( !pHEnhMetafile )
  1068. return pBuffer;
  1069. UserNdrDebugOut((UNDR_OUT4, "HENHMETAFILE_UserMarshal64\n"));
  1070. ALIGN( pBuffer, 7 );
  1071. // Discriminant of the encapsulated union and union arm.
  1072. if ( GDI_DATA_PASSING(*pFlags) )
  1073. {
  1074. // userHENHMETAFILE
  1075. *( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER;
  1076. ALIGN( pBuffer, 7 );
  1077. *( PHYPER_LV_CAST pBuffer)++ = (hyper)(*pHEnhMetafile);
  1078. if ( !*pHEnhMetafile )
  1079. return pBuffer;
  1080. // BYTE_BLOB: conformant size, size field, data
  1081. ulong ulDataSize = GetEnhMetaFileBits( *pHEnhMetafile, 0, NULL );
  1082. *( PHYPER_LV_CAST pBuffer)++ = ulDataSize;
  1083. *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
  1084. if ( 0 == GetEnhMetaFileBits( *pHEnhMetafile,
  1085. ulDataSize,
  1086. (uchar*)pBuffer ) )
  1087. RpcRaiseException( HRESULT_FROM_WIN32(GetLastError()));
  1088. pBuffer += ulDataSize;
  1089. }
  1090. else
  1091. {
  1092. // Sending a handle.
  1093. *(PULONG_LV_CAST pBuffer)++ = WDT_HANDLE64_MARKER;
  1094. ALIGN( pBuffer, 7 );
  1095. *(PHYPER_LV_CAST pBuffer)++ = (hyper)(*pHEnhMetafile);
  1096. }
  1097. return( pBuffer );
  1098. }
  1099. //+-------------------------------------------------------------------------
  1100. //
  1101. // Function: HENHMETAFILE_UserUnmarshallWorker64
  1102. //
  1103. // Synopsis: Unmarshalls an HENHMETAFILE object from the RPC buffer.
  1104. //
  1105. // history: Dec-00 JohnDoty Created from 32bit functions.
  1106. //
  1107. //--------------------------------------------------------------------------
  1108. unsigned char __RPC_FAR * __RPC_USER
  1109. HENHMETAFILE_UserUnmarshalWorker64 (
  1110. unsigned long * pFlags,
  1111. unsigned char * pBuffer,
  1112. HENHMETAFILE * pHEnhMetafile,
  1113. ULONG_PTR BufferSize )
  1114. {
  1115. CarefulBufferReader stream(pBuffer, BufferSize);
  1116. HENHMETAFILE hEnhMetafile;
  1117. stream.Align(8);
  1118. // Get the tag and handle. Caller checked for EOB.
  1119. unsigned long UnionDisc = stream.ReadULONGNA();
  1120. hEnhMetafile = (HENHMETAFILE)stream.ReadHYPER();
  1121. if ( IS_DATA_MARKER( UnionDisc) )
  1122. {
  1123. if ( hEnhMetafile )
  1124. {
  1125. // Byte blob : conformant size, size field, data
  1126. ulong ulDataSize = (ulong)stream.ReadHYPERNA();
  1127. if ( stream.ReadULONGNA() != ulDataSize )
  1128. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  1129. stream.CheckSize(ulDataSize);
  1130. hEnhMetafile = SetEnhMetaFileBits( ulDataSize, (uchar*)stream.GetBuffer() );
  1131. if (NULL == hEnhMetafile)
  1132. RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
  1133. stream.Advance(ulDataSize);
  1134. }
  1135. }
  1136. else if ( !IS_HANDLE64_MARKER( UnionDisc ) )
  1137. {
  1138. RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
  1139. }
  1140. // No reusage of the old object.
  1141. if (*pHEnhMetafile)
  1142. DeleteEnhMetaFile( *pHEnhMetafile );
  1143. *pHEnhMetafile = hEnhMetafile;
  1144. return( stream.GetBuffer() );
  1145. }
  1146. //+-------------------------------------------------------------------------
  1147. //
  1148. // Function: HENHMETAFILE_UserUnmarshal64
  1149. //
  1150. // Synopsis: Unmarshalls an HENHMETAFILE object from the RPC buffer.
  1151. //
  1152. // history: Dec-00 JohnDoty Created from 32bit functions.
  1153. //
  1154. //--------------------------------------------------------------------------
  1155. unsigned char __RPC_FAR * __RPC_USER
  1156. HENHMETAFILE_UserUnmarshal64 (
  1157. unsigned long * pFlags,
  1158. unsigned char * pBuffer,
  1159. HENHMETAFILE * pHEnhMetafile )
  1160. {
  1161. UserNdrDebugOut((UNDR_OUT4, "HENHMETAFILE_UserUnmarshal64\n"));
  1162. // Get the buffer size and start of buffer.
  1163. CUserMarshalInfo MarshalInfo( pFlags, pBuffer );
  1164. ULONG_PTR BufferSize = MarshalInfo.GetBufferSize();
  1165. UCHAR* pBufferStart = MarshalInfo.GetBuffer();
  1166. pBuffer = HENHMETAFILE_UserUnmarshalWorker64( pFlags,
  1167. pBufferStart,
  1168. pHEnhMetafile,
  1169. BufferSize );
  1170. return( pBuffer );
  1171. }
  1172. //+-------------------------------------------------------------------------
  1173. //
  1174. // Function: HENHMETAFILE_UserFree64
  1175. //
  1176. // Synopsis: Free an HENHMETAFILE.
  1177. //
  1178. // history: Dec-00 JohnDoty Created from 32bit functions.
  1179. //
  1180. //--------------------------------------------------------------------------
  1181. void __RPC_USER
  1182. HENHMETAFILE_UserFree64 (
  1183. unsigned long * pFlags,
  1184. HENHMETAFILE * pHEnhMetafile )
  1185. {
  1186. UserNdrDebugOut((UNDR_FORCE, "HENHMETAFILE_UserFree64\n"));
  1187. if( pHEnhMetafile && *pHEnhMetafile )
  1188. {
  1189. if ( GDI_DATA_PASSING(*pFlags) )
  1190. {
  1191. DeleteEnhMetaFile( *pHEnhMetafile );
  1192. }
  1193. }
  1194. }
  1195. //+-------------------------------------------------------------------------
  1196. //
  1197. // Function: HMETAFILE_UserSize64
  1198. //
  1199. // Synopsis: Get the wire size the HMETAFILE handle and data.
  1200. //
  1201. // Derivation: Same wire layout as HENHMETAFILE
  1202. //
  1203. //--------------------------------------------------------------------------
  1204. unsigned long __RPC_USER
  1205. HMETAFILE_UserSize64 (
  1206. unsigned long * pFlags,
  1207. unsigned long Offset,
  1208. HMETAFILE * pHMetafile )
  1209. {
  1210. if ( !pHMetafile )
  1211. return Offset;
  1212. LENGTH_ALIGN( Offset, 7 );
  1213. // The encapsulated union.
  1214. // (aligned on 8)
  1215. // discriminant 4
  1216. // (align on 8) 4
  1217. // ptr or handle 8
  1218. Offset += 16;
  1219. if ( ! *pHMetafile )
  1220. return Offset;
  1221. if ( GDI_DATA_PASSING(*pFlags) )
  1222. {
  1223. // Byte blob
  1224. // (aligned on 8)
  1225. // conformance 8
  1226. // size 4
  1227. // data ulDataSize
  1228. ulong ulDataSize = GetMetaFileBitsEx( *pHMetafile, 0, NULL );
  1229. if (0 == ulDataSize)
  1230. RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
  1231. Offset += 12 + ulDataSize;
  1232. }
  1233. return( Offset );
  1234. }
  1235. //+-------------------------------------------------------------------------
  1236. //
  1237. // Function: HMETAFILE_UserMarshal64
  1238. //
  1239. // Synopsis: Marshals an HMETAFILE object into the RPC buffer.
  1240. //
  1241. // Derivation: Same wire layout as HENHMETAFILE
  1242. //
  1243. //--------------------------------------------------------------------------
  1244. unsigned char __RPC_FAR * __RPC_USER
  1245. HMETAFILE_UserMarshal64 (
  1246. unsigned long * pFlags,
  1247. unsigned char * pBuffer,
  1248. HMETAFILE * pHMetafile )
  1249. {
  1250. if ( !pHMetafile )
  1251. return pBuffer;
  1252. UserNdrDebugOut((UNDR_OUT4, "HMETAFILE_UserMarshal64\n"));
  1253. ALIGN( pBuffer, 7 );
  1254. // Discriminant of the encapsulated union and union arm.
  1255. if ( GDI_DATA_PASSING(*pFlags) )
  1256. {
  1257. // userHMETAFILE
  1258. *(PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER;
  1259. ALIGN( pBuffer, 7 );
  1260. *(PHYPER_LV_CAST pBuffer)++ = (hyper)(*pHMetafile);
  1261. if ( !*pHMetafile )
  1262. return pBuffer;
  1263. // BYTE_BLOB: conformant size, size field, data
  1264. ulong ulDataSize = GetMetaFileBitsEx( *pHMetafile, 0, NULL );
  1265. *( PHYPER_LV_CAST pBuffer)++ = ulDataSize;
  1266. *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
  1267. if ( 0 == GetMetaFileBitsEx( *pHMetafile,
  1268. ulDataSize,
  1269. (uchar*)pBuffer ) )
  1270. RpcRaiseException( HRESULT_FROM_WIN32(GetLastError()));
  1271. pBuffer += ulDataSize;
  1272. }
  1273. else
  1274. {
  1275. // Sending a handle.
  1276. *(PULONG_LV_CAST pBuffer)++ = WDT_HANDLE64_MARKER;
  1277. ALIGN( pBuffer, 7 );
  1278. *(PHYPER_LV_CAST pBuffer)++ = (hyper)(*(HANDLE *)pHMetafile);
  1279. }
  1280. return( pBuffer );
  1281. }
  1282. //+-------------------------------------------------------------------------
  1283. //
  1284. // Function: HMETAFILE_UserUnmarshal64
  1285. //
  1286. // Synopsis: Unmarshalls an HMETAFILE object from the RPC buffer.
  1287. //
  1288. // Derivation: Same wire layout as HENHMETAFILE
  1289. //
  1290. //--------------------------------------------------------------------------
  1291. unsigned char __RPC_FAR * __RPC_USER
  1292. HMETAFILE_UserUnmarshal64 (
  1293. unsigned long * pFlags,
  1294. unsigned char * pBuffer,
  1295. HMETAFILE * pHMetafile )
  1296. {
  1297. HMETAFILE hMetafile;
  1298. UserNdrDebugOut((UNDR_OUT4, "HMETAFILE_UserUnmarshal64\n"));
  1299. // Get the buffer size and the start of the buffer.
  1300. CUserMarshalInfo MarshalInfo( pFlags, pBuffer );
  1301. CarefulBufferReader stream( pBuffer, MarshalInfo.GetBufferSize() );
  1302. // Align the buffer and save the fixup size.
  1303. stream.Align(8);
  1304. unsigned long UnionDisc = stream.ReadULONGNA();
  1305. hMetafile = (HMETAFILE)stream.ReadHYPER();
  1306. if ( IS_DATA_MARKER( UnionDisc) )
  1307. {
  1308. if ( hMetafile )
  1309. {
  1310. // Byte blob : conformant size, size field, data
  1311. ulong ulDataSize = (ulong)stream.ReadHYPERNA();
  1312. if ( stream.ReadULONGNA() != ulDataSize )
  1313. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  1314. stream.CheckSize(ulDataSize);
  1315. hMetafile = SetMetaFileBitsEx( ulDataSize, (uchar*) stream.GetBuffer() );
  1316. if (NULL == hMetafile)
  1317. RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
  1318. stream.Advance(ulDataSize);
  1319. }
  1320. }
  1321. else if ( !IS_HANDLE64_MARKER( UnionDisc ) )
  1322. {
  1323. RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
  1324. }
  1325. // No reusage of the old object.
  1326. if (*pHMetafile)
  1327. DeleteMetaFile( *pHMetafile );
  1328. *pHMetafile = hMetafile;
  1329. return( stream.GetBuffer() );
  1330. }
  1331. //+-------------------------------------------------------------------------
  1332. //
  1333. // Function: HMETAFILE_UserFree64
  1334. //
  1335. // Synopsis: Free an HMETAFILE.
  1336. //
  1337. //--------------------------------------------------------------------------
  1338. void __RPC_USER
  1339. HMETAFILE_UserFree64(
  1340. unsigned long * pFlags,
  1341. HMETAFILE * pHMetafile )
  1342. {
  1343. UserNdrDebugOut((UNDR_FORCE, "HMETAFILE_UserFree64\n"));
  1344. if( pHMetafile && *pHMetafile )
  1345. {
  1346. if ( GDI_DATA_PASSING(*pFlags) )
  1347. {
  1348. DeleteMetaFile( *pHMetafile );
  1349. }
  1350. }
  1351. }
  1352. #endif // win64