示例#1
0
/*
 *  integer arithmetic expression
 */
IVAL arithexpr P1 (TYP *, tp)
{
    EXPR   *ep = exprnc ();

    if (ep != NIL_EXPR) {
        ep = implicit_castop (ep, tp);
        ep = constantopt (ep);
        if (is_icon (ep)) {
            return ep->v.i;
        }
    }
#ifndef SYNTAX_CORRECT
    message (ERR_CONSTINT);
    getsym ();
#endif /* SYNTAX_CORRECT */
    return 0L;
}
示例#2
0
IVAL intexpr P0 (void)
{
    EXPR   *ep = exprnc ();

    if (ep != NIL_EXPR) {
        ep = constantopt (ep);
        if (is_icon (ep)) {
            return ep->v.i;
        }
    }
#ifndef SYNTAX_CORRECT
    message (ERR_CONSTINT);
    /*
     * any return value is wrong, but 1 is
     * less likely than 0 to cause spurious
     * errors later in the compilation.
     */
#endif /* SYNTAX_CORRECT */
    return 1L;
}
示例#3
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;
}
示例#4
0
/*
 * @implemented
 */
HICON
NTAPI
NtUserFindExistingCursorIcon(
  _In_  PUNICODE_STRING pustrModule,
  _In_  PUNICODE_STRING pustrRsrc,
  _In_  FINDEXISTINGCURICONPARAM* param)
{
    PCURICON_OBJECT CurIcon;
    HICON Ret = NULL;
    UNICODE_STRING ustrModuleSafe, ustrRsrcSafe;
    FINDEXISTINGCURICONPARAM paramSafe;
    NTSTATUS Status;
    PPROCESSINFO pProcInfo = PsGetCurrentProcessWin32Process();
    RTL_ATOM atomModName;

    TRACE("Enter NtUserFindExistingCursorIcon\n");
    
    
    _SEH2_TRY
    {
        ProbeForRead(param, sizeof(*param), 1);
        RtlCopyMemory(&paramSafe, param, sizeof(paramSafe));
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        Status = _SEH2_GetExceptionCode();
    }
    _SEH2_END

    /* Capture resource name (it can be an INTRESOURCE == ATOM) */
    Status = ProbeAndCaptureUnicodeStringOrAtom(&ustrRsrcSafe, pustrRsrc);
    if(!NT_SUCCESS(Status))
        return NULL;
    Status = ProbeAndCaptureUnicodeString(&ustrModuleSafe, UserMode, pustrModule);
    if(!NT_SUCCESS(Status))
        goto done;
    Status = RtlLookupAtomInAtomTable(gAtomTable, ustrModuleSafe.Buffer, &atomModName);
    ReleaseCapturedUnicodeString(&ustrModuleSafe, UserMode);
    if(!NT_SUCCESS(Status))
    {
        /* The module is not in the atom table. No chance to find the cursor */
        goto done;
    }

    UserEnterExclusive();
    CurIcon = pProcInfo->pCursorCache;
    while(CurIcon)
    {
        /* Icon/cursor */
        if (paramSafe.bIcon != is_icon(CurIcon))
        {
            CurIcon = CurIcon->pcurNext;
            continue;
        }
        /* See if module names match */
        if (atomModName == CurIcon->atomModName)
        {
            /* They do. Now see if this is the same resource */
            if (IS_INTRESOURCE(CurIcon->strName.Buffer) != IS_INTRESOURCE(ustrRsrcSafe.Buffer))
            {
                /* One is an INT resource and the other is not -> no match */
                CurIcon = CurIcon->pcurNext;
                continue;
            }
            
            if (IS_INTRESOURCE(CurIcon->strName.Buffer))
            {
                if (CurIcon->strName.Buffer == ustrRsrcSafe.Buffer)
                {
                    /* INT resources match */
                    break;
                }
            }
            else if (RtlCompareUnicodeString(&ustrRsrcSafe, &CurIcon->strName, TRUE) == 0)
            {
                /* Resource name strings match */
                break;
            }
        }
        CurIcon = CurIcon->pcurNext;
    }
    if(CurIcon)
        Ret = CurIcon->head.h;
    UserLeave();

done:
    if(!IS_INTRESOURCE(ustrRsrcSafe.Buffer))
        ExFreePoolWithTag(ustrRsrcSafe.Buffer, TAG_STRING);
    
    return Ret;
}
示例#5
0
/* Mostly inspired from wine code.
 * We use low level functions because:
 *  - at this point, the icon bitmap could have a different bit depth than the DC,
 *    making it thus impossible to use NtCreateCompatibleDC and selecting the bitmap.
 *    This happens after a mode setting change.
 *  - it avoids massive GDI objects locking when only the destination surface needs it.
 *  - It makes (small) performance gains.
 */
