- Sync ole32 and oleaut32 regtests to Wine-1.3.
[reactos.git] / rostests / winetests / oleaut32 / olepicture.c
index c0d0de9..f00055e 100644 (file)
@@ -23,9 +23,9 @@
 #include <stdio.h>
 #include <math.h>
 #include <float.h>
-#include <time.h>
 
 #define COBJMACROS
+#define NONAMELESSUNION
 
 #include "wine/test.h"
 #include <windef.h>
@@ -36,6 +36,7 @@
 #include <winerror.h>
 #include <winnt.h>
 
+#include <urlmon.h>
 #include <wtypes.h>
 #include <olectl.h>
 #include <objidl.h>
@@ -121,6 +122,53 @@ static const unsigned char apmdata[] = {
 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00
 };
 
+/* MF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
+static const unsigned char metafile[] = {
+    0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x19, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x0a,
+    0x16, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x54, 0x65, 0x73, 0x74, 0x03, 0x00, 0x05, 0x00,
+    0x08, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00,
+    0x00, 0x00
+};
+
+/* EMF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
+static const unsigned char enhmetafile[] = {
+    0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xe7, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff,
+    0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+    0xf4, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+    0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
+    0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
+    0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0xc8, 0x41, 0x00, 0x80, 0xbb, 0x41,
+    0x0b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
+    0x04, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00,
+    0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
+    0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
+    0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+    0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+    0x14, 0x00, 0x00, 0x00
+};
+
+
 struct NoStatStreamImpl
 {
        const IStreamVtbl       *lpVtbl;   
@@ -168,6 +216,13 @@ test_pic_with_stream(LPSTREAM stream, unsigned int imgsize)
        ok(hres == S_OK,"IPicture_get_Handle does not return S_OK, but 0x%08x\n", hres);
        ok(handle != 0, "IPicture_get_Handle returns a NULL handle, but it should be non NULL\n");
 
+        if (handle)
+        {
+            BITMAP bmp;
+            GetObject((HGDIOBJ)handle, sizeof(BITMAP), &bmp);
+            todo_wine ok(bmp.bmBits != 0, "not a dib\n");
+        }
+
        width = 0;
        hres = IPicture_get_Width (pic, &width);
        ok(hres == S_OK,"IPicture_get_Width does not return S_OK, but 0x%08x\n", hres);
@@ -277,6 +332,7 @@ static void test_empty_image(void) {
        ULARGE_INTEGER  newpos1;
        LARGE_INTEGER   seekto;
        short           type;
+       DWORD           attr;
 
        /* Empty image. Happens occasionally in VB programs. */
        hglob = GlobalAlloc (0, 8);
