[User32] Theme Support Interface

- This is part 1, Tested with Wine user32 tests, Seamonkey, FireFox and AbiWord.
[References:]
- http://www.reactos.org/wiki/RegisterUserApiHook
- http://www.codeproject.com/KB/miscctrl/uxtheme.aspx
- http://opcode0x90.wordpress.com/2007/05/11/user32__clientloadlibraryx/
- US Patent 6992681 and 6762767 - Theme aware management using fusion

svn path=/trunk/; revision=43053
This commit is contained in:
James Tabor 2009-09-15 15:24:09 +00:00
parent b8395bbb78
commit b5f5703c66
18 changed files with 1111 additions and 115 deletions

View file

@ -1475,8 +1475,33 @@ ScrollBarWndProcA(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
/* /*
* @implemented * @implemented
*/ */
BOOL WINAPI EnableScrollBar( HWND hwnd, UINT nBar, UINT flags )
{
BOOL Hook, Ret = FALSE;
LOADUSERAPIHOOK
Hook = BeginIfHookedUserApiHook();
/* Bypass SEH and go direct. */
if (!Hook) return NtUserEnableScrollBar(hwnd, nBar, flags);
_SEH2_TRY
{
Ret = guah.EnableScrollBar(hwnd, nBar, flags);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
EndUserApiHook();
return Ret;
}
BOOL WINAPI BOOL WINAPI
GetScrollInfo(HWND Wnd, INT SBType, LPSCROLLINFO Info) RealGetScrollInfo(HWND Wnd, INT SBType, LPSCROLLINFO Info)
{ {
if (SB_CTL == SBType) if (SB_CTL == SBType)
{ {
@ -1488,6 +1513,35 @@ GetScrollInfo(HWND Wnd, INT SBType, LPSCROLLINFO Info)
} }
} }
/*
* @implemented
*/
BOOL WINAPI
GetScrollInfo(HWND Wnd, INT SBType, LPSCROLLINFO Info)
{
BOOL Hook, Ret = FALSE;
LOADUSERAPIHOOK
Hook = BeginIfHookedUserApiHook();
/* Bypass SEH and go direct. */
if (!Hook) return RealGetScrollInfo(Wnd, SBType, Info);
_SEH2_TRY
{
Ret = guah.GetScrollInfo(Wnd, SBType, Info);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
EndUserApiHook();
return Ret;
}
/* /*
* @implemented * @implemented
*/ */
@ -1526,11 +1580,8 @@ GetScrollRange(HWND Wnd, int Bar, LPINT MinPos, LPINT MaxPos)
} }
} }
/*
* @implemented
*/
INT WINAPI INT WINAPI
SetScrollInfo(HWND Wnd, int SBType, LPCSCROLLINFO Info, BOOL bRedraw) RealSetScrollInfo(HWND Wnd, int SBType, LPCSCROLLINFO Info, BOOL bRedraw)
{ {
if (SB_CTL == SBType) if (SB_CTL == SBType)
{ {
@ -1542,6 +1593,37 @@ SetScrollInfo(HWND Wnd, int SBType, LPCSCROLLINFO Info, BOOL bRedraw)
} }
} }
/*
* @implemented
*/
INT WINAPI
SetScrollInfo(HWND Wnd, int SBType, LPCSCROLLINFO Info, BOOL bRedraw)
{
BOOL Hook;
INT Ret = 0;
LOADUSERAPIHOOK
Hook = BeginIfHookedUserApiHook();
/* Bypass SEH and go direct. */
if (!Hook) return RealSetScrollInfo(Wnd, SBType, Info, bRedraw);
_SEH2_TRY
{
Ret = guah.SetScrollInfo(Wnd, SBType, Info, bRedraw);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
EndUserApiHook();
return Ret;
}
/* /*
* @implemented * @implemented
*/ */

View file

@ -42,6 +42,76 @@
/* SEH Support with PSEH */ /* SEH Support with PSEH */
#include <pseh/pseh2.h> #include <pseh/pseh2.h>
/* Temporarily in here for now. */
typedef struct _USERAPIHOOKINFO
{
DWORD m_size;
LPCWSTR m_dllname1;
LPCWSTR m_funname1;
LPCWSTR m_dllname2;
LPCWSTR m_funname2;
} USERAPIHOOKINFO,*PUSERAPIHOOKINFO;
typedef LRESULT(CALLBACK *WNDPROC_OWP)(HWND,UINT,WPARAM,LPARAM,ULONG_PTR,PDWORD);
typedef struct _UAHOWP
{
BYTE* MsgBitArray;
DWORD Size;
} UAHOWP, *PUAHOWP;
typedef struct tagUSERAPIHOOK
{
DWORD size;
WNDPROC DefWindowProcA;
WNDPROC DefWindowProcW;
UAHOWP DefWndProcArray;
FARPROC GetScrollInfo;
FARPROC SetScrollInfo;
FARPROC EnableScrollBar;
FARPROC AdjustWindowRectEx;
FARPROC SetWindowRgn;
WNDPROC_OWP PreWndProc;
WNDPROC_OWP PostWndProc;
UAHOWP WndProcArray;
WNDPROC_OWP PreDefDlgProc;
WNDPROC_OWP PostDefDlgProc;
UAHOWP DlgProcArray;
FARPROC GetSystemMetrics;
FARPROC SystemParametersInfoA;
FARPROC SystemParametersInfoW;
FARPROC ForceResetUserApiHook;
FARPROC DrawFrameControl;
FARPROC DrawCaption;
FARPROC MDIRedrawFrame;
FARPROC GetRealWindowOwner;
} USERAPIHOOK, *PUSERAPIHOOK;
typedef enum _UAPIHK
{
uahLoadInit,
uahStop,
uahShutdown
} UAPIHK, *PUAPIHK;
extern RTL_CRITICAL_SECTION gcsUserApiHook;
extern USERAPIHOOK guah;
typedef DWORD (CALLBACK * USERAPIHOOKPROC)(UAPIHK State, ULONG_PTR Info);
BOOL FASTCALL BeginIfHookedUserApiHook(VOID);
BOOL FASTCALL EndUserApiHook(VOID);
BOOL FASTCALL IsInsideUserApiHook(VOID);
VOID FASTCALL ResetUserApiHook(PUSERAPIHOOK);
BOOL FASTCALL IsMsgOverride(UINT,PUAHOWP);
#define LOADUSERAPIHOOK \
if (!gfServerProcess && \
!IsInsideUserApiHook() && \
(gpsi->dwSRVIFlags & SRVINFO_APIHOOK) && \
!RtlIsThreadWithinLoaderCallout()) \
{ \
NtUserCallNoParam(NOPARAM_ROUTINE_LOADUSERAPIHOOK); \
} \
/* FIXME: Use ntgdi.h then cleanup... */ /* FIXME: Use ntgdi.h then cleanup... */
LONG WINAPI GdiGetCharDimensions(HDC, LPTEXTMETRICW, LONG *); LONG WINAPI GdiGetCharDimensions(HDC, LPTEXTMETRICW, LONG *);
BOOL FASTCALL IsMetaFile(HDC); BOOL FASTCALL IsMetaFile(HDC);
@ -49,6 +119,7 @@ BOOL FASTCALL IsMetaFile(HDC);
extern PPROCESSINFO g_ppi; extern PPROCESSINFO g_ppi;
extern ULONG_PTR g_ulSharedDelta; extern ULONG_PTR g_ulSharedDelta;
extern PSERVERINFO gpsi; extern PSERVERINFO gpsi;
extern BOOL gfServerProcess;
static __inline PVOID static __inline PVOID
SharedPtrToUser(PVOID Ptr) SharedPtrToUser(PVOID Ptr)

View file

@ -45,7 +45,7 @@ UserGetInsideRectNC(PWND Wnd, RECT *rect);
DWORD DWORD
SCROLL_HitTest( HWND hwnd, INT nBar, POINT pt, BOOL bDragging ); SCROLL_HitTest( HWND hwnd, INT nBar, POINT pt, BOOL bDragging );
LRESULT FASTCALL IntCallWindowProcW(BOOL IsAnsiProc, WNDPROC WndProc, LRESULT FASTCALL IntCallWindowProcW(BOOL IsAnsiProc, WNDPROC WndProc, PWND pWnd,
HWND hWnd, UINT Msg, WPARAM wParam, HWND hWnd, UINT Msg, WPARAM wParam,
LPARAM lParam); LPARAM lParam);
@ -66,3 +66,4 @@ User32CreateWindowEx(DWORD dwExStyle,
HWND* WIN_ListChildren (HWND hWndparent); HWND* WIN_ListChildren (HWND hWndparent);
ULONG_PTR FASTCALL IntGetWndProc(PWND, BOOL); ULONG_PTR FASTCALL IntGetWndProc(PWND, BOOL);
DWORD WINAPI GetRealWindowOwner(HWND);

View file

@ -90,18 +90,49 @@ LogFontW2A(LPLOGFONTA pA, CONST LOGFONTW *pW)
#undef COPYS #undef COPYS
} }
int WINAPI
RealGetSystemMetrics(int nIndex)
{
GetConnected();
// FIXME("Global Server Data -> %x\n",gpsi);
if (nIndex < 0 || nIndex >= SM_CMETRICS) return 0;
return gpsi->aiSysMet[nIndex];
}
/* /*
* @implemented * @implemented
*/ */
int WINAPI int WINAPI
GetSystemMetrics(int nIndex) GetSystemMetrics(int nIndex)
{ {
GetConnected(); BOOL Hook;
// FIXME("Global Sever Data -> %x\n",gpsi); int Ret = 0;
if (nIndex < 0 || nIndex >= SM_CMETRICS) return 0;
return gpsi->aiSysMet[nIndex];
}
if (!gpsi) // Fixme! Hax! Need Timos delay load support?
{
return RealGetSystemMetrics(nIndex);
}
LOADUSERAPIHOOK
Hook = BeginIfHookedUserApiHook();
/* Bypass SEH and go direct. */
if (!Hook) return RealGetSystemMetrics(nIndex);
_SEH2_TRY
{
Ret = guah.GetSystemMetrics(nIndex);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
EndUserApiHook();
return Ret;
}
/* /*
* @unimplemented * @unimplemented
@ -110,11 +141,9 @@ BOOL WINAPI SetDeskWallpaper(LPCSTR filename)
{ {
return SystemParametersInfoA(SPI_SETDESKWALLPAPER,0,(PVOID)filename,TRUE); return SystemParametersInfoA(SPI_SETDESKWALLPAPER,0,(PVOID)filename,TRUE);
} }
/*
* @implemented
*/
BOOL WINAPI BOOL WINAPI
SystemParametersInfoA(UINT uiAction, RealSystemParametersInfoA(UINT uiAction,
UINT uiParam, UINT uiParam,
PVOID pvParam, PVOID pvParam,
UINT fWinIni) UINT fWinIni)
@ -275,12 +304,8 @@ SystemParametersInfoA(UINT uiAction,
return NtUserSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni); return NtUserSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni);
} }
/*
* @implemented
*/
BOOL WINAPI BOOL WINAPI
SystemParametersInfoW(UINT uiAction, RealSystemParametersInfoW(UINT uiAction,
UINT uiParam, UINT uiParam,
PVOID pvParam, PVOID pvParam,
UINT fWinIni) UINT fWinIni)
@ -300,6 +325,70 @@ SystemParametersInfoW(UINT uiAction,
} }
/*
* @implemented
*/
BOOL WINAPI
SystemParametersInfoA(UINT uiAction,
UINT uiParam,
PVOID pvParam,
UINT fWinIni)
{
BOOL Hook, Ret = FALSE;
LOADUSERAPIHOOK
Hook = BeginIfHookedUserApiHook();
/* Bypass SEH and go direct. */
if (!Hook) return RealSystemParametersInfoA(uiAction, uiParam, pvParam, fWinIni);
_SEH2_TRY
{
Ret = guah.SystemParametersInfoA(uiAction, uiParam, pvParam, fWinIni);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
EndUserApiHook();
return Ret;
}
/*
* @implemented
*/
BOOL WINAPI
SystemParametersInfoW(UINT uiAction,
UINT uiParam,
PVOID pvParam,
UINT fWinIni)
{
BOOL Hook, Ret = FALSE;
LOADUSERAPIHOOK
Hook = BeginIfHookedUserApiHook();
/* Bypass SEH and go direct. */
if (!Hook) return RealSystemParametersInfoW(uiAction, uiParam, pvParam, fWinIni);
_SEH2_TRY
{
Ret = guah.SystemParametersInfoW(uiAction, uiParam, pvParam, fWinIni);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
EndUserApiHook();
return Ret;
}
/* /*
* @implemented * @implemented
*/ */

View file

@ -13,6 +13,7 @@ PUSER_HANDLE_TABLE gHandleTable = NULL;
PUSER_HANDLE_ENTRY gHandleEntries = NULL; PUSER_HANDLE_ENTRY gHandleEntries = NULL;
PSERVERINFO gpsi = NULL; PSERVERINFO gpsi = NULL;
ULONG_PTR g_ulSharedDelta; ULONG_PTR g_ulSharedDelta;
BOOL gfServerProcess = FALSE;
WCHAR szAppInit[KEY_LENGTH]; WCHAR szAppInit[KEY_LENGTH];
@ -244,6 +245,10 @@ Init(VOID)
gpsi = SharedPtrToUser(UserCon.siClient.psi); gpsi = SharedPtrToUser(UserCon.siClient.psi);
gHandleTable = SharedPtrToUser(UserCon.siClient.aheList); gHandleTable = SharedPtrToUser(UserCon.siClient.aheList);
gHandleEntries = SharedPtrToUser(gHandleTable->handles); gHandleEntries = SharedPtrToUser(gHandleTable->handles);
RtlInitializeCriticalSection(&gcsUserApiHook);
gfServerProcess = TRUE; // FIXME HAX! Used in CsrClientConnectToServer(,,,,&gfServerProcess);
//ERR("1 SI 0x%x : HT 0x%x : D 0x%x\n", UserCon.siClient.psi, UserCon.siClient.aheList, g_ulSharedDelta); //ERR("1 SI 0x%x : HT 0x%x : D 0x%x\n", UserCon.siClient.psi, UserCon.siClient.aheList, g_ulSharedDelta);
/* Allocate an index for user32 thread local data. */ /* Allocate an index for user32 thread local data. */

View file

@ -485,25 +485,6 @@ BOOL WINAPI IsServerSideWindow(HWND wnd)
return FALSE; return FALSE;
} }
typedef BOOL (CALLBACK *THEME_HOOK_FUNC) (DWORD state,PVOID arg2); //return type and 2nd parameter unknown
/*
* @unimplemented
*/
BOOL WINAPI RegisterUserApiHook(HINSTANCE instance,THEME_HOOK_FUNC proc)
{
UNIMPLEMENTED;
return FALSE;
}
/*
* @unimplemented
*/
BOOL WINAPI UnregisterUserApiHook(VOID)
{
UNIMPLEMENTED;
return FALSE;
}
/* /*
* @unimplemented * @unimplemented
*/ */

