[OLEAUT32_WINETEST] Sync with Wine Staging 2.9. CORE-13362
[reactos.git] / rostests / winetests / oleaut32 / olepicture.c
index df99547..1b8e395 100644 (file)
@@ -102,7 +102,7 @@ static const unsigned char pngimage[285] = {
 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
 };
 
-/* 1x1 pixel bmp */
+/* 1bpp BI_RGB 1x1 pixel bmp */
 static const unsigned char bmpimage[66] = {
 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
@@ -111,6 +111,15 @@ static const unsigned char bmpimage[66] = {
 0x00,0x00
 };
 
+/* 8bpp BI_RLE8 1x1 pixel bmp */
+static const unsigned char bmpimage_rle8[] = {
+0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
+0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x01,0x00,
+0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
+0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x01,
+0x00,0x00
+};
+
 /* 2x2 pixel gif */
 static const unsigned char gif4pixel[42] = {
 0x47,0x49,0x46,0x38,0x37,0x61,0x02,0x00,0x02,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
@@ -173,6 +182,25 @@ static const unsigned char enhmetafile[] = {
     0x14, 0x00, 0x00, 0x00
 };
 
+static HBITMAP stock_bm;
+
+static HDC create_render_dc( void )
+{
+    HDC dc = CreateCompatibleDC( NULL );
+    BITMAPINFO info = {{sizeof(info.bmiHeader), 100, 100, 1, 32, BI_RGB }};
+    void *bits;
+    HBITMAP dib = CreateDIBSection( NULL, &info, DIB_RGB_COLORS, &bits, NULL, 0 );
+
+    stock_bm = SelectObject( dc, dib );
+    return dc;
+}
+
+static void delete_render_dc( HDC dc )
+{
+    HBITMAP dib = SelectObject( dc, stock_bm );
+    DeleteObject( dib );
+    DeleteDC( dc );
+}
 
 typedef struct NoStatStreamImpl
 {
@@ -225,7 +253,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;
@@ -484,7 +512,7 @@ static void test_Invoke(void)
     ok(hr == DISP_E_BADPARAMCOUNT, "IPictureDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
 
     /* DISPID_PICT_RENDER */
-    hdc = GetDC(0);
+    hdc = create_render_dc();
 
     for (i = 0; i < sizeof(args)/sizeof(args[0]); i++)
         V_VT(&args[i]) = VT_I4;
@@ -520,7 +548,7 @@ static void test_Invoke(void)
     hr = IPictureDisp_Invoke(picdisp, DISPID_PICT_RENDER, &GUID_NULL, 0, DISPATCH_METHOD, &dispparams, &varresult, NULL, NULL);
     ok(hr == DISP_E_BADPARAMCOUNT, "got 0x%08x\n", hr);
 
-    ReleaseDC(NULL, hdc);
+    delete_render_dc(hdc);
     IPictureDisp_Release(picdisp);
 }
 
@@ -564,11 +592,6 @@ static void test_apm(void)
     BOOL keep;
     short type;
 
-    if(!winetest_interactive) {
-        skip("ROSTESTS-2: oleaut_winetest:olepicture crashes with Page Fault.\n");
-        return;
-    }
-
     hglob = GlobalAlloc (0, sizeof(apmdata));
     data = GlobalLock(hglob);
     memcpy(data, apmdata, sizeof(apmdata));
@@ -625,11 +648,6 @@ static void test_enhmetafile(void)
     BOOL keep;
     short type;
 
-    if(!winetest_interactive) {
-        skip("ROSTESTS-2: oleaut_winetest:olepicture crashes with Page Fault.\n");
-        return;
-    }
-
     hglob = GlobalAlloc (0, sizeof(enhmetafile));
     data = GlobalLock(hglob);
     memcpy(data, enhmetafile, sizeof(enhmetafile));
@@ -714,7 +732,7 @@ static void test_Render(void)
     OLE_XSIZE_HIMETRIC pWidth;
     OLE_YSIZE_HIMETRIC pHeight;
     COLORREF result, expected;
-    HDC hdc = GetDC(0);
+    HDC hdc = create_render_dc();
 
     /* test IPicture::Render return code on uninitialized picture */
     OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic);
@@ -746,7 +764,7 @@ static void test_Render(void)
     desc.u.icon.hicon = LoadIconA(NULL, (LPCSTR)IDI_APPLICATION);
     if(!desc.u.icon.hicon){
         win_skip("LoadIcon failed. Skipping...\n");
-        ReleaseDC(NULL, hdc);
+        delete_render_dc(hdc);
         return;
     }
 
@@ -779,27 +797,22 @@ static void test_Render(void)
     hres = picture_render(pic, hdc, 1, 1, 9, 9, 0, 0, pWidth, -pHeight, NULL);
     ole_expect(hres, S_OK);
 
-    if(hres != S_OK) {
-        IPicture_Release(pic);
-        ReleaseDC(NULL, hdc);
-        return;
-    }
+    if(hres != S_OK) goto done;
 
     /* Evaluate the rendered Icon */
     result = GetPixel(hdc, 0, 0);
     ok(result == expected,
        "Color at 0,0 should be unchanged 0x%06X, but was 0x%06X\n", expected, result);
     result = GetPixel(hdc, 5, 5);
-    ok(result != expected ||
-        broken(result == expected), /* WinNT 4.0 and older may claim they drew */
-                                    /* the icon, even if they didn't. */
+    ok(result != expected,
        "Color at 5,5 should have changed, but still was 0x%06X\n", expected);
     result = GetPixel(hdc, 10, 10);
     ok(result == expected,
        "Color at 10,10 should be unchanged 0x%06X, but was 0x%06X\n", expected, result);
 
+done:
     IPicture_Release(pic);
-    ReleaseDC(NULL, hdc);
+    delete_render_dc(hdc);
 }
 
 static void test_get_Attributes(void)
@@ -864,6 +877,7 @@ static void test_OleLoadPicturePath(void)
     HANDLE file;
     DWORD size;
     WCHAR *ptr;
+    VARIANT var;
 
     const struct
     {
@@ -930,6 +944,14 @@ static void test_OleLoadPicturePath(void)
     if (pic)
         IPicture_Release(pic);
 
+    VariantInit(&var);
+    V_VT(&var) = VT_BSTR;
+    V_BSTR(&var) = SysAllocString(temp_fileW + 8);
+    hres = OleLoadPictureFile(var, (IDispatch **)&pic);
+    ok(hres == S_OK, "OleLoadPictureFile error %#x\n", hres);
+    IPicture_Release(pic);
+    VariantClear(&var);
+
     /* Try a DOS path with tacked on "file:". */
     hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
     ok(hres == S_OK ||
@@ -938,6 +960,13 @@ static void test_OleLoadPicturePath(void)
     if (pic)
         IPicture_Release(pic);
 
+    VariantInit(&var);
+    V_VT(&var) = VT_BSTR;
+    V_BSTR(&var) = SysAllocString(temp_fileW);
+    hres = OleLoadPictureFile(var, (IDispatch **)&pic);
+    ok(hres == CTL_E_PATHFILEACCESSERROR, "wrong error %#x\n", hres);
+    VariantClear(&var);
+
     DeleteFileA(temp_file);
 
     /* Try with a nonexistent file. */
@@ -947,12 +976,26 @@ static void test_OleLoadPicturePath(void)
        broken(hres == E_FAIL), /*Win2k */
        "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres);
 
+    VariantInit(&var);
+    V_VT(&var) = VT_BSTR;
+    V_BSTR(&var) = SysAllocString(temp_fileW + 8);
+    hres = OleLoadPictureFile(var, (IDispatch **)&pic);
+    ok(hres == CTL_E_FILENOTFOUND, "wrong error %#x\n", hres);
+    VariantClear(&var);
+
     hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
     ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */
        broken(hres == E_UNEXPECTED) || /* NT4 */
        broken(hres == E_FAIL), /* Win2k */
        "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres);
 
+    VariantInit(&var);
+    V_VT(&var) = VT_BSTR;
+    V_BSTR(&var) = SysAllocString(temp_fileW);
+    hres = OleLoadPictureFile(var, (IDispatch **)&pic);
+    ok(hres == CTL_E_PATHFILEACCESSERROR, "wrong error %#x\n", hres);
+    VariantClear(&var);
+
     file = CreateFileA(temp_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
                        FILE_ATTRIBUTE_NORMAL, NULL);
     WriteFile(file, bmpimage, sizeof(bmpimage), &size, NULL);
@@ -974,6 +1017,13 @@ static void test_OleLoadPicturePath(void)
     if (pic)
         IPicture_Release(pic);
 
+    VariantInit(&var);
+    V_VT(&var) = VT_BSTR;
+    V_BSTR(&var) = SysAllocString(temp_fileW);
+    hres = OleLoadPictureFile(var, (IDispatch **)&pic);
+    ok(hres == CTL_E_PATHFILEACCESSERROR, "wrong error %#x\n", hres);
+    VariantClear(&var);
+
     DeleteFileA(temp_file);
 
     /* Try with a nonexistent file. */
@@ -982,6 +1032,22 @@ static void test_OleLoadPicturePath(void)
        broken(hres == E_UNEXPECTED) || /* NT4 */
        broken(hres == E_FAIL), /* Win2k */
        "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres);
+
+    VariantInit(&var);
+    V_VT(&var) = VT_BSTR;
+    V_BSTR(&var) = SysAllocString(temp_fileW);
+    hres = OleLoadPictureFile(var, (IDispatch **)&pic);
+    ok(hres == CTL_E_PATHFILEACCESSERROR, "wrong error %#x\n", hres);
+    VariantClear(&var);
+
+    VariantInit(&var);
+    V_VT(&var) = VT_INT;
+    V_INT(&var) = 762;
+    hres = OleLoadPictureFile(var, (IDispatch **)&pic);
+    ok(hres == CTL_E_FILENOTFOUND, "wrong error %#x\n", hres);
+
+if (0) /* crashes under Windows */
+    hres = OleLoadPictureFile(var, NULL);
 }
 
 static void test_himetric(void)
@@ -1066,7 +1132,9 @@ static void test_load_save_bmp(void)
     DWORD *mem;
     IPersistStream *src_stream;
     IStream *dst_stream;
+    LARGE_INTEGER offset;
     HRESULT hr;
+    LONG size;
 
     desc.cbSizeofstruct = sizeof(desc);
     desc.picType = PICTYPE_BITMAP;
@@ -1088,6 +1156,23 @@ static void test_load_save_bmp(void)
     hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream);
     ok(hr == S_OK, "createstreamonhglobal error %#x\n", hr);
 
+    size = -1;
+    hr = IPicture_SaveAsFile(pic, dst_stream, TRUE, &size);
+    ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr);
+    ok(size == 66, "expected 66, got %d\n", size);
+    mem = GlobalLock(hmem);
+    ok(!memcmp(&mem[0], "BM", 2), "got wrong bmp header %04x\n", mem[0]);
+    GlobalUnlock(hmem);
+
+    size = -1;
+    hr = IPicture_SaveAsFile(pic, dst_stream, FALSE, &size);
+    ok(hr == E_FAIL, "expected E_FAIL, got %#x\n", hr);
+    ok(size == -1, "expected -1, got %d\n", size);
+
+    offset.QuadPart = 0;
+    hr = IStream_Seek(dst_stream, offset, SEEK_SET, NULL);
+    ok(hr == S_OK, "IStream_Seek %#x\n", hr);
+
     hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream);
     ok(hr == S_OK, "QueryInterface error %#x\n", hr);
 
