|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 2000.
//
// File: metafile.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 HMETAFILEPICT, HENHMETAFILE, and
// HMETAFILE.
//
// Functions:
// HMETAFILEPICT_UserSize
// HMETAFILEPICT_UserMarshal
// HMETAFILEPICT_UserUnmarshal
// HMETAFILEPICT_UserFree
// HMETAFILEPICT_UserSize64
// HMETAFILEPICT_UserMarshal64
// HMETAFILEPICT_UserUnmarshal64
// HMETAFILEPICT_UserFree64
// HENHMETAFILE_UserSize
// HENHMETAFILE_UserMarshal
// HENHMETAFILE_UserUnmarshal
// HENHMETAFILE_UserFree
// HENHMETAFILE_UserSize64
// HENHMETAFILE_UserMarshal64
// HENHMETAFILE_UserUnmarshal64
// HENHMETAFILE_UserFree64
// HMETAFILE_UserSize
// HMETAFILE_UserMarshal
// HMETAFILE_UserUnmarshal
// HMETAFILE_UserFree
// HMETAFILE_UserSize64
// HMETAFILE_UserMarshal64
// HMETAFILE_UserUnmarshal64
// HMETAFILE_UserFree64
//
// History: 13-Dec-00 JohnDoty Migrated from transmit.cxx
//
//--------------------------------------------------------------------------
#include "stdrpc.hxx"
#pragma hdrstop
#include <oleauto.h>
#include <objbase.h>
#include "transmit.hxx"
#include <rpcwdt.h>
#include <storext.h>
#include <valid.h>
#include <obase.h>
#include <stream.hxx>
#include "carefulreader.hxx"
// #########################################################################
//
// HMETAFILEPICT
// See transmit.h for explanation of hglobal vs. gdi data/handle passing.
//
// #########################################################################
//+-------------------------------------------------------------------------
//
// Function: HMETAFILEPICT_UserSize
//
// Synopsis: Get the wire size the HMETAFILEPICT handle and data.
//
// Derivation: Union of a long and the meta file pict handle.
// Then struct with top layer (and a hmetafile handle).
// The the representation of the metafile.
//
// history: May-95 Ryszardk Created.
//
//--------------------------------------------------------------------------
unsigned long __RPC_USER HMETAFILEPICT_UserSize ( unsigned long * pFlags, unsigned long Offset, HMETAFILEPICT * pHMetaFilePict ) { if ( !pHMetaFilePict ) return Offset;
LENGTH_ALIGN( Offset, 3 );
// Discriminant of the encapsulated union and the union arm.
// Union discriminant is 4 bytes + handle is represented by a long.
Offset += 8;
if ( ! *pHMetaFilePict ) return Offset;
if ( HGLOBAL_HANDLE_PASSING(*pFlags) ) { #if defined(_WIN64)
//Win64, inproc, we need a bit more space for the handle.
Offset -= 4; //Get rid of that bogus long...
LENGTH_ALIGN( Offset, 7 ); //Make sure alignment is right...
Offset += 8; //And add in the real size of the handle...
#endif
return Offset; }
// Now, this is a two layer object with HGLOBAL on top.
// Upper layer - hglobal part - needs to be sent as data.
METAFILEPICT * pMFP = (METAFILEPICT*) GlobalLock( *(HANDLE *)pHMetaFilePict );
if ( pMFP == NULL ) RAISE_RPC_EXCEPTION( E_OUTOFMEMORY );
// Upper layer: 3 long fields + ptr marker + enc. union
Offset += 4 * sizeof(long) + sizeof(userHMETAFILE);
// The lower part is a metafile handle.
if ( GDI_DATA_PASSING( *pFlags) ) { ulong ulDataSize = GetMetaFileBitsEx( pMFP->hMF, 0 , NULL );
Offset += 12 + ulDataSize; }
GlobalUnlock( *(HANDLE *)pHMetaFilePict );
return( Offset ) ; }
//+-------------------------------------------------------------------------
//
// Function: HMETAFILEPICT_UserMarshal
//
// Synopsis: Marshalls an HMETAFILEPICT object into the RPC buffer.
//
// history: May-95 Ryszardk Created.
//
//--------------------------------------------------------------------------
unsigned char __RPC_FAR * __RPC_USER HMETAFILEPICT_UserMarshal ( unsigned long * pFlags, unsigned char * pBuffer, HMETAFILEPICT * pHMetaFilePict ) { if ( !pHMetaFilePict ) return pBuffer;
UserNdrDebugOut((UNDR_OUT4, "HMETAFILEPICT_UserMarshal\n"));
ALIGN( pBuffer, 3 );
if ( HGLOBAL_HANDLE_PASSING(*pFlags) ) { // Sending only the top level global handle.
#if defined(_WIN64)
*( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE64_MARKER; ALIGN( pBuffer, 7 ); *( PHYPER_LV_CAST pBuffer)++ = *(__int64 *)( pHMetaFilePict ); #else
*( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE_MARKER; *( PLONG_LV_CAST pBuffer)++ = HandleToLong( *pHMetaFilePict ); #endif
return pBuffer; }
// userHMETAFILEPICT
// We need to send the data from the top (hglobal) layer.
*( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER; *( PLONG_LV_CAST pBuffer)++ = HandleToLong( *pHMetaFilePict );
if ( ! *pHMetaFilePict ) return pBuffer;
// remoteHMETAFILEPICT
METAFILEPICT * pMFP = (METAFILEPICT*) GlobalLock( *(HANDLE *)pHMetaFilePict ); if ( pMFP == NULL ) RpcRaiseException( E_OUTOFMEMORY );
*( PULONG_LV_CAST pBuffer)++ = pMFP->mm; *( PULONG_LV_CAST pBuffer)++ = pMFP->xExt; *( PULONG_LV_CAST pBuffer)++ = pMFP->yExt; *( PULONG_LV_CAST pBuffer)++ = USER_MARSHAL_MARKER;
// See if the HMETAFILE needs to be sent as data, too.
if ( GDI_DATA_PASSING(*pFlags) ) { // userHMETAFILE
*( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER; *( PLONG_LV_CAST pBuffer)++ = HandleToLong( pMFP->hMF );
if ( pMFP->hMF ) { ulong ulDataSize = GetMetaFileBitsEx( pMFP->hMF, 0 , NULL );
// conformant size then the size field
*( PULONG_LV_CAST pBuffer)++ = ulDataSize; *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
GetMetaFileBitsEx( pMFP->hMF, ulDataSize , pBuffer );
pBuffer += ulDataSize; } } else { // Sending only an HMETAFILE handle.
*( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE_MARKER; *( PLONG_LV_CAST pBuffer)++ = HandleToLong( pMFP->hMF ); } GlobalUnlock( *(HANDLE *)pHMetaFilePict );
return( pBuffer ); }
//+-------------------------------------------------------------------------
//
// Function: HMETAFILEPICT_UserUnmarshalWorker
//
// Synopsis: Unmarshalls an HMETAFILEPICT object from the RPC buffer.
//
// history: Aug-99 JohnStra Created.
//
//--------------------------------------------------------------------------
unsigned char __RPC_FAR * __RPC_USER HMETAFILEPICT_UserUnmarshalWorker ( unsigned long * pFlags, unsigned char * pBuffer, HMETAFILEPICT * pHMetaFilePict, ULONG_PTR BufferSize ) { BOOL fAllocMetaFile = FALSE; HMETAFILEPICT hMetaFilePict;
// 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 the tag and handle from the buffer. Caller checked for EOB.
unsigned long UnionDisc = *( PULONG_LV_CAST pBuffer)++; if (IS_HANDLE64_MARKER(UnionDisc)) { ALIGN( pBuffer, 7 ); hMetaFilePict = (HMETAFILEPICT)(*( PHYPER_LV_CAST pBuffer)++ ); } else { hMetaFilePict = (HMETAFILEPICT)LongToHandle( *( PLONG_LV_CAST pBuffer)++ ); }
if ( IS_DATA_MARKER( UnionDisc ) ) { if ( HGLOBAL_HANDLE_PASSING(*pFlags) ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
if ( hMetaFilePict ) { HGLOBAL hGlobal = GlobalAlloc( GMEM_MOVEABLE, sizeof(METAFILEPICT) ); HMETAFILEPICT hmfTemp = (HMETAFILEPICT) hGlobal; if ( hmfTemp == NULL ) RAISE_RPC_EXCEPTION( E_OUTOFMEMORY );
fAllocMetaFile = TRUE; METAFILEPICT * pMFP = (METAFILEPICT*) GlobalLock((HANDLE) hmfTemp ); if ( pMFP == NULL ) { GlobalFree((HANDLE)hmfTemp); RAISE_RPC_EXCEPTION( E_OUTOFMEMORY ); } RpcTryFinally { // Check for EOB before accessing metadata.
CHECK_BUFFER_SIZE( BufferSize, cbFixup + (8 * sizeof( ULONG )) ); pMFP->mm = *( PULONG_LV_CAST pBuffer)++; pMFP->xExt = *( PULONG_LV_CAST pBuffer)++; pMFP->yExt = *( PULONG_LV_CAST pBuffer)++; // validate marker.
if ( *( PULONG_LV_CAST pBuffer)++ != USER_MARSHAL_MARKER ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA ); UnionDisc = *( PULONG_LV_CAST pBuffer)++; pMFP->hMF = (HMETAFILE) LongToHandle( *( PLONG_LV_CAST pBuffer)++ ); if ( pMFP->hMF ) { if (IS_DATA_MARKER( UnionDisc ) ) { if ( GDI_HANDLE_PASSING(*pFlags) ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
// Check for EOB.
if ( BufferSize < cbFixup + (10 * sizeof( ULONG )) ) { RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA ); } else { // Conformant size then the size field. These must be the same.
ulong ulDataSize = *( PULONG_LV_CAST pBuffer)++; if ( ulDataSize == *( PULONG_LV_CAST pBuffer)++ ) { // Check for EOB before accessing data.
if ( BufferSize < cbFixup + (10 * sizeof(ULONG)) + ulDataSize ) { RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA ); } else { pMFP->hMF = SetMetaFileBitsEx( ulDataSize, (uchar*)pBuffer ); if (NULL == pMFP->hMF) RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
pBuffer += ulDataSize; } } else RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA ); } } else { if ( !IS_HANDLE_MARKER( UnionDisc ) ) RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
if ( GDI_DATA_PASSING(*pFlags) ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA ); } }
GlobalUnlock( (HANDLE) hmfTemp ); hMetaFilePict = hmfTemp; hmfTemp = NULL; } RpcFinally { if (hmfTemp != NULL) { GlobalUnlock(hmfTemp); GlobalFree(hmfTemp); } } RpcEndFinally; } } else { if ( !(IS_HANDLE_MARKER( UnionDisc ) || IS_HANDLE64_MARKER( UnionDisc )) ) RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
if ( HGLOBAL_DATA_PASSING(*pFlags) ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA ); } // no reusage, just release the previous one.
if ( *pHMetaFilePict ) { // This may happen on the client only and doesn't depend on
// how the other one was passed.
METAFILEPICT *pMFP = (METAFILEPICT*) GlobalLock( *(HANDLE *)pHMetaFilePict ); if ( pMFP == NULL ) { if (fAllocMetaFile) { // Do our best to clean up before we throw.
METAFILEPICT *ptmfp = (METAFILEPICT*)GlobalLock((HANDLE)hMetaFilePict); if (ptmfp) { if (ptmfp->hMF) DeleteMetaFile(ptmfp->hMF); GlobalUnlock((HANDLE)hMetaFilePict); } GlobalFree(hMetaFilePict); } RAISE_RPC_EXCEPTION( E_OUTOFMEMORY ); } if ( pMFP->hMF ) DeleteMetaFile( pMFP->hMF ); GlobalUnlock( *pHMetaFilePict ); GlobalFree( *pHMetaFilePict ); } *pHMetaFilePict = hMetaFilePict; return( pBuffer ); } //+-------------------------------------------------------------------------
//
// Function: HMETAFILEPICT_UserUnmarshal
//
// Synopsis: Unmarshalls an HMETAFILEPICT object from the RPC buffer.
//
// history: May-95 Ryszardk Created.
// Aug-99 JohnStra Factored out bulk of work into a
// worker routine in order to add
// consistency checks.
//
//--------------------------------------------------------------------------
unsigned char __RPC_FAR * __RPC_USER HMETAFILEPICT_UserUnmarshal ( unsigned long * pFlags, unsigned char * pBuffer, HMETAFILEPICT * pHMetaFilePict ) { UserNdrDebugOut((UNDR_OUT4, "HMETAFILEPICT_UserUnmarshal\n"));
// Get the buffer size.
CUserMarshalInfo MarshalInfo( pFlags, pBuffer ); ULONG_PTR BufferSize = MarshalInfo.GetBufferSize(); UCHAR* pBufferStart = MarshalInfo.GetBuffer();
pBuffer = HMETAFILEPICT_UserUnmarshalWorker( pFlags, pBufferStart, pHMetaFilePict, BufferSize ); return( pBuffer ); }
//+-------------------------------------------------------------------------
//
// Function: HMETAFILEPICT_UserFree
//
// Synopsis: Free an HMETAFILEPICT.
//
// history: May-95 Ryszardk Created.
//
//--------------------------------------------------------------------------
void __RPC_USER HMETAFILEPICT_UserFree( unsigned long * pFlags, HMETAFILEPICT * pHMetaFilePict ) { UserNdrDebugOut((UNDR_FORCE, "HMETAFILEPICT_UserFree\n"));
if( pHMetaFilePict && *pHMetaFilePict ) { if ( HGLOBAL_HANDLE_PASSING(*pFlags) ) return;
// Need to free the upper hglobal part.
METAFILEPICT * pMFP = (METAFILEPICT*) GlobalLock( *(HANDLE *)pHMetaFilePict ); if ( pMFP == NULL ) RAISE_RPC_EXCEPTION( E_OUTOFMEMORY ); // See if we need to free the hglobal, too.
if ( pMFP->hMF && HGLOBAL_DATA_PASSING(*pFlags) ) DeleteMetaFile( pMFP->hMF ); GlobalUnlock( *pHMetaFilePict ); GlobalFree( *pHMetaFilePict ); } }
//+-------------------------------------------------------------------------
//
// Function: HENHMETAFILE_UserSize
//
// Synopsis: Get the wire size the HENHMETAFILE handle and data.
//
// Derivation: Union of a long and the meta file handle and then struct.
//
// history: May-95 Ryszardk Created.
//
//--------------------------------------------------------------------------
unsigned long __RPC_USER HENHMETAFILE_UserSize ( unsigned long * pFlags, unsigned long Offset, HENHMETAFILE * pHEnhMetafile ) { if ( !pHEnhMetafile ) return Offset;
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 ( ! *pHEnhMetafile ) return Offset;
if ( GDI_DATA_PASSING(*pFlags) ) { // Pointee of the union arm for the remote case.
// Byte blob : conformant size, size field, data
Offset += 2 * sizeof(long); ulong ulDataSize = GetEnhMetaFileBits( *pHEnhMetafile, 0, NULL ); Offset += ulDataSize; }
return( Offset ); }
//+-------------------------------------------------------------------------
//
// Function: HENHMETAFILE_UserMarshall
//
// Synopsis: Marshalls an HENHMETAFILE object into the RPC buffer.
//
// history: May-95 Ryszardk Created.
//
//--------------------------------------------------------------------------
unsigned char __RPC_FAR * __RPC_USER HENHMETAFILE_UserMarshal ( unsigned long * pFlags, unsigned char * pBuffer, HENHMETAFILE * pHEnhMetafile ) { if ( !pHEnhMetafile ) return pBuffer;
UserNdrDebugOut((UNDR_OUT4, "HENHMETAFILE_UserMarshal\n"));
ALIGN( pBuffer, 3 );
// Discriminant of the encapsulated union and union arm.
if ( GDI_DATA_PASSING(*pFlags) ) { // userHENHMETAFILE
*( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER; *( PLONG_LV_CAST pBuffer)++ = HandleToLong( *pHEnhMetafile ); if ( !*pHEnhMetafile ) return pBuffer;
// BYTE_BLOB: conformant size, size field, data
ulong ulDataSize = GetEnhMetaFileBits( *pHEnhMetafile, 0, NULL );
*( PULONG_LV_CAST pBuffer)++ = ulDataSize; *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
if ( 0 == GetEnhMetaFileBits( *pHEnhMetafile, ulDataSize, (uchar*)pBuffer ) ) RpcRaiseException( HRESULT_FROM_WIN32(GetLastError()));
pBuffer += ulDataSize; } else { // Sending a handle.
*( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE_MARKER; *( PLONG_LV_CAST pBuffer)++ = HandleToLong(*(HANDLE *)pHEnhMetafile); }
return( pBuffer ); }
//+-------------------------------------------------------------------------
//
// Function: HENHMETAFILE_UserUnmarshallWorker
//
// Synopsis: Unmarshalls an HENHMETAFILE object from the RPC buffer.
//
// history: Aug-99 JohnStra Created.
//
//--------------------------------------------------------------------------
unsigned char __RPC_FAR * __RPC_USER HENHMETAFILE_UserUnmarshalWorker ( unsigned long * pFlags, unsigned char * pBuffer, HENHMETAFILE * pHEnhMetafile, ULONG_PTR BufferSize ) { HENHMETAFILE hEnhMetafile;
// 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 the tag and handle. Caller checked for EOB.
unsigned long UnionDisc = *( PULONG_LV_CAST pBuffer)++; hEnhMetafile = (HENHMETAFILE) LongToHandle( *( PLONG_LV_CAST pBuffer)++ );
if ( IS_DATA_MARKER( UnionDisc) ) { if ( GDI_HANDLE_PASSING(*pFlags) ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
if ( hEnhMetafile ) { // Check for EOB before accessing metadata.
CHECK_BUFFER_SIZE( BufferSize, cbFixup + (4 * sizeof( ULONG )) );
// Byte blob : conformant size, size field, data
ulong ulDataSize = *( PULONG_LV_CAST pBuffer)++; if ( *( PULONG_LV_CAST pBuffer)++ != ulDataSize ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
// Check for EOB before accessing data.
CHECK_BUFFER_SIZE( BufferSize, cbFixup + (4 * sizeof(ULONG)) + ulDataSize );
hEnhMetafile = SetEnhMetaFileBits( ulDataSize, (uchar*) pBuffer ); pBuffer += ulDataSize; } } else { if ( !IS_HANDLE_MARKER( UnionDisc ) ) RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG ); if ( GDI_DATA_PASSING(*pFlags) ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA ); }
// No reusage of the old object.
if (*pHEnhMetafile) DeleteEnhMetaFile( *pHEnhMetafile );
*pHEnhMetafile = hEnhMetafile;
return( pBuffer ); }
//+-------------------------------------------------------------------------
//
// Function: HENHMETAFILE_UserUnmarshall
//
// Synopsis: Unmarshalls an HENHMETAFILE object from the RPC buffer.
//
// history: May-95 Ryszardk Created.
// Aug-99 JohnStra Factored bulk of work out into a
// worker routine in order to add
// consistency checks.
//
//--------------------------------------------------------------------------
unsigned char __RPC_FAR * __RPC_USER HENHMETAFILE_UserUnmarshal ( unsigned long * pFlags, unsigned char * pBuffer, HENHMETAFILE * pHEnhMetafile ) { UserNdrDebugOut((UNDR_OUT4, "HENHMETAFILE_UserUnmarshal\n"));
// Get the buffer size and start of buffer.
CUserMarshalInfo MarshalInfo( pFlags, pBuffer ); ULONG_PTR BufferSize = MarshalInfo.GetBufferSize(); UCHAR* pBufferStart = MarshalInfo.GetBuffer();
pBuffer = HENHMETAFILE_UserUnmarshalWorker( pFlags, pBufferStart, pHEnhMetafile, BufferSize ); return( pBuffer ); }
//+-------------------------------------------------------------------------
//
// Function: HENHMETAFILE_UserFree
//
// Synopsis: Free an HENHMETAFILE.
//
// history: May-95 Ryszardk Created.
//
//--------------------------------------------------------------------------
void __RPC_USER HENHMETAFILE_UserFree( unsigned long * pFlags, HENHMETAFILE * pHEnhMetafile ) { UserNdrDebugOut((UNDR_FORCE, "HENHMETAFILE_UserFree\n"));
if( pHEnhMetafile && *pHEnhMetafile ) { if ( GDI_DATA_PASSING(*pFlags) ) { DeleteEnhMetaFile( *pHEnhMetafile ); } } }
// #########################################################################
//
// HMETAFILE
// See transmit.h for explanation of gdi data/handle passing.
//
// #########################################################################
//+-------------------------------------------------------------------------
//
// Function: HMETAFILE_UserSize
//
// Synopsis: Get the wire size the HMETAFILE handle and data.
//
// Derivation: Same wire layout as HENHMETAFILE
//
//--------------------------------------------------------------------------
unsigned long __RPC_USER HMETAFILE_UserSize ( unsigned long * pFlags, unsigned long Offset, HMETAFILE * pHMetafile ) { if ( !pHMetafile ) return Offset;
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 ( ! *pHMetafile ) return Offset;
if ( GDI_DATA_PASSING(*pFlags) ) { // Pointee of the union arm for the remote case.
// Byte blob : conformant size, size field, data
Offset += 2 * sizeof(long);
ulong ulDataSize = GetMetaFileBitsEx( *pHMetafile, 0, NULL ); Offset += ulDataSize; }
return( Offset ); }
//+-------------------------------------------------------------------------
//
// Function: HMETAFILE_UserMarshal
//
// Synopsis: Marshals an HMETAFILE object into the RPC buffer.
//
// Derivation: Same wire layout as HENHMETAFILE
//
//--------------------------------------------------------------------------
unsigned char __RPC_FAR * __RPC_USER HMETAFILE_UserMarshal ( unsigned long * pFlags, unsigned char * pBuffer, HMETAFILE * pHMetafile ) { if ( !pHMetafile ) return pBuffer;
UserNdrDebugOut((UNDR_OUT4, "HMETAFILE_UserMarshal\n"));
ALIGN( pBuffer, 3 );
// Discriminant of the encapsulated union and union arm.
if ( GDI_DATA_PASSING(*pFlags) ) { // userHMETAFILE
*( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER; *( PULONG_LV_CAST pBuffer)++ = PtrToUlong(*pHMetafile);
if ( !*pHMetafile ) return pBuffer;
// BYTE_BLOB: conformant size, size field, data
ulong ulDataSize = GetMetaFileBitsEx( *pHMetafile, 0, NULL );
*( PULONG_LV_CAST pBuffer)++ = ulDataSize; *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
if ( 0 == GetMetaFileBitsEx( *pHMetafile, ulDataSize, (uchar*)pBuffer ) ) RpcRaiseException( HRESULT_FROM_WIN32(GetLastError()));
pBuffer += ulDataSize; } else { // Sending a handle.
*( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE_MARKER; *( PULONG_LV_CAST pBuffer)++ = PtrToUlong(*(HANDLE *)pHMetafile); }
return( pBuffer ); }
//+-------------------------------------------------------------------------
//
// Function: HMETAFILE_UserUnmarshal
//
// Synopsis: Unmarshalls an HMETAFILE object from the RPC buffer.
//
// Derivation: Same wire layout as HENHMETAFILE
//
//--------------------------------------------------------------------------
unsigned char __RPC_FAR * __RPC_USER HMETAFILE_UserUnmarshal ( unsigned long * pFlags, unsigned char * pBuffer, HMETAFILE * pHMetafile ) { HMETAFILE hMetafile;
UserNdrDebugOut((UNDR_OUT4, "HMETAFILE_UserUnmarshal\n"));
// Get the buffer size and the start of the buffer.
CUserMarshalInfo MarshalInfo( pFlags, pBuffer ); ULONG_PTR BufferSize = MarshalInfo.GetBufferSize(); UCHAR* pBufferStart = MarshalInfo.GetBuffer();
// Align the buffer and save the fixup size.
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)) );
unsigned long UnionDisc = *( PULONG_LV_CAST pBuffer)++; hMetafile = (HMETAFILE) LongToHandle( *( PLONG_LV_CAST pBuffer)++ );
if ( IS_DATA_MARKER( UnionDisc) ) { if ( GDI_HANDLE_PASSING(*pFlags) ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
if ( hMetafile ) { // Check for EOB before accessing metadata.
CHECK_BUFFER_SIZE( BufferSize, cbFixup + (4 * sizeof( ULONG )) ); // Byte blob : conformant size, size field, data
ulong ulDataSize = *( PULONG_LV_CAST pBuffer)++; if ( *( PULONG_LV_CAST pBuffer)++ != ulDataSize ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
// Check for EOB before accessing data.
CHECK_BUFFER_SIZE( BufferSize, cbFixup + (4 * sizeof( ULONG )) + ulDataSize );
hMetafile = SetMetaFileBitsEx( ulDataSize, (uchar*) pBuffer ); pBuffer += ulDataSize; } } else { if ( !IS_HANDLE_MARKER( UnionDisc ) ) RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
if ( GDI_DATA_PASSING(*pFlags) ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA ); }
// No reusage of the old object.
if (*pHMetafile) DeleteMetaFile( *pHMetafile );
*pHMetafile = hMetafile;
return( pBuffer ); }
//+-------------------------------------------------------------------------
//
// Function: HMETAFILE_UserFree
//
// Synopsis: Free an HMETAFILE.
//
//--------------------------------------------------------------------------
void __RPC_USER HMETAFILE_UserFree( unsigned long * pFlags, HMETAFILE * pHMetafile ) { UserNdrDebugOut((UNDR_FORCE, "HMETAFILE_UserFree\n"));
if( pHMetafile && *pHMetafile ) { if ( GDI_DATA_PASSING(*pFlags) ) { DeleteMetaFile( *pHMetafile ); } } }
#if defined(_WIN64)
//+-------------------------------------------------------------------------
//
// Function: HMETAFILEPICT_UserSize64
//
// Synopsis: Get the wire size the HMETAFILEPICT handle and data.
//
// Derivation: Union of a long and the meta file pict handle.
// Then struct with top layer (and a hmetafile handle).
// The the representation of the metafile.
//
// history: Dec-00 JohnDoty Created from 32bit functions.
//
//--------------------------------------------------------------------------
unsigned long __RPC_USER HMETAFILEPICT_UserSize64 ( unsigned long * pFlags, unsigned long Offset, HMETAFILEPICT * pHMetaFilePict ) { if ( !pHMetaFilePict ) return Offset; // Discriminant of the encapsulated union and the union arm.
// Union discriminant is 4 bytes
LENGTH_ALIGN( Offset, 7 ); Offset += 4; LENGTH_ALIGN( Offset, 7 );
// Rest of the upper layer:
// (already aligned on 8)
// pointer marker (or handle) 8
Offset += 8;
if ( HGLOBAL_HANDLE_PASSING(*pFlags) ) { return Offset; }
if ( ! *pHMetaFilePict ) { return Offset; }
// METAFILEPICT is a structure containing an HMETAFILE.
// The structure is GlobalAlloc'd.
METAFILEPICT * pMFP = (METAFILEPICT*) GlobalLock( *(HANDLE *)pHMetaFilePict );
if ( pMFP == NULL ) RAISE_RPC_EXCEPTION( E_OUTOFMEMORY );
// 3xlong 12
// (align on 8) 4
// lower lev ptr. 8
// Lower level:
// (already aligned on 8)
// discriminant 4
// (align on 8) 4
Offset += 32;
// Lower layer: userHMETAFILE union...
if ( GDI_DATA_PASSING( *pFlags) ) { // pointer 8
// BYTE_BLOB:
// conformance 8
// size 4
// bytes ulDataSize
ulong ulDataSize = GetMetaFileBitsEx( pMFP->hMF, 0 , NULL ); if (0 == ulDataSize) RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
Offset += 20 + ulDataSize; } else { // handle 8
Offset += 8; }
GlobalUnlock( *(HANDLE *)pHMetaFilePict );
return( Offset ) ; }
//+-------------------------------------------------------------------------
//
// Function: HMETAFILEPICT_UserMarshal64
//
// Synopsis: Marshalls an HMETAFILEPICT object into the RPC buffer.
//
// history: Dec-00 JohnDoty Created from 32bit functions.
//
//--------------------------------------------------------------------------
unsigned char __RPC_FAR * __RPC_USER HMETAFILEPICT_UserMarshal64 ( unsigned long * pFlags, unsigned char * pBuffer, HMETAFILEPICT * pHMetaFilePict ) { if ( !pHMetaFilePict ) return pBuffer;
UserNdrDebugOut((UNDR_OUT4, "HMETAFILEPICT_UserMarshal64\n"));
ALIGN( pBuffer, 7 );
if ( HGLOBAL_HANDLE_PASSING(*pFlags) ) { *( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE64_MARKER; ALIGN( pBuffer, 7 ); *( PHYPER_LV_CAST pBuffer)++ = *(__int64 *)( pHMetaFilePict );
return pBuffer; }
// userHMETAFILEPICT
// We need to send the data from the top (hglobal) layer.
*( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER; ALIGN( pBuffer, 7 ); *( PHYPER_LV_CAST pBuffer)++ = *(__int64 *)( pHMetaFilePict );
if ( ! *pHMetaFilePict ) return pBuffer;
// remoteHMETAFILEPICT
METAFILEPICT * pMFP = (METAFILEPICT*)GlobalLock( *(HANDLE *)pHMetaFilePict ); if ( pMFP == NULL ) RpcRaiseException( E_OUTOFMEMORY );
*( PULONG_LV_CAST pBuffer)++ = pMFP->mm; *( PULONG_LV_CAST pBuffer)++ = pMFP->xExt; *( PULONG_LV_CAST pBuffer)++ = pMFP->yExt; ALIGN( pBuffer, 7 ); *( PHYPER_LV_CAST pBuffer)++ = USER_MARSHAL_MARKER;
// See if the HMETAFILE needs to be sent as data, too.
if ( GDI_DATA_PASSING(*pFlags) ) { // userHMETAFILE
*( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER; ALIGN( pBuffer, 7 ); *( PHYPER_LV_CAST pBuffer)++ = (hyper)( pMFP->hMF );
if ( pMFP->hMF ) { ulong ulDataSize = GetMetaFileBitsEx( pMFP->hMF, 0 , NULL ); if (0 == ulDataSize) { GlobalUnlock (*(HANDLE *)pHMetaFilePict); RpcRaiseException(HRESULT_FROM_WIN32(GetLastError())); } // conformant size then the size field
*( PHYPER_LV_CAST pBuffer)++ = ulDataSize; *( PULONG_LV_CAST pBuffer)++ = ulDataSize; GetMetaFileBitsEx( pMFP->hMF, ulDataSize , pBuffer ); pBuffer += ulDataSize; } } else { // Sending only an HMETAFILE handle.
*( PULONG_LV_CAST pBuffer)++ = WDT_HANDLE64_MARKER; ALIGN( pBuffer, 7 ); *( PHYPER_LV_CAST pBuffer)++ = (hyper)( pMFP->hMF ); }
GlobalUnlock( *(HANDLE *)pHMetaFilePict );
return( pBuffer ); }
//+-------------------------------------------------------------------------
//
// Function: HMETAFILEPICT_UserUnmarshalWorker64
//
// Synopsis: Unmarshalls an HMETAFILEPICT object from the RPC buffer.
//
// history: Dec-00 JohnDoty Created from 32bit functions.
//
//--------------------------------------------------------------------------
unsigned char __RPC_FAR * __RPC_USER HMETAFILEPICT_UserUnmarshalWorker64 ( unsigned long * pFlags, unsigned char * pBuffer, HMETAFILEPICT * pHMetaFilePict, ULONG_PTR BufferSize ) { CarefulBufferReader stream(pBuffer, BufferSize); BOOL fAllocMetaFile = FALSE; HMETAFILEPICT hMetaFilePict; stream.Align(8);
unsigned long UnionDisc = stream.ReadULONGNA(); hMetaFilePict = (HMETAFILEPICT)stream.ReadHYPER();
if ( IS_DATA_MARKER( UnionDisc ) ) { if ( HGLOBAL_HANDLE_PASSING(*pFlags) ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
if ( hMetaFilePict ) { HGLOBAL hGlobal = GlobalAlloc( GMEM_MOVEABLE, sizeof(METAFILEPICT) ); HMETAFILEPICT hmfTemp = (HMETAFILEPICT) hGlobal;
if ( hmfTemp == NULL ) RAISE_RPC_EXCEPTION( E_OUTOFMEMORY );
METAFILEPICT * pMFP = (METAFILEPICT*) GlobalLock((HANDLE) hmfTemp); if ( pMFP == NULL ) { GlobalFree((HANDLE)hmfTemp); RAISE_RPC_EXCEPTION( E_OUTOFMEMORY ); } fAllocMetaFile = TRUE; RpcTryFinally { pMFP->mm = stream.ReadULONGNA(); pMFP->xExt = stream.ReadULONGNA(); pMFP->yExt = stream.ReadULONGNA();
// validate marker.
if ( stream.ReadHYPER() != USER_MARSHAL_MARKER ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
UnionDisc = stream.ReadULONGNA(); pMFP->hMF = (HMETAFILE)stream.ReadHYPER();
if ( pMFP->hMF ) { if ( IS_DATA_MARKER( UnionDisc ) ) { if ( GDI_HANDLE_PASSING(*pFlags) ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
// Conformant size then the size field. These must be the same.
ULONG ulDataSize = (ULONG)stream.ReadHYPERNA(); if ( ulDataSize == stream.ReadULONGNA() ) { stream.CheckSize(ulDataSize); pMFP->hMF = SetMetaFileBitsEx( ulDataSize, (uchar*)stream.GetBuffer() ); if (NULL == pMFP->hMF) RpcRaiseException(HRESULT_FROM_WIN32(GetLastError())); stream.Advance(ulDataSize); } else RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA ); } else { if ( !IS_HANDLE64_MARKER( UnionDisc ) ) RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
if ( GDI_DATA_PASSING(*pFlags) ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA ); } }
GlobalUnlock( (HANDLE) hmfTemp ); hMetaFilePict = hmfTemp; hmfTemp = NULL; } RpcFinally { if (hmfTemp != NULL) { GlobalUnlock( (HANDLE) hmfTemp ); GlobalFree( (HANDLE) hmfTemp ); } } RpcEndFinally; } } else { if ( !IS_HANDLE64_MARKER( UnionDisc ) ) RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
if ( HGLOBAL_DATA_PASSING(*pFlags) ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA ); }
// no reusage, just release the previous one.
if ( *pHMetaFilePict ) { // This may happen on the client only and doesn't depend on
// how the other one was passed.
METAFILEPICT * pMFP = (METAFILEPICT*) GlobalLock( *(HANDLE *)pHMetaFilePict );
if ( pMFP == NULL ) { if (fAllocMetaFile) { // Do our best to clean up before we throw.
METAFILEPICT *ptmfp = (METAFILEPICT*)GlobalLock((HANDLE)hMetaFilePict); if (ptmfp) { if (ptmfp->hMF) DeleteMetaFile(ptmfp->hMF); GlobalUnlock((HANDLE)hMetaFilePict); } GlobalFree(hMetaFilePict); } RAISE_RPC_EXCEPTION( E_OUTOFMEMORY ); } if ( pMFP->hMF ) DeleteMetaFile( pMFP->hMF ); GlobalUnlock( *pHMetaFilePict ); GlobalFree( *pHMetaFilePict ); }
*pHMetaFilePict = hMetaFilePict;
return( stream.GetBuffer() ); } //+-------------------------------------------------------------------------
//
// Function: HMETAFILEPICT_UserUnmarshal64
//
// Synopsis: Unmarshalls an HMETAFILEPICT object from the RPC buffer.
//
// history: Dec-00 JohnDoty Created from 32bit functions.
//
//--------------------------------------------------------------------------
unsigned char __RPC_FAR * __RPC_USER HMETAFILEPICT_UserUnmarshal64 ( unsigned long * pFlags, unsigned char * pBuffer, HMETAFILEPICT * pHMetaFilePict ) { UserNdrDebugOut((UNDR_OUT4, "HMETAFILEPICT_UserUnmarshal64\n"));
// Get the buffer size.
CUserMarshalInfo MarshalInfo( pFlags, pBuffer ); ULONG_PTR BufferSize = MarshalInfo.GetBufferSize(); UCHAR* pBufferStart = MarshalInfo.GetBuffer();
pBuffer = HMETAFILEPICT_UserUnmarshalWorker64( pFlags, pBufferStart, pHMetaFilePict, BufferSize ); return( pBuffer ); }
//+-------------------------------------------------------------------------
//
// Function: HMETAFILEPICT_UserFree64
//
// Synopsis: Free an HMETAFILEPICT.
//
// history: Dec-00 JohnDoty Created from 32bit functions.
//
//--------------------------------------------------------------------------
void __RPC_USER HMETAFILEPICT_UserFree64 ( unsigned long * pFlags, HMETAFILEPICT * pHMetaFilePict ) { UserNdrDebugOut((UNDR_FORCE, "HMETAFILEPICT_UserFree64\n")); if( pHMetaFilePict && *pHMetaFilePict ) { if ( HGLOBAL_HANDLE_PASSING(*pFlags) ) return; // Need to free the upper hglobal part.
METAFILEPICT * pMFP = (METAFILEPICT*) GlobalLock( *(HANDLE *)pHMetaFilePict ); if ( pMFP == NULL ) RAISE_RPC_EXCEPTION( E_OUTOFMEMORY ); // See if we need to free the hglobal, too.
if ( pMFP->hMF && HGLOBAL_DATA_PASSING(*pFlags) ) DeleteMetaFile( pMFP->hMF );
GlobalUnlock( *pHMetaFilePict ); GlobalFree( *pHMetaFilePict ); } }
//+-------------------------------------------------------------------------
//
// Function: HENHMETAFILE_UserSize64
//
// Synopsis: Get the wire size the HENHMETAFILE handle and data.
//
// Derivation: Union of a long and the meta file handle and then struct.
//
// history: Dec-00 JohnDoty Created from 32bit functions.
//
//--------------------------------------------------------------------------
unsigned long __RPC_USER HENHMETAFILE_UserSize64 ( unsigned long * pFlags, unsigned long Offset, HENHMETAFILE * pHEnhMetafile ) { if ( !pHEnhMetafile ) return Offset;
LENGTH_ALIGN( Offset, 7 ); // The encapsulated union.
// (aligned on 8)
// discriminant 4
// (align on 8) 4
// pointer or handle 8
Offset += 16;
if ( ! *pHEnhMetafile ) return Offset;
if ( GDI_DATA_PASSING(*pFlags) ) { // BYTE_BLOB
// (aligned on 8)
// conformance 8
// size 4
// data ulDataSize
ulong ulDataSize = GetEnhMetaFileBits( *pHEnhMetafile, 0, NULL ); if (0 == ulDataSize) RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
Offset += 12 + ulDataSize; }
return( Offset ); }
//+-------------------------------------------------------------------------
//
// Function: HENHMETAFILE_UserMarshal64
//
// Synopsis: Marshalls an HENHMETAFILE object into the RPC buffer.
//
// history: Dec-00 JohnDoty Created from 32bit functions.
//
//--------------------------------------------------------------------------
unsigned char __RPC_FAR * __RPC_USER HENHMETAFILE_UserMarshal64 ( unsigned long * pFlags, unsigned char * pBuffer, HENHMETAFILE * pHEnhMetafile ) { if ( !pHEnhMetafile ) return pBuffer;
UserNdrDebugOut((UNDR_OUT4, "HENHMETAFILE_UserMarshal64\n"));
ALIGN( pBuffer, 7 ); // Discriminant of the encapsulated union and union arm.
if ( GDI_DATA_PASSING(*pFlags) ) { // userHENHMETAFILE
*( PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER; ALIGN( pBuffer, 7 ); *( PHYPER_LV_CAST pBuffer)++ = (hyper)(*pHEnhMetafile);
if ( !*pHEnhMetafile ) return pBuffer;
// BYTE_BLOB: conformant size, size field, data
ulong ulDataSize = GetEnhMetaFileBits( *pHEnhMetafile, 0, NULL );
*( PHYPER_LV_CAST pBuffer)++ = ulDataSize; *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
if ( 0 == GetEnhMetaFileBits( *pHEnhMetafile, ulDataSize, (uchar*)pBuffer ) ) RpcRaiseException( HRESULT_FROM_WIN32(GetLastError())); pBuffer += ulDataSize; } else { // Sending a handle.
*(PULONG_LV_CAST pBuffer)++ = WDT_HANDLE64_MARKER; ALIGN( pBuffer, 7 ); *(PHYPER_LV_CAST pBuffer)++ = (hyper)(*pHEnhMetafile); } return( pBuffer ); }
//+-------------------------------------------------------------------------
//
// Function: HENHMETAFILE_UserUnmarshallWorker64
//
// Synopsis: Unmarshalls an HENHMETAFILE object from the RPC buffer.
//
// history: Dec-00 JohnDoty Created from 32bit functions.
//
//--------------------------------------------------------------------------
unsigned char __RPC_FAR * __RPC_USER HENHMETAFILE_UserUnmarshalWorker64 ( unsigned long * pFlags, unsigned char * pBuffer, HENHMETAFILE * pHEnhMetafile, ULONG_PTR BufferSize ) { CarefulBufferReader stream(pBuffer, BufferSize); HENHMETAFILE hEnhMetafile;
stream.Align(8);
// Get the tag and handle. Caller checked for EOB.
unsigned long UnionDisc = stream.ReadULONGNA(); hEnhMetafile = (HENHMETAFILE)stream.ReadHYPER();
if ( IS_DATA_MARKER( UnionDisc) ) { if ( GDI_HANDLE_PASSING(*pFlags) ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
if ( hEnhMetafile ) { // Byte blob : conformant size, size field, data
ulong ulDataSize = (ulong)stream.ReadHYPERNA(); if ( stream.ReadULONGNA() != ulDataSize ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA ); stream.CheckSize(ulDataSize); hEnhMetafile = SetEnhMetaFileBits( ulDataSize, (uchar*)stream.GetBuffer() ); if (NULL == hEnhMetafile) RpcRaiseException(HRESULT_FROM_WIN32(GetLastError())); stream.Advance(ulDataSize); } } else { if ( !IS_HANDLE64_MARKER( UnionDisc ) ) RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
if ( GDI_DATA_PASSING(*pFlags) ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA ); }
// No reusage of the old object.
if (*pHEnhMetafile) DeleteEnhMetaFile( *pHEnhMetafile ); *pHEnhMetafile = hEnhMetafile;
return( stream.GetBuffer() ); }
//+-------------------------------------------------------------------------
//
// Function: HENHMETAFILE_UserUnmarshal64
//
// Synopsis: Unmarshalls an HENHMETAFILE object from the RPC buffer.
//
// history: Dec-00 JohnDoty Created from 32bit functions.
//
//--------------------------------------------------------------------------
unsigned char __RPC_FAR * __RPC_USER HENHMETAFILE_UserUnmarshal64 ( unsigned long * pFlags, unsigned char * pBuffer, HENHMETAFILE * pHEnhMetafile ) { UserNdrDebugOut((UNDR_OUT4, "HENHMETAFILE_UserUnmarshal64\n"));
// Get the buffer size and start of buffer.
CUserMarshalInfo MarshalInfo( pFlags, pBuffer ); ULONG_PTR BufferSize = MarshalInfo.GetBufferSize(); UCHAR* pBufferStart = MarshalInfo.GetBuffer();
pBuffer = HENHMETAFILE_UserUnmarshalWorker64( pFlags, pBufferStart, pHEnhMetafile, BufferSize ); return( pBuffer ); }
//+-------------------------------------------------------------------------
//
// Function: HENHMETAFILE_UserFree64
//
// Synopsis: Free an HENHMETAFILE.
//
// history: Dec-00 JohnDoty Created from 32bit functions.
//
//--------------------------------------------------------------------------
void __RPC_USER HENHMETAFILE_UserFree64 ( unsigned long * pFlags, HENHMETAFILE * pHEnhMetafile ) { UserNdrDebugOut((UNDR_FORCE, "HENHMETAFILE_UserFree64\n"));
if( pHEnhMetafile && *pHEnhMetafile ) { if ( GDI_DATA_PASSING(*pFlags) ) { DeleteEnhMetaFile( *pHEnhMetafile ); } } }
//+-------------------------------------------------------------------------
//
// Function: HMETAFILE_UserSize64
//
// Synopsis: Get the wire size the HMETAFILE handle and data.
//
// Derivation: Same wire layout as HENHMETAFILE
//
//--------------------------------------------------------------------------
unsigned long __RPC_USER HMETAFILE_UserSize64 ( unsigned long * pFlags, unsigned long Offset, HMETAFILE * pHMetafile ) { if ( !pHMetafile ) return Offset;
LENGTH_ALIGN( Offset, 7 );
// The encapsulated union.
// (aligned on 8)
// discriminant 4
// (align on 8) 4
// ptr or handle 8
Offset += 16;
if ( ! *pHMetafile ) return Offset;
if ( GDI_DATA_PASSING(*pFlags) ) { // Byte blob
// (aligned on 8)
// conformance 8
// size 4
// data ulDataSize
ulong ulDataSize = GetMetaFileBitsEx( *pHMetafile, 0, NULL ); if (0 == ulDataSize) RpcRaiseException(HRESULT_FROM_WIN32(GetLastError()));
Offset += 12 + ulDataSize; }
return( Offset ); }
//+-------------------------------------------------------------------------
//
// Function: HMETAFILE_UserMarshal64
//
// Synopsis: Marshals an HMETAFILE object into the RPC buffer.
//
// Derivation: Same wire layout as HENHMETAFILE
//
//--------------------------------------------------------------------------
unsigned char __RPC_FAR * __RPC_USER HMETAFILE_UserMarshal64 ( unsigned long * pFlags, unsigned char * pBuffer, HMETAFILE * pHMetafile ) { if ( !pHMetafile ) return pBuffer;
UserNdrDebugOut((UNDR_OUT4, "HMETAFILE_UserMarshal64\n"));
ALIGN( pBuffer, 7 );
// Discriminant of the encapsulated union and union arm.
if ( GDI_DATA_PASSING(*pFlags) ) { // userHMETAFILE
*(PULONG_LV_CAST pBuffer)++ = WDT_DATA_MARKER; ALIGN( pBuffer, 7 ); *(PHYPER_LV_CAST pBuffer)++ = (hyper)(*pHMetafile);
if ( !*pHMetafile ) return pBuffer;
// BYTE_BLOB: conformant size, size field, data
ulong ulDataSize = GetMetaFileBitsEx( *pHMetafile, 0, NULL );
*( PHYPER_LV_CAST pBuffer)++ = ulDataSize; *( PULONG_LV_CAST pBuffer)++ = ulDataSize;
if ( 0 == GetMetaFileBitsEx( *pHMetafile, ulDataSize, (uchar*)pBuffer ) ) RpcRaiseException( HRESULT_FROM_WIN32(GetLastError())); pBuffer += ulDataSize; } else { // Sending a handle.
*(PULONG_LV_CAST pBuffer)++ = WDT_HANDLE64_MARKER; ALIGN( pBuffer, 7 ); *(PHYPER_LV_CAST pBuffer)++ = (hyper)(*(HANDLE *)pHMetafile); }
return( pBuffer ); }
//+-------------------------------------------------------------------------
//
// Function: HMETAFILE_UserUnmarshal64
//
// Synopsis: Unmarshalls an HMETAFILE object from the RPC buffer.
//
// Derivation: Same wire layout as HENHMETAFILE
//
//--------------------------------------------------------------------------
unsigned char __RPC_FAR * __RPC_USER HMETAFILE_UserUnmarshal64 ( unsigned long * pFlags, unsigned char * pBuffer, HMETAFILE * pHMetafile ) { HMETAFILE hMetafile;
UserNdrDebugOut((UNDR_OUT4, "HMETAFILE_UserUnmarshal64\n"));
// Get the buffer size and the start of the buffer.
CUserMarshalInfo MarshalInfo( pFlags, pBuffer ); CarefulBufferReader stream( pBuffer, MarshalInfo.GetBufferSize() );
// Align the buffer and save the fixup size.
stream.Align(8); unsigned long UnionDisc = stream.ReadULONGNA(); hMetafile = (HMETAFILE)stream.ReadHYPER();
if ( IS_DATA_MARKER( UnionDisc) ) { if ( GDI_HANDLE_PASSING(*pFlags) ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
if ( hMetafile ) { // Byte blob : conformant size, size field, data
ulong ulDataSize = (ulong)stream.ReadHYPERNA(); if ( stream.ReadULONGNA() != ulDataSize ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA );
stream.CheckSize(ulDataSize); hMetafile = SetMetaFileBitsEx( ulDataSize, (uchar*) stream.GetBuffer() ); if (NULL == hMetafile) RpcRaiseException(HRESULT_FROM_WIN32(GetLastError())); stream.Advance(ulDataSize); } } else { if ( !IS_HANDLE64_MARKER( UnionDisc ) ) RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
if ( GDI_DATA_PASSING(*pFlags) ) RAISE_RPC_EXCEPTION( RPC_X_BAD_STUB_DATA ); } // No reusage of the old object.
if (*pHMetafile) DeleteMetaFile( *pHMetafile ); *pHMetafile = hMetafile;
return( stream.GetBuffer() ); }
//+-------------------------------------------------------------------------
//
// Function: HMETAFILE_UserFree64
//
// Synopsis: Free an HMETAFILE.
//
//--------------------------------------------------------------------------
void __RPC_USER HMETAFILE_UserFree64( unsigned long * pFlags, HMETAFILE * pHMetafile ) { UserNdrDebugOut((UNDR_FORCE, "HMETAFILE_UserFree64\n")); if( pHMetafile && *pHMetafile ) { if ( GDI_DATA_PASSING(*pFlags) ) { DeleteMetaFile( *pHMetafile ); } } }
#endif // win64
|