Exemple #1
0
/* NtUserMonitorFromPoint
 *
 * Returns a handle to the monitor containing the given point.
 *
 * Arguments
 *
 *   pt
 *     Point for which to find monitor
 *
 *   dwFlags
 *     Specifies the behaviour if the point isn't on any of the monitors.
 *
 * Return value
 *   If the point is found a handle to the monitor is returned; if not the
 *   return value depends on dwFlags
 */
HMONITOR
APIENTRY
NtUserMonitorFromPoint(
    IN POINT pt,
    IN DWORD dwFlags)
{
    RECTL rc;
    HMONITOR hMonitor = NULL;

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

    /* Fill rect (bottom-right exclusive) */
    rc.left = pt.x;
    rc.right = pt.x + 1;
    rc.top = pt.y;
    rc.bottom = pt.y + 1;

    UserEnterShared();

    /* Find intersecting monitor */
    IntGetMonitorsFromRect(&rc, &hMonitor, NULL, 1, dwFlags);

    UserLeave();
    return hMonitor;
}
Exemple #2
0
/* NtUserMonitorFromPoint
 *
 * Returns a handle to the monitor containing the given point.
 *
 * Arguments
 *
 *   point
 *     Point for which to find monitor
 *
 *   dwFlags
 *     Specifies the behaviour if the point isn't on any of the monitors.
 *
 * Return value
 *   If the point is found a handle to the monitor is returned; if not the
 *   return value depends on dwFlags
 */
HMONITOR
APIENTRY
NtUserMonitorFromPoint(
    IN POINT point,
    IN DWORD dwFlags)
{
    INT NumMonitors;
    RECTL InRect;
    HMONITOR hMonitor = NULL;

    /* fill inRect (bottom-right exclusive) */
    InRect.left = point.x;
    InRect.right = point.x + 1;
    InRect.top = point.y;
    InRect.bottom = point.y + 1;

    /* find intersecting monitor */
    NumMonitors = IntGetMonitorsFromRect(&InRect, &hMonitor, NULL, 1, dwFlags);
    if (NumMonitors < 0)
    {
        return (HMONITOR)NULL;
    }

    return hMonitor;
}
Exemple #3
0
HMONITOR
APIENTRY
NtUserMonitorFromWindow(
    IN HWND hWnd,
    IN DWORD dwFlags)
{
    PWND Window;
    HMONITOR hMonitor = NULL;
    RECTL Rect;
    DECLARE_RETURN(HMONITOR);

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

    if (!(Window = UserGetWindowObject(hWnd)))
    {
        if (dwFlags == MONITOR_DEFAULTTONULL)
        {
            RETURN(hMonitor);
        }
        IntGetMonitorsFromRect(NULL, &hMonitor, NULL, 1, dwFlags);
        RETURN(hMonitor);
    }

    Rect.left = Rect.right = Window->rcWindow.left;
    Rect.top = Rect.bottom = Window->rcWindow.bottom;

    IntGetMonitorsFromRect(&Rect, &hMonitor, NULL, 1, dwFlags);

    RETURN(hMonitor);

CLEANUP:
    TRACE("Leave NtUserMonitorFromWindow, ret=%i\n",_ret_);
    UserLeave();
    END_CLEANUP;
}
Exemple #4
0
HMONITOR
APIENTRY
NtUserMonitorFromWindow(
    IN HWND hWnd,
    IN DWORD dwFlags)
{
    PWND pWnd;
    HMONITOR hMonitor = NULL;
    RECTL Rect = {0, 0, 0, 0};

    TRACE("Enter NtUserMonitorFromWindow\n");

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

    UserEnterShared();

    /* If window is given, use it first */
    if (hWnd)
    {
        /* Get window object */
        pWnd = UserGetWindowObject(hWnd);
        if (!pWnd)
            goto cleanup;

        /* Find only monitors which have intersection with given window */
        Rect.left = Rect.right = pWnd->rcWindow.left;
        Rect.top = Rect.bottom = pWnd->rcWindow.bottom;
    }

    /* Find monitors now */
    IntGetMonitorsFromRect(&Rect, &hMonitor, NULL, 1, dwFlags);

cleanup:
    TRACE("Leave NtUserMonitorFromWindow, ret=%p\n", hMonitor);
    UserLeave();
    return hMonitor;
}
Exemple #5
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;
}
Exemple #6
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;
}
Exemple #7
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;
}
Exemple #8
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;
}
Exemple #9
0
PMONITOR NTAPI
UserMonitorFromRect(
    PRECTL pRect,
    DWORD dwFlags)
{
    ULONG cMonitors, LargestArea = 0, i;
    PRECTL prcMonitorList = NULL;
    HMONITOR *phMonitorList = NULL;
    HMONITOR hMonitor = NULL;

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

    /* Find intersecting monitors */
    cMonitors = IntGetMonitorsFromRect(pRect, &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(pRect, 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);

    return UserGetMonitorObject(hMonitor);
}