@@ -300,10 +356,16 @@ static void test_empty_image(void) {
        ok (hres == S_OK,"empty picture get type failed with hres 0x%08x\n", hres);
        ok (type == PICTYPE_NONE,"type is %d, but should be PICTYPE_NONE(0)\n", type);
 
+       attr = 0xdeadbeef;
+       hres = IPicture_get_Attributes (pic, &attr);
+       ok (hres == S_OK,"empty picture get attributes failed with hres 0x%08x\n", hres);
+       ok (attr == 0,"attr is %d, but should be 0\n", attr);
+
        hres = IPicture_get_Handle (pic, &handle);
        ok (hres == S_OK,"empty picture get handle failed with hres 0x%08x\n", hres);
        ok (handle == 0, "empty picture get handle did not return 0, but 0x%08x\n", handle);
        IPicture_Release (pic);
+       IStream_Release (stream);
 }
 
 static void test_empty_image_2(void) {
@@ -342,6 +404,7 @@ static void test_empty_image_2(void) {
        ok (type == PICTYPE_NONE,"type is %d, but should be PICTYPE_NONE(0)\n", type);
 
        IPicture_Release (pic);
+       IStream_Release (stream);
 }
 
 static void test_Invoke(void)
@@ -355,16 +418,17 @@ static void test_Invoke(void)
     HGLOBAL hglob;
     void *data;
 
-       hglob = GlobalAlloc (0, sizeof(gifimage));
-       data = GlobalLock(hglob);
-       memcpy(data, gifimage, sizeof(gifimage));
+    hglob = GlobalAlloc (0, sizeof(gifimage));
+    data = GlobalLock(hglob);
+    memcpy(data, gifimage, sizeof(gifimage));
     GlobalUnlock(hglob);
 
-       hr = CreateStreamOnHGlobal (hglob, FALSE, &stream);
+    hr = CreateStreamOnHGlobal (hglob, FALSE, &stream);
     ok_ole_success(hr, "CreateStreamOnHGlobal");
 
-       hr = pOleLoadPicture(stream, sizeof(gifimage), TRUE, &IID_IPictureDisp, (void **)&picdisp);
+    hr = pOleLoadPicture(stream, sizeof(gifimage), TRUE, &IID_IPictureDisp, (void **)&picdisp);
     IStream_Release(stream);
+    GlobalFree(hglob);
     ok_ole_success(hr, "OleLoadPicture");
 
     V_VT(&vararg) = VT_BOOL;
@@ -424,7 +488,7 @@ static void test_OleCreatePictureIndirect(void)
 
     if(!pOleCreatePictureIndirect)
     {
-        skip("Skipping OleCreatePictureIndirect tests\n");
+        win_skip("Skipping OleCreatePictureIndirect tests\n");
         return;
     }
 
@@ -442,7 +506,7 @@ static void test_OleCreatePictureIndirect(void)
     IPicture_Release(pict);
 }
 
-static void test_apm()
+static void test_apm(void)
 {
     OLE_HANDLE handle;
     LPSTREAM stream;
@@ -480,6 +544,342 @@ static void test_apm()
     IStream_Release(stream);
 }
 
