Exemplo n.º 1
0
/* IntDetachMonitor
 *
 * Deletes a MONITOR and removes it from the list of monitors.
 *
 * Arguments
 *
 *   pGdiDevice  Pointer to the PDEVOBJ from which the monitor was detached
 *
 * Return value
 *   Returns a NTSTATUS
 */
NTSTATUS
IntDetachMonitor(IN PDEVOBJ *pGdiDevice)
{
    PMONITOR Monitor;

    for (Monitor = gMonitorList; Monitor != NULL; Monitor = Monitor->Next)
    {
        if (Monitor->GdiDevice == pGdiDevice)
            break;
    }

    if (Monitor == NULL)
    {
        /* no monitor for given device found */
        return STATUS_INVALID_PARAMETER;
    }

    if (Monitor->IsPrimary && (Monitor->Next != NULL || Monitor->Prev != NULL))
    {
        PMONITOR NewPrimaryMonitor = (Monitor->Prev != NULL) ? (Monitor->Prev) : (Monitor->Next);

        ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&NewPrimaryMonitor->Lock);
        NewPrimaryMonitor->IsPrimary = TRUE;
        ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&NewPrimaryMonitor->Lock);
    }

    if (gMonitorList == Monitor)
    {
        gMonitorList = Monitor->Next;
        if (Monitor->Next != NULL)
            Monitor->Next->Prev = NULL;
    }
    else
    {
        Monitor->Prev->Next = Monitor->Next;
        if (Monitor->Next != NULL)
            Monitor->Next->Prev = Monitor->Prev;
    }

    if (Monitor->hrgnMonitor)
        GreDeleteObject(Monitor->hrgnMonitor);

    IntDestroyMonitorObject(Monitor);

    return STATUS_SUCCESS;
}
Exemplo n.º 2
0
/* IntGetMonitorsFromRect
 *
 * Returns a list of monitor handles/rectangles. The rectangles in the list are
 * the areas of intersection with the monitors.
 *
 * Arguments
 *
 *   pRect
 *      Rectangle in desktop coordinates. If this is NULL all monitors are
 *      returned and the rect list is filled with the sizes of the monitors.
 *
 *   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 rects in
 *      desktop coordinates.
 *      Can be NULL, will be ignored if no intersecting monitor is found and
 *      flags is MONITOR_DEFAULTTONEAREST
 *
 *   listSize
 *      Size of the hMonitorList and monitorRectList arguments. If this is zero
 *      hMonitorList and monitorRectList are ignored.
 *
 *   flags
 *      Either 0 or MONITOR_DEFAULTTONEAREST (ignored if rect is NULL)
 *
 * Returns
 *   The number of monitors which intersect the specified region.
 */
static
UINT
IntGetMonitorsFromRect(OPTIONAL IN LPCRECTL pRect,
                       OPTIONAL OUT HMONITOR *hMonitorList,
                       OPTIONAL OUT PRECTL monitorRectList,
                       OPTIONAL IN DWORD listSize,
                       OPTIONAL IN DWORD flags)
{
    PMONITOR Monitor, NearestMonitor = NULL, PrimaryMonitor = NULL;
    UINT iCount = 0;
    ULONG iNearestDistance = 0xffffffff;

    /* Find monitors which intersect the rectangle */
    for (Monitor = gMonitorList; Monitor != NULL; Monitor = Monitor->Next)
    {
        RECTL MonitorRect, IntersectionRect;

        ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&Monitor->Lock);
        MonitorRect = Monitor->rcMonitor;
        ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&Monitor->Lock);

        TRACE("MonitorRect: left = %d, top = %d, right = %d, bottom = %d\n",
               MonitorRect.left, MonitorRect.top, MonitorRect.right, MonitorRect.bottom);

        if (flags == MONITOR_DEFAULTTOPRIMARY && Monitor->IsPrimary)
        {
            PrimaryMonitor = Monitor;
        }

        /* Check if a rect is given */
        if (pRect == NULL)
        {
            /* No rect given, so use the full monitor rect */
            IntersectionRect = MonitorRect;
        }

        /* We have a rect, calculate intersection */
        else if (!RECTL_bIntersectRect(&IntersectionRect, &MonitorRect, pRect))
        {
            /* Rects did not intersect */
            if (flags == MONITOR_DEFAULTTONEAREST)
            {
                ULONG cx, cy, iDistance;

                /* Get x and y distance */
                cx = min(abs(MonitorRect.left - pRect->right),
                         abs(pRect->left - MonitorRect.right));
                cy = min(abs(MonitorRect.top - pRect->bottom),
                         abs(pRect->top - MonitorRect.bottom));

                /* Calculate distance square */
                iDistance = cx * cx + cy * cy;

                /* Check if this is the new nearest monitor */
                if (iDistance < iNearestDistance)
                {
                    iNearestDistance = iDistance;
                    NearestMonitor = Monitor;
                }
            }

            continue;
        }

        /* Check if there's space in the buffer */
        if (iCount < listSize)
        {
            if (hMonitorList != NULL)
                hMonitorList[iCount] = UserHMGetHandle(Monitor);
            if (monitorRectList != NULL)
                monitorRectList[iCount] = IntersectionRect;
        }

        /* Increase count of found monitors */
        iCount++;
    }

    /* Found nothing intersecting? */
    if (iCount == 0)
    {
        /* Check if we shall default to the nearest monitor */
        if (flags == MONITOR_DEFAULTTONEAREST && NearestMonitor)
        {
            if (hMonitorList && listSize > 0)
                hMonitorList[iCount] = UserHMGetHandle(NearestMonitor);
            iCount++;
        }
        /* Check if we shall default to the primary monitor */
        else if (flags == MONITOR_DEFAULTTOPRIMARY && PrimaryMonitor)
        {
            if (hMonitorList != NULL && listSize > 0)
                hMonitorList[iCount] = UserHMGetHandle(PrimaryMonitor);
            iCount++;
        }
    }

    return iCount;
}
Exemplo n.º 3
0
static
VOID
TestFastMutex(
    PFAST_MUTEX Mutex,
    KIRQL OriginalIrql)
{
    PKTHREAD Thread = KeGetCurrentThread();

    ok_irql(OriginalIrql);

    /* acquire/release normally */
    ExAcquireFastMutex(Mutex);
    CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL);
    ok_bool_false(ExTryToAcquireFastMutex(Mutex), "ExTryToAcquireFastMutex returned");
    CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL);
    ExReleaseFastMutex(Mutex);
    CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql);

