Leaked source code of windows server 2003
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.
 
 
 
 
 
 

197 lines
5.3 KiB

/*==========================================================================
*
* Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
*
* File: dibpatch.c
* Content: Code to patch the DIB engine to correct problems with using
* the VRAM bit to disable the video card's accelerator.
*
*@@BEGIN_MSINTERNAL
* History:
* Date By Reason
* ==== == ======
* 13-Sep-96 colinmc initial implementation
* 31-jan-97 colinmc Bug 5457: Fixed Win16 lock problem causing hang
* with mutliple AMovie instances on old cards
*@@END_MSINTERNAL
*
***************************************************************************/
#include "ddraw16.h"
extern UINT FAR PASCAL AllocCStoDSAlias(UINT);
#define DIBENGMODULE "DIBENG"
#define EXTTEXTOUTENTRYPOINT "DIB_EXTTEXTOUTEXT"
#define EXTTEXTOUTPATCHOFFSET 136
char szExtTextOutMagic[] = "\x74\x0a\xf7\x86\x60\xff\x00\x80";
char szExtTextOutPatch[] = "\x90\x90\x90\x90\x90\x90\x90\x90";
LPVOID GetModifiableCodeAddress(LPCSTR lpszModuleName, LPCSTR lpszEntryPointName)
{
HMODULE hModule;
FARPROC fpEntryPoint;
LPVOID lpCodeAddress;
hModule = GetModuleHandle(lpszModuleName);
if (NULL == hModule)
{
DPF(0, "DIB Engine not loaded");
return NULL;
}
fpEntryPoint = GetProcAddress(hModule, lpszEntryPointName);
if (NULL == fpEntryPoint)
{
DPF(0, "Could not locate DIB engine's ExtTextOut entry point");
return FALSE;
}
lpCodeAddress = (LPVOID)MAKELP(AllocCStoDSAlias(SELECTOROF(fpEntryPoint)), OFFSETOF(fpEntryPoint));
if (NULL == lpCodeAddress)
{
DPF(0, "Could not allocate data segment alias for code segment");
return FALSE;
}
return lpCodeAddress;
}
#define FREEMODIFIABLECODEADDRESS(lpCodeAddress) FreeSelector(SELECTOROF(lpCodeAddress))
BOOL ValidateDIBEngine(void)
{
LPBYTE lpCodeAddress;
LPBYTE lpMagicAddress;
BOOL fDIBEngineOK;
/*
* Get a pointer to the ExtTextOut code.
*/
lpCodeAddress = (LPBYTE)GetModifiableCodeAddress(DIBENGMODULE, EXTTEXTOUTENTRYPOINT);
if (NULL == lpCodeAddress)
return FALSE;
/*
* Move to the patch address.
*/
lpMagicAddress = lpCodeAddress + EXTTEXTOUTPATCHOFFSET;
/*
* Verify that the data at the patch address is the stuff we want to replace.
*/
fDIBEngineOK = (!_fmemcmp(lpMagicAddress, szExtTextOutMagic, sizeof(szExtTextOutMagic) - 1));
if (!fDIBEngineOK)
{
/*
* Couldn't find the signature bytes we are looking for. This might be because we
* already patched it. So check for the no-ops.
*/
fDIBEngineOK = (!_fmemcmp(lpMagicAddress, szExtTextOutPatch, sizeof(szExtTextOutPatch) - 1));
}
#ifdef DEBUG
if (!fDIBEngineOK)
DPF(2, "DIB Engine does not match magic or patch - different version?");
#endif
FREEMODIFIABLECODEADDRESS(lpMagicAddress);
return fDIBEngineOK;
}
BOOL PatchDIBEngineExtTextOut(BOOL fPatch)
{
LPBYTE lpCodeAddress;
LPBYTE lpMagicAddress;
/*
* Get a pointer to the ExtTextOut code.
*/
lpCodeAddress = (LPBYTE)GetModifiableCodeAddress(DIBENGMODULE, EXTTEXTOUTENTRYPOINT);
if (NULL == lpCodeAddress)
return FALSE;
/*
* Move to the patch address.
*/
lpMagicAddress = lpCodeAddress + EXTTEXTOUTPATCHOFFSET;
if (fPatch)
{
/*
* Don't do anything if its already patched.
*/
if (_fmemcmp(lpMagicAddress, szExtTextOutPatch, sizeof(szExtTextOutPatch) - 1))
{
/*
* Be very sure we know we are dealing with a DIB engine we can handle.
*/
if (_fmemcmp(lpMagicAddress, szExtTextOutMagic, sizeof(szExtTextOutMagic) - 1))
{
DPF(1, "Unknown DIB Engine. not fixing up");
FREEMODIFIABLECODEADDRESS(lpMagicAddress);
return FALSE;
}
/*
* Replace the offending code with NOPs.
*/
_fmemcpy(lpMagicAddress, szExtTextOutPatch, sizeof(szExtTextOutPatch) - 1);
}
}
else
{
/*
* Don't do anything if its already unpatched.
*/
if (!_fmemcmp(lpMagicAddress, szExtTextOutMagic, sizeof(szExtTextOutMagic) - 1))
{
/*
* Be very sure we know we are dealing with a DIB engine we can handle.
*/
if (_fmemcmp(lpMagicAddress, szExtTextOutPatch, sizeof(szExtTextOutPatch) - 1))
{
DPF(1, "Unknown DIB Engine. not fixing up");
FREEMODIFIABLECODEADDRESS(lpMagicAddress);
return FALSE;
}
/*
* Put the original code back.
*/
_fmemcpy(lpMagicAddress, szExtTextOutMagic, sizeof(szExtTextOutMagic) - 1);
}
}
FREEMODIFIABLECODEADDRESS(lpMagicAddress);
return TRUE;
}
BOOL DDAPI DD16_FixupDIBEngine(void)
{
/*
* Is this Win 4.1 (or higher)
*/
OSVERSIONINFO ver = {sizeof(OSVERSIONINFO)};
GetVersionEx(&ver);
if (ver.dwMajorVersion > 4 ||
(ver.dwMajorVersion == 4 && ver.dwMinorVersion >= 10))
{
return TRUE;
}
/*
* Is this a DIB engine version we can work with?
*/
if( !ValidateDIBEngine() )
return FALSE;
/*
* It is the correct version. So fix it up. Currently all this
* involves is patching the ExtTextOut routine.
*/
return PatchDIBEngineExtTextOut(TRUE);
}