BOOL
UserDrawIconEx(
    HDC hDc,
    INT xLeft,
    INT yTop,
    PCURICON_OBJECT pIcon,
    INT cxWidth,
    INT cyHeight,
    UINT istepIfAniCur,
    HBRUSH hbrFlickerFreeDraw,
    UINT diFlags)
{
    PSURFACE psurfDest, psurfMask, psurfColor; //, psurfOffScreen = NULL;
    PDC pdc = NULL;
    BOOL Ret = FALSE;
    HBITMAP hbmMask, hbmColor, hbmAlpha;
    BOOL bOffScreen;
    RECTL rcDest, rcSrc;
    CLIPOBJ* pdcClipObj = NULL;
    EXLATEOBJ exlo;
    
    /* Stupid case */
    if((diFlags & DI_NORMAL) == 0)
    {
        ERR("DrawIconEx called without mask or color bitmap to draw.\n");
        return FALSE;
    }

    if (pIcon->CURSORF_flags & CURSORF_ACON)
    {
        ACON* pAcon = (ACON*)pIcon;
        if(istepIfAniCur >= pAcon->cicur)
        {
            ERR("NtUserDrawIconEx: istepIfAniCur too big!\n");
            return FALSE;
        }
        pIcon = pAcon->aspcur[pAcon->aicur[istepIfAniCur]];
    }

    hbmMask = pIcon->hbmMask;
    hbmColor = pIcon->hbmColor;
    hbmAlpha = pIcon->hbmAlpha;
    
    /*
     * Get our objects. 
     * Shared locks are enough, we are only reading those bitmaps
     */
    psurfMask = SURFACE_ShareLockSurface(hbmMask);
    if(psurfMask == NULL)
    {
        ERR("Unable to lock the mask surface.\n");
        return FALSE;
    }
    
    /* Color bitmap is not mandatory */
    if(hbmColor == NULL)
    {
        /* But then the mask bitmap must have the information in it's bottom half */
        ASSERT(psurfMask->SurfObj.sizlBitmap.cy == 2*pIcon->cy);
        psurfColor = NULL;
    }
    else if ((psurfColor = SURFACE_ShareLockSurface(hbmColor)) == NULL)
    {
        ERR("Unable to lock the color bitmap.\n");
        SURFACE_ShareUnlockSurface(psurfMask);
        return FALSE;
    }
    
    pdc = DC_LockDc(hDc);
    if(!pdc)
    {
        ERR("Could not lock the destination DC.\n");
        SURFACE_ShareUnlockSurface(psurfMask);
        if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
        return FALSE;
    }
    /* Calculate destination rectangle */
    RECTL_vSetRect(&rcDest, xLeft, yTop, xLeft + cxWidth, yTop + cyHeight);
    IntLPtoDP(pdc, (LPPOINT)&rcDest, 2);
    RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
    
    /* Prepare the underlying surface */
    DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);

    /* We now have our destination surface and rectangle */
    psurfDest = pdc->dclevel.pSurface;
    
    if(psurfDest == NULL)
    {
        /* Empty DC */
        DC_vFinishBlit(pdc, NULL);
        DC_UnlockDc(pdc);
        SURFACE_ShareUnlockSurface(psurfMask);
        if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
        return FALSE;
    }
    
    /* Set source rect */
    RECTL_vSetRect(&rcSrc, 0, 0, pIcon->cx, pIcon->cy);

    /* Fix width parameter, if needed */
    if (!cxWidth)
    {
        if(diFlags & DI_DEFAULTSIZE)
            cxWidth = is_icon(pIcon) ? 
                UserGetSystemMetrics(SM_CXICON) : UserGetSystemMetrics(SM_CXCURSOR);
        else
            cxWidth = pIcon->cx;
    }
    
    /* Fix height parameter, if needed */
    if (!cyHeight)
    {
        if(diFlags & DI_DEFAULTSIZE)
            cyHeight = is_icon(pIcon) ? 
                UserGetSystemMetrics(SM_CYICON) : UserGetSystemMetrics(SM_CYCURSOR);
        else
            cyHeight = pIcon->cy;
    }

    /* Should we render off-screen? */
    bOffScreen = hbrFlickerFreeDraw && 
        (GDI_HANDLE_GET_TYPE(hbrFlickerFreeDraw) == GDI_OBJECT_TYPE_BRUSH);

    if (bOffScreen)
    {
        /* Yes: Allocate and paint the offscreen surface */
        EBRUSHOBJ eboFill;
        PBRUSH pbrush = BRUSH_ShareLockBrush(hbrFlickerFreeDraw);
        
        TRACE("Performing off-screen rendering.\n");
        
        if(!pbrush)
        {
            ERR("Failed to get brush object.\n");
            goto Cleanup;
        }

#if 0 //We lock the hdc surface during the whole function it makes no sense to use an offscreen surface for "flicker free" drawing
        psurfOffScreen = SURFACE_AllocSurface(STYPE_BITMAP,
            cxWidth, cyHeight, psurfDest->SurfObj.iBitmapFormat,
            0, 0, NULL);
        if(!psurfOffScreen)
        {
            ERR("Failed to allocate the off-screen surface.\n");
            BRUSH_ShareUnlockBrush(pbrush);
            goto Cleanup;
        }
        
        /* Paint the brush */
        EBRUSHOBJ_vInit(&eboFill, pbrush, psurfOffScreen, 0x00FFFFFF, 0, NULL);
        RECTL_vSetRect(&rcDest, 0, 0, cxWidth, cyHeight);
        
        Ret = IntEngBitBlt(&psurfOffScreen->SurfObj,
            NULL,
            NULL,
            NULL,
            NULL,
            &rcDest,
            NULL,
            NULL,
            &eboFill.BrushObject,
            &pbrush->ptOrigin,
            ROP4_PATCOPY);

        /* Clean up everything */
        EBRUSHOBJ_vCleanup(&eboFill);
        BRUSH_ShareUnlockBrush(pbrush);
            
        if(!Ret)
        {
            ERR("Failed to paint the off-screen surface.\n");
            goto Cleanup;
        }
        
        /* We now have our destination surface */
        psurfDest = psurfOffScreen;
#else
        pdcClipObj = pdc->rosdc.CombinedClip;
        /* Paint the brush */
        EBRUSHOBJ_vInit(&eboFill, pbrush, psurfDest, 0x00FFFFFF, 0, NULL);
        
        Ret = IntEngBitBlt(&psurfDest->SurfObj,
            NULL,
            NULL,
            pdcClipObj,
            NULL,
            &rcDest,
            NULL,
            NULL,
            &eboFill.BrushObject,
            &pbrush->ptOrigin,
            ROP4_PATCOPY);

        /* Clean up everything */
        EBRUSHOBJ_vCleanup(&eboFill);
        BRUSH_ShareUnlockBrush(pbrush);
            
        if(!Ret)
        {
            ERR("Failed to paint the off-screen surface.\n");
            goto Cleanup;
        }
#endif
    }
    else
    {
        /* We directly draw to the DC */
        TRACE("Performing on screen rendering.\n");
        pdcClipObj = pdc->rosdc.CombinedClip;
        // psurfOffScreen = NULL;
    }

    /* Now do the rendering */
	if(hbmAlpha && ((diFlags & DI_NORMAL) == DI_NORMAL))
	{
	    BLENDOBJ blendobj = { {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA } };
        PSURFACE psurf = NULL;

        psurf = SURFACE_ShareLockSurface(hbmAlpha);
        if(!psurf)
        {
            ERR("SURFACE_LockSurface failed!\n");
            goto NoAlpha;
        }
        
        /* Initialize color translation object */
        EXLATEOBJ_vInitialize(&exlo, psurf->ppal, psurfDest->ppal, 0xFFFFFFFF, 0xFFFFFFFF, 0);
        
        /* Now do it */
        Ret = IntEngAlphaBlend(&psurfDest->SurfObj,
                               &psurf->SurfObj,
                               pdcClipObj,
                               &exlo.xlo,
                               &rcDest,
                               &rcSrc,
                               &blendobj);
        
        EXLATEOBJ_vCleanup(&exlo);
        SURFACE_ShareUnlockSurface(psurf);
        if(Ret) goto done;
		ERR("NtGdiAlphaBlend failed!\n");
    }
