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
);
30 DWORD WINAPI
GetRealWindowOwner(HWND
);
32 /* GLOBALS *******************************************************************/
34 DWORD gcLoadUserApiHook
= 0;
35 LONG gcCallUserApiHook
= 0;
37 HINSTANCE ghmodUserApiHook
= NULL
;
38 USERAPIHOOKPROC gpfnInitUserApi
;
39 RTL_CRITICAL_SECTION gcsUserApiHook
;
40 // API Hooked Message group bitmaps
41 BYTE grgbDwpLiteHookMsg
[128];
42 BYTE grgbWndLiteHookMsg
[128];
43 BYTE grgbDlgLiteHookMsg
[128];
45 /* INTERNAL ******************************************************************/
48 Pre and Post Message handler stub.
52 DefaultOWP(HWND hWnd
, UINT Msg
, WPARAM wParam
, LPARAM lParam
, ULONG_PTR lResult
, PDWORD pData
)
58 Check for API Hooked Message Overrides. Using message bitmapping.. One bit
59 corresponds to one message number.
63 IsMsgOverride( UINT Msg
, PUAHOWP puaowpOverride
)
65 UINT nMsg
= Msg
/ 8; // Group Indexed, (Msg 1024) / 8 = (0 -> 127) bytes Max
67 if ( puaowpOverride
&& nMsg
< puaowpOverride
->Size
)
69 return (puaowpOverride
->MsgBitArray
[nMsg
] & (1 << (Msg
& WM_SETFOCUS
)));
76 CopyMsgMask(PUAHOWP Dest
, PUAHOWP Src
, PVOID hkmsg
, DWORD Size
)
80 if ( Src
&& Src
->Size
> 0 )
82 Dest
->MsgBitArray
= hkmsg
;
84 if ( Size
< nSize
) nSize
= Size
;
86 RtlCopyMemory(Dest
->MsgBitArray
, Src
->MsgBitArray
, nSize
);
90 Dest
->MsgBitArray
= NULL
;
98 IsInsideUserApiHook(VOID
)
100 if ( ghmodUserApiHook
&& gfUserApiHook
) return TRUE
;
106 BeginIfHookedUserApiHook(VOID
)
108 InterlockedIncrement(&gcCallUserApiHook
);
109 if (IsInsideUserApiHook()) return TRUE
;
111 InterlockedDecrement(&gcCallUserApiHook
);
117 ForceResetUserApiHook(HINSTANCE hInstance
)
119 if ( ghmodUserApiHook
== hInstance
&&
120 RtlIsThreadWithinLoaderCallout() )
122 ResetUserApiHook(&guah
);
123 gpfnInitUserApi
= NULL
;
131 ResetUserApiHook(PUSERAPIHOOK puah
)
133 // Setup Structure.....
134 puah
->size
= sizeof(USERAPIHOOK
);
135 puah
->DefWindowProcA
= (WNDPROC
)RealDefWindowProcA
;
136 puah
->DefWindowProcW
= (WNDPROC
)RealDefWindowProcW
;
137 puah
->DefWndProcArray
.MsgBitArray
= NULL
;
138 puah
->DefWndProcArray
.Size
= 0;
139 puah
->GetScrollInfo
= (FARPROC
)RealGetScrollInfo
;
140 puah
->SetScrollInfo
= (FARPROC
)RealSetScrollInfo
;
141 puah
->EnableScrollBar
= (FARPROC
)NtUserEnableScrollBar
;
142 puah
->AdjustWindowRectEx
= (FARPROC
)RealAdjustWindowRectEx
;
143 puah
->SetWindowRgn
= (FARPROC
)NtUserSetWindowRgn
;
144 puah
->PreWndProc
= (WNDPROC_OWP
)DefaultOWP
;
145 puah
->PostWndProc
= (WNDPROC_OWP
)DefaultOWP
;
146 puah
->WndProcArray
.MsgBitArray
= NULL
;
147 puah
->WndProcArray
.Size
= 0;
148 puah
->PreDefDlgProc
= (WNDPROC_OWP
)DefaultOWP
;
149 puah
->PostDefDlgProc
= (WNDPROC_OWP
)DefaultOWP
;
150 puah
->DlgProcArray
.MsgBitArray
= NULL
;
151 puah
->DlgProcArray
.Size
= 0;
152 puah
->GetSystemMetrics
= (FARPROC
)RealGetSystemMetrics
;
153 puah
->SystemParametersInfoA
= (FARPROC
)RealSystemParametersInfoA
;
154 puah
->SystemParametersInfoW
= (FARPROC
)RealSystemParametersInfoW
;
155 puah
->ForceResetUserApiHook
= (FARPROC
)ForceResetUserApiHook
;
156 puah
->DrawFrameControl
= (FARPROC
)RealDrawFrameControl
;
157 puah
->DrawCaption
= (FARPROC
)NtUserDrawCaption
;
158 puah
->MDIRedrawFrame
= (FARPROC
)RealMDIRedrawFrame
;
159 puah
->GetRealWindowOwner
= (FARPROC
)GetRealWindowOwner
;
170 if ( !InterlockedDecrement(&gcCallUserApiHook
) )
172 if ( !gcLoadUserApiHook
)
174 RtlEnterCriticalSection(&gcsUserApiHook
);
176 pfn
= gpfnInitUserApi
;
177 hModule
= ghmodUserApiHook
;
178 ghmodUserApiHook
= NULL
;
179 gpfnInitUserApi
= NULL
;
181 RtlLeaveCriticalSection(&gcsUserApiHook
);
183 if ( pfn
) Ret
= pfn(uahStop
, 0);
185 if ( hModule
) Ret
= FreeLibrary(hModule
);
193 ClearUserApiHook(HINSTANCE hInstance
)
196 USERAPIHOOKPROC pfn
= NULL
, pfn1
= NULL
;
198 RtlEnterCriticalSection(&gcsUserApiHook
);
199 hModule
= ghmodUserApiHook
;
200 if ( ghmodUserApiHook
== hInstance
)
202 pfn1
= gpfnInitUserApi
;
203 if ( --gcLoadUserApiHook
== 0 )
206 ResetUserApiHook(&guah
);
207 if ( gcCallUserApiHook
)
211 pfn
= gpfnInitUserApi
;
212 gcLoadUserApiHook
= 1;
217 ghmodUserApiHook
= NULL
;
218 gpfnInitUserApi
= NULL
;
222 RtlLeaveCriticalSection(&gcsUserApiHook
);
226 pfn(uahShutdown
, 0); // Shutdown.
228 RtlEnterCriticalSection(&gcsUserApiHook
);
229 pfn1
= gpfnInitUserApi
;
231 if ( --gcLoadUserApiHook
== 0 )
233 if ( gcCallUserApiHook
)
240 hInstance
= ghmodUserApiHook
;
241 ghmodUserApiHook
= NULL
;
242 gpfnInitUserApi
= NULL
;
245 RtlLeaveCriticalSection(&gcsUserApiHook
);
248 if ( pfn1
) pfn1(uahStop
, 0);
250 return hInstance
!= 0;
255 InitUserApiHook(HINSTANCE hInstance
, USERAPIHOOKPROC pfn
)
259 ResetUserApiHook(&uah
);
261 RtlEnterCriticalSection(&gcsUserApiHook
);
263 if (!pfn(uahLoadInit
,&uah
) || // Swap data, User32 to and Uxtheme from!
264 uah
.ForceResetUserApiHook
!= (FARPROC
)ForceResetUserApiHook
||
267 RtlLeaveCriticalSection(&gcsUserApiHook
);
271 if ( ghmodUserApiHook
)
273 if ( ghmodUserApiHook
!= hInstance
)
275 RtlLeaveCriticalSection(&gcsUserApiHook
);
283 ghmodUserApiHook
= hInstance
;
284 // Do not over write GetRealWindowOwner.
285 RtlCopyMemory(&guah
, &uah
, sizeof(USERAPIHOOK
) - sizeof(LONG
));
286 gpfnInitUserApi
= pfn
;
287 gcLoadUserApiHook
= 1;
289 // Copy Message Masks
290 CopyMsgMask(&guah
.DefWndProcArray
,
291 &uah
.DefWndProcArray
,
293 sizeof(grgbDwpLiteHookMsg
));
295 CopyMsgMask(&guah
.WndProcArray
,
298 sizeof(grgbWndLiteHookMsg
));
300 CopyMsgMask(&guah
.DlgProcArray
,
303 sizeof(grgbDlgLiteHookMsg
));
305 RtlLeaveCriticalSection(&gcsUserApiHook
);
311 RealMDIRedrawFrame(HWND hWnd
, DWORD flags
)
313 return NtUserxMDIRedrawFrame(hWnd
);
318 MDIRedrawFrame(HWND hWnd
, DWORD flags
)
320 BOOL Hook
, Ret
= FALSE
;
324 Hook
= BeginIfHookedUserApiHook();
326 /* Bypass SEH and go direct. */
327 if (!Hook
) return RealMDIRedrawFrame(hWnd
, flags
);
331 Ret
= guah
.MDIRedrawFrame(hWnd
, flags
);
333 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
346 (WNDPROC
)RealDefWindowProcA
,
347 (WNDPROC
)RealDefWindowProcW
,
349 (FARPROC
)RealGetScrollInfo
,
350 (FARPROC
)RealSetScrollInfo
,
351 (FARPROC
)NtUserEnableScrollBar
,
352 (FARPROC
)RealAdjustWindowRectEx
,
353 (FARPROC
)NtUserSetWindowRgn
,
354 (WNDPROC_OWP
)DefaultOWP
,
355 (WNDPROC_OWP
)DefaultOWP
,
357 (WNDPROC_OWP
)DefaultOWP
,
358 (WNDPROC_OWP
)DefaultOWP
,
360 (FARPROC
)RealGetSystemMetrics
,
361 (FARPROC
)RealSystemParametersInfoA
,
362 (FARPROC
)RealSystemParametersInfoW
,
363 (FARPROC
)ForceResetUserApiHook
,
364 (FARPROC
)RealDrawFrameControl
,
365 (FARPROC
)NtUserDrawCaption
,
366 (FARPROC
)RealMDIRedrawFrame
,
367 (FARPROC
)GetRealWindowOwner
,
370 /* FUNCTIONS *****************************************************************/
375 BOOL WINAPI
RegisterUserApiHook(PUSERAPIHOOKINFO puah
)
377 UNICODE_STRING m_dllname1
;
378 UNICODE_STRING m_funname1
;
380 if (puah
->m_size
== sizeof(USERAPIHOOKINFO
))
382 WARN("RegisterUserApiHook: %S and %S",puah
->m_dllname1
, puah
->m_funname1
);
383 RtlInitUnicodeString(&m_dllname1
, puah
->m_dllname1
);
384 RtlInitUnicodeString(&m_funname1
, puah
->m_funname1
);
385 return NtUserRegisterUserApiHook( &m_dllname1
, &m_funname1
, 0, 0);
393 BOOL WINAPI
UnregisterUserApiHook(VOID
)
395 return NtUserUnregisterUserApiHook();