- 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:
James Tabor 2011-11-05 05:18:57 +00:00
parent 888f1950e9
commit c30a8a6e49
2 changed files with 118 additions and 70 deletions

View file

@ -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;
}

View file

@ -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
*/