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.

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