mirror of
https://github.com/reactos/reactos.git
synced 2025-07-30 19:41:57 +00:00
[User32]
- Fixed Dialog Ansi and color control brush acquisition. - Added stack protection for message recursion. Due to wine message bug when in dialog initialization. See bug 6126. - Miscellaneous fixups. svn path=/trunk/; revision=54293
This commit is contained in:
parent
888f1950e9
commit
c30a8a6e49
2 changed files with 118 additions and 70 deletions
|
@ -45,6 +45,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(user32);
|
|||
#define SETDLGINFO(hwnd, info) SetWindowLongPtrW((hwnd), DWLP_ROS_DIALOGINFO, (LONG_PTR)(info))
|
||||
#define GET_WORD(ptr) (*(WORD *)(ptr))
|
||||
#define GET_DWORD(ptr) (*(DWORD *)(ptr))
|
||||
#define DLG_ISANSI 2
|
||||
void WINAPI WinPosActivateOtherWindow(HWND hwnd);
|
||||
|
||||
/* INTERNAL STRUCTS **********************************************************/
|
||||
|
@ -163,11 +164,11 @@ DIALOGINFO *DIALOG_get_info( HWND hWnd, BOOL create )
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (dlgInfo)
|
||||
{
|
||||
if (!(pWindow->state & WNDS_DIALOGWINDOW) || pWindow->fnid != FNID_DIALOG)
|
||||
{
|
||||
ERR("Wrong window class for Dialog!\n");
|
||||
ERR("Wrong window class for Dialog! fnId 0x%x\n", pWindow->fnid);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -264,11 +265,14 @@ static const WORD *DIALOG_GetControl32( const WORD *p, DLG_CONTROL_INFO *info,
|
|||
/* Windows treats dialog control class ids 0-5 same way as 0x80-0x85 */
|
||||
if ((id >= 0x80) && (id <= 0x85)) id -= 0x80;
|
||||
if (id <= 5)
|
||||
{
|
||||
info->className = class_names[id];
|
||||
}
|
||||
else
|
||||
{
|
||||
info->className = NULL;
|
||||
/* FIXME: load other classes here? */
|
||||
ERR("Unknown built-in class id %04x\n", id );
|
||||
}
|
||||
p += 2;
|
||||
}
|
||||
|
@ -300,6 +304,11 @@ static const WORD *DIALOG_GetControl32( const WORD *p, DLG_CONTROL_INFO *info,
|
|||
p += strlenW( info->windowName ) + 1;
|
||||
}
|
||||
|
||||
TRACE(" %s %s %ld, %d, %d, %d, %d, %08x, %08x, %08x\n",
|
||||
debugstr_w( info->className ), debugstr_w( info->windowName ),
|
||||
info->id, info->x, info->y, info->cx, info->cy,
|
||||
info->style, info->exStyle, info->helpId );
|
||||
|
||||
if (GET_WORD(p))
|
||||
{
|
||||
info->data = p + 1;
|
||||
|
@ -339,6 +348,7 @@ static BOOL DIALOG_CreateControls32( HWND hwnd, LPCSTR template, const DLG_TEMPL
|
|||
info.style &= ~WS_BORDER;
|
||||
info.exStyle |= WS_EX_CLIENTEDGE;
|
||||
}
|
||||
|
||||
if (unicode)
|
||||
{
|
||||
hwndCtrl = CreateWindowExW( info.exStyle | WS_EX_NOPARENTNOTIFY,
|
||||
|
@ -1147,8 +1157,7 @@ static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
|
|||
{
|
||||
case WM_ERASEBKGND:
|
||||
{
|
||||
HBRUSH brush = (HBRUSH)SendMessageW( hwnd, WM_CTLCOLORDLG, wParam, (LPARAM)hwnd );
|
||||
if (!brush) brush = (HBRUSH)DefWindowProcW( hwnd, WM_CTLCOLORDLG, wParam, (LPARAM)hwnd );
|
||||
HBRUSH brush = GetControlColor( hwnd, hwnd, (HDC)wParam, WM_CTLCOLORDLG);
|
||||
if (brush)
|
||||
{
|
||||
RECT rect;
|
||||
|
@ -1247,12 +1256,17 @@ static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
|
|||
/***********************************************************************
|
||||
* DEFDLG_Epilog
|
||||
*/
|
||||
static LRESULT DEFDLG_Epilog(HWND hwnd, UINT msg, BOOL fResult)
|
||||
static LRESULT DEFDLG_Epilog(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL fResult, BOOL fAnsi)
|
||||
{
|
||||
|
||||
// TODO: where's wine's WM_CTLCOLOR from?
|
||||
if ((msg >= WM_CTLCOLORMSGBOX && msg <= WM_CTLCOLORSTATIC) ||
|
||||
msg == WM_CTLCOLOR || msg == WM_COMPAREITEM ||
|
||||
msg == WM_CTLCOLOR)
|
||||
{
|
||||
if (fResult) return fResult;
|
||||
|
||||
return fAnsi ? DefWindowProcA(hwnd, msg, wParam, lParam):
|
||||
DefWindowProcW(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
if ( msg == WM_COMPAREITEM ||
|
||||
msg == WM_VKEYTOITEM || msg == WM_CHARTOITEM ||
|
||||
msg == WM_QUERYDRAGICON || msg == WM_INITDIALOG)
|
||||
return fResult;
|
||||
|
@ -1519,7 +1533,7 @@ CreateDialogIndirectParamAorW(
|
|||
* Also wine has one more parameter identifying weather it should call
|
||||
* the function with unicode or not
|
||||
*/
|
||||
return DIALOG_CreateIndirect( hInstance, lpTemplate, hWndParent, lpDialogFunc, lParamInit , !Flags, FALSE );
|
||||
return DIALOG_CreateIndirect( hInstance, lpTemplate, hWndParent, lpDialogFunc, lParamInit , Flags == DLG_ISANSI ? FALSE : TRUE, FALSE );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1535,7 +1549,7 @@ CreateDialogIndirectParamA(
|
|||
DLGPROC lpDialogFunc,
|
||||
LPARAM lParamInit)
|
||||
{
|
||||
return CreateDialogIndirectParamAorW( hInstance, lpTemplate, hWndParent, lpDialogFunc, lParamInit, 2 );
|
||||
return CreateDialogIndirectParamAorW( hInstance, lpTemplate, hWndParent, lpDialogFunc, lParamInit, DLG_ISANSI);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1653,7 +1667,7 @@ DefDlgProcA(
|
|||
return DefWindowProcA( hDlg, Msg, wParam, lParam );
|
||||
}
|
||||
}
|
||||
return DEFDLG_Epilog(hDlg, Msg, result);
|
||||
return DEFDLG_Epilog(hDlg, Msg, wParam, lParam, result, TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1713,7 +1727,7 @@ DefDlgProcW(
|
|||
return DefWindowProcW( hDlg, Msg, wParam, lParam );
|
||||
}
|
||||
}
|
||||
return DEFDLG_Epilog(hDlg, Msg, result);
|
||||
return DEFDLG_Epilog(hDlg, Msg, wParam, lParam, result, FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1735,7 +1749,7 @@ DialogBoxIndirectParamAorW(
|
|||
* Also wine has one more parameter identifying weather it should call
|
||||
* the function with unicode or not
|
||||
*/
|
||||
HWND hWnd = DIALOG_CreateIndirect( hInstance, hDialogTemplate, hWndParent, lpDialogFunc, dwInitParam, !Flags, TRUE );
|
||||
HWND hWnd = DIALOG_CreateIndirect( hInstance, hDialogTemplate, hWndParent, lpDialogFunc, dwInitParam, Flags == DLG_ISANSI ? FALSE : TRUE, TRUE );
|
||||
if (hWnd) return DIALOG_DoDialogBox( hWnd, hWndParent );
|
||||
return -1;
|
||||
}
|
||||
|
@ -1753,7 +1767,7 @@ DialogBoxIndirectParamA(
|
|||
DLGPROC lpDialogFunc,
|
||||
LPARAM dwInitParam)
|
||||
{
|
||||
return DialogBoxIndirectParamAorW( hInstance, hDialogTemplate, hWndParent, lpDialogFunc, dwInitParam, 2);
|
||||
return DialogBoxIndirectParamAorW( hInstance, hDialogTemplate, hWndParent, lpDialogFunc, dwInitParam, DLG_ISANSI);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2063,6 +2077,7 @@ GetDlgItem(
|
|||
for (i = 0; list[i]; i++) if (GetWindowLongPtrW(list[i], GWLP_ID) == nIDDlgItem) break;
|
||||
ret = list[i];
|
||||
HeapFree(GetProcessHeap(), 0, list);
|
||||
// if (!ret) SetLastError(ERROR_CONTROL_ID_NOT_FOUND);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -88,6 +88,8 @@ static inline int is_pointer_message( UINT message )
|
|||
return (message_pointer_flags[message / 32] & SET(message)) != 0;
|
||||
}
|
||||
|
||||
#undef SET
|
||||
|
||||
/* DDE message exchange
|
||||
*
|
||||
* - Session initialization
|
||||
|
@ -1031,6 +1033,48 @@ MsgiUnicodeToAnsiReply(LPMSG AnsiMsg, LPMSG UnicodeMsg, LRESULT *Result)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* map_wparam_AtoW
|
||||
*
|
||||
* Convert the wparam of an ASCII message to Unicode.
|
||||
*/
|
||||
static WPARAM
|
||||
map_wparam_AtoW( UINT message, WPARAM wparam )
|
||||
{
|
||||
switch(message)
|
||||
{
|
||||
case WM_CHARTOITEM:
|
||||
case EM_SETPASSWORDCHAR:
|
||||
case WM_CHAR:
|
||||
case WM_DEADCHAR:
|
||||
case WM_SYSCHAR:
|
||||
case WM_SYSDEADCHAR:
|
||||
case WM_MENUCHAR:
|
||||
{
|
||||
char ch[2];
|
||||
WCHAR wch[2];
|
||||
ch[0] = (wparam & 0xff);
|
||||
ch[1] = (wparam >> 8);
|
||||
MultiByteToWideChar(CP_ACP, 0, ch, 2, wch, 2);
|
||||
wparam = MAKEWPARAM(wch[0], wch[1]);
|
||||
}
|
||||
break;
|
||||
case WM_IME_CHAR:
|
||||
{
|
||||
char ch[2];
|
||||
WCHAR wch;
|
||||
ch[0] = (wparam >> 8);
|
||||
ch[1] = (wparam & 0xff);
|
||||
if (ch[0]) MultiByteToWideChar(CP_ACP, 0, ch, 2, &wch, 1);
|
||||
else MultiByteToWideChar(CP_ACP, 0, &ch[1], 1, &wch, 1);
|
||||
wparam = MAKEWPARAM( wch, HIWORD(wparam) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
return wparam;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
@ -1064,7 +1108,7 @@ GetMessageTime(VOID)
|
|||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
|
@ -1083,7 +1127,7 @@ InSendMessage(VOID)
|
|||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
DWORD
|
||||
WINAPI
|
||||
|
@ -1131,6 +1175,7 @@ IntCallWindowProcW(BOOL IsAnsiProc,
|
|||
{
|
||||
MSG AnsiMsg;
|
||||
MSG UnicodeMsg;
|
||||
ULONG_PTR LowLimit;
|
||||
BOOL Hook = FALSE, MsgOverride = FALSE, Dialog;
|
||||
LRESULT Result = 0, PreResult = 0;
|
||||
DWORD Hit = 0, Data = 0;
|
||||
|
@ -1141,6 +1186,14 @@ IntCallWindowProcW(BOOL IsAnsiProc,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
// Safeguard against excessive recursions.
|
||||
LowLimit = (ULONG_PTR)NtCurrentTeb()->NtTib.StackLimit;
|
||||
if (((ULONG_PTR)&lParam - LowLimit) < PAGE_SIZE )
|
||||
{
|
||||
ERR("IntCallWindowsProcW() Exceeded Stack!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (pWnd)
|
||||
Dialog = (pWnd->fnid == FNID_DIALOG);
|
||||
else
|
||||
|
@ -1286,6 +1339,7 @@ IntCallWindowProcA(BOOL IsAnsiProc,
|
|||
{
|
||||
MSG AnsiMsg;
|
||||
MSG UnicodeMsg;
|
||||
ULONG_PTR LowLimit;
|
||||
BOOL Hook = FALSE, MsgOverride = FALSE, Dialog;
|
||||
LRESULT Result = 0, PreResult = 0;
|
||||
DWORD Hit = 0, Data = 0;
|
||||
|
@ -1296,6 +1350,13 @@ IntCallWindowProcA(BOOL IsAnsiProc,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
LowLimit = (ULONG_PTR)NtCurrentTeb()->NtTib.StackLimit;
|
||||
if (((ULONG_PTR)&lParam - LowLimit) < PAGE_SIZE )
|
||||
{
|
||||
ERR("IntCallWindowsProcA() Exceeded Stack!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (pWnd)
|
||||
Dialog = (pWnd->fnid == FNID_DIALOG);
|
||||
else
|
||||
|
@ -1751,7 +1812,6 @@ DispatchMessageW(CONST MSG *lpmsg)
|
|||
return Ret;
|
||||
}
|
||||
|
||||
|
||||
static VOID
|
||||
IntConvertMsgToAnsi(LPMSG lpMsg)
|
||||
{
|
||||
|
@ -1793,9 +1853,9 @@ GetMessageA(LPMSG lpMsg,
|
|||
|
||||
Res = NtUserGetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
|
||||
if (-1 == (int) Res)
|
||||
{
|
||||
{
|
||||
return Res;
|
||||
}
|
||||
}
|
||||
|
||||
IntConvertMsgToAnsi(lpMsg);
|
||||
|
||||
|
@ -1821,9 +1881,9 @@ GetMessageW(LPMSG lpMsg,
|
|||
|
||||
Res = NtUserGetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
|
||||
if (-1 == (int) Res)
|
||||
{
|
||||
{
|
||||
return Res;
|
||||
}
|
||||
}
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
@ -1879,9 +1939,11 @@ PeekMessageA(LPMSG lpMsg,
|
|||
|
||||
Res = PeekMessageWorker(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
|
||||
if (-1 == (int) Res || !Res)
|
||||
{
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
IntConvertMsgToAnsi(lpMsg);
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
@ -1903,9 +1965,9 @@ PeekMessageW(
|
|||
|
||||
Res = PeekMessageWorker(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
|
||||
if (-1 == (int) Res || !Res)
|
||||
{
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
@ -2062,7 +2124,7 @@ SendMessageW(HWND Wnd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
|
||||
if (Wnd != HWND_TOPMOST && Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
|
||||
{
|
||||
Window = ValidateHwnd(Wnd);
|
||||
|
||||
|
@ -2127,7 +2189,7 @@ SendMessageA(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
|
||||
if (Wnd != HWND_TOPMOST && Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
|
||||
{
|
||||
Window = ValidateHwnd(Wnd);
|
||||
|
||||
|
@ -2291,7 +2353,8 @@ SendMessageTimeoutA(
|
|||
|
||||
if (lpdwResult) *lpdwResult = 0;
|
||||
|
||||
if (hWnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
|
||||
//// This is due to message system bug.
|
||||
if (hWnd != HWND_TOPMOST && hWnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
|
||||
{
|
||||
Window = ValidateHwnd(hWnd);
|
||||
|
||||
|
@ -2306,6 +2369,7 @@ SendMessageTimeoutA(
|
|||
return TRUE;
|
||||
}
|
||||
}
|
||||
////
|
||||
SPY_EnterMessage(SPY_SENDMESSAGE, hWnd, Msg, wParam, lParam);
|
||||
|
||||
dsm.uFlags = fuFlags;
|
||||
|
@ -2366,7 +2430,8 @@ SendMessageTimeoutW(
|
|||
|
||||
if (lpdwResult) *lpdwResult = 0;
|
||||
|
||||
if (hWnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
|
||||
//// This is due to message system bug.
|
||||
if (hWnd != HWND_TOPMOST && hWnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
|
||||
{
|
||||
Window = ValidateHwnd(hWnd);
|
||||
|
||||
|
@ -2381,6 +2446,7 @@ SendMessageTimeoutW(
|
|||
return TRUE;
|
||||
}
|
||||
}
|
||||
////
|
||||
SPY_EnterMessage(SPY_SENDMESSAGE, hWnd, Msg, wParam, lParam);
|
||||
|
||||
dsm.uFlags = fuFlags;
|
||||
|
@ -2611,6 +2677,7 @@ User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
|||
PWINDOWPROC_CALLBACK_ARGUMENTS CallbackArgs;
|
||||
MSG KMMsg, UMMsg;
|
||||
PWND pWnd = NULL;
|
||||
ULONG_PTR LowLimit;
|
||||
PCLIENTINFO pci = GetWin32ClientInfo();
|
||||
|
||||
/* Make sure we don't try to access mem beyond what we were given */
|
||||
|
@ -2619,6 +2686,13 @@ User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
|
|||
return STATUS_INFO_LENGTH_MISMATCH;
|
||||
}
|
||||
|
||||
LowLimit = (ULONG_PTR)NtCurrentTeb()->NtTib.StackLimit;
|
||||
if (((ULONG_PTR)&ArgumentLength - LowLimit) < PAGE_SIZE )
|
||||
{
|
||||
ERR("Callback from Win32k Exceeded Stack!\n");
|
||||
return STATUS_BAD_STACK;
|
||||
}
|
||||
|
||||
CallbackArgs = (PWINDOWPROC_CALLBACK_ARGUMENTS) Arguments;
|
||||
KMMsg.hwnd = CallbackArgs->Wnd;
|
||||
KMMsg.message = CallbackArgs->Msg;
|
||||
|
@ -2914,47 +2988,6 @@ VOID FASTCALL MessageCleanup(VOID)
|
|||
DeleteCriticalSection(&gcsMPH);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* map_wparam_AtoW
|
||||
*
|
||||
* Convert the wparam of an ASCII message to Unicode.
|
||||
*/
|
||||
static WPARAM
|
||||
map_wparam_AtoW( UINT message, WPARAM wparam )
|
||||
{
|
||||
switch(message)
|
||||
{
|
||||
case WM_CHARTOITEM:
|
||||
case EM_SETPASSWORDCHAR:
|
||||
case WM_CHAR:
|
||||
case WM_DEADCHAR:
|
||||
case WM_SYSCHAR:
|
||||
case WM_SYSDEADCHAR:
|
||||
case WM_MENUCHAR:
|
||||
{
|
||||
char ch[2];
|
||||
WCHAR wch[2];
|
||||
ch[0] = (wparam & 0xff);
|
||||
ch[1] = (wparam >> 8);
|
||||
MultiByteToWideChar(CP_ACP, 0, ch, 2, wch, 2);
|
||||
wparam = MAKEWPARAM(wch[0], wch[1]);
|
||||
}
|
||||
break;
|
||||
case WM_IME_CHAR:
|
||||
{
|
||||
char ch[2];
|
||||
WCHAR wch;
|
||||
ch[0] = (wparam >> 8);
|
||||
ch[1] = (wparam & 0xff);
|
||||
if (ch[0]) MultiByteToWideChar(CP_ACP, 0, ch, 2, &wch, 1);
|
||||
else MultiByteToWideChar(CP_ACP, 0, &ch[1], 1, &wch, 1);
|
||||
wparam = MAKEWPARAM( wch, HIWORD(wparam) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
return wparam;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue