Exemple #1
0
BOOL
NTAPI
GreSetBitmapOwner(
    _In_ HBITMAP hbmp,
    _In_ ULONG ulOwner)
{
    /* Check if we have the correct object type */
    if (GDI_HANDLE_GET_TYPE(hbmp) != GDILoObjType_LO_BITMAP_TYPE)
    {
        DPRINT1("Incorrect type for hbmp: %p\n", hbmp);
        return FALSE;
    }

    /// FIXME: this is a hack and doesn't handle a race condition properly.
    /// It needs to be done in GDIOBJ_vSetObjectOwner atomically.

    /* Check if we set public or none */
    if ((ulOwner == GDI_OBJ_HMGR_PUBLIC) ||
        (ulOwner == GDI_OBJ_HMGR_NONE))
    {
        /* Only allow this for owned objects */
        if (GreGetObjectOwner(hbmp) != GDI_OBJ_HMGR_POWNED)
        {
            DPRINT1("Cannot change owner for non-powned hbmp\n");
            return FALSE;
        }
    }

    return GreSetObjectOwner(hbmp, ulOwner);
}
Exemple #2
0
/* IntUpdateMonitorSize
 *
 * Reset size of the monitor using atached device
 *
 * Arguments
 *
 *   PMONITOR
 *      pGdiDevice  Pointer to the PDEVOBJ, which size has changed
 *
 * Return value
 *   Returns a NTSTATUS
 */
NTSTATUS
IntUpdateMonitorSize(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;
    }

    Monitor->rcMonitor.left  = 0;
    Monitor->rcMonitor.top   = 0;
    Monitor->rcMonitor.right  = Monitor->rcMonitor.left + Monitor->GdiDevice->gdiinfo.ulHorzRes;
    Monitor->rcMonitor.bottom = Monitor->rcMonitor.top + Monitor->GdiDevice->gdiinfo.ulVertRes;
    Monitor->rcWork = Monitor->rcMonitor;

    if (Monitor->hrgnMonitor)
    {
        GreSetObjectOwner(Monitor->hrgnMonitor, GDI_OBJ_HMGR_POWNED);
        GreDeleteObject(Monitor->hrgnMonitor);
    }

    Monitor->hrgnMonitor = IntSysCreateRectRgnIndirect( &Monitor->rcMonitor );

    IntGdiSetRegionOwner(Monitor->hrgnMonitor, GDI_OBJ_HMGR_PUBLIC);

    return STATUS_SUCCESS;
}
HANDLE NTAPI
UserSetClipboardData(UINT fmt, HANDLE hData, PSETCLIPBDATA scd)
{
    HANDLE hRet = NULL;
    PWINSTATION_OBJECT pWinStaObj = NULL;

    pWinStaObj = IntGetWinStaForCbAccess();
    if (!pWinStaObj)
        goto cleanup;

    /* If it's delayed rendering we don't have to open clipboard */
    if ((pWinStaObj->fInDelayedRendering &&
        pWinStaObj->spwndClipOwner->head.pti != PsGetCurrentThreadWin32Thread()) ||
        !IntIsClipboardOpenByMe(pWinStaObj))
    {
        ERR("Access denied!\n");
        EngSetLastError(ERROR_CLIPBOARD_NOT_OPEN);
        goto cleanup;
    }

    if (scd->fIncSerialNumber)
        pWinStaObj->iClipSerialNumber++;

    /* Is it a delayed render? */
    if (hData)
    {
        /* Is it a bitmap? */
        if (fmt == CF_BITMAP)
        {
            /* Make bitmap public */
            GreSetObjectOwner(hData, GDI_OBJ_HMGR_PUBLIC);
        }

        /* Save data in the clipboard */
        IntAddFormatedData(pWinStaObj, fmt, hData, scd->fGlobalHandle, FALSE);
        TRACE("hData stored\n");

        pWinStaObj->iClipSequenceNumber++;
        pWinStaObj->fClipboardChanged = TRUE;

        /* Note: Synthesized formats are added in NtUserCloseClipboard */
    }
    else
    {
        /* This is a delayed render */
        IntAddFormatedData(pWinStaObj, fmt, DATA_DELAYED, FALSE, FALSE);
        TRACE("SetClipboardData delayed format: %u\n", fmt);
    }

    /* Return hData on success */
    hRet = hData;

cleanup:
    TRACE("NtUserSetClipboardData returns: %p\n", hRet);

    if(pWinStaObj)
        ObDereferenceObject(pWinStaObj);

    return hRet;
}
static VOID WINAPI
IntSynthesizeBitmap(PWINSTATION_OBJECT pWinStaObj, PCLIP pBmEl)
{
    HDC hdc = NULL;
    PBITMAPINFO pBmi, pConvertedBmi = NULL;
    HBITMAP hBm = NULL;
    PCLIPBOARDDATA pMemObj;
    PCLIP pDibEl;
    ULONG Offset;

    TRACE("IntSynthesizeBitmap(%p, %p)\n", pWinStaObj, pBmEl);

    pDibEl = IntIsFormatAvailable(pWinStaObj, CF_DIB);
    ASSERT(pDibEl && !IS_DATA_SYNTHESIZED(pDibEl));
    if(!pDibEl->fGlobalHandle)
        return;

    pMemObj = (PCLIPBOARDDATA)UserGetObject(gHandleTable, pDibEl->hData, TYPE_CLIPDATA);
    if (!pMemObj)
        return;

	pBmi = (BITMAPINFO*)pMemObj->Data;

    if (pMemObj->cbData < sizeof(DWORD) && pMemObj->cbData < pBmi->bmiHeader.biSize)
        goto cleanup;

    pConvertedBmi = DIB_ConvertBitmapInfo(pBmi, DIB_RGB_COLORS);
    if (!pConvertedBmi)
        goto cleanup;

    Offset = DIB_BitmapInfoSize(pBmi, DIB_RGB_COLORS);

    hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE);
    if (!hdc)
        goto cleanup;

    hBm = GreCreateDIBitmapInternal(hdc,
                                    pConvertedBmi->bmiHeader.biWidth,
                                    pConvertedBmi->bmiHeader.biHeight,
                                    CBM_INIT,
                                    pMemObj->Data + Offset,
                                    pConvertedBmi,
                                    DIB_RGB_COLORS,
                                    0,
                                    pMemObj->cbData - Offset,
                                    0);

    if (hBm)
    {
        GreSetObjectOwner(hBm, GDI_OBJ_HMGR_PUBLIC);
        pBmEl->hData = hBm;
    }

