mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 12:55:43 +00:00
[WIN32K]
- Fix user32:monitor winetest failures (ClipCursor bugs) - Protect functions in accelerator.c with SEH svn path=/trunk/; revision=53636
This commit is contained in:
parent
c7b81786fe
commit
8571e00fdc
2 changed files with 100 additions and 41 deletions
|
@ -309,21 +309,32 @@ NtUserCopyAcceleratorTable(
|
||||||
|
|
||||||
Ret = 0;
|
Ret = 0;
|
||||||
|
|
||||||
while (!Done)
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
if (Entries)
|
ProbeForWrite(Entries, EntriesCount*sizeof(Entries[0]), 4);
|
||||||
|
|
||||||
|
while (!Done)
|
||||||
{
|
{
|
||||||
Entries[Ret].fVirt = Accel->Table[Ret].fVirt & 0x7f;
|
if (Entries)
|
||||||
Entries[Ret].key = Accel->Table[Ret].key;
|
{
|
||||||
Entries[Ret].cmd = Accel->Table[Ret].cmd;
|
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(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);
|
RETURN(Ret);
|
||||||
|
|
||||||
|
@ -342,6 +353,7 @@ NtUserCreateAcceleratorTable(
|
||||||
PACCELERATOR_TABLE Accel;
|
PACCELERATOR_TABLE Accel;
|
||||||
HACCEL hAccel;
|
HACCEL hAccel;
|
||||||
INT Index;
|
INT Index;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
DECLARE_RETURN(HACCEL);
|
DECLARE_RETURN(HACCEL);
|
||||||
|
|
||||||
TRACE("Enter NtUserCreateAcceleratorTable(Entries %p, EntriesCount %d)\n",
|
TRACE("Enter NtUserCreateAcceleratorTable(Entries %p, EntriesCount %d)\n",
|
||||||
|
@ -374,23 +386,42 @@ NtUserCreateAcceleratorTable(
|
||||||
RETURN( (HACCEL) NULL);
|
RETURN( (HACCEL) NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Index = 0; Index < EntriesCount; Index++)
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
Accel->Table[Index].fVirt = Entries[Index].fVirt&0x7f;
|
ProbeForRead(Entries, EntriesCount * sizeof(ACCEL), 4);
|
||||||
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;
|
for (Index = 0; Index < EntriesCount; Index++)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_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. */
|
/* Set the end-of-table terminator. */
|
||||||
|
@ -450,28 +481,41 @@ APIENTRY
|
||||||
NtUserTranslateAccelerator(
|
NtUserTranslateAccelerator(
|
||||||
HWND hWnd,
|
HWND hWnd,
|
||||||
HACCEL hAccel,
|
HACCEL hAccel,
|
||||||
LPMSG Message)
|
LPMSG pUnsafeMessage)
|
||||||
{
|
{
|
||||||
PWND Window = NULL;
|
PWND Window = NULL;
|
||||||
PACCELERATOR_TABLE Accel = NULL;
|
PACCELERATOR_TABLE Accel = NULL;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
MSG Message;
|
||||||
USER_REFERENCE_ENTRY AccelRef, WindowRef;
|
USER_REFERENCE_ENTRY AccelRef, WindowRef;
|
||||||
DECLARE_RETURN(int);
|
DECLARE_RETURN(int);
|
||||||
|
|
||||||
TRACE("NtUserTranslateAccelerator(hWnd %x, Table %x, Message %p)\n",
|
TRACE("NtUserTranslateAccelerator(hWnd %x, Table %x, Message %p)\n",
|
||||||
hWnd, hAccel, Message);
|
hWnd, hAccel, pUnsafeMessage);
|
||||||
UserEnterShared();
|
UserEnterShared();
|
||||||
|
|
||||||
if (Message == NULL)
|
if (pUnsafeMessage == NULL)
|
||||||
{
|
{
|
||||||
SetLastNtError(STATUS_INVALID_PARAMETER);
|
SetLastNtError(STATUS_INVALID_PARAMETER);
|
||||||
RETURN( 0);
|
RETURN( 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Message->message != WM_KEYDOWN) &&
|
_SEH2_TRY
|
||||||
(Message->message != WM_SYSKEYDOWN) &&
|
{
|
||||||
(Message->message != WM_SYSCHAR) &&
|
ProbeForRead(pUnsafeMessage, sizeof(MSG), 4);
|
||||||
(Message->message != WM_CHAR))
|
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);
|
RETURN( 0);
|
||||||
}
|
}
|
||||||
|
@ -490,17 +534,16 @@ NtUserTranslateAccelerator(
|
||||||
|
|
||||||
UserRefObjectCo(Window, &WindowRef);
|
UserRefObjectCo(Window, &WindowRef);
|
||||||
|
|
||||||
|
|
||||||
/* FIXME: Associate AcceleratorTable with the current thread */
|
/* FIXME: Associate AcceleratorTable with the current thread */
|
||||||
|
|
||||||
for (i = 0; i < Accel->Count; i++)
|
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].fVirt, Accel->Table[i].key,
|
||||||
Accel->Table[i].cmd))
|
Accel->Table[i].cmd))
|
||||||
{
|
{
|
||||||
TRACE("NtUserTranslateAccelerator(hWnd %x, Table %x, Message %p) = %i end\n",
|
TRACE("NtUserTranslateAccelerator(hWnd %x, Table %x, Message %p) = %i end\n",
|
||||||
hWnd, hAccel, Message, 1);
|
hWnd, hAccel, pUnsafeMessage, 1);
|
||||||
RETURN( 1);
|
RETURN( 1);
|
||||||
}
|
}
|
||||||
if (((Accel->Table[i].fVirt & 0x80) > 0))
|
if (((Accel->Table[i].fVirt & 0x80) > 0))
|
||||||
|
@ -516,7 +559,7 @@ CLEANUP:
|
||||||
if (Accel) UserDerefObjectCo(Accel);
|
if (Accel) UserDerefObjectCo(Accel);
|
||||||
|
|
||||||
TRACE("NtUserTranslateAccelerator(hWnd %x, Table %x, Message %p) = %i end\n",
|
TRACE("NtUserTranslateAccelerator(hWnd %x, Table %x, Message %p) = %i end\n",
|
||||||
hWnd, hAccel, Message, 0);
|
hWnd, hAccel, pUnsafeMessage, 0);
|
||||||
UserLeave();
|
UserLeave();
|
||||||
END_CLEANUP;
|
END_CLEANUP;
|
||||||
}
|
}
|
||||||
|
|
|
@ -564,13 +564,29 @@ UserClipCursor(
|
||||||
|
|
||||||
DesktopWindow = UserGetDesktopWindow();
|
DesktopWindow = UserGetDesktopWindow();
|
||||||
|
|
||||||
if (prcl != NULL &&
|
if (prcl != NULL && DesktopWindow != NULL)
|
||||||
(prcl->right > prcl->left) &&
|
|
||||||
(prcl->bottom > prcl->top) &&
|
|
||||||
DesktopWindow != NULL)
|
|
||||||
{
|
{
|
||||||
|
if (prcl->right < prcl->left || prcl->bottom < prcl->top)
|
||||||
|
{
|
||||||
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
CurInfo->bClipped = TRUE;
|
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);
|
UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, 0, 0, FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue