Source code of Windows XP (NT5)
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.

249 lines
5.5 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. IgnoreScheduler.cpp
  5. Abstract:
  6. Includes the following hooks:
  7. SetThreadPriority: Normalize the thread priority to prevent some application synchronization
  8. issues.
  9. SetPriorityClass: Normalize process class.
  10. SuspendThread: Prevent a thread from suspending itself.
  11. ResumeThread: Prevent a thread from resumming itself.
  12. Notes:
  13. This is a general purpose shim.
  14. History:
  15. 10/20/2000 jpipkins Created: SetPriorityClass created and merged with SetThreadPriority(linstev),
  16. SuspendThread/ResumeThread(dmunsil/a-brienw).
  17. --*/
  18. #include "precomp.h"
  19. IMPLEMENT_SHIM_BEGIN(IgnoreScheduler)
  20. #include "ShimHookMacro.h"
  21. APIHOOK_ENUM_BEGIN
  22. APIHOOK_ENUM_ENTRY(CreateProcessA)
  23. APIHOOK_ENUM_ENTRY(CreateProcessW)
  24. APIHOOK_ENUM_ENTRY(SetThreadPriority)
  25. APIHOOK_ENUM_ENTRY(SetPriorityClass)
  26. APIHOOK_ENUM_ENTRY(ResumeThread)
  27. APIHOOK_ENUM_ENTRY(SuspendThread)
  28. APIHOOK_ENUM_END
  29. /*++
  30. Remove any creation flags that specify process priority.
  31. --*/
  32. #define PRIORITYMASK (ABOVE_NORMAL_PRIORITY_CLASS | BELOW_NORMAL_PRIORITY_CLASS | HIGH_PRIORITY_CLASS | IDLE_PRIORITY_CLASS | REALTIME_PRIORITY_CLASS)
  33. BOOL
  34. APIHOOK(CreateProcessA)(
  35. LPCSTR lpApplicationName,
  36. LPSTR lpCommandLine,
  37. LPSECURITY_ATTRIBUTES lpProcessAttributes,
  38. LPSECURITY_ATTRIBUTES lpThreadAttributes,
  39. BOOL bInheritHandles,
  40. DWORD dwCreationFlags,
  41. LPVOID lpEnvironment,
  42. LPCSTR lpCurrentDirectory,
  43. LPSTARTUPINFOA lpStartupInfo,
  44. LPPROCESS_INFORMATION lpProcessInformation
  45. )
  46. {
  47. if (dwCreationFlags & PRIORITYMASK) {
  48. LOGN(eDbgLevelInfo, "[CreateProcessA] Forcing priority class to normal");
  49. dwCreationFlags &= ~PRIORITYMASK;
  50. dwCreationFlags |= NORMAL_PRIORITY_CLASS;
  51. }
  52. return ORIGINAL_API(CreateProcessA)(lpApplicationName, lpCommandLine,
  53. lpProcessAttributes, lpThreadAttributes, bInheritHandles,
  54. dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo,
  55. lpProcessInformation);
  56. }
  57. /*++
  58. Remove any creation flags that specify process priority.
  59. --*/
  60. BOOL
  61. APIHOOK(CreateProcessW)(
  62. LPCWSTR lpApplicationName,
  63. LPWSTR lpCommandLine,
  64. LPSECURITY_ATTRIBUTES lpProcessAttributes,
  65. LPSECURITY_ATTRIBUTES lpThreadAttributes,
  66. BOOL bInheritHandles,
  67. DWORD dwCreationFlags,
  68. LPVOID lpEnvironment,
  69. LPCWSTR lpCurrentDirectory,
  70. LPSTARTUPINFOW lpStartupInfo,
  71. LPPROCESS_INFORMATION lpProcessInformation
  72. )
  73. {
  74. if (dwCreationFlags & PRIORITYMASK) {
  75. LOGN(eDbgLevelInfo, "[CreateProcessW] Forcing priority class to normal");
  76. dwCreationFlags &= ~PRIORITYMASK;
  77. dwCreationFlags |= NORMAL_PRIORITY_CLASS;
  78. }
  79. return ORIGINAL_API(CreateProcessW)(lpApplicationName, lpCommandLine,
  80. lpProcessAttributes, lpThreadAttributes, bInheritHandles,
  81. dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo,
  82. lpProcessInformation);
  83. }
  84. /*++
  85. Normalize thread priority.
  86. --*/
  87. BOOL
  88. APIHOOK(SetThreadPriority)(
  89. HANDLE hThread,
  90. int nPriority
  91. )
  92. {
  93. if (nPriority != THREAD_PRIORITY_NORMAL) {
  94. LOGN(
  95. eDbgLevelInfo,
  96. "[SetThreadPriority] Forcing thread priority to normal.");
  97. }
  98. return ORIGINAL_API(SetThreadPriority)(hThread, THREAD_PRIORITY_NORMAL);
  99. }
  100. /*++
  101. Normalize Class priority.
  102. --*/
  103. BOOL
  104. APIHOOK(SetPriorityClass)(
  105. HANDLE hProcess,
  106. DWORD dwPriorityClass
  107. )
  108. {
  109. if (dwPriorityClass != NORMAL_PRIORITY_CLASS) {
  110. LOGN(
  111. eDbgLevelInfo,
  112. "[SetPriorityClass] Forcing priority class to normal.");
  113. }
  114. return ORIGINAL_API(SetPriorityClass)(hProcess, NORMAL_PRIORITY_CLASS);
  115. }
  116. /*++
  117. Get Thread ID for ResumeThread and SuspendThread Hooks
  118. --*/
  119. DWORD
  120. dwGetThreadID(
  121. HANDLE hThread
  122. )
  123. {
  124. THREAD_BASIC_INFORMATION ThreadBasicInfo;
  125. NTSTATUS Status;
  126. Status = NtQueryInformationThread(hThread,
  127. ThreadBasicInformation,
  128. &ThreadBasicInfo,
  129. sizeof(ThreadBasicInfo),
  130. NULL);
  131. if (NT_SUCCESS(Status)) {
  132. return (DWORD)ThreadBasicInfo.ClientId.UniqueThread;
  133. } else {
  134. LOGN(
  135. eDbgLevelError,
  136. "[dwGetThreadID] NtQueryInfomationThread failed.");
  137. return 0;
  138. }
  139. }
  140. /*++
  141. Disallow suspending self
  142. --*/
  143. DWORD
  144. APIHOOK(SuspendThread)(
  145. HANDLE hThread // handle to the thread
  146. )
  147. {
  148. //
  149. // If we're trying to suspend our own thread, refuse.
  150. //
  151. if (dwGetThreadID(hThread) != dwGetThreadID(GetCurrentThread())) {
  152. return ORIGINAL_API(SuspendThread)(hThread);
  153. } else {
  154. return 0;
  155. }
  156. }
  157. /*++
  158. Disallow resuming self, for same reason
  159. --*/
  160. DWORD
  161. APIHOOK(ResumeThread)(
  162. HANDLE hThread // handle to the thread
  163. )
  164. {
  165. //
  166. // If we're trying to resume our own thread, refuse.
  167. //
  168. if (dwGetThreadID(hThread) != dwGetThreadID(GetCurrentThread())) {
  169. return ORIGINAL_API(ResumeThread)(hThread);
  170. } else {
  171. return 0;
  172. }
  173. }
  174. /*++
  175. Register hooked functions
  176. --*/
  177. HOOK_BEGIN
  178. APIHOOK_ENTRY(KERNEL32.DLL, CreateProcessA)
  179. APIHOOK_ENTRY(KERNEL32.DLL, CreateProcessW)
  180. APIHOOK_ENTRY(KERNEL32.DLL, SetThreadPriority)
  181. APIHOOK_ENTRY(KERNEL32.DLL, SetPriorityClass)
  182. APIHOOK_ENTRY(KERNEL32.DLL, SuspendThread)
  183. APIHOOK_ENTRY(KERNEL32.DLL, ResumeThread)
  184. HOOK_END
  185. IMPLEMENT_SHIM_END