cleanup:
    if (hdc)
        UserReleaseDC(NULL, hdc, FALSE);

    if (pConvertedBmi)
        DIB_FreeConvertedBitmapInfo(pConvertedBmi, pBmi, -1);
}
Exemple #5
0
/* IntDestroyMonitorObject
 *
 * Destroys a MONITOR
 * You have to be the owner of the monitors lock to safely destroy it.
 *
 * Arguments
 *
 *   pMonitor
 *      Pointer to the MONITOR which shall be deleted
 */
static
void
IntDestroyMonitorObject(IN PMONITOR pMonitor)
{
    /* Remove monitor region */
    if (pMonitor->hrgnMonitor)
    {
        GreSetObjectOwner(pMonitor->hrgnMonitor, GDI_OBJ_HMGR_POWNED);
        GreDeleteObject(pMonitor->hrgnMonitor);
    }

    /* Destroy monitor object */
    UserDereferenceObject(pMonitor);
    UserDeleteObject(UserHMGetHandle(pMonitor), TYPE_MONITOR);
}
Exemple #6
0
VOID
NTAPI
DC_vSetOwner(PDC pdc, ULONG ulOwner)
{

    if (pdc->rosdc.hClipRgn)
    {
        IntGdiSetRegionOwner(pdc->rosdc.hClipRgn, ulOwner);
    }

    if (pdc->rosdc.hGCClipRgn)
    {
        IntGdiSetRegionOwner(pdc->rosdc.hGCClipRgn, ulOwner);
    }

    if (pdc->dclevel.hPath)
    {
        GreSetObjectOwner(pdc->dclevel.hPath, ulOwner);
    }

    /* Dereference current brush and pen */
    BRUSH_ShareUnlockBrush(pdc->dclevel.pbrFill);
    BRUSH_ShareUnlockBrush(pdc->dclevel.pbrLine);

    /* Select the default fill and line brush */
    pdc->dcattr.hbrush = StockObjects[WHITE_BRUSH];
    pdc->dcattr.hpen = StockObjects[BLACK_PEN];
    pdc->dclevel.pbrFill = BRUSH_ShareLockBrush(pdc->pdcattr->hbrush);
    pdc->dclevel.pbrLine = PEN_ShareLockPen(pdc->pdcattr->hpen);

    /* Mark them as dirty */
    pdc->pdcattr->ulDirty_ |= DIRTY_FILL|DIRTY_LINE;

    /* Allocate or free DC attribute */
    if (ulOwner == GDI_OBJ_HMGR_PUBLIC || ulOwner == GDI_OBJ_HMGR_NONE)
    {
        if (pdc->pdcattr != &pdc->dcattr)
            DC_vFreeDcAttr(pdc);
    }
    else if (ulOwner == GDI_OBJ_HMGR_POWNED)
    {
        if (pdc->pdcattr == &pdc->dcattr)
            DC_bAllocDcAttr(pdc);
    }

    /* Set the DC's ownership */
    GDIOBJ_vSetObjectOwner(&pdc->BaseObject, ulOwner);
}
static VOID FASTCALL
IntFreeElementData(PCLIP pElement)
{
    if (!IS_DATA_DELAYED(pElement) &&
        !IS_DATA_SYNTHESIZED(pElement))
    {
        if (pElement->fGlobalHandle)
            UserDeleteObject(pElement->hData, TYPE_CLIPDATA);
        else if (pElement->fmt == CF_BITMAP || pElement->fmt == CF_PALETTE ||
                 pElement->fmt == CF_DSPBITMAP)
        {
            GreSetObjectOwner(pElement->hData, GDI_OBJ_HMGR_POWNED);
            GreDeleteObject(pElement->hData);
        }
    }
}
Exemple #8
0
/* UserUpdateMonitorSize
 *
 * Reset size of the monitor using atached device
 *
 * Arguments
 *
 *   PMONITOR
 *      pGdiDevice  Pointer to the PDEVOBJ, which size has changed
 *
 * Return value
 *   Returns a NTSTATUS
 */
