276 lines
6.2 KiB
C++
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
|
|
|