//+------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 2000. // // File: bitmap.cxx // // Contents: Support for Windows/OLE data types for oleprx32.dll. // Used to be transmit_as routines, now user_marshal routines. // // This file contains support for HBITMAP. // // Functions: // HBITMAP_UserSize // HBITMAP_UserMarshal // HBITMAP_UserUnmarshal // HBITMAP_UserFree // HBITMAP_UserSize64 // HBITMAP_UserMarshal64 // HBITMAP_UserUnmarshal64 // HBITMAP_UserFree64 // // History: 13-Dec-00 JohnDoty Migrated from transmit.cxx // //-------------------------------------------------------------------------- #include "stdrpc.hxx" #pragma hdrstop #include #include #include "transmit.hxx" #include #include #include "widewrap.h" #include #include #include #include "carefulreader.hxx" //+------------------------------------------------------------------------- // // Function: HBITMAP_UserSize // // Synopsis: Get the wire size the HBITMAP handle and data. // // Derivation: Union of a long and the bitmap handle and then struct. // // history: May-95 Ryszardk Created. // //-------------------------------------------------------------------------- unsigned long __RPC_USER HBITMAP_UserSize ( unsigned long * pFlags, unsigned long Offset, HBITMAP * pHBitmap ) { if ( !pHBitmap ) return Offset; BITMAP bm; HBITMAP hBitmap = *pHBitmap; LENGTH_ALIGN( Offset, 3 ); // The encapsulated union. // Discriminant and then handle or pointer from the union arm. // Union discriminant is 4 bytes + handle is represented by a long. Offset += sizeof(long) + sizeof(long); if ( ! *pHBitmap ) return Offset; if ( GDI_DATA_PASSING(*pFlags) ) { // Pointee of the union arm for the remote case. // Conformat size, 6 fields, size, conf array. Offset += 4 + 4 * sizeof(LONG) + 2 * sizeof(WORD) + 4; // Get information about the bitmap #if defined(_CHICAGO_) if (FALSE == GetObjectA(hBitmap, sizeof(BITMAP), &bm)) #else if (FALSE == GetObject(hBitmap, sizeof(BITMAP), &bm)) #endif { RAISE_RPC_EXCEPTION(HRESULT_FROM_WIN32(GetLastError())); } ULONG ulDataSize = bm.bmPlanes * bm.bmHeight * bm.bmWidthBytes; Offset += ulDataSize; } return( Offset ) ; } //+------------------------------------------------------------------------- // // Function: HBITMAP_UserMarshall // // Synopsis: Marshalls an HBITMAP object into the RPC buffer. // // history: May-95 Ryszardk Created. // //-------------------------------------------------------------------------- unsigned char __RPC_FAR * __RPC_USER HBITMAP_UserMarshal ( unsigned long * pFlags, unsigned char * pBuffer, HBITMAP * pHBitmap ) { if ( !pHBitmap ) return pBuffer; UserNdrDebugOut((UNDR_OUT4, "HBITMAP_UserMarshal\n")); ALIGN( pBuffer, 3 ); // Discriminant of the encapsulated union and union arm. if ( GDI_DATA_PASSING(*pFlags) ) { // userHBITMAP *( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER; *( PULONG_LV_CAST pBuffer)++ = PtrToUlong(*pHBitmap); if ( ! *pHBitmap ) return pBuffer; // Get information about the bitmap BITMAP bm; HBITMAP hBitmap = *pHBitmap; #if defined(_CHICAGO_) if (FALSE == GetObjectA(hBitmap, sizeof(BITMAP), &bm)) #else if (FALSE == GetObject(hBitmap, sizeof(BITMAP), &bm)) #endif { RpcRaiseException(HRESULT_FROM_WIN32(GetLastError())); } DWORD dwCount = bm.bmPlanes * bm.bmHeight * bm.bmWidthBytes; *( PULONG_LV_CAST pBuffer)++ = dwCount; // Get the bm structure fields. ulong ulBmSize = 4 * sizeof(LONG) + 2 * sizeof( WORD ); memcpy( pBuffer, (void *) &bm, ulBmSize ); pBuffer += ulBmSize; // Get the raw bits. if (0 == GetBitmapBits( hBitmap, dwCount, pBuffer ) ) { RpcRaiseException(HRESULT_FROM_WIN32(GetLastError())); } pBuffer += dwCount; } else { // Sending a handle. *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE_MARKER; *( PULONG_LV_CAST pBuffer)++ = PtrToUlong(*(HANDLE *)pHBitmap); } return( pBuffer ); } //+------------------------------------------------------------------------- // // Function: HBITMAP_UserUnmarshallWorker // // Synopsis: Unmarshalls an HBITMAP object from the RPC buffer. // // history: Aug-99 JohnStra Created. // //-------------------------------------------------------------------------- unsigned char __RPC_FAR * __RPC_USER HBITMAP_UserUnmarshalWorker ( unsigned long * pFlags, unsigned char * pBuffer, HBITMAP * pHBitmap, ULONG_PTR BufferSize ) { HBITMAP hBitmap; // Align the buffer and save the fixup size. UCHAR* pBufferStart = pBuffer; ALIGN( pBuffer, 3 ); ULONG_PTR cbFixup = (ULONG_PTR)(pBuffer - pBufferStart); // Check for EOB before accessing discriminant and handle. CHECK_BUFFER_SIZE( BufferSize, cbFixup + (2 * sizeof( ULONG )) ); // Get Discriminant and handle. Caller checked for EOB. unsigned long UnionDisc = *( PULONG_LV_CAST pBuffer)++; hBitmap = (HBITMAP)LongToHandle( *( PLONG_LV_CAST pBuffer)++ ); if ( IS_DATA_MARKER( UnionDisc) ) { if ( hBitmap ) { ulong ulBmSize = 4 * sizeof(LONG) + 2 * sizeof( WORD ); // Check for EOB before accessing metadata. CHECK_BUFFER_SIZE( BufferSize, cbFixup + (3 * sizeof( ULONG )) + ulBmSize ); DWORD dwCount = *( PULONG_LV_CAST pBuffer)++; BITMAP * pBm = (BITMAP *) pBuffer; // verify dwCount matches the bitmap. if ( dwCount != (DWORD) pBm->bmPlanes * pBm->bmHeight * pBm->bmWidthBytes ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA ); pBuffer += ulBmSize; // Check for EOB before accessing data. CHECK_BUFFER_SIZE( BufferSize, cbFixup + (3 * sizeof(ULONG)) + ulBmSize + dwCount); // Create a bitmap based on the BITMAP structure and the raw bits in // the transmission buffer hBitmap = CreateBitmap( pBm->bmWidth, pBm->bmHeight, pBm->bmPlanes, pBm->bmBitsPixel, pBuffer ); pBuffer += dwCount; } } else if ( !IS_HANDLE_MARKER( UnionDisc ) ) { RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG ); } // A new bitmap handle is ready, destroy the old one, if needed. if ( *pHBitmap ) DeleteObject( *pHBitmap ); *pHBitmap = hBitmap; return( pBuffer ); } //+------------------------------------------------------------------------- // // Function: HBITMAP_UserUnmarshall // // Synopsis: Unmarshalls an HBITMAP object from the RPC buffer. // // history: May-95 Ryszardk Created. // Aug-99 JohnStra Factored bulk of work into a worker // routine in order to add consistency // checks. // //-------------------------------------------------------------------------- unsigned char __RPC_FAR * __RPC_USER HBITMAP_UserUnmarshal ( unsigned long * pFlags, unsigned char * pBuffer, HBITMAP * pHBitmap ) { UserNdrDebugOut((UNDR_OUT4, "HBITMAP_UserUnmarshal\n")); // Get the buffer size and ptr to buffer. CUserMarshalInfo MarshalInfo( pFlags, pBuffer ); ULONG_PTR BufferSize = MarshalInfo.GetBufferSize(); UCHAR* pBufferStart = MarshalInfo.GetBuffer(); pBuffer = HBITMAP_UserUnmarshalWorker( pFlags, pBufferStart, pHBitmap, BufferSize ); return( pBuffer ); } //+------------------------------------------------------------------------- // // Function: HBITMAP_UserFree // // Synopsis: Free an HBITMAP. // // history: May-95 Ryszardk Created. // //-------------------------------------------------------------------------- void __RPC_USER HBITMAP_UserFree( unsigned long * pFlags, HBITMAP * pHBitmap ) { UserNdrDebugOut((UNDR_OUT4, "HBITMAP_UserFree\n")); if( pHBitmap && *pHBitmap ) { if ( GDI_DATA_PASSING(*pFlags) ) { DeleteObject( *pHBitmap ); } } } #if defined(_WIN64) //+------------------------------------------------------------------------- // // Function: HBITMAP_UserSize64 // // Synopsis: Get the wire size the HBITMAP handle and data. // // Derivation: Union of a long and the bitmap handle and then struct. // // history: Dec-00 JohnDoty Created from 32bit functions. // //-------------------------------------------------------------------------- unsigned long __RPC_USER HBITMAP_UserSize64 ( unsigned long * pFlags, unsigned long Offset, HBITMAP * pHBitmap ) { if ( !pHBitmap ) return Offset; BITMAP bm; HBITMAP hBitmap = *pHBitmap; LENGTH_ALIGN( Offset, 7 ); // The encapsulated union. // (aligned on 8) // discriminant 4 // (align on 8) 4 // handle or ptr 8 Offset += 16; if ( ! *pHBitmap ) return Offset; if ( GDI_DATA_PASSING(*pFlags) ) { // Pointee of the union arm for the remote case. // (aligned on 8) // conformance 8 // 4xlong 16 // 2xword 4 // size 4 // data ulDataSize; if (FALSE == GetObject(hBitmap, sizeof(BITMAP), &bm)) RAISE_RPC_EXCEPTION(HRESULT_FROM_WIN32(GetLastError())); ULONG ulDataSize = bm.bmPlanes * bm.bmHeight * bm.bmWidthBytes; Offset += 32 + ulDataSize; } return( Offset ) ; } //+------------------------------------------------------------------------- // // Function: HBITMAP_UserMarshal64 // // Synopsis: Marshalls an HBITMAP object into the RPC buffer. // // history: Dec-00 JohnDoty Created from 32bit functions. // //-------------------------------------------------------------------------- unsigned char __RPC_FAR * __RPC_USER HBITMAP_UserMarshal64 ( unsigned long * pFlags, unsigned char * pBuffer, HBITMAP * pHBitmap ) { if ( !pHBitmap ) return pBuffer; UserNdrDebugOut((UNDR_OUT4, "HBITMAP_UserMarshal64\n")); ALIGN( pBuffer, 7 ); // Discriminant of the encapsulated union and union arm. if ( GDI_DATA_PASSING(*pFlags) ) { // userHBITMAP *( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER; ALIGN( pBuffer, 7 ); *( PHYPER_LV_CAST pBuffer)++ = (hyper)(*pHBitmap); if ( ! *pHBitmap ) return pBuffer; // Get information about the bitmap BITMAP bm; HBITMAP hBitmap = *pHBitmap; if (FALSE == GetObject(hBitmap, sizeof(BITMAP), &bm)) RpcRaiseException(HRESULT_FROM_WIN32(GetLastError())); ULONG ulCount = bm.bmPlanes * bm.bmHeight * bm.bmWidthBytes; // Conformance... *(PHYPER_LV_CAST pBuffer)++ = ulCount; // Get the bm structure fields. ulong ulBmSize = 4 * sizeof(LONG) + 2 * sizeof( WORD ); memcpy( pBuffer, &bm, ulBmSize ); pBuffer += ulBmSize; // Get the raw bits. *(PULONG_LV_CAST pBuffer)++ = ulCount; if (0 == GetBitmapBits( hBitmap, ulCount, pBuffer ) ) RpcRaiseException(HRESULT_FROM_WIN32(GetLastError())); pBuffer += ulCount; } else { // Sending a handle. *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE64_MARKER; ALIGN( pBuffer, 7 ); *( PHYPER_LV_CAST pBuffer)++ = (hyper)(*(HANDLE *)pHBitmap); } return( pBuffer ); } //+------------------------------------------------------------------------- // // Function: HBITMAP_UserUnmarshallWorker64 // // Synopsis: Unmarshalls an HBITMAP object from the RPC buffer. // // history: Dec-00 JohnDoty Created from 32bit functions. // //-------------------------------------------------------------------------- unsigned char __RPC_FAR * __RPC_USER HBITMAP_UserUnmarshalWorker64 ( unsigned long * pFlags, unsigned char * pBuffer, HBITMAP * pHBitmap, ULONG_PTR BufferSize ) { CarefulBufferReader stream(pBuffer, BufferSize); stream.Align(8); // Get Discriminant and handle. unsigned long UnionDisc = stream.ReadULONGNA(); HBITMAP hBitmap = (HBITMAP)stream.ReadHYPER(); if ( IS_DATA_MARKER( UnionDisc) ) { if ( hBitmap ) { DWORD dwCount = (DWORD)stream.ReadHYPERNA(); // Check for EOB before accessing metadata. ulong ulBmSize = 4 * sizeof(LONG) + 2 * sizeof(WORD); stream.CheckSize(ulBmSize); BITMAP * pBm = (BITMAP *)stream.GetBuffer(); // verify dwCount matches the bitmap. if ( dwCount != (DWORD) pBm->bmPlanes * pBm->bmHeight * pBm->bmWidthBytes ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA ); stream.Advance(ulBmSize); if (stream.ReadULONGNA() != dwCount) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA ); // Check for EOB before accessing data. stream.CheckSize(dwCount); // Create a bitmap based on the BITMAP structure and the raw bits in // the transmission buffer hBitmap = CreateBitmap( pBm->bmWidth, pBm->bmHeight, pBm->bmPlanes, pBm->bmBitsPixel, stream.GetBuffer() ); if (hBitmap == NULL) RpcRaiseException(HRESULT_FROM_WIN32(GetLastError())); stream.Advance(dwCount); } } else if ( !IS_HANDLE64_MARKER( UnionDisc ) ) { RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG ); } // A new bitmap handle is ready, destroy the old one, if needed. if ( *pHBitmap ) DeleteObject( *pHBitmap ); *pHBitmap = hBitmap; return( stream.GetBuffer() ); } //+------------------------------------------------------------------------- // // Function: HBITMAP_UserUnmarshal64 // // Synopsis: Unmarshalls an HBITMAP object from the RPC buffer. // // history: Dec-00 JohnDoty Created from 32bit functions. // //-------------------------------------------------------------------------- unsigned char __RPC_FAR * __RPC_USER HBITMAP_UserUnmarshal64 ( unsigned long * pFlags, unsigned char * pBuffer, HBITMAP * pHBitmap ) { UserNdrDebugOut((UNDR_OUT4, "HBITMAP_UserUnmarshal\n")); // Get the buffer size and ptr to buffer. CUserMarshalInfo MarshalInfo( pFlags, pBuffer ); ULONG_PTR BufferSize = MarshalInfo.GetBufferSize(); UCHAR* pBufferStart = MarshalInfo.GetBuffer(); pBuffer = HBITMAP_UserUnmarshalWorker64( pFlags, pBufferStart, pHBitmap, BufferSize ); return( pBuffer ); } //+------------------------------------------------------------------------- // // Function: HBITMAP_UserFree64 // // Synopsis: Free an HBITMAP. // // history: Dec-00 JohnDoty Created from 32bit functions. // //-------------------------------------------------------------------------- void __RPC_USER HBITMAP_UserFree64 ( unsigned long * pFlags, HBITMAP * pHBitmap ) { UserNdrDebugOut((UNDR_OUT4, "HBITMAP_UserFree\n")); if( pHBitmap && *pHBitmap ) { if ( GDI_DATA_PASSING(*pFlags) ) { DeleteObject( *pHBitmap ); } } } #endif