8c46751f6e2eb608ccd9d12de38191aec046b6ff
[reactos.git] / dll / directx / wine / d3drm / d3drm.c
1 /*
2 * Implementation of IDirect3DRM Interface
3 *
4 * Copyright 2010, 2012 Christian Costa
5 * Copyright 2011 André Hentschel
6 * Copyright 2016 Aaryaman Vasishta
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23 #include "d3drm_private.h"
24
25 static const char* get_IID_string(const GUID* guid)
26 {
27 if (IsEqualGUID(guid, &IID_IDirect3DRMFrame))
28 return "IID_IDirect3DRMFrame";
29 else if (IsEqualGUID(guid, &IID_IDirect3DRMFrame2))
30 return "IID_IDirect3DRMFrame2";
31 else if (IsEqualGUID(guid, &IID_IDirect3DRMFrame3))
32 return "IID_IDirect3DRMFrame3";
33 else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder))
34 return "IID_IDirect3DRMMeshBuilder";
35 else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder2))
36 return "IID_IDirect3DRMMeshBuilder2";
37 else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder3))
38 return "IID_IDirect3DRMMeshBuilder3";
39
40 return "?";
41 }
42
43 static HRESULT d3drm_create_texture_object(void **object, IDirect3DRM *d3drm)
44 {
45 struct d3drm_texture *texture;
46 HRESULT hr;
47
48 if (FAILED(hr = d3drm_texture_create(&texture, d3drm)))
49 return hr;
50
51 *object = &texture->IDirect3DRMTexture_iface;
52
53 return hr;
54 }
55
56 static HRESULT d3drm_create_device_object(void **object, IDirect3DRM *d3drm)
57 {
58 struct d3drm_device *device;
59 HRESULT hr;
60
61 if (FAILED(hr = d3drm_device_create(&device, d3drm)))
62 return hr;
63
64 *object = &device->IDirect3DRMDevice_iface;
65
66 return hr;
67 }
68
69 static HRESULT d3drm_create_viewport_object(void **object, IDirect3DRM *d3drm)
70 {
71 struct d3drm_viewport *viewport;
72 HRESULT hr;
73
74 if (FAILED(hr = d3drm_viewport_create(&viewport, d3drm)))
75 return hr;
76
77 *object = &viewport->IDirect3DRMViewport_iface;
78
79 return hr;
80 }
81
82 static HRESULT d3drm_create_face_object(void **object, IDirect3DRM *d3drm)
83 {
84 struct d3drm_face *face;
85 HRESULT hr;
86
87 if (FAILED(hr = d3drm_face_create(&face)))
88 return hr;
89
90 *object = &face->IDirect3DRMFace_iface;
91
92 return hr;
93 }
94
95 static HRESULT d3drm_create_mesh_builder_object(void **object, IDirect3DRM *d3drm)
96 {
97 struct d3drm_mesh_builder *mesh_builder;
98 HRESULT hr;
99
100 if (FAILED(hr = d3drm_mesh_builder_create(&mesh_builder, d3drm)))
101 return hr;
102
103 *object = &mesh_builder->IDirect3DRMMeshBuilder2_iface;
104
105 return hr;
106 }
107
108 static HRESULT d3drm_create_frame_object(void **object, IDirect3DRM *d3drm)
109 {
110 struct d3drm_frame *frame;
111 HRESULT hr;
112
113 if (FAILED(hr = d3drm_frame_create(&frame, NULL, d3drm)))
114 return hr;
115
116 *object = &frame->IDirect3DRMFrame_iface;
117
118 return hr;
119 }
120
121 static HRESULT d3drm_create_light_object(void **object, IDirect3DRM *d3drm)
122 {
123 struct d3drm_light *light;
124 HRESULT hr;
125
126 if (FAILED(hr = d3drm_light_create(&light, d3drm)))
127 return hr;
128
129 *object = &light->IDirect3DRMLight_iface;
130
131 return hr;
132 }
133
134 static HRESULT d3drm_create_material_object(void **object, IDirect3DRM *d3drm)
135 {
136 struct d3drm_material *material;
137 HRESULT hr;
138
139 if (FAILED(hr = d3drm_material_create(&material, d3drm)))
140 return hr;
141
142 *object = &material->IDirect3DRMMaterial2_iface;
143
144 return hr;
145 }
146
147 static HRESULT d3drm_create_mesh_object(void **object, IDirect3DRM *d3drm)
148 {
149 struct d3drm_mesh *mesh;
150 HRESULT hr;
151
152 if (FAILED(hr = d3drm_mesh_create(&mesh, d3drm)))
153 return hr;
154
155 *object = &mesh->IDirect3DRMMesh_iface;
156
157 return hr;
158 }
159
160 static HRESULT d3drm_create_animation_object(void **object, IDirect3DRM *d3drm)
161 {
162 struct d3drm_animation *animation;
163 HRESULT hr;
164
165 if (FAILED(hr = d3drm_animation_create(&animation, d3drm)))
166 return hr;
167
168 *object = &animation->IDirect3DRMAnimation_iface;
169
170 return hr;
171 }
172
173 static HRESULT d3drm_create_wrap_object(void **object, IDirect3DRM *d3drm)
174 {
175 struct d3drm_wrap *wrap;
176 HRESULT hr;
177
178 if (FAILED(hr = d3drm_wrap_create(&wrap, d3drm)))
179 return hr;
180
181 *object = &wrap->IDirect3DRMWrap_iface;
182
183 return hr;
184 }
185
186 struct d3drm
187 {
188 IDirect3DRM IDirect3DRM_iface;
189 IDirect3DRM2 IDirect3DRM2_iface;
190 IDirect3DRM3 IDirect3DRM3_iface;
191 LONG ref1, ref2, ref3, iface_count;
192 };
193
194 static inline struct d3drm *impl_from_IDirect3DRM(IDirect3DRM *iface)
195 {
196 return CONTAINING_RECORD(iface, struct d3drm, IDirect3DRM_iface);
197 }
198
199 static inline struct d3drm *impl_from_IDirect3DRM2(IDirect3DRM2 *iface)
200 {
201 return CONTAINING_RECORD(iface, struct d3drm, IDirect3DRM2_iface);
202 }
203
204 static inline struct d3drm *impl_from_IDirect3DRM3(IDirect3DRM3 *iface)
205 {
206 return CONTAINING_RECORD(iface, struct d3drm, IDirect3DRM3_iface);
207 }
208
209 static void d3drm_destroy(struct d3drm *d3drm)
210 {
211 HeapFree(GetProcessHeap(), 0, d3drm);
212 TRACE("d3drm object %p is being destroyed.\n", d3drm);
213 }
214
215 static HRESULT WINAPI d3drm1_QueryInterface(IDirect3DRM *iface, REFIID riid, void **out)
216 {
217 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
218
219 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
220
221 if (IsEqualGUID(riid, &IID_IDirect3DRM)
222 || IsEqualGUID(riid, &IID_IUnknown))
223 {
224 *out = &d3drm->IDirect3DRM_iface;
225 }
226 else if (IsEqualGUID(riid, &IID_IDirect3DRM2))
227 {
228 *out = &d3drm->IDirect3DRM2_iface;
229 }
230 else if (IsEqualGUID(riid, &IID_IDirect3DRM3))
231 {
232 *out = &d3drm->IDirect3DRM3_iface;
233 }
234 else
235 {
236 *out = NULL;
237 WARN("%s not implemented, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(riid));
238 return CLASS_E_CLASSNOTAVAILABLE;
239 }
240
241 IUnknown_AddRef((IUnknown *)*out);
242 return S_OK;
243 }
244
245 static ULONG WINAPI d3drm1_AddRef(IDirect3DRM *iface)
246 {
247 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
248 ULONG refcount = InterlockedIncrement(&d3drm->ref1);
249
250 TRACE("%p increasing refcount to %u.\n", iface, refcount);
251
252 if (refcount == 1)
253 InterlockedIncrement(&d3drm->iface_count);
254
255 return refcount;
256 }
257
258 static ULONG WINAPI d3drm1_Release(IDirect3DRM *iface)
259 {
260 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
261 ULONG refcount = InterlockedDecrement(&d3drm->ref1);
262
263 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
264
265 if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
266 d3drm_destroy(d3drm);
267
268 return refcount;
269 }
270
271 static HRESULT WINAPI d3drm1_CreateObject(IDirect3DRM *iface,
272 REFCLSID clsid, IUnknown *outer, REFIID iid, void **out)
273 {
274 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
275
276 TRACE("iface %p, clsid %s, outer %p, iid %s, out %p.\n",
277 iface, debugstr_guid(clsid), outer, debugstr_guid(iid), out);
278
279 return IDirect3DRM3_CreateObject(&d3drm->IDirect3DRM3_iface, clsid, outer, iid, out);
280 }
281
282 static HRESULT WINAPI d3drm1_CreateFrame(IDirect3DRM *iface,
283 IDirect3DRMFrame *parent_frame, IDirect3DRMFrame **frame)
284 {
285 struct d3drm_frame *object;
286 HRESULT hr;
287
288 TRACE("iface %p, parent_frame %p, frame %p.\n", iface, parent_frame, frame);
289
290 if (FAILED(hr = d3drm_frame_create(&object, (IUnknown *)parent_frame, iface)))
291 return hr;
292
293 *frame = &object->IDirect3DRMFrame_iface;
294
295 return D3DRM_OK;
296 }
297
298 static HRESULT WINAPI d3drm1_CreateMesh(IDirect3DRM *iface, IDirect3DRMMesh **mesh)
299 {
300 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
301
302 TRACE("iface %p, mesh %p.\n", iface, mesh);
303
304 return IDirect3DRM3_CreateMesh(&d3drm->IDirect3DRM3_iface, mesh);
305 }
306
307 static HRESULT WINAPI d3drm1_CreateMeshBuilder(IDirect3DRM *iface, IDirect3DRMMeshBuilder **mesh_builder)
308 {
309 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
310
311 TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);
312
313 return IDirect3DRM2_CreateMeshBuilder(&d3drm->IDirect3DRM2_iface, (IDirect3DRMMeshBuilder2 **)mesh_builder);
314 }
315
316 static HRESULT WINAPI d3drm1_CreateFace(IDirect3DRM *iface, IDirect3DRMFace **face)
317 {
318 struct d3drm_face *object;
319 HRESULT hr;
320
321 TRACE("iface %p, face %p.\n", iface, face);
322
323 if (FAILED(hr = d3drm_face_create(&object)))
324 return hr;
325
326 *face = &object->IDirect3DRMFace_iface;
327
328 return S_OK;
329 }
330
331 static HRESULT WINAPI d3drm1_CreateAnimation(IDirect3DRM *iface, IDirect3DRMAnimation **animation)
332 {
333 struct d3drm_animation *object;
334 HRESULT hr;
335
336 TRACE("iface %p, animation %p.\n", iface, animation);
337
338 if (!animation)
339 return D3DRMERR_BADVALUE;
340
341 if (FAILED(hr = d3drm_animation_create(&object, iface)))
342 return hr;
343
344 *animation = &object->IDirect3DRMAnimation_iface;
345
346 return S_OK;
347 }
348
349 static HRESULT WINAPI d3drm1_CreateAnimationSet(IDirect3DRM *iface, IDirect3DRMAnimationSet **set)
350 {
351 FIXME("iface %p, set %p stub!\n", iface, set);
352
353 return E_NOTIMPL;
354 }
355
356 static HRESULT WINAPI d3drm1_CreateTexture(IDirect3DRM *iface,
357 D3DRMIMAGE *image, IDirect3DRMTexture **texture)
358 {
359 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
360 IDirect3DRMTexture3 *texture3;
361 HRESULT hr;
362
363 TRACE("iface %p, image %p, texture %p.\n", iface, image, texture);
364
365 if (!texture)
366 return D3DRMERR_BADVALUE;
367
368 if (FAILED(hr = IDirect3DRM3_CreateTexture(&d3drm->IDirect3DRM3_iface, image, &texture3)))
369 {
370 *texture = NULL;
371 return hr;
372 }
373
374 hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture, (void **)texture);
375 IDirect3DRMTexture3_Release(texture3);
376
377 return hr;
378 }
379
380 static HRESULT WINAPI d3drm1_CreateLight(IDirect3DRM *iface,
381 D3DRMLIGHTTYPE type, D3DCOLOR color, IDirect3DRMLight **light)
382 {
383 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
384
385 TRACE("iface %p, type %#x, color 0x%08x, light %p.\n", iface, type, color, light);
386
387 return IDirect3DRM3_CreateLight(&d3drm->IDirect3DRM3_iface, type, color, light);
388 }
389
390 static HRESULT WINAPI d3drm1_CreateLightRGB(IDirect3DRM *iface, D3DRMLIGHTTYPE type,
391 D3DVALUE red, D3DVALUE green, D3DVALUE blue, IDirect3DRMLight **light)
392 {
393 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
394
395 TRACE("iface %p, type %#x, red %.8e, green %.8e, blue %.8e, light %p.\n",
396 iface, type, red, green, blue, light);
397
398 return IDirect3DRM3_CreateLightRGB(&d3drm->IDirect3DRM3_iface, type, red, green, blue, light);
399 }
400
401 static HRESULT WINAPI d3drm1_CreateMaterial(IDirect3DRM *iface,
402 D3DVALUE power, IDirect3DRMMaterial **material)
403 {
404 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
405
406 TRACE("iface %p, power %.8e, material %p.\n", iface, power, material);
407
408 return IDirect3DRM3_CreateMaterial(&d3drm->IDirect3DRM3_iface, power, (IDirect3DRMMaterial2 **)material);
409 }
410
411 static HRESULT WINAPI d3drm1_CreateDevice(IDirect3DRM *iface,
412 DWORD width, DWORD height, IDirect3DRMDevice **device)
413 {
414 struct d3drm_device *object;
415 HRESULT hr;
416
417 FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);
418
419 if (FAILED(hr = d3drm_device_create(&object, iface)))
420 return hr;
421
422 *device = &object->IDirect3DRMDevice_iface;
423
424 return D3DRM_OK;
425 }
426
427 static HRESULT WINAPI d3drm1_CreateDeviceFromSurface(IDirect3DRM *iface, GUID *guid,
428 IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, IDirect3DRMDevice **device)
429 {
430 struct d3drm_device *object;
431 HRESULT hr;
432
433 TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, device %p.\n",
434 iface, debugstr_guid(guid), ddraw, backbuffer, device);
435
436 if (!device)
437 return D3DRMERR_BADVALUE;
438 *device = NULL;
439
440 if (!backbuffer || !ddraw)
441 return D3DRMERR_BADDEVICE;
442
443 if (FAILED(hr = d3drm_device_create(&object, iface)))
444 return hr;
445
446 if (SUCCEEDED(hr = d3drm_device_init(object, 1, ddraw, backbuffer, TRUE)))
447 *device = &object->IDirect3DRMDevice_iface;
448 else
449 d3drm_device_destroy(object);
450
451 return hr;
452 }
453
454 static HRESULT WINAPI d3drm1_CreateDeviceFromD3D(IDirect3DRM *iface,
455 IDirect3D *d3d, IDirect3DDevice *d3d_device, IDirect3DRMDevice **device)
456 {
457 struct d3drm_device *object;
458 HRESULT hr;
459 TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
460 iface, d3d, d3d_device, device);
461
462 if (!device)
463 return D3DRMERR_BADVALUE;
464 *device = NULL;
465
466 if (FAILED(hr = d3drm_device_create(&object, iface)))
467 return hr;
468
469 if (FAILED(hr = IDirect3DRMDevice_InitFromD3D(&object->IDirect3DRMDevice_iface, d3d, d3d_device)))
470 {
471 d3drm_device_destroy(object);
472 return hr;
473 }
474 *device = &object->IDirect3DRMDevice_iface;
475
476 return D3DRM_OK;
477 }
478
479 static HRESULT WINAPI d3drm1_CreateDeviceFromClipper(IDirect3DRM *iface,
480 IDirectDrawClipper *clipper, GUID *guid, int width, int height,
481 IDirect3DRMDevice **device)
482 {
483 struct d3drm_device *object;
484 IDirectDraw *ddraw;
485 IDirectDrawSurface *render_target;
486 HRESULT hr;
487
488 TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
489 iface, clipper, debugstr_guid(guid), width, height, device);
490
491 if (!device)
492 return D3DRMERR_BADVALUE;
493 *device = NULL;
494
495 if (!clipper || !width || !height)
496 return D3DRMERR_BADVALUE;
497
498 hr = DirectDrawCreate(NULL, &ddraw, NULL);
499 if (FAILED(hr))
500 return hr;
501
502 if (FAILED(hr = d3drm_device_create(&object, iface)))
503 {
504 IDirectDraw_Release(ddraw);
505 return hr;
506 }
507
508 hr = d3drm_device_create_surfaces_from_clipper(object, ddraw, clipper, width, height, &render_target);
509 if (FAILED(hr))
510 {
511 IDirectDraw_Release(ddraw);
512 d3drm_device_destroy(object);
513 return hr;
514 }
515
516 hr = d3drm_device_init(object, 1, ddraw, render_target, TRUE);
517 IDirectDraw_Release(ddraw);
518 IDirectDrawSurface_Release(render_target);
519 if (FAILED(hr))
520 d3drm_device_destroy(object);
521 else
522 *device = &object->IDirect3DRMDevice_iface;
523
524 return hr;
525 }
526
527 static HRESULT WINAPI d3drm1_CreateTextureFromSurface(IDirect3DRM *iface,
528 IDirectDrawSurface *surface, IDirect3DRMTexture **texture)
529 {
530 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
531 IDirect3DRMTexture3 *texture3;
532 HRESULT hr;
533
534 TRACE("iface %p, surface %p, texture %p.\n", iface, surface, texture);
535
536 if (!texture)
537 return D3DRMERR_BADVALUE;
538
539 if (FAILED(hr = IDirect3DRM3_CreateTextureFromSurface(&d3drm->IDirect3DRM3_iface, surface, &texture3)))
540 {
541 *texture = NULL;
542 return hr;
543 }
544
545 hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture, (void **)texture);
546 IDirect3DRMTexture3_Release(texture3);
547
548 return hr;
549 }
550
551 static HRESULT WINAPI d3drm1_CreateShadow(IDirect3DRM *iface, IDirect3DRMVisual *visual,
552 IDirect3DRMLight *light, D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz,
553 IDirect3DRMVisual **shadow)
554 {
555 FIXME("iface %p, visual %p, light %p, px %.8e, py %.8e, pz %.8e, nx %.8e, ny %.8e, nz %.8e, shadow %p stub!\n",
556 iface, visual, light, px, py, pz, nx, ny, nz, shadow);
557
558 return E_NOTIMPL;
559 }
560
561 static HRESULT WINAPI d3drm1_CreateViewport(IDirect3DRM *iface, IDirect3DRMDevice *device,
562 IDirect3DRMFrame *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport **viewport)
563 {
564 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
565 IDirect3DRMDevice3 *device3;
566 IDirect3DRMFrame3 *camera3;
567 IDirect3DRMViewport2 *viewport2;
568 HRESULT hr;
569
570 TRACE("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p.\n",
571 iface, device, camera, x, y, width, height, viewport);
572
573 if (!device || !camera)
574 return D3DRMERR_BADOBJECT;
575 if (!viewport)
576 return D3DRMERR_BADVALUE;
577
578 if (FAILED(hr = IDirect3DRMDevice_QueryInterface(device, &IID_IDirect3DRMDevice3, (void **)&device3)))
579 return hr;
580
581 if (FAILED(hr = IDirect3DRMFrame_QueryInterface(camera, &IID_IDirect3DRMFrame3, (void **)&camera3)))
582 {
583 IDirect3DRMDevice3_Release(device3);
584 return hr;
585 }
586
587 hr = IDirect3DRM3_CreateViewport(&d3drm->IDirect3DRM3_iface, device3, camera3, x, y, width, height, &viewport2);
588 IDirect3DRMDevice3_Release(device3);
589 IDirect3DRMFrame3_Release(camera3);
590 if (FAILED(hr))
591 return hr;
592
593 hr = IDirect3DRMViewport2_QueryInterface(viewport2, &IID_IDirect3DRMViewport, (void **)viewport);
594 IDirect3DRMViewport2_Release(viewport2);
595
596 return hr;
597 }
598
599 static HRESULT WINAPI d3drm1_CreateWrap(IDirect3DRM *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame *frame,
600 D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz,
601 D3DVALUE ux, D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv,
602 IDirect3DRMWrap **wrap)
603 {
604 struct d3drm_wrap *object;
605 HRESULT hr;
606
607 FIXME("iface %p, type %#x, frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, "
608 "ux %.8e, uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e, wrap %p, semi-stub.\n",
609 iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);
610
611 if (!wrap)
612 return D3DRMERR_BADVALUE;
613
614 if (FAILED(hr = d3drm_wrap_create(&object, iface)))
615 return hr;
616
617 *wrap = &object->IDirect3DRMWrap_iface;
618
619 return S_OK;
620 }
621
622 static HRESULT WINAPI d3drm1_CreateUserVisual(IDirect3DRM *iface,
623 D3DRMUSERVISUALCALLBACK cb, void *ctx, IDirect3DRMUserVisual **visual)
624 {
625 FIXME("iface %p, cb %p, ctx %p visual %p stub!\n", iface, cb, ctx, visual);
626
627 return E_NOTIMPL;
628 }
629
630 static HRESULT WINAPI d3drm1_LoadTexture(IDirect3DRM *iface,
631 const char *filename, IDirect3DRMTexture **texture)
632 {
633 struct d3drm_texture *object;
634 HRESULT hr;
635
636 FIXME("iface %p, filename %s, texture %p stub!\n", iface, debugstr_a(filename), texture);
637
638 if (FAILED(hr = d3drm_texture_create(&object, iface)))
639 return hr;
640
641 *texture = &object->IDirect3DRMTexture_iface;
642
643 return D3DRM_OK;
644 }
645
646 static HRESULT WINAPI d3drm1_LoadTextureFromResource(IDirect3DRM *iface,
647 HRSRC resource, IDirect3DRMTexture **texture)
648 {
649 struct d3drm_texture *object;
650 HRESULT hr;
651
652 FIXME("iface %p, resource %p, texture %p stub!\n", iface, resource, texture);
653
654 if (FAILED(hr = d3drm_texture_create(&object, iface)))
655 return hr;
656
657 *texture = &object->IDirect3DRMTexture_iface;
658
659 return D3DRM_OK;
660 }
661
662 static HRESULT WINAPI d3drm1_SetSearchPath(IDirect3DRM *iface, const char *path)
663 {
664 FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
665
666 return E_NOTIMPL;
667 }
668
669 static HRESULT WINAPI d3drm1_AddSearchPath(IDirect3DRM *iface, const char *path)
670 {
671 FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
672
673 return E_NOTIMPL;
674 }
675
676 static HRESULT WINAPI d3drm1_GetSearchPath(IDirect3DRM *iface, DWORD *size, char *path)
677 {
678 FIXME("iface %p, size %p, path %p stub!\n", iface, size, path);
679
680 return E_NOTIMPL;
681 }
682
683 static HRESULT WINAPI d3drm1_SetDefaultTextureColors(IDirect3DRM *iface, DWORD color_count)
684 {
685 FIXME("iface %p, color_count %u stub!\n", iface, color_count);
686
687 return E_NOTIMPL;
688 }
689
690 static HRESULT WINAPI d3drm1_SetDefaultTextureShades(IDirect3DRM *iface, DWORD shade_count)
691 {
692 FIXME("iface %p, shade_count %u stub!\n", iface, shade_count);
693
694 return E_NOTIMPL;
695 }
696
697 static HRESULT WINAPI d3drm1_GetDevices(IDirect3DRM *iface, IDirect3DRMDeviceArray **array)
698 {
699 FIXME("iface %p, array %p stub!\n", iface, array);
700
701 return E_NOTIMPL;
702 }
703
704 static HRESULT WINAPI d3drm1_GetNamedObject(IDirect3DRM *iface,
705 const char *name, IDirect3DRMObject **object)
706 {
707 FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);
708
709 return E_NOTIMPL;
710 }
711
712 static HRESULT WINAPI d3drm1_EnumerateObjects(IDirect3DRM *iface, D3DRMOBJECTCALLBACK cb, void *ctx)
713 {
714 FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
715
716 return E_NOTIMPL;
717 }
718
719 static HRESULT WINAPI d3drm1_Load(IDirect3DRM *iface, void *source, void *object_id, IID **iids,
720 DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
721 D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame *parent_frame)
722 {
723 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
724 IDirect3DRMFrame3 *parent_frame3 = NULL;
725 HRESULT hr = D3DRM_OK;
726
727 TRACE("iface %p, source %p, object_id %p, iids %p, iid_count %u, flags %#x, "
728 "load_cb %p, load_ctx %p, load_tex_cb %p, load_tex_ctx %p, parent_frame %p.\n",
729 iface, source, object_id, iids, iid_count, flags,
730 load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
731
732 if (parent_frame)
733 hr = IDirect3DRMFrame_QueryInterface(parent_frame, &IID_IDirect3DRMFrame3, (void **)&parent_frame3);
734 if (SUCCEEDED(hr))
735 hr = IDirect3DRM3_Load(&d3drm->IDirect3DRM3_iface, source, object_id, iids, iid_count,
736 flags, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame3);
737 if (parent_frame3)
738 IDirect3DRMFrame3_Release(parent_frame3);
739
740 return hr;
741 }
742
743 static HRESULT WINAPI d3drm1_Tick(IDirect3DRM *iface, D3DVALUE tick)
744 {
745 FIXME("iface %p, tick %.8e stub!\n", iface, tick);
746
747 return E_NOTIMPL;
748 }
749
750 static const struct IDirect3DRMVtbl d3drm1_vtbl =
751 {
752 d3drm1_QueryInterface,
753 d3drm1_AddRef,
754 d3drm1_Release,
755 d3drm1_CreateObject,
756 d3drm1_CreateFrame,
757 d3drm1_CreateMesh,
758 d3drm1_CreateMeshBuilder,
759 d3drm1_CreateFace,
760 d3drm1_CreateAnimation,
761 d3drm1_CreateAnimationSet,
762 d3drm1_CreateTexture,
763 d3drm1_CreateLight,
764 d3drm1_CreateLightRGB,
765 d3drm1_CreateMaterial,
766 d3drm1_CreateDevice,
767 d3drm1_CreateDeviceFromSurface,
768 d3drm1_CreateDeviceFromD3D,
769 d3drm1_CreateDeviceFromClipper,
770 d3drm1_CreateTextureFromSurface,
771 d3drm1_CreateShadow,
772 d3drm1_CreateViewport,
773 d3drm1_CreateWrap,
774 d3drm1_CreateUserVisual,
775 d3drm1_LoadTexture,
776 d3drm1_LoadTextureFromResource,
777 d3drm1_SetSearchPath,
778 d3drm1_AddSearchPath,
779 d3drm1_GetSearchPath,
780 d3drm1_SetDefaultTextureColors,
781 d3drm1_SetDefaultTextureShades,
782 d3drm1_GetDevices,
783 d3drm1_GetNamedObject,
784 d3drm1_EnumerateObjects,
785 d3drm1_Load,
786 d3drm1_Tick,
787 };
788
789 static HRESULT WINAPI d3drm2_QueryInterface(IDirect3DRM2 *iface, REFIID riid, void **out)
790 {
791 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
792
793 return d3drm1_QueryInterface(&d3drm->IDirect3DRM_iface, riid, out);
794 }
795
796 static ULONG WINAPI d3drm2_AddRef(IDirect3DRM2 *iface)
797 {
798 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
799 ULONG refcount = InterlockedIncrement(&d3drm->ref2);
800
801 TRACE("%p increasing refcount to %u.\n", iface, refcount);
802
803 if (refcount == 1)
804 InterlockedIncrement(&d3drm->iface_count);
805
806 return refcount;
807 }
808
809 static ULONG WINAPI d3drm2_Release(IDirect3DRM2 *iface)
810 {
811 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
812 ULONG refcount = InterlockedDecrement(&d3drm->ref2);
813
814 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
815
816 if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
817 d3drm_destroy(d3drm);
818
819 return refcount;
820 }
821
822 static HRESULT WINAPI d3drm2_CreateObject(IDirect3DRM2 *iface,
823 REFCLSID clsid, IUnknown *outer, REFIID iid, void **out)
824 {
825 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
826
827 TRACE("iface %p, clsid %s, outer %p, iid %s, out %p.\n",
828 iface, debugstr_guid(clsid), outer, debugstr_guid(iid), out);
829
830 return IDirect3DRM3_CreateObject(&d3drm->IDirect3DRM3_iface, clsid, outer, iid, out);
831 }
832
833 static HRESULT WINAPI d3drm2_CreateFrame(IDirect3DRM2 *iface,
834 IDirect3DRMFrame *parent_frame, IDirect3DRMFrame2 **frame)
835 {
836 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
837 struct d3drm_frame *object;
838 HRESULT hr;
839
840 TRACE("iface %p, parent_frame %p, frame %p.\n", iface, parent_frame, frame);
841
842 if (FAILED(hr = d3drm_frame_create(&object, (IUnknown *)parent_frame, &d3drm->IDirect3DRM_iface)))
843 return hr;
844
845 *frame = &object->IDirect3DRMFrame2_iface;
846
847 return D3DRM_OK;
848 }
849
850 static HRESULT WINAPI d3drm2_CreateMesh(IDirect3DRM2 *iface, IDirect3DRMMesh **mesh)
851 {
852 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
853
854 TRACE("iface %p, mesh %p.\n", iface, mesh);
855
856 return IDirect3DRM3_CreateMesh(&d3drm->IDirect3DRM3_iface, mesh);
857 }
858
859 static HRESULT WINAPI d3drm2_CreateMeshBuilder(IDirect3DRM2 *iface, IDirect3DRMMeshBuilder2 **mesh_builder)
860 {
861 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
862 struct d3drm_mesh_builder *object;
863 HRESULT hr;
864
865 TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);
866
867 if (FAILED(hr = d3drm_mesh_builder_create(&object, &d3drm->IDirect3DRM_iface)))
868 return hr;
869
870 *mesh_builder = &object->IDirect3DRMMeshBuilder2_iface;
871
872 return S_OK;
873 }
874
875 static HRESULT WINAPI d3drm2_CreateFace(IDirect3DRM2 *iface, IDirect3DRMFace **face)
876 {
877 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
878
879 TRACE("iface %p, face %p.\n", iface, face);
880
881 return IDirect3DRM_CreateFace(&d3drm->IDirect3DRM_iface, face);
882 }
883
884 static HRESULT WINAPI d3drm2_CreateAnimation(IDirect3DRM2 *iface, IDirect3DRMAnimation **animation)
885 {
886 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
887
888 TRACE("iface %p, animation %p.\n", iface, animation);
889
890 return IDirect3DRM_CreateAnimation(&d3drm->IDirect3DRM_iface, animation);
891 }
892
893 static HRESULT WINAPI d3drm2_CreateAnimationSet(IDirect3DRM2 *iface, IDirect3DRMAnimationSet **set)
894 {
895 FIXME("iface %p, set %p stub!\n", iface, set);
896
897 return E_NOTIMPL;
898 }
899
900 static HRESULT WINAPI d3drm2_CreateTexture(IDirect3DRM2 *iface,
901 D3DRMIMAGE *image, IDirect3DRMTexture2 **texture)
902 {
903 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
904 IDirect3DRMTexture3 *texture3;
905 HRESULT hr;
906
907 TRACE("iface %p, image %p, texture %p.\n", iface, image, texture);
908
909 if (!texture)
910 return D3DRMERR_BADVALUE;
911
912 if (FAILED(hr = IDirect3DRM3_CreateTexture(&d3drm->IDirect3DRM3_iface, image, &texture3)))
913 {
914 *texture = NULL;
915 return hr;
916 }
917
918 hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture2, (void **)texture);
919 IDirect3DRMTexture3_Release(texture3);
920
921 return hr;
922 }
923
924 static HRESULT WINAPI d3drm2_CreateLight(IDirect3DRM2 *iface,
925 D3DRMLIGHTTYPE type, D3DCOLOR color, IDirect3DRMLight **light)
926 {
927 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
928
929 TRACE("iface %p, type %#x, color 0x%08x, light %p.\n", iface, type, color, light);
930
931 return IDirect3DRM3_CreateLight(&d3drm->IDirect3DRM3_iface, type, color, light);
932 }
933
934 static HRESULT WINAPI d3drm2_CreateLightRGB(IDirect3DRM2 *iface, D3DRMLIGHTTYPE type,
935 D3DVALUE red, D3DVALUE green, D3DVALUE blue, IDirect3DRMLight **light)
936 {
937 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
938
939 TRACE("iface %p, type %#x, red %.8e, green %.8e, blue %.8e, light %p.\n",
940 iface, type, red, green, blue, light);
941
942 return IDirect3DRM3_CreateLightRGB(&d3drm->IDirect3DRM3_iface, type, red, green, blue, light);
943 }
944
945 static HRESULT WINAPI d3drm2_CreateMaterial(IDirect3DRM2 *iface,
946 D3DVALUE power, IDirect3DRMMaterial **material)
947 {
948 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
949
950 TRACE("iface %p, power %.8e, material %p.\n", iface, power, material);
951
952 return IDirect3DRM3_CreateMaterial(&d3drm->IDirect3DRM3_iface, power, (IDirect3DRMMaterial2 **)material);
953 }
954
955 static HRESULT WINAPI d3drm2_CreateDevice(IDirect3DRM2 *iface,
956 DWORD width, DWORD height, IDirect3DRMDevice2 **device)
957 {
958 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
959 struct d3drm_device *object;
960 HRESULT hr;
961
962 FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);
963
964 if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface)))
965 return hr;
966
967 *device = &object->IDirect3DRMDevice2_iface;
968
969 return D3DRM_OK;
970 }
971
972 static HRESULT WINAPI d3drm2_CreateDeviceFromSurface(IDirect3DRM2 *iface, GUID *guid,
973 IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, IDirect3DRMDevice2 **device)
974 {
975 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
976 IDirect3DRMDevice3 *device3;
977 HRESULT hr;
978 TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, device %p.\n",
979 iface, debugstr_guid(guid), ddraw, backbuffer, device);
980
981 if (!device)
982 return D3DRMERR_BADVALUE;
983 *device = NULL;
984 hr = IDirect3DRM3_CreateDeviceFromSurface(&d3drm->IDirect3DRM3_iface, guid, ddraw, backbuffer, 0, &device3);
985 if (FAILED(hr))
986 return hr;
987
988 hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice2, (void**)device);
989 IDirect3DRMDevice3_Release(device3);
990
991 return hr;
992 }
993
994 static HRESULT WINAPI d3drm2_CreateDeviceFromD3D(IDirect3DRM2 *iface,
995 IDirect3D2 *d3d, IDirect3DDevice2 *d3d_device, IDirect3DRMDevice2 **device)
996 {
997 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
998 IDirect3DRMDevice3 *device3;
999 HRESULT hr;
1000
1001 TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
1002 iface, d3d, d3d_device, device);
1003
1004 if (!device)
1005 return D3DRMERR_BADVALUE;
1006 *device = NULL;
1007
1008 hr = IDirect3DRM3_CreateDeviceFromD3D(&d3drm->IDirect3DRM3_iface, d3d, d3d_device, &device3);
1009 if (FAILED(hr))
1010 return hr;
1011
1012 hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice2, (void **)device);
1013 IDirect3DRMDevice3_Release(device3);
1014
1015 return hr;
1016 }
1017
1018 static HRESULT WINAPI d3drm2_CreateDeviceFromClipper(IDirect3DRM2 *iface,
1019 IDirectDrawClipper *clipper, GUID *guid, int width, int height,
1020 IDirect3DRMDevice2 **device)
1021 {
1022 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1023 IDirect3DRMDevice3 *device3;
1024 HRESULT hr;
1025
1026 TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
1027 iface, clipper, debugstr_guid(guid), width, height, device);
1028
1029 if (!device)
1030 return D3DRMERR_BADVALUE;
1031 *device = NULL;
1032 hr = IDirect3DRM3_CreateDeviceFromClipper(&d3drm->IDirect3DRM3_iface, clipper, guid, width, height, &device3);
1033 if (FAILED(hr))
1034 return hr;
1035
1036 hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice2, (void**)device);
1037 IDirect3DRMDevice3_Release(device3);
1038
1039 return hr;
1040 }
1041
1042 static HRESULT WINAPI d3drm2_CreateTextureFromSurface(IDirect3DRM2 *iface,
1043 IDirectDrawSurface *surface, IDirect3DRMTexture2 **texture)
1044 {
1045 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1046 IDirect3DRMTexture3 *texture3;
1047 HRESULT hr;
1048
1049 TRACE("iface %p, surface %p, texture %p.\n", iface, surface, texture);
1050
1051 if (!texture)
1052 return D3DRMERR_BADVALUE;
1053
1054 if (FAILED(hr = IDirect3DRM3_CreateTextureFromSurface(&d3drm->IDirect3DRM3_iface, surface, &texture3)))
1055 {
1056 *texture = NULL;
1057 return hr;
1058 }
1059
1060 hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture, (void **)texture);
1061 IDirect3DRMTexture3_Release(texture3);
1062
1063 return hr;
1064 }
1065
1066 static HRESULT WINAPI d3drm2_CreateShadow(IDirect3DRM2 *iface, IDirect3DRMVisual *visual,
1067 IDirect3DRMLight *light, D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz,
1068 IDirect3DRMVisual **shadow)
1069 {
1070 FIXME("iface %p, visual %p, light %p, px %.8e, py %.8e, pz %.8e, nx %.8e, ny %.8e, nz %.8e, shadow %p stub!\n",
1071 iface, visual, light, px, py, pz, nx, ny, nz, shadow);
1072
1073 return E_NOTIMPL;
1074 }
1075
1076 static HRESULT WINAPI d3drm2_CreateViewport(IDirect3DRM2 *iface, IDirect3DRMDevice *device,
1077 IDirect3DRMFrame *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport **viewport)
1078 {
1079 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1080 IDirect3DRMDevice3 *device3;
1081 IDirect3DRMFrame3 *camera3;
1082 IDirect3DRMViewport2 *viewport2;
1083 HRESULT hr;
1084
1085 TRACE("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p.\n",
1086 iface, device, camera, x, y, width, height, viewport);
1087
1088 if (!device || !camera)
1089 return D3DRMERR_BADOBJECT;
1090 if (!viewport)
1091 return D3DRMERR_BADVALUE;
1092
1093 if (FAILED(hr = IDirect3DRMDevice_QueryInterface(device, &IID_IDirect3DRMDevice3, (void **)&device3)))
1094 return hr;
1095
1096 if (FAILED(hr = IDirect3DRMFrame_QueryInterface(camera, &IID_IDirect3DRMFrame3, (void **)&camera3)))
1097 {
1098 IDirect3DRMDevice3_Release(device3);
1099 return hr;
1100 }
1101
1102 hr = IDirect3DRM3_CreateViewport(&d3drm->IDirect3DRM3_iface, device3, camera3, x, y, width, height, &viewport2);
1103 IDirect3DRMDevice3_Release(device3);
1104 IDirect3DRMFrame3_Release(camera3);
1105 if (FAILED(hr))
1106 return hr;
1107
1108 hr = IDirect3DRMViewport2_QueryInterface(viewport2, &IID_IDirect3DRMViewport, (void **)viewport);
1109 IDirect3DRMViewport2_Release(viewport2);
1110
1111 return hr;
1112 }
1113
1114 static HRESULT WINAPI d3drm2_CreateWrap(IDirect3DRM2 *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame *frame,
1115 D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz,
1116 D3DVALUE ux, D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv,
1117 IDirect3DRMWrap **wrap)
1118 {
1119 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1120
1121 TRACE("iface %p, type %#x, frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, "
1122 "ux %.8e, uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e, wrap %p.\n",
1123 iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);
1124
1125 return IDirect3DRM_CreateWrap(&d3drm->IDirect3DRM_iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz,
1126 ou, ov, su, sv, wrap);
1127 }
1128
1129 static HRESULT WINAPI d3drm2_CreateUserVisual(IDirect3DRM2 *iface,
1130 D3DRMUSERVISUALCALLBACK cb, void *ctx, IDirect3DRMUserVisual **visual)
1131 {
1132 FIXME("iface %p, cb %p, ctx %p, visual %p stub!\n", iface, cb, ctx, visual);
1133
1134 return E_NOTIMPL;
1135 }
1136
1137 static HRESULT WINAPI d3drm2_LoadTexture(IDirect3DRM2 *iface,
1138 const char *filename, IDirect3DRMTexture2 **texture)
1139 {
1140 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1141 struct d3drm_texture *object;
1142 HRESULT hr;
1143
1144 FIXME("iface %p, filename %s, texture %p stub!\n", iface, debugstr_a(filename), texture);
1145
1146 if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1147 return hr;
1148
1149 *texture = &object->IDirect3DRMTexture2_iface;
1150
1151 return hr;
1152 }
1153
1154 static HRESULT WINAPI d3drm2_LoadTextureFromResource(IDirect3DRM2 *iface, HMODULE module,
1155 const char *resource_name, const char *resource_type, IDirect3DRMTexture2 **texture)
1156 {
1157 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1158 struct d3drm_texture *object;
1159 HRESULT hr;
1160
1161 FIXME("iface %p, resource_name %s, resource_type %s, texture %p stub!\n",
1162 iface, debugstr_a(resource_name), debugstr_a(resource_type), texture);
1163
1164 if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1165 return hr;
1166
1167 *texture = &object->IDirect3DRMTexture2_iface;
1168
1169 return D3DRM_OK;
1170 }
1171
1172 static HRESULT WINAPI d3drm2_SetSearchPath(IDirect3DRM2 *iface, const char *path)
1173 {
1174 FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
1175
1176 return E_NOTIMPL;
1177 }
1178
1179 static HRESULT WINAPI d3drm2_AddSearchPath(IDirect3DRM2 *iface, const char *path)
1180 {
1181 FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
1182
1183 return E_NOTIMPL;
1184 }
1185
1186 static HRESULT WINAPI d3drm2_GetSearchPath(IDirect3DRM2 *iface, DWORD *size, char *path)
1187 {
1188 FIXME("iface %p, size %p, path %p stub!\n", iface, size, path);
1189
1190 return E_NOTIMPL;
1191 }
1192
1193 static HRESULT WINAPI d3drm2_SetDefaultTextureColors(IDirect3DRM2 *iface, DWORD color_count)
1194 {
1195 FIXME("iface %p, color_count %u stub!\n", iface, color_count);
1196
1197 return E_NOTIMPL;
1198 }
1199
1200 static HRESULT WINAPI d3drm2_SetDefaultTextureShades(IDirect3DRM2 *iface, DWORD shade_count)
1201 {
1202 FIXME("iface %p, shade_count %u stub!\n", iface, shade_count);
1203
1204 return E_NOTIMPL;
1205 }
1206
1207 static HRESULT WINAPI d3drm2_GetDevices(IDirect3DRM2 *iface, IDirect3DRMDeviceArray **array)
1208 {
1209 FIXME("iface %p, array %p stub!\n", iface, array);
1210
1211 return E_NOTIMPL;
1212 }
1213
1214 static HRESULT WINAPI d3drm2_GetNamedObject(IDirect3DRM2 *iface,
1215 const char *name, IDirect3DRMObject **object)
1216 {
1217 FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);
1218
1219 return E_NOTIMPL;
1220 }
1221
1222 static HRESULT WINAPI d3drm2_EnumerateObjects(IDirect3DRM2 *iface, D3DRMOBJECTCALLBACK cb, void *ctx)
1223 {
1224 FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
1225
1226 return E_NOTIMPL;
1227 }
1228
1229 static HRESULT WINAPI d3drm2_Load(IDirect3DRM2 *iface, void *source, void *object_id, IID **iids,
1230 DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
1231 D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame *parent_frame)
1232 {
1233 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1234 IDirect3DRMFrame3 *parent_frame3 = NULL;
1235 HRESULT hr = D3DRM_OK;
1236
1237 TRACE("iface %p, source %p, object_id %p, iids %p, iid_count %u, flags %#x, "
1238 "load_cb %p, load_ctx %p, load_tex_cb %p, load_tex_ctx %p, parent_frame %p.\n",
1239 iface, source, object_id, iids, iid_count, flags,
1240 load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
1241
1242 if (parent_frame)
1243 hr = IDirect3DRMFrame_QueryInterface(parent_frame, &IID_IDirect3DRMFrame3, (void **)&parent_frame3);
1244 if (SUCCEEDED(hr))
1245 hr = IDirect3DRM3_Load(&d3drm->IDirect3DRM3_iface, source, object_id, iids, iid_count,
1246 flags, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame3);
1247 if (parent_frame3)
1248 IDirect3DRMFrame3_Release(parent_frame3);
1249
1250 return hr;
1251 }
1252
1253 static HRESULT WINAPI d3drm2_Tick(IDirect3DRM2 *iface, D3DVALUE tick)
1254 {
1255 FIXME("iface %p, tick %.8e stub!\n", iface, tick);
1256
1257 return E_NOTIMPL;
1258 }
1259
1260 static HRESULT WINAPI d3drm2_CreateProgressiveMesh(IDirect3DRM2 *iface, IDirect3DRMProgressiveMesh **mesh)
1261 {
1262 FIXME("iface %p, mesh %p stub!\n", iface, mesh);
1263
1264 return E_NOTIMPL;
1265 }
1266
1267 static const struct IDirect3DRM2Vtbl d3drm2_vtbl =
1268 {
1269 d3drm2_QueryInterface,
1270 d3drm2_AddRef,
1271 d3drm2_Release,
1272 d3drm2_CreateObject,
1273 d3drm2_CreateFrame,
1274 d3drm2_CreateMesh,
1275 d3drm2_CreateMeshBuilder,
1276 d3drm2_CreateFace,
1277 d3drm2_CreateAnimation,
1278 d3drm2_CreateAnimationSet,
1279 d3drm2_CreateTexture,
1280 d3drm2_CreateLight,
1281 d3drm2_CreateLightRGB,
1282 d3drm2_CreateMaterial,
1283 d3drm2_CreateDevice,
1284 d3drm2_CreateDeviceFromSurface,
1285 d3drm2_CreateDeviceFromD3D,
1286 d3drm2_CreateDeviceFromClipper,
1287 d3drm2_CreateTextureFromSurface,
1288 d3drm2_CreateShadow,
1289 d3drm2_CreateViewport,
1290 d3drm2_CreateWrap,
1291 d3drm2_CreateUserVisual,
1292 d3drm2_LoadTexture,
1293 d3drm2_LoadTextureFromResource,
1294 d3drm2_SetSearchPath,
1295 d3drm2_AddSearchPath,
1296 d3drm2_GetSearchPath,
1297 d3drm2_SetDefaultTextureColors,
1298 d3drm2_SetDefaultTextureShades,
1299 d3drm2_GetDevices,
1300 d3drm2_GetNamedObject,
1301 d3drm2_EnumerateObjects,
1302 d3drm2_Load,
1303 d3drm2_Tick,
1304 d3drm2_CreateProgressiveMesh,
1305 };
1306
1307 static HRESULT WINAPI d3drm3_QueryInterface(IDirect3DRM3 *iface, REFIID riid, void **out)
1308 {
1309 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1310
1311 return d3drm1_QueryInterface(&d3drm->IDirect3DRM_iface, riid, out);
1312 }
1313
1314 static ULONG WINAPI d3drm3_AddRef(IDirect3DRM3 *iface)
1315 {
1316 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1317 ULONG refcount = InterlockedIncrement(&d3drm->ref3);
1318
1319 TRACE("%p increasing refcount to %u.\n", iface, refcount);
1320
1321 if (refcount == 1)
1322 InterlockedIncrement(&d3drm->iface_count);
1323
1324 return refcount;
1325 }
1326
1327 static ULONG WINAPI d3drm3_Release(IDirect3DRM3 *iface)
1328 {
1329 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1330 ULONG refcount = InterlockedDecrement(&d3drm->ref3);
1331
1332 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
1333
1334 if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
1335 d3drm_destroy(d3drm);
1336
1337 return refcount;
1338 }
1339
1340 static HRESULT WINAPI d3drm3_CreateObject(IDirect3DRM3 *iface,
1341 REFCLSID clsid, IUnknown *outer, REFIID iid, void **out)
1342 {
1343 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1344 IUnknown *object;
1345 unsigned int i;
1346 HRESULT hr;
1347
1348 static const struct
1349 {
1350 const CLSID *clsid;
1351 HRESULT (*create_object)(void **object, IDirect3DRM *d3drm);
1352 }
1353 object_table[] =
1354 {
1355 {&CLSID_CDirect3DRMTexture, d3drm_create_texture_object},
1356 {&CLSID_CDirect3DRMDevice, d3drm_create_device_object},
1357 {&CLSID_CDirect3DRMViewport, d3drm_create_viewport_object},
1358 {&CLSID_CDirect3DRMFace, d3drm_create_face_object},
1359 {&CLSID_CDirect3DRMMeshBuilder, d3drm_create_mesh_builder_object},
1360 {&CLSID_CDirect3DRMFrame, d3drm_create_frame_object},
1361 {&CLSID_CDirect3DRMLight, d3drm_create_light_object},
1362 {&CLSID_CDirect3DRMMaterial, d3drm_create_material_object},
1363 {&CLSID_CDirect3DRMMesh, d3drm_create_mesh_object},
1364 {&CLSID_CDirect3DRMAnimation, d3drm_create_animation_object},
1365 {&CLSID_CDirect3DRMWrap, d3drm_create_wrap_object},
1366 };
1367
1368 TRACE("iface %p, clsid %s, outer %p, iid %s, out %p.\n",
1369 iface, debugstr_guid(clsid), outer, debugstr_guid(iid), out);
1370
1371 if (!out)
1372 return D3DRMERR_BADVALUE;
1373
1374 if (!clsid || !iid)
1375 {
1376 *out = NULL;
1377 return D3DRMERR_BADVALUE;
1378 }
1379
1380 if (outer)
1381 {
1382 FIXME("COM aggregation for outer IUnknown (%p) not implemented. Returning E_NOTIMPL.\n", outer);
1383 *out = NULL;
1384 return E_NOTIMPL;
1385 }
1386
1387 for (i = 0; i < ARRAY_SIZE(object_table); ++i)
1388 {
1389 if (IsEqualGUID(clsid, object_table[i].clsid))
1390 {
1391 if (FAILED(hr = object_table[i].create_object((void **)&object, &d3drm->IDirect3DRM_iface)))
1392 {
1393 *out = NULL;
1394 return hr;
1395 }
1396 break;
1397 }
1398 }
1399 if (i == ARRAY_SIZE(object_table))
1400 {
1401 FIXME("%s not implemented. Returning CLASSFACTORY_E_FIRST.\n", debugstr_guid(clsid));
1402 *out = NULL;
1403 return CLASSFACTORY_E_FIRST;
1404 }
1405
1406 if (FAILED(hr = IUnknown_QueryInterface(object, iid, out)))
1407 *out = NULL;
1408 IUnknown_Release(object);
1409
1410 return hr;
1411 }
1412
1413 static HRESULT WINAPI d3drm3_CreateFrame(IDirect3DRM3 *iface,
1414 IDirect3DRMFrame3 *parent, IDirect3DRMFrame3 **frame)
1415 {
1416 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1417 struct d3drm_frame *object;
1418 HRESULT hr;
1419
1420 TRACE("iface %p, parent %p, frame %p.\n", iface, parent, frame);
1421
1422 if (FAILED(hr = d3drm_frame_create(&object, (IUnknown *)parent, &d3drm->IDirect3DRM_iface)))
1423 return hr;
1424
1425 *frame = &object->IDirect3DRMFrame3_iface;
1426
1427 return D3DRM_OK;
1428 }
1429
1430 static HRESULT WINAPI d3drm3_CreateMesh(IDirect3DRM3 *iface, IDirect3DRMMesh **mesh)
1431 {
1432 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1433 struct d3drm_mesh *object;
1434 HRESULT hr;
1435
1436 TRACE("iface %p, mesh %p.\n", iface, mesh);
1437
1438 if (FAILED(hr = d3drm_mesh_create(&object, &d3drm->IDirect3DRM_iface)))
1439 return hr;
1440
1441 *mesh = &object->IDirect3DRMMesh_iface;
1442
1443 return S_OK;
1444 }
1445
1446 static HRESULT WINAPI d3drm3_CreateMeshBuilder(IDirect3DRM3 *iface, IDirect3DRMMeshBuilder3 **mesh_builder)
1447 {
1448 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1449 struct d3drm_mesh_builder *object;
1450 HRESULT hr;
1451
1452 TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);
1453
1454 if (FAILED(hr = d3drm_mesh_builder_create(&object, &d3drm->IDirect3DRM_iface)))
1455 return hr;
1456
1457 *mesh_builder = &object->IDirect3DRMMeshBuilder3_iface;
1458
1459 return S_OK;
1460 }
1461
1462 static HRESULT WINAPI d3drm3_CreateFace(IDirect3DRM3 *iface, IDirect3DRMFace2 **face)
1463 {
1464 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1465 IDirect3DRMFace *face1;
1466 HRESULT hr;
1467
1468 TRACE("iface %p, face %p.\n", iface, face);
1469
1470 if (FAILED(hr = IDirect3DRM_CreateFace(&d3drm->IDirect3DRM_iface, &face1)))
1471 return hr;
1472
1473 hr = IDirect3DRMFace_QueryInterface(face1, &IID_IDirect3DRMFace2, (void **)face);
1474 IDirect3DRMFace_Release(face1);
1475
1476 return hr;
1477 }
1478
1479 static HRESULT WINAPI d3drm3_CreateAnimation(IDirect3DRM3 *iface, IDirect3DRMAnimation2 **animation)
1480 {
1481 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1482 struct d3drm_animation *object;
1483 HRESULT hr;
1484
1485 TRACE("iface %p, animation %p.\n", iface, animation);
1486
1487 if (FAILED(hr = d3drm_animation_create(&object, &d3drm->IDirect3DRM_iface)))
1488 return hr;
1489
1490 *animation = &object->IDirect3DRMAnimation2_iface;
1491
1492 return hr;
1493 }
1494
1495 static HRESULT WINAPI d3drm3_CreateAnimationSet(IDirect3DRM3 *iface, IDirect3DRMAnimationSet2 **set)
1496 {
1497 FIXME("iface %p, set %p stub!\n", iface, set);
1498
1499 return E_NOTIMPL;
1500 }
1501
1502 static HRESULT WINAPI d3drm3_CreateTexture(IDirect3DRM3 *iface,
1503 D3DRMIMAGE *image, IDirect3DRMTexture3 **texture)
1504 {
1505 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1506 struct d3drm_texture *object;
1507 HRESULT hr;
1508
1509 TRACE("iface %p, image %p, texture %p.\n", iface, image, texture);
1510
1511 if (!texture)
1512 return D3DRMERR_BADVALUE;
1513
1514 if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1515 return hr;
1516
1517 *texture = &object->IDirect3DRMTexture3_iface;
1518
1519 if (FAILED(IDirect3DRMTexture3_InitFromImage(*texture, image)))
1520 {
1521 IDirect3DRMTexture3_Release(*texture);
1522 *texture = NULL;
1523 return D3DRMERR_BADVALUE;
1524 }
1525
1526 return D3DRM_OK;
1527 }
1528
1529 static HRESULT WINAPI d3drm3_CreateLight(IDirect3DRM3 *iface,
1530 D3DRMLIGHTTYPE type, D3DCOLOR color, IDirect3DRMLight **light)
1531 {
1532 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1533 struct d3drm_light *object;
1534 HRESULT hr;
1535
1536 FIXME("iface %p, type %#x, color 0x%08x, light %p partial stub!\n", iface, type, color, light);
1537
1538 if (SUCCEEDED(hr = d3drm_light_create(&object, &d3drm->IDirect3DRM_iface)))
1539 {
1540 IDirect3DRMLight_SetType(&object->IDirect3DRMLight_iface, type);
1541 IDirect3DRMLight_SetColor(&object->IDirect3DRMLight_iface, color);
1542 }
1543
1544 *light = &object->IDirect3DRMLight_iface;
1545
1546 return hr;
1547 }
1548
1549 static HRESULT WINAPI d3drm3_CreateLightRGB(IDirect3DRM3 *iface, D3DRMLIGHTTYPE type,
1550 D3DVALUE red, D3DVALUE green, D3DVALUE blue, IDirect3DRMLight **light)
1551 {
1552 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1553 struct d3drm_light *object;
1554 HRESULT hr;
1555
1556 FIXME("iface %p, type %#x, red %.8e, green %.8e, blue %.8e, light %p partial stub!\n",
1557 iface, type, red, green, blue, light);
1558
1559 if (SUCCEEDED(hr = d3drm_light_create(&object, &d3drm->IDirect3DRM_iface)))
1560 {
1561 IDirect3DRMLight_SetType(&object->IDirect3DRMLight_iface, type);
1562 IDirect3DRMLight_SetColorRGB(&object->IDirect3DRMLight_iface, red, green, blue);
1563 }
1564
1565 *light = &object->IDirect3DRMLight_iface;
1566
1567 return hr;
1568 }
1569
1570 static HRESULT WINAPI d3drm3_CreateMaterial(IDirect3DRM3 *iface,
1571 D3DVALUE power, IDirect3DRMMaterial2 **material)
1572 {
1573 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1574 struct d3drm_material *object;
1575 HRESULT hr;
1576
1577 TRACE("iface %p, power %.8e, material %p.\n", iface, power, material);
1578
1579 if (SUCCEEDED(hr = d3drm_material_create(&object, &d3drm->IDirect3DRM_iface)))
1580 IDirect3DRMMaterial2_SetPower(&object->IDirect3DRMMaterial2_iface, power);
1581
1582 *material = &object->IDirect3DRMMaterial2_iface;
1583
1584 return hr;
1585 }
1586
1587 static HRESULT WINAPI d3drm3_CreateDevice(IDirect3DRM3 *iface,
1588 DWORD width, DWORD height, IDirect3DRMDevice3 **device)
1589 {
1590 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1591 struct d3drm_device *object;
1592 HRESULT hr;
1593
1594 FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);
1595
1596 if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface)))
1597 return hr;
1598
1599 *device = &object->IDirect3DRMDevice3_iface;
1600
1601 return D3DRM_OK;
1602 }
1603
1604 static HRESULT WINAPI d3drm3_CreateDeviceFromSurface(IDirect3DRM3 *iface, GUID *guid,
1605 IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, DWORD flags, IDirect3DRMDevice3 **device)
1606 {
1607 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1608 struct d3drm_device *object;
1609 BOOL use_z_surface;
1610 HRESULT hr;
1611
1612 TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, flags %#x, device %p.\n",
1613 iface, debugstr_guid(guid), ddraw, backbuffer, flags, device);
1614
1615 if (!device)
1616 return D3DRMERR_BADVALUE;
1617 *device = NULL;
1618
1619 if (!backbuffer || !ddraw)
1620 return D3DRMERR_BADDEVICE;
1621
1622 if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface)))
1623 return hr;
1624
1625 use_z_surface = !(flags & D3DRMDEVICE_NOZBUFFER);
1626
1627 if (SUCCEEDED(hr = d3drm_device_init(object, 3, ddraw, backbuffer, use_z_surface)))
1628 *device = &object->IDirect3DRMDevice3_iface;
1629 else
1630 d3drm_device_destroy(object);
1631
1632 return hr;
1633 }
1634
1635 static HRESULT WINAPI d3drm3_CreateDeviceFromD3D(IDirect3DRM3 *iface,
1636 IDirect3D2 *d3d, IDirect3DDevice2 *d3d_device, IDirect3DRMDevice3 **device)
1637 {
1638 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1639 struct d3drm_device *object;
1640 HRESULT hr;
1641
1642 TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
1643 iface, d3d, d3d_device, device);
1644
1645 if (!device)
1646 return D3DRMERR_BADVALUE;
1647 *device = NULL;
1648
1649 if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface)))
1650 return hr;
1651
1652 if (FAILED(hr = IDirect3DRMDevice3_InitFromD3D2(&object->IDirect3DRMDevice3_iface, d3d, d3d_device)))
1653 {
1654 d3drm_device_destroy(object);
1655 return hr;
1656 }
1657 *device = &object->IDirect3DRMDevice3_iface;
1658
1659 return D3DRM_OK;
1660 }
1661
1662 static HRESULT WINAPI d3drm3_CreateDeviceFromClipper(IDirect3DRM3 *iface,
1663 IDirectDrawClipper *clipper, GUID *guid, int width, int height,
1664 IDirect3DRMDevice3 **device)
1665 {
1666 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1667 struct d3drm_device *object;
1668 IDirectDraw *ddraw;
1669 IDirectDrawSurface *render_target;
1670 HRESULT hr;
1671
1672 TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
1673 iface, clipper, debugstr_guid(guid), width, height, device);
1674
1675 if (!device)
1676 return D3DRMERR_BADVALUE;
1677 *device = NULL;
1678
1679 if (!clipper || !width || !height)
1680 return D3DRMERR_BADVALUE;
1681
1682 hr = DirectDrawCreate(NULL, &ddraw, NULL);
1683 if (FAILED(hr))
1684 return hr;
1685
1686 if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface)))
1687 {
1688 IDirectDraw_Release(ddraw);
1689 return hr;
1690 }
1691
1692 hr = d3drm_device_create_surfaces_from_clipper(object, ddraw, clipper, width, height, &render_target);
1693 if (FAILED(hr))
1694 {
1695 IDirectDraw_Release(ddraw);
1696 d3drm_device_destroy(object);
1697 return hr;
1698 }
1699
1700 hr = d3drm_device_init(object, 3, ddraw, render_target, TRUE);
1701 IDirectDraw_Release(ddraw);
1702 IDirectDrawSurface_Release(render_target);
1703 if (FAILED(hr))
1704 d3drm_device_destroy(object);
1705 else
1706 *device = &object->IDirect3DRMDevice3_iface;
1707
1708 return hr;
1709 }
1710
1711 static HRESULT WINAPI d3drm3_CreateShadow(IDirect3DRM3 *iface, IUnknown *object, IDirect3DRMLight *light,
1712 D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz, IDirect3DRMShadow2 **shadow)
1713 {
1714 FIXME("iface %p, object %p, light %p, px %.8e, py %.8e, pz %.8e, nx %.8e, ny %.8e, nz %.8e, shadow %p stub!\n",
1715 iface, object, light, px, py, pz, nx, ny, nz, shadow);
1716
1717 return E_NOTIMPL;
1718 }
1719
1720 static HRESULT WINAPI d3drm3_CreateTextureFromSurface(IDirect3DRM3 *iface,
1721 IDirectDrawSurface *surface, IDirect3DRMTexture3 **texture)
1722 {
1723 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1724 struct d3drm_texture *object;
1725 HRESULT hr;
1726
1727 TRACE("iface %p, surface %p, texture %p.\n", iface, surface, texture);
1728
1729 if (!texture)
1730 return D3DRMERR_BADVALUE;
1731
1732 if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1733 return hr;
1734
1735 *texture = &object->IDirect3DRMTexture3_iface;
1736
1737 if (FAILED(IDirect3DRMTexture3_InitFromSurface(*texture, surface)))
1738 {
1739 IDirect3DRMTexture3_Release(*texture);
1740 *texture = NULL;
1741 return D3DRMERR_BADVALUE;
1742 }
1743
1744 return D3DRM_OK;
1745 }
1746
1747 static HRESULT WINAPI d3drm3_CreateViewport(IDirect3DRM3 *iface, IDirect3DRMDevice3 *device,
1748 IDirect3DRMFrame3 *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport2 **viewport)
1749 {
1750 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1751 struct d3drm_viewport *object;
1752 HRESULT hr;
1753
1754 TRACE("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p.\n",
1755 iface, device, camera, x, y, width, height, viewport);
1756
1757 if (!device || !camera)
1758 return D3DRMERR_BADOBJECT;
1759 if (!viewport)
1760 return D3DRMERR_BADVALUE;
1761
1762 if (FAILED(hr = d3drm_viewport_create(&object, &d3drm->IDirect3DRM_iface)))
1763 return hr;
1764
1765 *viewport = &object->IDirect3DRMViewport2_iface;
1766
1767 if (FAILED(hr = IDirect3DRMViewport2_Init(*viewport, device, camera, x, y, width, height)))
1768 {
1769 IDirect3DRMViewport2_Release(*viewport);
1770 *viewport = NULL;
1771 return D3DRMERR_BADVALUE;
1772 }
1773
1774 return D3DRM_OK;
1775 }
1776
1777 static HRESULT WINAPI d3drm3_CreateWrap(IDirect3DRM3 *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame3 *frame,
1778 D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz,
1779 D3DVALUE ux, D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv,
1780 IDirect3DRMWrap **wrap)
1781 {
1782 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1783 struct d3drm_wrap *object;
1784 HRESULT hr;
1785
1786 FIXME("iface %p, type %#x, frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, "
1787 "ux %.8e, uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e, wrap %p, semi-stub.\n",
1788 iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);
1789
1790 if (!wrap)
1791 return D3DRMERR_BADVALUE;
1792
1793 if (FAILED(hr = d3drm_wrap_create(&object, &d3drm->IDirect3DRM_iface)))
1794 return hr;
1795
1796 *wrap = &object->IDirect3DRMWrap_iface;
1797
1798 return S_OK;
1799 }
1800
1801 static HRESULT WINAPI d3drm3_CreateUserVisual(IDirect3DRM3 *iface,
1802 D3DRMUSERVISUALCALLBACK cb, void *ctx, IDirect3DRMUserVisual **visual)
1803 {
1804 FIXME("iface %p, cb %p, ctx %p, visual %p stub!\n", iface, cb, ctx, visual);
1805
1806 return E_NOTIMPL;
1807 }
1808
1809 static HRESULT WINAPI d3drm3_LoadTexture(IDirect3DRM3 *iface,
1810 const char *filename, IDirect3DRMTexture3 **texture)
1811 {
1812 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1813 struct d3drm_texture *object;
1814 HRESULT hr;
1815
1816 FIXME("iface %p, filename %s, texture %p stub!\n", iface, debugstr_a(filename), texture);
1817
1818 if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1819 return hr;
1820
1821 *texture = &object->IDirect3DRMTexture3_iface;
1822
1823 return D3DRM_OK;
1824 }
1825
1826 static HRESULT WINAPI d3drm3_LoadTextureFromResource(IDirect3DRM3 *iface, HMODULE module,
1827 const char *resource_name, const char *resource_type, IDirect3DRMTexture3 **texture)
1828 {
1829 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1830 struct d3drm_texture *object;
1831 HRESULT hr;
1832
1833 FIXME("iface %p, module %p, resource_name %s, resource_type %s, texture %p stub!\n",
1834 iface, module, debugstr_a(resource_name), debugstr_a(resource_type), texture);
1835
1836 if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1837 return hr;
1838
1839 *texture = &object->IDirect3DRMTexture3_iface;
1840
1841 return D3DRM_OK;
1842 }
1843
1844 static HRESULT WINAPI d3drm3_SetSearchPath(IDirect3DRM3 *iface, const char *path)
1845 {
1846 FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
1847
1848 return E_NOTIMPL;
1849 }
1850
1851 static HRESULT WINAPI d3drm3_AddSearchPath(IDirect3DRM3 *iface, const char *path)
1852 {
1853 FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
1854
1855 return E_NOTIMPL;
1856 }
1857
1858 static HRESULT WINAPI d3drm3_GetSearchPath(IDirect3DRM3 *iface, DWORD *size, char *path)
1859 {
1860 FIXME("iface %p, size %p, path %p stub!\n", iface, size, path);
1861
1862 return E_NOTIMPL;
1863 }
1864
1865 static HRESULT WINAPI d3drm3_SetDefaultTextureColors(IDirect3DRM3 *iface, DWORD color_count)
1866 {
1867 FIXME("iface %p, color_count %u stub!\n", iface, color_count);
1868
1869 return E_NOTIMPL;
1870 }
1871
1872 static HRESULT WINAPI d3drm3_SetDefaultTextureShades(IDirect3DRM3 *iface, DWORD shade_count)
1873 {
1874 FIXME("iface %p, shade_count %u stub!\n", iface, shade_count);
1875
1876 return E_NOTIMPL;
1877 }
1878
1879 static HRESULT WINAPI d3drm3_GetDevices(IDirect3DRM3 *iface, IDirect3DRMDeviceArray **array)
1880 {
1881 FIXME("iface %p, array %p stub!\n", iface, array);
1882
1883 return E_NOTIMPL;
1884 }
1885
1886 static HRESULT WINAPI d3drm3_GetNamedObject(IDirect3DRM3 *iface,
1887 const char *name, IDirect3DRMObject **object)
1888 {
1889 FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);
1890
1891 return E_NOTIMPL;
1892 }
1893
1894 static HRESULT WINAPI d3drm3_EnumerateObjects(IDirect3DRM3 *iface, D3DRMOBJECTCALLBACK cb, void *ctx)
1895 {
1896 FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
1897
1898 return E_NOTIMPL;
1899 }
1900
1901 static HRESULT load_data(IDirect3DRM3 *iface, IDirectXFileData *data_object, IID **GUIDs, DWORD nb_GUIDs, D3DRMLOADCALLBACK LoadProc,
1902 void *ArgLP, D3DRMLOADTEXTURECALLBACK LoadTextureProc, void *ArgLTP, IDirect3DRMFrame3 *parent_frame)
1903 {
1904 HRESULT ret = D3DRMERR_BADOBJECT;
1905 HRESULT hr;
1906 const GUID* guid;
1907 DWORD i;
1908 BOOL requested = FALSE;
1909
1910 hr = IDirectXFileData_GetType(data_object, &guid);
1911 if (hr != DXFILE_OK)
1912 goto end;
1913
1914 TRACE("Found object type whose GUID = %s\n", debugstr_guid(guid));
1915
1916 /* Load object only if it is top level and requested or if it is part of another object */
1917
1918 if (IsEqualGUID(guid, &TID_D3DRMMesh))
1919 {
1920 TRACE("Found TID_D3DRMMesh\n");
1921
1922 for (i = 0; i < nb_GUIDs; i++)
1923 if (IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder) ||
1924 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder2) ||
1925 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder3))
1926 {
1927 requested = TRUE;
1928 break;
1929 }
1930
1931 if (requested || parent_frame)
1932 {
1933 IDirect3DRMMeshBuilder3 *meshbuilder;
1934
1935 TRACE("Load mesh data\n");
1936
1937 hr = IDirect3DRM3_CreateMeshBuilder(iface, &meshbuilder);
1938 if (SUCCEEDED(hr))
1939 {
1940 hr = load_mesh_data(meshbuilder, data_object, LoadTextureProc, ArgLTP);
1941 if (SUCCEEDED(hr))
1942 {
1943 /* Only top level objects are notified */
1944 if (!parent_frame)
1945 {
1946 IDirect3DRMObject *object;
1947
1948 hr = IDirect3DRMMeshBuilder3_QueryInterface(meshbuilder, GUIDs[i], (void**)&object);
1949 if (SUCCEEDED(hr))
1950 {
1951 LoadProc(object, GUIDs[i], ArgLP);
1952 IDirect3DRMObject_Release(object);
1953 }
1954 }
1955 else
1956 {
1957 IDirect3DRMFrame3_AddVisual(parent_frame, (IUnknown*)meshbuilder);
1958 }
1959 }
1960 IDirect3DRMMeshBuilder3_Release(meshbuilder);
1961 }
1962
1963 if (FAILED(hr))
1964 ERR("Cannot process mesh\n");
1965 }
1966 }
1967 else if (IsEqualGUID(guid, &TID_D3DRMFrame))
1968 {
1969 TRACE("Found TID_D3DRMFrame\n");
1970
1971 for (i = 0; i < nb_GUIDs; i++)
1972 if (IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame) ||
1973 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame2) ||
1974 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame3))
1975 {
1976 requested = TRUE;
1977 break;
1978 }
1979
1980 if (requested || parent_frame)
1981 {
1982 IDirect3DRMFrame3 *frame;
1983
1984 TRACE("Load frame data\n");
1985
1986 hr = IDirect3DRM3_CreateFrame(iface, parent_frame, &frame);
1987 if (SUCCEEDED(hr))
1988 {
1989 IDirectXFileObject *child;
1990
1991 while (SUCCEEDED(hr = IDirectXFileData_GetNextObject(data_object, &child)))
1992 {
1993 IDirectXFileData *data;
1994 IDirectXFileDataReference *reference;
1995 IDirectXFileBinary *binary;
1996
1997 if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
1998 &IID_IDirectXFileBinary, (void **)&binary)))
1999 {
2000 FIXME("Binary Object not supported yet\n");
2001 IDirectXFileBinary_Release(binary);
2002 }
2003 else if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
2004 &IID_IDirectXFileData, (void **)&data)))
2005 {
2006 TRACE("Found Data Object\n");
2007 hr = load_data(iface, data, GUIDs, nb_GUIDs, LoadProc, ArgLP, LoadTextureProc, ArgLTP, frame);
2008 IDirectXFileData_Release(data);
2009 }
2010 else if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
2011 &IID_IDirectXFileDataReference, (void **)&reference)))
2012 {
2013 TRACE("Found Data Object Reference\n");
2014 IDirectXFileDataReference_Resolve(reference, &data);
2015 hr = load_data(iface, data, GUIDs, nb_GUIDs, LoadProc, ArgLP, LoadTextureProc, ArgLTP, frame);
2016 IDirectXFileData_Release(data);
2017 IDirectXFileDataReference_Release(reference);
2018 }
2019 IDirectXFileObject_Release(child);
2020 }
2021
2022 if (hr != DXFILEERR_NOMOREOBJECTS)
2023 {
2024 IDirect3DRMFrame3_Release(frame);
2025 goto end;
2026 }
2027 hr = S_OK;
2028
2029 /* Only top level objects are notified */
2030 if (!parent_frame)
2031 {
2032 IDirect3DRMObject *object;
2033
2034 hr = IDirect3DRMFrame3_QueryInterface(frame, GUIDs[i], (void**)&object);
2035 if (SUCCEEDED(hr))
2036 {
2037 LoadProc(object, GUIDs[i], ArgLP);
2038 IDirect3DRMObject_Release(object);
2039 }
2040 }
2041 IDirect3DRMFrame3_Release(frame);
2042 }
2043
2044 if (FAILED(hr))
2045 ERR("Cannot process frame\n");
2046 }
2047 }
2048 else if (IsEqualGUID(guid, &TID_D3DRMMaterial))
2049 {
2050 TRACE("Found TID_D3DRMMaterial\n");
2051
2052 /* Cannot be requested so nothing to do */
2053 }
2054 else if (IsEqualGUID(guid, &TID_D3DRMFrameTransformMatrix))
2055 {
2056 TRACE("Found TID_D3DRMFrameTransformMatrix\n");
2057
2058 /* Cannot be requested */
2059 if (parent_frame)
2060 {
2061 D3DRMMATRIX4D *matrix;
2062 DWORD size;
2063
2064 TRACE("Load Frame Transform Matrix data\n");
2065
2066 hr = IDirectXFileData_GetData(data_object, NULL, &size, (void**)&matrix);
2067 if ((hr != DXFILE_OK) || (size != sizeof(matrix)))
2068 goto end;
2069
2070 hr = IDirect3DRMFrame3_AddTransform(parent_frame, D3DRMCOMBINE_REPLACE, *matrix);
2071 if (FAILED(hr))
2072 goto end;
2073 }
2074 }
2075 else
2076 {
2077 FIXME("Found unknown TID %s\n", debugstr_guid(guid));
2078 }
2079
2080 ret = D3DRM_OK;
2081
2082 end:
2083
2084 return ret;
2085 }
2086
2087 static HRESULT WINAPI d3drm3_Load(IDirect3DRM3 *iface, void *source, void *object_id, IID **iids,
2088 DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
2089 D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame3 *parent_frame)
2090 {
2091 DXFILELOADOPTIONS load_options;
2092 IDirectXFile *file = NULL;
2093 IDirectXFileEnumObject *enum_object = NULL;
2094 IDirectXFileData *data = NULL;
2095 HRESULT hr;
2096 const GUID* pGuid;
2097 DWORD size;
2098 struct d3drm_file_header *header;
2099 HRESULT ret = D3DRMERR_BADOBJECT;
2100 DWORD i;
2101
2102 TRACE("iface %p, source %p, object_id %p, iids %p, iid_count %u, flags %#x, "
2103 "load_cb %p, load_ctx %p, load_tex_cb %p, load_tex_ctx %p, parent_frame %p.\n",
2104 iface, source, object_id, iids, iid_count, flags,
2105 load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
2106
2107 TRACE("Looking for GUIDs:\n");
2108 for (i = 0; i < iid_count; ++i)
2109 TRACE("- %s (%s)\n", debugstr_guid(iids[i]), get_IID_string(iids[i]));
2110
2111 if (flags == D3DRMLOAD_FROMMEMORY)
2112 {
2113 load_options = DXFILELOAD_FROMMEMORY;
2114 }
2115 else if (flags == D3DRMLOAD_FROMFILE)
2116 {
2117 load_options = DXFILELOAD_FROMFILE;
2118 TRACE("Loading from file %s\n", debugstr_a(source));
2119 }
2120 else
2121 {
2122 FIXME("Load options %#x not supported yet.\n", flags);
2123 return E_NOTIMPL;
2124 }
2125
2126 hr = DirectXFileCreate(&file);
2127 if (hr != DXFILE_OK)
2128 goto end;
2129
2130 hr = IDirectXFile_RegisterTemplates(file, templates, strlen(templates));
2131 if (hr != DXFILE_OK)
2132 goto end;
2133
2134 hr = IDirectXFile_CreateEnumObject(file, source, load_options, &enum_object);
2135 if (hr != DXFILE_OK)
2136 goto end;
2137
2138 hr = IDirectXFileEnumObject_GetNextDataObject(enum_object, &data);
2139 if (hr != DXFILE_OK)
2140 goto end;
2141
2142 hr = IDirectXFileData_GetType(data, &pGuid);
2143 if (hr != DXFILE_OK)
2144 goto end;
2145
2146 TRACE("Found object type whose GUID = %s\n", debugstr_guid(pGuid));
2147
2148 if (!IsEqualGUID(pGuid, &TID_DXFILEHeader))
2149 {
2150 ret = D3DRMERR_BADFILE;
2151 goto end;
2152 }
2153
2154 hr = IDirectXFileData_GetData(data, NULL, &size, (void **)&header);
2155 if ((hr != DXFILE_OK) || (size != sizeof(*header)))
2156 goto end;
2157
2158 TRACE("Version is %u.%u, flags %#x.\n", header->major, header->minor, header->flags);
2159
2160 /* Version must be 1.0.x */
2161 if ((header->major != 1) || (header->minor != 0))
2162 {
2163 ret = D3DRMERR_BADFILE;
2164 goto end;
2165 }
2166
2167 IDirectXFileData_Release(data);
2168 data = NULL;
2169
2170 while (1)
2171 {
2172 hr = IDirectXFileEnumObject_GetNextDataObject(enum_object, &data);
2173 if (hr == DXFILEERR_NOMOREOBJECTS)
2174 {
2175 TRACE("No more object\n");
2176 break;
2177 }
2178 else if (hr != DXFILE_OK)
2179 {
2180 ret = D3DRMERR_BADFILE;
2181 goto end;
2182 }
2183
2184 ret = load_data(iface, data, iids, iid_count, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
2185 if (ret != D3DRM_OK)
2186 goto end;
2187
2188 IDirectXFileData_Release(data);
2189 data = NULL;
2190 }
2191
2192 ret = D3DRM_OK;
2193
2194 end:
2195 if (data)
2196 IDirectXFileData_Release(data);
2197 if (enum_object)
2198 IDirectXFileEnumObject_Release(enum_object);
2199 if (file)
2200 IDirectXFile_Release(file);
2201
2202 return ret;
2203 }
2204
2205 static HRESULT WINAPI d3drm3_Tick(IDirect3DRM3 *iface, D3DVALUE tick)
2206 {
2207 FIXME("iface %p, tick %.8e stub!\n", iface, tick);
2208
2209 return E_NOTIMPL;
2210 }
2211
2212 static HRESULT WINAPI d3drm3_CreateProgressiveMesh(IDirect3DRM3 *iface, IDirect3DRMProgressiveMesh **mesh)
2213 {
2214 FIXME("iface %p, mesh %p stub!\n", iface, mesh);
2215
2216 return E_NOTIMPL;
2217 }
2218
2219 static HRESULT WINAPI d3drm3_RegisterClient(IDirect3DRM3 *iface, REFGUID guid, DWORD *id)
2220 {
2221 FIXME("iface %p, guid %s, id %p stub!\n", iface, debugstr_guid(guid), id);
2222
2223 return E_NOTIMPL;
2224 }
2225
2226 static HRESULT WINAPI d3drm3_UnregisterClient(IDirect3DRM3 *iface, REFGUID guid)
2227 {
2228 FIXME("iface %p, guid %s stub!\n", iface, debugstr_guid(guid));
2229
2230 return E_NOTIMPL;
2231 }
2232
2233 static HRESULT WINAPI d3drm3_CreateClippedVisual(IDirect3DRM3 *iface,
2234 IDirect3DRMVisual *visual, IDirect3DRMClippedVisual **clipped_visual)
2235 {
2236 FIXME("iface %p, visual %p, clipped_visual %p stub!\n", iface, visual, clipped_visual);
2237
2238 return E_NOTIMPL;
2239 }
2240
2241 static HRESULT WINAPI d3drm3_SetOptions(IDirect3DRM3 *iface, DWORD flags)
2242 {
2243 FIXME("iface %p, flags %#x stub!\n", iface, flags);
2244
2245 return E_NOTIMPL;
2246 }
2247
2248 static HRESULT WINAPI d3drm3_GetOptions(IDirect3DRM3 *iface, DWORD *flags)
2249 {
2250 FIXME("iface %p, flags %p stub!\n", iface, flags);
2251
2252 return E_NOTIMPL;
2253 }
2254
2255 static const struct IDirect3DRM3Vtbl d3drm3_vtbl =
2256 {
2257 d3drm3_QueryInterface,
2258 d3drm3_AddRef,
2259 d3drm3_Release,
2260 d3drm3_CreateObject,
2261 d3drm3_CreateFrame,
2262 d3drm3_CreateMesh,
2263 d3drm3_CreateMeshBuilder,
2264 d3drm3_CreateFace,
2265 d3drm3_CreateAnimation,
2266 d3drm3_CreateAnimationSet,
2267 d3drm3_CreateTexture,
2268 d3drm3_CreateLight,
2269 d3drm3_CreateLightRGB,
2270 d3drm3_CreateMaterial,
2271 d3drm3_CreateDevice,
2272 d3drm3_CreateDeviceFromSurface,
2273 d3drm3_CreateDeviceFromD3D,
2274 d3drm3_CreateDeviceFromClipper,
2275 d3drm3_CreateTextureFromSurface,
2276 d3drm3_CreateShadow,
2277 d3drm3_CreateViewport,
2278 d3drm3_CreateWrap,
2279 d3drm3_CreateUserVisual,
2280 d3drm3_LoadTexture,
2281 d3drm3_LoadTextureFromResource,
2282 d3drm3_SetSearchPath,
2283 d3drm3_AddSearchPath,
2284 d3drm3_GetSearchPath,
2285 d3drm3_SetDefaultTextureColors,
2286 d3drm3_SetDefaultTextureShades,
2287 d3drm3_GetDevices,
2288 d3drm3_GetNamedObject,
2289 d3drm3_EnumerateObjects,
2290 d3drm3_Load,
2291 d3drm3_Tick,
2292 d3drm3_CreateProgressiveMesh,
2293 d3drm3_RegisterClient,
2294 d3drm3_UnregisterClient,
2295 d3drm3_CreateClippedVisual,
2296 d3drm3_SetOptions,
2297 d3drm3_GetOptions,
2298 };
2299
2300 HRESULT WINAPI Direct3DRMCreate(IDirect3DRM **d3drm)
2301 {
2302 struct d3drm *object;
2303
2304 TRACE("d3drm %p.\n", d3drm);
2305
2306 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
2307 return E_OUTOFMEMORY;
2308
2309 object->IDirect3DRM_iface.lpVtbl = &d3drm1_vtbl;
2310 object->IDirect3DRM2_iface.lpVtbl = &d3drm2_vtbl;
2311 object->IDirect3DRM3_iface.lpVtbl = &d3drm3_vtbl;
2312 object->ref1 = 1;
2313 object->iface_count = 1;
2314
2315 *d3drm = &object->IDirect3DRM_iface;
2316
2317 return S_OK;
2318 }
2319
2320 HRESULT WINAPI DllCanUnloadNow(void)
2321 {
2322 return S_FALSE;
2323 }
2324
2325 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
2326 {
2327 TRACE("(%s, %s, %p): stub\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
2328
2329 if(!ppv)
2330 return E_INVALIDARG;
2331
2332 return CLASS_E_CLASSNOTAVAILABLE;
2333 }