@@ -1119,7 +1204,9 @@ static void test_load_save_icon(void)
     DWORD *mem;
     IPersistStream *src_stream;
     IStream *dst_stream;
+    LARGE_INTEGER offset;
     HRESULT hr;
+    LONG size;
 
     desc.cbSizeofstruct = sizeof(desc);
     desc.picType = PICTYPE_ICON;
@@ -1140,6 +1227,24 @@ static void test_load_save_icon(void)
     hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream);
     ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr);
 
+    size = -1;
+    hr = IPicture_SaveAsFile(pic, dst_stream, TRUE, &size);
+    ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr);
+todo_wine
+    ok(size == 766, "expected 766, got %d\n", size);
+    mem = GlobalLock(hmem);
+    ok(mem[0] == 0x00010000, "got wrong icon header %04x\n", mem[0]);
+    GlobalUnlock(hmem);
+
+    size = -1;
+    hr = IPicture_SaveAsFile(pic, dst_stream, FALSE, &size);
+    ok(hr == E_FAIL, "expected E_FAIL, got %#x\n", hr);
+    ok(size == -1, "expected -1, got %d\n", size);
+
+    offset.QuadPart = 0;
+    hr = IStream_Seek(dst_stream, offset, SEEK_SET, NULL);
+    ok(hr == S_OK, "IStream_Seek %#x\n", hr);
+
     hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream);
     ok(hr == S_OK, "QueryInterface error %#x\n", hr);
 
