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.

585 lines
16 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 2000.
  5. //
  6. // File: bitmap.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 HBITMAP.
  12. //
  13. // Functions:
  14. // HBITMAP_UserSize
  15. // HBITMAP_UserMarshal
  16. // HBITMAP_UserUnmarshal
  17. // HBITMAP_UserFree
  18. // HBITMAP_UserSize64
  19. // HBITMAP_UserMarshal64
  20. // HBITMAP_UserUnmarshal64
  21. // HBITMAP_UserFree64
  22. //
  23. // History: 13-Dec-00 JohnDoty Migrated from transmit.cxx
  24. //
  25. //--------------------------------------------------------------------------
  26. #include "stdrpc.hxx"
  27. #pragma hdrstop
  28. #include <oleauto.h>
  29. #include <objbase.h>
  30. #include "transmit.hxx"
  31. #include <rpcwdt.h>
  32. #include <storext.h>
  33. #include "widewrap.h"
  34. #include <valid.h>
  35. #include <obase.h>
  36. #include <stream.hxx>
  37. #include "carefulreader.hxx"
  38. //+-------------------------------------------------------------------------
  39. //
  40. // Function: HBITMAP_UserSize
  41. //
  42. // Synopsis: Get the wire size the HBITMAP handle and data.
  43. //
  44. // Derivation: Union of a long and the bitmap handle and then struct.
  45. //
  46. // history: May-95 Ryszardk Created.
  47. //
  48. //--------------------------------------------------------------------------
  49. unsigned long __RPC_USER
  50. HBITMAP_UserSize (
  51. unsigned long * pFlags,
  52. unsigned long Offset,
  53. HBITMAP * pHBitmap )
  54. {
  55. if ( !pHBitmap )
  56. return Offset;
  57. BITMAP bm;
  58. HBITMAP hBitmap = *pHBitmap;
  59. LENGTH_ALIGN( Offset, 3 );
  60. // The encapsulated union.
  61. // Discriminant and then handle or pointer from the union arm.
  62. // Union discriminant is 4 bytes + handle is represented by a long.
  63. Offset += sizeof(long) + sizeof(long);
  64. if ( ! *pHBitmap )
  65. return Offset;
  66. if ( GDI_DATA_PASSING(*pFlags) )
  67. {
  68. // Pointee of the union arm for the remote case.
  69. // Conformat size, 6 fields, size, conf array.
  70. Offset += 4 + 4 * sizeof(LONG) + 2 * sizeof(WORD) + 4;
  71. // Get information about the bitmap
  72. #if defined(_CHICAGO_)
  73. if (FALSE == GetObjectA(hBitmap, sizeof(BITMAP), &bm))
  74. #else
  75. if (FALSE == GetObject(hBitmap, sizeof(BITMAP), &bm))
  76. #endif
  77. {
  78. RAISE_RPC_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
  79. }
  80. ULONG ulDataSize = bm.bmPlanes * bm.bmHeight * bm.bmWidthBytes;
  81. Offset += ulDataSize;
  82. }
  83. return( Offset ) ;
  84. }
  85. //+-------------------------------------------------------------------------
  86. //
  87. // Function: HBITMAP_UserMarshall
  88. //
  89. // Synopsis: Marshalls an HBITMAP object into the RPC buffer.
  90. //
  91. // history: May-95 Ryszardk Created.
  92. //
  93. //--------------------------------------------------------------------------
  94. unsigned char __RPC_FAR * __RPC_USER
  95. HBITMAP_UserMarshal (
  96. unsigned long * pFlags,
  97. unsigned char * pBuffer,
  98. HBITMAP * pHBitmap )
  99. {
  100. if ( !pHBitmap )
  101. return pBuffer;
  102. UserNdrDebugOut((UNDR_OUT4, "HBITMAP_UserMarshal\n"));
  103. ALIGN( pBuffer, 3 );
  104. // Discriminant of the encapsulated union and union arm.
  105. if ( GDI_DATA_PASSING(*pFlags) )
  106. {
  107. // userHBITMAP
  108. *( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER;
  109. *( PULONG_LV_CAST pBuffer)++ = PtrToUlong(*pHBitmap);
  110. if ( ! *pHBitmap )
  111. return pBuffer;
  112. // Get information about the bitmap
  113. BITMAP bm;
  114. HBITMAP hBitmap = *pHBitmap;
  115. #if defined(_CHICAGO_)
  116. if (FALSE == GetObjectA(hBitmap, sizeof(BITMAP), &bm))
  117. #else
  118. if (FALSE == GetObject(hBitmap, sizeof(BITMAP), &bm))
  119. #endif
  120. {
  121. RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
  122. }
  123. DWORD dwCount = bm.bmPlanes * bm.bmHeight * bm.bmWidthBytes;
  124. *( PULONG_LV_CAST pBuffer)++ = dwCount;
  125. // Get the bm structure fields.
  126. ulong ulBmSize = 4 * sizeof(LONG) + 2 * sizeof( WORD );
  127. memcpy( pBuffer, (void *) &bm, ulBmSize );
  128. pBuffer += ulBmSize;
  129. // Get the raw bits.
  130. if (0 == GetBitmapBits( hBitmap, dwCount, pBuffer ) )
  131. {
  132. RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
  133. }
  134. pBuffer += dwCount;
  135. }
  136. else
  137. {
  138. // Sending a handle.
  139. *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE_MARKER;
  140. *( PULONG_LV_CAST pBuffer)++ = PtrToUlong(*(HANDLE *)pHBitmap);
  141. }
  142. return( pBuffer );
  143. }
  144. //+-------------------------------------------------------------------------
  145. //
  146. // Function: HBITMAP_UserUnmarshallWorker
  147. //
  148. // Synopsis: Unmarshalls an HBITMAP object from the RPC buffer.
  149. //
  150. // history: Aug-99 JohnStra Created.
  151. //
  152. //--------------------------------------------------------------------------
  153. unsigned char __RPC_FAR * __RPC_USER
  154. HBITMAP_UserUnmarshalWorker (
  155. unsigned long * pFlags,
  156. unsigned char * pBuffer,
  157. HBITMAP * pHBitmap,
  158. ULONG_PTR BufferSize )
  159. {
  160. HBITMAP hBitmap;
  161. // Align the buffer and save the fixup size.
  162. UCHAR* pBufferStart = pBuffer;
  163. ALIGN( pBuffer, 3 );
  164. ULONG_PTR cbFixup = (ULONG_PTR)(pBuffer - pBufferStart);
  165. // Check for EOB before accessing discriminant and handle.
  166. CHECK_BUFFER_SIZE( BufferSize, cbFixup + (2 * sizeof( ULONG )) );
  167. // Get Discriminant and handle. Caller checked for EOB.
  168. unsigned long UnionDisc = *( PULONG_LV_CAST pBuffer)++;
  169. hBitmap = (HBITMAP)LongToHandle( *( PLONG_LV_CAST pBuffer)++ );
  170. if ( IS_DATA_MARKER( UnionDisc) )
  171. {
  172. if ( hBitmap )
  173. {
  174. ulong ulBmSize = 4 * sizeof(LONG) + 2 * sizeof( WORD );
  175. // Check for EOB before accessing metadata.
  176. CHECK_BUFFER_SIZE(
  177. BufferSize,
  178. cbFixup + (3 * sizeof( ULONG )) + ulBmSize );
  179. DWORD dwCount = *( PULONG_LV_CAST pBuffer)++;
  180. BITMAP * pBm = (BITMAP *) pBuffer;
  181. // verify dwCount matches the bitmap.
  182. if ( dwCount != (DWORD) pBm->bmPlanes * pBm->bmHeight * pBm->bmWidthBytes )
  183. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  184. pBuffer += ulBmSize;
  185. // Check for EOB before accessing data.
  186. CHECK_BUFFER_SIZE(
  187. BufferSize,
  188. cbFixup + (3 * sizeof(ULONG)) + ulBmSize + dwCount);
  189. // Create a bitmap based on the BITMAP structure and the raw bits in
  190. // the transmission buffer
  191. hBitmap = CreateBitmap( pBm->bmWidth,
  192. pBm->bmHeight,
  193. pBm->bmPlanes,
  194. pBm->bmBitsPixel,
  195. pBuffer );
  196. pBuffer += dwCount;
  197. }
  198. }
  199. else if ( !IS_HANDLE_MARKER( UnionDisc ) )
  200. {
  201. RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
  202. }
  203. // A new bitmap handle is ready, destroy the old one, if needed.
  204. if ( *pHBitmap )
  205. DeleteObject( *pHBitmap );
  206. *pHBitmap = hBitmap;
  207. return( pBuffer );
  208. }
  209. //+-------------------------------------------------------------------------
  210. //
  211. // Function: HBITMAP_UserUnmarshall
  212. //
  213. // Synopsis: Unmarshalls an HBITMAP object from the RPC buffer.
  214. //
  215. // history: May-95 Ryszardk Created.
  216. // Aug-99 JohnStra Factored bulk of work into a worker
  217. // routine in order to add consistency
  218. // checks.
  219. //
  220. //--------------------------------------------------------------------------
  221. unsigned char __RPC_FAR * __RPC_USER
  222. HBITMAP_UserUnmarshal (
  223. unsigned long * pFlags,
  224. unsigned char * pBuffer,
  225. HBITMAP * pHBitmap )
  226. {
  227. UserNdrDebugOut((UNDR_OUT4, "HBITMAP_UserUnmarshal\n"));
  228. // Get the buffer size and ptr to buffer.
  229. CUserMarshalInfo MarshalInfo( pFlags, pBuffer );
  230. ULONG_PTR BufferSize = MarshalInfo.GetBufferSize();
  231. UCHAR* pBufferStart = MarshalInfo.GetBuffer();
  232. pBuffer = HBITMAP_UserUnmarshalWorker( pFlags,
  233. pBufferStart,
  234. pHBitmap,
  235. BufferSize );
  236. return( pBuffer );
  237. }
  238. //+-------------------------------------------------------------------------
  239. //
  240. // Function: HBITMAP_UserFree
  241. //
  242. // Synopsis: Free an HBITMAP.
  243. //
  244. // history: May-95 Ryszardk Created.
  245. //
  246. //--------------------------------------------------------------------------
  247. void __RPC_USER
  248. HBITMAP_UserFree(
  249. unsigned long * pFlags,
  250. HBITMAP * pHBitmap )
  251. {
  252. UserNdrDebugOut((UNDR_OUT4, "HBITMAP_UserFree\n"));
  253. if( pHBitmap && *pHBitmap )
  254. {
  255. if ( GDI_DATA_PASSING(*pFlags) )
  256. {
  257. DeleteObject( *pHBitmap );
  258. }
  259. }
  260. }
  261. #if defined(_WIN64)
  262. //+-------------------------------------------------------------------------
  263. //
  264. // Function: HBITMAP_UserSize64
  265. //
  266. // Synopsis: Get the wire size the HBITMAP handle and data.
  267. //
  268. // Derivation: Union of a long and the bitmap handle and then struct.
  269. //
  270. // history: Dec-00 JohnDoty Created from 32bit functions.
  271. //
  272. //--------------------------------------------------------------------------
  273. unsigned long __RPC_USER
  274. HBITMAP_UserSize64 (
  275. unsigned long * pFlags,
  276. unsigned long Offset,
  277. HBITMAP * pHBitmap )
  278. {
  279. if ( !pHBitmap )
  280. return Offset;
  281. BITMAP bm;
  282. HBITMAP hBitmap = *pHBitmap;
  283. LENGTH_ALIGN( Offset, 7 );
  284. // The encapsulated union.
  285. // (aligned on 8)
  286. // discriminant 4
  287. // (align on 8) 4
  288. // handle or ptr 8
  289. Offset += 16;
  290. if ( ! *pHBitmap )
  291. return Offset;
  292. if ( GDI_DATA_PASSING(*pFlags) )
  293. {
  294. // Pointee of the union arm for the remote case.
  295. // (aligned on 8)
  296. // conformance 8
  297. // 4xlong 16
  298. // 2xword 4
  299. // size 4
  300. // data ulDataSize;
  301. if (FALSE == GetObject(hBitmap, sizeof(BITMAP), &bm))
  302. RAISE_RPC_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
  303. ULONG ulDataSize = bm.bmPlanes * bm.bmHeight * bm.bmWidthBytes;
  304. Offset += 32 + ulDataSize;
  305. }
  306. return( Offset ) ;
  307. }
  308. //+-------------------------------------------------------------------------
  309. //
  310. // Function: HBITMAP_UserMarshal64
  311. //
  312. // Synopsis: Marshalls an HBITMAP object into the RPC buffer.
  313. //
  314. // history: Dec-00 JohnDoty Created from 32bit functions.
  315. //
  316. //--------------------------------------------------------------------------
  317. unsigned char __RPC_FAR * __RPC_USER
  318. HBITMAP_UserMarshal64 (
  319. unsigned long * pFlags,
  320. unsigned char * pBuffer,
  321. HBITMAP * pHBitmap )
  322. {
  323. if ( !pHBitmap )
  324. return pBuffer;
  325. UserNdrDebugOut((UNDR_OUT4, "HBITMAP_UserMarshal64\n"));
  326. ALIGN( pBuffer, 7 );
  327. // Discriminant of the encapsulated union and union arm.
  328. if ( GDI_DATA_PASSING(*pFlags) )
  329. {
  330. // userHBITMAP
  331. *( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER;
  332. ALIGN( pBuffer, 7 );
  333. *( PHYPER_LV_CAST pBuffer)++ = (hyper)(*pHBitmap);
  334. if ( ! *pHBitmap )
  335. return pBuffer;
  336. // Get information about the bitmap
  337. BITMAP bm;
  338. HBITMAP hBitmap = *pHBitmap;
  339. if (FALSE == GetObject(hBitmap, sizeof(BITMAP), &bm))
  340. RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
  341. ULONG ulCount = bm.bmPlanes * bm.bmHeight * bm.bmWidthBytes;
  342. // Conformance...
  343. *(PHYPER_LV_CAST pBuffer)++ = ulCount;
  344. // Get the bm structure fields.
  345. ulong ulBmSize = 4 * sizeof(LONG) + 2 * sizeof( WORD );
  346. memcpy( pBuffer, &bm, ulBmSize );
  347. pBuffer += ulBmSize;
  348. // Get the raw bits.
  349. *(PULONG_LV_CAST pBuffer)++ = ulCount;
  350. if (0 == GetBitmapBits( hBitmap, ulCount, pBuffer ) )
  351. RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
  352. pBuffer += ulCount;
  353. }
  354. else
  355. {
  356. // Sending a handle.
  357. *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE64_MARKER;
  358. ALIGN( pBuffer, 7 );
  359. *( PHYPER_LV_CAST pBuffer)++ = (hyper)(*(HANDLE *)pHBitmap);
  360. }
  361. return( pBuffer );
  362. }
  363. //+-------------------------------------------------------------------------
  364. //
  365. // Function: HBITMAP_UserUnmarshallWorker64
  366. //
  367. // Synopsis: Unmarshalls an HBITMAP object from the RPC buffer.
  368. //
  369. // history: Dec-00 JohnDoty Created from 32bit functions.
  370. //
  371. //--------------------------------------------------------------------------
  372. unsigned char __RPC_FAR * __RPC_USER
  373. HBITMAP_UserUnmarshalWorker64 (
  374. unsigned long * pFlags,
  375. unsigned char * pBuffer,
  376. HBITMAP * pHBitmap,
  377. ULONG_PTR BufferSize )
  378. {
  379. CarefulBufferReader stream(pBuffer, BufferSize);
  380. stream.Align(8);
  381. // Get Discriminant and handle.
  382. unsigned long UnionDisc = stream.ReadULONGNA();
  383. HBITMAP hBitmap = (HBITMAP)stream.ReadHYPER();
  384. if ( IS_DATA_MARKER( UnionDisc) )
  385. {
  386. if ( hBitmap )
  387. {
  388. DWORD dwCount = (DWORD)stream.ReadHYPERNA();
  389. // Check for EOB before accessing metadata.
  390. ulong ulBmSize = 4 * sizeof(LONG) + 2 * sizeof(WORD);
  391. stream.CheckSize(ulBmSize);
  392. BITMAP * pBm = (BITMAP *)stream.GetBuffer();
  393. // verify dwCount matches the bitmap.
  394. if ( dwCount != (DWORD) pBm->bmPlanes * pBm->bmHeight * pBm->bmWidthBytes )
  395. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  396. stream.Advance(ulBmSize);
  397. if (stream.ReadULONGNA() != dwCount)
  398. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  399. // Check for EOB before accessing data.
  400. stream.CheckSize(dwCount);
  401. // Create a bitmap based on the BITMAP structure and the raw bits in
  402. // the transmission buffer
  403. hBitmap = CreateBitmap( pBm->bmWidth,
  404. pBm->bmHeight,
  405. pBm->bmPlanes,
  406. pBm->bmBitsPixel,
  407. stream.GetBuffer() );
  408. if (hBitmap == NULL)
  409. RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
  410. stream.Advance(dwCount);
  411. }
  412. }
  413. else if ( !IS_HANDLE64_MARKER( UnionDisc ) )
  414. {
  415. RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
  416. }
  417. // A new bitmap handle is ready, destroy the old one, if needed.
  418. if ( *pHBitmap )
  419. DeleteObject( *pHBitmap );
  420. *pHBitmap = hBitmap;
  421. return( stream.GetBuffer() );
  422. }
  423. //+-------------------------------------------------------------------------
  424. //
  425. // Function: HBITMAP_UserUnmarshal64
  426. //
  427. // Synopsis: Unmarshalls an HBITMAP object from the RPC buffer.
  428. //
  429. // history: Dec-00 JohnDoty Created from 32bit functions.
  430. //
  431. //--------------------------------------------------------------------------
  432. unsigned char __RPC_FAR * __RPC_USER
  433. HBITMAP_UserUnmarshal64 (
  434. unsigned long * pFlags,
  435. unsigned char * pBuffer,
  436. HBITMAP * pHBitmap )
  437. {
  438. UserNdrDebugOut((UNDR_OUT4, "HBITMAP_UserUnmarshal\n"));
  439. // Get the buffer size and ptr to buffer.
  440. CUserMarshalInfo MarshalInfo( pFlags, pBuffer );
  441. ULONG_PTR BufferSize = MarshalInfo.GetBufferSize();
  442. UCHAR* pBufferStart = MarshalInfo.GetBuffer();
  443. pBuffer = HBITMAP_UserUnmarshalWorker64( pFlags,
  444. pBufferStart,
  445. pHBitmap,
  446. BufferSize );
  447. return( pBuffer );
  448. }
  449. //+-------------------------------------------------------------------------
  450. //
  451. // Function: HBITMAP_UserFree64
  452. //
  453. // Synopsis: Free an HBITMAP.
  454. //
  455. // history: Dec-00 JohnDoty Created from 32bit functions.
  456. //
  457. //--------------------------------------------------------------------------
  458. void __RPC_USER
  459. HBITMAP_UserFree64 (
  460. unsigned long * pFlags,
  461. HBITMAP * pHBitmap )
  462. {
  463. UserNdrDebugOut((UNDR_OUT4, "HBITMAP_UserFree\n"));
  464. if( pHBitmap && *pHBitmap )
  465. {
  466. if ( GDI_DATA_PASSING(*pFlags) )
  467. {
  468. DeleteObject( *pHBitmap );
  469. }
  470. }
  471. }
  472. #endif