#ifdef _M_IX86
    /* ntoskrnl's fastcall version */
    ExiAcquireFastMutex(Mutex);
    CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL);
    ok_bool_false(ExiTryToAcquireFastMutex(Mutex), "ExiTryToAcquireFastMutex returned");
    CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL);
    ExiReleaseFastMutex(Mutex);
    CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql);
#endif

    /* try to acquire */
    ok_bool_true(ExTryToAcquireFastMutex(Mutex), "ExTryToAcquireFastMutex returned");
    CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL);
    ExReleaseFastMutex(Mutex);
    CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql);

    /* shortcut functions with critical region */
    ExEnterCriticalRegionAndAcquireFastMutexUnsafe(Mutex);
    ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned");
    ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(Mutex);

    /* acquire/release unsafe */
    if (!KmtIsCheckedBuild || OriginalIrql == APC_LEVEL)
    {
        ExAcquireFastMutexUnsafe(Mutex);
        CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, OriginalIrql);
        ExReleaseFastMutexUnsafe(Mutex);
        CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql);

        /* mismatched acquire/release */
        ExAcquireFastMutex(Mutex);
        CheckMutex(Mutex, 0L, Thread, 0LU, OriginalIrql, APC_LEVEL);
        ExReleaseFastMutexUnsafe(Mutex);
        CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, APC_LEVEL);
        KmtSetIrql(OriginalIrql);
        CheckMutex(Mutex, 1L, NULL, 0LU, OriginalIrql, OriginalIrql);

        Mutex->OldIrql = 0x55555555LU;
        ExAcquireFastMutexUnsafe(Mutex);
        CheckMutex(Mutex, 0L, Thread, 0LU, 0x55555555LU, OriginalIrql);
        Mutex->OldIrql = PASSIVE_LEVEL;
        ExReleaseFastMutex(Mutex);
        CheckMutex(Mutex, 1L, NULL, 0LU, PASSIVE_LEVEL, PASSIVE_LEVEL);
        KmtSetIrql(OriginalIrql);
        CheckMutex(Mutex, 1L, NULL, 0LU, PASSIVE_LEVEL, OriginalIrql);
    }

    if (!KmtIsCheckedBuild)
    {
        /* release without acquire */
        ExReleaseFastMutexUnsafe(Mutex);
        CheckMutex(Mutex, 2L, NULL, 0LU, PASSIVE_LEVEL, OriginalIrql);
        --Mutex->Count;
        Mutex->OldIrql = OriginalIrql;
        ExReleaseFastMutex(Mutex);
        CheckMutex(Mutex, 2L, NULL, 0LU, OriginalIrql, OriginalIrql);
        ExReleaseFastMutex(Mutex);
        CheckMutex(Mutex, 3L, NULL, 0LU, OriginalIrql, OriginalIrql);
        Mutex->Count -= 2;
    }

    /* make sure we survive this in case of error */
    ok_eq_long(Mutex->Count, 1L);
    Mutex->Count = 1;
    ok_irql(OriginalIrql);
    KmtSetIrql(OriginalIrql);
}