static HRESULT WINAPI ddrawex_surface4_SetPrivateData(IDirectDrawSurface4 *iface, REFGUID tag, void *data, DWORD data_size, DWORD flags) { struct ddrawex_surface *surface = impl_from_IDirectDrawSurface4(iface); TRACE("iface %p, tag %s, data %p, data_size %u, flags %#x.\n", iface, debugstr_guid(tag), data, data_size, flags); /* To completely avoid this we'd have to clone the private data API in * ddrawex. */ if (IsEqualGUID(&IID_DDrawexPriv, tag)) FIXME("Application uses ddrawex's private GUID.\n"); return IDirectDrawSurface4_SetPrivateData(surface->parent, tag, data, data_size, flags); }
/* dds_get_outer * * Given a surface from ddraw.dll it retrieves the pointer to the ddrawex.dll wrapper around it * * Parameters: * inner: ddraw.dll surface to retrieve the outer surface from * * Returns: * The surface wrapper. If there is none yet, a new one is created */ IDirectDrawSurface4 *dds_get_outer(IDirectDrawSurface4 *inner) { IDirectDrawSurface4 *outer = NULL; DWORD size = sizeof(outer); HRESULT hr; if(!inner) return NULL; hr = IDirectDrawSurface4_GetPrivateData(inner, &IID_DDrawexPriv, &outer, &size); if(FAILED(hr) || outer == NULL) { struct ddrawex_surface *impl; TRACE("Creating new ddrawex surface wrapper for surface %p\n", inner); impl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*impl)); impl->ref = 1; impl->IDirectDrawSurface3_iface.lpVtbl = &ddrawex_surface3_vtbl; impl->IDirectDrawSurface4_iface.lpVtbl = &ddrawex_surface4_vtbl; IDirectDrawSurface4_AddRef(inner); impl->parent = inner; outer = &impl->IDirectDrawSurface4_iface; hr = IDirectDrawSurface4_SetPrivateData(inner, &IID_DDrawexPriv, &outer, sizeof(outer), 0 /* Flags */); if(FAILED(hr)) { ERR("IDirectDrawSurface4_SetPrivateData failed\n"); } } return outer; }
static void test_surface_from_dc4(void) { IDirectDrawSurface4 *surf4; IDirectDrawSurface *surf1; DDSURFACEDESC2 ddsd2; IUnknown *tmp, *tmp2; IDirectDraw4 *dd4; IDirectDraw *dd1; DWORD priv, size; HRESULT hr; HDC dc; dd1 = createDD(); hr = IDirectDraw_QueryInterface(dd1, &IID_IDirectDraw4, (void **)&dd4); if (hr == E_NOINTERFACE) { win_skip("DirectDraw4 is not supported\n"); IDirectDraw_Release(dd1); return; } ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed, hr %#x.\n", hr); IDirectDraw_Release(dd1); memset(&ddsd2, 0, sizeof(ddsd2)); ddsd2.dwSize = sizeof(ddsd2); ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; ddsd2.dwWidth = 64; ddsd2.dwHeight = 64; ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL); if (hr == DDERR_UNSUPPORTEDMODE) { win_skip("Unsupported mode\n"); IDirectDraw3_Release(dd4); return; } ok(SUCCEEDED(hr), "CreateSurface failed, hr %#x.\n", hr); hr = IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **)&surf1); ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr); priv = 0xdeadbeef; size = sizeof(priv); hr = IDirectDrawSurface4_SetPrivateData(surf4, &guid, &priv, size, 0); ok(SUCCEEDED(hr), "SetPrivateData failed, hr %#x.\n", hr); priv = 0; hr = IDirectDrawSurface4_GetPrivateData(surf4, &guid, &priv, &size); ok(SUCCEEDED(hr), "GetPrivateData failed, hr %#x.\n", hr); ok(priv == 0xdeadbeef, "Expected private data 0xdeadbeef, got %#x.\n", priv); hr = IDirectDrawSurface4_GetDC(surf4, &dc); ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr); hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, NULL); ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %#x.\n", hr); hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp); ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr); ok((IDirectDrawSurface4 *)tmp != surf4, "Expected surface != %p.\n", surf4); hr = IUnknown_QueryInterface(tmp, &IID_IDirectDrawSurface, (void **)&tmp2); ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr); ok(tmp2 == tmp, "Expected %p, got %p.\n", tmp, tmp2); ok((IDirectDrawSurface *)tmp2 != surf1, "Expected surface != %p.\n", surf1); IUnknown_Release(tmp2); hr = IUnknown_QueryInterface(tmp, &IID_IDirectDrawSurface4, (void **)&tmp2); ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr); ok((IDirectDrawSurface4 *)tmp2 != surf4, "Expected surface != %p.\n", surf4); priv = 0; hr = IDirectDrawSurface4_GetPrivateData((IDirectDrawSurface4 *)tmp2, &guid, &priv, &size); ok(SUCCEEDED(hr), "GetPrivateData failed, hr %#x.\n", hr); ok(priv == 0xdeadbeef, "Expected private data 0xdeadbeef, got %#x.\n", priv); IUnknown_Release(tmp2); IUnknown_Release(tmp); hr = IDirectDrawSurface4_ReleaseDC(surf4, dc); ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr); dc = CreateCompatibleDC(NULL); ok(!!dc, "CreateCompatibleDC failed.\n"); tmp = (IUnknown *)0xdeadbeef; hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp); ok(hr == DDERR_NOTFOUND, "Expected DDERR_NOTFOUND, got %#x.\n", hr); ok(!tmp, "Expected surface NULL, got %p.\n", tmp); ok(DeleteDC(dc), "DeleteDC failed.\n"); tmp = (IUnknown *)0xdeadbeef; hr = IDirectDraw4_GetSurfaceFromDC(dd4, NULL, (IDirectDrawSurface4 **)&tmp); ok(hr == DDERR_NOTFOUND, "Expected DDERR_NOTFOUND, got %#x.\n", hr); ok(!tmp, "Expected surface NULL, got %p.\n", tmp); IDirectDrawSurface_Release(surf1); IDirectDrawSurface4_Release(surf4); IDirectDraw4_Release(dd4); }