You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
923 lines
24 KiB
923 lines
24 KiB
#include "private.h"
|
|
#include "globals.h"
|
|
#include "osver.h"
|
|
#include "transmit.h"
|
|
#include "cmydc.h"
|
|
|
|
|
|
#define MAXFILEMAPSIZE 0x1000
|
|
|
|
|
|
#define DATA_MARKER 0x0001
|
|
#define HANDLE_MARKER 0x0002
|
|
#define IS_DATA_MARKER( x) (x == DATA_MARKER)
|
|
#define IS_HANDLE_MARKER( x) (x == HANDLE_MARKER)
|
|
|
|
#define GDI_DATA_PASSING() (IsOnNT())
|
|
#define POINTER_CAST(x) *(x **)&
|
|
|
|
#define ICON_DATA_PASSING() (IsOnNT())
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// GetIconBitmaps
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL Cic_GetIconBitmaps(HICON hIcon, HBITMAP *phbmp, HBITMAP *phbmpMask, SIZE *psize)
|
|
{
|
|
CBitmapDC hdcSrc(TRUE);
|
|
CBitmapDC hdcMask(TRUE);
|
|
SIZE size;
|
|
|
|
size = *psize;
|
|
|
|
hdcSrc.SetDIB(size.cx, size.cy);
|
|
hdcMask.SetBitmap(size.cx, size.cy, 1, 1);
|
|
RECT rc = {0, 0, size.cx, size.cy};
|
|
FillRect(hdcSrc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
|
|
DrawIconEx(hdcSrc, 0, 0, hIcon, size.cx, size.cy, 0, NULL, DI_NORMAL);
|
|
DrawIconEx(hdcMask, 0, 0, hIcon, size.cx, size.cy, 0, NULL, DI_MASK);
|
|
*phbmp = hdcSrc.GetBitmapAndKeep();
|
|
*phbmpMask = hdcMask.GetBitmapAndKeep();
|
|
return TRUE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// CreateDIB
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
HBITMAP CreateDIB(int cx, int cy, int nWidthByte, BYTE *pMyBits, ULONG_PTR nBitsSize)
|
|
{
|
|
CBitmapDC hdc(TRUE);
|
|
|
|
HBITMAP hBmp;
|
|
BITMAPINFO bi = {0};
|
|
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
|
|
bi.bmiHeader.biWidth = cx;
|
|
bi.bmiHeader.biHeight = cy;
|
|
bi.bmiHeader.biPlanes = 1;
|
|
bi.bmiHeader.biBitCount = 32;
|
|
bi.bmiHeader.biCompression = BI_RGB;
|
|
|
|
BYTE *pDibBits;
|
|
hBmp = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void**)&pDibBits, NULL, 0);
|
|
|
|
if (hBmp)
|
|
{
|
|
int y;
|
|
for (y = 0; y < cy; y++)
|
|
{
|
|
int nyDibBites = (cy - y - 1) * nWidthByte;
|
|
int nyMyBites = y * nWidthByte;
|
|
memcpy(&pDibBits[nyDibBites], &pMyBits[nyMyBites], nWidthByte);
|
|
}
|
|
}
|
|
|
|
return hBmp;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// MARSHAL_HDR
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
template<class TYPE>
|
|
struct MARSHAL_HDR
|
|
{
|
|
DWORD dwDataType;
|
|
CAlignWinHandle<TYPE> h;
|
|
};
|
|
|
|
// #########################################################################
|
|
//
|
|
// HBITMAP
|
|
// See transmit.h for explanation of gdi data/handle passing.
|
|
//
|
|
// #########################################################################
|
|
|
|
struct BITMAP_WOW64
|
|
{
|
|
// Identical BITMAP structure.
|
|
|
|
LONG bmType;
|
|
LONG bmWidth;
|
|
LONG bmHeight;
|
|
LONG bmWidthBytes;
|
|
WORD bmPlanes;
|
|
WORD bmBitsPixel;
|
|
CAlignPointer<LPVOID> bmBits;
|
|
|
|
void operator = (BITMAP& a)
|
|
{
|
|
bmType = a.bmType;
|
|
bmWidth = a.bmWidth;
|
|
bmHeight = a.bmHeight;
|
|
bmWidthBytes = a.bmWidthBytes;
|
|
bmPlanes = a.bmPlanes;
|
|
bmBitsPixel = a.bmBitsPixel;
|
|
bmBits = a.bmBits;
|
|
}
|
|
|
|
void operator = (int a)
|
|
{
|
|
memset(this, a, sizeof(BITMAP_WOW64));
|
|
}
|
|
};
|
|
|
|
struct MARSHAL_HBITMAP
|
|
{
|
|
MARSHAL_HDR<HBITMAP> hdr;
|
|
MARSHAL_HDR<HBITMAP> hdr_2;
|
|
|
|
struct
|
|
{
|
|
DWORD dwCount;
|
|
BITMAP_WOW64 bm;
|
|
} bitmap_1;
|
|
|
|
struct
|
|
{
|
|
DWORD dwCount;
|
|
BITMAP_WOW64 bm;
|
|
} bitmap_2;
|
|
|
|
BYTE bits[1];
|
|
};
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// UserSize
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
ULONG Cic_HBITMAP_UserSize (HBITMAP *pHBitmap, HBITMAP *pHBitmap_2)
|
|
{
|
|
ULONG Offset = 0;
|
|
|
|
if ( !pHBitmap )
|
|
return 0;
|
|
|
|
BITMAP bm, bm_2;
|
|
HBITMAP hBitmap, hBitmap_2;
|
|
|
|
hBitmap = *pHBitmap;
|
|
hBitmap_2 = pHBitmap_2 ? *pHBitmap_2 : NULL;
|
|
|
|
memset(&bm, 0, sizeof(BITMAP));
|
|
memset(&bm_2, 0, sizeof(BITMAP));
|
|
|
|
//
|
|
// The encapsulated union.
|
|
// Discriminant and then handle or pointer from the union arm.
|
|
// Union discriminant is 4 bytes + handle is represented by a long.
|
|
//
|
|
|
|
if ( GDI_DATA_PASSING() )
|
|
{
|
|
Offset += sizeof(struct MARSHAL_HBITMAP);
|
|
|
|
if (hBitmap)
|
|
{
|
|
// Get information about the bitmap
|
|
if (!GetObject(hBitmap, sizeof(BITMAP), &bm))
|
|
return 0;
|
|
|
|
Offset += (bm.bmPlanes * bm.bmHeight * bm.bmWidthBytes);
|
|
}
|
|
|
|
if (hBitmap_2)
|
|
{
|
|
// Get information about the bitmap
|
|
if (!GetObject(hBitmap_2, sizeof(BITMAP), &bm_2))
|
|
return 0;
|
|
|
|
Offset += (bm_2.bmPlanes * bm_2.bmHeight * bm_2.bmWidthBytes);
|
|
}
|
|
|
|
Offset = Align( Offset );
|
|
|
|
}
|
|
else
|
|
{
|
|
if (pHBitmap)
|
|
Offset += Align( sizeof(struct MARSHAL_HDR<HBITMAP>) );
|
|
|
|
if (pHBitmap_2)
|
|
Offset += Align( sizeof(struct MARSHAL_HDR<HBITMAP>) );
|
|
}
|
|
|
|
return( Offset ) ;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// HBITMAP_UserMarshall
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
BYTE *Cic_HBITMAP_UserMarshal(BYTE *pBuffer, BYTE *pBufferEnd, HBITMAP *pHBitmap, HBITMAP *pHBitmap_2)
|
|
{
|
|
if ( !pHBitmap )
|
|
return pBuffer;
|
|
|
|
// Discriminant of the encapsulated union and union arm.
|
|
struct MARSHAL_HBITMAP* pdata = (struct MARSHAL_HBITMAP*) pBuffer;
|
|
|
|
if ( GDI_DATA_PASSING() )
|
|
{
|
|
if (!pHBitmap)
|
|
{
|
|
pdata->hdr.dwDataType = 0;
|
|
pdata->hdr.h = NULL;
|
|
}
|
|
else
|
|
{
|
|
pdata->hdr.dwDataType = DATA_MARKER;
|
|
pdata->hdr.h = *pHBitmap;
|
|
}
|
|
|
|
if (!pHBitmap_2)
|
|
{
|
|
pdata->hdr_2.dwDataType = 0;
|
|
pdata->hdr_2.h = NULL;
|
|
}
|
|
else
|
|
{
|
|
pdata->hdr_2.dwDataType = DATA_MARKER;
|
|
pdata->hdr_2.h = *pHBitmap_2;
|
|
}
|
|
|
|
//
|
|
// Get information about the bitmap
|
|
//
|
|
|
|
BITMAP bm, bm_2;
|
|
HBITMAP hBitmap = *pHBitmap;
|
|
HBITMAP hBitmap_2 = pHBitmap_2 ? *pHBitmap_2 : NULL;
|
|
|
|
//
|
|
// Bitmap object 1
|
|
//
|
|
if (!hBitmap)
|
|
{
|
|
pdata->bitmap_1.bm = 0;
|
|
pdata->bitmap_1.dwCount = 0;
|
|
}
|
|
else
|
|
{
|
|
if (!GetObject(hBitmap, sizeof(BITMAP), &bm))
|
|
return pBuffer + Align( sizeof(struct MARSHAL_HDR<HBITMAP>) );
|
|
|
|
pdata->bitmap_1.dwCount = bm.bmPlanes * bm.bmHeight * bm.bmWidthBytes;
|
|
|
|
//
|
|
// Get the bm structure fields.
|
|
//
|
|
pdata->bitmap_1.bm = bm;
|
|
}
|
|
|
|
|
|
//
|
|
// Bitmap object 2
|
|
//
|
|
|
|
if (!hBitmap_2)
|
|
{
|
|
pdata->bitmap_2.bm = 0;
|
|
pdata->bitmap_2.dwCount = 0;
|
|
}
|
|
else
|
|
{
|
|
if (!GetObject(hBitmap_2, sizeof(BITMAP), &bm_2))
|
|
return pBuffer + Align( sizeof(struct MARSHAL_HDR<HBITMAP>) );
|
|
|
|
pdata->bitmap_2.dwCount = bm_2.bmPlanes * bm_2.bmHeight * bm_2.bmWidthBytes;
|
|
|
|
pdata->bitmap_2.bm = bm_2;
|
|
}
|
|
|
|
//
|
|
// Get the raw bits.
|
|
//
|
|
|
|
if (hBitmap)
|
|
{
|
|
|
|
BYTE *pbTemp = pdata->bits;
|
|
if (pbTemp + pdata->bitmap_1.dwCount > pBufferEnd)
|
|
{
|
|
Assert(0);
|
|
pdata->bitmap_1.bm = 0;
|
|
pdata->bitmap_1.dwCount = 0;
|
|
}
|
|
else
|
|
{
|
|
GetBitmapBits( hBitmap,
|
|
pdata->bitmap_1.dwCount,
|
|
pdata->bits );
|
|
|
|
}
|
|
}
|
|
|
|
if (hBitmap_2)
|
|
{
|
|
BYTE *pbTemp = &pdata->bits[pdata->bitmap_1.dwCount];
|
|
if (pbTemp + pdata->bitmap_2.dwCount > pBufferEnd)
|
|
{
|
|
Assert(0);
|
|
pdata->bitmap_2.bm = 0;
|
|
pdata->bitmap_2.dwCount = 0;
|
|
}
|
|
else
|
|
{
|
|
GetBitmapBits( hBitmap_2,
|
|
pdata->bitmap_2.dwCount,
|
|
&pdata->bits[pdata->bitmap_1.dwCount]);
|
|
}
|
|
}
|
|
|
|
pBuffer += Align( sizeof(struct MARSHAL_HBITMAP) + pdata->bitmap_1.dwCount + pdata->bitmap_2.dwCount);
|
|
|
|
}
|
|
else
|
|
{
|
|
// Sending a handle.
|
|
|
|
pdata->hdr.dwDataType = 0;
|
|
pdata->hdr.h = NULL;
|
|
pdata->hdr_2.dwDataType = 0;
|
|
pdata->hdr_2.h = NULL;
|
|
|
|
if (pHBitmap)
|
|
{
|
|
pdata->hdr.dwDataType = HANDLE_MARKER;
|
|
pdata->hdr.h = *pHBitmap;
|
|
|
|
pBuffer += Align( sizeof(struct MARSHAL_HDR<HBITMAP>) );
|
|
}
|
|
|
|
if (pHBitmap_2)
|
|
{
|
|
pdata->hdr_2.dwDataType = HANDLE_MARKER;
|
|
pdata->hdr_2.h = *pHBitmap_2;
|
|
|
|
pBuffer += Align( sizeof(struct MARSHAL_HDR<HBITMAP>) );
|
|
}
|
|
|
|
}
|
|
|
|
return( pBuffer );
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// HBITMAP_UserUnmarshallWorker
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
BYTE *Cic_HBITMAP_UserUnmarshal(BYTE *pBuffer, HBITMAP *pHBitmap, HBITMAP *pHBitmap_2)
|
|
{
|
|
HBITMAP hBitmap, hBitmap_2;
|
|
|
|
// Get Discriminant and handle. Caller checked for EOB.
|
|
struct MARSHAL_HBITMAP* pdata = (struct MARSHAL_HBITMAP*) pBuffer;
|
|
|
|
DWORD UnionDisc = pdata->hdr.dwDataType;
|
|
hBitmap = pdata->hdr.h;
|
|
|
|
if (!hBitmap)
|
|
{
|
|
if (!pHBitmap_2)
|
|
{
|
|
*pHBitmap = NULL;
|
|
return pBuffer;
|
|
}
|
|
|
|
UnionDisc = pdata->hdr_2.dwDataType;
|
|
}
|
|
|
|
hBitmap_2 = pdata->hdr_2.h ? (HBITMAP)pdata->hdr_2.h : NULL;
|
|
|
|
if ( IS_DATA_MARKER( UnionDisc) )
|
|
{
|
|
ULONG_PTR dwCount = 0;
|
|
ULONG_PTR dwCount_2 = 0;
|
|
|
|
if ( hBitmap )
|
|
{
|
|
dwCount = pdata->bitmap_1.dwCount;
|
|
|
|
// verify dwCount matches the bitmap.
|
|
if ( dwCount != (DWORD) pdata->bitmap_1.bm.bmPlanes *
|
|
pdata->bitmap_1.bm.bmHeight *
|
|
pdata->bitmap_1.bm.bmWidthBytes )
|
|
{
|
|
Assert(0);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
// Create a bitmap based on the BITMAP structure and the raw bits in
|
|
// the transmission buffer
|
|
|
|
if (pdata->bitmap_1.bm.bmBitsPixel == 0x20)
|
|
hBitmap = CreateDIB( pdata->bitmap_1.bm.bmWidth,
|
|
pdata->bitmap_1.bm.bmHeight,
|
|
pdata->bitmap_1.bm.bmWidthBytes,
|
|
pdata->bits, dwCount);
|
|
else
|
|
hBitmap = CreateBitmap( pdata->bitmap_1.bm.bmWidth,
|
|
pdata->bitmap_1.bm.bmHeight,
|
|
pdata->bitmap_1.bm.bmPlanes,
|
|
pdata->bitmap_1.bm.bmBitsPixel,
|
|
pdata->bits);
|
|
}
|
|
|
|
if (hBitmap_2)
|
|
{
|
|
dwCount_2 = pdata->bitmap_2.dwCount;
|
|
|
|
// verify dwCount_2 matches the bitmap.
|
|
if ( dwCount_2 != (DWORD) pdata->bitmap_2.bm.bmPlanes *
|
|
pdata->bitmap_2.bm.bmHeight *
|
|
pdata->bitmap_2.bm.bmWidthBytes )
|
|
{
|
|
Assert(0);
|
|
return NULL;
|
|
}
|
|
|
|
// Create a bitmap based on the BITMAP structure and the raw bits in
|
|
// the transmission buffer
|
|
|
|
if (pdata->bitmap_2.bm.bmBitsPixel == 0x20)
|
|
hBitmap_2 = CreateDIB( pdata->bitmap_2.bm.bmWidth,
|
|
pdata->bitmap_2.bm.bmHeight,
|
|
pdata->bitmap_2.bm.bmWidthBytes,
|
|
&pdata->bits[dwCount], dwCount_2);
|
|
else
|
|
hBitmap_2 = CreateBitmap( pdata->bitmap_2.bm.bmWidth,
|
|
pdata->bitmap_2.bm.bmHeight,
|
|
pdata->bitmap_2.bm.bmPlanes,
|
|
pdata->bitmap_2.bm.bmBitsPixel,
|
|
&pdata->bits[dwCount]);
|
|
}
|
|
|
|
|
|
pBuffer += Align( sizeof(struct MARSHAL_HBITMAP) + dwCount + dwCount_2 );
|
|
}
|
|
else if ( !IS_HANDLE_MARKER( UnionDisc ) )
|
|
{
|
|
Assert(0);
|
|
}
|
|
|
|
// A new bitmap handle is ready, destroy the old one, if needed.
|
|
|
|
if ( *pHBitmap )
|
|
DeleteObject( *pHBitmap );
|
|
|
|
*pHBitmap = hBitmap;
|
|
|
|
if ( pHBitmap_2 )
|
|
{
|
|
if ( *pHBitmap_2 )
|
|
DeleteObject( *pHBitmap_2 );
|
|
|
|
*pHBitmap_2 = hBitmap_2;
|
|
}
|
|
|
|
|
|
return( pBuffer );
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// HBITMAP_UserFree
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
void Cic_HBITMAP_UserFree(HBITMAP *pHBitmap, HBITMAP *pHBitmap_2)
|
|
{
|
|
if( pHBitmap && *pHBitmap )
|
|
{
|
|
if ( GDI_DATA_PASSING() )
|
|
{
|
|
DeleteObject( *pHBitmap );
|
|
}
|
|
}
|
|
|
|
if( pHBitmap_2 && *pHBitmap_2 )
|
|
{
|
|
if ( GDI_DATA_PASSING() )
|
|
{
|
|
DeleteObject( *pHBitmap_2 );
|
|
}
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// TF_LBBALLOON
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// UserSize
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
ULONG Cic_TF_LBBALLOONINFO_UserSize(TF_LBBALLOONINFO *pInfo)
|
|
{
|
|
ULONG ulRet;
|
|
|
|
ulRet = sizeof(TF_LBBALLOONINFO);
|
|
LENGTH_ALIGN(ulRet, CIC_ALIGNMENT);
|
|
|
|
if (pInfo->bstrText)
|
|
ulRet += (SysStringByteLen(pInfo->bstrText) + 2);
|
|
else
|
|
ulRet += 2;
|
|
|
|
LENGTH_ALIGN(ulRet, CIC_ALIGNMENT);
|
|
return ulRet;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// UserMarshal
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
BYTE *Cic_TF_LBBALLOONINFO_UserMarshal(BYTE *pBuf, TF_LBBALLOONINFO *pInfo)
|
|
{
|
|
if (!pInfo)
|
|
return pBuf;
|
|
|
|
memcpy(pBuf, pInfo, sizeof(TF_LBBALLOONINFO));
|
|
pBuf += sizeof(TF_LBBALLOONINFO);
|
|
POINTER_ALIGN( pBuf, CIC_ALIGNMENT);
|
|
if (pInfo->bstrText)
|
|
wcscpy((WCHAR *)pBuf, pInfo->bstrText);
|
|
|
|
|
|
pBuf += ((pInfo->bstrText ? wcslen(pInfo->bstrText) : 0) + 2);
|
|
POINTER_ALIGN( pBuf, CIC_ALIGNMENT);
|
|
return pBuf;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// UserUnMarshal
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
HRESULT Cic_TF_LBBALLOONINFO_UserUnmarshal(BYTE *pBuf, TF_LBBALLOONINFO *pInfo)
|
|
{
|
|
HRESULT hr;;
|
|
|
|
if (!pInfo)
|
|
return S_OK;
|
|
|
|
hr = S_OK;
|
|
|
|
memcpy(pInfo, pBuf, sizeof(TF_LBBALLOONINFO));
|
|
|
|
if (pInfo->bstrText)
|
|
{
|
|
BYTE *pTmp = pBuf + sizeof(TF_LBBALLOONINFO);
|
|
POINTER_ALIGN( pTmp, CIC_ALIGNMENT);
|
|
pInfo->bstrText = SysAllocString((WCHAR *)pTmp);
|
|
hr = (pInfo->bstrText != NULL) ? S_OK : E_OUTOFMEMORY;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// UserFree
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
void Cic_TF_LBBALLOONINFO_UserFree(TF_LBBALLOONINFO *pInfo)
|
|
{
|
|
if (pInfo->bstrText)
|
|
{
|
|
SysFreeString(pInfo->bstrText);
|
|
pInfo->bstrText = NULL;
|
|
}
|
|
}
|
|
|
|
// #########################################################################
|
|
//
|
|
// HICON
|
|
// See transmit.h for explanation of gdi data/handle passing.
|
|
//
|
|
// #########################################################################
|
|
|
|
struct ICONINFO_WOW64
|
|
{
|
|
// Identical ICONINFO structure.
|
|
|
|
BOOL fIcon;
|
|
DWORD xHotspot;
|
|
DWORD yHotspot;
|
|
CAlignWinHandle<HBITMAP> hbmMask;
|
|
CAlignWinHandle<HBITMAP> hbmColor;
|
|
|
|
void operator = (ICONINFO& a)
|
|
{
|
|
fIcon = a.fIcon;
|
|
xHotspot = a.xHotspot;
|
|
yHotspot = a.yHotspot;
|
|
hbmMask = a.hbmMask;
|
|
hbmColor = a.hbmColor;
|
|
}
|
|
|
|
};
|
|
|
|
struct MARSHAL_HICON
|
|
{
|
|
MARSHAL_HDR<HICON> hdr;
|
|
|
|
ICONINFO_WOW64 ic;
|
|
|
|
MARSHAL_HBITMAP bm;
|
|
};
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// UserSize
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
ULONG Cic_HICON_UserSize (HICON *pHIcon)
|
|
{
|
|
ULONG Offset = 0;
|
|
|
|
if ( !pHIcon )
|
|
return 0;
|
|
|
|
HICON hIcon = *pHIcon;
|
|
|
|
//
|
|
// The encapsulated union.
|
|
// Discriminant and then handle or pointer from the union arm.
|
|
// Union discriminant is 4 bytes + handle is represented by a long.
|
|
//
|
|
if ( ! *pHIcon )
|
|
return Align( sizeof(struct MARSHAL_HDR<HICON>) );
|
|
|
|
if ( ICON_DATA_PASSING() )
|
|
{
|
|
ICONINFO IconInfo;
|
|
ULONG ulBmpUserSize = 0;
|
|
if (!GetIconInfo(hIcon, &IconInfo))
|
|
return 0;
|
|
|
|
Offset += Align( sizeof(struct MARSHAL_HICON) );
|
|
|
|
//
|
|
// On NT4, CreateBitmap() can not create different device type
|
|
// bitmap. We convert the dc bitmap by calling DrawIconEx().
|
|
//
|
|
// We may want to use DIB section to marshal but marshaling and
|
|
// unmarshaling happens in same device so it does not have to
|
|
// convert bitmaps to DIB.
|
|
//
|
|
if (!IsOnNT5())
|
|
{
|
|
HBITMAP hbmp = NULL;
|
|
HBITMAP hbmpMask = NULL;
|
|
SIZE size;
|
|
BITMAP bmp;
|
|
|
|
if (!GetObject( IconInfo.hbmColor, sizeof(bmp), &bmp ))
|
|
{
|
|
Offset = 0;
|
|
goto DeleteAndExit;
|
|
}
|
|
|
|
size.cx = bmp.bmWidth;
|
|
size.cy = bmp.bmHeight;
|
|
Cic_GetIconBitmaps(*pHIcon, &hbmp, &hbmpMask, &size);
|
|
|
|
ulBmpUserSize = Cic_HBITMAP_UserSize(&hbmp, &hbmpMask);
|
|
if (!ulBmpUserSize)
|
|
{
|
|
Offset = 0;
|
|
goto DeleteAndExit;
|
|
}
|
|
|
|
Offset += ulBmpUserSize;
|
|
Offset = Align( Offset );
|
|
|
|
DeleteAndExit:
|
|
if (hbmp)
|
|
DeleteObject(hbmp);
|
|
if (hbmpMask)
|
|
DeleteObject(hbmpMask);
|
|
}
|
|
else
|
|
{
|
|
ulBmpUserSize = Cic_HBITMAP_UserSize(&IconInfo.hbmColor, &IconInfo.hbmMask);
|
|
if (!ulBmpUserSize)
|
|
{
|
|
Offset = 0;
|
|
goto Exit;
|
|
}
|
|
|
|
Offset += ulBmpUserSize;
|
|
Offset = Align( Offset );
|
|
|
|
}
|
|
Exit:
|
|
if (IconInfo.hbmColor)
|
|
DeleteObject(IconInfo.hbmColor);
|
|
if (IconInfo.hbmMask)
|
|
DeleteObject(IconInfo.hbmMask);
|
|
}
|
|
else
|
|
{
|
|
Offset += Align( sizeof(struct MARSHAL_HDR<HICON>) );
|
|
}
|
|
|
|
return( Offset ) ;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// HICON_UserMarshall
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
BYTE *Cic_HICON_UserMarshal(BYTE *pBuffer, BYTE *pBufferEnd, HICON *pHIcon)
|
|
{
|
|
if ( !pHIcon )
|
|
return pBuffer;
|
|
|
|
// Discriminant of the encapsulated union and union arm.
|
|
struct MARSHAL_HICON* pdata = (struct MARSHAL_HICON*) pBuffer;
|
|
|
|
if ( ICON_DATA_PASSING() )
|
|
{
|
|
pdata->hdr.dwDataType = DATA_MARKER;
|
|
pdata->hdr.h = *pHIcon;
|
|
|
|
if ( ! *pHIcon )
|
|
return pBuffer + Align( sizeof(struct MARSHAL_HDR<HICON>) );
|
|
|
|
//
|
|
// Get information about the bitmap
|
|
//
|
|
ICONINFO IconInfo;
|
|
|
|
if (!GetIconInfo(*pHIcon, &IconInfo))
|
|
memset(&IconInfo, 0, sizeof(IconInfo));
|
|
|
|
//
|
|
// Get the ic structure fields.
|
|
//
|
|
pdata->ic = IconInfo;
|
|
|
|
//
|
|
// On NT4, CreateBitmap() can not create different device type
|
|
// bitmap. We convert the dc bitmap by calling DrawIconEx().
|
|
//
|
|
// We may want to use DIB section to marshal but marshaling and
|
|
// unmarshaling happens in same device so it does not have to
|
|
// convert bitmaps to DIB.
|
|
//
|
|
if (!IsOnNT5())
|
|
{
|
|
HBITMAP hbmp = NULL;
|
|
HBITMAP hbmpMask = NULL;
|
|
SIZE size;
|
|
BITMAP bmp;
|
|
GetObject( IconInfo.hbmColor, sizeof(bmp), &bmp );
|
|
size.cx = bmp.bmWidth;
|
|
size.cy = bmp.bmHeight;
|
|
Cic_GetIconBitmaps(*pHIcon, &hbmp, &hbmpMask, &size);
|
|
|
|
pBuffer = Cic_HBITMAP_UserMarshal((BYTE*) &pdata->bm, pBufferEnd, &hbmp, &hbmpMask);
|
|
|
|
if (hbmp)
|
|
DeleteObject(hbmp);
|
|
if (hbmpMask)
|
|
DeleteObject(hbmpMask);
|
|
}
|
|
else
|
|
{
|
|
pBuffer = Cic_HBITMAP_UserMarshal((BYTE*) &pdata->bm, pBufferEnd, &IconInfo.hbmColor, &IconInfo.hbmMask);
|
|
}
|
|
if (IconInfo.hbmColor)
|
|
DeleteObject(IconInfo.hbmColor);
|
|
if (IconInfo.hbmColor)
|
|
DeleteObject(IconInfo.hbmMask);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// we need to make sure this pointer of the Icon is
|
|
// not a resource.
|
|
//
|
|
HICON hIcon = CopyIcon(*pHIcon);
|
|
if (hIcon)
|
|
DestroyIcon(*pHIcon);
|
|
else
|
|
hIcon = *pHIcon;
|
|
|
|
// Sending a handle.
|
|
|
|
pdata->hdr.dwDataType = HANDLE_MARKER;
|
|
pdata->hdr.h = hIcon;
|
|
|
|
pBuffer += Align( sizeof(struct MARSHAL_HDR<HICON>) );
|
|
|
|
}
|
|
|
|
return( pBuffer );
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// HICON_UserUnmarshallWorker
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
BYTE *Cic_HICON_UserUnmarshal(BYTE *pBuffer, HICON *pHIcon)
|
|
{
|
|
HICON hIcon = NULL;
|
|
|
|
// Get Discriminant and handle. Caller checked for EOB.
|
|
struct MARSHAL_HICON* pdata = (struct MARSHAL_HICON*) pBuffer;
|
|
|
|
DWORD UnionDisc = pdata->hdr.dwDataType;
|
|
hIcon = pdata->hdr.h;
|
|
|
|
if ( IS_DATA_MARKER( UnionDisc) )
|
|
{
|
|
if ( hIcon )
|
|
{
|
|
ICONINFO IconInfo;
|
|
IconInfo.fIcon = pdata->ic.fIcon;
|
|
IconInfo.xHotspot = pdata->ic.xHotspot;
|
|
IconInfo.yHotspot = pdata->ic.yHotspot;
|
|
IconInfo.hbmMask = pdata->ic.hbmMask;
|
|
IconInfo.hbmColor = pdata->ic.hbmColor;
|
|
|
|
//
|
|
// We just get the bitmap handle from marshaling buffer.
|
|
// And the marshaling buffer does not have a valid bitmap handle.
|
|
//
|
|
IconInfo.hbmColor = NULL;
|
|
IconInfo.hbmMask = NULL;
|
|
|
|
pBuffer = Cic_HBITMAP_UserUnmarshal((BYTE*) &pdata->bm, &IconInfo.hbmColor, &IconInfo.hbmMask);
|
|
if (pBuffer)
|
|
{
|
|
hIcon = CreateIconIndirect(&IconInfo);
|
|
}
|
|
|
|
if (IconInfo.hbmColor)
|
|
DeleteObject(IconInfo.hbmColor);
|
|
if (IconInfo.hbmMask)
|
|
DeleteObject(IconInfo.hbmMask);
|
|
}
|
|
}
|
|
else if ( !IS_HANDLE_MARKER( UnionDisc ) )
|
|
{
|
|
Assert(0);
|
|
}
|
|
|
|
// A new bitmap handle is ready, destroy the old one, if needed.
|
|
|
|
if ( *pHIcon )
|
|
DestroyIcon( *pHIcon );
|
|
|
|
*pHIcon = hIcon;
|
|
|
|
return( pBuffer );
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// HICON_UserFree
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
void Cic_HICON_UserFree(HICON *pHIcon)
|
|
{
|
|
if( pHIcon && *pHIcon )
|
|
{
|
|
if ( ICON_DATA_PASSING() )
|
|
{
|
|
DestroyIcon( *pHIcon );
|
|
}
|
|
}
|
|
}
|