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.

188 lines
4.0 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. USNF97.cpp
  5. Abstract:
  6. USNF '97 synchronizes it's video playback with cli/sti combinations. This
  7. fails on NT, so we have to make sure they aren't bltting during the
  8. refresh. Note that each time a cli/sti is hit, it makes only 1 blt
  9. synchronize with the refresh. After the intro has played, cli/sti is no
  10. longer used and so the blts don't incur extra overhead.
  11. Notes:
  12. This is an app specific shim.
  13. History:
  14. 02/10/2000 linstev Created
  15. --*/
  16. #include "precomp.h"
  17. IMPLEMENT_SHIM_BEGIN(USNF97)
  18. #include "ShimHookMacro.h"
  19. APIHOOK_ENUM_BEGIN
  20. APIHOOK_ENUM_ENTRY_DIRECTX_COMSERVER()
  21. APIHOOK_ENUM_ENTRY(GetStartupInfoA)
  22. APIHOOK_ENUM_END
  23. IMPLEMENT_DIRECTX_COMSERVER_HOOKS()
  24. LPDIRECTDRAW g_lpDirectDraw = NULL;
  25. BOOL bFixBlt = FALSE;
  26. /*++
  27. Hook create surface so we can be sure we're being called.
  28. --*/
  29. HRESULT
  30. COMHOOK(IDirectDraw, CreateSurface)(
  31. PVOID pThis,
  32. LPDDSURFACEDESC lpDDSurfaceDesc,
  33. LPDIRECTDRAWSURFACE* lplpDDSurface,
  34. IUnknown* pUnkOuter
  35. )
  36. {
  37. HRESULT hReturn;
  38. _pfn_IDirectDraw_CreateSurface pfnOld =
  39. ORIGINAL_COM(IDirectDraw, CreateSurface, pThis);
  40. if (SUCCEEDED(hReturn = (*pfnOld)(
  41. pThis,
  42. lpDDSurfaceDesc,
  43. lplpDDSurface,
  44. pUnkOuter)))
  45. {
  46. HookObject(
  47. NULL,
  48. IID_IDirectDrawSurface,
  49. (PVOID*)lplpDDSurface,
  50. NULL,
  51. FALSE);
  52. }
  53. g_lpDirectDraw = (LPDIRECTDRAW)pThis;
  54. return hReturn;
  55. }
  56. /*++
  57. Synchronize the blt with the refresh if a cli/sti has just been called.
  58. --*/
  59. HRESULT
  60. COMHOOK(IDirectDrawSurface, Blt)(
  61. LPDIRECTDRAWSURFACE lpDDDestSurface,
  62. LPRECT lpDestRect,
  63. LPDIRECTDRAWSURFACE lpDDSrcSurface,
  64. LPRECT lpSrcRect,
  65. DWORD dwFlags,
  66. LPDDBLTFX lpDDBltFX
  67. )
  68. {
  69. // Original Blt
  70. _pfn_IDirectDrawSurface_Blt pfnOld = ORIGINAL_COM(IDirectDrawSurface, Blt, (LPVOID) lpDDDestSurface);
  71. if (bFixBlt)
  72. {
  73. // Make sure we're in the blank.
  74. DWORD dwScanLine = 0;
  75. while (dwScanLine<480)
  76. {
  77. g_lpDirectDraw->GetScanLine(&dwScanLine);
  78. }
  79. bFixBlt = FALSE;
  80. }
  81. return (*pfnOld)(
  82. lpDDDestSurface,
  83. lpDestRect,
  84. lpDDSrcSurface,
  85. lpSrcRect,
  86. dwFlags,
  87. lpDDBltFX);
  88. }
  89. /*++
  90. Custom exception handler to filter the cli/sti instructions.
  91. Handle out of range idivs.
  92. --*/
  93. LONG
  94. USNF97_ExceptionFilter(
  95. struct _EXCEPTION_POINTERS *ExceptionInfo
  96. )
  97. {
  98. CONTEXT *lpContext = ExceptionInfo->ContextRecord;
  99. LONG lRet = EXCEPTION_CONTINUE_SEARCH;
  100. if ((*((LPBYTE)lpContext->Eip) == 0xFA) ||
  101. (*((LPBYTE)lpContext->Eip) == 0xFB))
  102. {
  103. bFixBlt = TRUE;
  104. lpContext->Eip++;
  105. lRet = EXCEPTION_CONTINUE_EXECUTION;
  106. }
  107. else if ((*((LPBYTE)lpContext->Eip) == 0xF7) || // Handle idiv
  108. (*((LPBYTE)lpContext->Eip+1) == 0xF7)) // Handle 16 bit idiv
  109. {
  110. DPFN( eDbgLevelWarning, "Detected 'idiv' overflow: validating edx:eax");
  111. lpContext->Edx=0;
  112. if ((LONG)lpContext->Eax < 0)
  113. {
  114. lpContext->Eax = (DWORD)(-(LONG)lpContext->Eax);
  115. }
  116. lRet = EXCEPTION_CONTINUE_EXECUTION;
  117. }
  118. return lRet;
  119. }
  120. /*++
  121. Hook the exception handler.
  122. --*/
  123. VOID
  124. APIHOOK(GetStartupInfoA)(
  125. LPSTARTUPINFOA lpStartupInfo
  126. )
  127. {
  128. SetUnhandledExceptionFilter(USNF97_ExceptionFilter);
  129. ORIGINAL_API(GetStartupInfoA)(lpStartupInfo);
  130. }
  131. /*++
  132. Register hooked functions
  133. --*/
  134. HOOK_BEGIN
  135. APIHOOK_ENTRY(KERNEL32.DLL, GetStartupInfoA)
  136. APIHOOK_ENTRY_DIRECTX_COMSERVER()
  137. COMHOOK_ENTRY(DirectDraw, IDirectDraw, CreateSurface, 6)
  138. COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface, Blt, 5)
  139. HOOK_END
  140. IMPLEMENT_SHIM_END