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.

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