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

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dibpatch.c
  6. * Content: Code to patch the DIB engine to correct problems with using
  7. * the VRAM bit to disable the video card's accelerator.
  8. *
  9. *@@BEGIN_MSINTERNAL
  10. * History:
  11. * Date By Reason
  12. * ==== == ======
  13. * 13-Sep-96 colinmc initial implementation
  14. * 31-jan-97 colinmc Bug 5457: Fixed Win16 lock problem causing hang
  15. * with mutliple AMovie instances on old cards
  16. *@@END_MSINTERNAL
  17. *
  18. ***************************************************************************/
  19. #include "ddraw16.h"
  20. extern UINT FAR PASCAL AllocCStoDSAlias(UINT);
  21. #define DIBENGMODULE "DIBENG"
  22. #define EXTTEXTOUTENTRYPOINT "DIB_EXTTEXTOUTEXT"
  23. #define EXTTEXTOUTPATCHOFFSET 136
  24. char szExtTextOutMagic[] = "\x74\x0a\xf7\x86\x60\xff\x00\x80";
  25. char szExtTextOutPatch[] = "\x90\x90\x90\x90\x90\x90\x90\x90";
  26. LPVOID GetModifiableCodeAddress(LPCSTR lpszModuleName, LPCSTR lpszEntryPointName)
  27. {
  28. HMODULE hModule;
  29. FARPROC fpEntryPoint;
  30. LPVOID lpCodeAddress;
  31. hModule = GetModuleHandle(lpszModuleName);
  32. if (NULL == hModule)
  33. {
  34. DPF(0, "DIB Engine not loaded");
  35. return NULL;
  36. }
  37. fpEntryPoint = GetProcAddress(hModule, lpszEntryPointName);
  38. if (NULL == fpEntryPoint)
  39. {
  40. DPF(0, "Could not locate DIB engine's ExtTextOut entry point");
  41. return FALSE;
  42. }
  43. lpCodeAddress = (LPVOID)MAKELP(AllocCStoDSAlias(SELECTOROF(fpEntryPoint)), OFFSETOF(fpEntryPoint));
  44. if (NULL == lpCodeAddress)
  45. {
  46. DPF(0, "Could not allocate data segment alias for code segment");
  47. return FALSE;
  48. }
  49. return lpCodeAddress;
  50. }
  51. #define FREEMODIFIABLECODEADDRESS(lpCodeAddress) FreeSelector(SELECTOROF(lpCodeAddress))
  52. BOOL ValidateDIBEngine(void)
  53. {
  54. LPBYTE lpCodeAddress;
  55. LPBYTE lpMagicAddress;
  56. BOOL fDIBEngineOK;
  57. /*
  58. * Get a pointer to the ExtTextOut code.
  59. */
  60. lpCodeAddress = (LPBYTE)GetModifiableCodeAddress(DIBENGMODULE, EXTTEXTOUTENTRYPOINT);
  61. if (NULL == lpCodeAddress)
  62. return FALSE;
  63. /*
  64. * Move to the patch address.
  65. */
  66. lpMagicAddress = lpCodeAddress + EXTTEXTOUTPATCHOFFSET;
  67. /*
  68. * Verify that the data at the patch address is the stuff we want to replace.
  69. */
  70. fDIBEngineOK = (!_fmemcmp(lpMagicAddress, szExtTextOutMagic, sizeof(szExtTextOutMagic) - 1));
  71. if (!fDIBEngineOK)
  72. {
  73. /*
  74. * Couldn't find the signature bytes we are looking for. This might be because we
  75. * already patched it. So check for the no-ops.
  76. */
  77. fDIBEngineOK = (!_fmemcmp(lpMagicAddress, szExtTextOutPatch, sizeof(szExtTextOutPatch) - 1));
  78. }
  79. #ifdef DEBUG
  80. if (!fDIBEngineOK)
  81. DPF(2, "DIB Engine does not match magic or patch - different version?");
  82. #endif
  83. FREEMODIFIABLECODEADDRESS(lpMagicAddress);
  84. return fDIBEngineOK;
  85. }
  86. BOOL PatchDIBEngineExtTextOut(BOOL fPatch)
  87. {
  88. LPBYTE lpCodeAddress;
  89. LPBYTE lpMagicAddress;
  90. /*
  91. * Get a pointer to the ExtTextOut code.
  92. */
  93. lpCodeAddress = (LPBYTE)GetModifiableCodeAddress(DIBENGMODULE, EXTTEXTOUTENTRYPOINT);
  94. if (NULL == lpCodeAddress)
  95. return FALSE;
  96. /*
  97. * Move to the patch address.
  98. */
  99. lpMagicAddress = lpCodeAddress + EXTTEXTOUTPATCHOFFSET;
  100. if (fPatch)
  101. {
  102. /*
  103. * Don't do anything if its already patched.
  104. */
  105. if (_fmemcmp(lpMagicAddress, szExtTextOutPatch, sizeof(szExtTextOutPatch) - 1))
  106. {
  107. /*
  108. * Be very sure we know we are dealing with a DIB engine we can handle.
  109. */
  110. if (_fmemcmp(lpMagicAddress, szExtTextOutMagic, sizeof(szExtTextOutMagic) - 1))
  111. {
  112. DPF(1, "Unknown DIB Engine. not fixing up");
  113. FREEMODIFIABLECODEADDRESS(lpMagicAddress);
  114. return FALSE;
  115. }
  116. /*
  117. * Replace the offending code with NOPs.
  118. */
  119. _fmemcpy(lpMagicAddress, szExtTextOutPatch, sizeof(szExtTextOutPatch) - 1);
  120. }
  121. }
  122. else
  123. {
  124. /*
  125. * Don't do anything if its already unpatched.
  126. */
  127. if (!_fmemcmp(lpMagicAddress, szExtTextOutMagic, sizeof(szExtTextOutMagic) - 1))
  128. {
  129. /*
  130. * Be very sure we know we are dealing with a DIB engine we can handle.
  131. */
  132. if (_fmemcmp(lpMagicAddress, szExtTextOutPatch, sizeof(szExtTextOutPatch) - 1))
  133. {
  134. DPF(1, "Unknown DIB Engine. not fixing up");
  135. FREEMODIFIABLECODEADDRESS(lpMagicAddress);
  136. return FALSE;
  137. }
  138. /*
  139. * Put the original code back.
  140. */
  141. _fmemcpy(lpMagicAddress, szExtTextOutMagic, sizeof(szExtTextOutMagic) - 1);
  142. }
  143. }
  144. FREEMODIFIABLECODEADDRESS(lpMagicAddress);
  145. return TRUE;
  146. }
  147. BOOL DDAPI DD16_FixupDIBEngine(void)
  148. {
  149. /*
  150. * Is this Win 4.1 (or higher)
  151. */
  152. OSVERSIONINFO ver = {sizeof(OSVERSIONINFO)};
  153. GetVersionEx(&ver);
  154. if (ver.dwMajorVersion > 4 ||
  155. (ver.dwMajorVersion == 4 && ver.dwMinorVersion >= 10))
  156. {
  157. return TRUE;
  158. }
  159. /*
  160. * Is this a DIB engine version we can work with?
  161. */
  162. if( !ValidateDIBEngine() )
  163. return FALSE;
  164. /*
  165. * It is the correct version. So fix it up. Currently all this
  166. * involves is patching the ExtTextOut routine.
  167. */
  168. return PatchDIBEngineExtTextOut(TRUE);
  169. }