NTSTATUS NTAPI
UserUpdateMonitorSize(IN HDEV hDev)
{
	PMONITOR pMonitor;
    SIZEL DeviceSize;

    /* Find monitor attached to given device */
    for (pMonitor = gMonitorList; pMonitor != NULL; pMonitor = pMonitor->pMonitorNext)
    {
        if (pMonitor->hDev == hDev)
            break;
    }

    if (pMonitor == NULL)
    {
        /* No monitor has been found */
        return STATUS_INVALID_PARAMETER;
    }

    /* Get the size of the hdev */
    PDEVOBJ_sizl((PPDEVOBJ)hDev, &DeviceSize);

    /* Update monitor size */
    pMonitor->rcMonitor.left  = 0;
    pMonitor->rcMonitor.top   = 0;
    pMonitor->rcMonitor.right  = pMonitor->rcMonitor.left + DeviceSize.cx;
    pMonitor->rcMonitor.bottom = pMonitor->rcMonitor.top + DeviceSize.cy;
    pMonitor->rcWork = pMonitor->rcMonitor;

    /* Destroy monitor region... */
    if (pMonitor->hrgnMonitor)
    {
        GreSetObjectOwner(pMonitor->hrgnMonitor, GDI_OBJ_HMGR_POWNED);
        GreDeleteObject(pMonitor->hrgnMonitor);
    }

    /* ...and create new one */
    pMonitor->hrgnMonitor = NtGdiCreateRectRgn(
        pMonitor->rcMonitor.left,
        pMonitor->rcMonitor.top,
        pMonitor->rcMonitor.right,
        pMonitor->rcMonitor.bottom);
    if (pMonitor->hrgnMonitor)
        IntGdiSetRegionOwner(pMonitor->hrgnMonitor, GDI_OBJ_HMGR_PUBLIC);

    return STATUS_SUCCESS;
}
Exemple #9
0
VOID
NTAPI
DC_vSetOwner(PDC pdc, ULONG ulOwner)
{

    if (pdc->rosdc.hClipRgn)
    {
        IntGdiSetRegionOwner(pdc->rosdc.hClipRgn, ulOwner);
    }

    if (pdc->rosdc.hGCClipRgn)
    {
        IntGdiSetRegionOwner(pdc->rosdc.hGCClipRgn, ulOwner);
    }

    if (pdc->dclevel.hPath)
    {
        GreSetObjectOwner(pdc->dclevel.hPath, ulOwner);
    }

    IntGdiSetBrushOwner(pdc->dclevel.pbrFill, ulOwner);
    IntGdiSetBrushOwner(pdc->dclevel.pbrLine, ulOwner);

    /* Allocate or free DC attribute */
    if (ulOwner == GDI_OBJ_HMGR_PUBLIC || ulOwner == GDI_OBJ_HMGR_NONE)
    {
        if (pdc->pdcattr != &pdc->dcattr)
            DC_vFreeDcAttr(pdc);
    }
    else if (ulOwner == GDI_OBJ_HMGR_POWNED)
    {
        if (pdc->pdcattr == &pdc->dcattr)
            DC_bAllocDcAttr(pdc);
    }

    /* Set the DC's ownership */
    GDIOBJ_vSetObjectOwner(&pdc->BaseObject, ulOwner);
}
Exemple #10
0
/*
 * @implemented
 */