@@ -1174,6 +1279,7 @@ static void test_load_save_empty_picture(void)
     IStream *dst_stream, *stream;
     LARGE_INTEGER offset;
     HRESULT hr;
+    LONG size;
 
     memset(&pic, 0, sizeof(pic));
     desc.cbSizeofstruct = sizeof(desc);
@@ -1183,7 +1289,7 @@ static void test_load_save_empty_picture(void)
 
     type = -1;
     hr = IPicture_get_Type(pic, &type);
-    ok(hr == S_OK,"get_Type error %#8x\n", hr);
+    ok(hr == S_OK, "get_Type error %#x\n", hr);
     ok(type == PICTYPE_NONE,"expected picture type PICTYPE_NONE, got %d\n", type);
 
     handle = (OLE_HANDLE)0xdeadbeef;
@@ -1195,6 +1301,16 @@ static void test_load_save_empty_picture(void)
     hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream);
     ok(hr == S_OK, "createstreamonhglobal error %#x\n", hr);
 
+    size = -1;
+    hr = IPicture_SaveAsFile(pic, dst_stream, TRUE, &size);
+    ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr);
+    ok(size == -1, "expected -1, got %d\n", size);
+
+    size = -1;
+    hr = IPicture_SaveAsFile(pic, dst_stream, FALSE, &size);
+    ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr);
+    ok(size == -1, "expected -1, got %d\n", size);
+
     hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream);
     ok(hr == S_OK, "QueryInterface error %#x\n", hr);
 