NoAlpha:
    if (diFlags & DI_MASK)
    {
        DWORD rop4 = (diFlags & DI_IMAGE) ? ROP4_SRCAND : ROP4_SRCCOPY;
        
        EXLATEOBJ_vInitSrcMonoXlate(&exlo, psurfDest->ppal, 0x00FFFFFF, 0);
        
        Ret = IntEngStretchBlt(&psurfDest->SurfObj,
                               &psurfMask->SurfObj,
                               NULL,
                               pdcClipObj,
                               &exlo.xlo,
                               NULL,
                               &rcDest,
                               &rcSrc,
                               NULL,
                               NULL,
                               NULL,
                               rop4);
        
        EXLATEOBJ_vCleanup(&exlo);

        if(!Ret)
        {
            ERR("Failed to mask the bitmap data.\n");
            goto Cleanup;
        }
    }

    if(diFlags & DI_IMAGE)
    {
		if (psurfColor)
        {
            DWORD rop4 = (diFlags & DI_MASK) ? ROP4_SRCINVERT : ROP4_SRCCOPY ;
            
            EXLATEOBJ_vInitialize(&exlo, psurfColor->ppal, psurfDest->ppal, 0x00FFFFFF, 0x00FFFFFF, 0);
            
            Ret = IntEngStretchBlt(&psurfDest->SurfObj,
                                   &psurfColor->SurfObj,
                                   NULL,
                                   pdcClipObj,
                                   &exlo.xlo,
                                   NULL,
                                   &rcDest,
                                   &rcSrc,
                                   NULL,
                                   NULL,
                                   NULL,
                                   rop4);
        
            EXLATEOBJ_vCleanup(&exlo);

            if(!Ret)
            {
                ERR("Failed to render the icon bitmap.\n");
                goto Cleanup;
            }
        }
        else
        {
            /* Mask bitmap holds the information in its bottom half */
            DWORD rop4 = (diFlags & DI_MASK) ? ROP4_SRCINVERT : ROP4_SRCCOPY;
            RECTL_vOffsetRect(&rcSrc, 0, pIcon->cy);
            
            EXLATEOBJ_vInitSrcMonoXlate(&exlo, psurfDest->ppal, 0x00FFFFFF, 0);
        
            Ret = IntEngStretchBlt(&psurfDest->SurfObj,
                                   &psurfMask->SurfObj,
                                   NULL,
                                   pdcClipObj,
                                   &exlo.xlo,
                                   NULL,
                                   &rcDest,
                                   &rcSrc,
                                   NULL,
                                   NULL,
                                   NULL,
                                   rop4);
            
            EXLATEOBJ_vCleanup(&exlo);

            if(!Ret)
            {
                ERR("Failed to render the icon bitmap.\n");
                goto Cleanup;
            }
        }
    }

