|
|
/*==========================================================================
* * 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); }
|