From: Paul Gofman Subject: [PATCH] gdi32: Don't free bitmap memory pointer in D3DKMTDestroyDCFromMemory(). Message-Id: <20200324174257.128772-1-gofmanp@gmail.com> Date: Tue, 24 Mar 2020 20:42:57 +0300 Signed-off-by: Paul Gofman --- 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