Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenusrapihk.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS user32.dll 00004 * FILE: dll/win32/user32/misc/usrapihk.c 00005 * PURPOSE: User32.dll User32 Api Hook interface and support functions 00006 * PROGRAMMER: 00007 * 00008 * 00009 * 00010 * Information: 00011 * http://www.reactos.org/wiki/RegisterUserApiHook 00012 * 00013 */ 00014 #include <user32.h> 00015 00016 #include <wine/debug.h> 00017 00018 WINE_DEFAULT_DEBUG_CHANNEL(user32); 00019 00020 BOOL WINAPI RealAdjustWindowRectEx(LPRECT,DWORD,BOOL,DWORD); 00021 LRESULT WINAPI RealDefWindowProcA(HWND,UINT,WPARAM,LPARAM); 00022 LRESULT WINAPI RealDefWindowProcW(HWND,UINT,WPARAM,LPARAM); 00023 BOOL WINAPI RealDrawFrameControl(HDC,LPRECT,UINT,UINT); 00024 BOOL WINAPI RealGetScrollInfo(HWND,INT,LPSCROLLINFO); 00025 int WINAPI RealGetSystemMetrics(int); 00026 BOOL WINAPI RealMDIRedrawFrame(HWND,DWORD); 00027 INT WINAPI RealSetScrollInfo(HWND,int,LPCSCROLLINFO,BOOL); 00028 BOOL WINAPI RealSystemParametersInfoA(UINT,UINT,PVOID,UINT); 00029 BOOL WINAPI RealSystemParametersInfoW(UINT,UINT,PVOID,UINT); 00030 DWORD WINAPI GetRealWindowOwner(HWND); 00031 00032 /* GLOBALS *******************************************************************/ 00033 00034 DWORD gcLoadUserApiHook = 0; 00035 LONG gcCallUserApiHook = 0; 00036 DWORD gfUserApiHook; 00037 HINSTANCE ghmodUserApiHook = NULL; 00038 USERAPIHOOKPROC gpfnInitUserApi; 00039 RTL_CRITICAL_SECTION gcsUserApiHook; 00040 // API Hooked Message group bitmaps 00041 BYTE grgbDwpLiteHookMsg[128]; 00042 BYTE grgbWndLiteHookMsg[128]; 00043 BYTE grgbDlgLiteHookMsg[128]; 00044 00045 /* INTERNAL ******************************************************************/ 00046 00047 /* 00048 Pre and Post Message handler stub. 00049 */ 00050 LRESULT 00051 WINAPI 00052 DefaultOWP(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR lResult, PDWORD pData) 00053 { 00054 return 0; 00055 } 00056 00057 /* 00058 Check for API Hooked Message Overrides. Using message bitmapping.. One bit 00059 corresponds to one message number. 00060 */ 00061 BOOL 00062 FASTCALL 00063 IsMsgOverride( UINT Msg, PUAHOWP puaowpOverride) 00064 { 00065 UINT nMsg = Msg / 8; // Group Indexed, (Msg 1024) / 8 = (0 -> 127) bytes Max 00066 00067 if ( puaowpOverride && nMsg < puaowpOverride->Size ) 00068 { 00069 return (puaowpOverride->MsgBitArray[nMsg] & (1 << (Msg & WM_SETFOCUS))); 00070 } 00071 return FALSE; 00072 } 00073 00074 VOID 00075 FASTCALL 00076 CopyMsgMask(PUAHOWP Dest, PUAHOWP Src, PVOID hkmsg, DWORD Size) 00077 { 00078 DWORD nSize; 00079 00080 if ( Src && Src->Size > 0 ) 00081 { 00082 Dest->MsgBitArray = hkmsg; 00083 nSize = Src->Size; 00084 if ( Size < nSize) nSize = Size; 00085 Dest->Size = nSize; 00086 RtlCopyMemory(Dest->MsgBitArray, Src->MsgBitArray, nSize); 00087 return; 00088 } 00089 00090 Dest->MsgBitArray = NULL; 00091 Dest->Size = 0; 00092 return; 00093 } 00094 00095 00096 BOOL 00097 FASTCALL 00098 IsInsideUserApiHook(VOID) 00099 { 00100 if ( ghmodUserApiHook && gfUserApiHook ) return TRUE; 00101 return FALSE; 00102 } 00103 00104 BOOL 00105 FASTCALL 00106 BeginIfHookedUserApiHook(VOID) 00107 { 00108 InterlockedIncrement(&gcCallUserApiHook); 00109 if (IsInsideUserApiHook()) return TRUE; 00110 00111 InterlockedDecrement(&gcCallUserApiHook); 00112 return FALSE; 00113 } 00114 00115 BOOL 00116 FASTCALL 00117 ForceResetUserApiHook(HINSTANCE hInstance) 00118 { 00119 if ( ghmodUserApiHook == hInstance && 00120 RtlIsThreadWithinLoaderCallout() ) 00121 { 00122 ResetUserApiHook(&guah); 00123 gpfnInitUserApi = NULL; 00124 return TRUE; 00125 } 00126 return FALSE; 00127 } 00128 00129 VOID 00130 FASTCALL 00131 ResetUserApiHook(PUSERAPIHOOK puah) 00132 { 00133 // Setup Structure..... 00134 puah->size = sizeof(USERAPIHOOK); 00135 puah->DefWindowProcA = (WNDPROC)RealDefWindowProcA; 00136 puah->DefWindowProcW = (WNDPROC)RealDefWindowProcW; 00137 puah->DefWndProcArray.MsgBitArray = NULL; 00138 puah->DefWndProcArray.Size = 0; 00139 puah->GetScrollInfo = (FARPROC)RealGetScrollInfo; 00140 puah->SetScrollInfo = (FARPROC)RealSetScrollInfo; 00141 puah->EnableScrollBar = (FARPROC)NtUserEnableScrollBar; 00142 puah->AdjustWindowRectEx = (FARPROC)RealAdjustWindowRectEx; 00143 puah->SetWindowRgn = (FARPROC)NtUserSetWindowRgn; 00144 puah->PreWndProc = (WNDPROC_OWP)DefaultOWP; 00145 puah->PostWndProc = (WNDPROC_OWP)DefaultOWP; 00146 puah->WndProcArray.MsgBitArray = NULL; 00147 puah->WndProcArray.Size = 0; 00148 puah->PreDefDlgProc = (WNDPROC_OWP)DefaultOWP; 00149 puah->PostDefDlgProc = (WNDPROC_OWP)DefaultOWP; 00150 puah->DlgProcArray.MsgBitArray = NULL; 00151 puah->DlgProcArray.Size = 0; 00152 puah->GetSystemMetrics = (FARPROC)RealGetSystemMetrics; 00153 puah->SystemParametersInfoA = (FARPROC)RealSystemParametersInfoA; 00154 puah->SystemParametersInfoW = (FARPROC)RealSystemParametersInfoW; 00155 puah->ForceResetUserApiHook = (FARPROC)ForceResetUserApiHook; 00156 puah->DrawFrameControl = (FARPROC)RealDrawFrameControl; 00157 puah->DrawCaption = (FARPROC)NtUserDrawCaption; 00158 puah->MDIRedrawFrame = (FARPROC)RealMDIRedrawFrame; 00159 puah->GetRealWindowOwner = (FARPROC)GetRealWindowOwner; 00160 } 00161 00162 BOOL 00163 FASTCALL 00164 EndUserApiHook(VOID) 00165 { 00166 HMODULE hModule; 00167 USERAPIHOOKPROC pfn; 00168 BOOL Ret = FALSE; 00169 00170 if ( !InterlockedDecrement(&gcCallUserApiHook) ) 00171 { 00172 if ( !gcLoadUserApiHook ) 00173 { 00174 RtlEnterCriticalSection(&gcsUserApiHook); 00175 00176 pfn = gpfnInitUserApi; 00177 hModule = ghmodUserApiHook; 00178 ghmodUserApiHook = NULL; 00179 gpfnInitUserApi = NULL; 00180 00181 RtlLeaveCriticalSection(&gcsUserApiHook); 00182 00183 if ( pfn ) Ret = pfn(uahStop, 0); 00184 00185 if ( hModule ) Ret = FreeLibrary(hModule); 00186 } 00187 } 00188 return Ret; 00189 } 00190 00191 BOOL 00192 WINAPI 00193 ClearUserApiHook(HINSTANCE hInstance) 00194 { 00195 HMODULE hModule; 00196 USERAPIHOOKPROC pfn = NULL, pfn1 = NULL; 00197 00198 RtlEnterCriticalSection(&gcsUserApiHook); 00199 hModule = ghmodUserApiHook; 00200 if ( ghmodUserApiHook == hInstance ) 00201 { 00202 pfn1 = gpfnInitUserApi; 00203 if ( --gcLoadUserApiHook == 0 ) 00204 { 00205 gfUserApiHook = 0; 00206 ResetUserApiHook(&guah); 00207 if ( gcCallUserApiHook ) 00208 { 00209 hInstance = NULL; 00210 pfn1 = NULL; 00211 pfn = gpfnInitUserApi; 00212 gcLoadUserApiHook = 1; 00213 } 00214 else 00215 { 00216 hInstance = hModule; 00217 ghmodUserApiHook = NULL; 00218 gpfnInitUserApi = NULL; 00219 } 00220 } 00221 } 00222 RtlLeaveCriticalSection(&gcsUserApiHook); 00223 00224 if ( pfn ) 00225 { 00226 pfn(uahShutdown, 0); // Shutdown. 00227 00228 RtlEnterCriticalSection(&gcsUserApiHook); 00229 pfn1 = gpfnInitUserApi; 00230 00231 if ( --gcLoadUserApiHook == 0 ) 00232 { 00233 if ( gcCallUserApiHook ) 00234 { 00235 hInstance = NULL; 00236 pfn1 = NULL; 00237 } 00238 else 00239 { 00240 hInstance = ghmodUserApiHook; 00241 ghmodUserApiHook = NULL; 00242 gpfnInitUserApi = NULL; 00243 } 00244 } 00245 RtlLeaveCriticalSection(&gcsUserApiHook); 00246 } 00247 00248 if ( pfn1 ) pfn1(uahStop, 0); 00249 00250 return hInstance != 0; 00251 } 00252 00253 BOOL 00254 WINAPI 00255 InitUserApiHook(HINSTANCE hInstance, USERAPIHOOKPROC pfn) 00256 { 00257 USERAPIHOOK uah; 00258 00259 ResetUserApiHook(&uah); 00260 00261 RtlEnterCriticalSection(&gcsUserApiHook); 00262 00263 if (!pfn(uahLoadInit,&uah) || // Swap data, User32 to and Uxtheme from! 00264 uah.ForceResetUserApiHook != (FARPROC)ForceResetUserApiHook || 00265 uah.size <= 0 ) 00266 { 00267 RtlLeaveCriticalSection(&gcsUserApiHook); 00268 return FALSE; 00269 } 00270 00271 if ( ghmodUserApiHook ) 00272 { 00273 if ( ghmodUserApiHook != hInstance ) 00274 { 00275 RtlLeaveCriticalSection(&gcsUserApiHook); 00276 pfn(uahStop, 0); 00277 return FALSE; 00278 } 00279 gcLoadUserApiHook++; 00280 } 00281 else 00282 { 00283 ghmodUserApiHook = hInstance; 00284 // Do not over write GetRealWindowOwner. 00285 RtlCopyMemory(&guah, &uah, sizeof(USERAPIHOOK) - sizeof(LONG)); 00286 gpfnInitUserApi = pfn; 00287 gcLoadUserApiHook = 1; 00288 gfUserApiHook = 1; 00289 // Copy Message Masks 00290 CopyMsgMask(&guah.DefWndProcArray, 00291 &uah.DefWndProcArray, 00292 &grgbDwpLiteHookMsg, 00293 sizeof(grgbDwpLiteHookMsg)); 00294 00295 CopyMsgMask(&guah.WndProcArray, 00296 &uah.WndProcArray, 00297 &grgbWndLiteHookMsg, 00298 sizeof(grgbWndLiteHookMsg)); 00299 00300 CopyMsgMask(&guah.DlgProcArray, 00301 &uah.DlgProcArray, 00302 &grgbDlgLiteHookMsg, 00303 sizeof(grgbDlgLiteHookMsg)); 00304 } 00305 RtlLeaveCriticalSection(&gcsUserApiHook); 00306 return TRUE; 00307 } 00308 00309 BOOL 00310 WINAPI 00311 RealMDIRedrawFrame(HWND hWnd, DWORD flags) 00312 { 00313 return NtUserxMDIRedrawFrame(hWnd); 00314 } 00315 00316 BOOL 00317 WINAPI 00318 MDIRedrawFrame(HWND hWnd, DWORD flags) 00319 { 00320 BOOL Hook, Ret = FALSE; 00321 00322 LoadUserApiHook(); 00323 00324 Hook = BeginIfHookedUserApiHook(); 00325 00326 /* Bypass SEH and go direct. */ 00327 if (!Hook) return RealMDIRedrawFrame(hWnd, flags); 00328 00329 _SEH2_TRY 00330 { 00331 Ret = guah.MDIRedrawFrame(hWnd, flags); 00332 } 00333 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00334 { 00335 } 00336 _SEH2_END; 00337 00338 EndUserApiHook(); 00339 00340 return Ret; 00341 } 00342 00343 USERAPIHOOK guah = 00344 { 00345 sizeof(USERAPIHOOK), 00346 (WNDPROC)RealDefWindowProcA, 00347 (WNDPROC)RealDefWindowProcW, 00348 {NULL, 0}, 00349 (FARPROC)RealGetScrollInfo, 00350 (FARPROC)RealSetScrollInfo, 00351 (FARPROC)NtUserEnableScrollBar, 00352 (FARPROC)RealAdjustWindowRectEx, 00353 (FARPROC)NtUserSetWindowRgn, 00354 (WNDPROC_OWP)DefaultOWP, 00355 (WNDPROC_OWP)DefaultOWP, 00356 {NULL, 0}, 00357 (WNDPROC_OWP)DefaultOWP, 00358 (WNDPROC_OWP)DefaultOWP, 00359 {NULL, 0}, 00360 (FARPROC)RealGetSystemMetrics, 00361 (FARPROC)RealSystemParametersInfoA, 00362 (FARPROC)RealSystemParametersInfoW, 00363 (FARPROC)ForceResetUserApiHook, 00364 (FARPROC)RealDrawFrameControl, 00365 (FARPROC)NtUserDrawCaption, 00366 (FARPROC)RealMDIRedrawFrame, 00367 (FARPROC)GetRealWindowOwner, 00368 }; 00369 00370 /* FUNCTIONS *****************************************************************/ 00371 00372 /* 00373 * @implemented 00374 */ 00375 BOOL WINAPI RegisterUserApiHook(PUSERAPIHOOKINFO puah) 00376 { 00377 UNICODE_STRING m_dllname1; 00378 UNICODE_STRING m_funname1; 00379 00380 if (puah->m_size == sizeof(USERAPIHOOKINFO)) 00381 { 00382 WARN("RegisterUserApiHook: %S and %S",puah->m_dllname1, puah->m_funname1); 00383 RtlInitUnicodeString(&m_dllname1, puah->m_dllname1); 00384 RtlInitUnicodeString(&m_funname1, puah->m_funname1); 00385 return NtUserRegisterUserApiHook( &m_dllname1, &m_funname1, 0, 0); 00386 } 00387 return FALSE; 00388 } 00389 00390 /* 00391 * @implemented 00392 */ 00393 BOOL WINAPI UnregisterUserApiHook(VOID) 00394 { 00395 return NtUserUnregisterUserApiHook(); 00396 } Generated on Sun May 27 2012 04:38:43 for ReactOS by
1.7.6.1
|