From 182a2cbf47a8562a43db6bdc8bd29e0980a9ddcd Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Thu, 21 Apr 2016 14:40:58 +0800
Subject: oleaut32: OleLoadPicture should create a DIB section for a being
 loaded bitmap. (v3)

Application in the bug 39474 depends on this (GetObject/bmBits should not be
NULL, otherwise it crashes).
---
 dlls/oleaut32/olepicture.c       | 65 ++++++++++++++++------------------------
 dlls/oleaut32/tests/olepicture.c |  2 +-
 2 files changed, 27 insertions(+), 40 deletions(-)

diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c
index bfca22f..1b6fb2c 100644
--- a/dlls/oleaut32/olepicture.c
+++ b/dlls/oleaut32/olepicture.c
@@ -999,23 +999,16 @@ static HRESULT OLEPictureImpl_LoadDIB(OLEPictureImpl *This, BYTE *xbuf, ULONG xr
 {
     BITMAPFILEHEADER	*bfh = (BITMAPFILEHEADER*)xbuf;
     BITMAPINFO		*bi = (BITMAPINFO*)(bfh+1);
-    HDC			hdcref;
+    void *bits;
+    BITMAP bmp;
 
-    /* Does not matter whether this is a coreheader or not, we only use
-     * components which are in both
-     */
-    hdcref = GetDC(0);
-    This->desc.u.bmp.hbitmap = CreateDIBitmap(
-	hdcref,
-	&(bi->bmiHeader),
-	CBM_INIT,
-	xbuf+bfh->bfOffBits,
-	bi,
-       DIB_RGB_COLORS
-    );
-    ReleaseDC(0, hdcref);
+    This->desc.u.bmp.hbitmap = CreateDIBSection(0, bi, DIB_RGB_COLORS, &bits, NULL, 0);
     if (This->desc.u.bmp.hbitmap == 0)
         return E_FAIL;
+
+    GetObjectA(This->desc.u.bmp.hbitmap, sizeof(bmp), &bmp);
+    memcpy(bits, xbuf + bfh->bfOffBits, bmp.bmHeight * bmp.bmWidthBytes);
+
     This->desc.picType = PICTYPE_BITMAP;
     OLEPictureImpl_SetBitmap(This);
     return S_OK;
@@ -1025,10 +1018,9 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour
 {
     HRESULT hr;
     BITMAPINFOHEADER bih;
-    HDC hdcref;
     UINT width, height;
     UINT stride, buffersize;
-    LPBYTE bits=NULL;
+    BYTE *bits, *mask = NULL;
     WICRect rc;
     IWICBitmapSource *real_source;
     UINT x, y;
@@ -1056,34 +1048,28 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour
     stride = 4 * width;
     buffersize = stride * height;
 
-    bits = HeapAlloc(GetProcessHeap(), 0, buffersize);
-    if (!bits)
+    mask = HeapAlloc(GetProcessHeap(), 0, buffersize);
+    if (!mask)
     {
         hr = E_OUTOFMEMORY;
         goto end;
     }
 
+    This->desc.u.bmp.hbitmap = CreateDIBSection(0, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void **)&bits, NULL, 0);
+    if (This->desc.u.bmp.hbitmap == 0)
+    {
+        hr = E_FAIL;
+        goto end;
+    }
+
     rc.X = 0;
     rc.Y = 0;
     rc.Width = width;
     rc.Height = height;
     hr = IWICBitmapSource_CopyPixels(real_source, &rc, stride, buffersize, bits);
     if (FAILED(hr))
-        goto end;
-
-    hdcref = GetDC(0);
-    This->desc.u.bmp.hbitmap = CreateDIBitmap(
-        hdcref,
-        &bih,
-        CBM_INIT,
-        bits,
-        (BITMAPINFO*)&bih,
-        DIB_RGB_COLORS);
-
-    if (This->desc.u.bmp.hbitmap == 0)
     {
-        hr = E_FAIL;
-        ReleaseDC(0, hdcref);
+        DeleteObject(This->desc.u.bmp.hbitmap);
         goto end;
     }
 
@@ -1097,23 +1083,25 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour
             if((*pixel & 0x80000000) == 0)
             {
                 has_alpha = TRUE;
-                *pixel = black;
+                *(DWORD *)(mask + stride * y + 4 * x) = black;
             }
             else
-                *pixel = white;
+                *(DWORD *)(mask + stride * y + 4 * x) = white;
         }
     }
 
     if (has_alpha)
     {
-        HDC hdcBmp, hdcXor, hdcMask;
+        HDC hdcref, hdcBmp, hdcXor, hdcMask;
         HBITMAP hbmoldBmp, hbmoldXor, hbmoldMask;
 
+        hdcref = GetDC(0);
+
         This->hbmXor = CreateDIBitmap(
             hdcref,
             &bih,
             CBM_INIT,
-            bits,
+            mask,
             (BITMAPINFO*)&bih,
             DIB_RGB_COLORS
         );
@@ -1138,12 +1126,11 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour
         DeleteDC(hdcBmp);
         DeleteDC(hdcXor);
         DeleteDC(hdcMask);
+        ReleaseDC(0, hdcref);
     }
 
-    ReleaseDC(0, hdcref);
-
 end:
-    HeapFree(GetProcessHeap(), 0, bits);
+    HeapFree(GetProcessHeap(), 0, mask);
     IWICBitmapSource_Release(real_source);
     return hr;
 }
diff --git a/dlls/oleaut32/tests/olepicture.c b/dlls/oleaut32/tests/olepicture.c
index b716f25..795ee71 100644
--- a/dlls/oleaut32/tests/olepicture.c
+++ b/dlls/oleaut32/tests/olepicture.c
@@ -240,7 +240,7 @@ test_pic_with_stream(LPSTREAM stream, unsigned int imgsize)
         {
             BITMAP bmp;
             GetObjectA(UlongToHandle(handle), sizeof(BITMAP), &bmp);
-            todo_wine ok(bmp.bmBits != 0, "not a dib\n");
+            ok(bmp.bmBits != 0, "not a dib\n");
         }
 
 	width = 0;
-- 
2.9.0