done:
#if 0
    /* We're done. Was it a double buffered draw ? */
    if(bOffScreen)
    {
        /* Yes. Draw it back to our DC */
        POINTL ptSrc = {0, 0};

        /* Calculate destination rectangle */
        RECTL_vSetRect(&rcDest, xLeft, yTop, xLeft + cxWidth, yTop + cyHeight);
        IntLPtoDP(pdc, (LPPOINT)&rcDest, 2);
        RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
        
        /* Get the clip object */
        pdcClipObj = pdc->rosdc.CombinedClip;
        
        /* We now have our destination surface and rectangle */
        psurfDest = pdc->dclevel.pSurface;
        
        /* Color translation */
        EXLATEOBJ_vInitialize(&exlo, psurfOffScreen->ppal, psurfDest->ppal, 0x00FFFFFF, 0x00FFFFFF, 0);
        
        /* Blt it! */
        Ret = IntEngBitBlt(&psurfDest->SurfObj,
                           &psurfOffScreen->SurfObj,
                           NULL,
                           pdcClipObj,
                           &exlo.xlo,
                           &rcDest,
                           &ptSrc,
                           NULL,
                           NULL,
                           NULL,
                           ROP4_SRCCOPY);
                           
        EXLATEOBJ_vCleanup(&exlo);
    }
#endif
Cleanup:
    if(pdc)
    {
        DC_vFinishBlit(pdc, NULL);
        DC_UnlockDc(pdc);
    }

#if 0
    /* Delete off screen rendering surface */
    if(psurfOffScreen)
        GDIOBJ_vDeleteObject(&psurfOffScreen->BaseObject);
#endif

    /* Unlock other surfaces */
    SURFACE_ShareUnlockSurface(psurfMask);
    if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);

    return Ret;
}