[PATCH] gdi32: Don't free bitmap memory pointer in D3DKMTDestroyDCFromMemory().

Paul Gofman gofmanp at gmail.com
Tue Mar 24 12:42:57 CDT 2020


Signed-off-by: Paul Gofman <gofmanp at gmail.com>
---
 dlls/gdi32/dib.c          | 14 +++++++++++++-
 dlls/gdi32/tests/bitmap.c | 27 +++++++++++++++++++++++++++
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c
index 3d267ba89c..f33c198ae1 100644
--- a/dlls/gdi32/dib.c
+++ b/dlls/gdi32/dib.c
@@ -1706,12 +1706,21 @@ error:
  */
 NTSTATUS WINAPI D3DKMTDestroyDCFromMemory( const D3DKMT_DESTROYDCFROMMEMORY *desc )
 {
+    BITMAPOBJ *bmp;
+
     if (!desc) return STATUS_INVALID_PARAMETER;
 
     TRACE("dc %p, bitmap %p.\n", desc->hDc, desc->hBitmap);
 
     if (GetObjectType( desc->hDc ) != OBJ_MEMDC ||
         GetObjectType( desc->hBitmap ) != OBJ_BITMAP) return STATUS_INVALID_PARAMETER;
+
+    if (!(bmp = GDI_GetObjPtr( desc->hBitmap, OBJ_BITMAP )))
+        return STATUS_INVALID_PARAMETER;
+
+    bmp->dib.dsBm.bmBits = NULL;
+    GDI_ReleaseObj( desc->hBitmap );
+
     DeleteObject( desc->hBitmap );
     DeleteDC( desc->hDc );
 
@@ -1828,7 +1837,10 @@ static BOOL DIB_DeleteObject( HGDIOBJ handle )
         UnmapViewOfFile( (char *)bmp->dib.dsBm.bmBits -
                          (bmp->dib.dsOffset % SystemInfo.dwAllocationGranularity) );
     }
-    else VirtualFree( bmp->dib.dsBm.bmBits, 0, MEM_RELEASE );
+    else if (bmp->dib.dsBm.bmBits)
+    {
+        VirtualFree( bmp->dib.dsBm.bmBits, 0, MEM_RELEASE );
+    }
 
     HeapFree(GetProcessHeap(), 0, bmp->color_table);
     HeapFree( GetProcessHeap(), 0, bmp );
diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c
index fe3482671b..ff04b4012c 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -5680,6 +5680,7 @@ static void test_D3DKMTCreateDCFromMemory( void )
 {
     D3DKMT_DESTROYDCFROMMEMORY destroy_desc;
     D3DKMT_CREATEDCFROMMEMORY create_desc;
+    MEMORY_BASIC_INFORMATION mbi;
     unsigned int width_bytes;
     unsigned int i, x, y, z;
     DWORD expected, colour;
@@ -5692,6 +5693,7 @@ static void test_D3DKMTCreateDCFromMemory( void )
     int size;
     HDC bmp_dc;
     HBITMAP bmp;
+    SIZE_T len;
 
     static const struct
     {
@@ -5933,6 +5935,31 @@ static void test_D3DKMTCreateDCFromMemory( void )
         DeleteObject( SelectObject( bmp_dc, bmp ) );
         DeleteDC( bmp_dc );
     }
+
+    create_desc.pMemory = VirtualAlloc(NULL, 0x10000, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+    create_desc.Format = D3DDDIFMT_A8R8G8B8;
+    create_desc.Width = 16;
+    create_desc.Height = 16;
+    create_desc.Pitch = 16 * 4;
+    create_desc.hDeviceDc = CreateCompatibleDC(NULL);
+    create_desc.pColorTable = NULL;
+
+    status = pD3DKMTCreateDCFromMemory(&create_desc);
+    ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
+    DeleteDC(create_desc.hDeviceDc);
+
+    destroy_desc.hDc = create_desc.hDc;
+    destroy_desc.hBitmap = create_desc.hBitmap;
+    status = pD3DKMTDestroyDCFromMemory( &destroy_desc );
+    ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
+
+    memset(&mbi, 0, sizeof(mbi));
+    len = VirtualQuery(create_desc.pMemory, &mbi, sizeof(mbi));
+    ok(len == sizeof(mbi), "Got unexpected len %lu.\n", len);
+    ok(mbi.Protect == PAGE_READWRITE && mbi.RegionSize == 0x10000,
+            "Got unexpected memory state, protect %#x, RegionSize %#lx.\n",
+            mbi.Protect, mbi.RegionSize);
+    VirtualFree(create_desc.pMemory, 0, MEM_RELEASE);
 }
 
 START_TEST(bitmap)
-- 
2.25.1




More information about the wine-devel mailing list