Beispiel #1
0
BOOL
APIENTRY
NtUserSBGetParms(
  HWND hWnd, 
  int fnBar, 
  PSBDATA pSBData,
  LPSCROLLINFO lpsi)
{
   NTSTATUS Status;
   PWND Window;
   SCROLLINFO psi;
   DWORD sz;
   BOOL Ret;
   DECLARE_RETURN(BOOL);
   USER_REFERENCE_ENTRY Ref;

   TRACE("Enter NtUserGetScrollInfo\n");
   UserEnterExclusive();

   Status = MmCopyFromCaller(&psi.cbSize, &(lpsi->cbSize), sizeof(UINT));
   if(!NT_SUCCESS(Status) ||
         !((psi.cbSize == sizeof(SCROLLINFO)) || (psi.cbSize == sizeof(SCROLLINFO) - sizeof(psi.nTrackPos))))
   {
      SetLastNtError(Status);
      RETURN(FALSE);
   }
   sz = psi.cbSize;
   Status = MmCopyFromCaller(&psi, lpsi, sz);
   if (!NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      RETURN(FALSE);
   }

   if(!(Window = UserGetWindowObject(hWnd)))
   {
      RETURN(FALSE);
   }

   UserRefObjectCo(Window, &Ref);
   Ret = co_IntGetScrollInfo(Window, fnBar, &psi);
   UserDerefObjectCo(Window);

   Status = MmCopyToCaller(lpsi, &psi, sz);
   if(!NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      RETURN( FALSE);
   }

   RETURN( Ret);

CLEANUP:
   TRACE("Leave NtUserGetScrollInfo, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}
Beispiel #2
0
NTSTATUS FASTCALL
IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest,
                                      PUNICODE_STRING Source)
{
   NTSTATUS Status;
   PWSTR Src;

   Status = MmCopyFromCaller(Dest, Source, sizeof(UNICODE_STRING));
   if(!NT_SUCCESS(Status))
   {
      return Status;
   }

   if(Dest->Length > 0x4000)
   {
      return STATUS_UNSUCCESSFUL;
   }

   Src = Dest->Buffer;
   Dest->Buffer = NULL;
   Dest->MaximumLength = 0;

   if(Dest->Length > 0 && Src)
   {
      Dest->MaximumLength = Dest->Length + sizeof(WCHAR);
      Dest->Buffer = ExAllocatePoolWithTag(PagedPool, Dest->MaximumLength, TAG_STRING);
      if(!Dest->Buffer)
      {
         return STATUS_NO_MEMORY;
      }

      Status = MmCopyFromCaller(Dest->Buffer, Src, Dest->Length);
      if(!NT_SUCCESS(Status))
      {
         ExFreePoolWithTag(Dest->Buffer, TAG_STRING);
         Dest->Buffer = NULL;
         return Status;
      }

      /* Make sure the string is null-terminated */
      Src = (PWSTR)((PBYTE)Dest->Buffer + Dest->Length);
      *Src = L'\0';

      return STATUS_SUCCESS;
   }

   /* String is empty */
   return STATUS_SUCCESS;
}
Beispiel #3
0
NTSTATUS FASTCALL
IntSafeCopyUnicodeString(PUNICODE_STRING Dest,
                         PUNICODE_STRING Source)
{
   NTSTATUS Status;
   PWSTR Src;

   Status = MmCopyFromCaller(Dest, Source, sizeof(UNICODE_STRING));
   if(!NT_SUCCESS(Status))
   {
      return Status;
   }

   if(Dest->Length > 0x4000)
   {
      return STATUS_UNSUCCESSFUL;
   }

   Src = Dest->Buffer;
   Dest->Buffer = NULL;
   Dest->MaximumLength = Dest->Length;

   if(Dest->Length > 0 && Src)
   {
      Dest->Buffer = ExAllocatePoolWithTag(PagedPool, Dest->MaximumLength, TAG_STRING);
      if(!Dest->Buffer)
      {
         return STATUS_NO_MEMORY;
      }

      Status = MmCopyFromCaller(Dest->Buffer, Src, Dest->Length);
      if(!NT_SUCCESS(Status))
      {
         ExFreePoolWithTag(Dest->Buffer, TAG_STRING);
         Dest->Buffer = NULL;
         return Status;
      }


      return STATUS_SUCCESS;
   }

   /* String is empty */
   return STATUS_SUCCESS;
}
Beispiel #4
0
BOOL
APIENTRY
NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
{
   NTSTATUS Status;
   SCROLLBARINFO sbi;
   PWND Window;
   BOOL Ret;
   DECLARE_RETURN(BOOL);
   USER_REFERENCE_ENTRY Ref;

   TRACE("Enter NtUserGetScrollBarInfo\n");
   UserEnterExclusive();

   Status = MmCopyFromCaller(&sbi, psbi, sizeof(SCROLLBARINFO));
   if(!NT_SUCCESS(Status) || (sbi.cbSize != sizeof(SCROLLBARINFO)))
   {
      SetLastNtError(Status);
      RETURN(FALSE);
   }

   if(!(Window = UserGetWindowObject(hWnd)))
   {
      RETURN(FALSE);
   }

   UserRefObjectCo(Window, &Ref);
   Ret = co_IntGetScrollBarInfo(Window, idObject, &sbi);
   UserDerefObjectCo(Window);

   Status = MmCopyToCaller(psbi, &sbi, sizeof(SCROLLBARINFO));
   if(!NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      Ret = FALSE;
   }

   RETURN( Ret);

CLEANUP:
   TRACE("Leave NtUserGetScrollBarInfo, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;

}
Beispiel #5
0
DWORD
APIENTRY
NtUserSetScrollInfo(
   HWND hWnd,
   int fnBar,
   LPCSCROLLINFO lpsi,
   BOOL bRedraw)
{
   PWND Window = NULL;
   NTSTATUS Status;
   SCROLLINFO ScrollInfo;
   DECLARE_RETURN(DWORD);
   USER_REFERENCE_ENTRY Ref;

   TRACE("Enter NtUserSetScrollInfo\n");
   UserEnterExclusive();

   if(!(Window = UserGetWindowObject(hWnd)) || // FIXME:
        Window == UserGetDesktopWindow() ||    // pWnd->fnid == FNID_DESKTOP
        Window == UserGetMessageWindow() )     // pWnd->fnid == FNID_MESSAGEWND
   {
      RETURN( 0);
   }
   UserRefObjectCo(Window, &Ref);

   Status = MmCopyFromCaller(&ScrollInfo, lpsi, sizeof(SCROLLINFO) - sizeof(ScrollInfo.nTrackPos));
   if(!NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      RETURN( 0);
   }

   RETURN(co_IntSetScrollInfo(Window, fnBar, &ScrollInfo, bRedraw));

CLEANUP:
   if (Window)
      UserDerefObjectCo(Window);

   TRACE("Leave NtUserSetScrollInfo, ret=%lu\n", _ret_);
   UserLeave();
   END_CLEANUP;

}
Beispiel #6
0
BOOL
APIENTRY
NtUserGetGUIThreadInfo(
   DWORD idThread, /* If NULL use foreground thread */
   LPGUITHREADINFO lpgui)
{
   NTSTATUS Status;
   PTHRDCARETINFO CaretInfo;
   GUITHREADINFO SafeGui;
   PDESKTOP Desktop;
   PUSER_MESSAGE_QUEUE MsgQueue;
   PTHREADINFO W32Thread;
   PETHREAD Thread = NULL;

   DECLARE_RETURN(BOOLEAN);

   TRACE("Enter NtUserGetGUIThreadInfo\n");
   UserEnterShared();

   Status = MmCopyFromCaller(&SafeGui, lpgui, sizeof(DWORD));
   if(!NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      RETURN( FALSE);
   }

   if(SafeGui.cbSize != sizeof(GUITHREADINFO))
   {
      EngSetLastError(ERROR_INVALID_PARAMETER);
      RETURN( FALSE);
   }

   if (idThread)
   {
      Status = PsLookupThreadByThreadId((HANDLE)(DWORD_PTR)idThread, &Thread);
      if(!NT_SUCCESS(Status))
      {
         EngSetLastError(ERROR_ACCESS_DENIED);
         RETURN( FALSE);
      }
      W32Thread = (PTHREADINFO)Thread->Tcb.Win32Thread;
      Desktop = W32Thread->rpdesk;

      if (!Thread || !Desktop )
      {
        if(Thread)
           ObDereferenceObject(Thread);
        EngSetLastError(ERROR_ACCESS_DENIED);
        RETURN( FALSE);
      }
      
      if ( W32Thread->MessageQueue )
        MsgQueue = W32Thread->MessageQueue;
      else
      {
        if ( Desktop ) MsgQueue = Desktop->ActiveMessageQueue;
      }
   }
   else
   {  /* Get the foreground thread */
      /* FIXME: Handle NULL queue properly? */
      MsgQueue = IntGetFocusMessageQueue();
      if(!MsgQueue)
      {
        EngSetLastError(ERROR_ACCESS_DENIED);
        RETURN( FALSE);
      }
   }

   CaretInfo = &MsgQueue->CaretInfo;

   SafeGui.flags = (CaretInfo->Visible ? GUI_CARETBLINKING : 0);
/*
   if (W32Thread->pMenuState->pGlobalPopupMenu)
   {
       SafeGui.flags |= GUI_INMENUMODE;

       if (W32Thread->pMenuState->pGlobalPopupMenu->spwndNotify)
          SafeGui.hwndMenuOwner = UserHMGetHandle(W32Thread->pMenuState->pGlobalPopupMenu->spwndNotify);

       if (W32Thread->pMenuState->pGlobalPopupMenu->fHasMenuBar)
       {
          if (W32Thread->pMenuState->pGlobalPopupMenu->fIsSysMenu)
          {
             SafeGui.flags |= GUI_SYSTEMMENUMODE;
          }
       }
       else
       {
          SafeGui.flags |= GUI_POPUPMENUMODE;
       }
   }
 */
   SafeGui.hwndMenuOwner = MsgQueue->MenuOwner;

   if (MsgQueue->MenuOwner)
      SafeGui.flags |= GUI_INMENUMODE | MsgQueue->MenuState;

   if (MsgQueue->MoveSize)
      SafeGui.flags |= GUI_INMOVESIZE;

   /* FIXME: Add flag GUI_16BITTASK */

   SafeGui.hwndActive = MsgQueue->spwndActive ? UserHMGetHandle(MsgQueue->spwndActive) : 0;
   SafeGui.hwndFocus = MsgQueue->spwndFocus ? UserHMGetHandle(MsgQueue->spwndFocus) : 0;
   SafeGui.hwndCapture = MsgQueue->spwndCapture ? UserHMGetHandle(MsgQueue->spwndCapture) : 0;
   SafeGui.hwndMoveSize = MsgQueue->MoveSize;
   SafeGui.hwndCaret = CaretInfo->hWnd;

   SafeGui.rcCaret.left = CaretInfo->Pos.x;
   SafeGui.rcCaret.top = CaretInfo->Pos.y;
   SafeGui.rcCaret.right = SafeGui.rcCaret.left + CaretInfo->Size.cx;
   SafeGui.rcCaret.bottom = SafeGui.rcCaret.top + CaretInfo->Size.cy;

   if (idThread)
      ObDereferenceObject(Thread);

   Status = MmCopyToCaller(lpgui, &SafeGui, sizeof(GUITHREADINFO));
   if(!NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      RETURN( FALSE);
   }

   RETURN( TRUE);

CLEANUP:
   TRACE("Leave NtUserGetGUIThreadInfo, ret=%u\n",_ret_);
   UserLeave();
   END_CLEANUP;
}
Beispiel #7
0
// this is highly hacked from W32kPolygon...
BOOL
Polygon ( CONST PPOINT UnsafePoints, int Count, int polyFillMode )
{
  BOOL ret;
  RECTL DestRect;
  int CurrentPoint;
  PPOINT Points;
  SURFOBJ* SurfObj = 0;
  DC dc;
  PBRUSHOBJ OutBrushObj = 0;

  dc.CombinedClip = 0;
  dc.w.polyFillMode = polyFillMode;

  DPRINT1("In W32kPolygon()\n");

  if ( NULL == UnsafePoints || Count < 2)
    {
      DPRINT1("ERROR_INVALID_PARAMETER\n");
      return FALSE;
    }

  /* Copy points from userspace to kernelspace */
  Points = (PPOINT)EngAllocMem(0, Count * sizeof(POINT));
  if (NULL == Points)
    {
      DPRINT1("ERROR_NOT_ENOUGH_MEMORY\n");
      return FALSE;
    }
  MmCopyFromCaller(Points, UnsafePoints, Count * sizeof(POINT));
  if ( memcmp ( Points, UnsafePoints, Count * sizeof(POINT) ) )
    {
      free(Points);
      return FALSE;
    }

  DestRect.left   = Points[0].x;
  DestRect.right  = Points[0].x;
  DestRect.top    = Points[0].y;
  DestRect.bottom = Points[0].y;

  for (CurrentPoint = 1; CurrentPoint < Count; ++CurrentPoint)
    {
      DestRect.left     = MIN(DestRect.left, Points[CurrentPoint].x);
      DestRect.right    = MAX(DestRect.right, Points[CurrentPoint].x);
      DestRect.top      = MIN(DestRect.top, Points[CurrentPoint].y);
      DestRect.bottom   = MAX(DestRect.bottom, Points[CurrentPoint].y);
    }

  // Draw the Polygon Edges with the current pen
  for (CurrentPoint = 0; CurrentPoint < Count; ++CurrentPoint)
    {
      POINT To, From; //, Next;

      /* Let CurrentPoint be i
       * if i+1 > Count, Draw a line from Points[i] to Points[0]
       * Draw a line from Points[i] to Points[i+1]
       */
      From = Points[CurrentPoint];
      if ( CurrentPoint + 1 >= Count)
	{
	  To = Points[0];
	}
      else
	{
	  To = Points[CurrentPoint + 1];
	}

      DPRINT1("Polygon Making line from (%ld,%ld) to (%ld,%ld)\n", From.x, From.y, To.x, To.y );
      IntEngLineTo(SurfObj,
	           dc.CombinedClip,
	           OutBrushObj,
	           From.x,
	           From.y,
	           To.x,
	           To.y,
	           &DestRect,
	           EDGE_CHAR); /* MIX */
    }
  /* determine the fill mode to fill the polygon. */
  ret = FillPolygon(&dc, SurfObj, OutBrushObj, FILL_CHAR, Points, Count, DestRect );
  free(Points);

  return ret;
}
Beispiel #8
0
/* NtUserMonitorFromRect
 *
 * Returns a handle to the monitor having the largest intersection with a
 * given rectangle
 *
 * Arguments
 *
 *   pRect
 *     Pointer to a RECT for which to find monitor
 *
 *   dwFlags
 *     Specifies the behaviour if no monitor intersects the given rect
 *
 * Return value
 *   If a monitor intersects the rect a handle to it is returned; if not the
 *   return value depends on dwFlags
 */
HMONITOR
APIENTRY
NtUserMonitorFromRect(
    IN LPCRECTL pRect,
    IN DWORD dwFlags)
{
    ULONG numMonitors, iLargestArea = 0, i;
    PRECTL rectList;
    HMONITOR *hMonitorList;
    HMONITOR hMonitor = NULL;
    RECTL rect;
    NTSTATUS status;

    /* get rect */
    status = MmCopyFromCaller(&rect, pRect, sizeof (RECT));
    if (!NT_SUCCESS(status))
    {
        SetLastNtError(status);
        return (HMONITOR)NULL;
    }

    /* find intersecting monitors */
    numMonitors = IntGetMonitorsFromRect(&rect, &hMonitor, NULL, 1, dwFlags);
    if (numMonitors <= 1)
    {
        return hMonitor;
    }

    hMonitorList = ExAllocatePoolWithTag(PagedPool,
                                         sizeof(HMONITOR) * numMonitors,
                                         USERTAG_MONITORRECTS);
    if (hMonitorList == NULL)
    {
        /* FIXME: EngSetLastError? */
        return (HMONITOR)NULL;
    }

    rectList = ExAllocatePoolWithTag(PagedPool,
                                     sizeof(RECT) * numMonitors,
                                     USERTAG_MONITORRECTS);
    if (rectList == NULL)
    {
        ExFreePoolWithTag(hMonitorList, USERTAG_MONITORRECTS);
        /* FIXME: EngSetLastError? */
        return (HMONITOR)NULL;
    }

    /* get intersecting monitors */
    numMonitors = IntGetMonitorsFromRect(&rect, hMonitorList, rectList,
                                         numMonitors, 0);
    if (numMonitors == 0)
    {
        ExFreePoolWithTag(hMonitorList, USERTAG_MONITORRECTS);
        ExFreePoolWithTag(rectList, USERTAG_MONITORRECTS);
        return (HMONITOR)NULL;
    }

    /* find largest intersection */
    for (i = 0; i < numMonitors; i++)
    {
        ULONG area = (rectList[i].right - rectList[i].left) *
                     (rectList[i].bottom - rectList[i].top);
        if (area >= iLargestArea)
        {
            hMonitor = hMonitorList[i];
        }
    }

    ExFreePoolWithTag(hMonitorList, USERTAG_MONITORRECTS);
    ExFreePoolWithTag(rectList, USERTAG_MONITORRECTS);

    return hMonitor;
}
Beispiel #9
0
/* NtUserGetMonitorInfo
 *
 * Retrieves information about a given monitor
 *
 * Arguments
 *
 *   hMonitor
 *      Handle to a monitor for which to get information
 *
 *   pMonitorInfo
 *      Pointer to a MONITORINFO struct which is filled with the information.
 *      The cbSize member must be set to sizeof(MONITORINFO) or
 *      sizeof(MONITORINFOEX). Even if set to sizeof(MONITORINFOEX) only parts
 *      from MONITORINFO will be filled.
 *
 *   pDevice
 *      Pointer to a UNICODE_STRING which will recieve the device's name. The
 *      length should be CCHDEVICENAME
 *      Can be NULL
 *
 * Return value
 *   TRUE on success; FALSE on failure (calls SetLastNtError())
 *
 */
BOOL
APIENTRY
NtUserGetMonitorInfo(
    IN HMONITOR hMonitor,
    OUT LPMONITORINFO pMonitorInfo)
{
    PMONITOR Monitor;
    MONITORINFOEXW MonitorInfo;
    NTSTATUS Status;
    DECLARE_RETURN(BOOL);

    TRACE("Enter NtUserGetMonitorInfo\n");
    UserEnterShared();

    /* get monitor object */
    if (!(Monitor = UserGetMonitorObject(hMonitor)))
    {
        TRACE("Couldnt find monitor 0x%lx\n", hMonitor);
        RETURN(FALSE);
    }

    if(pMonitorInfo == NULL)
    {
        SetLastNtError(STATUS_INVALID_PARAMETER);
        RETURN(FALSE);
    }

    /* get size of pMonitorInfo */
    Status = MmCopyFromCaller(&MonitorInfo.cbSize, &pMonitorInfo->cbSize, sizeof (MonitorInfo.cbSize));
    if (!NT_SUCCESS(Status))
    {
        SetLastNtError(Status);
        RETURN(FALSE);
    }
    if ((MonitorInfo.cbSize != sizeof (MONITORINFO)) &&
            (MonitorInfo.cbSize != sizeof (MONITORINFOEXW)))
    {
        SetLastNtError(STATUS_INVALID_PARAMETER);
        RETURN(FALSE);
    }

    /* fill monitor info */
    MonitorInfo.rcMonitor = Monitor->rcMonitor;
    MonitorInfo.rcWork = Monitor->rcWork;
    MonitorInfo.dwFlags = 0;

    if (Monitor->IsPrimary)
        MonitorInfo.dwFlags |= MONITORINFOF_PRIMARY;

    /* fill device name */
    if (MonitorInfo.cbSize == sizeof (MONITORINFOEXW))
    {
        RtlStringCbCopyNW(MonitorInfo.szDevice,
                          sizeof(MonitorInfo.szDevice),
                          Monitor->DeviceName.Buffer,
                          Monitor->DeviceName.Length);
    }

    /* output data */
    Status = MmCopyToCaller(pMonitorInfo, &MonitorInfo, MonitorInfo.cbSize);
    if (!NT_SUCCESS(Status))
    {
        TRACE("GetMonitorInfo: MmCopyToCaller failed\n");
        SetLastNtError(Status);
        RETURN(FALSE);
    }

    TRACE("GetMonitorInfo: success\n");

    RETURN(TRUE);

CLEANUP:
    TRACE("Leave NtUserGetMonitorInfo, ret=%i\n",_ret_);
    UserLeave();
    END_CLEANUP;
}
Beispiel #10
0
/* NtUserEnumDisplayMonitors
 *
 * Enumerates display monitors which intersect the given HDC/cliprect
 *
 * Arguments
 *
 *   hDC
 *      Handle to a DC for which to enum intersecting monitors. If this is NULL
 *      it returns all monitors which are part of the current virtual screen.
 *
 *   pRect
 *      Clipping rectangle with coordinate system origin at the DCs origin if the
 *      given HDC is not NULL or in virtual screen coordinated if it is NULL.
 *      Can be NULL
 *
 *   hMonitorList
 *      Pointer to an array of HMONITOR which is filled with monitor handles.
 *      Can be NULL
 *
 *   monitorRectList
 *      Pointer to an array of RECT which is filled with intersection rectangles.
 *      Can be NULL
 *
 *   listSize
 *      Size of the hMonitorList and monitorRectList arguments. If this is zero
 *      hMonitorList and monitorRectList are ignored.
 *
 * Returns
 *   The number of monitors which intersect the specified region or -1 on failure.
 */
INT
APIENTRY
NtUserEnumDisplayMonitors(
    OPTIONAL IN HDC hDC,
    OPTIONAL IN LPCRECTL pRect,
    OPTIONAL OUT HMONITOR *hMonitorList,
    OPTIONAL OUT PRECTL monitorRectList,
    OPTIONAL IN DWORD listSize)
{
    INT numMonitors, i;
    HMONITOR *safeHMonitorList = NULL;
    PRECTL safeRectList = NULL;
    RECTL rect, *myRect;
    RECTL dcRect;
    NTSTATUS status;

    /* get rect */
    if (pRect != NULL)
    {
        status = MmCopyFromCaller(&rect, pRect, sizeof (RECT));
        if (!NT_SUCCESS(status))
        {
            TRACE("MmCopyFromCaller() failed!\n");
            SetLastNtError(status);
            return -1;
        }
    }

    if (hDC != NULL)
    {
        PDC dc;
        INT regionType;

        /* get visible region bounding rect */
        dc = DC_LockDc(hDC);
        if (dc == NULL)
        {
            TRACE("DC_LockDc() failed!\n");
            /* FIXME: setlasterror? */
            return -1;
        }
        regionType = REGION_GetRgnBox(dc->prgnVis, &dcRect);
        DC_UnlockDc(dc);

        if (regionType == 0)
        {
            TRACE("NtGdiGetRgnBox() failed!\n");
            return -1;
        }
        if (regionType == NULLREGION)
            return 0;
        if (regionType == COMPLEXREGION)
        {
            /* TODO: warning */
        }

        /* if hDC and pRect are given the area of interest is pRect with
           coordinate origin at the DC position */
        if (pRect != NULL)
        {
            rect.left += dcRect.left;
            rect.right += dcRect.left;
            rect.top += dcRect.top;
            rect.bottom += dcRect.top;
        }
        /* if hDC is given and pRect is not the area of interest is the
           bounding rect of hDC */
        else
        {
            rect = dcRect;
        }
    }

    if (hDC == NULL && pRect == NULL)
        myRect = NULL;
    else
        myRect = &rect;

    /* find intersecting monitors */
    numMonitors = IntGetMonitorsFromRect(myRect, NULL, NULL, 0, 0);
    if (numMonitors == 0 || listSize == 0 ||
            (hMonitorList == NULL && monitorRectList == NULL))
    {
        TRACE("numMonitors = %d\n", numMonitors);
        return numMonitors;
    }

    if (hMonitorList != NULL && listSize != 0)
    {
        safeHMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof (HMONITOR) * listSize, USERTAG_MONITORRECTS);
        if (safeHMonitorList == NULL)
        {
            /* FIXME: EngSetLastError? */
            return -1;
        }
    }
    if (monitorRectList != NULL && listSize != 0)
    {
        safeRectList = ExAllocatePoolWithTag(PagedPool, sizeof (RECT) * listSize, USERTAG_MONITORRECTS);
        if (safeRectList == NULL)
        {
            ExFreePoolWithTag(safeHMonitorList, USERTAG_MONITORRECTS);
            /* FIXME: EngSetLastError? */
            return -1;
        }
    }

    /* get intersecting monitors */
    numMonitors = IntGetMonitorsFromRect(myRect, safeHMonitorList, safeRectList,
                                         listSize, 0 );

    if (hDC != NULL && pRect != NULL && safeRectList != NULL)
        for (i = 0; i < numMonitors; i++)
        {
            safeRectList[i].left -= dcRect.left;
            safeRectList[i].right -= dcRect.left;
            safeRectList[i].top -= dcRect.top;
            safeRectList[i].bottom -= dcRect.top;
        }

    /* output result */
    if (hMonitorList != NULL && listSize != 0)
    {
        status = MmCopyToCaller(hMonitorList, safeHMonitorList, sizeof (HMONITOR) * listSize);
        ExFreePool(safeHMonitorList);
        if (!NT_SUCCESS(status))
        {
            ExFreePoolWithTag(safeRectList, USERTAG_MONITORRECTS);
            SetLastNtError(status);
            return -1;
        }
    }
    if (monitorRectList != NULL && listSize != 0)
    {
        status = MmCopyToCaller(monitorRectList, safeRectList, sizeof (RECT) * listSize);
        ExFreePoolWithTag(safeRectList, USERTAG_MONITORRECTS);
        if (!NT_SUCCESS(status))
        {
            SetLastNtError(status);
            return -1;
        }
    }

    return numMonitors;
}
Beispiel #11
0
/* NtUserMonitorFromRect
 *
 * Returns a handle to the monitor having the largest intersection with a
 * given rectangle
 *
 * Arguments
 *
 *   pRectUnsafe
 *     Pointer to a RECT for which to find monitor
 *
 *   dwFlags
 *     Specifies the behaviour if no monitor intersects the given rect
 *
 * Return value
 *   If a monitor intersects the rect a handle to it is returned; if not the
 *   return value depends on dwFlags
 */
HMONITOR
APIENTRY
NtUserMonitorFromRect(
    IN LPCRECTL pRectUnsafe,
    IN DWORD dwFlags)
{
    ULONG cMonitors, LargestArea = 0, i;
    PRECTL prcMonitorList = NULL;
    HMONITOR *phMonitorList = NULL;
    HMONITOR hMonitor = NULL;
    RECTL Rect;
    NTSTATUS Status;

    /* Check if flags are valid */
    if (dwFlags != MONITOR_DEFAULTTONULL &&
        dwFlags != MONITOR_DEFAULTTOPRIMARY &&
        dwFlags != MONITOR_DEFAULTTONEAREST)
    {
        EngSetLastError(ERROR_INVALID_FLAGS);
        return NULL;
    }

    /* Copy rectangle to safe buffer */
    Status = MmCopyFromCaller(&Rect, pRectUnsafe, sizeof (RECT));
    if (!NT_SUCCESS(Status))
    {
        SetLastNtError(Status);
        return NULL;
    }

    UserEnterShared();

    /* Find intersecting monitors */
    cMonitors = IntGetMonitorsFromRect(&Rect, &hMonitor, NULL, 1, dwFlags);
    if (cMonitors <= 1)
    {
        /* No or one monitor found. Just return handle. */
        goto cleanup;
    }

    /* There is more than one monitor. Find monitor with largest intersection.
       Temporary reset hMonitor */
    hMonitor = NULL;

    /* Allocate helper buffers */
    phMonitorList = ExAllocatePoolWithTag(PagedPool,
                                          sizeof(HMONITOR) * cMonitors,
                                          USERTAG_MONITORRECTS);
    if (phMonitorList == NULL)
    {
        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
        goto cleanup;
    }

    prcMonitorList = ExAllocatePoolWithTag(PagedPool,
                                           sizeof(RECT) * cMonitors,
                                           USERTAG_MONITORRECTS);
    if (prcMonitorList == NULL)
    {
        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
        goto cleanup;
    }

    /* Get intersecting monitors again but now with rectangle list */
    cMonitors = IntGetMonitorsFromRect(&Rect, phMonitorList, prcMonitorList,
                                       cMonitors, 0);

    /* Find largest intersection */
    for (i = 0; i < cMonitors; i++)
    {
        ULONG Area = (prcMonitorList[i].right - prcMonitorList[i].left) *
                     (prcMonitorList[i].bottom - prcMonitorList[i].top);
        if (Area >= LargestArea)
        {
            hMonitor = phMonitorList[i];
            LargestArea = Area;
        }
    }

cleanup:
    if (phMonitorList)
        ExFreePoolWithTag(phMonitorList, USERTAG_MONITORRECTS);
    if (prcMonitorList)
        ExFreePoolWithTag(prcMonitorList, USERTAG_MONITORRECTS);
    UserLeave();

    return hMonitor;
}
Beispiel #12
0
/* NtUserGetMonitorInfo
 *
 * Retrieves information about a given monitor
 *
 * Arguments
 *
 *   hMonitor
 *      Handle to a monitor for which to get information
 *
 *   pMonitorInfoUnsafe
 *      Pointer to a MONITORINFO struct which is filled with the information.
 *      The cbSize member must be set to sizeof(MONITORINFO) or
 *      sizeof(MONITORINFOEX). Even if set to sizeof(MONITORINFOEX) only parts
 *      from MONITORINFO will be filled.
 *
 *   pDevice
 *      Pointer to a UNICODE_STRING which will receive the device's name. The
 *      length should be CCHDEVICENAME
 *      Can be NULL
 *
 * Return value
 *   TRUE on success; FALSE on failure (calls SetLastNtError())
 *
 */
BOOL
APIENTRY
NtUserGetMonitorInfo(
    IN HMONITOR hMonitor,
    OUT LPMONITORINFO pMonitorInfoUnsafe)
{
    PMONITOR pMonitor;
    MONITORINFOEXW MonitorInfo;
    NTSTATUS Status;
    BOOL bRet = FALSE;
    PWCHAR pwstrDeviceName;

    TRACE("Enter NtUserGetMonitorInfo\n");
    UserEnterShared();

    /* Get monitor object */
    pMonitor = UserGetMonitorObject(hMonitor);
    if (!pMonitor)
    {
        TRACE("Couldnt find monitor %p\n", hMonitor);
        goto cleanup;
    }

    /* Check if pMonitorInfoUnsafe is valid */
    if(pMonitorInfoUnsafe == NULL)
    {
        SetLastNtError(STATUS_INVALID_PARAMETER);
        goto cleanup;
    }

    pwstrDeviceName = ((PPDEVOBJ)(pMonitor->hDev))->pGraphicsDevice->szWinDeviceName;

    /* Get size of pMonitorInfoUnsafe */
    Status = MmCopyFromCaller(&MonitorInfo.cbSize, &pMonitorInfoUnsafe->cbSize, sizeof(MonitorInfo.cbSize));
    if (!NT_SUCCESS(Status))
    {
        SetLastNtError(Status);
        goto cleanup;
    }

    /* Check if size of struct is valid */
    if (MonitorInfo.cbSize != sizeof(MONITORINFO) &&
        MonitorInfo.cbSize != sizeof(MONITORINFOEXW))
    {
        SetLastNtError(STATUS_INVALID_PARAMETER);
        goto cleanup;
    }

    /* Fill monitor info */
    MonitorInfo.rcMonitor = pMonitor->rcMonitor;
    MonitorInfo.rcWork = pMonitor->rcWork;
    MonitorInfo.dwFlags = 0;
    if (pMonitor->IsPrimary)
        MonitorInfo.dwFlags |= MONITORINFOF_PRIMARY;

    /* Fill device name */
    if (MonitorInfo.cbSize == sizeof(MONITORINFOEXW))
    {
        RtlStringCbCopyNExW(MonitorInfo.szDevice,
                          sizeof(MonitorInfo.szDevice),
                          pwstrDeviceName,
                          (wcslen(pwstrDeviceName)+1) * sizeof(WCHAR),
                          NULL, NULL, STRSAFE_FILL_BEHIND_NULL);
    }

    /* Output data */
    Status = MmCopyToCaller(pMonitorInfoUnsafe, &MonitorInfo, MonitorInfo.cbSize);
    if (!NT_SUCCESS(Status))
    {
        TRACE("GetMonitorInfo: MmCopyToCaller failed\n");
        SetLastNtError(Status);
        goto cleanup;
    }

    TRACE("GetMonitorInfo: success\n");
    bRet = TRUE;

cleanup:
    TRACE("Leave NtUserGetMonitorInfo, ret=%i\n", bRet);
    UserLeave();
    return bRet;
}
Beispiel #13
0
/* NtUserEnumDisplayMonitors
 *
 * Enumerates display monitors which intersect the given HDC/cliprect
 *
 * Arguments
 *
 *   hdc
 *      Handle to a DC for which to enum intersecting monitors. If this is NULL
 *      it returns all monitors which are part of the current virtual screen.
 *
 *   pUnsafeRect
 *      Clipping rectangle with coordinate system origin at the DCs origin if the
 *      given HDC is not NULL or in virtual screen coordinated if it is NULL.
 *      Can be NULL
 *
 *   phUnsafeMonitorList
 *      Pointer to an array of HMONITOR which is filled with monitor handles.
 *      Can be NULL
 *
 *   prcUnsafeMonitorList
 *      Pointer to an array of RECT which is filled with intersection rectangles.
 *      Can be NULL
 *
 *   dwListSize
 *      Size of the hMonitorList and monitorRectList arguments. If this is zero
 *      hMonitorList and monitorRectList are ignored.
 *
 * Returns
 *   The number of monitors which intersect the specified region or -1 on failure.
 */
INT
APIENTRY
NtUserEnumDisplayMonitors(
    OPTIONAL IN HDC hdc,
    OPTIONAL IN LPCRECTL pUnsafeRect,
    OPTIONAL OUT HMONITOR *phUnsafeMonitorList,
    OPTIONAL OUT PRECTL prcUnsafeMonitorList,
    OPTIONAL IN DWORD dwListSize)
{
    INT cMonitors, iRet = -1, i;
    HMONITOR *phMonitorList = NULL;
    PRECTL prcMonitorList = NULL;
    RECTL rc, *pRect;
    RECTL DcRect = {0};
    NTSTATUS Status;

    /* Get rectangle */
    if (pUnsafeRect != NULL)
    {
        Status = MmCopyFromCaller(&rc, pUnsafeRect, sizeof(RECT));
        if (!NT_SUCCESS(Status))
        {
            TRACE("MmCopyFromCaller() failed!\n");
            SetLastNtError(Status);
            return -1;
        }
    }

    if (hdc != NULL)
    {
        PDC pDc;
        INT iRgnType;

        /* Get visible region bounding rect */
        pDc = DC_LockDc(hdc);
        if (pDc == NULL)
        {
            TRACE("DC_LockDc() failed!\n");
            /* FIXME: setlasterror? */
            return -1;
        }
        iRgnType = REGION_GetRgnBox(pDc->prgnVis, &DcRect);
        DC_UnlockDc(pDc);

        if (iRgnType == 0)
        {
            TRACE("NtGdiGetRgnBox() failed!\n");
            return -1;
        }
        if (iRgnType == NULLREGION)
            return 0;
        if (iRgnType == COMPLEXREGION)
        {
            /* TODO: Warning */
        }

        /* If hdc and pRect are given the area of interest is pRect with
           coordinate origin at the DC position */
        if (pUnsafeRect != NULL)
        {
            rc.left += DcRect.left;
            rc.right += DcRect.left;
            rc.top += DcRect.top;
            rc.bottom += DcRect.top;
        }
        /* If hdc is given and pRect is not the area of interest is the
           bounding rect of hdc */
        else
        {
            rc = DcRect;
        }
    }

    if (hdc == NULL && pUnsafeRect == NULL)
        pRect = NULL;
    else
        pRect = &rc;

    UserEnterShared();

    /* Find intersecting monitors */
    cMonitors = IntGetMonitorsFromRect(pRect, NULL, NULL, 0, MONITOR_DEFAULTTONULL);
    if (cMonitors == 0 || dwListSize == 0 ||
        (phUnsafeMonitorList == NULL && prcUnsafeMonitorList == NULL))
    {
        /* Simple case - just return monitors count */
        TRACE("cMonitors = %d\n", cMonitors);
        iRet = cMonitors;
        goto cleanup;
    }

    /* Allocate safe buffers */
    if (phUnsafeMonitorList != NULL && dwListSize != 0)
    {
        phMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof (HMONITOR) * dwListSize, USERTAG_MONITORRECTS);
        if (phMonitorList == NULL)
        {
            EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
            goto cleanup;
        }
    }
    if (prcUnsafeMonitorList != NULL && dwListSize != 0)
    {
        prcMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof (RECT) * dwListSize, USERTAG_MONITORRECTS);
        if (prcMonitorList == NULL)
        {
            EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
            goto cleanup;
        }
    }

    /* Get intersecting monitors */
    cMonitors = IntGetMonitorsFromRect(pRect, phMonitorList, prcMonitorList,
                                       dwListSize, MONITOR_DEFAULTTONULL);

    if (hdc != NULL && pRect != NULL && prcMonitorList != NULL)
        for (i = 0; i < cMonitors; i++)
        {
            prcMonitorList[i].left -= DcRect.left;
            prcMonitorList[i].right -= DcRect.left;
            prcMonitorList[i].top -= DcRect.top;
            prcMonitorList[i].bottom -= DcRect.top;
        }

    /* Output result */
    if (phUnsafeMonitorList != NULL && dwListSize != 0)
    {
        Status = MmCopyToCaller(phUnsafeMonitorList, phMonitorList, sizeof(HMONITOR) * dwListSize);
        if (!NT_SUCCESS(Status))
        {
            SetLastNtError(Status);
            goto cleanup;
        }
    }
    if (prcUnsafeMonitorList != NULL && dwListSize != 0)
    {
        Status = MmCopyToCaller(prcUnsafeMonitorList, prcMonitorList, sizeof(RECT) * dwListSize);
        if (!NT_SUCCESS(Status))
        {
            SetLastNtError(Status);
            goto cleanup;
        }
    }

    /* Return monitors count on success */
    iRet = cMonitors;

