windows-nt/Source/XPSP1/NT/windows/appcompat/shims/general/disablew2kownerdrawbuttonstates.cpp
2020-09-26 16:20:57 +08:00

395 lines
10 KiB
C++

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
DisableW2KOwnerDrawButtonStates.cpp
Abstract:
Hooks all application-defined window procedures and filters out new
owner-draw buttons states (introduced in Win2000).
Notes:
This shim can be reused for other shims that require WindowProc hooking.
Copy all APIHook_* functions and simply replace the code in WindowProcHook
and DialogProcHook.
History:
11/01/1999 markder Created
02/15/1999 markder Reworked WndProc hooking mechanism so that it generically
hooks all WndProcs for the process.
11/29/2000 andyseti Converted into GeneralPurpose shim.
--*/
#include "precomp.h"
IMPLEMENT_SHIM_BEGIN(DisableW2KOwnerDrawButtonStates)
#include "ShimHookMacro.h"
APIHOOK_ENUM_BEGIN
APIHOOK_ENUM_ENTRY(RegisterClassA)
APIHOOK_ENUM_ENTRY(RegisterClassW)
APIHOOK_ENUM_ENTRY(RegisterClassExA)
APIHOOK_ENUM_ENTRY(RegisterClassExW)
APIHOOK_ENUM_ENTRY(CreateDialogParamA)
APIHOOK_ENUM_ENTRY(CreateDialogParamW)
APIHOOK_ENUM_ENTRY(CreateDialogIndirectParamA)
APIHOOK_ENUM_ENTRY(CreateDialogIndirectParamW)
APIHOOK_ENUM_ENTRY(CreateDialogIndirectParamAorW)
APIHOOK_ENUM_ENTRY(SetWindowLongA)
APIHOOK_ENUM_ENTRY(SetWindowLongW)
APIHOOK_ENUM_END
/*++
Change WM_DRAWITEM behaviour
--*/
LRESULT CALLBACK
WindowProcHook(
WNDPROC pfnOld, // address of old WindowProc
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
// Check for message we're interested in
if (uMsg == WM_DRAWITEM)
{
if (((LPDRAWITEMSTRUCT) lParam)->itemState &
~(ODS_SELECTED |
ODS_GRAYED |
ODS_DISABLED |
ODS_CHECKED |
ODS_FOCUS |
ODS_DEFAULT |
ODS_COMBOBOXEDIT |
ODS_HOTLIGHT |
ODS_INACTIVE))
{
LOGN(eDbgLevelError, "Removed Win2K-specific Owner-draw button flags.");
// Remove all Win9x-incompatible owner draw button states.
((LPDRAWITEMSTRUCT) lParam)->itemState &=
(ODS_SELECTED |
ODS_GRAYED |
ODS_DISABLED |
ODS_CHECKED |
ODS_FOCUS |
ODS_DEFAULT |
ODS_COMBOBOXEDIT |
ODS_HOTLIGHT |
ODS_INACTIVE);
}
}
return (*pfnOld)(hwnd, uMsg, wParam, lParam);
}
INT_PTR CALLBACK
DialogProcHook(
DLGPROC pfnOld, // address of old DialogProc
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
// Check for message we're interested in
if (uMsg == WM_DRAWITEM)
{
if (((LPDRAWITEMSTRUCT) lParam)->itemState &
~(ODS_SELECTED |
ODS_GRAYED |
ODS_DISABLED |
ODS_CHECKED |
ODS_FOCUS |
ODS_DEFAULT |
ODS_COMBOBOXEDIT |
ODS_HOTLIGHT |
ODS_INACTIVE))
{
LOGN(eDbgLevelError, "Removed Win2K-specific Owner-draw button flags.");
// Remove all Win9x-incompatible owner draw button states.
((LPDRAWITEMSTRUCT) lParam)->itemState &=
(ODS_SELECTED |
ODS_GRAYED |
ODS_DISABLED |
ODS_CHECKED |
ODS_FOCUS |
ODS_DEFAULT |
ODS_COMBOBOXEDIT |
ODS_HOTLIGHT |
ODS_INACTIVE);
}
}
return (*pfnOld)(hwndDlg, uMsg, wParam, lParam);
}
/*++
Hook all possible calls that can initialize or change a window's
WindowProc (or DialogProc)
--*/
ATOM
APIHOOK(RegisterClassA)(
CONST WNDCLASSA *lpWndClass // class data
)
{
WNDCLASSA wcNewWndClass = *lpWndClass;
wcNewWndClass.lpfnWndProc = (WNDPROC) HookCallback(lpWndClass->lpfnWndProc, WindowProcHook);
DPFN(eDbgLevelInfo, "Hooked window proc via RegisterClassA.");
return ORIGINAL_API(RegisterClassA)(&wcNewWndClass);
}
ATOM
APIHOOK(RegisterClassW)(
CONST WNDCLASSW *lpWndClass // class data
)
{
WNDCLASSW wcNewWndClass = *lpWndClass;
wcNewWndClass.lpfnWndProc = (WNDPROC) HookCallback(lpWndClass->lpfnWndProc, WindowProcHook);
DPFN( eDbgLevelInfo, "Hooked window proc via RegisterClassW.");
return ORIGINAL_API(RegisterClassW)(&wcNewWndClass);
}
ATOM
APIHOOK(RegisterClassExA)(
CONST WNDCLASSEXA *lpwcx // class data
)
{
WNDCLASSEXA wcNewWndClass = *lpwcx;
wcNewWndClass.lpfnWndProc = (WNDPROC) HookCallback(lpwcx->lpfnWndProc, WindowProcHook);
DPFN( eDbgLevelInfo, "Hooked window proc via RegisterClassExA.");
return ORIGINAL_API(RegisterClassExA)(&wcNewWndClass);
}
ATOM
APIHOOK(RegisterClassExW)(
CONST WNDCLASSEXW *lpwcx // class data
)
{
WNDCLASSEXW wcNewWndClass = *lpwcx;
wcNewWndClass.lpfnWndProc = (WNDPROC) HookCallback(lpwcx->lpfnWndProc, WindowProcHook);
DPFN( eDbgLevelInfo, "Hooked window proc via RegisterClassExW.");
return ORIGINAL_API(RegisterClassExW)(&wcNewWndClass);
}
HWND
APIHOOK(CreateDialogParamA)(
HINSTANCE hInstance, // handle to module
LPCSTR lpTemplateName, // dialog box template
HWND hWndParent, // handle to owner window
DLGPROC lpDialogFunc, // dialog box procedure
LPARAM dwInitParam // initialization value
)
{
lpDialogFunc = (DLGPROC) HookCallback(lpDialogFunc, DialogProcHook);
DPFN( eDbgLevelInfo, "Hooked window proc via CreateDialogParamA.");
return ORIGINAL_API(CreateDialogParamA)(
hInstance,
lpTemplateName,
hWndParent,
lpDialogFunc,
dwInitParam );
}
HWND
APIHOOK(CreateDialogParamW)(
HINSTANCE hInstance, // handle to module
LPCWSTR lpTemplateName, // dialog box template
HWND hWndParent, // handle to owner window
DLGPROC lpDialogFunc, // dialog box procedure
LPARAM dwInitParam // initialization value
)
{
lpDialogFunc = (DLGPROC) HookCallback(lpDialogFunc, DialogProcHook);
DPFN( eDbgLevelInfo, "Hooked window proc via CreateDialogParamW.");
return ORIGINAL_API(CreateDialogParamW)(
hInstance,
lpTemplateName,
hWndParent,
lpDialogFunc,
dwInitParam );
}
HWND
APIHOOK(CreateDialogIndirectParamA)(
HINSTANCE hInstance, // handle to module
LPCDLGTEMPLATE lpTemplate, // dialog box template
HWND hWndParent, // handle to owner window
DLGPROC lpDialogFunc, // dialog box procedure
LPARAM lParamInit // initialization value
)
{
lpDialogFunc = (DLGPROC) HookCallback(lpDialogFunc, DialogProcHook);
DPFN( eDbgLevelInfo, "Hooked window proc via CreateDialogIndirectParamA.");
return ORIGINAL_API(CreateDialogIndirectParamA)(
hInstance,
lpTemplate,
hWndParent,
lpDialogFunc,
lParamInit );
}
HWND
APIHOOK(CreateDialogIndirectParamW)(
HINSTANCE hInstance, // handle to module
LPCDLGTEMPLATE lpTemplate, // dialog box template
HWND hWndParent, // handle to owner window
DLGPROC lpDialogFunc, // dialog box procedure
LPARAM lParamInit // initialization value
)
{
lpDialogFunc = (DLGPROC) HookCallback(lpDialogFunc, DialogProcHook);
DPFN( eDbgLevelInfo, "Hooked window proc via CreateDialogIndirectParamW.");
return ORIGINAL_API(CreateDialogIndirectParamW)(
hInstance,
lpTemplate,
hWndParent,
lpDialogFunc,
lParamInit );
}
HWND
APIHOOK(CreateDialogIndirectParamAorW)(
HINSTANCE hInstance, // handle to module
LPCDLGTEMPLATE lpTemplate, // dialog box template
HWND hWndParent, // handle to owner window
DLGPROC lpDialogFunc, // dialog box procedure
LPARAM lParamInit // initialization value
)
{
lpDialogFunc = (DLGPROC) HookCallback(lpDialogFunc, DialogProcHook);
DPFN( eDbgLevelInfo, "Hooked window proc via CreateDialogIndirectParamAorW.");
return ORIGINAL_API(CreateDialogIndirectParamAorW)(
hInstance,
lpTemplate,
hWndParent,
lpDialogFunc,
lParamInit );
}
LONG
APIHOOK(SetWindowLongA)(
HWND hWnd,
int nIndex,
LONG dwNewLong
)
{
if (nIndex == GWL_WNDPROC)
{
LOGN( eDbgLevelError, "Hooked window proc via SetWindowLongA. Pre-hook: 0x%X. ", dwNewLong);
dwNewLong = (LONG) HookCallback((PVOID)dwNewLong, WindowProcHook);
DPFN( eDbgLevelInfo, "Post-hook: 0x%X.", dwNewLong);
}
else if (nIndex == DWL_DLGPROC)
{
LOGN( eDbgLevelError, "Hooked dialog proc via SetWindowLongA. Pre-hook: 0x%X. ", dwNewLong);
dwNewLong = (LONG) HookCallback((PVOID)dwNewLong, DialogProcHook);
DPFN( eDbgLevelInfo, "Post-hook: 0x%X.", dwNewLong);
}
return ORIGINAL_API(SetWindowLongA)(
hWnd,
nIndex,
dwNewLong );
}
LONG
APIHOOK(SetWindowLongW)(
HWND hWnd,
int nIndex,
LONG dwNewLong
)
{
if (nIndex == GWL_WNDPROC)
{
LOGN( eDbgLevelError, "Hooked window proc via SetWindowLongW. Pre-hook: 0x%X. ", dwNewLong);
dwNewLong = (LONG) HookCallback((PVOID)dwNewLong, WindowProcHook);
DPFN( eDbgLevelInfo, "Post-hook: 0x%X.", dwNewLong);
}
else if (nIndex == DWL_DLGPROC)
{
LOGN( eDbgLevelError, "Hooked dialog proc via SetWindowLongW. Pre-hook: 0x%X. ", dwNewLong);
dwNewLong = (LONG) HookCallback((PVOID)dwNewLong, DialogProcHook);
DPFN( eDbgLevelInfo, "Post-hook: 0x%X.", dwNewLong);
}
return ORIGINAL_API(SetWindowLongW)(
hWnd,
nIndex,
dwNewLong );
}
/*++
Register hooked functions
--*/
HOOK_BEGIN
APIHOOK_ENTRY(USER32.DLL, RegisterClassA)
APIHOOK_ENTRY(USER32.DLL, RegisterClassW);
APIHOOK_ENTRY(USER32.DLL, RegisterClassExA);
APIHOOK_ENTRY(USER32.DLL, RegisterClassExW);
APIHOOK_ENTRY(USER32.DLL, CreateDialogParamA);
APIHOOK_ENTRY(USER32.DLL, CreateDialogParamW);
APIHOOK_ENTRY(USER32.DLL, CreateDialogIndirectParamA);
APIHOOK_ENTRY(USER32.DLL, CreateDialogIndirectParamW);
APIHOOK_ENTRY(USER32.DLL, CreateDialogIndirectParamAorW);
APIHOOK_ENTRY(USER32.DLL, SetWindowLongA);
APIHOOK_ENTRY(USER32.DLL, SetWindowLongW);
HOOK_END
IMPLEMENT_SHIM_END