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;
- Entries[Ret].key = Accel->Table[Ret].key;
- Entries[Ret].cmd = Accel->Table[Ret].cmd;
+ 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(Ret + 1 == EntriesCount) Done = TRUE;
+ }
- if((Accel->Table[Ret].fVirt & 0x80) != 0) Done = TRUE;
+ if((Accel->Table[Ret].fVirt & 0x80) != 0) Done = TRUE;
- Ret++;
+ Ret++;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ Ret = 0;
}
+ _SEH2_END;
RETURN(Ret);
PACCELERATOR_TABLE Accel;
HACCEL hAccel;
INT Index;
+ NTSTATUS Status = STATUS_SUCCESS;
DECLARE_RETURN(HACCEL);
TRACE("Enter NtUserCreateAcceleratorTable(Entries %p, EntriesCount %d)\n",
RETURN( (HACCEL) NULL);
}
- for (Index = 0; Index < EntriesCount; Index++)
+ _SEH2_TRY
{
- Accel->Table[Index].fVirt = Entries[Index].fVirt&0x7f;
- if(Accel->Table[Index].fVirt & FVIRTKEY)
- {
- Accel->Table[Index].key = Entries[Index].key;
- }
- else
+ ProbeForRead(Entries, EntriesCount * sizeof(ACCEL), 4);
+
+ for (Index = 0; Index < EntriesCount; Index++)
{
- RtlMultiByteToUnicodeN(&Accel->Table[Index].key,
- sizeof(WCHAR),
- NULL,
- (PCSTR)&Entries[Index].key,
- sizeof(CHAR));
+ 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;
- Accel->Table[Index].cmd = Entries[Index].cmd;
+ 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. */
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);
}
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))
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;
}
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