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.

156 lines
3.2 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. MechWarrior2.cpp
  5. Abstract:
  6. This shim fixes a problem with MW2 expecting BitBlt to return a specific
  7. value, contrary to the published documentation. It also fixes a situation
  8. in which a thread calls "SuspendThread" on itself, killing itself.
  9. Notes:
  10. This shim is specific to Mechwarrior, though potentially some of this could
  11. be applied to other apps that use the AIL32 libraries.
  12. History:
  13. 05/16/2000 dmunsil Created
  14. --*/
  15. #include "precomp.h"
  16. #include <nt.h>
  17. #include <ntrtl.h>
  18. #include <nturtl.h>
  19. IMPLEMENT_SHIM_BEGIN(MechWarrior2)
  20. #include "ShimHookMacro.h"
  21. APIHOOK_ENUM_BEGIN
  22. APIHOOK_ENUM_ENTRY(BitBlt)
  23. APIHOOK_ENUM_ENTRY(SuspendThread)
  24. APIHOOK_ENUM_ENTRY(ResumeThread)
  25. APIHOOK_ENUM_END
  26. DWORD dwGetThreadID(HANDLE hThread)
  27. {
  28. THREAD_BASIC_INFORMATION ThreadBasicInfo;
  29. NTSTATUS Status;
  30. TEB teb;
  31. Status = NtQueryInformationThread(
  32. hThread,
  33. ThreadBasicInformation,
  34. &ThreadBasicInfo,
  35. sizeof(ThreadBasicInfo),
  36. NULL
  37. );
  38. if (!NT_SUCCESS(Status)) {
  39. DPFN( eDbgLevelError, "NtQueryInfomationThread failed\n");
  40. return 0;
  41. }
  42. return (DWORD)ThreadBasicInfo.ClientId.UniqueThread;
  43. }
  44. /*++
  45. Return what Mechwarrior is expecting from BitBlt
  46. --*/
  47. BOOL
  48. APIHOOK(BitBlt)(
  49. HDC hdcDest, // handle to destination DC
  50. int nXDest, // x-coord of destination upper-left corner
  51. int nYDest, // y-coord of destination upper-left corner
  52. int nWidth, // width of destination rectangle
  53. int nHeight, // height of destination rectangle
  54. HDC hdcSrc, // handle to source DC
  55. int nXSrc, // x-coordinate of source upper-left corner
  56. int nYSrc, // y-coordinate of source upper-left corner
  57. DWORD dwRop // raster operation code
  58. )
  59. {
  60. BOOL bRet;
  61. bRet = ORIGINAL_API(BitBlt)(
  62. hdcDest,
  63. nXDest,
  64. nYDest,
  65. nWidth,
  66. nHeight,
  67. hdcSrc,
  68. nXSrc,
  69. nYSrc,
  70. dwRop
  71. );
  72. if (bRet) {
  73. bRet = 0x1e0; // this is what MechWarrior expects to be returned.
  74. }
  75. return bRet;
  76. }
  77. /*++
  78. Disallow suspending self
  79. --*/
  80. DWORD
  81. APIHOOK(SuspendThread)(
  82. HANDLE hThread // handle to the thread
  83. )
  84. {
  85. // if we're trying to suspend our own thread, refuse
  86. if (dwGetThreadID(hThread) != dwGetThreadID(GetCurrentThread())) {
  87. return ORIGINAL_API(SuspendThread)(hThread);
  88. } else {
  89. return 0;
  90. }
  91. }
  92. /*++
  93. Disallow resuming self, for same reason
  94. --*/
  95. DWORD
  96. APIHOOK(ResumeThread)(
  97. HANDLE hThread // handle to the thread
  98. )
  99. {
  100. // if we're trying to resume our own thread, refuse
  101. if (dwGetThreadID(hThread) != dwGetThreadID(GetCurrentThread())) {
  102. return ORIGINAL_API(SuspendThread)(hThread);
  103. } else {
  104. return 0;
  105. }
  106. }
  107. /*++
  108. Register hooked functions
  109. --*/
  110. HOOK_BEGIN
  111. APIHOOK_ENTRY(GDI32.DLL, BitBlt )
  112. APIHOOK_ENTRY(Kernel32.DLL, SuspendThread )
  113. APIHOOK_ENTRY(Kernel32.DLL, ResumeThread )
  114. HOOK_END
  115. IMPLEMENT_SHIM_END