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.

631 lines
19 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 2000.
  5. //
  6. // File: hpalette.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 HPALETTE.
  12. //
  13. // Functions:
  14. // HPALETTE_UserSize
  15. // HPALETTE_UserMarshal
  16. // HPALETTE_UserUnmarshal
  17. // HPALETTE_UserFree
  18. // HPALETTE_UserSize64
  19. // HPALETTE_UserMarshal64
  20. // HPALETTE_UserUnmarshal64
  21. // HPALETTE_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: HPALETTE_UserSize
  41. //
  42. // Synopsis: Get the wire size the HPALETTE handle and data.
  43. //
  44. // Derivation: Union of a long and the hpalette handle.
  45. // Then the struct represents hpalette.
  46. //
  47. // history: May-95 Ryszardk Created.
  48. //
  49. //--------------------------------------------------------------------------
  50. unsigned long __RPC_USER
  51. HPALETTE_UserSize (
  52. unsigned long * pFlags,
  53. unsigned long Offset,
  54. HPALETTE * pHPalette )
  55. {
  56. if ( !pHPalette )
  57. return Offset;
  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 ( ! *pHPalette )
  64. return Offset;
  65. if ( GDI_DATA_PASSING(*pFlags) )
  66. {
  67. // Conformat struct with version and size and conf array of entries.
  68. Offset += sizeof(long) + 2 * sizeof(short);
  69. // Determine the number of color entries in the palette
  70. DWORD cEntries = GetPaletteEntries(*pHPalette, 0, 0, NULL);
  71. Offset += cEntries * sizeof(PALETTEENTRY);
  72. }
  73. return( Offset ) ;
  74. }
  75. //+-------------------------------------------------------------------------
  76. //
  77. // Function: HPALETTE_UserMarshall
  78. //
  79. // Synopsis: Marshalls an HPALETTE object into the RPC buffer.
  80. //
  81. // history: May-95 Ryszardk Created.
  82. //
  83. //--------------------------------------------------------------------------
  84. unsigned char __RPC_FAR * __RPC_USER
  85. HPALETTE_UserMarshal (
  86. unsigned long * pFlags,
  87. unsigned char * pBuffer,
  88. HPALETTE * pHPalette )
  89. {
  90. if ( !pHPalette )
  91. return pBuffer;
  92. UserNdrDebugOut((UNDR_OUT4, "HPALETTE_UserMarshal\n"));
  93. ALIGN( pBuffer, 3 );
  94. // Discriminant of the encapsulated union and union arm.
  95. if ( GDI_DATA_PASSING(*pFlags) )
  96. {
  97. // userHPALETTE
  98. *( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER;
  99. *( PULONG_LV_CAST pBuffer)++ = PtrToUlong(*pHPalette);
  100. if ( ! *pHPalette )
  101. return pBuffer;
  102. // rpcLOGPALETTE
  103. // Logpalette is a conformant struct with a version field,
  104. // size filed and conformant array of palentries.
  105. // Determine the number of color entries in the palette
  106. DWORD cEntries = GetPaletteEntries(*pHPalette, 0, 0, NULL);
  107. // Conformant size
  108. *( PULONG_LV_CAST pBuffer)++ = cEntries;
  109. // Fields: both are short!
  110. // The old code was just setting the version number.
  111. // They say it has to be that way.
  112. *( PUSHORT_LV_CAST pBuffer)++ = (ushort) 0x300;
  113. *( PUSHORT_LV_CAST pBuffer)++ = (ushort) cEntries;
  114. // Entries: each entry is a struct with 4 bytes.
  115. // Calculate the resultant data size
  116. DWORD cbData = cEntries * sizeof(PALETTEENTRY);
  117. if (cbData)
  118. {
  119. if (0 == GetPaletteEntries( *pHPalette,
  120. 0,
  121. cEntries,
  122. (PALETTEENTRY *)pBuffer ) )
  123. {
  124. RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
  125. }
  126. pBuffer += cbData;
  127. }
  128. }
  129. else
  130. {
  131. // Sending a handle.
  132. *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE_MARKER;
  133. *( PULONG_LV_CAST pBuffer)++ = PtrToUlong(*(HANDLE *)pHPalette); }
  134. return( pBuffer );
  135. }
  136. //+-------------------------------------------------------------------------
  137. //
  138. // Function: HPALETTE_UserUnmarshallWorker
  139. //
  140. // Synopsis: Unmarshalls an HPALETTE object from the RPC buffer.
  141. //
  142. // history: Aug-99 JohnStra Created.
  143. //
  144. //--------------------------------------------------------------------------
  145. unsigned char __RPC_FAR * __RPC_USER
  146. HPALETTE_UserUnmarshalWorker (
  147. unsigned long * pFlags,
  148. unsigned char * pBuffer,
  149. HPALETTE * pHPalette,
  150. ULONG_PTR BufferSize )
  151. {
  152. HPALETTE hPalette;
  153. // Align the buffer and save the fixup size.
  154. UCHAR* pBufferStart = pBuffer;
  155. ALIGN( pBuffer, 3 );
  156. ULONG_PTR cbFixup = (ULONG_PTR)(pBuffer - pBufferStart);
  157. // Check for EOB before accessing discriminant and handle.
  158. CHECK_BUFFER_SIZE( BufferSize, cbFixup + (2 * sizeof( ULONG )) );
  159. // Get disc and handle.
  160. unsigned long UnionDisc = *( PULONG_LV_CAST pBuffer)++;
  161. hPalette = (HPALETTE)LongToHandle( *( PLONG_LV_CAST pBuffer)++ );
  162. if ( IS_DATA_MARKER( UnionDisc) )
  163. {
  164. if ( hPalette )
  165. {
  166. // Check for EOB before accessing metadata.
  167. CHECK_BUFFER_SIZE(
  168. BufferSize,
  169. cbFixup + (3 * sizeof(ULONG)) + (2 * sizeof(USHORT))) ;
  170. // Get the conformant size.
  171. DWORD cEntries = *( PULONG_LV_CAST pBuffer)++;
  172. LOGPALETTE * pLogPal;
  173. // If there are 0 color entries, we need to allocate the LOGPALETTE
  174. // structure with the one dummy entry (it's a variably sized struct).
  175. // Otherwise, we need to allocate enough space for the extra n-1
  176. // entries at the tail of the structure
  177. if (0 == cEntries)
  178. {
  179. pLogPal = (LOGPALETTE *) WdtpAllocate( pFlags,
  180. sizeof(LOGPALETTE));
  181. }
  182. else
  183. {
  184. pLogPal = (LOGPALETTE *)
  185. WdtpAllocate( pFlags,
  186. sizeof(LOGPALETTE) +
  187. (cEntries - 1) * sizeof(PALETTEENTRY));
  188. }
  189. pLogPal->palVersion = *( PUSHORT_LV_CAST pBuffer)++;
  190. pLogPal->palNumEntries = *( PUSHORT_LV_CAST pBuffer)++;
  191. if ( pLogPal->palVersion != 0x300 || pLogPal->palNumEntries != cEntries )
  192. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  193. // If there are entries, move them into out LOGPALETTE structure
  194. if (cEntries)
  195. {
  196. // Check for EOB before accessing data.
  197. CHECK_BUFFER_SIZE(
  198. BufferSize,
  199. cbFixup + (3 * sizeof(ULONG)) +
  200. (2 * sizeof(USHORT)) +
  201. (cEntries * sizeof(PALETTEENTRY)) );
  202. memcpy( &(pLogPal->palPalEntry[0]),
  203. pBuffer,
  204. cEntries * sizeof(PALETTEENTRY) );
  205. pBuffer += cEntries * sizeof(PALETTEENTRY);
  206. }
  207. // Attempt to create the palette
  208. hPalette = CreatePalette(pLogPal);
  209. // Success or failure, we're done with the LOGPALETTE structure
  210. WdtpFree( pFlags, pLogPal );
  211. // If the creation failed, raise an exception
  212. if (NULL == hPalette)
  213. {
  214. RAISE_RPC_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
  215. }
  216. }
  217. }
  218. else if ( !IS_HANDLE_MARKER( UnionDisc ) )
  219. {
  220. RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
  221. }
  222. // A new palette is ready, destroy the old one, if needed.
  223. if ( *pHPalette )
  224. DeleteObject( *pHPalette );
  225. *pHPalette = hPalette;
  226. return( pBuffer );
  227. }
  228. //+-------------------------------------------------------------------------
  229. //
  230. // Function: HPALETTE_UserUnmarshall
  231. //
  232. // Synopsis: Unmarshalls an HPALETTE object from the RPC buffer.
  233. //
  234. // history: May-95 Ryszardk Created.
  235. // Aug-99 JohnStra Factored bulk of work out inta a
  236. // worker routine in order to add
  237. // consistency checks.
  238. //
  239. //--------------------------------------------------------------------------
  240. unsigned char __RPC_FAR * __RPC_USER
  241. HPALETTE_UserUnmarshal (
  242. unsigned long * pFlags,
  243. unsigned char * pBuffer,
  244. HPALETTE * pHPalette )
  245. {
  246. UserNdrDebugOut((UNDR_OUT4, "HPALETTE_UserUnmarshal\n"));
  247. // Get the buffer size.
  248. CUserMarshalInfo MarshalInfo( pFlags, pBuffer );
  249. ULONG_PTR BufferSize = MarshalInfo.GetBufferSize();
  250. UCHAR* pBufferStart = MarshalInfo.GetBuffer();
  251. pBuffer = HPALETTE_UserUnmarshalWorker( pFlags,
  252. pBufferStart,
  253. pHPalette,
  254. BufferSize );
  255. return( pBuffer );
  256. }
  257. //+-------------------------------------------------------------------------
  258. //
  259. // Function: HPALETTE_UserFree
  260. //
  261. // Synopsis: Free an HPALETTE.
  262. //
  263. // history: May-95 Ryszardk Created.
  264. //
  265. //--------------------------------------------------------------------------
  266. void __RPC_USER
  267. HPALETTE_UserFree(
  268. unsigned long * pFlags,
  269. HPALETTE * pHPalette )
  270. {
  271. UserNdrDebugOut((UNDR_OUT4, "HPALETTE_UserFree\n"));
  272. if( pHPalette && *pHPalette )
  273. {
  274. if ( GDI_DATA_PASSING(*pFlags) )
  275. {
  276. DeleteObject( *pHPalette );
  277. }
  278. }
  279. }
  280. #if defined(_WIN64)
  281. //+-------------------------------------------------------------------------
  282. //
  283. // Function: HPALETTE_UserSize64
  284. //
  285. // Synopsis: Get the wire size the HPALETTE handle and data.
  286. //
  287. // Derivation: Union of a long and the hpalette handle.
  288. // Then the struct represents hpalette.
  289. //
  290. // history: Dec-00 JohnDoty Created from 32bit functions.
  291. //
  292. //--------------------------------------------------------------------------
  293. unsigned long __RPC_USER
  294. HPALETTE_UserSize64 (
  295. unsigned long * pFlags,
  296. unsigned long Offset,
  297. HPALETTE * pHPalette )
  298. {
  299. if ( !pHPalette )
  300. return Offset;
  301. LENGTH_ALIGN( Offset, 7 );
  302. // The encapsulated union.
  303. // (aligned to 8)
  304. // discriminant 4
  305. // (align to 8) 4
  306. // ptr or handle 8
  307. Offset += 16;
  308. if ( ! *pHPalette )
  309. return Offset;
  310. if ( GDI_DATA_PASSING(*pFlags) )
  311. {
  312. // Conformat struct with version and size and conf array of entries.
  313. // (aligned to 8)
  314. // conformance 8
  315. // palVersion 2
  316. // palNumEntries 2
  317. // entries sizeof(PALETTEENTRY) * cEntries
  318. DWORD cEntries = GetPaletteEntries(*pHPalette, 0, 0, NULL);
  319. Offset += 12 + (cEntries * sizeof(PALETTEENTRY));
  320. }
  321. return( Offset ) ;
  322. }
  323. //+-------------------------------------------------------------------------
  324. //
  325. // Function: HPALETTE_UserMarshal64
  326. //
  327. // Synopsis: Marshalls an HPALETTE object into the RPC buffer.
  328. //
  329. // history: Dec-00 JohnDoty Created from 32bit functions.
  330. //
  331. //--------------------------------------------------------------------------
  332. unsigned char __RPC_FAR * __RPC_USER
  333. HPALETTE_UserMarshal64 (
  334. unsigned long * pFlags,
  335. unsigned char * pBuffer,
  336. HPALETTE * pHPalette )
  337. {
  338. if ( !pHPalette )
  339. return pBuffer;
  340. UserNdrDebugOut((UNDR_OUT4, "HPALETTE_UserMarshal\n"));
  341. ALIGN( pBuffer, 7 );
  342. // Discriminant of the encapsulated union and union arm.
  343. if ( GDI_DATA_PASSING(*pFlags) )
  344. {
  345. // userHPALETTE
  346. *(PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER;
  347. ALIGN( pBuffer, 7 );
  348. *(PHYPER_LV_CAST pBuffer)++ = (hyper)(*pHPalette);
  349. if ( ! *pHPalette )
  350. return pBuffer;
  351. // rpcLOGPALETTE
  352. // Logpalette is a conformant struct with a version field,
  353. // size filed and conformant array of palentries.
  354. // Determine the number of color entries in the palette
  355. DWORD cEntries = GetPaletteEntries(*pHPalette, 0, 0, NULL);
  356. // Conformant size
  357. *( PHYPER_LV_CAST pBuffer)++ = cEntries;
  358. // Fields: both are short!
  359. // The old code was just setting the version number.
  360. // They say it has to be that way.
  361. *( PUSHORT_LV_CAST pBuffer)++ = (ushort) 0x300;
  362. *( PUSHORT_LV_CAST pBuffer)++ = (ushort) cEntries;
  363. // Entries: each entry is a struct with 4 bytes.
  364. // Calculate the resultant data size
  365. DWORD cbData = cEntries * sizeof(PALETTEENTRY);
  366. if (cbData)
  367. {
  368. if (0 == GetPaletteEntries( *pHPalette,
  369. 0,
  370. cEntries,
  371. (PALETTEENTRY *)pBuffer ) )
  372. {
  373. RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
  374. }
  375. pBuffer += cbData;
  376. }
  377. }
  378. else
  379. {
  380. // Sending a handle.
  381. *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE64_MARKER;
  382. ALIGN( pBuffer, 7 );
  383. *( PHYPER_LV_CAST pBuffer)++ = (hyper)(*(HANDLE *)pHPalette);
  384. }
  385. return( pBuffer );
  386. }
  387. //+-------------------------------------------------------------------------
  388. //
  389. // Function: HPALETTE_UserUnmarshalWorker64
  390. //
  391. // Synopsis: Unmarshalls an HPALETTE object from the RPC buffer.
  392. //
  393. // history: Dec-00 JohnDoty Created from 32bit functions.
  394. //
  395. //--------------------------------------------------------------------------
  396. unsigned char __RPC_FAR * __RPC_USER
  397. HPALETTE_UserUnmarshalWorker64 (
  398. unsigned long * pFlags,
  399. unsigned char * pBuffer,
  400. HPALETTE * pHPalette,
  401. ULONG_PTR BufferSize )
  402. {
  403. CarefulBufferReader stream(pBuffer, BufferSize);
  404. HPALETTE hPalette;
  405. // Align the buffer and save the fixup size.
  406. stream.Align(8);
  407. // Get disc and handle.
  408. unsigned long UnionDisc = stream.ReadULONGNA();
  409. hPalette = (HPALETTE)stream.ReadHYPER();
  410. if ( IS_DATA_MARKER( UnionDisc) )
  411. {
  412. if ( hPalette )
  413. {
  414. // Get the conformant size.
  415. DWORD cEntries = (DWORD)stream.ReadHYPER();
  416. LOGPALETTE * pLogPal;
  417. // If there are 0 color entries, we need to allocate the LOGPALETTE
  418. // structure with the one dummy entry (it's a variably sized struct).
  419. // Otherwise, we need to allocate enough space for the extra n-1
  420. // entries at the tail of the structure
  421. if (0 == cEntries)
  422. {
  423. pLogPal = (LOGPALETTE *) WdtpAllocate( pFlags,
  424. sizeof(LOGPALETTE));
  425. }
  426. else
  427. {
  428. pLogPal = (LOGPALETTE *) WdtpAllocate( pFlags,
  429. sizeof(LOGPALETTE) +
  430. (cEntries - 1) * sizeof(PALETTEENTRY));
  431. }
  432. pLogPal->palVersion = stream.ReadUSHORTNA();
  433. pLogPal->palNumEntries = stream.ReadUSHORTNA();
  434. if ( pLogPal->palVersion != 0x300 || pLogPal->palNumEntries != cEntries )
  435. RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
  436. // If there are entries, move them into out LOGPALETTE structure
  437. if (cEntries)
  438. {
  439. // Check for EOB before accessing data.
  440. stream.CheckSize(cEntries * sizeof(PALETTEENTRY));
  441. memcpy( &(pLogPal->palPalEntry[0]),
  442. stream.GetBuffer(),
  443. cEntries * sizeof(PALETTEENTRY) );
  444. stream.Advance(cEntries * sizeof(PALETTEENTRY));
  445. }
  446. // Attempt to create the palette
  447. hPalette = CreatePalette(pLogPal);
  448. // Success or failure, we're done with the LOGPALETTE structure
  449. WdtpFree( pFlags, pLogPal );
  450. // If the creation failed, raise an exception
  451. if (NULL == hPalette)
  452. {
  453. RAISE_RPC_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
  454. }
  455. }
  456. }
  457. else if ( !IS_HANDLE64_MARKER( UnionDisc ) )
  458. {
  459. RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
  460. }
  461. // A new palette is ready, destroy the old one, if needed.
  462. if ( *pHPalette )
  463. DeleteObject( *pHPalette );
  464. *pHPalette = hPalette;
  465. return( stream.GetBuffer() );
  466. }
  467. //+-------------------------------------------------------------------------
  468. //
  469. // Function: HPALETTE_UserUnmarshal64
  470. //
  471. // Synopsis: Unmarshalls an HPALETTE object from the RPC buffer.
  472. //
  473. // history: Dec-00 JohnDoty Created from 32bit functions.
  474. //
  475. //--------------------------------------------------------------------------
  476. unsigned char __RPC_FAR * __RPC_USER
  477. HPALETTE_UserUnmarshal64 (
  478. unsigned long * pFlags,
  479. unsigned char * pBuffer,
  480. HPALETTE * pHPalette )
  481. {
  482. UserNdrDebugOut((UNDR_OUT4, "HPALETTE_UserUnmarshal\n"));
  483. // Get the buffer size.
  484. CUserMarshalInfo MarshalInfo( pFlags, pBuffer );
  485. ULONG_PTR BufferSize = MarshalInfo.GetBufferSize();
  486. UCHAR* pBufferStart = MarshalInfo.GetBuffer();
  487. pBuffer = HPALETTE_UserUnmarshalWorker64( pFlags,
  488. pBufferStart,
  489. pHPalette,
  490. BufferSize );
  491. return( pBuffer );
  492. }
  493. //+-------------------------------------------------------------------------
  494. //
  495. // Function: HPALETTE_UserFree64
  496. //
  497. // Synopsis: Free an HPALETTE.
  498. //
  499. // history: Dec-00 JohnDoty Created from 32bit functions.
  500. //
  501. //--------------------------------------------------------------------------
  502. void __RPC_USER
  503. HPALETTE_UserFree64 (
  504. unsigned long * pFlags,
  505. HPALETTE * pHPalette )
  506. {
  507. UserNdrDebugOut((UNDR_OUT4, "HPALETTE_UserFree\n"));
  508. if( pHPalette && *pHPalette )
  509. {
  510. if ( GDI_DATA_PASSING(*pFlags) )
  511. {
  512. DeleteObject( *pHPalette );
  513. }
  514. }
  515. }
  516. #endif // win64