windows-nt/Source/XPSP1/NT/com/ole32/oleprx32/proxy/metafile.cxx
2020-09-26 16:20:57 +08:00

1670 lines
48 KiB
C++

//+-------------------------------------------------------------------------
//
// 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 "widewrap.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 )
{
unsigned long ulDataSize, fHandle;
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 ( hMetaFilePict )
{
HGLOBAL hGlobal = GlobalAlloc( GMEM_MOVEABLE, sizeof(METAFILEPICT) );
hMetaFilePict = (HMETAFILEPICT) hGlobal;
if ( hMetaFilePict == NULL )
RAISE_RPC_EXCEPTION( E_OUTOFMEMORY );
METAFILEPICT * pMFP = (METAFILEPICT*) GlobalLock((HANDLE) hMetaFilePict );
if ( pMFP == NULL )
RAISE_RPC_EXCEPTION( E_OUTOFMEMORY );
// 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)++ );
ULONG ulExcept = 0;
if ( pMFP->hMF )
{
if (IS_DATA_MARKER( UnionDisc ) )
{
// Check for EOB.
if ( BufferSize < cbFixup + (10 * sizeof( ULONG )) )
ulExcept = 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 )
ulExcept = RPC_X_BAD_STUB_DATA;
else
{
pMFP->hMF = SetMetaFileBitsEx( ulDataSize, (uchar*)pBuffer );
pBuffer += ulDataSize;
}
}
else
ulExcept = RPC_X_BAD_STUB_DATA;
}
}
else if ( !IS_HANDLE_MARKER( UnionDisc ) )
{
ulExcept = RPC_S_INVALID_TAG;
}
}
GlobalUnlock( (HANDLE) hMetaFilePict );
// wait until we've called GlobalUnlock before raising any exceptions.
if ( ulExcept != 0 )
{
RAISE_RPC_EXCEPTION( ulExcept );
}
}
}
else if ( !(IS_HANDLE_MARKER( UnionDisc ) || IS_HANDLE64_MARKER( UnionDisc )) )
{
RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
}
// 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 )
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 ( 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 );
}
// 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 ( 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 );
}
// 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);
unsigned long ulDataSize, fHandle;
HMETAFILEPICT hMetaFilePict;
stream.Align(8);
unsigned long UnionDisc = stream.ReadULONGNA();
hMetaFilePict = (HMETAFILEPICT)stream.ReadHYPER();
if ( IS_DATA_MARKER( UnionDisc ) )
{
if ( hMetaFilePict )
{
HGLOBAL hGlobal = GlobalAlloc( GMEM_MOVEABLE, sizeof(METAFILEPICT) );
hMetaFilePict = (HMETAFILEPICT) hGlobal;
if ( hMetaFilePict == NULL )
RAISE_RPC_EXCEPTION( E_OUTOFMEMORY );
METAFILEPICT * pMFP = (METAFILEPICT*) GlobalLock((HANDLE) hMetaFilePict );
if ( pMFP == NULL )
RAISE_RPC_EXCEPTION( E_OUTOFMEMORY );
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 ) )
{
// 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 );
}
}
}
RpcFinally
{
GlobalUnlock( (HANDLE) hMetaFilePict );
}
RpcEndFinally;
}
}
else if ( !IS_HANDLE64_MARKER( UnionDisc ) )
{
RAISE_RPC_EXCEPTION( RPC_S_INVALID_TAG );
}
// 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 )
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 ( 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 );
}
// 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 ( 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 );
}
// 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