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.

268 lines
5.1 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. IgnoreHungAppPaint.cpp
  5. Abstract:
  6. Setup the hollow brush to prevent user from trashing peoples windows.
  7. Notes:
  8. This is a general purpose shim.
  9. History:
  10. 12/04/2000 linstev Created
  11. --*/
  12. #include "precomp.h"
  13. #include <new.h>
  14. IMPLEMENT_SHIM_BEGIN(IgnoreHungAppPaint)
  15. #include "ShimHookMacro.h"
  16. APIHOOK_ENUM_BEGIN
  17. APIHOOK_ENUM_ENTRY(RegisterClassA)
  18. APIHOOK_ENUM_ENTRY(RegisterClassW)
  19. APIHOOK_ENUM_ENTRY(RegisterClassExA)
  20. APIHOOK_ENUM_ENTRY(RegisterClassExW)
  21. APIHOOK_ENUM_END
  22. struct HUNGCLASS
  23. {
  24. CString csClass;
  25. HUNGCLASS *next;
  26. };
  27. HUNGCLASS *g_lHungList = NULL;
  28. BOOL g_bAll = FALSE;
  29. /*++
  30. Check if a class needs a hollow brush.
  31. --*/
  32. BOOL
  33. IsHungClassW(LPCWSTR wszClass)
  34. {
  35. BOOL bRet = FALSE;
  36. if (wszClass)
  37. {
  38. HUNGCLASS *h = g_lHungList;
  39. while (h)
  40. {
  41. if (h->csClass.CompareNoCase(wszClass) == 0)
  42. {
  43. LOGN(eDbgLevelWarning, "Matched hung class: forcing HOLLOW_BRUSH");
  44. bRet = TRUE;
  45. break;
  46. }
  47. h = h->next;
  48. }
  49. }
  50. return bRet;
  51. }
  52. /*++
  53. Check if a class needs a hollow brush.
  54. --*/
  55. BOOL
  56. IsHungClassA(LPCSTR szClass)
  57. {
  58. CSTRING_TRY
  59. {
  60. CString csClass(szClass);
  61. return IsHungClassW(csClass);
  62. }
  63. CSTRING_CATCH
  64. {
  65. // Do nothing
  66. }
  67. return FALSE;
  68. }
  69. /*++
  70. Hook all possible calls that can initialize or change a window's
  71. WindowProc (or DialogProc)
  72. --*/
  73. ATOM
  74. APIHOOK(RegisterClassA)(
  75. WNDCLASSA *lpWndClass
  76. )
  77. {
  78. if (lpWndClass && (g_bAll || IsHungClassA(lpWndClass->lpszClassName)))
  79. {
  80. lpWndClass->hbrBackground = (HBRUSH) GetStockObject(HOLLOW_BRUSH);
  81. }
  82. return ORIGINAL_API(RegisterClassA)(lpWndClass);
  83. }
  84. ATOM
  85. APIHOOK(RegisterClassW)(
  86. WNDCLASSW *lpWndClass
  87. )
  88. {
  89. if (lpWndClass && IsHungClassW(lpWndClass->lpszClassName))
  90. {
  91. lpWndClass->hbrBackground = (HBRUSH) GetStockObject(HOLLOW_BRUSH);
  92. }
  93. return ORIGINAL_API(RegisterClassW)(lpWndClass);
  94. }
  95. ATOM
  96. APIHOOK(RegisterClassExA)(
  97. WNDCLASSEXA *lpWndClass
  98. )
  99. {
  100. if (lpWndClass && IsHungClassA(lpWndClass->lpszClassName))
  101. {
  102. lpWndClass->hbrBackground = (HBRUSH) GetStockObject(HOLLOW_BRUSH);
  103. }
  104. return ORIGINAL_API(RegisterClassExA)(lpWndClass);
  105. }
  106. ATOM
  107. APIHOOK(RegisterClassExW)(
  108. WNDCLASSEXW *lpWndClass
  109. )
  110. {
  111. if (lpWndClass && IsHungClassW(lpWndClass->lpszClassName))
  112. {
  113. lpWndClass->hbrBackground = (HBRUSH) GetStockObject(HOLLOW_BRUSH);
  114. }
  115. return ORIGINAL_API(RegisterClassExW)(lpWndClass);
  116. }
  117. /*++
  118. Parse the command line for fixes:
  119. CLASS1; CLASS2; CLASS3 ...
  120. --*/
  121. VOID
  122. ParseCommandLineA(
  123. LPCSTR lpCommandLine
  124. )
  125. {
  126. // Add all the defaults if no command line is specified
  127. if (!lpCommandLine || (lpCommandLine[0] == '\0'))
  128. {
  129. g_bAll = TRUE;
  130. DPFN(eDbgLevelInfo, "All classes will use HOLLOW_BRUSH");
  131. return;
  132. }
  133. char seps[] = " ,\t;";
  134. char *token = NULL;
  135. // Since strtok modifies the string, we need to copy it
  136. int cchCmdLine = strlen(lpCommandLine) + 1;
  137. LPSTR szCommandLine = (LPSTR) malloc(cchCmdLine);
  138. if (!szCommandLine) goto Exit;
  139. HRESULT hr;
  140. hr = StringCchCopyA(szCommandLine, cchCmdLine, lpCommandLine);
  141. if (FAILED(hr))
  142. {
  143. goto Exit;
  144. }
  145. //
  146. // Run the string, looking for fix names
  147. //
  148. token = _strtok(szCommandLine, seps);
  149. while (token)
  150. {
  151. HUNGCLASS *h;
  152. h = (HUNGCLASS *) malloc(sizeof(HUNGCLASS));
  153. if (h)
  154. {
  155. CSTRING_TRY
  156. {
  157. // Force a default construct of the CString (malloc doesn't)
  158. new(&h->csClass) CString();
  159. h->csClass = token;
  160. h->next = g_lHungList;
  161. g_lHungList = h;
  162. DPFN(eDbgLevelInfo, "Adding %s", token);
  163. }
  164. CSTRING_CATCH
  165. {
  166. // Do nothing, loop around and try again with next one.
  167. DPFN(eDbgLevelError, "[IgnoreHungAppPaint] CString exception caught, out of memory");
  168. }
  169. }
  170. else
  171. {
  172. DPFN(eDbgLevelError, "Out of memory");
  173. }
  174. // Get the next token
  175. token = _strtok(NULL, seps);
  176. }
  177. Exit:
  178. if (szCommandLine)
  179. {
  180. free(szCommandLine);
  181. }
  182. }
  183. /*++
  184. Register hooked functions
  185. --*/
  186. BOOL
  187. NOTIFY_FUNCTION(
  188. DWORD fdwReason
  189. )
  190. {
  191. if (fdwReason == DLL_PROCESS_ATTACH) {
  192. ParseCommandLineA(COMMAND_LINE);
  193. }
  194. return TRUE;
  195. }
  196. HOOK_BEGIN
  197. CALL_NOTIFY_FUNCTION
  198. APIHOOK_ENTRY(USER32.DLL, RegisterClassA)
  199. APIHOOK_ENTRY(USER32.DLL, RegisterClassW);
  200. APIHOOK_ENTRY(USER32.DLL, RegisterClassExA);
  201. APIHOOK_ENTRY(USER32.DLL, RegisterClassExW);
  202. HOOK_END
  203. IMPLEMENT_SHIM_END