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.

923 lines
24 KiB

  1. #include "private.h"
  2. #include "globals.h"
  3. #include "osver.h"
  4. #include "transmit.h"
  5. #include "cmydc.h"
  6. #define MAXFILEMAPSIZE 0x1000
  7. #define DATA_MARKER 0x0001
  8. #define HANDLE_MARKER 0x0002
  9. #define IS_DATA_MARKER( x) (x == DATA_MARKER)
  10. #define IS_HANDLE_MARKER( x) (x == HANDLE_MARKER)
  11. #define GDI_DATA_PASSING() (IsOnNT())
  12. #define POINTER_CAST(x) *(x **)&
  13. #define ICON_DATA_PASSING() (IsOnNT())
  14. //+---------------------------------------------------------------------------
  15. //
  16. // GetIconBitmaps
  17. //
  18. //----------------------------------------------------------------------------
  19. BOOL Cic_GetIconBitmaps(HICON hIcon, HBITMAP *phbmp, HBITMAP *phbmpMask, SIZE *psize)
  20. {
  21. CBitmapDC hdcSrc(TRUE);
  22. CBitmapDC hdcMask(TRUE);
  23. SIZE size;
  24. size = *psize;
  25. hdcSrc.SetDIB(size.cx, size.cy);
  26. hdcMask.SetBitmap(size.cx, size.cy, 1, 1);
  27. RECT rc = {0, 0, size.cx, size.cy};
  28. FillRect(hdcSrc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
  29. DrawIconEx(hdcSrc, 0, 0, hIcon, size.cx, size.cy, 0, NULL, DI_NORMAL);
  30. DrawIconEx(hdcMask, 0, 0, hIcon, size.cx, size.cy, 0, NULL, DI_MASK);
  31. *phbmp = hdcSrc.GetBitmapAndKeep();
  32. *phbmpMask = hdcMask.GetBitmapAndKeep();
  33. return TRUE;
  34. }
  35. //+---------------------------------------------------------------------------
  36. //
  37. // CreateDIB
  38. //
  39. //----------------------------------------------------------------------------
  40. HBITMAP CreateDIB(int cx, int cy, int nWidthByte, BYTE *pMyBits, ULONG_PTR nBitsSize)
  41. {
  42. CBitmapDC hdc(TRUE);
  43. HBITMAP hBmp;
  44. BITMAPINFO bi = {0};
  45. bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
  46. bi.bmiHeader.biWidth = cx;
  47. bi.bmiHeader.biHeight = cy;
  48. bi.bmiHeader.biPlanes = 1;
  49. bi.bmiHeader.biBitCount = 32;
  50. bi.bmiHeader.biCompression = BI_RGB;
  51. BYTE *pDibBits;
  52. hBmp = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&pDibBits, NULL, 0);
  53. if (hBmp)
  54. {
  55. int y;
  56. for (y = 0; y < cy; y++)
  57. {
  58. int nyDibBites = (cy - y - 1) * nWidthByte;
  59. int nyMyBites = y * nWidthByte;
  60. memcpy(&pDibBits[nyDibBites], &pMyBits[nyMyBites], nWidthByte);
  61. }
  62. }
  63. return hBmp;
  64. }
  65. //+---------------------------------------------------------------------------
  66. //
  67. // MARSHAL_HDR
  68. //
  69. //----------------------------------------------------------------------------
  70. template<class TYPE>
  71. struct MARSHAL_HDR
  72. {
  73. DWORD dwDataType;
  74. CAlignWinHandle<TYPE> h;
  75. };
  76. // #########################################################################
  77. //
  78. // HBITMAP
  79. // See transmit.h for explanation of gdi data/handle passing.
  80. //
  81. // #########################################################################
  82. struct BITMAP_WOW64
  83. {
  84. // Identical BITMAP structure.
  85. LONG bmType;
  86. LONG bmWidth;
  87. LONG bmHeight;
  88. LONG bmWidthBytes;
  89. WORD bmPlanes;
  90. WORD bmBitsPixel;
  91. CAlignPointer<LPVOID> bmBits;
  92. void operator = (BITMAP& a)
  93. {
  94. bmType = a.bmType;
  95. bmWidth = a.bmWidth;
  96. bmHeight = a.bmHeight;
  97. bmWidthBytes = a.bmWidthBytes;
  98. bmPlanes = a.bmPlanes;
  99. bmBitsPixel = a.bmBitsPixel;
  100. bmBits = a.bmBits;
  101. }
  102. void operator = (int a)
  103. {
  104. memset(this, a, sizeof(BITMAP_WOW64));
  105. }
  106. };
  107. struct MARSHAL_HBITMAP
  108. {
  109. MARSHAL_HDR<HBITMAP> hdr;
  110. MARSHAL_HDR<HBITMAP> hdr_2;
  111. struct
  112. {
  113. DWORD dwCount;
  114. BITMAP_WOW64 bm;
  115. } bitmap_1;
  116. struct
  117. {
  118. DWORD dwCount;
  119. BITMAP_WOW64 bm;
  120. } bitmap_2;
  121. BYTE bits[1];
  122. };
  123. //+-------------------------------------------------------------------------
  124. //
  125. // UserSize
  126. //
  127. //--------------------------------------------------------------------------
  128. ULONG Cic_HBITMAP_UserSize (HBITMAP *pHBitmap, HBITMAP *pHBitmap_2)
  129. {
  130. ULONG Offset = 0;
  131. if ( !pHBitmap )
  132. return 0;
  133. BITMAP bm, bm_2;
  134. HBITMAP hBitmap, hBitmap_2;
  135. hBitmap = *pHBitmap;
  136. hBitmap_2 = pHBitmap_2 ? *pHBitmap_2 : NULL;
  137. memset(&bm, 0, sizeof(BITMAP));
  138. memset(&bm_2, 0, sizeof(BITMAP));
  139. //
  140. // The encapsulated union.
  141. // Discriminant and then handle or pointer from the union arm.
  142. // Union discriminant is 4 bytes + handle is represented by a long.
  143. //
  144. if ( GDI_DATA_PASSING() )
  145. {
  146. Offset += sizeof(struct MARSHAL_HBITMAP);
  147. if (hBitmap)
  148. {
  149. // Get information about the bitmap
  150. if (!GetObject(hBitmap, sizeof(BITMAP), &bm))
  151. return 0;
  152. Offset += (bm.bmPlanes * bm.bmHeight * bm.bmWidthBytes);
  153. }
  154. if (hBitmap_2)
  155. {
  156. // Get information about the bitmap
  157. if (!GetObject(hBitmap_2, sizeof(BITMAP), &bm_2))
  158. return 0;
  159. Offset += (bm_2.bmPlanes * bm_2.bmHeight * bm_2.bmWidthBytes);
  160. }
  161. Offset = Align( Offset );
  162. }
  163. else
  164. {
  165. if (pHBitmap)
  166. Offset += Align( sizeof(struct MARSHAL_HDR<HBITMAP>) );
  167. if (pHBitmap_2)
  168. Offset += Align( sizeof(struct MARSHAL_HDR<HBITMAP>) );
  169. }
  170. return( Offset ) ;
  171. }
  172. //+-------------------------------------------------------------------------
  173. //
  174. // HBITMAP_UserMarshall
  175. //
  176. //--------------------------------------------------------------------------
  177. BYTE *Cic_HBITMAP_UserMarshal(BYTE *pBuffer, BYTE *pBufferEnd, HBITMAP *pHBitmap, HBITMAP *pHBitmap_2)
  178. {
  179. if ( !pHBitmap )
  180. return pBuffer;
  181. // Discriminant of the encapsulated union and union arm.
  182. struct MARSHAL_HBITMAP* pdata = (struct MARSHAL_HBITMAP*) pBuffer;
  183. if ( GDI_DATA_PASSING() )
  184. {
  185. if (!pHBitmap)
  186. {
  187. pdata->hdr.dwDataType = 0;
  188. pdata->hdr.h = NULL;
  189. }
  190. else
  191. {
  192. pdata->hdr.dwDataType = DATA_MARKER;
  193. pdata->hdr.h = *pHBitmap;
  194. }
  195. if (!pHBitmap_2)
  196. {
  197. pdata->hdr_2.dwDataType = 0;
  198. pdata->hdr_2.h = NULL;
  199. }
  200. else
  201. {
  202. pdata->hdr_2.dwDataType = DATA_MARKER;
  203. pdata->hdr_2.h = *pHBitmap_2;
  204. }
  205. //
  206. // Get information about the bitmap
  207. //
  208. BITMAP bm, bm_2;
  209. HBITMAP hBitmap = *pHBitmap;
  210. HBITMAP hBitmap_2 = pHBitmap_2 ? *pHBitmap_2 : NULL;
  211. //
  212. // Bitmap object 1
  213. //
  214. if (!hBitmap)
  215. {
  216. pdata->bitmap_1.bm = 0;
  217. pdata->bitmap_1.dwCount = 0;
  218. }
  219. else
  220. {
  221. if (!GetObject(hBitmap, sizeof(BITMAP), &bm))
  222. return pBuffer + Align( sizeof(struct MARSHAL_HDR<HBITMAP>) );
  223. pdata->bitmap_1.dwCount = bm.bmPlanes * bm.bmHeight * bm.bmWidthBytes;
  224. //
  225. // Get the bm structure fields.
  226. //
  227. pdata->bitmap_1.bm = bm;
  228. }
  229. //
  230. // Bitmap object 2
  231. //
  232. if (!hBitmap_2)
  233. {
  234. pdata->bitmap_2.bm = 0;
  235. pdata->bitmap_2.dwCount = 0;
  236. }
  237. else
  238. {
  239. if (!GetObject(hBitmap_2, sizeof(BITMAP), &bm_2))
  240. return pBuffer + Align( sizeof(struct MARSHAL_HDR<HBITMAP>) );
  241. pdata->bitmap_2.dwCount = bm_2.bmPlanes * bm_2.bmHeight * bm_2.bmWidthBytes;
  242. pdata->bitmap_2.bm = bm_2;
  243. }
  244. //
  245. // Get the raw bits.
  246. //
  247. if (hBitmap)
  248. {
  249. BYTE *pbTemp = pdata->bits;
  250. if (pbTemp + pdata->bitmap_1.dwCount > pBufferEnd)
  251. {
  252. Assert(0);
  253. pdata->bitmap_1.bm = 0;
  254. pdata->bitmap_1.dwCount = 0;
  255. }
  256. else
  257. {
  258. GetBitmapBits( hBitmap,
  259. pdata->bitmap_1.dwCount,
  260. pdata->bits );
  261. }
  262. }
  263. if (hBitmap_2)
  264. {
  265. BYTE *pbTemp = &pdata->bits[pdata->bitmap_1.dwCount];
  266. if (pbTemp + pdata->bitmap_2.dwCount > pBufferEnd)
  267. {
  268. Assert(0);
  269. pdata->bitmap_2.bm = 0;
  270. pdata->bitmap_2.dwCount = 0;
  271. }
  272. else
  273. {
  274. GetBitmapBits( hBitmap_2,
  275. pdata->bitmap_2.dwCount,
  276. &pdata->bits[pdata->bitmap_1.dwCount]);
  277. }
  278. }
  279. pBuffer += Align( sizeof(struct MARSHAL_HBITMAP) + pdata->bitmap_1.dwCount + pdata->bitmap_2.dwCount);
  280. }
  281. else
  282. {
  283. // Sending a handle.
  284. pdata->hdr.dwDataType = 0;
  285. pdata->hdr.h = NULL;
  286. pdata->hdr_2.dwDataType = 0;
  287. pdata->hdr_2.h = NULL;
  288. if (pHBitmap)
  289. {
  290. pdata->hdr.dwDataType = HANDLE_MARKER;
  291. pdata->hdr.h = *pHBitmap;
  292. pBuffer += Align( sizeof(struct MARSHAL_HDR<HBITMAP>) );
  293. }
  294. if (pHBitmap_2)
  295. {
  296. pdata->hdr_2.dwDataType = HANDLE_MARKER;
  297. pdata->hdr_2.h = *pHBitmap_2;
  298. pBuffer += Align( sizeof(struct MARSHAL_HDR<HBITMAP>) );
  299. }
  300. }
  301. return( pBuffer );
  302. }
  303. //+-------------------------------------------------------------------------
  304. //
  305. // HBITMAP_UserUnmarshallWorker
  306. //
  307. //--------------------------------------------------------------------------
  308. BYTE *Cic_HBITMAP_UserUnmarshal(BYTE *pBuffer, HBITMAP *pHBitmap, HBITMAP *pHBitmap_2)
  309. {
  310. HBITMAP hBitmap, hBitmap_2;
  311. // Get Discriminant and handle. Caller checked for EOB.
  312. struct MARSHAL_HBITMAP* pdata = (struct MARSHAL_HBITMAP*) pBuffer;
  313. DWORD UnionDisc = pdata->hdr.dwDataType;
  314. hBitmap = pdata->hdr.h;
  315. if (!hBitmap)
  316. {
  317. if (!pHBitmap_2)
  318. {
  319. *pHBitmap = NULL;
  320. return pBuffer;
  321. }
  322. UnionDisc = pdata->hdr_2.dwDataType;
  323. }
  324. hBitmap_2 = pdata->hdr_2.h ? (HBITMAP)pdata->hdr_2.h : NULL;
  325. if ( IS_DATA_MARKER( UnionDisc) )
  326. {
  327. ULONG_PTR dwCount = 0;
  328. ULONG_PTR dwCount_2 = 0;
  329. if ( hBitmap )
  330. {
  331. dwCount = pdata->bitmap_1.dwCount;
  332. // verify dwCount matches the bitmap.
  333. if ( dwCount != (DWORD) pdata->bitmap_1.bm.bmPlanes *
  334. pdata->bitmap_1.bm.bmHeight *
  335. pdata->bitmap_1.bm.bmWidthBytes )
  336. {
  337. Assert(0);
  338. return NULL;
  339. }
  340. // Create a bitmap based on the BITMAP structure and the raw bits in
  341. // the transmission buffer
  342. if (pdata->bitmap_1.bm.bmBitsPixel == 0x20)
  343. hBitmap = CreateDIB( pdata->bitmap_1.bm.bmWidth,
  344. pdata->bitmap_1.bm.bmHeight,
  345. pdata->bitmap_1.bm.bmWidthBytes,
  346. pdata->bits, dwCount);
  347. else
  348. hBitmap = CreateBitmap( pdata->bitmap_1.bm.bmWidth,
  349. pdata->bitmap_1.bm.bmHeight,
  350. pdata->bitmap_1.bm.bmPlanes,
  351. pdata->bitmap_1.bm.bmBitsPixel,
  352. pdata->bits);
  353. }
  354. if (hBitmap_2)
  355. {
  356. dwCount_2 = pdata->bitmap_2.dwCount;
  357. // verify dwCount_2 matches the bitmap.
  358. if ( dwCount_2 != (DWORD) pdata->bitmap_2.bm.bmPlanes *
  359. pdata->bitmap_2.bm.bmHeight *
  360. pdata->bitmap_2.bm.bmWidthBytes )
  361. {
  362. Assert(0);
  363. return NULL;
  364. }
  365. // Create a bitmap based on the BITMAP structure and the raw bits in
  366. // the transmission buffer
  367. if (pdata->bitmap_2.bm.bmBitsPixel == 0x20)
  368. hBitmap_2 = CreateDIB( pdata->bitmap_2.bm.bmWidth,
  369. pdata->bitmap_2.bm.bmHeight,
  370. pdata->bitmap_2.bm.bmWidthBytes,
  371. &pdata->bits[dwCount], dwCount_2);
  372. else
  373. hBitmap_2 = CreateBitmap( pdata->bitmap_2.bm.bmWidth,
  374. pdata->bitmap_2.bm.bmHeight,
  375. pdata->bitmap_2.bm.bmPlanes,
  376. pdata->bitmap_2.bm.bmBitsPixel,
  377. &pdata->bits[dwCount]);
  378. }
  379. pBuffer += Align( sizeof(struct MARSHAL_HBITMAP) + dwCount + dwCount_2 );
  380. }
  381. else if ( !IS_HANDLE_MARKER( UnionDisc ) )
  382. {
  383. Assert(0);
  384. }
  385. // A new bitmap handle is ready, destroy the old one, if needed.
  386. if ( *pHBitmap )
  387. DeleteObject( *pHBitmap );
  388. *pHBitmap = hBitmap;
  389. if ( pHBitmap_2 )
  390. {
  391. if ( *pHBitmap_2 )
  392. DeleteObject( *pHBitmap_2 );
  393. *pHBitmap_2 = hBitmap_2;
  394. }
  395. return( pBuffer );
  396. }
  397. //+-------------------------------------------------------------------------
  398. //
  399. // HBITMAP_UserFree
  400. //
  401. //--------------------------------------------------------------------------
  402. void Cic_HBITMAP_UserFree(HBITMAP *pHBitmap, HBITMAP *pHBitmap_2)
  403. {
  404. if( pHBitmap && *pHBitmap )
  405. {
  406. if ( GDI_DATA_PASSING() )
  407. {
  408. DeleteObject( *pHBitmap );
  409. }
  410. }
  411. if( pHBitmap_2 && *pHBitmap_2 )
  412. {
  413. if ( GDI_DATA_PASSING() )
  414. {
  415. DeleteObject( *pHBitmap_2 );
  416. }
  417. }
  418. }
  419. //////////////////////////////////////////////////////////////////////////////
  420. //
  421. // TF_LBBALLOON
  422. //
  423. //////////////////////////////////////////////////////////////////////////////
  424. //+-------------------------------------------------------------------------
  425. //
  426. // UserSize
  427. //
  428. //--------------------------------------------------------------------------
  429. ULONG Cic_TF_LBBALLOONINFO_UserSize(TF_LBBALLOONINFO *pInfo)
  430. {
  431. ULONG ulRet;
  432. ulRet = sizeof(TF_LBBALLOONINFO);
  433. LENGTH_ALIGN(ulRet, CIC_ALIGNMENT);
  434. if (pInfo->bstrText)
  435. ulRet += (SysStringByteLen(pInfo->bstrText) + 2);
  436. else
  437. ulRet += 2;
  438. LENGTH_ALIGN(ulRet, CIC_ALIGNMENT);
  439. return ulRet;
  440. }
  441. //+-------------------------------------------------------------------------
  442. //
  443. // UserMarshal
  444. //
  445. //--------------------------------------------------------------------------
  446. BYTE *Cic_TF_LBBALLOONINFO_UserMarshal(BYTE *pBuf, TF_LBBALLOONINFO *pInfo)
  447. {
  448. if (!pInfo)
  449. return pBuf;
  450. memcpy(pBuf, pInfo, sizeof(TF_LBBALLOONINFO));
  451. pBuf += sizeof(TF_LBBALLOONINFO);
  452. POINTER_ALIGN( pBuf, CIC_ALIGNMENT);
  453. if (pInfo->bstrText)
  454. wcscpy((WCHAR *)pBuf, pInfo->bstrText);
  455. pBuf += ((pInfo->bstrText ? wcslen(pInfo->bstrText) : 0) + 2);
  456. POINTER_ALIGN( pBuf, CIC_ALIGNMENT);
  457. return pBuf;
  458. }
  459. //+-------------------------------------------------------------------------
  460. //
  461. // UserUnMarshal
  462. //
  463. //--------------------------------------------------------------------------
  464. HRESULT Cic_TF_LBBALLOONINFO_UserUnmarshal(BYTE *pBuf, TF_LBBALLOONINFO *pInfo)
  465. {
  466. HRESULT hr;;
  467. if (!pInfo)
  468. return S_OK;
  469. hr = S_OK;
  470. memcpy(pInfo, pBuf, sizeof(TF_LBBALLOONINFO));
  471. if (pInfo->bstrText)
  472. {
  473. BYTE *pTmp = pBuf + sizeof(TF_LBBALLOONINFO);
  474. POINTER_ALIGN( pTmp, CIC_ALIGNMENT);
  475. pInfo->bstrText = SysAllocString((WCHAR *)pTmp);
  476. hr = (pInfo->bstrText != NULL) ? S_OK : E_OUTOFMEMORY;
  477. }
  478. return hr;
  479. }
  480. //+-------------------------------------------------------------------------
  481. //
  482. // UserFree
  483. //
  484. //--------------------------------------------------------------------------
  485. void Cic_TF_LBBALLOONINFO_UserFree(TF_LBBALLOONINFO *pInfo)
  486. {
  487. if (pInfo->bstrText)
  488. {
  489. SysFreeString(pInfo->bstrText);
  490. pInfo->bstrText = NULL;
  491. }
  492. }
  493. // #########################################################################
  494. //
  495. // HICON
  496. // See transmit.h for explanation of gdi data/handle passing.
  497. //
  498. // #########################################################################
  499. struct ICONINFO_WOW64
  500. {
  501. // Identical ICONINFO structure.
  502. BOOL fIcon;
  503. DWORD xHotspot;
  504. DWORD yHotspot;
  505. CAlignWinHandle<HBITMAP> hbmMask;
  506. CAlignWinHandle<HBITMAP> hbmColor;
  507. void operator = (ICONINFO& a)
  508. {
  509. fIcon = a.fIcon;
  510. xHotspot = a.xHotspot;
  511. yHotspot = a.yHotspot;
  512. hbmMask = a.hbmMask;
  513. hbmColor = a.hbmColor;
  514. }
  515. };
  516. struct MARSHAL_HICON
  517. {
  518. MARSHAL_HDR<HICON> hdr;
  519. ICONINFO_WOW64 ic;
  520. MARSHAL_HBITMAP bm;
  521. };
  522. //+-------------------------------------------------------------------------
  523. //
  524. // UserSize
  525. //
  526. //--------------------------------------------------------------------------
  527. ULONG Cic_HICON_UserSize (HICON *pHIcon)
  528. {
  529. ULONG Offset = 0;
  530. if ( !pHIcon )
  531. return 0;
  532. HICON hIcon = *pHIcon;
  533. //
  534. // The encapsulated union.
  535. // Discriminant and then handle or pointer from the union arm.
  536. // Union discriminant is 4 bytes + handle is represented by a long.
  537. //
  538. if ( ! *pHIcon )
  539. return Align( sizeof(struct MARSHAL_HDR<HICON>) );
  540. if ( ICON_DATA_PASSING() )
  541. {
  542. ICONINFO IconInfo;
  543. ULONG ulBmpUserSize = 0;
  544. if (!GetIconInfo(hIcon, &IconInfo))
  545. return 0;
  546. Offset += Align( sizeof(struct MARSHAL_HICON) );
  547. //
  548. // On NT4, CreateBitmap() can not create different device type
  549. // bitmap. We convert the dc bitmap by calling DrawIconEx().
  550. //
  551. // We may want to use DIB section to marshal but marshaling and
  552. // unmarshaling happens in same device so it does not have to
  553. // convert bitmaps to DIB.
  554. //
  555. if (!IsOnNT5())
  556. {
  557. HBITMAP hbmp = NULL;
  558. HBITMAP hbmpMask = NULL;
  559. SIZE size;
  560. BITMAP bmp;
  561. if (!GetObject( IconInfo.hbmColor, sizeof(bmp), &bmp ))
  562. {
  563. Offset = 0;
  564. goto DeleteAndExit;
  565. }
  566. size.cx = bmp.bmWidth;
  567. size.cy = bmp.bmHeight;
  568. Cic_GetIconBitmaps(*pHIcon, &hbmp, &hbmpMask, &size);
  569. ulBmpUserSize = Cic_HBITMAP_UserSize(&hbmp, &hbmpMask);
  570. if (!ulBmpUserSize)
  571. {
  572. Offset = 0;
  573. goto DeleteAndExit;
  574. }
  575. Offset += ulBmpUserSize;
  576. Offset = Align( Offset );
  577. DeleteAndExit:
  578. if (hbmp)
  579. DeleteObject(hbmp);
  580. if (hbmpMask)
  581. DeleteObject(hbmpMask);
  582. }
  583. else
  584. {
  585. ulBmpUserSize = Cic_HBITMAP_UserSize(&IconInfo.hbmColor, &IconInfo.hbmMask);
  586. if (!ulBmpUserSize)
  587. {
  588. Offset = 0;
  589. goto Exit;
  590. }
  591. Offset += ulBmpUserSize;
  592. Offset = Align( Offset );
  593. }
  594. Exit:
  595. if (IconInfo.hbmColor)
  596. DeleteObject(IconInfo.hbmColor);
  597. if (IconInfo.hbmMask)
  598. DeleteObject(IconInfo.hbmMask);
  599. }
  600. else
  601. {
  602. Offset += Align( sizeof(struct MARSHAL_HDR<HICON>) );
  603. }
  604. return( Offset ) ;
  605. }
  606. //+-------------------------------------------------------------------------
  607. //
  608. // HICON_UserMarshall
  609. //
  610. //--------------------------------------------------------------------------
  611. BYTE *Cic_HICON_UserMarshal(BYTE *pBuffer, BYTE *pBufferEnd, HICON *pHIcon)
  612. {
  613. if ( !pHIcon )
  614. return pBuffer;
  615. // Discriminant of the encapsulated union and union arm.
  616. struct MARSHAL_HICON* pdata = (struct MARSHAL_HICON*) pBuffer;
  617. if ( ICON_DATA_PASSING() )
  618. {
  619. pdata->hdr.dwDataType = DATA_MARKER;
  620. pdata->hdr.h = *pHIcon;
  621. if ( ! *pHIcon )
  622. return pBuffer + Align( sizeof(struct MARSHAL_HDR<HICON>) );
  623. //
  624. // Get information about the bitmap
  625. //
  626. ICONINFO IconInfo;
  627. if (!GetIconInfo(*pHIcon, &IconInfo))
  628. memset(&IconInfo, 0, sizeof(IconInfo));
  629. //
  630. // Get the ic structure fields.
  631. //
  632. pdata->ic = IconInfo;
  633. //
  634. // On NT4, CreateBitmap() can not create different device type
  635. // bitmap. We convert the dc bitmap by calling DrawIconEx().
  636. //
  637. // We may want to use DIB section to marshal but marshaling and
  638. // unmarshaling happens in same device so it does not have to
  639. // convert bitmaps to DIB.
  640. //
  641. if (!IsOnNT5())
  642. {
  643. HBITMAP hbmp = NULL;
  644. HBITMAP hbmpMask = NULL;
  645. SIZE size;
  646. BITMAP bmp;
  647. GetObject( IconInfo.hbmColor, sizeof(bmp), &bmp );
  648. size.cx = bmp.bmWidth;
  649. size.cy = bmp.bmHeight;
  650. Cic_GetIconBitmaps(*pHIcon, &hbmp, &hbmpMask, &size);
  651. pBuffer = Cic_HBITMAP_UserMarshal((BYTE*) &pdata->bm, pBufferEnd, &hbmp, &hbmpMask);
  652. if (hbmp)
  653. DeleteObject(hbmp);
  654. if (hbmpMask)
  655. DeleteObject(hbmpMask);
  656. }
  657. else
  658. {
  659. pBuffer = Cic_HBITMAP_UserMarshal((BYTE*) &pdata->bm, pBufferEnd, &IconInfo.hbmColor, &IconInfo.hbmMask);
  660. }
  661. if (IconInfo.hbmColor)
  662. DeleteObject(IconInfo.hbmColor);
  663. if (IconInfo.hbmColor)
  664. DeleteObject(IconInfo.hbmMask);
  665. }
  666. else
  667. {
  668. //
  669. // we need to make sure this pointer of the Icon is
  670. // not a resource.
  671. //
  672. HICON hIcon = CopyIcon(*pHIcon);
  673. if (hIcon)
  674. DestroyIcon(*pHIcon);
  675. else
  676. hIcon = *pHIcon;
  677. // Sending a handle.
  678. pdata->hdr.dwDataType = HANDLE_MARKER;
  679. pdata->hdr.h = hIcon;
  680. pBuffer += Align( sizeof(struct MARSHAL_HDR<HICON>) );
  681. }
  682. return( pBuffer );
  683. }
  684. //+-------------------------------------------------------------------------
  685. //
  686. // HICON_UserUnmarshallWorker
  687. //
  688. //--------------------------------------------------------------------------
  689. BYTE *Cic_HICON_UserUnmarshal(BYTE *pBuffer, HICON *pHIcon)
  690. {
  691. HICON hIcon = NULL;
  692. // Get Discriminant and handle. Caller checked for EOB.
  693. struct MARSHAL_HICON* pdata = (struct MARSHAL_HICON*) pBuffer;
  694. DWORD UnionDisc = pdata->hdr.dwDataType;
  695. hIcon = pdata->hdr.h;
  696. if ( IS_DATA_MARKER( UnionDisc) )
  697. {
  698. if ( hIcon )
  699. {
  700. ICONINFO IconInfo;
  701. IconInfo.fIcon = pdata->ic.fIcon;
  702. IconInfo.xHotspot = pdata->ic.xHotspot;
  703. IconInfo.yHotspot = pdata->ic.yHotspot;
  704. IconInfo.hbmMask = pdata->ic.hbmMask;
  705. IconInfo.hbmColor = pdata->ic.hbmColor;
  706. //
  707. // We just get the bitmap handle from marshaling buffer.
  708. // And the marshaling buffer does not have a valid bitmap handle.
  709. //
  710. IconInfo.hbmColor = NULL;
  711. IconInfo.hbmMask = NULL;
  712. pBuffer = Cic_HBITMAP_UserUnmarshal((BYTE*) &pdata->bm, &IconInfo.hbmColor, &IconInfo.hbmMask);
  713. if (pBuffer)
  714. {
  715. hIcon = CreateIconIndirect(&IconInfo);
  716. }
  717. if (IconInfo.hbmColor)
  718. DeleteObject(IconInfo.hbmColor);
  719. if (IconInfo.hbmMask)
  720. DeleteObject(IconInfo.hbmMask);
  721. }
  722. }
  723. else if ( !IS_HANDLE_MARKER( UnionDisc ) )
  724. {
  725. Assert(0);
  726. }
  727. // A new bitmap handle is ready, destroy the old one, if needed.
  728. if ( *pHIcon )
  729. DestroyIcon( *pHIcon );
  730. *pHIcon = hIcon;
  731. return( pBuffer );
  732. }
  733. //+-------------------------------------------------------------------------
  734. //
  735. // HICON_UserFree
  736. //
  737. //--------------------------------------------------------------------------
  738. void Cic_HICON_UserFree(HICON *pHIcon)
  739. {
  740. if( pHIcon && *pHIcon )
  741. {
  742. if ( ICON_DATA_PASSING() )
  743. {
  744. DestroyIcon( *pHIcon );
  745. }
  746. }
  747. }