Esempio n. 1
0
VOID
NTAPI
SURFACE_vCleanup(PVOID ObjectBody)
{
    PSURFACE psurf = (PSURFACE)ObjectBody;
    PVOID pvBits = psurf->SurfObj.pvBits;

    /* Check if the surface has bits */
    if (pvBits)
    {
        /* Only bitmaps can have bits */
        ASSERT(psurf->SurfObj.iType == STYPE_BITMAP);

        /* Check if it is a DIB section */
        if (psurf->hDIBSection)
        {
            /* Unmap the section view */
            EngUnmapSectionView(pvBits, psurf->dwOffset, psurf->hSecure);
        }
        else if (psurf->SurfObj.fjBitmap & BMF_USERMEM)
        {
            /* Bitmap was allocated from usermode memory */
            EngFreeUserMem(pvBits);
        }
        else if (psurf->SurfObj.fjBitmap & BMF_KMSECTION)
        {
            /* Bitmap was allocated from a kernel section */
            if (!EngFreeSectionMem(NULL, pvBits))
            {
                DPRINT1("EngFreeSectionMem failed for %p!\n", pvBits);
                // Should we BugCheck here?
                ASSERT(FALSE);
            }
        }
        else if (psurf->SurfObj.fjBitmap & BMF_POOLALLOC)
        {
            /* Free a pool allocation */
            EngFreeMem(pvBits);
        }
    }

    /* Free palette */
    if(psurf->ppal)
    {
        PALETTE_ShareUnlockPalette(psurf->ppal);
    }
}
Esempio n. 2
0
PVOID
APIENTRY
EngAllocSectionMem(
    OUT PVOID *ppvSection,
    IN ULONG fl,
    IN SIZE_T cjSize,
    IN ULONG ulTag)
{
    NTSTATUS Status;
    PENGSECTION pSection;

    /* Check parameter */
    if (cjSize == 0) return NULL;

    /* Allocate a section object */
    pSection = EngCreateSectionHack(fl, cjSize, ulTag);
    if (!pSection)
    {
        *ppvSection = NULL;
        return NULL;
    }

    /* Map the section in session space */
    Status = MmMapViewInSessionSpace(pSection->pvSectionObject,
                                     &pSection->pvMappedBase,
                                     &pSection->cjViewSize);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to map a section Status=0x%x\n", Status);
        *ppvSection = NULL;
        EngFreeSectionMem(pSection, NULL);
        return NULL;
    }

    if (fl & FL_ZERO_MEMORY)
    {
        RtlZeroMemory(pSection->pvMappedBase, cjSize);
    }

    /* Set section pointer and return base address */
    *ppvSection = pSection;
    return pSection->pvMappedBase;
}
Esempio n. 3
0
PSURFACE
NTAPI
SURFACE_AllocSurface(
    _In_ USHORT iType,
    _In_ ULONG cx,
    _In_ ULONG cy,
    _In_ ULONG iFormat,
    _In_ ULONG fjBitmap,
    _In_opt_ ULONG cjWidth,
    _In_opt_ ULONG cjBufSize,
    _In_opt_ PVOID pvBits)
{
    ULONG cBitsPixel, cjBits, cjObject;
    PSURFACE psurf;
    SURFOBJ *pso;
    PVOID pvSection;

    NT_ASSERT(!pvBits || (iType == STYPE_BITMAP));
    NT_ASSERT((iFormat <= BMF_32BPP) || (cjBufSize != 0));
    NT_ASSERT((LONG)cy > 0);

    /* Verify format */
    if ((iFormat < BMF_1BPP) || (iFormat > BMF_PNG))
    {
        DPRINT1("Invalid bitmap format: %lu\n", iFormat);
        return NULL;
    }

    /* Get bits per pixel from the format */
    cBitsPixel = gajBitsPerFormat[iFormat];

    /* Are bits and a width in bytes given? */
    if (pvBits && cjWidth)
    {
        /* Align the width (Windows compatibility, drivers expect that) */
        cjWidth = WIDTH_BYTES_ALIGN32((cjWidth << 3) / cBitsPixel, cBitsPixel);
    }
    else
    {
        /* Calculate width from the bitmap width in pixels */
        cjWidth = WIDTH_BYTES_ALIGN32(cx, cBitsPixel);
    }

    /* Is this an uncompressed format? */
    if (iFormat <= BMF_32BPP)
    {
        /* Calculate the correct bitmap size in bytes */
        if (!NT_SUCCESS(RtlULongMult(cjWidth, cy, &cjBits)))
        {
            DPRINT1("Overflow calculating size: cjWidth %lu, cy %lu\n",
                    cjWidth, cy);
            return NULL;
        }

        /* Did we get a buffer and size? */
        if ((pvBits != NULL) && (cjBufSize != 0))
        {
            /* Make sure the buffer is large enough */
            if (cjBufSize < cjBits)
            {
                DPRINT1("Buffer is too small, required: %lu, got %lu\n",
                        cjBits, cjBufSize);
                return NULL;
            }
        }
    }
    else
    {
        /* Compressed format, use the provided size */
        NT_ASSERT(cjBufSize != 0);
        cjBits = cjBufSize;
    }

    /* Check if we need an extra large object */
    if ((iType == STYPE_BITMAP) && (pvBits == NULL) &&
        !(fjBitmap & BMF_USERMEM) && !(fjBitmap & BMF_KMSECTION))
    {
        /* Allocate an object large enough to hold the bits */
        cjObject = sizeof(SURFACE) + cjBits;
    }
    else
    {
        /* Otherwise just allocate the SURFACE structure */
        cjObject = sizeof(SURFACE);
    }

    /* Check for arithmetic overflow */
    if (cjObject < sizeof(SURFACE))
    {
        /* Fail! */
        DPRINT1("Overflow calculating cjObject: cjBits %lu\n", cjBits);
        return NULL;
    }

    /* Allocate a SURFACE object */
    psurf = (PSURFACE)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP, cjObject);
    if (!psurf)
    {
        return NULL;
    }

    /* Initialize the basic fields */
    pso = &psurf->SurfObj;
    pso->hsurf = psurf->BaseObject.hHmgr;
    pso->sizlBitmap.cx = cx;
    pso->sizlBitmap.cy = cy;
    pso->iBitmapFormat = iFormat;
    pso->iType = iType;
    pso->fjBitmap = (USHORT)fjBitmap;
    pso->iUniq = InterlockedIncrement(&giUniqueSurface);
    pso->cjBits = cjBits;

    /* Check if we need a bitmap buffer */
    if (iType == STYPE_BITMAP)
    {
        /* Check if we got one or if we need to allocate one */
        if (pvBits != NULL)
        {
            /* Use the caller provided buffer */
            pso->pvBits = pvBits;
        }
        else if (fjBitmap & BMF_USERMEM)
        {
            /* User mode memory was requested */
            pso->pvBits = EngAllocUserMem(cjBits, 0);

            /* Check for failure */
            if (!pso->pvBits)
            {
                GDIOBJ_vDeleteObject(&psurf->BaseObject);
                return NULL;
            }
        }
        else if (fjBitmap & BMF_KMSECTION)
        {
            /* Use a kernel mode section */
            pso->pvBits = EngAllocSectionMem(&pvSection,
                                             (fjBitmap & BMF_NOZEROINIT) ?
                                                 0 : FL_ZERO_MEMORY,
                                             cjBits, TAG_DIB);

            /* Check for failure */
            if (!pso->pvBits)
            {
                GDIOBJ_vDeleteObject(&psurf->BaseObject);
                return NULL;
            }

            /* Free the section already, but keep the mapping */
            EngFreeSectionMem(pvSection, NULL);
        }
        else
        {
            /* Buffer is after the object */
            pso->pvBits = psurf + 1;

            /* Zero the buffer, except requested otherwise */
            if (!(fjBitmap & BMF_NOZEROINIT))
            {
                RtlZeroMemory(pso->pvBits, cjBits);
            }
        }

        /* Set pvScan0 and lDelta */
        if (fjBitmap & BMF_TOPDOWN)
        {
            /* Topdown is the normal way */
            pso->pvScan0 = pso->pvBits;
            pso->lDelta = cjWidth;
        }
        else
        {
            /* Inversed bitmap (bottom up) */
            pso->pvScan0 = ((PCHAR)pso->pvBits + pso->cjBits - cjWidth);
            pso->lDelta = -(LONG)cjWidth;
        }
    }
    else
    {
        /* There are no bitmap bits */
        pso->pvScan0 = pso->pvBits = NULL;
        pso->lDelta = 0;
    }

    /* Assign a default palette and increment its reference count */
    SURFACE_vSetPalette(psurf, appalSurfaceDefault[iFormat]);

    return psurf;
}