2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS user32.dll
4 * FILE: dll/win32/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
);
31 /* GLOBALS *******************************************************************/
33 DWORD gcLoadUserApiHook
= 0;
34 LONG gcCallUserApiHook
= 0;
36 HINSTANCE ghmodUserApiHook
= NULL
;
37 USERAPIHOOKPROC gpfnInitUserApi
;
38 RTL_CRITICAL_SECTION gcsUserApiHook
;
39 // API Hooked Message group bitmaps
40 BYTE grgbDwpLiteHookMsg
[128];
41 BYTE grgbWndLiteHookMsg
[128];
42 BYTE grgbDlgLiteHookMsg
[128];
44 /* INTERNAL ******************************************************************/
47 Pre and Post Message handler stub.
51 DefaultOWP(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
, ULONG_PTR lResult
, PDWORD pData
)
57 Check for API Hooked Message Overrides. Using message bitmapping.. One bit
58 corresponds to one message number.
62 IsMsgOverride( UINT Msg
, PUAHOWP puaowpOverride
)
64 UINT nMsg
= Msg
/ 8; // Group Indexed, (Msg 1024) / 8 = (0 -> 127) bytes Max
66 if ( puaowpOverride
&& nMsg
< puaowpOverride
->Size
)
68 return (puaowpOverride
->MsgBitArray
[nMsg
] & (1 << (Msg
& WM_SETFOCUS
)));
75 CopyMsgMask(PUAHOWP Dest
, PUAHOWP Src
, PVOID hkmsg
, DWORD Size
)
79 if ( Src
&& Src
->Size
> 0 )
81 Dest
->MsgBitArray
= hkmsg
;
83 if ( Size
< nSize
) nSize
= Size
;
85 RtlCopyMemory(Dest
->MsgBitArray
, Src
->MsgBitArray
, nSize
);
89 Dest
->MsgBitArray
= NULL
;
97 IsInsideUserApiHook(VOID
)
99 if ( ghmodUserApiHook
&& gfUserApiHook
) return TRUE
;
105 BeginIfHookedUserApiHook(VOID
)
107 InterlockedIncrement(&gcCallUserApiHook
);
108 if (IsInsideUserApiHook()) return TRUE
;
110 InterlockedDecrement(&gcCallUserApiHook
);
116 ForceResetUserApiHook(HINSTANCE hInstance
)
118 if ( ghmodUserApiHook
== hInstance
&&
119 RtlIsThreadWithinLoaderCallout() )
121 ResetUserApiHook(&guah
);
122 gpfnInitUserApi
= NULL
;
130 ResetUserApiHook(PUSERAPIHOOK puah
)
132 // Setup Structure.....
133 puah
->size
= sizeof(USERAPIHOOK
);
134 puah
->DefWindowProcA
= (WNDPROC
)RealDefWindowProcA
;
135 puah
->DefWindowProcW
= (WNDPROC
)RealDefWindowProcW
;
136 puah
->DefWndProcArray
.MsgBitArray
= NULL
;
137 puah
->DefWndProcArray
.Size
= 0;
138 puah
->GetScrollInfo
= (FARPROC
)RealGetScrollInfo
;
139 puah
->SetScrollInfo
= (FARPROC
)RealSetScrollInfo
;
140 puah
->EnableScrollBar
= (FARPROC
)NtUserEnableScrollBar
;
141 puah
->AdjustWindowRectEx
= (FARPROC
)RealAdjustWindowRectEx
;
142 puah
->SetWindowRgn
= (FARPROC
)NtUserSetWindowRgn
;
143 puah
->PreWndProc
= (WNDPROC_OWP
)DefaultOWP
;
144 puah
->PostWndProc
= (WNDPROC_OWP
)DefaultOWP
;
145 puah
->WndProcArray
.MsgBitArray
= NULL
;
146 puah
->WndProcArray
.Size
= 0;
147 puah
->PreDefDlgProc
= (WNDPROC_OWP
)DefaultOWP
;
148 puah
->PostDefDlgProc
= (WNDPROC_OWP
)DefaultOWP
;
149 puah
->DlgProcArray
.MsgBitArray
= NULL
;
150 puah
->DlgProcArray
.Size
= 0;
151 puah
->GetSystemMetrics
= (FARPROC
)RealGetSystemMetrics
;
152 puah
->SystemParametersInfoA
= (FARPROC
)RealSystemParametersInfoA
;
153 puah
->SystemParametersInfoW
= (FARPROC
)RealSystemParametersInfoW
;
154 puah
->ForceResetUserApiHook
= (FARPROC
)ForceResetUserApiHook
;
155 puah
->DrawFrameControl
= (FARPROC
)RealDrawFrameControl
;
156 puah
->DrawCaption
= (FARPROC
)NtUserDrawCaption
;
157 puah
->MDIRedrawFrame
= (FARPROC
)RealMDIRedrawFrame
;
158 puah
->GetRealWindowOwner
= (FARPROC
)GetRealWindowOwner
;
169 if ( !InterlockedDecrement(&gcCallUserApiHook
) )
171 if ( !gcLoadUserApiHook
)
173 RtlEnterCriticalSection(&gcsUserApiHook
);
175 pfn
= gpfnInitUserApi
;
176 hModule
= ghmodUserApiHook
;
177 ghmodUserApiHook
= NULL
;
178 gpfnInitUserApi
= NULL
;
180 RtlLeaveCriticalSection(&gcsUserApiHook
);
182 if ( pfn
) Ret
= pfn(uahStop
, 0);
184 if ( hModule
) Ret
= FreeLibrary(hModule
);
192 ClearUserApiHook(HINSTANCE hInstance
)
195 USERAPIHOOKPROC pfn
= NULL
, pfn1
= NULL
;
197 RtlEnterCriticalSection(&gcsUserApiHook
);
198 hModule
= ghmodUserApiHook
;
199 if ( ghmodUserApiHook
== hInstance
)
201 pfn1
= gpfnInitUserApi
;
202 if ( --gcLoadUserApiHook
== 1 )
205 ResetUserApiHook(&guah
);
206 if ( gcCallUserApiHook
)
210 pfn
= gpfnInitUserApi
;
211 gcLoadUserApiHook
= 1;
216 ghmodUserApiHook
= NULL
;
217 gpfnInitUserApi
= NULL
;
221 RtlLeaveCriticalSection(&gcsUserApiHook
);
225 pfn(uahShutdown
, 0); // Shutdown.
227 RtlEnterCriticalSection(&gcsUserApiHook
);
228 pfn1
= gpfnInitUserApi
;
230 if ( --gcLoadUserApiHook
== 1 )
232 if ( gcCallUserApiHook
)
239 hInstance
= ghmodUserApiHook
;
240 ghmodUserApiHook
= NULL
;
241 gpfnInitUserApi
= NULL
;
244 RtlLeaveCriticalSection(&gcsUserApiHook
);
247 if ( pfn1
) pfn1(uahStop
, 0);
249 return hInstance
!= 0;
254 InitUserApiHook(HINSTANCE hInstance
, USERAPIHOOKPROC pfn
)
258 ResetUserApiHook(&uah
);
260 RtlEnterCriticalSection(&gcsUserApiHook
);
262 if (!pfn(uahLoadInit
,(ULONG_PTR
)&uah
) || // Swap data, User32 to and Uxtheme from!
263 uah
.ForceResetUserApiHook
!= (FARPROC
)ForceResetUserApiHook
||
266 RtlLeaveCriticalSection(&gcsUserApiHook
);
270 if ( ghmodUserApiHook
)
272 if ( ghmodUserApiHook
!= hInstance
)
274 RtlLeaveCriticalSection(&gcsUserApiHook
);
282 ghmodUserApiHook
= hInstance
;
283 // Do not over write GetRealWindowOwner.
284 RtlCopyMemory(&guah
, &uah
, sizeof(USERAPIHOOK
) - sizeof(LONG
));
285 gpfnInitUserApi
= pfn
;
286 gcLoadUserApiHook
= 1;
288 // Copy Message Masks
289 CopyMsgMask(&guah
.DefWndProcArray
,
290 &uah
.DefWndProcArray
,
292 sizeof(grgbDwpLiteHookMsg
));
294 CopyMsgMask(&guah
.WndProcArray
,
297 sizeof(grgbWndLiteHookMsg
));
299 CopyMsgMask(&guah
.DlgProcArray
,
302 sizeof(grgbDlgLiteHookMsg
));
304 RtlLeaveCriticalSection(&gcsUserApiHook
);
310 RealMDIRedrawFrame(HWND hWnd
, DWORD flags
)
312 return (BOOL
)NtUserCallHwndLock(hWnd
, HWNDLOCK_ROUTINE_REDRAWFRAME
);
317 MDIRedrawFrame(HWND hWnd
, DWORD flags
)
319 BOOL Hook
, Ret
= FALSE
;
323 Hook
= BeginIfHookedUserApiHook();
325 /* Bypass SEH and go direct. */
326 if (!Hook
) return RealMDIRedrawFrame(hWnd
, flags
);
330 Ret
= guah
.MDIRedrawFrame(hWnd
, flags
);
332 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
345 (WNDPROC
)RealDefWindowProcA
,
346 (WNDPROC
)RealDefWindowProcW
,
348 (FARPROC
)RealGetScrollInfo
,
349 (FARPROC
)RealSetScrollInfo
,
350 (FARPROC
)NtUserEnableScrollBar
,
351 (FARPROC
)RealAdjustWindowRectEx
,
352 (FARPROC
)NtUserSetWindowRgn
,
353 (WNDPROC_OWP
)DefaultOWP
,
354 (WNDPROC_OWP
)DefaultOWP
,
356 (WNDPROC_OWP
)DefaultOWP
,
357 (WNDPROC_OWP
)DefaultOWP
,
359 (FARPROC
)RealGetSystemMetrics
,
360 (FARPROC
)RealSystemParametersInfoA
,
361 (FARPROC
)RealSystemParametersInfoW
,
362 (FARPROC
)ForceResetUserApiHook
,
363 (FARPROC
)RealDrawFrameControl
,
364 (FARPROC
)NtUserDrawCaption
,
365 (FARPROC
)RealMDIRedrawFrame
,
366 (FARPROC
)GetRealWindowOwner
,
369 /* FUNCTIONS *****************************************************************/
374 BOOL WINAPI
RegisterUserApiHook(PUSERAPIHOOKINFO puah
)
376 UNICODE_STRING m_dllname1
;
377 UNICODE_STRING m_funname1
;
379 if (puah
->m_size
== sizeof(USERAPIHOOKINFO
))
381 WARN("RegisterUserApiHook: %S and %S",puah
->m_dllname1
, puah
->m_funname1
);
382 RtlInitUnicodeString(&m_dllname1
, puah
->m_dllname1
);
383 RtlInitUnicodeString(&m_funname1
, puah
->m_funname1
);
384 return NtUserRegisterUserApiHook( &m_dllname1
, &m_funname1
, 0, 0);
392 BOOL WINAPI
UnregisterUserApiHook(VOID
)
394 // Direct call to Win32k! Here only as a prototype.....