mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
901 lines
23 KiB
901 lines
23 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: surfobj.cxx
|
|
*
|
|
* Surface user objects.
|
|
*
|
|
* Copyright (c) 1990-1995 Microsoft Corporation
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.hxx"
|
|
|
|
// The following declarations are required by the native c8 compiler.
|
|
|
|
PSURFACE SURFACE::pdibDefault; // The default bitmap pointer
|
|
|
|
ULONG DbgSurf = 0;
|
|
|
|
#define KM_SIZE_MAX 0x40000
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* pvAllocateKernelSection - Allocate kernel mode section
|
|
*
|
|
* Arguments:
|
|
*
|
|
* AllocationSize - size in bytes of requested memory
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Pointer to memory or NULL
|
|
*
|
|
* History:
|
|
*
|
|
* 22-May-1996 -by- Mark Enstrom [marke]
|
|
*
|
|
\**************************************************************************/
|
|
|
|
typedef struct _KMSECTIONHEADER
|
|
{
|
|
PVOID pSection;
|
|
ULONG Tag;
|
|
}KMSECTIONHEADER,*PKMSECTIONHEADER;
|
|
|
|
PVOID
|
|
pvAllocateKernelSection(
|
|
SIZE_T AllocationSize,
|
|
ULONG Tag
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
LARGE_INTEGER MaximumSize;
|
|
HANDLE hMemory;
|
|
PVOID pvAlloc = NULL;
|
|
PVOID pvRet = NULL;
|
|
|
|
//
|
|
// Create km section
|
|
//
|
|
|
|
ACCESS_MASK DesiredAccess = SECTION_MAP_READ |
|
|
SECTION_MAP_WRITE;
|
|
|
|
ULONG SectionPageProtection = PAGE_READWRITE;
|
|
|
|
ULONG AllocationAttributes = SEC_COMMIT |
|
|
SEC_NO_CHANGE;
|
|
|
|
MaximumSize.HighPart = 0;
|
|
MaximumSize.LowPart = AllocationSize + sizeof(KMSECTIONHEADER);
|
|
|
|
Status = ZwCreateSection(
|
|
&hMemory,
|
|
DesiredAccess,
|
|
NULL,
|
|
&MaximumSize,
|
|
SectionPageProtection,
|
|
AllocationAttributes,
|
|
NULL);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
WARNING1("pvAllocateKernelSection: Failed creation of Kernel section\n");
|
|
}
|
|
else
|
|
{
|
|
PVOID pHandleSection;
|
|
|
|
//
|
|
// map a copy of this section into kernel address space
|
|
//
|
|
|
|
Status = ObReferenceObjectByHandle(hMemory,
|
|
SECTION_MAP_READ | SECTION_MAP_WRITE,
|
|
NULL,
|
|
KernelMode,
|
|
&pHandleSection,
|
|
NULL);
|
|
|
|
ZwClose(hMemory);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
WARNING1("pvAllocateKernelSection: ObReferenceObjectByHandle failed\n");
|
|
}
|
|
else
|
|
{
|
|
ULONG ViewSize = 0;
|
|
|
|
Status = MmMapViewInSystemSpace(
|
|
pHandleSection,
|
|
(PVOID*)&pvAlloc,
|
|
&ViewSize);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
//
|
|
// free section
|
|
//
|
|
|
|
WARNING1("pvAllocateKernelSection: MmMapViewInSystemSpace failed\n");
|
|
ObDereferenceObject(pHandleSection);
|
|
}
|
|
else
|
|
{
|
|
((PKMSECTIONHEADER)pvAlloc)->Tag = Tag;
|
|
((PKMSECTIONHEADER)pvAlloc)->pSection = pHandleSection;
|
|
pvRet = (PVOID)(((PUCHAR)pvAlloc)+sizeof(KMSECTIONHEADER));
|
|
}
|
|
}
|
|
}
|
|
|
|
return(pvRet);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vFreeKernelSection: Free kernel mode section
|
|
*
|
|
* Arguments:
|
|
*
|
|
* pvMem - Kernel mode section pointer
|
|
*
|
|
* Return Value:
|
|
*
|
|
* None
|
|
*
|
|
* History:
|
|
*
|
|
* 22-May-1996 -by- Mark Enstrom [marke]
|
|
*
|
|
\**************************************************************************/
|
|
|
|
VOID
|
|
vFreeKernelSection(
|
|
PVOID pvMem
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
PVOID pHandleSection;
|
|
|
|
if (pvMem != NULL)
|
|
{
|
|
PKMSECTIONHEADER pvHeader = (PKMSECTIONHEADER)((PUCHAR)pvMem - sizeof(KMSECTIONHEADER));
|
|
|
|
pHandleSection = pvHeader->pSection;
|
|
|
|
//
|
|
// unmap kernel mode view
|
|
//
|
|
|
|
Status = MmUnmapViewInSystemSpace((PVOID)pvHeader);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
WARNING1("vFreeKernelSection: MmUnmapViewInSystemSpace failed\n");
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// delete reference to section
|
|
//
|
|
|
|
ObDereferenceObject(pHandleSection);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WARNING("vFreeKernelSection called with NULL pvMem\n");
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* SURFACE::bDeleteSurface()
|
|
*
|
|
* Delete the surface. Make sure it is not selected into a DC if it is
|
|
* a bitmap. We do under cover of multi-lock to ensure no one will select
|
|
* the bitmap into a DC after we checked cRef.
|
|
*
|
|
* History:
|
|
* Mon 17-Feb-1992 -by- Patrick Haluptzok [patrickh]
|
|
* Add support for closing journal file.
|
|
*
|
|
* Fri 22-Feb-1991 -by- Patrick Haluptzok [patrickh]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL
|
|
SURFACE::bDeleteSurface()
|
|
{
|
|
BOOL bRet = TRUE;
|
|
|
|
if (!bIsDefault() && bValid())
|
|
{
|
|
HANDLE hSecure = NULL;
|
|
HANDLE hDibSection = NULL;
|
|
PVOID pvBitsBaseOld = NULL;
|
|
|
|
if (iType() == STYPE_BITMAP)
|
|
{
|
|
hSecure = DIB.hSecure;
|
|
hDibSection = DIB.hDIBSection;
|
|
pvBitsBaseOld = pvBitsBase();
|
|
}
|
|
|
|
PDEVOBJ pdo(hdev());
|
|
ULONG iTypeOld = iType();
|
|
DHSURF dhsurfOld = dhsurf();
|
|
PPALETTE ppalOld = ppal();
|
|
EWNDOBJ *pwoDelete = pwo();
|
|
PVOID pvBitsOld = pvBits();
|
|
FLONG fl = fjBitmap();
|
|
|
|
//
|
|
// If the surface is a bitmap, ensure it is not selected into a DC.
|
|
// Also make sure we are the only one with it locked down. These are
|
|
// both tested at once with HmgRemoveObject, because we increment
|
|
// and decrement the alt lock count at the same time we increment
|
|
// and decrement the cRef count on selection and deselection into
|
|
// DCs. Note that surfaces can also be locked for GetDIBits with no
|
|
// DC involvement, so the alt lock count may be higher than the
|
|
// reference count.
|
|
//
|
|
|
|
ASSERTGDI(HmgQueryLock((HOBJ) hGet()) == 0,
|
|
"ERROR cLock != 0 in bDeleteSurface");
|
|
|
|
if (HmgRemoveObject((HOBJ) hGet(), 0, 1, TRUE, SURF_TYPE))
|
|
{
|
|
//
|
|
// If this is a device bitmap tell the device to delete its info.
|
|
//
|
|
|
|
if (iTypeOld == STYPE_DEVBITMAP)
|
|
{
|
|
VACQUIREDEVLOCK(pdo.pDevLock());
|
|
|
|
(*PPFNDRV(pdo,DeleteDeviceBitmap))(dhsurfOld);
|
|
|
|
VRELEASEDEVLOCK(pdo.pDevLock());
|
|
}
|
|
|
|
FREEOBJ(this, SURF_TYPE);
|
|
|
|
//
|
|
// Note, 'this' not set to NULL
|
|
//
|
|
|
|
//
|
|
// For kernel mode, we must unlock the section memory,
|
|
// then free the memory. If the section handle is NULL
|
|
// then we just use NtVirtualFree, otherwise we must
|
|
// use NtUnmapViewOfSection
|
|
//
|
|
|
|
if (hSecure != NULL)
|
|
{
|
|
MmUnsecureVirtualMemory(hSecure);
|
|
|
|
if (pvBitsOld == NULL)
|
|
{
|
|
WARNING("bDeleteSurface: deleting DIB but hSecure or pvBitsOld == NULL");
|
|
}
|
|
else
|
|
{
|
|
if (hDibSection != NULL)
|
|
{
|
|
ZwUnmapViewOfSection(NtCurrentProcess(), pvBitsBaseOld);
|
|
}
|
|
else
|
|
{
|
|
|
|
ULONG ViewSize = 0;
|
|
|
|
ZwFreeVirtualMemory(
|
|
NtCurrentProcess(),
|
|
&pvBitsOld,
|
|
&ViewSize,
|
|
MEM_RELEASE);
|
|
}
|
|
}
|
|
}
|
|
else if (fl & BMF_USERMEM)
|
|
{
|
|
EngFreeUserMem(pvBitsOld);
|
|
}
|
|
else if (fl & BMF_KMSECTION)
|
|
{
|
|
vFreeKernelSection(pvBitsOld);
|
|
}
|
|
|
|
//
|
|
// This DC is going away, the associated WNDOBJ should be deleted.
|
|
// The WNDOBJs for memory bitmap and printer surface are deleted here.
|
|
// The WNDOBJs for display DCs are deleted in DestroyWindow.
|
|
//
|
|
|
|
if (pwoDelete)
|
|
{
|
|
GreDeleteWnd((PVOID) pwoDelete);
|
|
}
|
|
|
|
if (ppalOld != NULL)
|
|
{
|
|
XEPALOBJ pal(ppalOld);
|
|
pal.vUnrefPalette();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// if we can't remove it because it is selected, mark it for lazy deletion
|
|
//
|
|
|
|
if (HmgQueryAltLock((HOBJ)hGet()) != 1)
|
|
{
|
|
vLazyDelete();
|
|
bRet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
WARNING("bDeleteSurface failed, handle busy\n");
|
|
SAVE_ERROR_CODE(ERROR_BUSY);
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return(bRet);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* SURFMEM::DSMEMOBJ
|
|
*
|
|
* Constructor for device surface memory object.
|
|
*
|
|
* History:
|
|
* 13-Feb-1991 -by- Patrick Haluptzok patrickh
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID
|
|
SURFMEM::DSMEMOBJ(DHSURF dhsurfNew)
|
|
{
|
|
//
|
|
// DEVICE SURFACE, Don't allocate EBITMAP and DIB portions of SURFACE
|
|
//
|
|
|
|
SIZE_T AllocSize = offsetof(SURFACE,EBitmap);
|
|
AllocationFlags = SURFACE_DEVSURF;
|
|
|
|
ps = (PSURFACE)ALLOCOBJ(AllocSize, SURF_TYPE, TRUE);
|
|
|
|
if (ps != (SURFACE *)NULL)
|
|
{
|
|
ps->iType(STYPE_DEVICE);
|
|
ps->dhsurf(dhsurfNew);
|
|
|
|
//
|
|
// Because when we allocated the memory we asked for zero
|
|
// initialization, we don't have to explicitly set the following
|
|
// values to zero.
|
|
//
|
|
// Set initial uniqueness. Set 0 because that means don't cache it
|
|
// and we don't support caching of device managed surfaces.
|
|
//
|
|
// ps->iUniq(0);
|
|
// ps->flags(0);
|
|
// ps->pwo((EWNDOBJ *)NULL);
|
|
// ps->pfnBitBlt((PFN_DrvBitBlt)NULL);
|
|
// ps->pfnTextOut((PFN_DrvTextOut)NULL);
|
|
//
|
|
|
|
//
|
|
// Now that the surface is set up, give it a handle
|
|
//
|
|
|
|
if (HmgInsertObject(ps, HMGR_ALLOC_ALT_LOCK, SURF_TYPE) == 0)
|
|
{
|
|
WARNING("SURFACE::DSMEMOBJ failed HmgInsertObject\n");
|
|
FREEOBJ(ps, SURF_TYPE);
|
|
ps = NULL;
|
|
}
|
|
else
|
|
{
|
|
ps->hsurf(ps->hGet());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WARNING("Surface allocation failed\n");
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* SURFMEM::DDBMEMOBJ
|
|
*
|
|
* Constructor for device dependent bitmap memory object
|
|
*
|
|
* History:
|
|
* 29-Jan-1991 -by- Patrick Haluptzok patrickh
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID
|
|
SURFMEM::DDBMEMOBJ(PDEVBITMAPINFO pdbmi, DHSURF dhsurfNew)
|
|
{
|
|
//
|
|
// For DEVICE BITMAP, allocate all of SURFACE except DIB portion
|
|
//
|
|
|
|
SIZE_T AllocSize = offsetof(SURFACE,DIB);
|
|
AllocationFlags = SURFACE_DDB;
|
|
|
|
ps = (PSURFACE)ALLOCOBJ(AllocSize, SURF_TYPE, TRUE);
|
|
|
|
if (ps != NULL)
|
|
{
|
|
//
|
|
// Initialize the surf fields
|
|
//
|
|
|
|
SIZEL sizlTemp;
|
|
|
|
ps->dhsurf(dhsurfNew);
|
|
sizlTemp.cx = pdbmi->cxBitmap;
|
|
sizlTemp.cy = pdbmi->cyBitmap;
|
|
ps->sizl(sizlTemp);
|
|
ps->iType(STYPE_DEVBITMAP);
|
|
ps->fjBitmap(pdbmi->fl);
|
|
ps->iFormat(pdbmi->iFormat);
|
|
|
|
//
|
|
// Because when we allocated the memory we asked for zero
|
|
// initialization, we don't have to explicitly set the following
|
|
// values to zero.
|
|
//
|
|
// Cache pointers to heavily used functions
|
|
//
|
|
// Initialize the BITMAP fields
|
|
//
|
|
// Set initial uniqueness. Set 0 because that means don't cache it
|
|
// and we don't support caching of device managed surfaces.
|
|
//
|
|
// ps->flags(0);
|
|
// ps->pwo((EWNDOBJ *) NULL);
|
|
// ps->hdev((HDEV) 0);
|
|
// ps->pfnBitBlt(0);
|
|
// ps->pfnTextOut(0);
|
|
// sizlTemp.cx = 0;
|
|
// sizlTemp.cy = 0;
|
|
// ps->sizlDim(sizlTemp);
|
|
// ps->EBitmap.hdc = (HDC) 0;
|
|
// ps->EBitmap.cRef = 0;
|
|
// ps->ppal((PPALETTE) NULL);
|
|
// ps->iUniq(0);
|
|
// ps->pvBits(NULL);
|
|
// ps->cjBits(0);
|
|
// ps->lDelta(0);
|
|
// ps->pvScan0(NULL);
|
|
//
|
|
|
|
//
|
|
// Now that the surface is set up, give it a handle
|
|
//
|
|
|
|
if (HmgInsertObject(ps, HMGR_ALLOC_ALT_LOCK, SURF_TYPE) == 0)
|
|
{
|
|
WARNING("SURMEM::DDBMEMOBJ failed HmgInsertObject\n");
|
|
FREEOBJ(ps, SURF_TYPE);
|
|
ps = NULL;
|
|
}
|
|
else
|
|
{
|
|
ps->hsurf(ps->hGet());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WARNING("DDB allocation failed\n");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* SURFMEM::bCreateDIB
|
|
*
|
|
* Constructor for device independent bitmap memory object
|
|
*
|
|
* History:
|
|
* Mon 18-May-1992 -by- Patrick Haluptzok [patrickh]
|
|
* return BOOL
|
|
*
|
|
* 28-Jan-1991 -by- Patrick Haluptzok patrickh
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL
|
|
SURFMEM::bCreateDIB(
|
|
PDEVBITMAPINFO pdbmi,
|
|
PVOID pvBitsIn,
|
|
HANDLE hDIBSection,
|
|
DWORD dsOffset,
|
|
HANDLE hSecure
|
|
)
|
|
{
|
|
BOOL bRet = TRUE;
|
|
|
|
AllocationFlags = SURFACE_DIB;
|
|
ps = (PSURFACE) NULL;
|
|
FLONG flAllocateSection = 0;
|
|
|
|
//
|
|
// Figure out the length of a scanline
|
|
//
|
|
|
|
ULONG cjScanTemp;
|
|
|
|
switch(pdbmi->iFormat)
|
|
{
|
|
case BMF_1BPP:
|
|
cjScanTemp = ((pdbmi->cxBitmap + 31) & ~31) >> 3;
|
|
break;
|
|
|
|
case BMF_4BPP:
|
|
cjScanTemp = ((pdbmi->cxBitmap + 7) & ~7) >> 1;
|
|
break;
|
|
|
|
case BMF_8BPP:
|
|
cjScanTemp = (pdbmi->cxBitmap + 3) & ~3;
|
|
break;
|
|
|
|
case BMF_16BPP:
|
|
cjScanTemp = ((pdbmi->cxBitmap + 1) & ~1) << 1;
|
|
break;
|
|
|
|
case BMF_24BPP:
|
|
cjScanTemp = ((pdbmi->cxBitmap * 3) + 3) & ~3;
|
|
break;
|
|
|
|
case BMF_32BPP:
|
|
cjScanTemp = pdbmi->cxBitmap << 2;
|
|
break;
|
|
|
|
case BMF_8RLE:
|
|
case BMF_4RLE:
|
|
break;
|
|
|
|
default:
|
|
WARNING("ERROR: DIBMEMOBJ failed INVALID BITMAP FORMAT \n");
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// If we are given a pointer to bits, then only allocate a DIB header.
|
|
// Otherwise allocate space for the header and the required bits.
|
|
//
|
|
|
|
SIZE_T size = (SIZE_T) sizeof(SURFACE);
|
|
|
|
FSHORT fsAlloc = HMGR_ALLOC_ALT_LOCK|HMGR_NO_ZERO_INIT;
|
|
|
|
if (pvBitsIn == (PVOID) NULL)
|
|
{
|
|
LONGLONG eq = Int32x32To64(pdbmi->cyBitmap, cjScanTemp);
|
|
|
|
eq += (LONGLONG) (ULONGLONG) size;
|
|
|
|
if (eq > LONG_MAX)
|
|
{
|
|
WARNING("Attempting to allocate > 4Gb\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
// see if we need to allocate the bits out of USER memory
|
|
|
|
if (pdbmi->fl & BMF_USERMEM)
|
|
{
|
|
pvBitsIn = EngAllocUserMem((LONG) eq,'mbuG'); //Gubm
|
|
|
|
if (pvBitsIn == NULL)
|
|
return(FALSE);
|
|
}
|
|
else if (eq > KM_SIZE_MAX)
|
|
{
|
|
//
|
|
// try first to use KMsection
|
|
//
|
|
|
|
pvBitsIn = pvAllocateKernelSection((SIZE_T)eq,'mbkG');
|
|
|
|
if (pvBitsIn != NULL)
|
|
{
|
|
//
|
|
// mark surface as KM SECTION
|
|
//
|
|
|
|
flAllocateSection = BMF_KMSECTION;
|
|
}
|
|
}
|
|
|
|
//
|
|
// combine size and allocate from pool
|
|
//
|
|
|
|
if (pvBitsIn == NULL)
|
|
{
|
|
size = (SIZE_T) ((LONG) eq);
|
|
|
|
if ((pdbmi->fl & BMF_NOZEROINIT) == 0)
|
|
{
|
|
fsAlloc = HMGR_ALLOC_ALT_LOCK;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ASSERTGDI(!(pdbmi->fl & BMF_USERMEM),"bCreateDIB - flags error\n");
|
|
}
|
|
|
|
ps = (PSURFACE)ALLOCOBJ(size,SURF_TYPE,!(fsAlloc & HMGR_NO_ZERO_INIT));
|
|
|
|
if (ps == NULL)
|
|
{
|
|
WARNING("DIBMEMOBJ failed memory alloc\n");
|
|
bRet = FALSE;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Initialize the surf fields
|
|
//
|
|
|
|
SIZEL sizlTemp;
|
|
sizlTemp.cx = pdbmi->cxBitmap;
|
|
sizlTemp.cy = pdbmi->cyBitmap;
|
|
ps->sizl(sizlTemp);
|
|
ps->iType(STYPE_BITMAP);
|
|
ps->pfnBitBlt(EngBitBlt);
|
|
ps->pfnTextOut(EngTextOut);
|
|
|
|
if (pdbmi->hpal != (HPALETTE) 0)
|
|
{
|
|
EPALOBJ palSurf(pdbmi->hpal);
|
|
ASSERTGDI(palSurf.bValid(), "ERROR invalid palette DIBMEMOBJ");
|
|
|
|
//
|
|
// Set palette into surface.
|
|
//
|
|
|
|
ps->ppal(palSurf.ppalGet());
|
|
|
|
//
|
|
// Reference count it by making sure it is not unlocked.
|
|
//
|
|
|
|
palSurf.ppalSet((PPALETTE) NULL); // It won't be unlocked
|
|
}
|
|
else
|
|
{
|
|
ps->ppal((PPALETTE) NULL);
|
|
}
|
|
|
|
//
|
|
// Initialize the BITMAP fields
|
|
//
|
|
|
|
ps->iFormat(pdbmi->iFormat);
|
|
|
|
ps->fjBitmap(
|
|
(pdbmi->fl | flAllocateSection) &
|
|
(BMF_TOPDOWN | BMF_USERMEM | BMF_KMSECTION)
|
|
);
|
|
|
|
ps->DIB.hDIBSection = hDIBSection;
|
|
ps->DIB.dwOffset = dsOffset;
|
|
ps->DIB.hSecure = hSecure;
|
|
|
|
ps->dhsurf((DHSURF) 0);
|
|
ps->dhpdev((DHPDEV) 0);
|
|
ps->flags(0);
|
|
ps->pwo((EWNDOBJ *) NULL);
|
|
sizlTemp.cx = 0;
|
|
sizlTemp.cy = 0;
|
|
ps->sizlDim(sizlTemp);
|
|
ps->hdev((HDEV) 0);
|
|
ps->EBitmap.hdc = (HDC) 0;
|
|
ps->EBitmap.cRef = 0;
|
|
ps->EBitmap.hpalHint = 0;
|
|
ps->pdcoAA = NULL;
|
|
|
|
if (hSecure != (HANDLE) NULL)
|
|
{
|
|
//
|
|
// Set flag for DIBSECTION so driver doesn't cache it.
|
|
// because we don't know to increment the uniqueness
|
|
// when the app writes on it.
|
|
//
|
|
|
|
ps->so.fjBitmap |= BMF_DONTCACHE;
|
|
}
|
|
|
|
//
|
|
// Initialize the DIB fields
|
|
//
|
|
|
|
if (pvBitsIn == (PVOID) NULL)
|
|
{
|
|
ps->pvBits((PVOID) (((ULONG) ps) + sizeof(SURFACE)));
|
|
}
|
|
else
|
|
{
|
|
ps->pvBits(pvBitsIn);
|
|
}
|
|
|
|
if ((pdbmi->iFormat != BMF_8RLE) &&
|
|
(pdbmi->iFormat != BMF_4RLE))
|
|
{
|
|
ps->cjBits(pdbmi->cyBitmap * cjScanTemp);
|
|
|
|
if (pdbmi->fl & BMF_TOPDOWN)
|
|
{
|
|
ps->lDelta(cjScanTemp);
|
|
ps->pvScan0(ps->pvBits());
|
|
}
|
|
else
|
|
{
|
|
ps->lDelta(-(LONG)cjScanTemp);
|
|
ps->pvScan0((PVOID) (((PBYTE) ps->pvBits()) +
|
|
(ps->cjBits() - cjScanTemp)));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// lDelta is 0 because RLE's don't have scanlines.
|
|
//
|
|
|
|
ps->cjBits(pdbmi->cjBits);
|
|
ps->pvScan0(ps->pvBits());
|
|
ps->lDelta(0);
|
|
}
|
|
|
|
//
|
|
// Set initial uniqueness. Not 0 because that means don't cache it.
|
|
//
|
|
|
|
ps->iUniq(1);
|
|
|
|
//
|
|
// Now that the surface is set up, give it a handle
|
|
//
|
|
|
|
if (HmgInsertObject(ps, fsAlloc, SURF_TYPE) == 0)
|
|
{
|
|
WARNING("bCreateDIB failed HmgInsertObject\n");
|
|
FREEOBJ(ps, SURF_TYPE);
|
|
ps = NULL;
|
|
bRet = FALSE;
|
|
}
|
|
else
|
|
{
|
|
ps->hsurf(ps->hGet());
|
|
}
|
|
}
|
|
|
|
//
|
|
// cleanup in failure case
|
|
//
|
|
|
|
if (!bRet && pvBitsIn)
|
|
{
|
|
if (pdbmi->fl & BMF_USERMEM)
|
|
{
|
|
EngFreeUserMem(pvBitsIn);
|
|
}
|
|
else if (flAllocateSection & BMF_KMSECTION)
|
|
{
|
|
vFreeKernelSection(pvBitsIn);
|
|
}
|
|
}
|
|
|
|
return(bRet);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* SURFMEM::~SURFMEM
|
|
*
|
|
* Description:
|
|
*
|
|
* SURFACE Destructor, takes appropriate action based
|
|
* on allocation flags
|
|
*
|
|
\**************************************************************************/
|
|
SURFMEM::~SURFMEM()
|
|
{
|
|
|
|
if (ps != (SURFACE*) NULL)
|
|
{
|
|
//
|
|
// what type of surface
|
|
//
|
|
|
|
if (AllocationFlags & SURFACE_KEEP)
|
|
{
|
|
|
|
DEC_SHARE_REF_CNT(ps);
|
|
|
|
} else {
|
|
|
|
if (AllocationFlags & SURFACE_DIB)
|
|
{
|
|
//
|
|
// free selected palette
|
|
//
|
|
|
|
if (ps->ppal() != NULL)
|
|
{
|
|
XEPALOBJ pal(ps->ppal());
|
|
pal.vUnrefPalette();
|
|
}
|
|
}
|
|
|
|
//
|
|
// remove object from hmgr and free
|
|
//
|
|
|
|
if (!HmgRemoveObject((HOBJ) ps->hGet(), 0, 1, TRUE, SURF_TYPE))
|
|
{
|
|
ASSERTGDI(TRUE, "Failed to remove object in ~DIBMEMOBJ");
|
|
}
|
|
|
|
PVOID pvBitsOld = ps->pvBits();
|
|
FLONG fl = ps->fjBitmap();
|
|
|
|
FREEOBJ(ps, SURF_TYPE);
|
|
|
|
if (fl & BMF_USERMEM)
|
|
{
|
|
RIP("SURFMEM destructor has BMF_USERMEM set\n");
|
|
}
|
|
else if (fl & BMF_KMSECTION)
|
|
{
|
|
vFreeKernelSection(pvBitsOld);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#if DBG
|
|
void SURFACE::vDump()
|
|
{
|
|
DbgPrint("SURFACE @ %-#x\n", this);
|
|
DbgPrint(" so.dhsurf = %-#x\n" , so.dhsurf);
|
|
DbgPrint(" so.hsurf = %-#x\n" , so.hsurf);
|
|
DbgPrint(" so.dhpdev = %-#x\n" , so.dhpdev);
|
|
DbgPrint(" so.hdev = %-#x\n" , so.hdev);
|
|
DbgPrint(" so.sizlBitmap = %u %u\n" , so.sizlBitmap.cx , so.sizlBitmap.cy);
|
|
DbgPrint(" so.cjBits = %u\n" , so.cjBits);
|
|
DbgPrint(" so.pvBits = %-#x\n" , so.pvBits);
|
|
DbgPrint(" so.pvScan0 = %-#x\n" , so.pvScan0);
|
|
DbgPrint(" so.lDelta = %d\n" , so.lDelta);
|
|
DbgPrint(" so.iUniq = %u\n" , so.iUniq);
|
|
DbgPrint(" so.iBitmapFormat = %u\n" , so.iBitmapFormat);
|
|
DbgPrint(" so.iType = %u\n" , so.iType);
|
|
DbgPrint(" so.fjBitmap = %-#x\n" , so.fjBitmap);
|
|
|
|
|
|
DbgPrint(" SurfFlags = %-#x\n" , SurfFlags);
|
|
DbgPrint(" pPal = %-#x\n" , pPal);
|
|
DbgPrint(" pWo = %-#x\n" , pWo);
|
|
DbgPrint(" pFnBitBlt = %-#x\n" , pFnBitBlt);
|
|
DbgPrint(" pFnTextOut = %-#x\n" , pFnTextOut);
|
|
DbgPrint(" EBitmap.sizlDim = %u %u\n" , EBitmap.sizlDim.cx, EBitmap.sizlDim.cy);
|
|
DbgPrint(" EBitmap.hdc = %-#x\n" , EBitmap.hdc);
|
|
DbgPrint(" EBitmap.cRef = %-#x\n" , EBitmap.cRef);
|
|
DbgPrint(" DIB.hDIBSection = %-#x\n" , DIB.hDIBSection);
|
|
DbgPrint(" DIB.hSecure = %-#x\n" , DIB.hSecure);
|
|
|
|
}
|
|
#endif
|