BOOL
APIENTRY
NtUserSetCursorIconData(
  _In_     HCURSOR Handle,
  _In_opt_ PUNICODE_STRING pustrModule,
  _In_opt_ PUNICODE_STRING pustrRsrc,
  _In_     const CURSORDATA* pCursorData)
{
    PCURICON_OBJECT CurIcon;
    NTSTATUS Status = STATUS_SUCCESS;
    BOOLEAN Ret = FALSE;
    BOOLEAN IsShared = FALSE, IsAnim = FALSE;
    DWORD numFrames;
    UINT i = 0;
    
    TRACE("Enter NtUserSetCursorIconData\n");
    
    UserEnterExclusive();

    if (!(CurIcon = UserGetCurIconObject(Handle)))
    {
        UserLeave();
        EngSetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }

    _SEH2_TRY
    {
        ProbeForRead(pCursorData, sizeof(*pCursorData), 1);
        if(pCursorData->CURSORF_flags & CURSORF_ACON)
        {
            /* This is an animated cursor */
            PACON AniCurIcon = (PACON)CurIcon;
            DWORD numSteps;

            numFrames = AniCurIcon->cpcur = pCursorData->cpcur;
            numSteps = AniCurIcon->cicur = pCursorData->cicur;
            AniCurIcon->iicur = pCursorData->iicur;
            AniCurIcon->rt = pCursorData->rt;

            /* Calculate size: one cursor object for each frame, and a frame index and jiffies for each "step" */
            AniCurIcon->aspcur = ExAllocatePoolWithTag(PagedPool | POOL_RAISE_IF_ALLOCATION_FAILURE, /* Let SEH catch allocation failures */
                numFrames * sizeof(CURICON_OBJECT*) + numSteps * (sizeof(DWORD) + sizeof(INT)),
                USERTAG_CURSOR);
            AniCurIcon->aicur = (DWORD*)(AniCurIcon->aspcur + numFrames);
            AniCurIcon->ajifRate = (INT*)(AniCurIcon->aicur + numSteps);

            RtlZeroMemory(AniCurIcon->aspcur, numFrames * sizeof(CURICON_OBJECT*));

            ProbeForRead(pCursorData->aicur, numSteps * sizeof(DWORD), 1);
            RtlCopyMemory(AniCurIcon->aicur, pCursorData->aicur, numSteps * sizeof(DWORD));
            ProbeForRead(pCursorData->ajifRate, numSteps * sizeof(INT), 1);
            RtlCopyMemory(AniCurIcon->ajifRate, pCursorData->ajifRate, numSteps * sizeof(INT));
            
            AniCurIcon->CURSORF_flags = pCursorData->CURSORF_flags;
            pCursorData = pCursorData->aspcur;

            IsAnim = TRUE;
        }
        else
        {
            CurIcon->xHotspot = pCursorData->xHotspot;
            CurIcon->yHotspot = pCursorData->yHotspot;
            CurIcon->cx = pCursorData->cx;
            CurIcon->cy = pCursorData->cy;
            CurIcon->rt = pCursorData->rt;
            CurIcon->bpp = pCursorData->bpp;
            CurIcon->hbmMask = pCursorData->hbmMask;
            CurIcon->hbmColor = pCursorData->hbmColor;
            CurIcon->hbmAlpha = pCursorData->hbmAlpha;
            CurIcon->CURSORF_flags = pCursorData->CURSORF_flags;
        }
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        Status = _SEH2_GetExceptionCode();
    }
    _SEH2_END
    
    if (!NT_SUCCESS(Status))
    {
        SetLastNtError(Status);
        goto done;
    }

    if(IsAnim)
    {
        PACON AniCurIcon = (PACON)CurIcon;
        /* This is an animated cursor. Create a cursor object for each frame and set up the data */
        for(i = 0; i < numFrames; i++)
        {
            HANDLE hCurFrame = IntCreateCurIconHandle(FALSE);
            if(!NtUserSetCursorIconData(hCurFrame, NULL, NULL, pCursorData))
                goto done;
            AniCurIcon->aspcur[i] = UserGetCurIconObject(hCurFrame);
            if(!AniCurIcon->aspcur[i])
                goto done;
            pCursorData++;
        }
    }
    
    if(CurIcon->CURSORF_flags & CURSORF_LRSHARED)
    {
        IsShared = TRUE;
        if(pustrRsrc && pustrModule)
        {
            UNICODE_STRING ustrModuleSafe;
            /* We use this convenient function, because INTRESOURCEs and ATOMs are the same */
            Status = ProbeAndCaptureUnicodeStringOrAtom(&CurIcon->strName, pustrRsrc);
            if(!NT_SUCCESS(Status))
                goto done;
            Status = ProbeAndCaptureUnicodeString(&ustrModuleSafe, UserMode, pustrModule);
            if(!NT_SUCCESS(Status))
                goto done;
            Status = RtlAddAtomToAtomTable(gAtomTable, ustrModuleSafe.Buffer, &CurIcon->atomModName);
            ReleaseCapturedUnicodeString(&ustrModuleSafe, UserMode);
            if(!NT_SUCCESS(Status))
                goto done;
        }
    }

    if(!CurIcon->hbmMask)
    {
        ERR("NtUserSetCursorIconData was got no hbmMask.\n");
        EngSetLastError(ERROR_INVALID_PARAMETER);
        goto done;
    }

    GreSetObjectOwner(CurIcon->hbmMask, GDI_OBJ_HMGR_PUBLIC);

    if(CurIcon->hbmColor)
        GreSetObjectOwner(CurIcon->hbmColor, GDI_OBJ_HMGR_PUBLIC);
    
    if(CurIcon->hbmAlpha)
        GreSetObjectOwner(CurIcon->hbmAlpha, GDI_OBJ_HMGR_PUBLIC);

    if(IsShared)
    {
        /* Update process cache in case of shared cursor */
        PPROCESSINFO ppi = CurIcon->head.ppi;
        UserReferenceObject(CurIcon);
        CurIcon->pcurNext = ppi->pCursorCache;
        ppi->pCursorCache = CurIcon;
    }
    
    Ret = TRUE;

done:
    if(!Ret && IsShared)
    {
        if(!IS_INTRESOURCE(CurIcon->strName.Buffer))
            ExFreePoolWithTag(CurIcon->strName.Buffer, TAG_STRING);
    }

    if(!Ret && IsAnim)
    {
        PACON AniCurIcon = (PACON)CurIcon;
        for(i = 0; i < numFrames; i++)
        {
            if(AniCurIcon->aspcur[i])
                IntDestroyCurIconObject(AniCurIcon->aspcur[i], TRUE);
        }
        AniCurIcon->cicur = 0;
        AniCurIcon->cpcur = 0;
        ExFreePoolWithTag(AniCurIcon->aspcur, USERTAG_CURSOR);
        AniCurIcon->aspcur = NULL;
        AniCurIcon->aicur = NULL;
        AniCurIcon->ajifRate = NULL;
    }

    UserDereferenceObject(CurIcon);
    TRACE("Leave NtUserSetCursorIconData, ret=%i\n",Ret);
    UserLeave();

    return Ret;
}
Exemple #11
0
/*
 * @implemented
 */
