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.

473 lines
14 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. if( NULL == wcNewWndClass.lpfnWndProc ) {
  127. DPFN(eDbgLevelInfo, "Failed to hook window proc via RegisterClassA.");
  128. return ORIGINAL_API(RegisterClassA)(lpWndClass);
  129. }
  130. DPFN(eDbgLevelInfo, "Hooked window proc via RegisterClassA.");
  131. return ORIGINAL_API(RegisterClassA)(&wcNewWndClass);
  132. }
  133. ATOM
  134. APIHOOK(RegisterClassW)(
  135. CONST WNDCLASSW *lpWndClass // class data
  136. )
  137. {
  138. WNDCLASSW wcNewWndClass = *lpWndClass;
  139. wcNewWndClass.lpfnWndProc = (WNDPROC) HookCallback(lpWndClass->lpfnWndProc, WindowProcHook);
  140. if( NULL == wcNewWndClass.lpfnWndProc ) {
  141. DPFN(eDbgLevelInfo, "Failed to hook window proc via RegisterClassW.");
  142. return ORIGINAL_API(RegisterClassW)(lpWndClass);
  143. }
  144. DPFN( eDbgLevelInfo, "Hooked window proc via RegisterClassW.");
  145. return ORIGINAL_API(RegisterClassW)(&wcNewWndClass);
  146. }
  147. ATOM
  148. APIHOOK(RegisterClassExA)(
  149. CONST WNDCLASSEXA *lpwcx // class data
  150. )
  151. {
  152. WNDCLASSEXA wcNewWndClass = *lpwcx;
  153. wcNewWndClass.lpfnWndProc = (WNDPROC) HookCallback(lpwcx->lpfnWndProc, WindowProcHook);
  154. if( NULL == wcNewWndClass.lpfnWndProc ) {
  155. DPFN(eDbgLevelInfo, "Failed to hook window proc via RegisterClassExA.");
  156. return ORIGINAL_API(RegisterClassExA)(lpwcx);
  157. }
  158. DPFN( eDbgLevelInfo, "Hooked window proc via RegisterClassExA.");
  159. return ORIGINAL_API(RegisterClassExA)(&wcNewWndClass);
  160. }
  161. ATOM
  162. APIHOOK(RegisterClassExW)(
  163. CONST WNDCLASSEXW *lpwcx // class data
  164. )
  165. {
  166. WNDCLASSEXW wcNewWndClass = *lpwcx;
  167. wcNewWndClass.lpfnWndProc = (WNDPROC) HookCallback(lpwcx->lpfnWndProc, WindowProcHook);
  168. if( NULL == wcNewWndClass.lpfnWndProc ) {
  169. DPFN(eDbgLevelInfo, "Failed to hook window proc via RegisterClassExW.");
  170. return ORIGINAL_API(RegisterClassExW)(lpwcx);
  171. }
  172. DPFN( eDbgLevelInfo, "Hooked window proc via RegisterClassExW.");
  173. return ORIGINAL_API(RegisterClassExW)(&wcNewWndClass);
  174. }
  175. HWND
  176. APIHOOK(CreateDialogParamA)(
  177. HINSTANCE hInstance, // handle to module
  178. LPCSTR lpTemplateName, // dialog box template
  179. HWND hWndParent, // handle to owner window
  180. DLGPROC lpDialogFunc, // dialog box procedure
  181. LPARAM dwInitParam // initialization value
  182. )
  183. {
  184. DLGPROC lpNewDialogFunc = (DLGPROC) HookCallback(lpDialogFunc, DialogProcHook);
  185. if( NULL == lpNewDialogFunc ) {
  186. DPFN( eDbgLevelInfo, "Failed to hook window proc via CreateDialogParamA.");
  187. return ORIGINAL_API(CreateDialogParamA)(
  188. hInstance,
  189. lpTemplateName,
  190. hWndParent,
  191. lpDialogFunc,
  192. dwInitParam );
  193. }
  194. DPFN( eDbgLevelInfo, "Hooked window proc via CreateDialogParamA.");
  195. return ORIGINAL_API(CreateDialogParamA)(
  196. hInstance,
  197. lpTemplateName,
  198. hWndParent,
  199. lpNewDialogFunc,
  200. dwInitParam );
  201. }
  202. HWND
  203. APIHOOK(CreateDialogParamW)(
  204. HINSTANCE hInstance, // handle to module
  205. LPCWSTR lpTemplateName, // dialog box template
  206. HWND hWndParent, // handle to owner window
  207. DLGPROC lpDialogFunc, // dialog box procedure
  208. LPARAM dwInitParam // initialization value
  209. )
  210. {
  211. DLGPROC lpNewDialogFunc = (DLGPROC) HookCallback(lpDialogFunc, DialogProcHook);
  212. if( NULL == lpNewDialogFunc ) {
  213. DPFN( eDbgLevelInfo, "Failed to hook window proc via CreateDialogParamW.");
  214. return ORIGINAL_API(CreateDialogParamW)(
  215. hInstance,
  216. lpTemplateName,
  217. hWndParent,
  218. lpDialogFunc,
  219. dwInitParam );
  220. }
  221. DPFN( eDbgLevelInfo, "Hooked window proc via CreateDialogParamW.");
  222. return ORIGINAL_API(CreateDialogParamW)(
  223. hInstance,
  224. lpTemplateName,
  225. hWndParent,
  226. lpNewDialogFunc,
  227. dwInitParam );
  228. }
  229. HWND
  230. APIHOOK(CreateDialogIndirectParamA)(
  231. HINSTANCE hInstance, // handle to module
  232. LPCDLGTEMPLATE lpTemplate, // dialog box template
  233. HWND hWndParent, // handle to owner window
  234. DLGPROC lpDialogFunc, // dialog box procedure
  235. LPARAM lParamInit // initialization value
  236. )
  237. {
  238. DLGPROC lpNewDialogFunc = (DLGPROC) HookCallback(lpDialogFunc, DialogProcHook);
  239. if( NULL == lpNewDialogFunc ) {
  240. DPFN( eDbgLevelInfo, "Failed to hook window proc via CreateDialogIndirectParamA.");
  241. return ORIGINAL_API(CreateDialogIndirectParamA)(
  242. hInstance,
  243. lpTemplate,
  244. hWndParent,
  245. lpDialogFunc,
  246. lParamInit );
  247. }
  248. DPFN( eDbgLevelInfo, "Hooked window proc via CreateDialogIndirectParamA.");
  249. return ORIGINAL_API(CreateDialogIndirectParamA)(
  250. hInstance,
  251. lpTemplate,
  252. hWndParent,
  253. lpNewDialogFunc,
  254. lParamInit );
  255. }
  256. HWND
  257. APIHOOK(CreateDialogIndirectParamW)(
  258. HINSTANCE hInstance, // handle to module
  259. LPCDLGTEMPLATE lpTemplate, // dialog box template
  260. HWND hWndParent, // handle to owner window
  261. DLGPROC lpDialogFunc, // dialog box procedure
  262. LPARAM lParamInit // initialization value
  263. )
  264. {
  265. DLGPROC lpNewDialogFunc = (DLGPROC) HookCallback(lpDialogFunc, DialogProcHook);
  266. if( NULL == lpNewDialogFunc ) {
  267. DPFN( eDbgLevelInfo, "Failed to hook window proc via CreateDialogIndirectParamW.");
  268. return ORIGINAL_API(CreateDialogIndirectParamW)(
  269. hInstance,
  270. lpTemplate,
  271. hWndParent,
  272. lpDialogFunc,
  273. lParamInit );
  274. }
  275. DPFN( eDbgLevelInfo, "Hooked window proc via CreateDialogIndirectParamW.");
  276. return ORIGINAL_API(CreateDialogIndirectParamW)(
  277. hInstance,
  278. lpTemplate,
  279. hWndParent,
  280. lpNewDialogFunc,
  281. lParamInit );
  282. }
  283. HWND
  284. APIHOOK(CreateDialogIndirectParamAorW)(
  285. HINSTANCE hInstance, // handle to module
  286. LPCDLGTEMPLATE lpTemplate, // dialog box template
  287. HWND hWndParent, // handle to owner window
  288. DLGPROC lpDialogFunc, // dialog box procedure
  289. LPARAM lParamInit // initialization value
  290. )
  291. {
  292. DLGPROC lpNewDialogFunc = (DLGPROC) HookCallback(lpDialogFunc, DialogProcHook);
  293. if( NULL == lpNewDialogFunc ) {
  294. DPFN( eDbgLevelInfo, "Failed to hook window proc via CreateDialogIndirectParamAorW.");
  295. return ORIGINAL_API(CreateDialogIndirectParamAorW)(
  296. hInstance,
  297. lpTemplate,
  298. hWndParent,
  299. lpDialogFunc,
  300. lParamInit );
  301. }
  302. DPFN( eDbgLevelInfo, "Hooked window proc via CreateDialogIndirectParamAorW.");
  303. return ORIGINAL_API(CreateDialogIndirectParamAorW)(
  304. hInstance,
  305. lpTemplate,
  306. hWndParent,
  307. lpNewDialogFunc,
  308. lParamInit );
  309. }
  310. LONG
  311. APIHOOK(SetWindowLongA)(
  312. HWND hWnd,
  313. int nIndex,
  314. LONG dwNewLong
  315. )
  316. {
  317. if (nIndex == GWL_WNDPROC)
  318. {
  319. LOGN( eDbgLevelError, "Hooked window proc via SetWindowLongA. Pre-hook: 0x%X. ", dwNewLong);
  320. LONG tmp = (LONG) HookCallback((PVOID)dwNewLong, WindowProcHook);
  321. if( NULL != tmp) {
  322. dwNewLong = tmp;
  323. }
  324. DPFN( eDbgLevelInfo, "Post-hook: 0x%X.", dwNewLong);
  325. }
  326. else if (nIndex == DWL_DLGPROC)
  327. {
  328. LOGN( eDbgLevelError, "Hooked dialog proc via SetWindowLongA. Pre-hook: 0x%X. ", dwNewLong);
  329. LONG tmp = (LONG) HookCallback((PVOID)dwNewLong, DialogProcHook);
  330. if( NULL != tmp) {
  331. dwNewLong = tmp;
  332. }
  333. DPFN( eDbgLevelInfo, "Post-hook: 0x%X.", dwNewLong);
  334. }
  335. return ORIGINAL_API(SetWindowLongA)(
  336. hWnd,
  337. nIndex,
  338. dwNewLong );
  339. }
  340. LONG
  341. APIHOOK(SetWindowLongW)(
  342. HWND hWnd,
  343. int nIndex,
  344. LONG dwNewLong
  345. )
  346. {
  347. if (nIndex == GWL_WNDPROC)
  348. {
  349. LOGN( eDbgLevelError, "Hooked window proc via SetWindowLongW. Pre-hook: 0x%X. ", dwNewLong);
  350. LONG tmp = (LONG) HookCallback((PVOID)dwNewLong, WindowProcHook);
  351. if( NULL != tmp) {
  352. dwNewLong = tmp;
  353. }
  354. DPFN( eDbgLevelInfo, "Post-hook: 0x%X.", dwNewLong);
  355. }
  356. else if (nIndex == DWL_DLGPROC)
  357. {
  358. LOGN( eDbgLevelError, "Hooked dialog proc via SetWindowLongW. Pre-hook: 0x%X. ", dwNewLong);
  359. LONG tmp = (LONG) HookCallback((PVOID)dwNewLong, DialogProcHook);
  360. if( NULL != tmp) {
  361. dwNewLong = tmp;
  362. }
  363. DPFN( eDbgLevelInfo, "Post-hook: 0x%X.", dwNewLong);
  364. }
  365. return ORIGINAL_API(SetWindowLongW)(
  366. hWnd,
  367. nIndex,
  368. dwNewLong );
  369. }
  370. /*++
  371. Register hooked functions
  372. --*/
  373. HOOK_BEGIN
  374. APIHOOK_ENTRY(USER32.DLL, RegisterClassA)
  375. APIHOOK_ENTRY(USER32.DLL, RegisterClassW);
  376. APIHOOK_ENTRY(USER32.DLL, RegisterClassExA);
  377. APIHOOK_ENTRY(USER32.DLL, RegisterClassExW);
  378. APIHOOK_ENTRY(USER32.DLL, CreateDialogParamA);
  379. APIHOOK_ENTRY(USER32.DLL, CreateDialogParamW);
  380. APIHOOK_ENTRY(USER32.DLL, CreateDialogIndirectParamA);
  381. APIHOOK_ENTRY(USER32.DLL, CreateDialogIndirectParamW);
  382. APIHOOK_ENTRY(USER32.DLL, CreateDialogIndirectParamAorW);
  383. APIHOOK_ENTRY(USER32.DLL, SetWindowLongA);
  384. APIHOOK_ENTRY(USER32.DLL, SetWindowLongW);
  385. HOOK_END
  386. IMPLEMENT_SHIM_END