Author: rharabien
Date: Thu Sep 8 09:55:28 2011
New Revision: 53636
URL:
http://svn.reactos.org/svn/reactos?rev=53636&view=rev
Log:
[WIN32K]
- Fix user32:monitor winetest failures (ClipCursor bugs)
- Protect functions in accelerator.c with SEH
Modified:
trunk/reactos/subsystems/win32/win32k/ntuser/accelerator.c
trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/accelerator.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/accelerator.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/accelerator.c [iso-8859-1] Thu Sep 8
09:55:28 2011
@@ -309,21 +309,32 @@
Ret = 0;
- while (!Done)
- {
- if (Entries)
+ _SEH2_TRY
+ {
+ ProbeForWrite(Entries, EntriesCount*sizeof(Entries[0]), 4);
+
+ while (!Done)
{
- Entries[Ret].fVirt = Accel->Table[Ret].fVirt & 0x7f;
- Entries[Ret].key = Accel->Table[Ret].key;
- Entries[Ret].cmd = Accel->Table[Ret].cmd;
-
- if(Ret + 1 == EntriesCount) Done = TRUE;
+ if (Entries)
+ {
+ Entries[Ret].fVirt = Accel->Table[Ret].fVirt & 0x7f;
+ Entries[Ret].key = Accel->Table[Ret].key;
+ Entries[Ret].cmd = Accel->Table[Ret].cmd;
+
+ if(Ret + 1 == EntriesCount) Done = TRUE;
+ }
+
+ if((Accel->Table[Ret].fVirt & 0x80) != 0) Done = TRUE;
+
+ Ret++;
}
-
- if((Accel->Table[Ret].fVirt & 0x80) != 0) Done = TRUE;
-
- Ret++;
- }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ Ret = 0;
+ }
+ _SEH2_END;
RETURN(Ret);
@@ -342,6 +353,7 @@
PACCELERATOR_TABLE Accel;
HACCEL hAccel;
INT Index;
+ NTSTATUS Status = STATUS_SUCCESS;
DECLARE_RETURN(HACCEL);
TRACE("Enter NtUserCreateAcceleratorTable(Entries %p, EntriesCount %d)\n",
@@ -374,23 +386,42 @@
RETURN( (HACCEL) NULL);
}
- for (Index = 0; Index < EntriesCount; Index++)
- {
- Accel->Table[Index].fVirt = Entries[Index].fVirt&0x7f;
- if(Accel->Table[Index].fVirt & FVIRTKEY)
+ _SEH2_TRY
+ {
+ ProbeForRead(Entries, EntriesCount * sizeof(ACCEL), 4);
+
+ for (Index = 0; Index < EntriesCount; Index++)
{
- Accel->Table[Index].key = Entries[Index].key;
+ Accel->Table[Index].fVirt = Entries[Index].fVirt&0x7f;
+ if(Accel->Table[Index].fVirt & FVIRTKEY)
+ {
+ Accel->Table[Index].key = Entries[Index].key;
+ }
+ else
+ {
+ RtlMultiByteToUnicodeN(&Accel->Table[Index].key,
+ sizeof(WCHAR),
+ NULL,
+ (PCSTR)&Entries[Index].key,
+ sizeof(CHAR));
+ }
+
+ Accel->Table[Index].cmd = Entries[Index].cmd;
}
- else
- {
- RtlMultiByteToUnicodeN(&Accel->Table[Index].key,
- sizeof(WCHAR),
- NULL,
- (PCSTR)&Entries[Index].key,
- sizeof(CHAR));
- }
-
- Accel->Table[Index].cmd = Entries[Index].cmd;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(Accel->Table, USERTAG_ACCEL);
+ UserDereferenceObject(Accel);
+ UserDeleteObject(hAccel, otAccel);
+ SetLastNtError(Status);
+ RETURN( (HACCEL) NULL);
}
/* Set the end-of-table terminator. */
@@ -450,28 +481,41 @@
NtUserTranslateAccelerator(
HWND hWnd,
HACCEL hAccel,
- LPMSG Message)
+ LPMSG pUnsafeMessage)
{
PWND Window = NULL;
PACCELERATOR_TABLE Accel = NULL;
ULONG i;
+ MSG Message;
USER_REFERENCE_ENTRY AccelRef, WindowRef;
DECLARE_RETURN(int);
TRACE("NtUserTranslateAccelerator(hWnd %x, Table %x, Message %p)\n",
- hWnd, hAccel, Message);
+ hWnd, hAccel, pUnsafeMessage);
UserEnterShared();
- if (Message == NULL)
+ if (pUnsafeMessage == NULL)
{
SetLastNtError(STATUS_INVALID_PARAMETER);
RETURN( 0);
}
- if ((Message->message != WM_KEYDOWN) &&
- (Message->message != WM_SYSKEYDOWN) &&
- (Message->message != WM_SYSCHAR) &&
- (Message->message != WM_CHAR))
+ _SEH2_TRY
+ {
+ ProbeForRead(pUnsafeMessage, sizeof(MSG), 4);
+ RtlCopyMemory(&Message, pUnsafeMessage, sizeof(MSG));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(RETURN( 0));
+ }
+ _SEH2_END;
+
+ if ((Message.message != WM_KEYDOWN) &&
+ (Message.message != WM_SYSKEYDOWN) &&
+ (Message.message != WM_SYSCHAR) &&
+ (Message.message != WM_CHAR))
{
RETURN( 0);
}
@@ -490,17 +534,16 @@
UserRefObjectCo(Window, &WindowRef);
-
/* FIXME: Associate AcceleratorTable with the current thread */
for (i = 0; i < Accel->Count; i++)
{
- if (co_IntTranslateAccelerator(Window, Message->message, Message->wParam,
Message->lParam,
+ if (co_IntTranslateAccelerator(Window, Message.message, Message.wParam,
Message.lParam,
Accel->Table[i].fVirt, Accel->Table[i].key,
Accel->Table[i].cmd))
{
TRACE("NtUserTranslateAccelerator(hWnd %x, Table %x, Message %p) = %i
end\n",
- hWnd, hAccel, Message, 1);
+ hWnd, hAccel, pUnsafeMessage, 1);
RETURN( 1);
}
if (((Accel->Table[i].fVirt & 0x80) > 0))
@@ -516,7 +559,7 @@
if (Accel) UserDerefObjectCo(Accel);
TRACE("NtUserTranslateAccelerator(hWnd %x, Table %x, Message %p) = %i
end\n",
- hWnd, hAccel, Message, 0);
+ hWnd, hAccel, pUnsafeMessage, 0);
UserLeave();
END_CLEANUP;
}
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1] Thu Sep 8
09:55:28 2011
@@ -564,13 +564,29 @@
DesktopWindow = UserGetDesktopWindow();
- if (prcl != NULL &&
- (prcl->right > prcl->left) &&
- (prcl->bottom > prcl->top) &&
- DesktopWindow != NULL)
- {
+ if (prcl != NULL && DesktopWindow != NULL)
+ {
+ if (prcl->right < prcl->left || prcl->bottom < prcl->top)
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
CurInfo->bClipped = TRUE;
- RECTL_bIntersectRect(&CurInfo->rcClip, prcl,
&DesktopWindow->rcWindow);
+
+ /* Set nw cliping region. Note: we can't use RECTL_bIntersectRect because
+ it sets rect to 0 0 0 0 when it's empty. For more info see monitor
winetest */
+ CurInfo->rcClip.left = max(prcl->left, DesktopWindow->rcWindow.left);
+ CurInfo->rcClip.right = min(prcl->right,
DesktopWindow->rcWindow.right);
+ if (CurInfo->rcClip.right < CurInfo->rcClip.left)
+ CurInfo->rcClip.right = CurInfo->rcClip.left;
+
+ CurInfo->rcClip.top = max(prcl->top, DesktopWindow->rcWindow.top);
+ CurInfo->rcClip.bottom = min(prcl->bottom,
DesktopWindow->rcWindow.bottom);
+ if (CurInfo->rcClip.bottom < CurInfo->rcClip.top)
+ CurInfo->rcClip.bottom = CurInfo->rcClip.top;
+
+ /* Make sure cursor is in clipping region */
UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, 0, 0, FALSE);
}
else