BOOL
APIENTRY
NtUserGetIconInfo(
  _In_       HANDLE hCurIcon,
  _Out_opt_  PICONINFO IconInfo,
  _Out_opt_  PUNICODE_STRING lpModule,   // Optional
  _Out_opt_  PUNICODE_STRING lpResName,  // Optional
  _Out_opt_  LPDWORD pbpp,               // Optional
  _In_       BOOL bInternal)
{
    ICONINFO ii;
    PCURICON_OBJECT CurIcon;
    NTSTATUS Status = STATUS_SUCCESS;
    BOOL Ret = FALSE;
    DWORD colorBpp = 0;

    TRACE("Enter NtUserGetIconInfo\n");

    /* Check if something was actually asked */
    if (!IconInfo && !lpModule && !lpResName)
    {
        WARN("Nothing to fill.\n");
        EngSetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }
    
    UserEnterExclusive();

    if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
    {
        WARN("UserGetIconObject(0x%08x) Failed.\n", hCurIcon);
        UserLeave();
        return FALSE;
    }
    
    /* Give back the icon information */
    if(IconInfo)
    {
        PCURICON_OBJECT FrameCurIcon = CurIcon;
        if(CurIcon->CURSORF_flags & CURSORF_ACON)
        {
            /* Get information from first frame. */
            FrameCurIcon = ((PACON)CurIcon)->aspcur[0];
        }
            
        /* Fill data */
        ii.fIcon = is_icon(FrameCurIcon);
        ii.xHotspot = FrameCurIcon->xHotspot;
        ii.yHotspot = FrameCurIcon->yHotspot;

        /* Copy bitmaps */
        ii.hbmMask = BITMAP_CopyBitmap(FrameCurIcon->hbmMask);
        GreSetObjectOwner(ii.hbmMask, GDI_OBJ_HMGR_POWNED);
        ii.hbmColor = BITMAP_CopyBitmap(FrameCurIcon->hbmColor);
        GreSetObjectOwner(ii.hbmColor, GDI_OBJ_HMGR_POWNED);
        colorBpp = FrameCurIcon->bpp;

        /* Copy fields */
        _SEH2_TRY
        {
            ProbeForWrite(IconInfo, sizeof(ICONINFO), 1);
            RtlCopyMemory(IconInfo, &ii, sizeof(ICONINFO));

            if (pbpp)
            {
                ProbeForWrite(pbpp, sizeof(DWORD), 1);
                *pbpp = colorBpp;
            }
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            Status = _SEH2_GetExceptionCode();
        }
        _SEH2_END

        if (!NT_SUCCESS(Status))
        {
            WARN("Status: 0x%08x.\n", Status);
            SetLastNtError(Status);
            goto leave;
        }
    }

    /* Give back the module name */
    if(lpModule)
    {
        ULONG BufLen = 0;
        if (!CurIcon->atomModName)
            goto leave;

        RtlQueryAtomInAtomTable(gAtomTable, CurIcon->atomModName, NULL, NULL, NULL, &BufLen);
        /* Get the module name from the atom table */
        _SEH2_TRY
        {
            if (BufLen > (lpModule->MaximumLength * sizeof(WCHAR)))
            {
                lpModule->Length = 0;
            }
            else
            {
                ProbeForWrite(lpModule->Buffer, lpModule->MaximumLength, 1);
                BufLen = lpModule->MaximumLength * sizeof(WCHAR);
                RtlQueryAtomInAtomTable(gAtomTable, CurIcon->atomModName, NULL, NULL, lpModule->Buffer, &BufLen);
                lpModule->Length = BufLen/sizeof(WCHAR);
            }
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            Status = _SEH2_GetExceptionCode();
        }
        _SEH2_END

        if (!NT_SUCCESS(Status))
        {
            SetLastNtError(Status);
            goto leave;
        }
    }
    
    if (lpResName)
    {
        if (!CurIcon->strName.Buffer)
            goto leave;

        /* Copy it */
        _SEH2_TRY
        {
            ProbeForWrite(lpResName, sizeof(UNICODE_STRING), 1);
            if (IS_INTRESOURCE(CurIcon->strName.Buffer))
            {
                lpResName->Buffer = CurIcon->strName.Buffer;
                lpResName->Length = 0;
            }
            else if (lpResName->MaximumLength < CurIcon->strName.Length)
            {
                lpResName->Length = 0;
            }
            else
            {
                ProbeForWrite(lpResName->Buffer, lpResName->MaximumLength * sizeof(WCHAR), 1);
                RtlCopyMemory(lpResName->Buffer, CurIcon->strName.Buffer, lpResName->Length);
            }
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            Status = _SEH2_GetExceptionCode();
        }
        _SEH2_END
    }

    if (!NT_SUCCESS(Status))
    {
        SetLastNtError(Status);
        goto leave;
    }
    
    Ret = TRUE;

leave:
    UserDereferenceObject(CurIcon);

    TRACE("Leave NtUserGetIconInfo, ret=%i\n", Ret);
    UserLeave();

    return Ret;
}
Exemple #12
0
BOOLEAN FASTCALL
IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, BOOLEAN bForce)
{
    if(CurIcon->CURSORF_flags & CURSORF_CURRENT)
    {
        /* Mark the object as destroyed, and fail, as per tests */
        TRACE("Cursor is current, marking as destroyed.\n");
        UserDeleteObject(CurIcon->head.h, TYPE_CURSOR);
        return FALSE;
    }

    if(CurIcon->head.ppi != PsGetCurrentProcessWin32Process())
    {
        /* This object doesn't belong to the current process */
        WARN("Trying to delete foreign cursor!\n");
        UserDereferenceObject(CurIcon);
        EngSetLastError(ERROR_DESTROY_OBJECT_OF_OTHER_THREAD);
        return FALSE;
    }
    
    /* Do not destroy it if it is shared. (And we're not forced to) */
    if((CurIcon->CURSORF_flags & CURSORF_LRSHARED) && !bForce)
    {
        /* Tests show this is a valid call */
        WARN("Trying to destroy shared cursor!\n");
        UserDereferenceObject(CurIcon);
        return TRUE;
    }

    if(!(CurIcon->CURSORF_flags & CURSORF_ACON))
    {
        HBITMAP bmpMask = CurIcon->hbmMask;
        HBITMAP bmpColor = CurIcon->hbmColor;
        HBITMAP bmpAlpha = CurIcon->hbmAlpha;

        /* Delete bitmaps */
        if (bmpMask)
        {
            GreSetObjectOwner(bmpMask, GDI_OBJ_HMGR_POWNED);
            GreDeleteObject(bmpMask);
            CurIcon->hbmMask = NULL;
        }
        if (bmpColor)
        {
            GreSetObjectOwner(bmpColor, GDI_OBJ_HMGR_POWNED);
            GreDeleteObject(bmpColor);
            CurIcon->hbmColor = NULL;
        }
        if (bmpAlpha)
        {
            GreSetObjectOwner(bmpAlpha, GDI_OBJ_HMGR_POWNED);
            GreDeleteObject(bmpAlpha);
            CurIcon->hbmAlpha = NULL;
        }
    }
    else
    {
        PACON AniCurIcon = (PACON)CurIcon;
        UINT i;

        for(i = 0; i < AniCurIcon->cpcur; i++)
            IntDestroyCurIconObject(AniCurIcon->aspcur[i], TRUE);
        ExFreePoolWithTag(AniCurIcon->aspcur, USERTAG_CURSOR);
    }

    if (CurIcon->CURSORF_flags & CURSORF_LRSHARED)
    {
        if (!IS_INTRESOURCE(CurIcon->strName.Buffer))
            ExFreePoolWithTag(CurIcon->strName.Buffer, TAG_STRING);
        if (CurIcon->atomModName)
            RtlDeleteAtomFromAtomTable(gAtomTable, CurIcon->atomModName);
        CurIcon->strName.Buffer = NULL;
        CurIcon->atomModName = 0;
    }

    /* We were given a pointer, no need to keep the reference any longer! */
    UserDereferenceObject(CurIcon);
    return UserDeleteObject(CurIcon->head.h, TYPE_CURSOR);
}