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

276 lines
6.2 KiB
C++

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
EuropeanAirWar.cpp
Abstract:
European Air War takes advantage of the fact GDI and DDRAW affect separate
palettes in win98. This causes a problem on win2k when EAW calls
GetSystemPaletteEntries and expects the original GDI palette, but in win2k
it has be faded to black by DDRAW. This fix restores the system palette at
a convienient spot in SetSystemPaletteUse. It also sets SYSPAL_STATIC
before creating dialog boxes.
In addition this corrects an install problem that occurs when setting the
path for the readme file in a start->programs shortcut.
Notes:
This is an app specific shim and should NOT be
included in the layer.
History:
10/23/2000 linstev Created
10/23/2000 mnikkel Modified
--*/
#include "precomp.h"
IMPLEMENT_SHIM_BEGIN(EuropeanAirWar)
#include "ShimHookMacro.h"
APIHOOK_ENUM_BEGIN
APIHOOK_ENUM_ENTRY(SetSystemPaletteUse)
APIHOOK_ENUM_ENTRY(DialogBoxParamA)
APIHOOK_ENUM_ENTRY_COMSERVER(SHELL32)
APIHOOK_ENUM_END
IMPLEMENT_COMSERVER_HOOK(SHELL32)
CString * g_csArgBuffer = NULL;
/*++
Retrieve the system palette and set the palette entries flag so the palette is
updated correctly.
--*/
UINT
APIHOOK(SetSystemPaletteUse)(
HDC hdc,
UINT uUsage
)
{
UINT iRet = ORIGINAL_API(SetSystemPaletteUse)(hdc, uUsage);
int i;
HDC hdcnew;
HPALETTE hpal, hpalold;
LPLOGPALETTE plogpal;
// Create a palette we can realize
plogpal = (LPLOGPALETTE) malloc(sizeof(LOGPALETTE) + sizeof(PALETTEENTRY)*256);
if ( plogpal )
{
LOGN( eDbgLevelError, "[EuropeanAirWar] APIHook_SetSystemPaletteUse reseting palette");
plogpal->palVersion = 0x0300;
plogpal->palNumEntries = 256;
hdcnew = GetDC(0);
GetSystemPaletteEntries(hdcnew, 0, 256, &plogpal->palPalEntry[0]);
for (i=0; i<256; i++)
{
plogpal->palPalEntry[i].peFlags = PC_RESERVED | PC_NOCOLLAPSE;
}
// Realize the palette
hpal = CreatePalette(plogpal);
hpalold = SelectPalette(hdcnew, hpal, FALSE);
RealizePalette(hdcnew);
SelectPalette(hdcnew, hpalold, FALSE);
DeleteObject(hpal);
ReleaseDC(0, hdcnew);
free(plogpal);
}
else
{
LOGN( eDbgLevelError, "[EuropeanAirWar] APIHook_SetSystemPaletteUse failed to allocate memory");
}
return iRet;
}
/*++
Set the Palette Use to static before creating a dialog box.
--*/
int
APIHOOK(DialogBoxParamA)(
HINSTANCE hInstance,
LPCSTR lpTemplateName,
HWND hWndParent,
DLGPROC lpDialogFunc,
LPARAM dwInitParam
)
{
int iRet;
HDC hdc;
LOGN( eDbgLevelError, "[EuropeanAirWar] APIHook_DialogBoxParamA setting palette static for dialog box");
// Set the palette use to static to prevent
// any color changes in the dialog box.
if (hdc = GetDC(0))
{
SetSystemPaletteUse(hdc, SYSPAL_STATIC);
ReleaseDC(0, hdc);
}
iRet = ORIGINAL_API(DialogBoxParamA)(
hInstance,
lpTemplateName,
hWndParent,
lpDialogFunc,
dwInitParam);
// Reset the palette use to NoStatic256
// after dialog box has been displayed.
// use 256 to prevent white dot artifacts.
if (hdc = GetDC(0))
{
SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC256);
ReleaseDC(0, hdc);
}
return iRet;
}
/*++
Catch IShellLink::SetPathA and correct the wordpad path
--*/
HRESULT
COMHOOK(IShellLinkA, SetPath)(
PVOID pThis,
LPCSTR pszFile
)
{
HRESULT hrReturn = E_FAIL;
PCHAR pStr= NULL;
CHAR szBuffer[MAX_PATH];
_pfn_IShellLinkA_SetPath pfnOld = ORIGINAL_COM(IShellLinkA, SetPath, pThis);
if ( pfnOld )
{
CSTRING_TRY
{
// pszFile = "c:\windows\wordpad.exe command line arguments"
// Strip off the arguments and save them for when they call IShellLinkA::SetArguments
CString csFile(pszFile);
int nWordpadIndex = csFile.Find(L"wordpad.exe");
if (nWordpadIndex >= 0)
{
// Find the first space after wordpad.exe
int nSpaceIndex = csFile.Find(L' ', nWordpadIndex);
if (nSpaceIndex >= 0)
{
// Save the cl args in g_csArgBuffer
g_csArgBuffer = new CString;
if (g_csArgBuffer)
{
csFile.Mid(nSpaceIndex, *g_csArgBuffer); // includes the space
csFile.Truncate(nSpaceIndex);
}
}
hrReturn = (*pfnOld)( pThis, csFile.GetAnsi() );
return hrReturn;
}
}
CSTRING_CATCH
{
// Do nothing
}
hrReturn = (*pfnOld)( pThis, pszFile );
}
return hrReturn;
}
/*++
Catch IShellLink::SetArguments and correct the readme path.
--*/
HRESULT
COMHOOK(IShellLinkA, SetArguments)(
PVOID pThis,
LPCSTR pszArgs
)
{
HRESULT hrReturn = E_FAIL;
_pfn_IShellLinkA_SetArguments pfnOld = ORIGINAL_COM(IShellLinkA, SetArguments, pThis);
if (pfnOld)
{
if (g_csArgBuffer && !g_csArgBuffer->IsEmpty())
{
CSTRING_TRY
{
CString csArgs(pszArgs);
*g_csArgBuffer += L" ";
*g_csArgBuffer += csArgs;
hrReturn = (*pfnOld)( pThis, g_csArgBuffer->GetAnsi() );
// Delete the buffer so we don't add these args to everthing
delete g_csArgBuffer;
g_csArgBuffer = NULL;
return hrReturn;
}
CSTRING_CATCH
{
// Do Nothing
}
}
hrReturn = (*pfnOld)( pThis, pszArgs );
}
return hrReturn;
}
/*++
Register hooked functions
--*/
HOOK_BEGIN
APIHOOK_ENTRY(GDI32.DLL, SetSystemPaletteUse)
APIHOOK_ENTRY(USER32.DLL, DialogBoxParamA)
APIHOOK_ENTRY_COMSERVER(SHELL32)
COMHOOK_ENTRY(ShellLink, IShellLinkA, SetPath, 20)
COMHOOK_ENTRY(ShellLink, IShellLinkA, SetArguments, 11)
HOOK_END
IMPLEMENT_SHIM_END