cleanup:
    if (phMonitorList)
        ExFreePoolWithTag(phMonitorList, USERTAG_MONITORRECTS);
    if (prcMonitorList)
        ExFreePoolWithTag(prcMonitorList, USERTAG_MONITORRECTS);

    UserLeave();
    return iRet;
}
Beispiel #14
0
/*
 * NtUserSendInput
 *
 * Generates input events from software
 */
UINT
APIENTRY
NtUserSendInput(
    UINT nInputs,
    LPINPUT pInput,
    INT cbSize)
{
    PTHREADINFO pti;
    UINT uRet = 0;

    TRACE("Enter NtUserSendInput\n");
    UserEnterExclusive();

    pti = PsGetCurrentThreadWin32Thread();
    ASSERT(pti);

    if (!pti->rpdesk)
    {
        goto cleanup;
    }

    if (!nInputs || !pInput || cbSize != sizeof(INPUT))
    {
        EngSetLastError(ERROR_INVALID_PARAMETER);
        goto cleanup;
    }

    /*
     * FIXME: Check access rights of the window station
     *        e.g. services running in the service window station cannot block input
     */
    if (!ThreadHasInputAccess(pti) ||
        !IntIsActiveDesktop(pti->rpdesk))
    {
        EngSetLastError(ERROR_ACCESS_DENIED);
        goto cleanup;
    }

    while (nInputs--)
    {
        INPUT SafeInput;
        NTSTATUS Status;

        Status = MmCopyFromCaller(&SafeInput, pInput++, sizeof(INPUT));
        if (!NT_SUCCESS(Status))
        {
            SetLastNtError(Status);
            goto cleanup;
        }

        switch (SafeInput.type)
        {
            case INPUT_MOUSE:
                if (UserSendMouseInput(&SafeInput.mi, TRUE))
                    uRet++;
                break;
            case INPUT_KEYBOARD:
                if (UserSendKeyboardInput(&SafeInput.ki, TRUE))
                    uRet++;
                break;
            case INPUT_HARDWARE:
                FIXME("INPUT_HARDWARE not supported!");
                break;
            default:
                ERR("SendInput(): Invalid input type: 0x%x\n", SafeInput.type);
                break;
        }
    }

cleanup:
    TRACE("Leave NtUserSendInput, ret=%u\n", uRet);
    UserLeave();
    return uRet;
}
Beispiel #15
0
BOOL
APIENTRY
NtUserSetScrollBarInfo(
   HWND hWnd,
   LONG idObject,
   SETSCROLLBARINFO *info)
{
   PWND Window = NULL;
   SETSCROLLBARINFO Safeinfo;
   PSCROLLBARINFO sbi;
   LPSCROLLINFO psi;
   NTSTATUS Status;
   LONG Obj;
   DECLARE_RETURN(BOOL);
   USER_REFERENCE_ENTRY Ref;

   TRACE("Enter NtUserSetScrollBarInfo\n");
   UserEnterExclusive();

   if(!(Window = UserGetWindowObject(hWnd)))
   {
      RETURN( FALSE);
   }
   UserRefObjectCo(Window, &Ref);

   Obj = SBOBJ_TO_SBID(idObject);
   if(!SBID_IS_VALID(Obj))
   {
      EngSetLastError(ERROR_INVALID_PARAMETER);
      ERR("Trying to set scrollinfo for unknown scrollbar type %d\n", Obj);
      RETURN( FALSE);
   }

   if(!co_IntCreateScrollBars(Window))
   {
      RETURN(FALSE);
   }

   Status = MmCopyFromCaller(&Safeinfo, info, sizeof(SETSCROLLBARINFO));
   if(!NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      RETURN(FALSE);
   }

   sbi = IntGetScrollbarInfoFromWindow(Window, Obj);
   psi = IntGetScrollInfoFromWindow(Window, Obj);

   psi->nTrackPos = Safeinfo.nTrackPos;
   sbi->reserved = Safeinfo.reserved;
   RtlCopyMemory(&sbi->rgstate, &Safeinfo.rgstate, sizeof(Safeinfo.rgstate));

   RETURN(TRUE);

CLEANUP:
   if (Window)
      UserDerefObjectCo(Window);

   TRACE("Leave NtUserSetScrollBarInfo, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}