/*
 * Implementation of IDirect3DRM Interface
 *
 * Copyright 2010, 2012 Christian Costa
 * Copyright 2011 André Hentschel
 * Copyright 2016 Aaryaman Vasishta
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "wine/debug.h"

#define COBJMACROS

#include "winbase.h"
#include "wingdi.h"
#include "dxfile.h"
#include "rmxfguid.h"

#include "d3drm_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(d3drm);

static const char* get_IID_string(const GUID* guid)
{
    if (IsEqualGUID(guid, &IID_IDirect3DRMFrame))
        return "IID_IDirect3DRMFrame";
    else if (IsEqualGUID(guid, &IID_IDirect3DRMFrame2))
        return "IID_IDirect3DRMFrame2";
    else if (IsEqualGUID(guid, &IID_IDirect3DRMFrame3))
        return "IID_IDirect3DRMFrame3";
    else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder))
        return "IID_IDirect3DRMMeshBuilder";
    else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder2))
        return "IID_IDirect3DRMMeshBuilder2";
    else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder3))
        return "IID_IDirect3DRMMeshBuilder3";

    return "?";
}

struct d3drm
{
    IDirect3DRM IDirect3DRM_iface;
    IDirect3DRM2 IDirect3DRM2_iface;
    IDirect3DRM3 IDirect3DRM3_iface;
    LONG ref1, ref2, ref3, iface_count;
};

static inline struct d3drm *impl_from_IDirect3DRM(IDirect3DRM *iface)
{
    return CONTAINING_RECORD(iface, struct d3drm, IDirect3DRM_iface);
}

static inline struct d3drm *impl_from_IDirect3DRM2(IDirect3DRM2 *iface)
{
    return CONTAINING_RECORD(iface, struct d3drm, IDirect3DRM2_iface);
}

static inline struct d3drm *impl_from_IDirect3DRM3(IDirect3DRM3 *iface)
{
    return CONTAINING_RECORD(iface, struct d3drm, IDirect3DRM3_iface);
}

static void d3drm_destroy(struct d3drm *d3drm)
{
    HeapFree(GetProcessHeap(), 0, d3drm);
    TRACE("d3drm object %p is being destroyed.\n", d3drm);
}

static HRESULT WINAPI d3drm1_QueryInterface(IDirect3DRM *iface, REFIID riid, void **out)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);

    TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);

    if (IsEqualGUID(riid, &IID_IDirect3DRM)
            || IsEqualGUID(riid, &IID_IUnknown))
    {
        *out = &d3drm->IDirect3DRM_iface;
    }
    else if (IsEqualGUID(riid, &IID_IDirect3DRM2))
    {
        *out = &d3drm->IDirect3DRM2_iface;
    }
    else if (IsEqualGUID(riid, &IID_IDirect3DRM3))
    {
        *out = &d3drm->IDirect3DRM3_iface;
    }
    else
    {
        *out = NULL;
        WARN("%s not implemented, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(riid));
        return CLASS_E_CLASSNOTAVAILABLE;
    }

    IUnknown_AddRef((IUnknown *)*out);
    return S_OK;
}

static ULONG WINAPI d3drm1_AddRef(IDirect3DRM *iface)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
    ULONG refcount = InterlockedIncrement(&d3drm->ref1);

    TRACE("%p increasing refcount to %u.\n", iface, refcount);

    if (refcount == 1)
        InterlockedIncrement(&d3drm->iface_count);

    return refcount;
}

static ULONG WINAPI d3drm1_Release(IDirect3DRM *iface)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
    ULONG refcount = InterlockedDecrement(&d3drm->ref1);

    TRACE("%p decreasing refcount to %u.\n", iface, refcount);

    if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
        d3drm_destroy(d3drm);

    return refcount;
}

static HRESULT WINAPI d3drm1_CreateObject(IDirect3DRM *iface,
        REFCLSID clsid, IUnknown *outer, REFIID iid, void **out)
{
    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 IDirect3DRM3_CreateObject(&d3drm->IDirect3DRM3_iface, clsid, outer, iid, out);
}

static HRESULT WINAPI d3drm1_CreateFrame(IDirect3DRM *iface,
        IDirect3DRMFrame *parent_frame, IDirect3DRMFrame **frame)
{
    TRACE("iface %p, parent_frame %p, frame %p.\n", iface, parent_frame, frame);

    return Direct3DRMFrame_create(&IID_IDirect3DRMFrame, (IUnknown *)parent_frame, (IUnknown **)frame);
}

static HRESULT WINAPI d3drm1_CreateMesh(IDirect3DRM *iface, IDirect3DRMMesh **mesh)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);

    TRACE("iface %p, mesh %p.\n", iface, mesh);

    return IDirect3DRM3_CreateMesh(&d3drm->IDirect3DRM3_iface, mesh);
}

static HRESULT WINAPI d3drm1_CreateMeshBuilder(IDirect3DRM *iface, IDirect3DRMMeshBuilder **mesh_builder)
{
    TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);

    return Direct3DRMMeshBuilder_create(&IID_IDirect3DRMMeshBuilder, (IUnknown **)mesh_builder);
}

static HRESULT WINAPI d3drm1_CreateFace(IDirect3DRM *iface, IDirect3DRMFace **face)
{
    TRACE("iface %p, face %p.\n", iface, face);

    return Direct3DRMFace_create(&IID_IDirect3DRMFace, (IUnknown **)face);
}

static HRESULT WINAPI d3drm1_CreateAnimation(IDirect3DRM *iface, IDirect3DRMAnimation **animation)
{
    FIXME("iface %p, animation %p stub!\n", iface, animation);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm1_CreateAnimationSet(IDirect3DRM *iface, IDirect3DRMAnimationSet **set)
{
    FIXME("iface %p, set %p stub!\n", iface, set);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm1_CreateTexture(IDirect3DRM *iface,
        D3DRMIMAGE *image, IDirect3DRMTexture **texture)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
    IDirect3DRMTexture3 *texture3;
    HRESULT hr;

    TRACE("iface %p, image %p, texture %p.\n", iface, image, texture);

    if (!texture)
        return D3DRMERR_BADVALUE;

    if (FAILED(hr = IDirect3DRM3_CreateTexture(&d3drm->IDirect3DRM3_iface, image, &texture3)))
    {
        *texture = NULL;
        return hr;
    }

    hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture, (void **)texture);
    IDirect3DRMTexture3_Release(texture3);

    return hr;
}

static HRESULT WINAPI d3drm1_CreateLight(IDirect3DRM *iface,
        D3DRMLIGHTTYPE type, D3DCOLOR color, IDirect3DRMLight **light)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);

    TRACE("iface %p, type %#x, color 0x%08x, light %p.\n", iface, type, color, light);

    return IDirect3DRM3_CreateLight(&d3drm->IDirect3DRM3_iface, type, color, light);
}

static HRESULT WINAPI d3drm1_CreateLightRGB(IDirect3DRM *iface, D3DRMLIGHTTYPE type,
        D3DVALUE red, D3DVALUE green, D3DVALUE blue, IDirect3DRMLight **light)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);

    TRACE("iface %p, type %#x, red %.8e, green %.8e, blue %.8e, light %p.\n",
            iface, type, red, green, blue, light);

    return IDirect3DRM3_CreateLightRGB(&d3drm->IDirect3DRM3_iface, type, red, green, blue, light);
}

static HRESULT WINAPI d3drm1_CreateMaterial(IDirect3DRM *iface,
        D3DVALUE power, IDirect3DRMMaterial **material)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);

    TRACE("iface %p, power %.8e, material %p.\n", iface, power, material);

    return IDirect3DRM3_CreateMaterial(&d3drm->IDirect3DRM3_iface, power, (IDirect3DRMMaterial2 **)material);
}

static HRESULT WINAPI d3drm1_CreateDevice(IDirect3DRM *iface,
        DWORD width, DWORD height, IDirect3DRMDevice **device)
{
    struct d3drm_device *object;
    HRESULT hr;
    FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);

    hr = d3drm_device_create(&object);
    if (FAILED(hr))
        return hr;

    *device = IDirect3DRMDevice_from_impl(object);

    return D3DRM_OK;
}

static HRESULT WINAPI d3drm1_CreateDeviceFromSurface(IDirect3DRM *iface, GUID *guid,
        IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, IDirect3DRMDevice **device)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
    struct d3drm_device *object;
    HRESULT hr;

    TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, device %p.\n",
            iface, debugstr_guid(guid), ddraw, backbuffer, device);

    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;

    if (!backbuffer || !ddraw)
        return D3DRMERR_BADDEVICE;

    hr = d3drm_device_create(&object);
    if (FAILED(hr))
        return hr;

    hr = d3drm_device_init(object, 1, &d3drm->IDirect3DRM_iface, ddraw, backbuffer, TRUE);
    if (SUCCEEDED(hr))
        *device = IDirect3DRMDevice_from_impl(object);
    else
        d3drm_device_destroy(object);

    return hr;
}

static HRESULT WINAPI d3drm1_CreateDeviceFromD3D(IDirect3DRM *iface,
        IDirect3D *d3d, IDirect3DDevice *d3d_device, IDirect3DRMDevice **device)
{
    struct d3drm_device *object;
    HRESULT hr;
    TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
            iface, d3d, d3d_device, device);

    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;
    if (!d3d || !d3d_device)
        return D3DRMERR_BADVALUE;

    hr = d3drm_device_create(&object);
    if (FAILED(hr))
        return hr;

    hr = d3drm_device_set_ddraw_device_d3d(object, iface, d3d, d3d_device);
    if (FAILED(hr))
    {
        d3drm_device_destroy(object);
        return hr;
    }
    *device = IDirect3DRMDevice_from_impl(object);

    return D3DRM_OK;
}

static HRESULT WINAPI d3drm1_CreateDeviceFromClipper(IDirect3DRM *iface,
        IDirectDrawClipper *clipper, GUID *guid, int width, int height,
        IDirect3DRMDevice **device)
{
    struct d3drm_device *object;
    IDirectDraw *ddraw;
    IDirectDrawSurface *render_target;
    HRESULT hr;

    TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
            iface, clipper, debugstr_guid(guid), width, height, device);

    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;

    if (!clipper || !width || !height)
        return D3DRMERR_BADVALUE;

    hr = DirectDrawCreate(NULL, &ddraw, NULL);
    if (FAILED(hr))
        return hr;

    hr = d3drm_device_create(&object);
    if (FAILED(hr))
    {
        IDirectDraw_Release(ddraw);
        return hr;
    }

    hr = d3drm_device_create_surfaces_from_clipper(object, ddraw, clipper, width, height, &render_target);
    if (FAILED(hr))
    {
        IDirectDraw_Release(ddraw);
        d3drm_device_destroy(object);
        return hr;
    }

    hr = d3drm_device_init(object, 1, iface, ddraw, render_target, TRUE);
    IDirectDraw_Release(ddraw);
    IDirectDrawSurface_Release(render_target);
    if (FAILED(hr))
        d3drm_device_destroy(object);
    else
        *device = IDirect3DRMDevice_from_impl(object);

    return hr;
}

static HRESULT WINAPI d3drm1_CreateTextureFromSurface(IDirect3DRM *iface,
        IDirectDrawSurface *surface, IDirect3DRMTexture **texture)
{
    FIXME("iface %p, surface %p, texture %p stub!\n", iface, surface, texture);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm1_CreateShadow(IDirect3DRM *iface, IDirect3DRMVisual *visual,
        IDirect3DRMLight *light, D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz,
        IDirect3DRMVisual **shadow)
{
    FIXME("iface %p, visual %p, light %p, px %.8e, py %.8e, pz %.8e, nx %.8e, ny %.8e, nz %.8e, shadow %p stub!\n",
            iface, visual, light, px, py, pz, nx, ny, nz, shadow);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm1_CreateViewport(IDirect3DRM *iface, IDirect3DRMDevice *device,
        IDirect3DRMFrame *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport **viewport)
{
    FIXME("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p partial stub!\n",
            iface, device, camera, x, y, width, height, viewport);

    return Direct3DRMViewport_create(&IID_IDirect3DRMViewport, (IUnknown **)viewport);
}

static HRESULT WINAPI d3drm1_CreateWrap(IDirect3DRM *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame *frame,
        D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz,
        D3DVALUE ux, D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv,
        IDirect3DRMWrap **wrap)
{
    FIXME("iface %p, type %#x, frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, "
            "ux %.8e, uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e, wrap %p stub!\n",
            iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm1_CreateUserVisual(IDirect3DRM *iface,
        D3DRMUSERVISUALCALLBACK cb, void *ctx, IDirect3DRMUserVisual **visual)
{
    FIXME("iface %p, cb %p, ctx %p visual %p stub!\n", iface, cb, ctx, visual);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm1_LoadTexture(IDirect3DRM *iface,
        const char *filename, IDirect3DRMTexture **texture)
{
    struct d3drm_texture *object;
    HRESULT hr;

    FIXME("iface %p, filename %s, texture %p stub!\n", iface, debugstr_a(filename), texture);

    if (FAILED(hr = d3drm_texture_create(&object, iface)))
        return hr;

    *texture = &object->IDirect3DRMTexture_iface;

    return D3DRM_OK;
}

static HRESULT WINAPI d3drm1_LoadTextureFromResource(IDirect3DRM *iface,
        HRSRC resource, IDirect3DRMTexture **texture)
{
    struct d3drm_texture *object;
    HRESULT hr;

    FIXME("iface %p, resource %p, texture %p stub!\n", iface, resource, texture);

    if (FAILED(hr = d3drm_texture_create(&object, iface)))
        return hr;

    *texture = &object->IDirect3DRMTexture_iface;

    return D3DRM_OK;
}

static HRESULT WINAPI d3drm1_SetSearchPath(IDirect3DRM *iface, const char *path)
{
    FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm1_AddSearchPath(IDirect3DRM *iface, const char *path)
{
    FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm1_GetSearchPath(IDirect3DRM *iface, DWORD *size, char *path)
{
    FIXME("iface %p, size %p, path %p stub!\n", iface, size, path);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm1_SetDefaultTextureColors(IDirect3DRM *iface, DWORD color_count)
{
    FIXME("iface %p, color_count %u stub!\n", iface, color_count);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm1_SetDefaultTextureShades(IDirect3DRM *iface, DWORD shade_count)
{
    FIXME("iface %p, shade_count %u stub!\n", iface, shade_count);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm1_GetDevices(IDirect3DRM *iface, IDirect3DRMDeviceArray **array)
{
    FIXME("iface %p, array %p stub!\n", iface, array);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm1_GetNamedObject(IDirect3DRM *iface,
        const char *name, IDirect3DRMObject **object)
{
    FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm1_EnumerateObjects(IDirect3DRM *iface, D3DRMOBJECTCALLBACK cb, void *ctx)
{
    FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm1_Load(IDirect3DRM *iface, void *source, void *object_id, IID **iids,
        DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
        D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame *parent_frame)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
    IDirect3DRMFrame3 *parent_frame3 = NULL;
    HRESULT hr = D3DRM_OK;

    TRACE("iface %p, source %p, object_id %p, iids %p, iid_count %u, flags %#x, "
            "load_cb %p, load_ctx %p, load_tex_cb %p, load_tex_ctx %p, parent_frame %p.\n",
            iface, source, object_id, iids, iid_count, flags,
            load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);

    if (parent_frame)
        hr = IDirect3DRMFrame_QueryInterface(parent_frame, &IID_IDirect3DRMFrame3, (void **)&parent_frame3);
    if (SUCCEEDED(hr))
        hr = IDirect3DRM3_Load(&d3drm->IDirect3DRM3_iface, source, object_id, iids, iid_count,
                flags, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame3);
    if (parent_frame3)
        IDirect3DRMFrame3_Release(parent_frame3);

    return hr;
}

static HRESULT WINAPI d3drm1_Tick(IDirect3DRM *iface, D3DVALUE tick)
{
    FIXME("iface %p, tick %.8e stub!\n", iface, tick);

    return E_NOTIMPL;
}

static const struct IDirect3DRMVtbl d3drm1_vtbl =
{
    d3drm1_QueryInterface,
    d3drm1_AddRef,
    d3drm1_Release,
    d3drm1_CreateObject,
    d3drm1_CreateFrame,
    d3drm1_CreateMesh,
    d3drm1_CreateMeshBuilder,
    d3drm1_CreateFace,
    d3drm1_CreateAnimation,
    d3drm1_CreateAnimationSet,
    d3drm1_CreateTexture,
    d3drm1_CreateLight,
    d3drm1_CreateLightRGB,
    d3drm1_CreateMaterial,
    d3drm1_CreateDevice,
    d3drm1_CreateDeviceFromSurface,
    d3drm1_CreateDeviceFromD3D,
    d3drm1_CreateDeviceFromClipper,
    d3drm1_CreateTextureFromSurface,
    d3drm1_CreateShadow,
    d3drm1_CreateViewport,
    d3drm1_CreateWrap,
    d3drm1_CreateUserVisual,
    d3drm1_LoadTexture,
    d3drm1_LoadTextureFromResource,
    d3drm1_SetSearchPath,
    d3drm1_AddSearchPath,
    d3drm1_GetSearchPath,
    d3drm1_SetDefaultTextureColors,
    d3drm1_SetDefaultTextureShades,
    d3drm1_GetDevices,
    d3drm1_GetNamedObject,
    d3drm1_EnumerateObjects,
    d3drm1_Load,
    d3drm1_Tick,
};

static HRESULT WINAPI d3drm2_QueryInterface(IDirect3DRM2 *iface, REFIID riid, void **out)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);

    return d3drm1_QueryInterface(&d3drm->IDirect3DRM_iface, riid, out);
}

static ULONG WINAPI d3drm2_AddRef(IDirect3DRM2 *iface)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
    ULONG refcount = InterlockedIncrement(&d3drm->ref2);

    TRACE("%p increasing refcount to %u.\n", iface, refcount);

    if (refcount == 1)
        InterlockedIncrement(&d3drm->iface_count);

    return refcount;
}

static ULONG WINAPI d3drm2_Release(IDirect3DRM2 *iface)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
    ULONG refcount = InterlockedDecrement(&d3drm->ref2);

    TRACE("%p decreasing refcount to %u.\n", iface, refcount);

    if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
        d3drm_destroy(d3drm);

    return refcount;
}

static HRESULT WINAPI d3drm2_CreateObject(IDirect3DRM2 *iface,
        REFCLSID clsid, IUnknown *outer, REFIID iid, void **out)
{
    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 IDirect3DRM3_CreateObject(&d3drm->IDirect3DRM3_iface, clsid, outer, iid, out);
}

static HRESULT WINAPI d3drm2_CreateFrame(IDirect3DRM2 *iface,
        IDirect3DRMFrame *parent_frame, IDirect3DRMFrame2 **frame)
{
    TRACE("iface %p, parent_frame %p, frame %p.\n", iface, parent_frame, frame);

    return Direct3DRMFrame_create(&IID_IDirect3DRMFrame2, (IUnknown*)parent_frame, (IUnknown**)frame);
}

static HRESULT WINAPI d3drm2_CreateMesh(IDirect3DRM2 *iface, IDirect3DRMMesh **mesh)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);

    TRACE("iface %p, mesh %p.\n", iface, mesh);

    return IDirect3DRM3_CreateMesh(&d3drm->IDirect3DRM3_iface, mesh);
}

static HRESULT WINAPI d3drm2_CreateMeshBuilder(IDirect3DRM2 *iface, IDirect3DRMMeshBuilder2 **mesh_builder)
{
    TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);

    return Direct3DRMMeshBuilder_create(&IID_IDirect3DRMMeshBuilder2, (IUnknown **)mesh_builder);
}

static HRESULT WINAPI d3drm2_CreateFace(IDirect3DRM2 *iface, IDirect3DRMFace **face)
{
    TRACE("iface %p, face %p.\n", iface, face);

    return Direct3DRMFace_create(&IID_IDirect3DRMFace, (IUnknown **)face);
}

static HRESULT WINAPI d3drm2_CreateAnimation(IDirect3DRM2 *iface, IDirect3DRMAnimation **animation)
{
    FIXME("iface %p, animation %p stub!\n", iface, animation);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm2_CreateAnimationSet(IDirect3DRM2 *iface, IDirect3DRMAnimationSet **set)
{
    FIXME("iface %p, set %p stub!\n", iface, set);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm2_CreateTexture(IDirect3DRM2 *iface,
        D3DRMIMAGE *image, IDirect3DRMTexture2 **texture)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
    IDirect3DRMTexture3 *texture3;
    HRESULT hr;

    TRACE("iface %p, image %p, texture %p.\n", iface, image, texture);

    if (!texture)
        return D3DRMERR_BADVALUE;

    if (FAILED(hr = IDirect3DRM3_CreateTexture(&d3drm->IDirect3DRM3_iface, image, &texture3)))
    {
        *texture = NULL;
        return hr;
    }

    hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture2, (void **)texture);
    IDirect3DRMTexture3_Release(texture3);

    return hr;
}

static HRESULT WINAPI d3drm2_CreateLight(IDirect3DRM2 *iface,
        D3DRMLIGHTTYPE type, D3DCOLOR color, IDirect3DRMLight **light)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);

    TRACE("iface %p, type %#x, color 0x%08x, light %p.\n", iface, type, color, light);

    return IDirect3DRM3_CreateLight(&d3drm->IDirect3DRM3_iface, type, color, light);
}

static HRESULT WINAPI d3drm2_CreateLightRGB(IDirect3DRM2 *iface, D3DRMLIGHTTYPE type,
        D3DVALUE red, D3DVALUE green, D3DVALUE blue, IDirect3DRMLight **light)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);

    TRACE("iface %p, type %#x, red %.8e, green %.8e, blue %.8e, light %p.\n",
            iface, type, red, green, blue, light);

    return IDirect3DRM3_CreateLightRGB(&d3drm->IDirect3DRM3_iface, type, red, green, blue, light);
}

static HRESULT WINAPI d3drm2_CreateMaterial(IDirect3DRM2 *iface,
        D3DVALUE power, IDirect3DRMMaterial **material)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);

    TRACE("iface %p, power %.8e, material %p.\n", iface, power, material);

    return IDirect3DRM3_CreateMaterial(&d3drm->IDirect3DRM3_iface, power, (IDirect3DRMMaterial2 **)material);
}

static HRESULT WINAPI d3drm2_CreateDevice(IDirect3DRM2 *iface,
        DWORD width, DWORD height, IDirect3DRMDevice2 **device)
{
    struct d3drm_device *object;
    HRESULT hr;
    FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);

    hr = d3drm_device_create(&object);
    if (FAILED(hr))
        return hr;

    *device = IDirect3DRMDevice2_from_impl(object);

    return D3DRM_OK;
}

static HRESULT WINAPI d3drm2_CreateDeviceFromSurface(IDirect3DRM2 *iface, GUID *guid,
        IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, IDirect3DRMDevice2 **device)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
    IDirect3DRMDevice3 *device3;
    HRESULT hr;
    TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, device %p.\n",
            iface, debugstr_guid(guid), ddraw, backbuffer, device);

    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;
    hr = IDirect3DRM3_CreateDeviceFromSurface(&d3drm->IDirect3DRM3_iface, guid, ddraw, backbuffer, 0, &device3);
    if (FAILED(hr))
        return hr;

    hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice2, (void**)device);
    IDirect3DRMDevice3_Release(device3);

    return hr;
}

static HRESULT WINAPI d3drm2_CreateDeviceFromD3D(IDirect3DRM2 *iface,
    IDirect3D2 *d3d, IDirect3DDevice2 *d3d_device, IDirect3DRMDevice2 **device)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
    IDirect3D *d3d1;
    IDirect3DDevice *d3d_device1;
    IDirect3DRMDevice *device1;
    HRESULT hr;
    TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
            iface, d3d, d3d_device, device);

    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;
    if (!d3d || !d3d_device)
        return D3DRMERR_BADVALUE;

    hr = IDirect3D2_QueryInterface(d3d, &IID_IDirect3D, (void **)&d3d1);
    if (FAILED(hr))
        return hr;

    hr = IDirect3DDevice2_QueryInterface(d3d_device, &IID_IDirect3DDevice, (void **)&d3d_device1);
    if (FAILED(hr))
    {
        IDirect3D_Release(d3d1);
        return hr;
    }

    hr = IDirect3DRM_CreateDeviceFromD3D(&d3drm->IDirect3DRM_iface, d3d1, d3d_device1, &device1);
    IDirect3D_Release(d3d1);
    IDirect3DDevice_Release(d3d_device1);
    if (FAILED(hr))
        return hr;

    hr = IDirect3DRMDevice_QueryInterface(device1, &IID_IDirect3DRMDevice2, (void **)device);
    IDirect3DRMDevice_Release(device1);

    return hr;
}

static HRESULT WINAPI d3drm2_CreateDeviceFromClipper(IDirect3DRM2 *iface,
        IDirectDrawClipper *clipper, GUID *guid, int width, int height,
        IDirect3DRMDevice2 **device)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
    IDirect3DRMDevice3 *device3;
    HRESULT hr;

    TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
            iface, clipper, debugstr_guid(guid), width, height, device);

    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;
    hr = IDirect3DRM3_CreateDeviceFromClipper(&d3drm->IDirect3DRM3_iface, clipper, guid, width, height, &device3);
    if (FAILED(hr))
        return hr;

    hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice2, (void**)device);
    IDirect3DRMDevice3_Release(device3);

    return hr;
}

static HRESULT WINAPI d3drm2_CreateTextureFromSurface(IDirect3DRM2 *iface,
        IDirectDrawSurface *surface, IDirect3DRMTexture2 **texture)
{
    FIXME("iface %p, surface %p, texture %p stub!\n", iface, surface, texture);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm2_CreateShadow(IDirect3DRM2 *iface, IDirect3DRMVisual *visual,
        IDirect3DRMLight *light, D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz,
        IDirect3DRMVisual **shadow)
{
    FIXME("iface %p, visual %p, light %p, px %.8e, py %.8e, pz %.8e, nx %.8e, ny %.8e, nz %.8e, shadow %p stub!\n",
            iface, visual, light, px, py, pz, nx, ny, nz, shadow);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm2_CreateViewport(IDirect3DRM2 *iface, IDirect3DRMDevice *device,
        IDirect3DRMFrame *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport **viewport)
{
    FIXME("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p partial stub!\n",
            iface, device, camera, x, y, width, height, viewport);

    return Direct3DRMViewport_create(&IID_IDirect3DRMViewport, (IUnknown **)viewport);
}

static HRESULT WINAPI d3drm2_CreateWrap(IDirect3DRM2 *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame *frame,
        D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz,
        D3DVALUE ux, D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv,
        IDirect3DRMWrap **wrap)
{
    FIXME("iface %p, type %#x, frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, "
            "ux %.8e, uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e, wrap %p stub!\n",
            iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm2_CreateUserVisual(IDirect3DRM2 *iface,
        D3DRMUSERVISUALCALLBACK cb, void *ctx, IDirect3DRMUserVisual **visual)
{
    FIXME("iface %p, cb %p, ctx %p, visual %p stub!\n", iface, cb, ctx, visual);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm2_LoadTexture(IDirect3DRM2 *iface,
        const char *filename, IDirect3DRMTexture2 **texture)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
    struct d3drm_texture *object;
    HRESULT hr;

    FIXME("iface %p, filename %s, texture %p stub!\n", iface, debugstr_a(filename), texture);

    if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
        return hr;

    *texture = &object->IDirect3DRMTexture2_iface;

    return hr;
}

static HRESULT WINAPI d3drm2_LoadTextureFromResource(IDirect3DRM2 *iface, HMODULE module,
        const char *resource_name, const char *resource_type, IDirect3DRMTexture2 **texture)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
    struct d3drm_texture *object;
    HRESULT hr;

    FIXME("iface %p, resource_name %s, resource_type %s, texture %p stub!\n",
            iface, debugstr_a(resource_name), debugstr_a(resource_type), texture);

    if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
        return hr;

    *texture = &object->IDirect3DRMTexture2_iface;

    return D3DRM_OK;
}

static HRESULT WINAPI d3drm2_SetSearchPath(IDirect3DRM2 *iface, const char *path)
{
    FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm2_AddSearchPath(IDirect3DRM2 *iface, const char *path)
{
    FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm2_GetSearchPath(IDirect3DRM2 *iface, DWORD *size, char *path)
{
    FIXME("iface %p, size %p, path %p stub!\n", iface, size, path);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm2_SetDefaultTextureColors(IDirect3DRM2 *iface, DWORD color_count)
{
    FIXME("iface %p, color_count %u stub!\n", iface, color_count);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm2_SetDefaultTextureShades(IDirect3DRM2 *iface, DWORD shade_count)
{
    FIXME("iface %p, shade_count %u stub!\n", iface, shade_count);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm2_GetDevices(IDirect3DRM2 *iface, IDirect3DRMDeviceArray **array)
{
    FIXME("iface %p, array %p stub!\n", iface, array);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm2_GetNamedObject(IDirect3DRM2 *iface,
        const char *name, IDirect3DRMObject **object)
{
    FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm2_EnumerateObjects(IDirect3DRM2 *iface, D3DRMOBJECTCALLBACK cb, void *ctx)
{
    FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm2_Load(IDirect3DRM2 *iface, void *source, void *object_id, IID **iids,
        DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
        D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame *parent_frame)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
    IDirect3DRMFrame3 *parent_frame3 = NULL;
    HRESULT hr = D3DRM_OK;

    TRACE("iface %p, source %p, object_id %p, iids %p, iid_count %u, flags %#x, "
            "load_cb %p, load_ctx %p, load_tex_cb %p, load_tex_ctx %p, parent_frame %p.\n",
            iface, source, object_id, iids, iid_count, flags,
            load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);

    if (parent_frame)
        hr = IDirect3DRMFrame_QueryInterface(parent_frame, &IID_IDirect3DRMFrame3, (void **)&parent_frame3);
    if (SUCCEEDED(hr))
        hr = IDirect3DRM3_Load(&d3drm->IDirect3DRM3_iface, source, object_id, iids, iid_count,
                flags, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame3);
    if (parent_frame3)
        IDirect3DRMFrame3_Release(parent_frame3);

    return hr;
}

static HRESULT WINAPI d3drm2_Tick(IDirect3DRM2 *iface, D3DVALUE tick)
{
    FIXME("iface %p, tick %.8e stub!\n", iface, tick);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm2_CreateProgressiveMesh(IDirect3DRM2 *iface, IDirect3DRMProgressiveMesh **mesh)
{
    FIXME("iface %p, mesh %p stub!\n", iface, mesh);

    return E_NOTIMPL;
}

static const struct IDirect3DRM2Vtbl d3drm2_vtbl =
{
    d3drm2_QueryInterface,
    d3drm2_AddRef,
    d3drm2_Release,
    d3drm2_CreateObject,
    d3drm2_CreateFrame,
    d3drm2_CreateMesh,
    d3drm2_CreateMeshBuilder,
    d3drm2_CreateFace,
    d3drm2_CreateAnimation,
    d3drm2_CreateAnimationSet,
    d3drm2_CreateTexture,
    d3drm2_CreateLight,
    d3drm2_CreateLightRGB,
    d3drm2_CreateMaterial,
    d3drm2_CreateDevice,
    d3drm2_CreateDeviceFromSurface,
    d3drm2_CreateDeviceFromD3D,
    d3drm2_CreateDeviceFromClipper,
    d3drm2_CreateTextureFromSurface,
    d3drm2_CreateShadow,
    d3drm2_CreateViewport,
    d3drm2_CreateWrap,
    d3drm2_CreateUserVisual,
    d3drm2_LoadTexture,
    d3drm2_LoadTextureFromResource,
    d3drm2_SetSearchPath,
    d3drm2_AddSearchPath,
    d3drm2_GetSearchPath,
    d3drm2_SetDefaultTextureColors,
    d3drm2_SetDefaultTextureShades,
    d3drm2_GetDevices,
    d3drm2_GetNamedObject,
    d3drm2_EnumerateObjects,
    d3drm2_Load,
    d3drm2_Tick,
    d3drm2_CreateProgressiveMesh,
};

static HRESULT WINAPI d3drm3_QueryInterface(IDirect3DRM3 *iface, REFIID riid, void **out)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);

    return d3drm1_QueryInterface(&d3drm->IDirect3DRM_iface, riid, out);
}

static ULONG WINAPI d3drm3_AddRef(IDirect3DRM3 *iface)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    ULONG refcount = InterlockedIncrement(&d3drm->ref3);

    TRACE("%p increasing refcount to %u.\n", iface, refcount);

    if (refcount == 1)
        InterlockedIncrement(&d3drm->iface_count);

    return refcount;
}

static ULONG WINAPI d3drm3_Release(IDirect3DRM3 *iface)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    ULONG refcount = InterlockedDecrement(&d3drm->ref3);

    TRACE("%p decreasing refcount to %u.\n", iface, refcount);

    if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
        d3drm_destroy(d3drm);

    return refcount;
}

static HRESULT WINAPI d3drm3_CreateObject(IDirect3DRM3 *iface,
        REFCLSID clsid, IUnknown *outer, REFIID iid, void **out)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    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);

    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, &d3drm->IDirect3DRM_iface)))
        {
            *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,
        IDirect3DRMFrame3 *parent, IDirect3DRMFrame3 **frame)
{
    TRACE("iface %p, parent %p, frame %p.\n", iface, parent, frame);

    return Direct3DRMFrame_create(&IID_IDirect3DRMFrame3, (IUnknown *)parent, (IUnknown **)frame);
}

static HRESULT WINAPI d3drm3_CreateMesh(IDirect3DRM3 *iface, IDirect3DRMMesh **mesh)
{
    TRACE("iface %p, mesh %p.\n", iface, mesh);

    return Direct3DRMMesh_create(mesh);
}

static HRESULT WINAPI d3drm3_CreateMeshBuilder(IDirect3DRM3 *iface, IDirect3DRMMeshBuilder3 **mesh_builder)
{
    TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);

    return Direct3DRMMeshBuilder_create(&IID_IDirect3DRMMeshBuilder3, (IUnknown **)mesh_builder);
}

static HRESULT WINAPI d3drm3_CreateFace(IDirect3DRM3 *iface, IDirect3DRMFace2 **face)
{
    TRACE("iface %p, face %p.\n", iface, face);

    return Direct3DRMFace_create(&IID_IDirect3DRMFace2, (IUnknown **)face);
}

static HRESULT WINAPI d3drm3_CreateAnimation(IDirect3DRM3 *iface, IDirect3DRMAnimation2 **animation)
{
    FIXME("iface %p, animation %p stub!\n", iface, animation);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm3_CreateAnimationSet(IDirect3DRM3 *iface, IDirect3DRMAnimationSet2 **set)
{
    FIXME("iface %p, set %p stub!\n", iface, set);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm3_CreateTexture(IDirect3DRM3 *iface,
        D3DRMIMAGE *image, IDirect3DRMTexture3 **texture)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_texture *object;
    HRESULT hr;

    TRACE("iface %p, image %p, texture %p.\n", iface, image, texture);

    if (!texture)
        return D3DRMERR_BADVALUE;

    if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
        return hr;

    *texture = &object->IDirect3DRMTexture3_iface;

    if (FAILED(IDirect3DRMTexture3_InitFromImage(*texture, image)))
    {
        IDirect3DRMTexture3_Release(*texture);
        *texture = NULL;
        return D3DRMERR_BADVALUE;
    }

    return D3DRM_OK;
}

static HRESULT WINAPI d3drm3_CreateLight(IDirect3DRM3 *iface,
        D3DRMLIGHTTYPE type, D3DCOLOR color, IDirect3DRMLight **light)
{
    HRESULT hr;

    FIXME("iface %p, type %#x, color 0x%08x, light %p partial stub!\n", iface, type, color, light);

    if (SUCCEEDED(hr = Direct3DRMLight_create((IUnknown **)light)))
    {
        IDirect3DRMLight_SetType(*light, type);
        IDirect3DRMLight_SetColor(*light, color);
    }

    return hr;
}

static HRESULT WINAPI d3drm3_CreateLightRGB(IDirect3DRM3 *iface, D3DRMLIGHTTYPE type,
        D3DVALUE red, D3DVALUE green, D3DVALUE blue, IDirect3DRMLight **light)
{
    HRESULT hr;

    FIXME("iface %p, type %#x, red %.8e, green %.8e, blue %.8e, light %p partial stub!\n",
            iface, type, red, green, blue, light);

    if (SUCCEEDED(hr = Direct3DRMLight_create((IUnknown **)light)))
    {
        IDirect3DRMLight_SetType(*light, type);
        IDirect3DRMLight_SetColorRGB(*light, red, green, blue);
    }

    return hr;
}

static HRESULT WINAPI d3drm3_CreateMaterial(IDirect3DRM3 *iface,
        D3DVALUE power, IDirect3DRMMaterial2 **material)
{
    HRESULT hr;

    TRACE("iface %p, power %.8e, material %p.\n", iface, power, material);

    if (SUCCEEDED(hr = Direct3DRMMaterial_create(material)))
        IDirect3DRMMaterial2_SetPower(*material, power);

    return hr;
}

static HRESULT WINAPI d3drm3_CreateDevice(IDirect3DRM3 *iface,
        DWORD width, DWORD height, IDirect3DRMDevice3 **device)
{
    struct d3drm_device *object;
    HRESULT hr;
    FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);

    hr = d3drm_device_create(&object);
    if (FAILED(hr))
        return hr;

    *device = IDirect3DRMDevice3_from_impl(object);

    return D3DRM_OK;
}

static HRESULT WINAPI d3drm3_CreateDeviceFromSurface(IDirect3DRM3 *iface, GUID *guid,
        IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, DWORD flags, IDirect3DRMDevice3 **device)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_device *object;
    BOOL use_z_surface;
    HRESULT hr;

    TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, flags %#x, device %p.\n",
            iface, debugstr_guid(guid), ddraw, backbuffer, flags, device);

    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;

    if (!backbuffer || !ddraw)
        return D3DRMERR_BADDEVICE;

    hr = d3drm_device_create(&object);
    if (FAILED(hr))
        return hr;

    use_z_surface = !(flags & D3DRMDEVICE_NOZBUFFER);

    hr = d3drm_device_init(object, 3, &d3drm->IDirect3DRM_iface, ddraw, backbuffer, use_z_surface);
    if (SUCCEEDED(hr))
        *device = IDirect3DRMDevice3_from_impl(object);
    else
        d3drm_device_destroy(object);

    return hr;
}

static HRESULT WINAPI d3drm3_CreateDeviceFromD3D(IDirect3DRM3 *iface,
        IDirect3D2 *d3d, IDirect3DDevice2 *d3d_device, IDirect3DRMDevice3 **device)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    IDirect3D *d3d1;
    IDirect3DDevice *d3d_device1;
    IDirect3DRMDevice *device1;
    HRESULT hr;
    TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
            iface, d3d, d3d_device, device);

    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;
    if (!d3d || !d3d_device)
        return D3DRMERR_BADVALUE;

    hr = IDirect3D2_QueryInterface(d3d, &IID_IDirect3D, (void **)&d3d1);
    if (FAILED(hr))
        return hr;
    hr = IDirect3DDevice2_QueryInterface(d3d_device, &IID_IDirect3DDevice, (void **)&d3d_device1);
    if (FAILED(hr))
    {
        IDirect3D_Release(d3d1);
        return hr;
    }

    hr = IDirect3DRM_CreateDeviceFromD3D(&d3drm->IDirect3DRM_iface, d3d1, d3d_device1, &device1);
    IDirect3D_Release(d3d1);
    IDirect3DDevice_Release(d3d_device1);
    if (FAILED(hr))
        return hr;

    hr = IDirect3DRMDevice_QueryInterface(device1, &IID_IDirect3DRMDevice3, (void **)device);
    IDirect3DRMDevice_Release(device1);

    return hr;
}

static HRESULT WINAPI d3drm3_CreateDeviceFromClipper(IDirect3DRM3 *iface,
        IDirectDrawClipper *clipper, GUID *guid, int width, int height,
        IDirect3DRMDevice3 **device)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_device *object;
    IDirectDraw *ddraw;
    IDirectDrawSurface *render_target;
    HRESULT hr;

    TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
            iface, clipper, debugstr_guid(guid), width, height, device);

    if (!device)
        return D3DRMERR_BADVALUE;
    *device = NULL;

    if (!clipper || !width || !height)
        return D3DRMERR_BADVALUE;

    hr = DirectDrawCreate(NULL, &ddraw, NULL);
    if (FAILED(hr))
        return hr;

    hr = d3drm_device_create(&object);
    if (FAILED(hr))
    {
        IDirectDraw_Release(ddraw);
        return hr;
    }

    hr = d3drm_device_create_surfaces_from_clipper(object, ddraw, clipper, width, height, &render_target);
    if (FAILED(hr))
    {
        IDirectDraw_Release(ddraw);
        d3drm_device_destroy(object);
        return hr;
    }

    hr = d3drm_device_init(object, 3, &d3drm->IDirect3DRM_iface, ddraw, render_target, TRUE);
    IDirectDraw_Release(ddraw);
    IDirectDrawSurface_Release(render_target);
    if (FAILED(hr))
        d3drm_device_destroy(object);
    else
        *device = IDirect3DRMDevice3_from_impl(object);

    return hr;
}

static HRESULT WINAPI d3drm3_CreateShadow(IDirect3DRM3 *iface, IUnknown *object, IDirect3DRMLight *light,
        D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz, IDirect3DRMShadow2 **shadow)
{
    FIXME("iface %p, object %p, light %p, px %.8e, py %.8e, pz %.8e, nx %.8e, ny %.8e, nz %.8e, shadow %p stub!\n",
            iface, object, light, px, py, pz, nx, ny, nz, shadow);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm3_CreateTextureFromSurface(IDirect3DRM3 *iface,
        IDirectDrawSurface *surface, IDirect3DRMTexture3 **texture)
{
    FIXME("iface %p, surface %p, texture %p stub!\n", iface, surface, texture);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm3_CreateViewport(IDirect3DRM3 *iface, IDirect3DRMDevice3 *device,
        IDirect3DRMFrame3 *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport2 **viewport)
{
    FIXME("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p partial stub!\n",
            iface, device, camera, x, y, width, height, viewport);

    return Direct3DRMViewport_create(&IID_IDirect3DRMViewport2, (IUnknown **)viewport);
}

static HRESULT WINAPI d3drm3_CreateWrap(IDirect3DRM3 *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame3 *frame,
        D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz,
        D3DVALUE ux, D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv,
        IDirect3DRMWrap **wrap)
{
    FIXME("iface %p, type %#x, frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, "
            "ux %.8e, uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e, wrap %p stub!\n",
            iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm3_CreateUserVisual(IDirect3DRM3 *iface,
        D3DRMUSERVISUALCALLBACK cb, void *ctx, IDirect3DRMUserVisual **visual)
{
    FIXME("iface %p, cb %p, ctx %p, visual %p stub!\n", iface, cb, ctx, visual);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm3_LoadTexture(IDirect3DRM3 *iface,
        const char *filename, IDirect3DRMTexture3 **texture)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_texture *object;
    HRESULT hr;

    FIXME("iface %p, filename %s, texture %p stub!\n", iface, debugstr_a(filename), texture);

    if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
        return hr;

    *texture = &object->IDirect3DRMTexture3_iface;

    return D3DRM_OK;
}

static HRESULT WINAPI d3drm3_LoadTextureFromResource(IDirect3DRM3 *iface, HMODULE module,
        const char *resource_name, const char *resource_type, IDirect3DRMTexture3 **texture)
{
    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
    struct d3drm_texture *object;
    HRESULT hr;

    FIXME("iface %p, module %p, resource_name %s, resource_type %s, texture %p stub!\n",
            iface, module, debugstr_a(resource_name), debugstr_a(resource_type), texture);

    if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
        return hr;

    *texture = &object->IDirect3DRMTexture3_iface;

    return D3DRM_OK;
}

static HRESULT WINAPI d3drm3_SetSearchPath(IDirect3DRM3 *iface, const char *path)
{
    FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm3_AddSearchPath(IDirect3DRM3 *iface, const char *path)
{
    FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm3_GetSearchPath(IDirect3DRM3 *iface, DWORD *size, char *path)
{
    FIXME("iface %p, size %p, path %p stub!\n", iface, size, path);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm3_SetDefaultTextureColors(IDirect3DRM3 *iface, DWORD color_count)
{
    FIXME("iface %p, color_count %u stub!\n", iface, color_count);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm3_SetDefaultTextureShades(IDirect3DRM3 *iface, DWORD shade_count)
{
    FIXME("iface %p, shade_count %u stub!\n", iface, shade_count);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm3_GetDevices(IDirect3DRM3 *iface, IDirect3DRMDeviceArray **array)
{
    FIXME("iface %p, array %p stub!\n", iface, array);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm3_GetNamedObject(IDirect3DRM3 *iface,
        const char *name, IDirect3DRMObject **object)
{
    FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm3_EnumerateObjects(IDirect3DRM3 *iface, D3DRMOBJECTCALLBACK cb, void *ctx)
{
    FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);

    return E_NOTIMPL;
}

static HRESULT load_data(IDirect3DRM3 *iface, IDirectXFileData *data_object, IID **GUIDs, DWORD nb_GUIDs, D3DRMLOADCALLBACK LoadProc,
                         void *ArgLP, D3DRMLOADTEXTURECALLBACK LoadTextureProc, void *ArgLTP, IDirect3DRMFrame3 *parent_frame)
{
    HRESULT ret = D3DRMERR_BADOBJECT;
    HRESULT hr;
    const GUID* guid;
    DWORD i;
    BOOL requested = FALSE;

    hr = IDirectXFileData_GetType(data_object, &guid);
    if (hr != DXFILE_OK)
        goto end;

    TRACE("Found object type whose GUID = %s\n", debugstr_guid(guid));

    /* Load object only if it is top level and requested or if it is part of another object */

    if (IsEqualGUID(guid, &TID_D3DRMMesh))
    {
        TRACE("Found TID_D3DRMMesh\n");

        for (i = 0; i < nb_GUIDs; i++)
            if (IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder) ||
                IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder2) ||
                IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder3))
            {
                requested = TRUE;
                break;
            }

        if (requested || parent_frame)
        {
            IDirect3DRMMeshBuilder3 *meshbuilder;

            TRACE("Load mesh data\n");

            hr = IDirect3DRM3_CreateMeshBuilder(iface, &meshbuilder);
            if (SUCCEEDED(hr))
            {
                hr = load_mesh_data(meshbuilder, data_object, LoadTextureProc, ArgLTP);
                if (SUCCEEDED(hr))
                {
                    /* Only top level objects are notified */
                    if (!parent_frame)
                    {
                        IDirect3DRMObject *object;

                        hr = IDirect3DRMMeshBuilder3_QueryInterface(meshbuilder, GUIDs[i], (void**)&object);
                        if (SUCCEEDED(hr))
                        {
                            LoadProc(object, GUIDs[i], ArgLP);
                            IDirect3DRMObject_Release(object);
                        }
                    }
                    else
                    {
                        IDirect3DRMFrame3_AddVisual(parent_frame, (IUnknown*)meshbuilder);
                    }
                }
                IDirect3DRMMeshBuilder3_Release(meshbuilder);
            }

            if (FAILED(hr))
                ERR("Cannot process mesh\n");
        }
    }
    else if (IsEqualGUID(guid, &TID_D3DRMFrame))
    {
        TRACE("Found TID_D3DRMFrame\n");

        for (i = 0; i < nb_GUIDs; i++)
            if (IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame) ||
                IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame2) ||
                IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame3))
            {
                requested = TRUE;
                break;
            }

        if (requested || parent_frame)
        {
            IDirect3DRMFrame3 *frame;

            TRACE("Load frame data\n");

            hr = IDirect3DRM3_CreateFrame(iface, parent_frame, &frame);
            if (SUCCEEDED(hr))
            {
                IDirectXFileObject *child;

                while (SUCCEEDED(hr = IDirectXFileData_GetNextObject(data_object, &child)))
                {
                    IDirectXFileData *data;
                    IDirectXFileDataReference *reference;
                    IDirectXFileBinary *binary;

                    if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
                            &IID_IDirectXFileBinary, (void **)&binary)))
                    {
                        FIXME("Binary Object not supported yet\n");
                        IDirectXFileBinary_Release(binary);
                    }
                    else if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
                            &IID_IDirectXFileData, (void **)&data)))
                    {
                        TRACE("Found Data Object\n");
                        hr = load_data(iface, data, GUIDs, nb_GUIDs, LoadProc, ArgLP, LoadTextureProc, ArgLTP, frame);
                        IDirectXFileData_Release(data);
                    }
                    else if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
                            &IID_IDirectXFileDataReference, (void **)&reference)))
                    {
                        TRACE("Found Data Object Reference\n");
                        IDirectXFileDataReference_Resolve(reference, &data);
                        hr = load_data(iface, data, GUIDs, nb_GUIDs, LoadProc, ArgLP, LoadTextureProc, ArgLTP, frame);
                        IDirectXFileData_Release(data);
                        IDirectXFileDataReference_Release(reference);
                    }
                    IDirectXFileObject_Release(child);
                }

                if (hr != DXFILEERR_NOMOREOBJECTS)
                {
                    IDirect3DRMFrame3_Release(frame);
                    goto end;
                }
                hr = S_OK;

                /* Only top level objects are notified */
                if (!parent_frame)
                {
                    IDirect3DRMObject *object;

                    hr = IDirect3DRMFrame3_QueryInterface(frame, GUIDs[i], (void**)&object);
                    if (SUCCEEDED(hr))
                    {
                        LoadProc(object, GUIDs[i], ArgLP);
                        IDirect3DRMObject_Release(object);
                    }
                }
                IDirect3DRMFrame3_Release(frame);
            }

            if (FAILED(hr))
                ERR("Cannot process frame\n");
        }
    }
    else if (IsEqualGUID(guid, &TID_D3DRMMaterial))
    {
        TRACE("Found TID_D3DRMMaterial\n");

        /* Cannot be requested so nothing to do */
    }
    else if (IsEqualGUID(guid, &TID_D3DRMFrameTransformMatrix))
    {
        TRACE("Found TID_D3DRMFrameTransformMatrix\n");

        /* Cannot be requested */
        if (parent_frame)
        {
            D3DRMMATRIX4D *matrix;
            DWORD size;

            TRACE("Load Frame Transform Matrix data\n");

            hr = IDirectXFileData_GetData(data_object, NULL, &size, (void**)&matrix);
            if ((hr != DXFILE_OK) || (size != sizeof(matrix)))
                goto end;

            hr = IDirect3DRMFrame3_AddTransform(parent_frame, D3DRMCOMBINE_REPLACE, *matrix);
            if (FAILED(hr))
                goto end;
        }
    }
    else
    {
        FIXME("Found unknown TID %s\n", debugstr_guid(guid));
    }

    ret = D3DRM_OK;

