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.

394 lines
10 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. DisableW2KOwnerDrawButtonStates.cpp
  5. Abstract:
  6. Hooks all application-defined window procedures and filters out new
  7. owner-draw buttons states (introduced in Win2000).
  8. Notes:
  9. This shim can be reused for other shims that require WindowProc hooking.
  10. Copy all APIHook_* functions and simply replace the code in WindowProcHook
  11. and DialogProcHook.
  12. History:
  13. 11/01/1999 markder Created
  14. 02/15/1999 markder Reworked WndProc hooking mechanism so that it generically
  15. hooks all WndProcs for the process.
  16. 11/29/2000 andyseti Converted into GeneralPurpose shim.
  17. --*/
  18. #include "precomp.h"
  19. IMPLEMENT_SHIM_BEGIN(DisableW2KOwnerDrawButtonStates)
  20. #include "ShimHookMacro.h"
  21. APIHOOK_ENUM_BEGIN
  22. APIHOOK_ENUM_ENTRY(RegisterClassA)
  23. APIHOOK_ENUM_ENTRY(RegisterClassW)
  24. APIHOOK_ENUM_ENTRY(RegisterClassExA)
  25. APIHOOK_ENUM_ENTRY(RegisterClassExW)
  26. APIHOOK_ENUM_ENTRY(CreateDialogParamA)
  27. APIHOOK_ENUM_ENTRY(CreateDialogParamW)
  28. APIHOOK_ENUM_ENTRY(CreateDialogIndirectParamA)
  29. APIHOOK_ENUM_ENTRY(CreateDialogIndirectParamW)
  30. APIHOOK_ENUM_ENTRY(CreateDialogIndirectParamAorW)
  31. APIHOOK_ENUM_ENTRY(SetWindowLongA)
  32. APIHOOK_ENUM_ENTRY(SetWindowLongW)
  33. APIHOOK_ENUM_END
  34. /*++
  35. Change WM_DRAWITEM behaviour
  36. --*/
  37. LRESULT CALLBACK
  38. WindowProcHook(
  39. WNDPROC pfnOld, // address of old WindowProc
  40. HWND hwnd, // handle to window
  41. UINT uMsg, // message identifier
  42. WPARAM wParam, // first message parameter
  43. LPARAM lParam // second message parameter
  44. )
  45. {
  46. // Check for message we're interested in
  47. if (uMsg == WM_DRAWITEM)
  48. {
  49. if (((LPDRAWITEMSTRUCT) lParam)->itemState &
  50. ~(ODS_SELECTED |
  51. ODS_GRAYED |
  52. ODS_DISABLED |
  53. ODS_CHECKED |
  54. ODS_FOCUS |
  55. ODS_DEFAULT |
  56. ODS_COMBOBOXEDIT |
  57. ODS_HOTLIGHT |
  58. ODS_INACTIVE))
  59. {
  60. LOGN(eDbgLevelError, "Removed Win2K-specific Owner-draw button flags.");
  61. // Remove all Win9x-incompatible owner draw button states.
  62. ((LPDRAWITEMSTRUCT) lParam)->itemState &=
  63. (ODS_SELECTED |
  64. ODS_GRAYED |
  65. ODS_DISABLED |
  66. ODS_CHECKED |
  67. ODS_FOCUS |
  68. ODS_DEFAULT |
  69. ODS_COMBOBOXEDIT |
  70. ODS_HOTLIGHT |
  71. ODS_INACTIVE);
  72. }
  73. }
  74. return (*pfnOld)(hwnd, uMsg, wParam, lParam);
  75. }
  76. INT_PTR CALLBACK
  77. DialogProcHook(
  78. DLGPROC pfnOld, // address of old DialogProc
  79. HWND hwndDlg, // handle to dialog box
  80. UINT uMsg, // message
  81. WPARAM wParam, // first message parameter
  82. LPARAM lParam // second message parameter
  83. )
  84. {
  85. // Check for message we're interested in
  86. if (uMsg == WM_DRAWITEM)
  87. {
  88. if (((LPDRAWITEMSTRUCT) lParam)->itemState &
  89. ~(ODS_SELECTED |
  90. ODS_GRAYED |
  91. ODS_DISABLED |
  92. ODS_CHECKED |
  93. ODS_FOCUS |
  94. ODS_DEFAULT |
  95. ODS_COMBOBOXEDIT |
  96. ODS_HOTLIGHT |
  97. ODS_INACTIVE))
  98. {
  99. LOGN(eDbgLevelError, "Removed Win2K-specific Owner-draw button flags.");
  100. // Remove all Win9x-incompatible owner draw button states.
  101. ((LPDRAWITEMSTRUCT) lParam)->itemState &=
  102. (ODS_SELECTED |
  103. ODS_GRAYED |
  104. ODS_DISABLED |
  105. ODS_CHECKED |
  106. ODS_FOCUS |
  107. ODS_DEFAULT |
  108. ODS_COMBOBOXEDIT |
  109. ODS_HOTLIGHT |
  110. ODS_INACTIVE);
  111. }
  112. }
  113. return (*pfnOld)(hwndDlg, uMsg, wParam, lParam);
  114. }
  115. /*++
  116. Hook all possible calls that can initialize or change a window's
  117. WindowProc (or DialogProc)
  118. --*/
  119. ATOM
  120. APIHOOK(RegisterClassA)(
  121. CONST WNDCLASSA *lpWndClass // class data
  122. )
  123. {
  124. WNDCLASSA wcNewWndClass = *lpWndClass;
  125. wcNewWndClass.lpfnWndProc = (WNDPROC) HookCallback(lpWndClass->lpfnWndProc, WindowProcHook);
  126. DPFN(eDbgLevelInfo, "Hooked window proc via RegisterClassA.");
  127. return ORIGINAL_API(RegisterClassA)(&wcNewWndClass);
  128. }
  129. ATOM
  130. APIHOOK(RegisterClassW)(
  131. CONST WNDCLASSW *lpWndClass // class data
  132. )
  133. {
  134. WNDCLASSW wcNewWndClass = *lpWndClass;
  135. wcNewWndClass.lpfnWndProc = (WNDPROC) HookCallback(lpWndClass->lpfnWndProc, WindowProcHook);
  136. DPFN( eDbgLevelInfo, "Hooked window proc via RegisterClassW.");
  137. return ORIGINAL_API(RegisterClassW)(&wcNewWndClass);
  138. }
  139. ATOM
  140. APIHOOK(RegisterClassExA)(
  141. CONST WNDCLASSEXA *lpwcx // class data
  142. )
  143. {
  144. WNDCLASSEXA wcNewWndClass = *lpwcx;
  145. wcNewWndClass.lpfnWndProc = (WNDPROC) HookCallback(lpwcx->lpfnWndProc, WindowProcHook);
  146. DPFN( eDbgLevelInfo, "Hooked window proc via RegisterClassExA.");
  147. return ORIGINAL_API(RegisterClassExA)(&wcNewWndClass);
  148. }
  149. ATOM
  150. APIHOOK(RegisterClassExW)(
  151. CONST WNDCLASSEXW *lpwcx // class data
  152. )
  153. {
  154. WNDCLASSEXW wcNewWndClass = *lpwcx;
  155. wcNewWndClass.lpfnWndProc = (WNDPROC) HookCallback(lpwcx->lpfnWndProc, WindowProcHook);
  156. DPFN( eDbgLevelInfo, "Hooked window proc via RegisterClassExW.");
  157. return ORIGINAL_API(RegisterClassExW)(&wcNewWndClass);
  158. }
  159. HWND
  160. APIHOOK(CreateDialogParamA)(
  161. HINSTANCE hInstance, // handle to module
  162. LPCSTR lpTemplateName, // dialog box template
  163. HWND hWndParent, // handle to owner window
  164. DLGPROC lpDialogFunc, // dialog box procedure
  165. LPARAM dwInitParam // initialization value
  166. )
  167. {
  168. lpDialogFunc = (DLGPROC) HookCallback(lpDialogFunc, DialogProcHook);
  169. DPFN( eDbgLevelInfo, "Hooked window proc via CreateDialogParamA.");
  170. return ORIGINAL_API(CreateDialogParamA)(
  171. hInstance,
  172. lpTemplateName,
  173. hWndParent,
  174. lpDialogFunc,
  175. dwInitParam );
  176. }
  177. HWND
  178. APIHOOK(CreateDialogParamW)(
  179. HINSTANCE hInstance, // handle to module
  180. LPCWSTR lpTemplateName, // dialog box template
  181. HWND hWndParent, // handle to owner window
  182. DLGPROC lpDialogFunc, // dialog box procedure
  183. LPARAM dwInitParam // initialization value
  184. )
  185. {
  186. lpDialogFunc = (DLGPROC) HookCallback(lpDialogFunc, DialogProcHook);
  187. DPFN( eDbgLevelInfo, "Hooked window proc via CreateDialogParamW.");
  188. return ORIGINAL_API(CreateDialogParamW)(
  189. hInstance,
  190. lpTemplateName,
  191. hWndParent,
  192. lpDialogFunc,
  193. dwInitParam );
  194. }
  195. HWND
  196. APIHOOK(CreateDialogIndirectParamA)(
  197. HINSTANCE hInstance, // handle to module
  198. LPCDLGTEMPLATE lpTemplate, // dialog box template
  199. HWND hWndParent, // handle to owner window
  200. DLGPROC lpDialogFunc, // dialog box procedure
  201. LPARAM lParamInit // initialization value
  202. )
  203. {
  204. lpDialogFunc = (DLGPROC) HookCallback(lpDialogFunc, DialogProcHook);
  205. DPFN( eDbgLevelInfo, "Hooked window proc via CreateDialogIndirectParamA.");
  206. return ORIGINAL_API(CreateDialogIndirectParamA)(
  207. hInstance,
  208. lpTemplate,
  209. hWndParent,
  210. lpDialogFunc,
  211. lParamInit );
  212. }
  213. HWND
  214. APIHOOK(CreateDialogIndirectParamW)(
  215. HINSTANCE hInstance, // handle to module
  216. LPCDLGTEMPLATE lpTemplate, // dialog box template
  217. HWND hWndParent, // handle to owner window
  218. DLGPROC lpDialogFunc, // dialog box procedure
  219. LPARAM lParamInit // initialization value
  220. )
  221. {
  222. lpDialogFunc = (DLGPROC) HookCallback(lpDialogFunc, DialogProcHook);
  223. DPFN( eDbgLevelInfo, "Hooked window proc via CreateDialogIndirectParamW.");
  224. return ORIGINAL_API(CreateDialogIndirectParamW)(
  225. hInstance,
  226. lpTemplate,
  227. hWndParent,
  228. lpDialogFunc,
  229. lParamInit );
  230. }
  231. HWND
  232. APIHOOK(CreateDialogIndirectParamAorW)(
  233. HINSTANCE hInstance, // handle to module
  234. LPCDLGTEMPLATE lpTemplate, // dialog box template
  235. HWND hWndParent, // handle to owner window
  236. DLGPROC lpDialogFunc, // dialog box procedure
  237. LPARAM lParamInit // initialization value
  238. )
  239. {
  240. lpDialogFunc = (DLGPROC) HookCallback(lpDialogFunc, DialogProcHook);
  241. DPFN( eDbgLevelInfo, "Hooked window proc via CreateDialogIndirectParamAorW.");
  242. return ORIGINAL_API(CreateDialogIndirectParamAorW)(
  243. hInstance,
  244. lpTemplate,
  245. hWndParent,
  246. lpDialogFunc,
  247. lParamInit );
  248. }
  249. LONG
  250. APIHOOK(SetWindowLongA)(
  251. HWND hWnd,
  252. int nIndex,
  253. LONG dwNewLong
  254. )
  255. {
  256. if (nIndex == GWL_WNDPROC)
  257. {
  258. LOGN( eDbgLevelError, "Hooked window proc via SetWindowLongA. Pre-hook: 0x%X. ", dwNewLong);
  259. dwNewLong = (LONG) HookCallback((PVOID)dwNewLong, WindowProcHook);
  260. DPFN( eDbgLevelInfo, "Post-hook: 0x%X.", dwNewLong);
  261. }
  262. else if (nIndex == DWL_DLGPROC)
  263. {
  264. LOGN( eDbgLevelError, "Hooked dialog proc via SetWindowLongA. Pre-hook: 0x%X. ", dwNewLong);
  265. dwNewLong = (LONG) HookCallback((PVOID)dwNewLong, DialogProcHook);
  266. DPFN( eDbgLevelInfo, "Post-hook: 0x%X.", dwNewLong);
  267. }
  268. return ORIGINAL_API(SetWindowLongA)(
  269. hWnd,
  270. nIndex,
  271. dwNewLong );
  272. }
  273. LONG
  274. APIHOOK(SetWindowLongW)(
  275. HWND hWnd,
  276. int nIndex,
  277. LONG dwNewLong
  278. )
  279. {
  280. if (nIndex == GWL_WNDPROC)
  281. {
  282. LOGN( eDbgLevelError, "Hooked window proc via SetWindowLongW. Pre-hook: 0x%X. ", dwNewLong);
  283. dwNewLong = (LONG) HookCallback((PVOID)dwNewLong, WindowProcHook);
  284. DPFN( eDbgLevelInfo, "Post-hook: 0x%X.", dwNewLong);
  285. }
  286. else if (nIndex == DWL_DLGPROC)
  287. {
  288. LOGN( eDbgLevelError, "Hooked dialog proc via SetWindowLongW. Pre-hook: 0x%X. ", dwNewLong);
  289. dwNewLong = (LONG) HookCallback((PVOID)dwNewLong, DialogProcHook);
  290. DPFN( eDbgLevelInfo, "Post-hook: 0x%X.", dwNewLong);
  291. }
  292. return ORIGINAL_API(SetWindowLongW)(
  293. hWnd,
  294. nIndex,
  295. dwNewLong );
  296. }
  297. /*++
  298. Register hooked functions
  299. --*/
  300. HOOK_BEGIN
  301. APIHOOK_ENTRY(USER32.DLL, RegisterClassA)
  302. APIHOOK_ENTRY(USER32.DLL, RegisterClassW);
  303. APIHOOK_ENTRY(USER32.DLL, RegisterClassExA);
  304. APIHOOK_ENTRY(USER32.DLL, RegisterClassExW);
  305. APIHOOK_ENTRY(USER32.DLL, CreateDialogParamA);
  306. APIHOOK_ENTRY(USER32.DLL, CreateDialogParamW);
  307. APIHOOK_ENTRY(USER32.DLL, CreateDialogIndirectParamA);
  308. APIHOOK_ENTRY(USER32.DLL, CreateDialogIndirectParamW);
  309. APIHOOK_ENTRY(USER32.DLL, CreateDialogIndirectParamAorW);
  310. APIHOOK_ENTRY(USER32.DLL, SetWindowLongA);
  311. APIHOOK_ENTRY(USER32.DLL, SetWindowLongW);
  312. HOOK_END
  313. IMPLEMENT_SHIM_END