Author: tkreuzer
Date: Fri Feb 17 15:51:13 2012
New Revision: 55671
URL:
http://svn.reactos.org/svn/reactos?rev=55671&view=rev
Log:
[WIN32K]
Fix another bug in NtGdiSelectBitmap, where selecting the same bitmap a second time, would
release the bitmap
Modified:
trunk/reactos/subsystems/win32/win32k/objects/dcobjs.c
Modified: trunk/reactos/subsystems/win32/win32k/objects/dcobjs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/dcobjs.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/dcobjs.c [iso-8859-1] Fri Feb 17
15:51:13 2012
@@ -261,11 +261,9 @@
IN HBITMAP hbmp)
{
PDC pdc;
- PDC_ATTR pdcattr;
HBITMAP hbmpOld;
PSURFACE psurfNew, psurfOld;
HRGN hVisRgn;
- SIZEL sizlBitmap = {1, 1};
HDC hdcOld;
ASSERT_NOGDILOCKS();
@@ -278,7 +276,6 @@
{
return NULL;
}
- pdcattr = pdc->pdcattr;
/* Must be a memory dc to select a bitmap */
if (pdc->dctype != DC_TYPE_MEMORY)
@@ -290,10 +287,34 @@
/* Save the old bitmap */
psurfOld = pdc->dclevel.pSurface;
+ /* Check if there is a bitmap selected */
+ if (psurfOld)
+ {
+ /* Get the old bitmap's handle */
+ hbmpOld = psurfOld->BaseObject.hHmgr;
+ }
+ else
+ {
+ /* Use the default bitmap */
+ hbmpOld = StockObjects[DEFAULT_BITMAP];
+ }
+
+ /* Check if the new bitmap is already selected */
+ if (hbmp == hbmpOld)
+ {
+ /* Unlock the DC and return the old bitmap */
+ DC_UnlockDc(pdc);
+ return hbmpOld;
+ }
+
/* Check if the default bitmap was passed */
if (hbmp == StockObjects[DEFAULT_BITMAP])
{
psurfNew = NULL;
+
+ /* Default bitmap is 1x1 pixel */
+ pdc->dclevel.sizl.cx = 1;
+ pdc->dclevel.sizl.cy = 1;
// HACK
psurfNew = SURFACE_ShareLockSurface(hbmp);
@@ -308,28 +329,32 @@
return NULL;
}
- /* Set the bitmp's hdc */
+ /* Set the bitmap's hdc and check if it was set before */
hdcOld = InterlockedCompareExchangePointer((PVOID*)&psurfNew->hdc, hdc,
0);
- if (hdcOld != NULL && hdcOld != hdc)
- {
- /* The bitmap is already selected, fail */
+ if (hdcOld != NULL)
+ {
+ /* The bitmap is already selected into a different DC */
+ ASSERT(hdcOld != hdc);
+
+ /* Dereference the bitmap, unlock the DC and fail. */
SURFACE_ShareUnlockSurface(psurfNew);
DC_UnlockDc(pdc);
return NULL;
}
- /* Get the bitmap size */
- sizlBitmap = psurfNew->SurfObj.sizlBitmap;
+ /* Copy the bitmap size */
+ pdc->dclevel.sizl = psurfNew->SurfObj.sizlBitmap;
/* Check if the bitmap is a dibsection */
if(psurfNew->hSecure)
{
/* Set DIBSECTION attribute */
- pdcattr->ulDirty_ |= DC_DIBSECTION;
+ pdc->pdcattr->ulDirty_ |= DC_DIBSECTION;
}
else
{
- pdcattr->ulDirty_ &= ~DC_DIBSECTION;
+ /* Remove DIBSECTION attribute */
+ pdc->pdcattr->ulDirty_ &= ~DC_DIBSECTION;
}
}
@@ -339,37 +364,30 @@
/* Check if there was a bitmap selected before */
if (psurfOld)
{
- /* Get the old bitmap's handle */
- hbmpOld = psurfOld->BaseObject.hHmgr;
-
- /* Reset hdc of the old bitmap,it isn't selected anymore */
+ /* Reset hdc of the old bitmap, it isn't selected anymore */
psurfOld->hdc = NULL;
/* Dereference the old bitmap */
SURFACE_ShareUnlockSurface(psurfOld);
}
- else
- {
- /* Return default bitmap */
- hbmpOld = StockObjects[DEFAULT_BITMAP];
- }
/* Mark the dc brushes invalid */
- pdcattr->ulDirty_ |= DIRTY_FILL | DIRTY_LINE;
-
- /* Unlock the DC */
- DC_UnlockDc(pdc);
+ pdc->pdcattr->ulDirty_ |= DIRTY_FILL | DIRTY_LINE;
/* FIXME: Improve by using a region without a handle and selecting it */
hVisRgn = IntSysCreateRectRgn( 0,
0,
- sizlBitmap.cx,
- sizlBitmap.cy);
+ pdc->dclevel.sizl.cx,
+ pdc->dclevel.sizl.cy);
+
if (hVisRgn)
{
GdiSelectVisRgn(hdc, hVisRgn);
GreDeleteObject(hVisRgn);
}
+
+ /* Unlock the DC */
+ DC_UnlockDc(pdc);
/* Return the old bitmap handle */
return hbmpOld;