end:

    return ret;
}

static HRESULT WINAPI d3drm3_Load(IDirect3DRM3 *iface, void *source, void *object_id, IID **iids,
        DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
        D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame3 *parent_frame)
{
    DXFILELOADOPTIONS load_options;
    IDirectXFile *file = NULL;
    IDirectXFileEnumObject *enum_object = NULL;
    IDirectXFileData *data = NULL;
    HRESULT hr;
    const GUID* pGuid;
    DWORD size;
    struct d3drm_file_header *header;
    HRESULT ret = D3DRMERR_BADOBJECT;
    DWORD i;

    TRACE("iface %p, source %p, object_id %p, iids %p, iid_count %u, flags %#x, "
            "load_cb %p, load_ctx %p, load_tex_cb %p, load_tex_ctx %p, parent_frame %p.\n",
            iface, source, object_id, iids, iid_count, flags,
            load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);

    TRACE("Looking for GUIDs:\n");
    for (i = 0; i < iid_count; ++i)
        TRACE("- %s (%s)\n", debugstr_guid(iids[i]), get_IID_string(iids[i]));

    if (flags == D3DRMLOAD_FROMMEMORY)
    {
        load_options = DXFILELOAD_FROMMEMORY;
    }
    else if (flags == D3DRMLOAD_FROMFILE)
    {
        load_options = DXFILELOAD_FROMFILE;
        TRACE("Loading from file %s\n", debugstr_a(source));
    }
    else
    {
        FIXME("Load options %#x not supported yet.\n", flags);
        return E_NOTIMPL;
    }

    hr = DirectXFileCreate(&file);
    if (hr != DXFILE_OK)
        goto end;

    hr = IDirectXFile_RegisterTemplates(file, templates, strlen(templates));
    if (hr != DXFILE_OK)
        goto end;

    hr = IDirectXFile_CreateEnumObject(file, source, load_options, &enum_object);
    if (hr != DXFILE_OK)
        goto end;

    hr = IDirectXFileEnumObject_GetNextDataObject(enum_object, &data);
    if (hr != DXFILE_OK)
        goto end;

    hr = IDirectXFileData_GetType(data, &pGuid);
    if (hr != DXFILE_OK)
        goto end;

    TRACE("Found object type whose GUID = %s\n", debugstr_guid(pGuid));

    if (!IsEqualGUID(pGuid, &TID_DXFILEHeader))
    {
        ret = D3DRMERR_BADFILE;
        goto end;
    }

    hr = IDirectXFileData_GetData(data, NULL, &size, (void **)&header);
    if ((hr != DXFILE_OK) || (size != sizeof(*header)))
        goto end;

    TRACE("Version is %u.%u, flags %#x.\n", header->major, header->minor, header->flags);

    /* Version must be 1.0.x */
    if ((header->major != 1) || (header->minor != 0))
    {
        ret = D3DRMERR_BADFILE;
        goto end;
    }

    IDirectXFileData_Release(data);
    data = NULL;

    while (1)
    {
        hr = IDirectXFileEnumObject_GetNextDataObject(enum_object, &data);
        if (hr == DXFILEERR_NOMOREOBJECTS)
        {
            TRACE("No more object\n");
            break;
        }
        else if (hr != DXFILE_OK)
        {
            ret = D3DRMERR_BADFILE;
            goto end;
        }

        ret = load_data(iface, data, iids, iid_count, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
        if (ret != D3DRM_OK)
            goto end;

        IDirectXFileData_Release(data);
        data = NULL;
    }

    ret = D3DRM_OK;

end:
    if (data)
        IDirectXFileData_Release(data);
    if (enum_object)
        IDirectXFileEnumObject_Release(enum_object);
    if (file)
        IDirectXFile_Release(file);

    return ret;
}

static HRESULT WINAPI d3drm3_Tick(IDirect3DRM3 *iface, D3DVALUE tick)
{
    FIXME("iface %p, tick %.8e stub!\n", iface, tick);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm3_CreateProgressiveMesh(IDirect3DRM3 *iface, IDirect3DRMProgressiveMesh **mesh)
{
    FIXME("iface %p, mesh %p stub!\n", iface, mesh);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm3_RegisterClient(IDirect3DRM3 *iface, REFGUID guid, DWORD *id)
{
    FIXME("iface %p, guid %s, id %p stub!\n", iface, debugstr_guid(guid), id);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm3_UnregisterClient(IDirect3DRM3 *iface, REFGUID guid)
{
    FIXME("iface %p, guid %s stub!\n", iface, debugstr_guid(guid));

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm3_CreateClippedVisual(IDirect3DRM3 *iface,
        IDirect3DRMVisual *visual, IDirect3DRMClippedVisual **clipped_visual)
{
    FIXME("iface %p, visual %p, clipped_visual %p stub!\n", iface, visual, clipped_visual);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm3_SetOptions(IDirect3DRM3 *iface, DWORD flags)
{
    FIXME("iface %p, flags %#x stub!\n", iface, flags);

    return E_NOTIMPL;
}

static HRESULT WINAPI d3drm3_GetOptions(IDirect3DRM3 *iface, DWORD *flags)
{
    FIXME("iface %p, flags %p stub!\n", iface, flags);

    return E_NOTIMPL;
}

static const struct IDirect3DRM3Vtbl d3drm3_vtbl =
{
    d3drm3_QueryInterface,
    d3drm3_AddRef,
    d3drm3_Release,
    d3drm3_CreateObject,
    d3drm3_CreateFrame,
    d3drm3_CreateMesh,
    d3drm3_CreateMeshBuilder,
    d3drm3_CreateFace,
    d3drm3_CreateAnimation,
    d3drm3_CreateAnimationSet,
    d3drm3_CreateTexture,
    d3drm3_CreateLight,
    d3drm3_CreateLightRGB,
    d3drm3_CreateMaterial,
    d3drm3_CreateDevice,
    d3drm3_CreateDeviceFromSurface,
    d3drm3_CreateDeviceFromD3D,
    d3drm3_CreateDeviceFromClipper,
    d3drm3_CreateTextureFromSurface,
    d3drm3_CreateShadow,
    d3drm3_CreateViewport,
    d3drm3_CreateWrap,
    d3drm3_CreateUserVisual,
    d3drm3_LoadTexture,
    d3drm3_LoadTextureFromResource,
    d3drm3_SetSearchPath,
    d3drm3_AddSearchPath,
    d3drm3_GetSearchPath,
    d3drm3_SetDefaultTextureColors,
    d3drm3_SetDefaultTextureShades,
    d3drm3_GetDevices,
    d3drm3_GetNamedObject,
    d3drm3_EnumerateObjects,
    d3drm3_Load,
    d3drm3_Tick,
    d3drm3_CreateProgressiveMesh,
    d3drm3_RegisterClient,
    d3drm3_UnregisterClient,
    d3drm3_CreateClippedVisual,
    d3drm3_SetOptions,
    d3drm3_GetOptions,
};

HRESULT WINAPI Direct3DRMCreate(IDirect3DRM **d3drm)
{
    struct d3drm *object;

    TRACE("d3drm %p.\n", d3drm);

    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
        return E_OUTOFMEMORY;

    object->IDirect3DRM_iface.lpVtbl = &d3drm1_vtbl;
    object->IDirect3DRM2_iface.lpVtbl = &d3drm2_vtbl;
    object->IDirect3DRM3_iface.lpVtbl = &d3drm3_vtbl;
    object->ref1 = 1;
    object->iface_count = 1;

    *d3drm = &object->IDirect3DRM_iface;

    return S_OK;
}

HRESULT WINAPI DllCanUnloadNow(void)
{
    return S_FALSE;
}

HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
{
    TRACE("(%s, %s, %p): stub\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);

    if(!ppv)
        return E_INVALIDARG;

    return CLASS_E_CLASSNOTAVAILABLE;
}