View file

@ -0,0 +1,397 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll
* FILE: dll/win32/user32/misc/usrapihk.c
* PURPOSE: User32.dll User32 Api Hook interface and support functions
* PROGRAMMER:
*
*
*
* Information:
* http://www.reactos.org/wiki/RegisterUserApiHook
*
*/
#include <user32.h>
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(user32);
BOOL WINAPI RealAdjustWindowRectEx(LPRECT,DWORD,BOOL,DWORD);
LRESULT WINAPI RealDefWindowProcA(HWND,UINT,WPARAM,LPARAM);
LRESULT WINAPI RealDefWindowProcW(HWND,UINT,WPARAM,LPARAM);
BOOL WINAPI RealDrawFrameControl(HDC,LPRECT,UINT,UINT);
BOOL WINAPI RealGetScrollInfo(HWND,INT,LPSCROLLINFO);
int WINAPI RealGetSystemMetrics(int);
BOOL WINAPI RealMDIRedrawFrame(HWND,DWORD);
INT WINAPI RealSetScrollInfo(HWND,int,LPCSCROLLINFO,BOOL);
BOOL WINAPI RealSystemParametersInfoA(UINT,UINT,PVOID,UINT);
BOOL WINAPI RealSystemParametersInfoW(UINT,UINT,PVOID,UINT);
/* GLOBALS *******************************************************************/
DWORD gcLoadUserApiHook = 0;
LONG gcCallUserApiHook = 0;
DWORD gfUserApiHook;
HINSTANCE ghmodUserApiHook = NULL;
USERAPIHOOKPROC gpfnInitUserApi;
RTL_CRITICAL_SECTION gcsUserApiHook;
// API Hooked Message group bitmaps
BYTE grgbDwpLiteHookMsg[128];
BYTE grgbWndLiteHookMsg[128];
BYTE grgbDlgLiteHookMsg[128];
/* INTERNAL ******************************************************************/
/*
Pre and Post Message handler stub.
*/
LRESULT
WINAPI
DefaultOWP(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR lResult, PDWORD pData)
{
return 0;
}
/*
Check for API Hooked Message Overrides. Using message bitmapping.. One bit
corresponds to one message number.
*/
BOOL
FASTCALL
IsMsgOverride( UINT Msg, PUAHOWP puaowpOverride)
{
UINT nMsg = Msg / 8; // Group Indexed, (Msg 1024) / 8 = (0 -> 127) bytes Max
if ( puaowpOverride && nMsg < puaowpOverride->Size )
{
return (puaowpOverride->MsgBitArray[nMsg] & (1 << (Msg & WM_SETFOCUS)));
}
return FALSE;
}
VOID
FASTCALL
CopyMsgMask(PUAHOWP Dest, PUAHOWP Src, PVOID hkmsg, DWORD Size)
{
DWORD nSize;
if ( Src && Src->Size > 0 )
{
Dest->MsgBitArray = hkmsg;
nSize = Src->Size;
if ( Size < nSize) nSize = Size;
Dest->Size = nSize;
RtlCopyMemory(Dest->MsgBitArray, Src->MsgBitArray, nSize);
return;
}
Dest->MsgBitArray = NULL;
Dest->Size = 0;
return;
}
BOOL
FASTCALL
IsInsideUserApiHook(VOID)
{
if ( ghmodUserApiHook && gfUserApiHook ) return TRUE;
return FALSE;
}
BOOL
FASTCALL
BeginIfHookedUserApiHook(VOID)
{
InterlockedIncrement(&gcCallUserApiHook);
if (IsInsideUserApiHook()) return TRUE;
InterlockedDecrement(&gcCallUserApiHook);
return FALSE;
}
BOOL
FASTCALL
ForceResetUserApiHook(HINSTANCE hInstance)
{
if ( ghmodUserApiHook == hInstance &&
RtlIsThreadWithinLoaderCallout() )
{
ResetUserApiHook(&guah);
gpfnInitUserApi = NULL;
return TRUE;
}
return FALSE;
}
VOID
FASTCALL
ResetUserApiHook(PUSERAPIHOOK puah)
{
// Setup Structure.....
puah->size = sizeof(USERAPIHOOK);
puah->DefWindowProcA = (WNDPROC)RealDefWindowProcA;
puah->DefWindowProcW = (WNDPROC)RealDefWindowProcW;
puah->DefWndProcArray.MsgBitArray = NULL;
puah->DefWndProcArray.Size = 0;
puah->GetScrollInfo = (FARPROC)RealGetScrollInfo;
puah->SetScrollInfo = (FARPROC)RealSetScrollInfo;
puah->EnableScrollBar = (FARPROC)NtUserEnableScrollBar;
puah->AdjustWindowRectEx = (FARPROC)RealAdjustWindowRectEx;
puah->SetWindowRgn = (FARPROC)NtUserSetWindowRgn;
puah->PreWndProc = (WNDPROC_OWP)DefaultOWP;
puah->PostWndProc = (WNDPROC_OWP)DefaultOWP;
puah->WndProcArray.MsgBitArray = NULL;
puah->WndProcArray.Size = 0;
puah->PreDefDlgProc = (WNDPROC_OWP)DefaultOWP;
puah->PostDefDlgProc = (WNDPROC_OWP)DefaultOWP;
puah->DlgProcArray.MsgBitArray = NULL;
puah->DlgProcArray.Size = 0;
puah->GetSystemMetrics = (FARPROC)RealGetSystemMetrics;
puah->SystemParametersInfoA = (FARPROC)RealSystemParametersInfoA;
puah->SystemParametersInfoW = (FARPROC)RealSystemParametersInfoW;
puah->ForceResetUserApiHook = (FARPROC)ForceResetUserApiHook;
puah->DrawFrameControl = (FARPROC)RealDrawFrameControl;
puah->DrawCaption = (FARPROC)NtUserDrawCaption;
puah->MDIRedrawFrame = (FARPROC)RealMDIRedrawFrame;
puah->GetRealWindowOwner = (FARPROC)GetRealWindowOwner;
}
BOOL
FASTCALL
EndUserApiHook(VOID)
{
HMODULE hModule;
USERAPIHOOKPROC pfn;
BOOL Ret = FALSE;
if ( !InterlockedDecrement(&gcCallUserApiHook) )
{
if ( !gcLoadUserApiHook )
{
RtlEnterCriticalSection(&gcsUserApiHook);
pfn = gpfnInitUserApi;
hModule = ghmodUserApiHook;
ghmodUserApiHook = NULL;
gpfnInitUserApi = NULL;
RtlLeaveCriticalSection(&gcsUserApiHook);
if ( pfn ) Ret = pfn(uahStop, 0);
if ( hModule ) Ret = FreeLibrary(hModule);
}
}
return Ret;
}
BOOL
WINAPI
ClearUserApiHook(HINSTANCE hInstance)
{
HMODULE hModule;
USERAPIHOOKPROC pfn = NULL, pfn1 = NULL;
RtlEnterCriticalSection(&gcsUserApiHook);
hModule = ghmodUserApiHook;
if ( ghmodUserApiHook == hInstance )
{
pfn1 = gpfnInitUserApi;
if ( --gcLoadUserApiHook == 1 )
{
gfUserApiHook = 0;
ResetUserApiHook(&guah);
if ( gcCallUserApiHook )
{
hInstance = NULL;
pfn1 = NULL;
pfn = gpfnInitUserApi;
gcLoadUserApiHook = 1;
}
else
{
hInstance = hModule;
ghmodUserApiHook = NULL;
gpfnInitUserApi = NULL;
}
}
}
RtlLeaveCriticalSection(&gcsUserApiHook);
if ( pfn )
{
pfn(uahShutdown, 0); // Shutdown.
RtlEnterCriticalSection(&gcsUserApiHook);
pfn1 = gpfnInitUserApi;
if ( --gcLoadUserApiHook == 1 )
{
if ( gcCallUserApiHook )
{
hInstance = NULL;
pfn1 = NULL;
}
else
{
hInstance = ghmodUserApiHook;
ghmodUserApiHook = NULL;
gpfnInitUserApi = NULL;
}
}
RtlLeaveCriticalSection(&gcsUserApiHook);
}
if ( pfn1 ) pfn1(uahStop, 0);
return hInstance != 0;
}
BOOL
WINAPI
InitUserApiHook(HINSTANCE hInstance, USERAPIHOOKPROC pfn)
{
USERAPIHOOK uah;
ResetUserApiHook(&uah);
RtlEnterCriticalSection(&gcsUserApiHook);
if (!pfn(uahLoadInit,(ULONG_PTR)&uah) || // Swap data, User32 to and Uxtheme from!
uah.ForceResetUserApiHook != (FARPROC)ForceResetUserApiHook ||
uah.size <= 0 )
{
RtlLeaveCriticalSection(&gcsUserApiHook);
return FALSE;
}
if ( ghmodUserApiHook )
{
if ( ghmodUserApiHook != hInstance )
{
RtlLeaveCriticalSection(&gcsUserApiHook);
pfn(uahStop, 0);
return FALSE;
}
gcLoadUserApiHook++;
}
else
{
ghmodUserApiHook = hInstance;
// Do not over write GetRealWindowOwner.
RtlCopyMemory(&guah, &uah, sizeof(USERAPIHOOK) - sizeof(LONG));
gpfnInitUserApi = pfn;
gcLoadUserApiHook = 1;
gfUserApiHook = 1;
// Copy Message Masks
CopyMsgMask(&guah.DefWndProcArray,
&uah.DefWndProcArray,
&grgbDwpLiteHookMsg,
sizeof(grgbDwpLiteHookMsg));
CopyMsgMask(&guah.WndProcArray,
&uah.WndProcArray,
&grgbWndLiteHookMsg,
sizeof(grgbWndLiteHookMsg));
CopyMsgMask(&guah.DlgProcArray,
&uah.DlgProcArray,
&grgbDlgLiteHookMsg,
sizeof(grgbDlgLiteHookMsg));
}
RtlLeaveCriticalSection(&gcsUserApiHook);
return TRUE;
}
BOOL
WINAPI
RealMDIRedrawFrame(HWND hWnd, DWORD flags)
{
return (BOOL)NtUserCallHwndLock(hWnd, HWNDLOCK_ROUTINE_REDRAWFRAME);
}
BOOL
WINAPI
MDIRedrawFrame(HWND hWnd, DWORD flags)
{
BOOL Hook, Ret = FALSE;
LOADUSERAPIHOOK
Hook = BeginIfHookedUserApiHook();
/* Bypass SEH and go direct. */
if (!Hook) return RealMDIRedrawFrame(hWnd, flags);
_SEH2_TRY
{
Ret = guah.MDIRedrawFrame(hWnd, flags);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
EndUserApiHook();
return Ret;
}
USERAPIHOOK guah =
{
sizeof(USERAPIHOOK),
(WNDPROC)RealDefWindowProcA,
(WNDPROC)RealDefWindowProcW,
{NULL, 0},
(FARPROC)RealGetScrollInfo,
(FARPROC)RealSetScrollInfo,
(FARPROC)NtUserEnableScrollBar,
(FARPROC)RealAdjustWindowRectEx,
(FARPROC)NtUserSetWindowRgn,
(WNDPROC_OWP)DefaultOWP,
(WNDPROC_OWP)DefaultOWP,
{NULL, 0},
(WNDPROC_OWP)DefaultOWP,
(WNDPROC_OWP)DefaultOWP,
{NULL, 0},
(FARPROC)RealGetSystemMetrics,
(FARPROC)RealSystemParametersInfoA,
(FARPROC)RealSystemParametersInfoW,
(FARPROC)ForceResetUserApiHook,
(FARPROC)RealDrawFrameControl,
(FARPROC)NtUserDrawCaption,
(FARPROC)RealMDIRedrawFrame,
(FARPROC)GetRealWindowOwner,
};
/* FUNCTIONS *****************************************************************/
/*
* @implemented
*/
BOOL WINAPI RegisterUserApiHook(PUSERAPIHOOKINFO puah)
{
UNICODE_STRING m_dllname1;
UNICODE_STRING m_funname1;
if (puah->m_size == sizeof(USERAPIHOOKINFO))
{
WARN("RegisterUserApiHook: %S and %S",puah->m_dllname1, puah->m_funname1);
RtlInitUnicodeString(&m_dllname1, puah->m_dllname1);
RtlInitUnicodeString(&m_funname1, puah->m_funname1);
return NtUserRegisterUserApiHook( &m_dllname1, &m_funname1, 0, 0);
}
return FALSE;
}
/*
* @implemented
*/
BOOL WINAPI UnregisterUserApiHook(VOID)
{
// Direct call to Win32k! Here only as a prototype.....
UNIMPLEMENTED;
return FALSE;
}

View file

@ -194,7 +194,7 @@
@ stdcall EditWndProc(long long long long) EditWndProcA @ stdcall EditWndProc(long long long long) EditWndProcA
@ stdcall EmptyClipboard() NtUserEmptyClipboard @ stdcall EmptyClipboard() NtUserEmptyClipboard
@ stdcall EnableMenuItem(long long long) @ stdcall EnableMenuItem(long long long)
@ stdcall EnableScrollBar(long long long) NtUserEnableScrollBar @ stdcall EnableScrollBar(long long long)
@ stdcall EnableWindow(long long) @ stdcall EnableWindow(long long)
@ stdcall EndDeferWindowPos(long) @ stdcall EndDeferWindowPos(long)
@ stdcall EndDialog(long long) @ stdcall EndDialog(long long)
@ -557,7 +557,7 @@
@ stdcall RegisterShellHookWindow(long) @ stdcall RegisterShellHookWindow(long)
@ stdcall RegisterSystemThread(long long) @ stdcall RegisterSystemThread(long long)
@ stdcall RegisterTasklist(long) NtUserRegisterTasklist @ stdcall RegisterTasklist(long) NtUserRegisterTasklist
@ stub RegisterUserApiHook @ stdcall RegisterUserApiHook(ptr)
@ stdcall RegisterWindowMessageA(str) @ stdcall RegisterWindowMessageA(str)
@ stdcall RegisterWindowMessageW(wstr) @ stdcall RegisterWindowMessageW(wstr)
@ stdcall ReleaseCapture() @ stdcall ReleaseCapture()
@ -711,7 +711,7 @@
@ stdcall UnregisterDeviceNotification(long) @ stdcall UnregisterDeviceNotification(long)
@ stdcall UnregisterHotKey(long long) NtUserUnregisterHotKey @ stdcall UnregisterHotKey(long long) NtUserUnregisterHotKey
@ stub UnregisterMessagePumpHook @ stub UnregisterMessagePumpHook
@ stub UnregisterUserApiHook @ stdcall UnregisterUserApiHook() NtUserUnregisterUserApiHook
@ stdcall UpdateLayeredWindow(long long ptr ptr long ptr long ptr long) @ stdcall UpdateLayeredWindow(long long ptr ptr long ptr long ptr long)
@ stdcall UpdateLayeredWindowIndirect(long ptr) @ stdcall UpdateLayeredWindowIndirect(long ptr)
@ stdcall UpdatePerUserSystemParameters(long long) @ stdcall UpdatePerUserSystemParameters(long long)

View file

@ -43,6 +43,7 @@
<file>rtlstr.c</file> <file>rtlstr.c</file>
<file>stubs.c</file> <file>stubs.c</file>
<file>timer.c</file> <file>timer.c</file>
<file>usrapihk.c</file>
<file>winhelp.c</file> <file>winhelp.c</file>
<file>winsta.c</file> <file>winsta.c</file>
<file>wsprintf.c</file> <file>wsprintf.c</file>

View file

@ -1879,10 +1879,10 @@ DefWndImmIsUIMessageW(HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
LRESULT WINAPI LRESULT WINAPI
DefWindowProcA(HWND hWnd, RealDefWindowProcA(HWND hWnd,
UINT Msg, UINT Msg,
WPARAM wParam, WPARAM wParam,
LPARAM lParam) LPARAM lParam)
{ {
LRESULT Result = 0; LRESULT Result = 0;
PWND Wnd; PWND Wnd;
@ -2032,10 +2032,10 @@ DefWindowProcA(HWND hWnd,
LRESULT WINAPI LRESULT WINAPI
DefWindowProcW(HWND hWnd, RealDefWindowProcW(HWND hWnd,
UINT Msg, UINT Msg,
WPARAM wParam, WPARAM wParam,
LPARAM lParam) LPARAM lParam)
{ {
LRESULT Result = 0; LRESULT Result = 0;
PWND Wnd; PWND Wnd;
@ -2175,3 +2175,68 @@ DefWindowProcW(HWND hWnd,
return Result; return Result;
} }
LRESULT WINAPI
DefWindowProcA(HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
BOOL Hook, msgOverride;
LRESULT Result = 0;
LOADUSERAPIHOOK
Hook = BeginIfHookedUserApiHook();
if (Hook)
msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray);
/* Bypass SEH and go direct. */
if (!Hook || !msgOverride)
return RealDefWindowProcA(hWnd, Msg, wParam, lParam);
_SEH2_TRY
{
Result = guah.DefWindowProcA(hWnd, Msg, wParam, lParam);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
EndUserApiHook();
return Result;
}
LRESULT WINAPI
DefWindowProcW(HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
BOOL Hook, msgOverride;
LRESULT Result = 0;
LOADUSERAPIHOOK
Hook = BeginIfHookedUserApiHook();
if (Hook)
msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray);
/* Bypass SEH and go direct. */
if (!Hook || !msgOverride)
return RealDefWindowProcW(hWnd, Msg, wParam, lParam);
_SEH2_TRY
{
Result = guah.DefWindowProcW(hWnd, Msg, wParam, lParam);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
EndUserApiHook();
return Result;
}

View file

@ -1437,7 +1437,7 @@ cleanup:
* @implemented * @implemented
*/ */
BOOL WINAPI BOOL WINAPI
DrawFrameControl(HDC hDC, LPRECT rc, UINT uType, UINT uState) RealDrawFrameControl(HDC hDC, LPRECT rc, UINT uType, UINT uState)
{ {
if (GetMapMode(hDC) != MM_TEXT) if (GetMapMode(hDC) != MM_TEXT)
return FALSE; return FALSE;
@ -1461,6 +1461,32 @@ DrawFrameControl(HDC hDC, LPRECT rc, UINT uType, UINT uState)
return FALSE; return FALSE;
} }
BOOL WINAPI
DrawFrameControl(HDC hDC, LPRECT rc, UINT uType, UINT uState)
{
BOOL Hook, Ret = FALSE;
LOADUSERAPIHOOK
Hook = BeginIfHookedUserApiHook();
/* Bypass SEH and go direct. */
if (!Hook) return RealDrawFrameControl(hDC, rc, uType, uState);
_SEH2_TRY
{
Ret = guah.DrawFrameControl(hDC, rc, uType, uState);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
EndUserApiHook();
return Ret;
}
/* /*
* @implemented * @implemented
*/ */

View file

@ -1138,6 +1138,7 @@ SetMessageExtraInfo(
LRESULT FASTCALL LRESULT FASTCALL
IntCallWindowProcW(BOOL IsAnsiProc, IntCallWindowProcW(BOOL IsAnsiProc,
WNDPROC WndProc, WNDPROC WndProc,
PWND pWnd,
HWND hWnd, HWND hWnd,
UINT Msg, UINT Msg,
WPARAM wParam, WPARAM wParam,
@ -1145,7 +1146,9 @@ IntCallWindowProcW(BOOL IsAnsiProc,
{ {
MSG AnsiMsg; MSG AnsiMsg;
MSG UnicodeMsg; MSG UnicodeMsg;
LRESULT Result; BOOL Hook = FALSE, MsgOverride = FALSE, Dialog;
LRESULT Result = 0, PreResult = 0;
DWORD Data = 0;
if (WndProc == NULL) if (WndProc == NULL)
{ {
@ -1153,33 +1156,116 @@ IntCallWindowProcW(BOOL IsAnsiProc,
return FALSE; return FALSE;
} }
if (pWnd)
Dialog = (pWnd->fnid == FNID_DIALOG);
else
Dialog = FALSE;
Hook = BeginIfHookedUserApiHook();
if (Hook)
{
if (!Dialog)
MsgOverride = IsMsgOverride( Msg, &guah.WndProcArray);
else
MsgOverride = IsMsgOverride( Msg, &guah.DlgProcArray);
}
if (IsAnsiProc) if (IsAnsiProc)
{ {
UnicodeMsg.hwnd = hWnd; UnicodeMsg.hwnd = hWnd;
UnicodeMsg.message = Msg; UnicodeMsg.message = Msg;
UnicodeMsg.wParam = wParam; UnicodeMsg.wParam = wParam;
UnicodeMsg.lParam = lParam; UnicodeMsg.lParam = lParam;
if (! MsgiUnicodeToAnsiMessage(&AnsiMsg, &UnicodeMsg)) if (! MsgiUnicodeToAnsiMessage(&AnsiMsg, &UnicodeMsg))
{ {
return FALSE; goto Exit;
} }
if (Hook && MsgOverride)
{
_SEH2_TRY
{
if (!Dialog)
PreResult = guah.PreWndProc(AnsiMsg.hwnd, AnsiMsg.message, AnsiMsg.wParam, AnsiMsg.lParam, (ULONG_PTR)&Result, &Data );
else
PreResult = guah.PreDefDlgProc(AnsiMsg.hwnd, AnsiMsg.message, AnsiMsg.wParam, AnsiMsg.lParam, (ULONG_PTR)&Result, &Data );
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
}
if (PreResult) goto Exit;
Result = WndProc(AnsiMsg.hwnd, AnsiMsg.message, AnsiMsg.wParam, AnsiMsg.lParam); Result = WndProc(AnsiMsg.hwnd, AnsiMsg.message, AnsiMsg.wParam, AnsiMsg.lParam);
if (Hook && MsgOverride)
{
_SEH2_TRY
{
if (!Dialog)
guah.PostWndProc(AnsiMsg.hwnd, AnsiMsg.message, AnsiMsg.wParam, AnsiMsg.lParam, (ULONG_PTR)&Result, &Data );
else
guah.PostDefDlgProc(AnsiMsg.hwnd, AnsiMsg.message, AnsiMsg.wParam, AnsiMsg.lParam, (ULONG_PTR)&Result, &Data );
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
}
if (! MsgiUnicodeToAnsiReply(&AnsiMsg, &UnicodeMsg, &Result)) if (! MsgiUnicodeToAnsiReply(&AnsiMsg, &UnicodeMsg, &Result))
{ {
return FALSE; goto Exit;
} }
return Result; }
}
else else
{ {
return WndProc(hWnd, Msg, wParam, lParam); if (Hook && MsgOverride)
} {
_SEH2_TRY
{
if (!Dialog)
PreResult = guah.PreWndProc(hWnd, Msg, wParam, lParam, (ULONG_PTR)&Result, &Data );
else
PreResult = guah.PreDefDlgProc(hWnd, Msg, wParam, lParam, (ULONG_PTR)&Result, &Data );
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
}
if (PreResult) goto Exit;
Result = WndProc(hWnd, Msg, wParam, lParam);
if (Hook && MsgOverride)
{
_SEH2_TRY
{
if (!Dialog)
guah.PostWndProc(hWnd, Msg, wParam, lParam, (ULONG_PTR)&Result, &Data );
else
guah.PostDefDlgProc(hWnd, Msg, wParam, lParam, (ULONG_PTR)&Result, &Data );
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
}
}
Exit:
if (Hook) EndUserApiHook();
return Result;
} }
static LRESULT FASTCALL static LRESULT FASTCALL
IntCallWindowProcA(BOOL IsAnsiProc, IntCallWindowProcA(BOOL IsAnsiProc,
WNDPROC WndProc, WNDPROC WndProc,
PWND pWnd,
HWND hWnd, HWND hWnd,
UINT Msg, UINT Msg,
WPARAM wParam, WPARAM wParam,
@ -1187,7 +1273,9 @@ IntCallWindowProcA(BOOL IsAnsiProc,
{ {
MSG AnsiMsg; MSG AnsiMsg;
MSG UnicodeMsg; MSG UnicodeMsg;
LRESULT Result; BOOL Hook = FALSE, MsgOverride = FALSE, Dialog;
LRESULT Result = 0, PreResult = 0;
DWORD Data = 0;
if (WndProc == NULL) if (WndProc == NULL)
{ {
@ -1195,29 +1283,111 @@ IntCallWindowProcA(BOOL IsAnsiProc,
return FALSE; return FALSE;
} }
if (IsAnsiProc) if (pWnd)
{ Dialog = (pWnd->fnid == FNID_DIALOG);
return WndProc(hWnd, Msg, wParam, lParam);
}
else else
{ Dialog = FALSE;
Hook = BeginIfHookedUserApiHook();
if (Hook)
{
if (!Dialog)
MsgOverride = IsMsgOverride( Msg, &guah.WndProcArray);
else
MsgOverride = IsMsgOverride( Msg, &guah.DlgProcArray);
}
if (IsAnsiProc)
{
if (Hook && MsgOverride)
{
_SEH2_TRY
{
if (!Dialog)
PreResult = guah.PreWndProc(hWnd, Msg, wParam, lParam, (ULONG_PTR)&Result, &Data );
else
PreResult = guah.PreDefDlgProc(hWnd, Msg, wParam, lParam, (ULONG_PTR)&Result, &Data );
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
}
if (PreResult) goto Exit;
Result = WndProc(hWnd, Msg, wParam, lParam);
if (Hook && MsgOverride)
{
_SEH2_TRY
{
if (!Dialog)
guah.PostWndProc(hWnd, Msg, wParam, lParam, (ULONG_PTR)&Result, &Data );
else
guah.PostDefDlgProc(hWnd, Msg, wParam, lParam, (ULONG_PTR)&Result, &Data );
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
}
}
else
{
AnsiMsg.hwnd = hWnd; AnsiMsg.hwnd = hWnd;
AnsiMsg.message = Msg; AnsiMsg.message = Msg;
AnsiMsg.wParam = wParam; AnsiMsg.wParam = wParam;
AnsiMsg.lParam = lParam; AnsiMsg.lParam = lParam;
if (! MsgiAnsiToUnicodeMessage(&UnicodeMsg, &AnsiMsg)) if (! MsgiAnsiToUnicodeMessage(&UnicodeMsg, &AnsiMsg))
{ {
return FALSE; goto Exit;
} }
if (Hook && MsgOverride)
{
_SEH2_TRY
{
if (!Dialog)
PreResult = guah.PreWndProc(UnicodeMsg.hwnd, UnicodeMsg.message, UnicodeMsg.wParam, UnicodeMsg.lParam, (ULONG_PTR)&Result, &Data );
else
PreResult = guah.PreDefDlgProc(UnicodeMsg.hwnd, UnicodeMsg.message, UnicodeMsg.wParam, UnicodeMsg.lParam, (ULONG_PTR)&Result, &Data );
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
}
if (PreResult) goto Exit;
Result = WndProc(UnicodeMsg.hwnd, UnicodeMsg.message, Result = WndProc(UnicodeMsg.hwnd, UnicodeMsg.message,
UnicodeMsg.wParam, UnicodeMsg.lParam); UnicodeMsg.wParam, UnicodeMsg.lParam);
if (Hook && MsgOverride)
{
_SEH2_TRY
{
if (!Dialog)
guah.PostWndProc(UnicodeMsg.hwnd, UnicodeMsg.message, UnicodeMsg.wParam, UnicodeMsg.lParam, (ULONG_PTR)&Result, &Data );
else
guah.PostDefDlgProc(UnicodeMsg.hwnd, UnicodeMsg.message, UnicodeMsg.wParam, UnicodeMsg.lParam, (ULONG_PTR)&Result, &Data );
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
}
if (! MsgiAnsiToUnicodeReply(&UnicodeMsg, &AnsiMsg, &Result)) if (! MsgiAnsiToUnicodeReply(&UnicodeMsg, &AnsiMsg, &Result))
{ {
return FALSE; goto Exit;
} }
return Result; }
}
Exit:
if (Hook) EndUserApiHook();
return Result;
} }
@ -1267,9 +1437,9 @@ IntCallMessageProc(IN PWND Wnd, IN HWND hWnd, IN UINT Msg, IN WPARAM wParam, IN
the same. the same.
*/ */
if (!Ansi) if (!Ansi)
return IntCallWindowProcW(IsAnsi, WndProc, hWnd, Msg, wParam, lParam); return IntCallWindowProcW(IsAnsi, WndProc, Wnd, hWnd, Msg, wParam, lParam);
else else
return IntCallWindowProcA(IsAnsi, WndProc, hWnd, Msg, wParam, lParam); return IntCallWindowProcA(IsAnsi, WndProc, Wnd, hWnd, Msg, wParam, lParam);
} }
@ -1283,6 +1453,7 @@ CallWindowProcA(WNDPROC lpPrevWndFunc,
WPARAM wParam, WPARAM wParam,
LPARAM lParam) LPARAM lParam)
{ {
PWND pWnd;
PCALLPROCDATA CallProc; PCALLPROCDATA CallProc;
if (lpPrevWndFunc == NULL) if (lpPrevWndFunc == NULL)
@ -1291,8 +1462,10 @@ CallWindowProcA(WNDPROC lpPrevWndFunc,
return 0; return 0;
} }
pWnd = ValidateHwnd(hWnd);
if (!IsCallProcHandle(lpPrevWndFunc)) if (!IsCallProcHandle(lpPrevWndFunc))
return IntCallWindowProcA(TRUE, lpPrevWndFunc, hWnd, Msg, wParam, lParam); return IntCallWindowProcA(TRUE, lpPrevWndFunc, pWnd, hWnd, Msg, wParam, lParam);
else else
{ {
CallProc = ValidateCallProc((HANDLE)lpPrevWndFunc); CallProc = ValidateCallProc((HANDLE)lpPrevWndFunc);
@ -1300,6 +1473,7 @@ CallWindowProcA(WNDPROC lpPrevWndFunc,
{ {
return IntCallWindowProcA(!(CallProc->wType & UserGetCPDA2U), return IntCallWindowProcA(!(CallProc->wType & UserGetCPDA2U),
CallProc->pfnClientPrevious, CallProc->pfnClientPrevious,
pWnd,
hWnd, hWnd,
Msg, Msg,
wParam, wParam,
@ -1324,6 +1498,7 @@ CallWindowProcW(WNDPROC lpPrevWndFunc,
WPARAM wParam, WPARAM wParam,
LPARAM lParam) LPARAM lParam)
{ {
PWND pWnd;
PCALLPROCDATA CallProc; PCALLPROCDATA CallProc;
/* FIXME - can the first parameter be NULL? */ /* FIXME - can the first parameter be NULL? */
@ -1333,8 +1508,10 @@ CallWindowProcW(WNDPROC lpPrevWndFunc,
return 0; return 0;
} }
pWnd = ValidateHwnd(hWnd);
if (!IsCallProcHandle(lpPrevWndFunc)) if (!IsCallProcHandle(lpPrevWndFunc))
return IntCallWindowProcW(FALSE, lpPrevWndFunc, hWnd, Msg, wParam, lParam); return IntCallWindowProcW(FALSE, lpPrevWndFunc, pWnd, hWnd, Msg, wParam, lParam);
else else
{ {
CallProc = ValidateCallProc((HANDLE)lpPrevWndFunc); CallProc = ValidateCallProc((HANDLE)lpPrevWndFunc);
@ -1342,6 +1519,7 @@ CallWindowProcW(WNDPROC lpPrevWndFunc,
{ {
return IntCallWindowProcW(!(CallProc->wType & UserGetCPDA2U), return IntCallWindowProcW(!(CallProc->wType & UserGetCPDA2U),
CallProc->pfnClientPrevious, CallProc->pfnClientPrevious,
pWnd,
hWnd, hWnd,
Msg, Msg,
wParam, wParam,
@ -1821,13 +1999,14 @@ SendMessageW(HWND Wnd,
MSG UMMsg, KMMsg; MSG UMMsg, KMMsg;
NTUSERSENDMESSAGEINFO Info; NTUSERSENDMESSAGEINFO Info;
LRESULT Result; LRESULT Result;
PWND Window;
PTHREADINFO ti = GetW32ThreadInfo();
Window = ValidateHwnd(Wnd);
if (!Window) return FALSE;
if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST)) if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
{ {
PWND Window;
PTHREADINFO ti = GetW32ThreadInfo();
Window = ValidateHwnd(Wnd);
if (Window != NULL && Window->head.pti == ti && !IsThreadHooked(GetWin32ClientInfo())) if (Window != NULL && Window->head.pti == ti && !IsThreadHooked(GetWin32ClientInfo()))
{ {
/* NOTE: We can directly send messages to the window procedure /* NOTE: We can directly send messages to the window procedure
@ -1861,6 +2040,7 @@ SendMessageW(HWND Wnd,
/* We need to send the message ourselves */ /* We need to send the message ourselves */
Result = IntCallWindowProcW( Info.Ansi, Result = IntCallWindowProcW( Info.Ansi,
Info.Proc, Info.Proc,
Window,
UMMsg.hwnd, UMMsg.hwnd,
UMMsg.message, UMMsg.message,
UMMsg.wParam, UMMsg.wParam,
@ -1885,13 +2065,14 @@ SendMessageA(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
MSG KMMsg; MSG KMMsg;
LRESULT Result; LRESULT Result;
NTUSERSENDMESSAGEINFO Info; NTUSERSENDMESSAGEINFO Info;
PWND Window;
PTHREADINFO ti = GetW32ThreadInfo();
Window = ValidateHwnd(Wnd);
if (!Window) return FALSE;
if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST)) if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
{ {
PWND Window;
PTHREADINFO ti = GetW32ThreadInfo();
Window = ValidateHwnd(Wnd);
if (Window != NULL && Window->head.pti == ti && !IsThreadHooked(GetWin32ClientInfo())) if (Window != NULL && Window->head.pti == ti && !IsThreadHooked(GetWin32ClientInfo()))
{ {
/* NOTE: We can directly send messages to the window procedure /* NOTE: We can directly send messages to the window procedure
@ -1934,7 +2115,7 @@ SendMessageA(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
the Unicode message though */ the Unicode message though */
MsgiUMToKMCleanup(&UcMsg, &KMMsg); MsgiUMToKMCleanup(&UcMsg, &KMMsg);
MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg); MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg);
Result = IntCallWindowProcA(Info.Ansi, Info.Proc, Wnd, Msg, wParam, lParam); Result = IntCallWindowProcA(Info.Ansi, Info.Proc, Window, Wnd, Msg, wParam, lParam);
} }
else else
{ {
@ -1943,6 +2124,7 @@ SendMessageA(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
message to avoid another conversion */ message to avoid another conversion */
Result = IntCallWindowProcW( Info.Ansi, Result = IntCallWindowProcW( Info.Ansi,
Info.Proc, Info.Proc,
Window,
UcMsg.hwnd, UcMsg.hwnd,
UcMsg.message, UcMsg.message,
UcMsg.wParam, UcMsg.wParam,
@ -2048,21 +2230,28 @@ SendMessageTimeoutA(
} }
if (! Info.HandledByKernel) if (! Info.HandledByKernel)
{ {
PWND pWnd;
pWnd = ValidateHwnd(hWnd);
/* We need to send the message ourselves */ /* We need to send the message ourselves */
if (Info.Ansi) if (Info.Ansi)
{ {
/* Ansi message and Ansi window proc, that's easy. Clean up /* Ansi message and Ansi window proc, that's easy. Clean up
the Unicode message though */ the Unicode message though */
MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg); MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg);
Result = IntCallWindowProcA(Info.Ansi, Info.Proc, hWnd, Msg, wParam, lParam); Result = IntCallWindowProcA(Info.Ansi, Info.Proc, pWnd, hWnd, Msg, wParam, lParam);
} }
else else
{ {
/* Unicode winproc. Although we started out with an Ansi message we /* Unicode winproc. Although we started out with an Ansi message we
already converted it to Unicode for the kernel call. Reuse that already converted it to Unicode for the kernel call. Reuse that
message to avoid another conversion */ message to avoid another conversion */
Result = IntCallWindowProcW(Info.Ansi, Info.Proc, UcMsg.hwnd, Result = IntCallWindowProcW( Info.Ansi,
UcMsg.message, UcMsg.wParam, UcMsg.lParam); Info.Proc,
pWnd,
UcMsg.hwnd,
UcMsg.message,
UcMsg.wParam,
UcMsg.lParam);
if (! MsgiAnsiToUnicodeReply(&UcMsg, &AnsiMsg, &Result)) if (! MsgiAnsiToUnicodeReply(&UcMsg, &AnsiMsg, &Result))
{ {
SPY_ExitMessage(SPY_RESULT_OK, hWnd, Msg, Result, wParam, lParam); SPY_ExitMessage(SPY_RESULT_OK, hWnd, Msg, Result, wParam, lParam);
@ -2112,8 +2301,10 @@ SendMessageTimeoutW(
lpdwResult, &Info); lpdwResult, &Info);
if (! Info.HandledByKernel) if (! Info.HandledByKernel)
{ {
PWND pWnd;
pWnd = ValidateHwnd(hWnd);
/* We need to send the message ourselves */ /* We need to send the message ourselves */
Result = IntCallWindowProcW(Info.Ansi, Info.Proc, hWnd, Msg, wParam, lParam); Result = IntCallWindowProcW(Info.Ansi, Info.Proc, pWnd, hWnd, Msg, wParam, lParam);
if(lpdwResult) if(lpdwResult)
*lpdwResult = Result; *lpdwResult = Result;
@ -2322,6 +2513,8 @@ User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
{ {
PWINDOWPROC_CALLBACK_ARGUMENTS CallbackArgs; PWINDOWPROC_CALLBACK_ARGUMENTS CallbackArgs;
MSG KMMsg, UMMsg; MSG KMMsg, UMMsg;
PWND pWnd = NULL;
PCLIENTINFO pci = GetWin32ClientInfo();
/* Make sure we don't try to access mem beyond what we were given */ /* Make sure we don't try to access mem beyond what we were given */
if (ArgumentLength < sizeof(WINDOWPROC_CALLBACK_ARGUMENTS)) if (ArgumentLength < sizeof(WINDOWPROC_CALLBACK_ARGUMENTS))
@ -2362,8 +2555,12 @@ User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
{ {
} }
if (pci->CallbackWnd.hWnd == UMMsg.hwnd)
pWnd = pci->CallbackWnd.pvWnd;
CallbackArgs->Result = IntCallWindowProcW( CallbackArgs->IsAnsiProc, CallbackArgs->Result = IntCallWindowProcW( CallbackArgs->IsAnsiProc,
CallbackArgs->Proc, CallbackArgs->Proc,
pWnd,
UMMsg.hwnd, UMMsg.hwnd,
UMMsg.message, UMMsg.message,
UMMsg.wParam, UMMsg.wParam,

View file

@ -1058,14 +1058,11 @@ DefWndTrackScrollBar(HWND hWnd, WPARAM wParam, POINT Point)
/* PUBLIC FUNCTIONS ***********************************************************/ /* PUBLIC FUNCTIONS ***********************************************************/
/*
* @implemented
*/
BOOL WINAPI BOOL WINAPI
AdjustWindowRectEx(LPRECT lpRect, RealAdjustWindowRectEx(LPRECT lpRect,
DWORD dwStyle, DWORD dwStyle,
BOOL bMenu, BOOL bMenu,
DWORD dwExStyle) DWORD dwExStyle)
{ {
SIZE BorderSize; SIZE BorderSize;
@ -1089,6 +1086,38 @@ AdjustWindowRectEx(LPRECT lpRect,
return TRUE; return TRUE;
} }
/*
* @implemented
*/
BOOL WINAPI
AdjustWindowRectEx(LPRECT lpRect,
DWORD dwStyle,
BOOL bMenu,
DWORD dwExStyle)
{
BOOL Hook, Ret = FALSE;
LOADUSERAPIHOOK
Hook = BeginIfHookedUserApiHook();
/* Bypass SEH and go direct. */
if (!Hook) return RealAdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle);
_SEH2_TRY
{
Ret = guah.AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
EndUserApiHook();
return Ret;
}
/* /*
* @implemented * @implemented
@ -1110,7 +1139,27 @@ AdjustWindowRect(LPRECT lpRect,
BOOL WINAPI BOOL WINAPI
DrawCaption(HWND hWnd, HDC hDC, LPCRECT lprc, UINT uFlags) DrawCaption(HWND hWnd, HDC hDC, LPCRECT lprc, UINT uFlags)
{ {
return NtUserDrawCaption(hWnd, hDC, lprc, uFlags); BOOL Hook, Ret = FALSE;
LOADUSERAPIHOOK
Hook = BeginIfHookedUserApiHook();
/* Bypass SEH and go direct. */
if (!Hook) return NtUserDrawCaption(hWnd, hDC, lprc, uFlags);
_SEH2_TRY
{
Ret = guah.DrawCaption(hWnd, hDC, lprc, uFlags);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
EndUserApiHook();
return Ret;
} }
/* /*

View file

@ -131,7 +131,6 @@ ScrollDC(HDC hDC, int dx, int dy, CONST RECT *lprcScroll, CONST RECT *lprcClip,
lprcUpdate); lprcUpdate);
} }
/* /*
* @implemented * @implemented
*/ */
@ -142,9 +141,29 @@ SetWindowRgn(
HRGN hRgn, HRGN hRgn,
BOOL bRedraw) BOOL bRedraw)
{ {
return (int)NtUserSetWindowRgn(hWnd, hRgn, bRedraw); BOOL Hook;
} int Ret = 0;
LOADUSERAPIHOOK
Hook = BeginIfHookedUserApiHook();
/* Bypass SEH and go direct. */
if (!Hook) return (int)NtUserSetWindowRgn(hWnd, hRgn, bRedraw);
_SEH2_TRY
{
Ret = guah.SetWindowRgn(hWnd, hRgn, bRedraw);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
_SEH2_END;
EndUserApiHook();
return Ret;
}
/* /*
* @implemented * @implemented

View file

@ -1875,6 +1875,12 @@ GetFocus(VOID)
return (HWND)NtUserGetThreadState(THREADSTATE_FOCUSWINDOW); return (HWND)NtUserGetThreadState(THREADSTATE_FOCUSWINDOW);
} }
DWORD WINAPI
GetRealWindowOwner(HWND hwnd)
{
return NtUserQueryWindow(hwnd, QUERY_WINDOW_REAL_ID);
}
/* /*
* @implemented * @implemented
*/ */

View file

@ -560,6 +560,7 @@ typedef LONG_PTR (NTAPI *PFN_FNID)(PWND, UINT, WPARAM, LPARAM, ULONG_PTR);
#define COLOR_LAST COLOR_MENUBAR #define COLOR_LAST COLOR_MENUBAR
#define MAX_MB_STRINGS 11 #define MAX_MB_STRINGS 11
#define SRVINFO_APIHOOK 0x0010
#define SRVINFO_METRICS 0x0020 #define SRVINFO_METRICS 0x0020
typedef struct tagOEMBITMAPINFO typedef struct tagOEMBITMAPINFO
@ -2359,11 +2360,13 @@ NtUserRegisterRawInputDevices(
IN UINT uiNumDevices, IN UINT uiNumDevices,
IN UINT cbSize); IN UINT cbSize);
DWORD BOOL
NTAPI NTAPI
NtUserRegisterUserApiHook( NtUserRegisterUserApiHook(
DWORD dwUnknown1, PUNICODE_STRING m_dllname1,
DWORD dwUnknown2); PUNICODE_STRING m_funname1,
DWORD dwUnknown3,
DWORD dwUnknown4);
BOOL BOOL
NTAPI NTAPI
@ -2875,7 +2878,7 @@ NTAPI
NtUserUnregisterHotKey(HWND hWnd, NtUserUnregisterHotKey(HWND hWnd,
int id); int id);
DWORD BOOL
NTAPI NTAPI
NtUserUnregisterUserApiHook(VOID); NtUserUnregisterUserApiHook(VOID);

View file

@ -949,13 +949,17 @@ NtUserRealWaitMessageEx(
return 0; return 0;
} }
DWORD BOOL
APIENTRY APIENTRY
NtUserRegisterUserApiHook( NtUserRegisterUserApiHook(
DWORD dwUnknown1, PUNICODE_STRING m_dllname1,
DWORD dwUnknown2) PUNICODE_STRING m_funname1,
DWORD dwUnknown3,
DWORD dwUnknown4)
{ {
UserEnterExclusive();
UNIMPLEMENTED; UNIMPLEMENTED;
UserLeave();
return 0; return 0;
} }
@ -1080,7 +1084,7 @@ NtUserPaintMenuBar(
return 0; return 0;
} }
DWORD BOOL
APIENTRY APIENTRY
NtUserUnregisterUserApiHook(VOID) NtUserUnregisterUserApiHook(VOID)
{ {

View file

@ -493,7 +493,7 @@ NtUserRealInternalGetMessage 6
NtUserRealWaitMessageEx 2 NtUserRealWaitMessageEx 2
NtUserRedrawWindow 4 NtUserRedrawWindow 4
NtUserRegisterClassExWOW 7 NtUserRegisterClassExWOW 7
NtUserRegisterUserApiHook 2 NtUserRegisterUserApiHook 4
NtUserRegisterHotKey 4 NtUserRegisterHotKey 4
NtUserRegisterRawInputDevices 3 NtUserRegisterRawInputDevices 3
NtUserRegisterTasklist 1 NtUserRegisterTasklist 1