windows-nt/Source/XPSP1/NT/windows/appcompat/shims/general/aliasdxdc.cpp
2020-09-26 16:20:57 +08:00

805 lines
16 KiB
C++

/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
AliasDXDC.cpp
Abstract:
Win2k used to cache DCs for surfaces. Apparently this no longer happens on
Whistler as the handles come back different on different calls to GetDC for
the same surface.
Our solution is to alias the handle returned from the IDirectDrawSurface::GetDC
and fix it up in the GDI functions that depend on it.
Notes:
This is a general purpose shim.
History:
12/02/2001 linstev Created
--*/
#include "precomp.h"
IMPLEMENT_SHIM_BEGIN(AliasDXDC)
#include "ShimHookMacro.h"
APIHOOK_ENUM_BEGIN
APIHOOK_ENUM_ENTRY_DIRECTX_COMSERVER()
APIHOOK_ENUM_ENTRY(BitBlt)
APIHOOK_ENUM_ENTRY(CreateDIBSection)
APIHOOK_ENUM_ENTRY(Ellipse)
APIHOOK_ENUM_ENTRY(GetCurrentObject)
APIHOOK_ENUM_ENTRY(GetDeviceCaps)
APIHOOK_ENUM_ENTRY(GetPixel)
APIHOOK_ENUM_ENTRY(SetPixel)
APIHOOK_ENUM_ENTRY(GetSystemPaletteEntries)
APIHOOK_ENUM_ENTRY(GetTextExtentPoint32A)
APIHOOK_ENUM_ENTRY(GetTextFaceA)
APIHOOK_ENUM_ENTRY(GetTextMetricsA)
APIHOOK_ENUM_ENTRY(LineTo)
APIHOOK_ENUM_ENTRY(MoveToEx)
APIHOOK_ENUM_ENTRY(RealizePalette)
APIHOOK_ENUM_ENTRY(Rectangle)
APIHOOK_ENUM_ENTRY(SelectObject)
APIHOOK_ENUM_ENTRY(SelectPalette)
APIHOOK_ENUM_ENTRY(SetDIBColorTable)
APIHOOK_ENUM_ENTRY(SetStretchBltMode)
APIHOOK_ENUM_ENTRY(SetSystemPaletteUse)
APIHOOK_ENUM_ENTRY(StretchBlt)
APIHOOK_ENUM_ENTRY(StretchDIBits)
APIHOOK_ENUM_ENTRY(TextOutA)
APIHOOK_ENUM_END
IMPLEMENT_DIRECTX_COMSERVER_HOOKS()
#define ALIASDC (HDC) 0x42
HDC g_hDcLast = 0;
/*++
UnAlias the DC if required.
--*/
HDC FixDC(HDC hdc)
{
if (hdc == ALIASDC) {
return g_hDcLast;
} else {
return hdc;
}
}
/*++
Hook create surface so we can be sure we're being called.
--*/
HRESULT
COMHOOK(IDirectDraw, CreateSurface)(
PVOID pThis,
LPDDSURFACEDESC lpDDSurfaceDesc,
LPDIRECTDRAWSURFACE* lplpDDSurface,
IUnknown* pUnkOuter
)
{
HRESULT hReturn;
_pfn_IDirectDraw_CreateSurface pfnOld =
ORIGINAL_COM(IDirectDraw, CreateSurface, pThis);
if (SUCCEEDED(hReturn = (*pfnOld)(
pThis,
lpDDSurfaceDesc,
lplpDDSurface,
pUnkOuter)))
{
HookObject(
NULL,
IID_IDirectDrawSurface,
(PVOID*)lplpDDSurface,
NULL,
FALSE);
}
return hReturn;
}
/*++
Hook create surface so we can be sure we're being called.
--*/
HRESULT
COMHOOK(IDirectDraw2, CreateSurface)(
PVOID pThis,
LPDDSURFACEDESC lpDDSurfaceDesc,
LPDIRECTDRAWSURFACE* lplpDDSurface,
IUnknown* pUnkOuter
)
{
HRESULT hReturn;
_pfn_IDirectDraw2_CreateSurface pfnOld =
ORIGINAL_COM(IDirectDraw2, CreateSurface, pThis);
if (SUCCEEDED(hReturn = (*pfnOld)(
pThis,
lpDDSurfaceDesc,
lplpDDSurface,
pUnkOuter)))
{
HookObject(
NULL,
IID_IDirectDrawSurface2,
(PVOID*)lplpDDSurface,
NULL,
FALSE);
}
return hReturn;
}
/*++
Hook create surface so we can be sure we're being called.
--*/
HRESULT
COMHOOK(IDirectDraw4, CreateSurface)(
PVOID pThis,
LPDDSURFACEDESC2 lpDDSurfaceDesc,
LPDIRECTDRAWSURFACE* lplpDDSurface,
IUnknown* pUnkOuter
)
{
HRESULT hReturn;
_pfn_IDirectDraw4_CreateSurface pfnOld =
ORIGINAL_COM(IDirectDraw4, CreateSurface, pThis);
if (SUCCEEDED(hReturn = (*pfnOld)(
pThis,
lpDDSurfaceDesc,
lplpDDSurface,
pUnkOuter)))
{
HookObject(
NULL,
IID_IDirectDrawSurface4,
(PVOID*)lplpDDSurface,
NULL,
FALSE);
}
return hReturn;
}
/*++
Hook create surface so we can be sure we're being called.
--*/
HRESULT
COMHOOK(IDirectDraw7, CreateSurface)(
PVOID pThis,
LPDDSURFACEDESC2 lpDDSurfaceDesc,
LPDIRECTDRAWSURFACE* lplpDDSurface,
IUnknown* pUnkOuter
)
{
HRESULT hReturn;
_pfn_IDirectDraw7_CreateSurface pfnOld =
ORIGINAL_COM(IDirectDraw7, CreateSurface, pThis);
if (SUCCEEDED(hReturn = (*pfnOld)(
pThis,
lpDDSurfaceDesc,
lplpDDSurface,
pUnkOuter)))
{
HookObject(
NULL,
IID_IDirectDrawSurface7,
(PVOID*)lplpDDSurface,
NULL,
FALSE);
}
return hReturn;
}
/*++
Get the DC
--*/
HRESULT
COMHOOK(IDirectDrawSurface, GetDC)(
LPDIRECTDRAWSURFACE lpDDSurface,
HDC FAR *lphDC
)
{
HRESULT hReturn;
_pfn_IDirectDrawSurface_GetDC pfnOld =
ORIGINAL_COM(IDirectDrawSurface, GetDC, (LPVOID) lpDDSurface);
if (SUCCEEDED(hReturn = (*pfnOld)(
lpDDSurface,
lphDC)))
{
g_hDcLast = *lphDC;
*lphDC = ALIASDC;
DPFN( eDbgLevelWarning, "[Surface_GetDC] Acquired DC %08lx", g_hDcLast);
}
return hReturn;
}
/*++
Get the DC
--*/
HRESULT
COMHOOK(IDirectDrawSurface2, GetDC)(
LPDIRECTDRAWSURFACE lpDDSurface,
HDC FAR *lphDC
)
{
HRESULT hReturn;
_pfn_IDirectDrawSurface2_GetDC pfnOld =
ORIGINAL_COM(IDirectDrawSurface2, GetDC, (LPVOID) lpDDSurface);
if (SUCCEEDED(hReturn = (*pfnOld)(
lpDDSurface,
lphDC)))
{
g_hDcLast = *lphDC;
*lphDC = ALIASDC;
DPFN( eDbgLevelWarning, "[Surface_GetDC2] Acquired DC %08lx", g_hDcLast);
}
return hReturn;
}
/*++
Get the DC
--*/
HRESULT
COMHOOK(IDirectDrawSurface4, GetDC)(
LPDIRECTDRAWSURFACE lpDDSurface,
HDC FAR *lphDC
)
{
HRESULT hReturn;
_pfn_IDirectDrawSurface4_GetDC pfnOld =
ORIGINAL_COM(IDirectDrawSurface4, GetDC, (LPVOID) lpDDSurface);
if (SUCCEEDED(hReturn = (*pfnOld)(
lpDDSurface,
lphDC)))
{
g_hDcLast = *lphDC;
*lphDC = ALIASDC;
DPFN( eDbgLevelWarning, "[Surface_GetDC4] Acquired DC %08lx", g_hDcLast);
}
return hReturn;
}
/*++
Get the DC
--*/
HRESULT
COMHOOK(IDirectDrawSurface7, GetDC)(
LPDIRECTDRAWSURFACE lpDDSurface,
HDC FAR *lphDC
)
{
HRESULT hReturn;
_pfn_IDirectDrawSurface7_GetDC pfnOld =
ORIGINAL_COM(IDirectDrawSurface7, GetDC, (LPVOID) lpDDSurface);
if (SUCCEEDED(hReturn = (*pfnOld)(
lpDDSurface,
lphDC)))
{
g_hDcLast = *lphDC;
*lphDC = ALIASDC;
DPFN( eDbgLevelWarning, "[Surface_GetDC7] Acquired DC %08lx", g_hDcLast);
}
return hReturn;
}
/*++
ReleaseDC the DC
--*/
HRESULT
COMHOOK(IDirectDrawSurface, ReleaseDC)(
LPDIRECTDRAWSURFACE lpDDSurface,
HDC hDC
)
{
HRESULT hReturn = DDERR_GENERIC;
_pfn_IDirectDrawSurface_ReleaseDC pfnOld =
ORIGINAL_COM(IDirectDrawSurface, ReleaseDC, (LPVOID) lpDDSurface);
if (hDC == ALIASDC)
{
hDC = g_hDcLast;
if (SUCCEEDED(hReturn = (*pfnOld)(lpDDSurface, hDC)))
{
DPFN( eDbgLevelWarning, "[Surface_ReleaseDC] Released DC %08lx", g_hDcLast);
g_hDcLast = 0;
}
}
else
{
hReturn = (*pfnOld)(lpDDSurface, hDC);
}
return hReturn;
}
/*++
ReleaseDC the DC
--*/
HRESULT
COMHOOK(IDirectDrawSurface2, ReleaseDC)(
LPDIRECTDRAWSURFACE lpDDSurface,
HDC hDC
)
{
HRESULT hReturn = DDERR_GENERIC;
_pfn_IDirectDrawSurface2_ReleaseDC pfnOld =
ORIGINAL_COM(IDirectDrawSurface2, ReleaseDC, (LPVOID) lpDDSurface);
if (hDC == ALIASDC)
{
hDC = g_hDcLast;
if (SUCCEEDED(hReturn = (*pfnOld)(lpDDSurface, hDC)))
{
DPFN( eDbgLevelWarning, "[Surface_ReleaseDC2] Released DC %08lx", g_hDcLast);
g_hDcLast = 0;
}
}
else
{
hReturn = (*pfnOld)(lpDDSurface, hDC);
}
return hReturn;
}
/*++
ReleaseDC the DC
--*/
HRESULT
COMHOOK(IDirectDrawSurface4, ReleaseDC)(
LPDIRECTDRAWSURFACE lpDDSurface,
HDC hDC
)
{
HRESULT hReturn = DDERR_GENERIC;
_pfn_IDirectDrawSurface4_ReleaseDC pfnOld =
ORIGINAL_COM(IDirectDrawSurface4, ReleaseDC, (LPVOID) lpDDSurface);
if (hDC == ALIASDC)
{
hDC = g_hDcLast;
if (SUCCEEDED(hReturn = (*pfnOld)(lpDDSurface, hDC)))
{
DPFN( eDbgLevelWarning, "[Surface_ReleaseDC4] Released DC %08lx", g_hDcLast);
g_hDcLast = 0;
}
}
else
{
hReturn = (*pfnOld)(lpDDSurface, hDC);
}
return hReturn;
}
/*++
ReleaseDC the DC
--*/
HRESULT
COMHOOK(IDirectDrawSurface7, ReleaseDC)(
LPDIRECTDRAWSURFACE lpDDSurface,
HDC hDC
)
{
HRESULT hReturn = DDERR_GENERIC;
_pfn_IDirectDrawSurface7_ReleaseDC pfnOld =
ORIGINAL_COM(IDirectDrawSurface7, ReleaseDC, (LPVOID) lpDDSurface);
if (hDC == ALIASDC)
{
hDC = g_hDcLast;
if (SUCCEEDED(hReturn = (*pfnOld)(lpDDSurface, hDC)))
{
DPFN( eDbgLevelWarning, "[Surface_ReleaseDC7] Released DC %08lx", g_hDcLast);
g_hDcLast = 0;
}
}
else
{
hReturn = (*pfnOld)(lpDDSurface, hDC);
}
return hReturn;
}
/*++
Unalias the DC.
--*/
BOOL
APIHOOK(BitBlt)(
HDC hdcDest,
int nXDest,
int nYDest,
int nWidth,
int nHeight,
HDC hdcSrc,
int nXSrc,
int nYSrc,
DWORD dwRop
)
{
return ORIGINAL_API(BitBlt)(FixDC(hdcDest), nXDest, nYDest, nWidth,
nHeight, FixDC(hdcSrc), nXSrc, nYSrc, dwRop);
}
HBITMAP
APIHOOK(CreateDIBSection)(
HDC hdc,
CONST BITMAPINFO *pbmi,
UINT iUsage,
VOID *ppvBits,
HANDLE hSection,
DWORD dwOffset
)
{
return ORIGINAL_API(CreateDIBSection)(FixDC(hdc), pbmi, iUsage, ppvBits, hSection,
dwOffset);
}
BOOL
APIHOOK(Ellipse)(
HDC hdc,
int nLeftRect,
int nTopRect,
int nRightRect,
int nBottomRect
)
{
return ORIGINAL_API(Ellipse)(FixDC(hdc), nLeftRect, nTopRect, nRightRect,
nBottomRect);
}
HGDIOBJ
APIHOOK(GetCurrentObject)(
HDC hdc,
UINT uObjectType
)
{
return ORIGINAL_API(GetCurrentObject)(FixDC(hdc), uObjectType);
}
int
APIHOOK(GetDeviceCaps)(
HDC hdc,
int nIndex
)
{
return ORIGINAL_API(GetDeviceCaps)(FixDC(hdc), nIndex);
}
COLORREF
APIHOOK(GetPixel)(
HDC hdc,
int XPos,
int nYPos
)
{
return ORIGINAL_API(GetPixel)(FixDC(hdc), XPos, nYPos);
}
COLORREF
APIHOOK(SetPixel)(
HDC hdc,
int XPos,
int nYPos,
COLORREF crColor
)
{
return ORIGINAL_API(SetPixel)(FixDC(hdc), XPos, nYPos, crColor);
}
UINT
APIHOOK(GetSystemPaletteEntries)(
HDC hdc,
UINT iStartIndex,
UINT nEntries,
LPPALETTEENTRY lppe
)
{
return ORIGINAL_API(GetSystemPaletteEntries)(FixDC(hdc), iStartIndex,
nEntries, lppe);
}
BOOL
APIHOOK(GetTextExtentPoint32A)(
HDC hdc,
LPCSTR lpString,
int cbString,
LPSIZE lpSize
)
{
return ORIGINAL_API(GetTextExtentPoint32A)(FixDC(hdc), lpString, cbString, lpSize);
}
int
APIHOOK(GetTextFaceA)(
HDC hdc,
int nCount,
LPSTR lpFaceName
)
{
return ORIGINAL_API(GetTextFaceA)(FixDC(hdc), nCount, lpFaceName);
}
BOOL
APIHOOK(GetTextMetricsA)(
HDC hdc,
LPTEXTMETRICA lptm
)
{
return ORIGINAL_API(GetTextMetricsA)(FixDC(hdc), lptm);
}
BOOL
APIHOOK(LineTo)(
HDC hdc,
int nXEnd,
int nYEnd
)
{
return ORIGINAL_API(LineTo)(FixDC(hdc), nXEnd, nYEnd);
}
BOOL
APIHOOK(MoveToEx)(
HDC hdc,
int X,
int Y,
LPPOINT lpPoint
)
{
return ORIGINAL_API(MoveToEx)(FixDC(hdc), X, Y, lpPoint);
}
UINT
APIHOOK(RealizePalette)(HDC hdc)
{
return ORIGINAL_API(RealizePalette)(FixDC(hdc));
}
BOOL
APIHOOK(Rectangle)(
HDC hdc,
int nLeftRect,
int nTopRect,
int nRightRect,
int nBottomRect
)
{
return ORIGINAL_API(Rectangle)(FixDC(hdc), nLeftRect, nTopRect, nRightRect,
nBottomRect);
}
HGDIOBJ
APIHOOK(SelectObject)(
HDC hdc,
HGDIOBJ hgdiobj
)
{
return ORIGINAL_API(SelectObject)(FixDC(hdc), hgdiobj);
}
HPALETTE
APIHOOK(SelectPalette)(
HDC hdc,
HPALETTE hpal,
BOOL bForceBackground
)
{
return ORIGINAL_API(SelectPalette)(FixDC(hdc), hpal, bForceBackground);
}
UINT
APIHOOK(SetDIBColorTable)(
HDC hdc,
UINT uStartIndex,
UINT cEntries,
CONST RGBQUAD *pColors
)
{
return ORIGINAL_API(SetDIBColorTable)(FixDC(hdc), uStartIndex, cEntries,
pColors);
}
int
APIHOOK(SetStretchBltMode)(
HDC hdc,
int iStretchMode
)
{
return ORIGINAL_API(SetStretchBltMode)(FixDC(hdc), iStretchMode);
}
UINT
APIHOOK(SetSystemPaletteUse)(
HDC hdc,
UINT uUsage
)
{
return ORIGINAL_API(SetSystemPaletteUse)(FixDC(hdc), uUsage);
}
BOOL
APIHOOK(StretchBlt)(
HDC hdcDest,
int nXOriginDest,
int nYOriginDest,
int nWidthDest,
int nHeightDest,
HDC hdcSrc,
int nXOriginSrc,
int nYOriginSrc,
int nWidthSrc,
int nHeightSrc,
DWORD dwRop
)
{
return ORIGINAL_API(StretchBlt)(FixDC(hdcDest), nXOriginDest, nYOriginDest,
nWidthDest, nHeightDest, FixDC(hdcSrc), nXOriginSrc, nYOriginSrc,
nWidthSrc, nHeightSrc, dwRop);
}
int
APIHOOK(StretchDIBits)(
HDC hdc,
int XDest,
int YDest,
int nDestWidth,
int nDestHeight,
int XSrc,
int YSrc,
int nSrcWidth,
int nSrcHeight,
CONST VOID *lpBits,
CONST BITMAPINFO *lpBitsInfo,
UINT iUsage,
DWORD dwRop
)
{
return ORIGINAL_API(StretchDIBits)(FixDC(hdc), XDest, YDest, nDestWidth,
nDestHeight, XSrc, YSrc, nSrcWidth, nSrcHeight, lpBits, lpBitsInfo,
iUsage, dwRop);
}
BOOL
APIHOOK(TextOutA)(
HDC hdc,
int nXStart,
int nYStart,
LPCSTR lpString,
int cbString
)
{
return ORIGINAL_API(TextOutA)(FixDC(hdc), nXStart, nYStart, lpString, cbString);
}
/*++
Register hooked functions
--*/
HOOK_BEGIN
APIHOOK_ENTRY_DIRECTX_COMSERVER()
COMHOOK_ENTRY(DirectDraw, IDirectDraw, CreateSurface, 6)
COMHOOK_ENTRY(DirectDraw, IDirectDraw2, CreateSurface, 6)
COMHOOK_ENTRY(DirectDraw, IDirectDraw4, CreateSurface, 6)
COMHOOK_ENTRY(DirectDraw, IDirectDraw7, CreateSurface, 6)
COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface, GetDC, 17)
COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface2, GetDC, 17)
COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface4, GetDC, 17)
COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface7, GetDC, 17)
COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface, ReleaseDC, 26)
COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface2, ReleaseDC, 26)
COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface4, ReleaseDC, 26)
COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface7, ReleaseDC, 26)
APIHOOK_ENTRY(GDI32.DLL, BitBlt)
APIHOOK_ENTRY(GDI32.DLL, CreateDIBSection)
APIHOOK_ENTRY(GDI32.DLL, Ellipse)
APIHOOK_ENTRY(GDI32.DLL, GetCurrentObject)
APIHOOK_ENTRY(GDI32.DLL, GetDeviceCaps)
APIHOOK_ENTRY(GDI32.DLL, GetPixel)
APIHOOK_ENTRY(GDI32.DLL, SetPixel)
APIHOOK_ENTRY(GDI32.DLL, GetSystemPaletteEntries)
APIHOOK_ENTRY(GDI32.DLL, GetTextExtentPoint32A)
APIHOOK_ENTRY(GDI32.DLL, GetTextFaceA)
APIHOOK_ENTRY(GDI32.DLL, GetTextMetricsA)
APIHOOK_ENTRY(GDI32.DLL, LineTo)
APIHOOK_ENTRY(GDI32.DLL, MoveToEx)
APIHOOK_ENTRY(GDI32.DLL, RealizePalette)
APIHOOK_ENTRY(GDI32.DLL, Rectangle)
APIHOOK_ENTRY(GDI32.DLL, SelectObject)
APIHOOK_ENTRY(GDI32.DLL, SelectPalette)
APIHOOK_ENTRY(GDI32.DLL, SetDIBColorTable)
APIHOOK_ENTRY(GDI32.DLL, SetStretchBltMode)
APIHOOK_ENTRY(GDI32.DLL, SetSystemPaletteUse)
APIHOOK_ENTRY(GDI32.DLL, StretchBlt)
APIHOOK_ENTRY(GDI32.DLL, StretchDIBits)
APIHOOK_ENTRY(GDI32.DLL, TextOutA)
HOOK_END
IMPLEMENT_SHIM_END