@@ -1260,6 +1376,89 @@ static void test_load_save_empty_picture(void)
     IStream_Release(stream);
 }
 
+static void test_load_save_emf(void)
+{
+    HDC hdc;
+    IPicture *pic;
+    PICTDESC desc;
+    short type;
+    OLE_HANDLE handle;
+    HGLOBAL hmem;
+    DWORD *mem;
+    ENHMETAHEADER *emh;
+    IPersistStream *src_stream;
+    IStream *dst_stream;
+    LARGE_INTEGER offset;
+    HRESULT hr;
+    LONG size;
+
+    hdc = CreateEnhMetaFileA(0, NULL, NULL, NULL);
+    ok(hdc != 0, "CreateEnhMetaFileA failed\n");
+
+    desc.cbSizeofstruct = sizeof(desc);
+    desc.picType = PICTYPE_ENHMETAFILE;
+    desc.u.emf.hemf = CloseEnhMetaFile(hdc);
+    ok(desc.u.emf.hemf != 0, "CloseEnhMetaFile failed\n");
+    hr = OleCreatePictureIndirect(&desc, &IID_IPicture, FALSE, (void**)&pic);
+    ok(hr == S_OK, "OleCreatePictureIndirect error %#x\n", hr);
+
+    type = -1;
+    hr = IPicture_get_Type(pic, &type);
+    ok(hr == S_OK,"get_Type error %#8x\n", hr);
+    ok(type == PICTYPE_ENHMETAFILE,"expected PICTYPE_ENHMETAFILE, got %d\n", type);
+
+    hr = IPicture_get_Handle(pic, &handle);
+    ok(hr == S_OK,"get_Handle error %#8x\n", hr);
+    ok(IntToPtr(handle) == desc.u.emf.hemf, "get_Handle returned wrong handle %#x\n", handle);
+
+    hmem = GlobalAlloc(GMEM_MOVEABLE, 0);
+    hr = CreateStreamOnHGlobal(hmem, FALSE, &dst_stream);
+    ok(hr == S_OK, "createstreamonhglobal error %#x\n", hr);
+
+    size = -1;
+    hr = IPicture_SaveAsFile(pic, dst_stream, TRUE, &size);
+    ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr);
+    ok(size == 128, "expected 128, got %d\n", size);
+    emh = GlobalLock(hmem);
+if (size)
+{
+    ok(emh->iType == EMR_HEADER, "wrong iType %04x\n", emh->iType);
+    ok(emh->dSignature == ENHMETA_SIGNATURE, "wrong dSignature %08x\n", emh->dSignature);
+}
+    GlobalUnlock(hmem);
+
+    size = -1;
+    hr = IPicture_SaveAsFile(pic, dst_stream, FALSE, &size);
+    ok(hr == E_FAIL, "expected E_FAIL, got %#x\n", hr);
+    ok(size == -1, "expected -1, got %d\n", size);
+
+    offset.QuadPart = 0;
+    hr = IStream_Seek(dst_stream, offset, SEEK_SET, NULL);
+    ok(hr == S_OK, "IStream_Seek %#x\n", hr);
+
+    hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream);
+    ok(hr == S_OK, "QueryInterface error %#x\n", hr);
+
+    hr = IPersistStream_Save(src_stream, dst_stream, TRUE);
+    ok(hr == S_OK, "Save error %#x\n", hr);
+
+    IPersistStream_Release(src_stream);
+    IStream_Release(dst_stream);
+
+    mem = GlobalLock(hmem);
+    ok(!memcmp(mem, "lt\0\0", 4), "got wrong stream header %04x\n", mem[0]);
+    ok(mem[1] == 128, "expected 128, got %u\n", mem[1]);
+    emh = (ENHMETAHEADER *)(mem + 2);
+    ok(emh->iType == EMR_HEADER, "wrong iType %04x\n", emh->iType);
+    ok(emh->dSignature == ENHMETA_SIGNATURE, "wrong dSignature %08x\n", emh->dSignature);
+
+    GlobalUnlock(hmem);
+    GlobalFree(hmem);
+
+    DeleteEnhMetaFile(desc.u.emf.hemf);
+    IPicture_Release(pic);
+}
+
 START_TEST(olepicture)
 {
     hOleaut32 = GetModuleHandleA("oleaut32.dll");
@@ -1275,6 +1474,7 @@ START_TEST(olepicture)
     test_pic(gifimage, sizeof(gifimage));
     test_pic(jpgimage, sizeof(jpgimage));
     test_pic(bmpimage, sizeof(bmpimage));
+    test_pic(bmpimage_rle8, sizeof(bmpimage_rle8));
     test_pic(gif4pixel, sizeof(gif4pixel));
     /* FIXME: No PNG support in Windows... */
     if (0) test_pic(pngimage, sizeof(pngimage));
@@ -1299,6 +1499,7 @@ START_TEST(olepicture)
     test_load_save_bmp();
     test_load_save_icon();
     test_load_save_empty_picture();
+    test_load_save_emf();
 }
 
 
@@ -1332,14 +1533,9 @@ static HRESULT WINAPI NoStatStreamImpl_QueryInterface(
   NoStatStreamImpl* const This = impl_from_IStream(iface);
   if (ppvObject==0) return E_INVALIDARG;
   *ppvObject = 0;
-  if (IsEqualIID(&IID_IUnknown, riid))
-  {
-    *ppvObject = This;
-  }
-  else if (IsEqualIID(&IID_IStream, riid))
-  {
-    *ppvObject = This;
-  }
+
+  if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IStream, riid))
+    *ppvObject = &This->IStream_iface;
 
   if ((*ppvObject)==0)
     return E_NOINTERFACE;