2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS user32.dll
4 * FILE: win32ss/user/user32/misc/usrapihk.c
5 * PURPOSE: User32.dll User32 Api Hook interface and support functions
11 * http://www.reactos.org/wiki/RegisterUserApiHook
16 #include <wine/debug.h>
18 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
20 BOOL WINAPI
RealAdjustWindowRectEx(LPRECT
,DWORD
,BOOL
,DWORD
);
21 LRESULT WINAPI
RealDefWindowProcA(HWND
,UINT
,WPARAM
,LPARAM
);
22 LRESULT WINAPI
RealDefWindowProcW(HWND
,UINT
,WPARAM
,LPARAM
);
23 BOOL WINAPI
RealDrawFrameControl(HDC
,LPRECT
,UINT
,UINT
);
24 BOOL WINAPI
RealGetScrollInfo(HWND
,INT
,LPSCROLLINFO
);
25 int WINAPI
RealGetSystemMetrics(int);
26 BOOL WINAPI
RealMDIRedrawFrame(HWND
,DWORD
);
27 INT WINAPI
RealSetScrollInfo(HWND
,int,LPCSCROLLINFO
,BOOL
);
28 BOOL WINAPI
RealSystemParametersInfoA(UINT
,UINT
,PVOID
,UINT
);
29 BOOL WINAPI
RealSystemParametersInfoW(UINT
,UINT
,PVOID
,UINT
);
30 DWORD WINAPI
GetRealWindowOwner(HWND
);
31 LRESULT WINAPI
RealUserDrawCaption(HWND hWnd
, HDC hDC
, LPCRECT lpRc
, UINT uFlags
);
33 /* GLOBALS *******************************************************************/
35 DWORD gcLoadUserApiHook
= 0;
36 LONG gcCallUserApiHook
= 0;
37 DWORD gfUserApiHook
= 0;
38 HINSTANCE ghmodUserApiHook
= NULL
;
39 USERAPIHOOKPROC gpfnInitUserApi
;
40 RTL_CRITICAL_SECTION gcsUserApiHook
;
41 // API Hooked Message group bitmaps
42 BYTE grgbDwpLiteHookMsg
[128];
43 BYTE grgbWndLiteHookMsg
[128];
44 BYTE grgbDlgLiteHookMsg
[128];
46 /* INTERNAL ******************************************************************/
49 Pre and Post Message handler stub.
53 DefaultOWP(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
, ULONG_PTR lResult
, PDWORD pData
)
59 Check for API Hooked Message Overrides. Using message bitmapping.. One bit
60 corresponds to one message number.
64 IsMsgOverride( UINT Msg
, PUAHOWP puaowpOverride
)
66 UINT nMsg
= Msg
/ 8; // Group Indexed, (Msg 1024) / 8 = (0 -> 127) bytes Max
68 if ( puaowpOverride
&& nMsg
< puaowpOverride
->Size
)
70 return (puaowpOverride
->MsgBitArray
[nMsg
] & (1 << (Msg
& WM_SETFOCUS
)));
77 CopyMsgMask(PUAHOWP Dest
, PUAHOWP Src
, PVOID hkmsg
, DWORD Size
)
81 if ( Src
&& Src
->Size
> 0 )
83 Dest
->MsgBitArray
= hkmsg
;
85 if ( Size
< nSize
) nSize
= Size
;
87 RtlCopyMemory(Dest
->MsgBitArray
, Src
->MsgBitArray
, nSize
);
91 Dest
->MsgBitArray
= NULL
;
99 IsInsideUserApiHook(VOID
)
101 if ( ghmodUserApiHook
&& gfUserApiHook
) return TRUE
;
107 BeginIfHookedUserApiHook(VOID
)
109 InterlockedIncrement(&gcCallUserApiHook
);
110 if (IsInsideUserApiHook()) return TRUE
;
112 InterlockedDecrement(&gcCallUserApiHook
);
118 ForceResetUserApiHook(HINSTANCE hInstance
)
120 if ( ghmodUserApiHook
== hInstance
&&
121 RtlIsThreadWithinLoaderCallout() )
123 ResetUserApiHook(&guah
);
124 gpfnInitUserApi
= NULL
;
132 ResetUserApiHook(PUSERAPIHOOK puah
)
134 // Setup Structure.....
135 puah
->size
= sizeof(USERAPIHOOK
);
136 puah
->DefWindowProcA
= RealDefWindowProcA
;
137 puah
->DefWindowProcW
= RealDefWindowProcW
;
138 puah
->DefWndProcArray
.MsgBitArray
= NULL
;
139 puah
->DefWndProcArray
.Size
= 0;
140 puah
->GetScrollInfo
= (FARPROC
)RealGetScrollInfo
;
141 puah
->SetScrollInfo
= (FARPROC
)RealSetScrollInfo
;
142 puah
->EnableScrollBar
= (FARPROC
)NtUserEnableScrollBar
;
143 puah
->AdjustWindowRectEx
= (FARPROC
)RealAdjustWindowRectEx
;
144 puah
->SetWindowRgn
= NtUserSetWindowRgn
;
145 puah
->PreWndProc
= DefaultOWP
;
146 puah
->PostWndProc
= DefaultOWP
;
147 puah
->WndProcArray
.MsgBitArray
= NULL
;
148 puah
->WndProcArray
.Size
= 0;
149 puah
->PreDefDlgProc
= DefaultOWP
;
150 puah
->PostDefDlgProc
= DefaultOWP
;
151 puah
->DlgProcArray
.MsgBitArray
= NULL
;
152 puah
->DlgProcArray
.Size
= 0;
153 puah
->GetSystemMetrics
= (FARPROC
)RealGetSystemMetrics
;
154 puah
->SystemParametersInfoA
= (FARPROC
)RealSystemParametersInfoA
;
155 puah
->SystemParametersInfoW
= (FARPROC
)RealSystemParametersInfoW
;
156 puah
->ForceResetUserApiHook
= (FARPROC
)ForceResetUserApiHook
;
157 puah
->DrawFrameControl
= (FARPROC
)RealDrawFrameControl
;
158 puah
->DrawCaption
= (FARPROC
)RealUserDrawCaption
;
159 puah
->MDIRedrawFrame
= (FARPROC
)RealMDIRedrawFrame
;
160 puah
->GetRealWindowOwner
= (FARPROC
)GetRealWindowOwner
;
171 if ( !InterlockedDecrement(&gcCallUserApiHook
) )
173 if ( !gcLoadUserApiHook
)
175 RtlEnterCriticalSection(&gcsUserApiHook
);
177 pfn
= gpfnInitUserApi
;
178 hModule
= ghmodUserApiHook
;
179 ghmodUserApiHook
= NULL
;
180 gpfnInitUserApi
= NULL
;
182 RtlLeaveCriticalSection(&gcsUserApiHook
);
184 if ( pfn
) Ret
= pfn(uahStop
, 0);
186 if ( hModule
) Ret
= FreeLibrary(hModule
);
194 ClearUserApiHook(HINSTANCE hInstance
)
197 USERAPIHOOKPROC pfn
= NULL
, pfn1
= NULL
;
199 RtlEnterCriticalSection(&gcsUserApiHook
);
200 hModule
= ghmodUserApiHook
;
201 if ( ghmodUserApiHook
== hInstance
)
203 pfn1
= gpfnInitUserApi
;
204 if ( --gcLoadUserApiHook
== 0 )
207 ResetUserApiHook(&guah
);
208 if ( gcCallUserApiHook
)
212 pfn
= gpfnInitUserApi
;
213 gcLoadUserApiHook
= 1;
218 ghmodUserApiHook
= NULL
;
219 gpfnInitUserApi
= NULL
;
223 RtlLeaveCriticalSection(&gcsUserApiHook
);
227 pfn(uahShutdown
, 0); // Shutdown.
229 RtlEnterCriticalSection(&gcsUserApiHook
);
230 pfn1
= gpfnInitUserApi
;
232 if ( --gcLoadUserApiHook
== 0 )
234 if ( gcCallUserApiHook
)
241 hInstance
= ghmodUserApiHook
;
242 ghmodUserApiHook
= NULL
;
243 gpfnInitUserApi
= NULL
;
246 RtlLeaveCriticalSection(&gcsUserApiHook
);
249 if ( pfn1
) pfn1(uahStop
, 0);
251 return hInstance
!= 0;
256 InitUserApiHook(HINSTANCE hInstance
, USERAPIHOOKPROC pfn
)
260 ResetUserApiHook(&uah
);
262 RtlEnterCriticalSection(&gcsUserApiHook
);
264 if (!pfn(uahLoadInit
,&uah
) || // Swap data, User32 to and Uxtheme from!
265 uah
.ForceResetUserApiHook
!= (FARPROC
)ForceResetUserApiHook
||
268 RtlLeaveCriticalSection(&gcsUserApiHook
);
272 if ( ghmodUserApiHook
)
274 if ( ghmodUserApiHook
!= hInstance
)
276 RtlLeaveCriticalSection(&gcsUserApiHook
);
284 ghmodUserApiHook
= hInstance
;
285 // Do not over write GetRealWindowOwner.
286 RtlCopyMemory(&guah
, &uah
, sizeof(USERAPIHOOK
) - sizeof(LONG
));
287 gpfnInitUserApi
= pfn
;
288 gcLoadUserApiHook
= 1;
290 // Copy Message Masks
291 CopyMsgMask(&guah
.DefWndProcArray
,
292 &uah
.DefWndProcArray
,
294 sizeof(grgbDwpLiteHookMsg
));
296 CopyMsgMask(&guah
.WndProcArray
,
299 sizeof(grgbWndLiteHookMsg
));
301 CopyMsgMask(&guah
.DlgProcArray
,
304 sizeof(grgbDlgLiteHookMsg
));
306 RtlLeaveCriticalSection(&gcsUserApiHook
);
312 RealMDIRedrawFrame(HWND hWnd
, DWORD flags
)
314 return NtUserxMDIRedrawFrame(hWnd
);
319 MDIRedrawFrame(HWND hWnd
, DWORD flags
)
321 BOOL Hook
, Ret
= FALSE
;
325 Hook
= BeginIfHookedUserApiHook();
327 /* Bypass SEH and go direct. */
328 if (!Hook
) return RealMDIRedrawFrame(hWnd
, flags
);
332 Ret
= guah
.MDIRedrawFrame(hWnd
, flags
);
334 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
350 (FARPROC
)RealGetScrollInfo
,
351 (FARPROC
)RealSetScrollInfo
,
352 (FARPROC
)NtUserEnableScrollBar
,
353 (FARPROC
)RealAdjustWindowRectEx
,
361 (FARPROC
)RealGetSystemMetrics
,
362 (FARPROC
)RealSystemParametersInfoA
,
363 (FARPROC
)RealSystemParametersInfoW
,
364 (FARPROC
)ForceResetUserApiHook
,
365 (FARPROC
)RealDrawFrameControl
,
366 (FARPROC
)NtUserDrawCaption
,
367 (FARPROC
)RealMDIRedrawFrame
,
368 (FARPROC
)GetRealWindowOwner
,
371 /* FUNCTIONS *****************************************************************/
376 BOOL WINAPI
RegisterUserApiHook(PUSERAPIHOOKINFO puah
)
378 UNICODE_STRING m_dllname1
;
379 UNICODE_STRING m_funname1
;
381 if (puah
->m_size
== sizeof(USERAPIHOOKINFO
))
383 WARN("RegisterUserApiHook: %S and %S",puah
->m_dllname1
, puah
->m_funname1
);
384 RtlInitUnicodeString(&m_dllname1
, puah
->m_dllname1
);
385 RtlInitUnicodeString(&m_funname1
, puah
->m_funname1
);
386 return NtUserRegisterUserApiHook( &m_dllname1
, &m_funname1
, 0, 0);
394 BOOL WINAPI
UnregisterUserApiHook(VOID
)
396 return NtUserUnregisterUserApiHook();