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.

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