+static void test_metafile(void)
+{
+    LPSTREAM stream;
+    IPicture *pict;
+    HGLOBAL hglob;
+    LPBYTE *data;
+
+    hglob = GlobalAlloc (0, sizeof(metafile));
+    data = GlobalLock(hglob);
+    memcpy(data, metafile, sizeof(metafile));
+
+    ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
+    /* Windows does not load simple metafiles */
+    ole_expect(OleLoadPictureEx(stream, sizeof(metafile), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict), E_FAIL);
+
+    IStream_Release(stream);
+}
+
+static void test_enhmetafile(void)
+{
+    OLE_HANDLE handle;
+    LPSTREAM stream;
+    IPicture *pict;
+    HGLOBAL hglob;
+    LPBYTE *data;
+    LONG cxy;
+    BOOL keep;
+    short type;
+
+    hglob = GlobalAlloc (0, sizeof(enhmetafile));
+    data = GlobalLock(hglob);
+    memcpy(data, enhmetafile, sizeof(enhmetafile));
+
+    ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
+    ole_check(OleLoadPictureEx(stream, sizeof(enhmetafile), TRUE, &IID_IPicture, 10, 10, 0, (LPVOID *)&pict));
+
+    ole_check(IPicture_get_Handle(pict, &handle));
+    ok(handle != 0, "handle is null\n");
+
+    ole_check(IPicture_get_Type(pict, &type));
+    expect_eq(type, PICTYPE_ENHMETAFILE, short, "%d");
+
+    ole_check(IPicture_get_Height(pict, &cxy));
+    expect_eq(cxy, -23, LONG, "%d");
+
+    ole_check(IPicture_get_Width(pict, &cxy));
+    expect_eq(cxy, -25, LONG, "%d");
+
+    ole_check(IPicture_get_KeepOriginalFormat(pict, &keep));
+    todo_wine expect_eq(keep, FALSE, LONG, "%d");
+
+    IPicture_Release(pict);
+    IStream_Release(stream);
+}
+
+static void test_Render(void)
+{
+    IPicture *pic;
+    HRESULT hres;
+    short type;
+    PICTDESC desc;
+    OLE_XSIZE_HIMETRIC pWidth;
+    OLE_YSIZE_HIMETRIC pHeight;
+    COLORREF result, expected;
+    HDC hdc = GetDC(0);
+
+    /* test IPicture::Render return code on uninitialized picture */
+    OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic);
+    hres = IPicture_get_Type(pic, &type);
+    ok(hres == S_OK, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres);
+    ok(type == PICTYPE_UNINITIALIZED, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type);
+    /* zero dimensions */
+    hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 0, 0, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 0, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 10, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 0, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 0, 10, 0, 0, 10, 10, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 10, 0, 0, 0, 10, 10, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 10, 10, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    /* nonzero dimensions, PICTYPE_UNINITIALIZED */
+    hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 10, NULL);
+    ole_expect(hres, S_OK);
+    IPicture_Release(pic);
+
+    desc.cbSizeofstruct = sizeof(PICTDESC);
+    desc.picType = PICTYPE_ICON;
+    desc.u.icon.hicon = LoadIcon(NULL, IDI_APPLICATION);
+    if(!desc.u.icon.hicon){
+        win_skip("LoadIcon failed. Skipping...\n");
+        ReleaseDC(NULL, hdc);
+        return;
+    }
+
+    OleCreatePictureIndirect(&desc, &IID_IPicture, TRUE, (VOID**)&pic);
+    /* zero dimensions, PICTYPE_ICON */
+    hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 0, 0, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 10, 0, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 10, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 10, 10, 0, 0, 0, 0, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 0, 10, 0, 0, 10, 10, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 10, 0, 0, 0, 10, 10, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+    hres = IPicture_Render(pic, hdc, 0, 0, 0, 0, 0, 0, 10, 10, NULL);
+    ole_expect(hres, CTL_E_INVALIDPROPERTYVALUE);
+
+    /* Check if target size and position is respected */
+    IPicture_get_Width(pic, &pWidth);
+    IPicture_get_Height(pic, &pHeight);
+
+    SetPixelV(hdc, 0, 0, 0x00F0F0F0);
+    SetPixelV(hdc, 5, 5, 0x00F0F0F0);
+    SetPixelV(hdc, 10, 10, 0x00F0F0F0);
+    expected = GetPixel(hdc, 0, 0);
+
+    hres = IPicture_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;
+    }
+
+    /* 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. */
+       "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);
+
+    IPicture_Release(pic);
+    ReleaseDC(NULL, hdc);
+}
+
+static void test_get_Attributes(void)
+{
+    IPicture *pic;
+    HRESULT hres;
+    short type;
+    DWORD attr;
+
+    OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic);
+    hres = IPicture_get_Type(pic, &type);
+    ok(hres == S_OK, "IPicture_get_Type does not return S_OK, but 0x%08x\n", hres);
+    ok(type == PICTYPE_UNINITIALIZED, "Expected type = PICTYPE_UNINITIALIZED, got = %d\n", type);
+
+    hres = IPicture_get_Attributes(pic, NULL);
+    ole_expect(hres, E_POINTER);
+
+    attr = 0xdeadbeef;
+    hres = IPicture_get_Attributes(pic, &attr);
+    ole_expect(hres, S_OK);
+    ok(attr == 0, "IPicture_get_Attributes does not reset attr to zero, got %d\n", attr);
+
+    IPicture_Release(pic);
+}
+
+static void test_get_Handle(void)
+{
+    IPicture *pic;
+    HRESULT hres;
+
+    OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic);
+
+    hres = IPicture_get_Handle(pic, NULL);
+    ole_expect(hres, E_POINTER);
+
+    IPicture_Release(pic);
+}
+
+static void test_get_Type(void)
+{
+    IPicture *pic;
+    HRESULT hres;
+
+    OleCreatePictureIndirect(NULL, &IID_IPicture, TRUE, (VOID**)&pic);
+
+    hres = IPicture_get_Type(pic, NULL);
+    ole_expect(hres, E_POINTER);
+
+    IPicture_Release(pic);
+}
+
+static void test_OleLoadPicturePath(void)
+{
+    static WCHAR emptyW[] = {0};
+
+    IPicture *pic;
+    HRESULT hres;
+    int i;
+    char temp_path[MAX_PATH];
+    char temp_file[MAX_PATH];
+    WCHAR temp_fileW[MAX_PATH + 5] = {'f','i','l','e',':','/','/','/'};
+    HANDLE file;
+    DWORD size;
+    WCHAR *ptr;
+
+    const struct
+    {
+        LPOLESTR szURLorPath;
+        REFIID riid;
+        IPicture **pic;
+    } invalid_parameters[] =
+    {
+        {NULL,  NULL,          NULL},
+        {NULL,  NULL,          &pic},
+        {NULL,  &IID_IPicture, NULL},
+        {NULL,  &IID_IPicture, &pic},
+        {emptyW, NULL,          NULL},
+        {emptyW, &IID_IPicture, NULL},
+    };
+
+    for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++)
+    {
+        pic = (IPicture *)0xdeadbeef;
+        hres = OleLoadPicturePath(invalid_parameters[i].szURLorPath, NULL, 0, 0,
+                                  invalid_parameters[i].riid,
+                                  (void **)invalid_parameters[i].pic);
+        ok(hres == E_INVALIDARG,
+           "[%d] Expected OleLoadPicturePath to return E_INVALIDARG, got 0x%08x\n", i, hres);
+        ok(pic == (IPicture *)0xdeadbeef,
+           "[%d] Expected output pointer to be 0xdeadbeef, got %p\n", i, pic);
+    }
+
+    pic = (IPicture *)0xdeadbeef;
+    hres = OleLoadPicturePath(emptyW, NULL, 0, 0, NULL, (void **)&pic);
+    todo_wine
+    ok(hres == INET_E_UNKNOWN_PROTOCOL || /* XP/Vista+ */
+       hres == E_UNEXPECTED || /* NT4/Win95 */
+       hres == E_FAIL || /* Win95 OSR2 */
+       hres == E_OUTOFMEMORY, /* Win98/Win2k/Win2k3 */
+       "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres);
+    ok(pic == NULL,
+       "Expected the output interface pointer to be NULL, got %p\n", pic);
+
+    pic = (IPicture *)0xdeadbeef;
+    hres = OleLoadPicturePath(emptyW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
+    todo_wine
+    ok(hres == INET_E_UNKNOWN_PROTOCOL || /* XP/Vista+ */
+       hres == E_UNEXPECTED || /* NT4/Win95 */
+       hres == E_FAIL || /* Win95 OSR2 */
+       hres == E_OUTOFMEMORY, /* Win98/Win2k/Win2k3 */
+       "Expected OleLoadPicturePath to return INET_E_UNKNOWN_PROTOCOL, got 0x%08x\n", hres);
+    ok(pic == NULL,
+       "Expected the output interface pointer to be NULL, got %p\n", pic);
+
+    /* Create a local temporary image file for testing. */
+    GetTempPathA(sizeof(temp_path), temp_path);
+    GetTempFileNameA(temp_path, "bmp", 0, temp_file);
+    file = CreateFileA(temp_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
+                       FILE_ATTRIBUTE_NORMAL, NULL);
+    WriteFile(file, bmpimage, sizeof(bmpimage), &size, NULL);
+    CloseHandle(file);
+
+    MultiByteToWideChar(CP_ACP, 0, temp_file, -1, temp_fileW + 8, sizeof(temp_fileW)/sizeof(WCHAR) - 8);
+
+    /* Try a normal DOS path. */
+    hres = OleLoadPicturePath(temp_fileW + 8, NULL, 0, 0, &IID_IPicture, (void **)&pic);
+    ok(hres == S_OK ||
+       broken(hres == E_UNEXPECTED), /* NT4/Win95 */
+       "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres);
+    if (pic)
+        IPicture_Release(pic);
+
+    /* Try a DOS path with tacked on "file:". */
+    hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
+    ok(hres == S_OK ||
+       broken(hres == E_UNEXPECTED), /* NT4/Win95 */
+       "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres);
+    if (pic)
+        IPicture_Release(pic);
+
+    DeleteFileA(temp_file);
+
+    /* Try with a nonexistent file. */
+    hres = OleLoadPicturePath(temp_fileW + 8, NULL, 0, 0, &IID_IPicture, (void **)&pic);
+    ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */
+       hres == E_UNEXPECTED || /* NT4/Win95 */
+       hres == E_FAIL, /* Win9x/Win2k */
+       "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres);
+
+    hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
+    ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */
+       hres == E_UNEXPECTED || /* NT4/Win95 */
+       hres == E_FAIL, /* Win9x/Win2k */
+       "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres);
+
+    file = CreateFileA(temp_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
+                       FILE_ATTRIBUTE_NORMAL, NULL);
+    WriteFile(file, bmpimage, sizeof(bmpimage), &size, NULL);
+    CloseHandle(file);
+
+    /* Try a "file:" URL with slash separators. */
+    ptr = temp_fileW + 8;
+    while (*ptr)
+    {
+        if (*ptr == '\\')
+            *ptr = '/';
+        ptr++;
+    }
+
+    hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
+    ok(hres == S_OK ||
+       broken(hres == E_UNEXPECTED), /* NT4/Win95 */
+       "Expected OleLoadPicturePath to return S_OK, got 0x%08x\n", hres);
+    if (pic)
+        IPicture_Release(pic);
+
+    DeleteFileA(temp_file);
+
+    /* Try with a nonexistent file. */
+    hres = OleLoadPicturePath(temp_fileW, NULL, 0, 0, &IID_IPicture, (void **)&pic);
+    ok(hres == INET_E_RESOURCE_NOT_FOUND || /* XP+ */
+       hres == E_UNEXPECTED || /* NT4/Win95 */
+       hres == E_FAIL, /* Win9x/Win2k */
+       "Expected OleLoadPicturePath to return INET_E_RESOURCE_NOT_FOUND, got 0x%08x\n", hres);
+}
+
 START_TEST(olepicture)
 {
        hOleaut32 = GetModuleHandleA("oleaut32.dll");
@@ -487,7 +887,7 @@ START_TEST(olepicture)
        pOleCreatePictureIndirect = (void*)GetProcAddress(hOleaut32, "OleCreatePictureIndirect");
        if (!pOleLoadPicture)
        {
-           skip("OleLoadPicture is not available\n");
+           win_skip("OleLoadPicture is not available\n");
            return;
        }
 
@@ -496,14 +896,21 @@ START_TEST(olepicture)
        test_pic(jpgimage, sizeof(jpgimage));
        test_pic(bmpimage, sizeof(bmpimage));
         test_pic(gif4pixel, sizeof(gif4pixel));
-       /* FIXME: No PNG support yet in Wine or in older Windows... */
+       /* FIXME: No PNG support in Windows... */
        if (0) test_pic(pngimage, sizeof(pngimage));
        test_empty_image();
        test_empty_image_2();
         test_apm();
-
-       test_Invoke();
-        test_OleCreatePictureIndirect();
+        test_metafile();
+        test_enhmetafile();
+
+    test_Invoke();
+    test_OleCreatePictureIndirect();
+    test_Render();
+    test_get_Attributes();
+    test_get_Handle();
+    test_get_Type();
+    test_OleLoadPicturePath();
 }
 
 
@@ -532,13 +939,13 @@ static HRESULT WINAPI NoStatStreamImpl_QueryInterface(
   NoStatStreamImpl* const This=(NoStatStreamImpl*)iface;
   if (ppvObject==0) return E_INVALIDARG;
   *ppvObject = 0;
-  if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
+  if (IsEqualIID(&IID_IUnknown, riid))
   {
-    *ppvObject = (IStream*)This;
+    *ppvObject = This;
   }
-  else if (memcmp(&IID_IStream, riid, sizeof(IID_IStream)) == 0)
+  else if (IsEqualIID(&IID_IStream, riid))
   {
-    *ppvObject = (IStream*)This;
+    *ppvObject = This;
   }
 
   if ((*ppvObject)==0)