diff --git a/dlls/d3drm/d3drm.c b/dlls/d3drm/d3drm.c index fe3331538c5..edb46df6089 100644 --- a/dlls/d3drm/d3drm.c +++ b/dlls/d3drm/d3drm.c @@ -139,10 +139,12 @@ static ULONG WINAPI d3drm1_Release(IDirect3DRM *iface) static HRESULT WINAPI d3drm1_CreateObject(IDirect3DRM *iface, REFCLSID clsid, IUnknown *outer, REFIID iid, void **out) { - FIXME("iface %p, clsid %s, outer %p, iid %s, out %p stub!\n", + struct d3drm *d3drm = impl_from_IDirect3DRM(iface); + + TRACE("iface %p, clsid %s, outer %p, iid %s, out %p.\n", iface, debugstr_guid(clsid), outer, debugstr_guid(iid), out); - return E_NOTIMPL; + return IDirect3DRM3_CreateObject(&d3drm->IDirect3DRM3_iface, clsid, outer, iid, out); } static HRESULT WINAPI d3drm1_CreateFrame(IDirect3DRM *iface, @@ -603,10 +605,12 @@ static ULONG WINAPI d3drm2_Release(IDirect3DRM2 *iface) static HRESULT WINAPI d3drm2_CreateObject(IDirect3DRM2 *iface, REFCLSID clsid, IUnknown *outer, REFIID iid, void **out) { - FIXME("iface %p, clsid %s, outer %p, iid %s, out %p stub!\n", + struct d3drm *d3drm = impl_from_IDirect3DRM2(iface); + + TRACE("iface %p, clsid %s, outer %p, iid %s, out %p.\n", iface, debugstr_guid(clsid), outer, debugstr_guid(iid), out); - return E_NOTIMPL; + return IDirect3DRM3_CreateObject(&d3drm->IDirect3DRM3_iface, clsid, outer, iid, out); } static HRESULT WINAPI d3drm2_CreateFrame(IDirect3DRM2 *iface, @@ -1054,10 +1058,50 @@ static ULONG WINAPI d3drm3_Release(IDirect3DRM3 *iface) static HRESULT WINAPI d3drm3_CreateObject(IDirect3DRM3 *iface, REFCLSID clsid, IUnknown *outer, REFIID iid, void **out) { - FIXME("iface %p, clsid %s, outer %p, iid %s, out %p stub!\n", + IUnknown *object; + HRESULT hr; + + TRACE("iface %p, clsid %s, outer %p, iid %s, out %p.\n", iface, debugstr_guid(clsid), outer, debugstr_guid(iid), out); - return E_NOTIMPL; + if (!out) + return D3DRMERR_BADVALUE; + + if (!clsid || !iid) + { + *out = NULL; + return D3DRMERR_BADVALUE; + } + + if (outer) + { + FIXME("COM aggregation for outer IUnknown (%p) not implemented. Returning E_NOTIMPL.\n", outer); + *out = NULL; + return E_NOTIMPL; + } + + if (IsEqualGUID(clsid, &CLSID_CDirect3DRMTexture)) + { + struct d3drm_texture *texture; + if (FAILED(hr = d3drm_texture_create(&texture))) + { + *out = NULL; + return hr; + } + object = (IUnknown *)&texture->IDirect3DRMTexture3_iface; + } + else + { + FIXME("%s not implemented. Returning CLASSFACTORY_E_FIRST.\n", debugstr_guid(clsid)); + *out = NULL; + return CLASSFACTORY_E_FIRST; + } + + if (FAILED(hr = IUnknown_QueryInterface(object, iid, out))) + *out = NULL; + IUnknown_Release(object); + + return hr; } static HRESULT WINAPI d3drm3_CreateFrame(IDirect3DRM3 *iface, diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index a8f9c40ddfc..9f6eaab5225 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -1353,23 +1353,24 @@ static void test_object(void) { REFCLSID clsid; REFIID iid; + BOOL todo; } tests[] = { - { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMDevice }, - { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMDevice2 }, - { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMDevice3 }, - { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMWinDevice }, - { &CLSID_CDirect3DRMTexture, &IID_IDirect3DRMTexture }, - { &CLSID_CDirect3DRMTexture, &IID_IDirect3DRMTexture2 }, - { &CLSID_CDirect3DRMTexture, &IID_IDirect3DRMTexture3 }, - { &CLSID_CDirect3DRMViewport, &IID_IDirect3DRMViewport }, - { &CLSID_CDirect3DRMViewport, &IID_IDirect3DRMViewport2 }, + { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMDevice, TRUE }, + { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMDevice2, TRUE }, + { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMDevice3, TRUE }, + { &CLSID_CDirect3DRMDevice, &IID_IDirect3DRMWinDevice, TRUE }, + { &CLSID_CDirect3DRMTexture, &IID_IDirect3DRMTexture, FALSE }, + { &CLSID_CDirect3DRMTexture, &IID_IDirect3DRMTexture2, FALSE }, + { &CLSID_CDirect3DRMTexture, &IID_IDirect3DRMTexture3, FALSE }, + { &CLSID_CDirect3DRMViewport, &IID_IDirect3DRMViewport, TRUE }, + { &CLSID_CDirect3DRMViewport, &IID_IDirect3DRMViewport2, TRUE }, }; IDirect3DRM *d3drm1; IDirect3DRM2 *d3drm2; IDirect3DRM3 *d3drm3; - IUnknown *unknown; + IUnknown *unknown = (IUnknown *)0xdeadbeef; HRESULT hr; ULONG ref1, ref2, ref3, ref4; int i; @@ -1382,17 +1383,26 @@ static void test_object(void) hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3); ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface (hr = %#x).\n", hr); + hr = IDirect3DRM_CreateObject(d3drm1, &CLSID_DirectDraw, NULL, &IID_IDirectDraw, (void **)&unknown); + ok(hr == CLASSFACTORY_E_FIRST, "Expected hr == CLASSFACTORY_E_FIRST, got %#x.\n", hr); + ok(!unknown, "Expected object returned == NULL, got %p.\n", unknown); + for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i) { + unknown = (IUnknown *)0xdeadbeef; hr = IDirect3DRM_CreateObject(d3drm1, NULL, NULL, tests[i].iid, (void **)&unknown); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Test %u: expected hr == D3DRMERR_BADVALUE, got %#x.\n", i, hr); + ok(hr == D3DRMERR_BADVALUE, "Test %u: expected hr == D3DRMERR_BADVALUE, got %#x.\n", i, hr); + ok(!unknown, "Expected object returned == NULL, got %p.\n", unknown); + unknown = (IUnknown *)0xdeadbeef; hr = IDirect3DRM_CreateObject(d3drm1, tests[i].clsid, NULL, NULL, (void **)&unknown); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Test %u: expected hr == D3DRMERR_BADVALUE, got %#x.\n", i, hr); + ok(hr == D3DRMERR_BADVALUE, "Test %u: expected hr == D3DRMERR_BADVALUE, got %#x.\n", i, hr); + ok(!unknown, "Expected object returned == NULL, got %p.\n", unknown); hr = IDirect3DRM_CreateObject(d3drm1, tests[i].clsid, NULL, NULL, NULL); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Test %u: expected hr == D3DRMERR_BADVALUE, got %#x.\n", i, hr); + ok(hr == D3DRMERR_BADVALUE, "Test %u: expected hr == D3DRMERR_BADVALUE, got %#x.\n", i, hr); hr = IDirect3DRM_CreateObject(d3drm1, tests[i].clsid, NULL, tests[i].iid, (void **)&unknown); - todo_wine ok(SUCCEEDED(hr), "Test %u: expected hr == D3DRM_OK, got %#x.\n", i, hr); + todo_wine_if(tests[i].todo) + ok(SUCCEEDED(hr), "Test %u: expected hr == D3DRM_OK, got %#x.\n", i, hr); if (SUCCEEDED(hr)) { ref2 = get_refcount((IUnknown *)d3drm1);