* Sync up to trunk HEAD (r62502).
[reactos.git] / dll / directx / wine / d3dx9_36 / xfile.c
1 /*
2 * Copyright (C) 2012 Christian Costa
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 *
18 */
19
20 #include "d3dx9_36_private.h"
21
22 #include "d3dx9xof.h"
23 #undef MAKE_DDHRESULT
24 #include "dxfile.h"
25
26 static HRESULT error_dxfile_to_d3dxfile(HRESULT error)
27 {
28 switch (error)
29 {
30 case DXFILEERR_BADFILETYPE:
31 return D3DXFERR_BADFILETYPE;
32 case DXFILEERR_BADFILEVERSION:
33 return D3DXFERR_BADFILEVERSION;
34 case DXFILEERR_BADFILEFLOATSIZE:
35 return D3DXFERR_BADFILEFLOATSIZE;
36 case DXFILEERR_PARSEERROR:
37 return D3DXFERR_PARSEERROR;
38 case DXFILEERR_BADVALUE:
39 return D3DXFERR_BADVALUE;
40 default:
41 FIXME("Cannot map error %#x\n", error);
42 return E_FAIL;
43 }
44 }
45
46 typedef struct {
47 ID3DXFile ID3DXFile_iface;
48 LONG ref;
49 IDirectXFile *dxfile;
50 } ID3DXFileImpl;
51
52 typedef struct {
53 ID3DXFileEnumObject ID3DXFileEnumObject_iface;
54 LONG ref;
55 ULONG nb_children;
56 ID3DXFileData **children;
57 } ID3DXFileEnumObjectImpl;
58
59 typedef struct {
60 ID3DXFileData ID3DXFileData_iface;
61 LONG ref;
62 BOOL reference;
63 IDirectXFileData *dxfile_data;
64 ULONG nb_children;
65 ID3DXFileData **children;
66 } ID3DXFileDataImpl;
67
68
69 static inline ID3DXFileImpl* impl_from_ID3DXFile(ID3DXFile *iface)
70 {
71 return CONTAINING_RECORD(iface, ID3DXFileImpl, ID3DXFile_iface);
72 }
73
74 static inline ID3DXFileEnumObjectImpl* impl_from_ID3DXFileEnumObject(ID3DXFileEnumObject *iface)
75 {
76 return CONTAINING_RECORD(iface, ID3DXFileEnumObjectImpl, ID3DXFileEnumObject_iface);
77 }
78
79 static inline ID3DXFileDataImpl* impl_from_ID3DXFileData(ID3DXFileData *iface)
80 {
81 return CONTAINING_RECORD(iface, ID3DXFileDataImpl, ID3DXFileData_iface);
82 }
83
84 /*** IUnknown methods ***/
85
86 static HRESULT WINAPI ID3DXFileDataImpl_QueryInterface(ID3DXFileData *iface, REFIID riid, void **ret_iface)
87 {
88 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ret_iface);
89
90 if (IsEqualGUID(riid, &IID_IUnknown) ||
91 IsEqualGUID(riid, &IID_ID3DXFileData))
92 {
93 iface->lpVtbl->AddRef(iface);
94 *ret_iface = iface;
95 return S_OK;
96 }
97
98 WARN("(%p)->(%s, %p), not found\n", iface, debugstr_guid(riid), ret_iface);
99 *ret_iface = NULL;
100 return E_NOINTERFACE;
101 }
102
103 static ULONG WINAPI ID3DXFileDataImpl_AddRef(ID3DXFileData *iface)
104 {
105 ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface);
106 ULONG ref = InterlockedIncrement(&This->ref);
107
108 TRACE("(%p)->(): new ref = %u\n", iface, ref);
109
110 return ref;
111 }
112
113 static ULONG WINAPI ID3DXFileDataImpl_Release(ID3DXFileData *iface)
114 {
115 ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface);
116 ULONG ref = InterlockedDecrement(&This->ref);
117
118 TRACE("(%p)->(): new ref = %u\n", iface, ref);
119
120 if (!ref)
121 {
122 ULONG i;
123
124 for (i = 0; i < This->nb_children; i++)
125 (This->children[i])->lpVtbl->Release(This->children[i]);
126 HeapFree(GetProcessHeap(), 0, This->children);
127 IDirectXFileData_Release(This->dxfile_data);
128 HeapFree(GetProcessHeap(), 0, This);
129 }
130
131 return ref;
132 }
133
134
135 /*** ID3DXFileData methods ***/
136
137 static HRESULT WINAPI ID3DXFileDataImpl_GetEnum(ID3DXFileData *iface, ID3DXFileEnumObject **enum_object)
138 {
139 FIXME("(%p)->(%p): stub\n", iface, enum_object);
140
141 return E_NOTIMPL;
142 }
143
144
145 static HRESULT WINAPI ID3DXFileDataImpl_GetName(ID3DXFileData *iface, char *name, SIZE_T *size)
146 {
147 ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface);
148 DWORD dxfile_size;
149 HRESULT ret;
150
151 TRACE("(%p)->(%p, %p)\n", iface, name, size);
152
153 if (!size)
154 return D3DXFERR_BADVALUE;
155
156 dxfile_size = *size;
157
158 ret = IDirectXFileData_GetName(This->dxfile_data, name, &dxfile_size);
159 if (ret != DXFILE_OK)
160 return error_dxfile_to_d3dxfile(ret);
161
162 if (!dxfile_size)
163 {
164 /* Contrary to d3dxof, d3dx9_36 returns an empty string with a null byte when no name is available.
165 * If the input size is 0, it returns a length of 1 without touching the buffer */
166 dxfile_size = 1;
167 if (name && *size)
168 name[0] = 0;
169 }
170
171 *size = dxfile_size;
172
173 return S_OK;
174 }
175
176
177 static HRESULT WINAPI ID3DXFileDataImpl_GetId(ID3DXFileData *iface, GUID *guid)
178 {
179 ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface);
180 HRESULT ret;
181
182 TRACE("(%p)->(%p)\n", iface, guid);
183
184 if (!guid)
185 return E_POINTER;
186
187 ret = IDirectXFileData_GetId(This->dxfile_data, guid);
188 if (ret != DXFILE_OK)
189 return error_dxfile_to_d3dxfile(ret);
190
191 return S_OK;
192 }
193
194
195 static HRESULT WINAPI ID3DXFileDataImpl_Lock(ID3DXFileData *iface, SIZE_T *size, const void **data)
196 {
197 ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface);
198 DWORD dxfile_size;
199 HRESULT ret;
200
201 TRACE("(%p)->(%p, %p)\n", iface, size, data);
202
203 if (!size || !data)
204 return E_POINTER;
205
206 ret = IDirectXFileData_GetData(This->dxfile_data, NULL, &dxfile_size, (void**)data);
207 if (ret != DXFILE_OK)
208 return error_dxfile_to_d3dxfile(ret);
209
210 *size = dxfile_size;
211
212 return S_OK;
213 }
214
215
216 static HRESULT WINAPI ID3DXFileDataImpl_Unlock(ID3DXFileData *iface)
217 {
218 TRACE("(%p)->()\n", iface);
219
220 /* Nothing to do */
221
222 return S_OK;
223 }
224
225
226 static HRESULT WINAPI ID3DXFileDataImpl_GetType(ID3DXFileData *iface, GUID *guid)
227 {
228 ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface);
229 const GUID *dxfile_guid;
230 HRESULT ret;
231
232 TRACE("(%p)->(%p)\n", iface, guid);
233
234 ret = IDirectXFileData_GetType(This->dxfile_data, &dxfile_guid);
235 if (ret != DXFILE_OK)
236 return error_dxfile_to_d3dxfile(ret);
237
238 *guid = *dxfile_guid;
239
240 return S_OK;
241 }
242
243
244 static BOOL WINAPI ID3DXFileDataImpl_IsReference(ID3DXFileData *iface)
245 {
246 ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface);
247
248 TRACE("(%p)->()\n", iface);
249
250 return This->reference;
251 }
252
253
254 static HRESULT WINAPI ID3DXFileDataImpl_GetChildren(ID3DXFileData *iface, SIZE_T *children)
255 {
256 ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface);
257
258 TRACE("(%p)->(%p)\n", iface, children);
259
260 if (!children)
261 return E_POINTER;
262
263 *children = This->nb_children;
264
265 return S_OK;
266 }
267
268
269 static HRESULT WINAPI ID3DXFileDataImpl_GetChild(ID3DXFileData *iface, SIZE_T id, ID3DXFileData **object)
270 {
271 ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface);
272
273 TRACE("(%p)->(%lu, %p)\n", iface, id, object);
274
275 if (!object)
276 return E_POINTER;
277
278 *object = This->children[id];
279 (*object)->lpVtbl->AddRef(*object);
280
281 return S_OK;
282 }
283
284
285 static const ID3DXFileDataVtbl ID3DXFileData_Vtbl =
286 {
287 ID3DXFileDataImpl_QueryInterface,
288 ID3DXFileDataImpl_AddRef,
289 ID3DXFileDataImpl_Release,
290 ID3DXFileDataImpl_GetEnum,
291 ID3DXFileDataImpl_GetName,
292 ID3DXFileDataImpl_GetId,
293 ID3DXFileDataImpl_Lock,
294 ID3DXFileDataImpl_Unlock,
295 ID3DXFileDataImpl_GetType,
296 ID3DXFileDataImpl_IsReference,
297 ID3DXFileDataImpl_GetChildren,
298 ID3DXFileDataImpl_GetChild
299 };
300
301
302 static HRESULT ID3DXFileDataImpl_Create(IDirectXFileObject *dxfile_object, ID3DXFileData **ret_iface)
303 {
304 ID3DXFileDataImpl *object;
305 IDirectXFileObject *data_object;
306 HRESULT ret;
307
308 TRACE("(%p, %p)\n", dxfile_object, ret_iface);
309
310 *ret_iface = NULL;
311
312 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
313 if (!object)
314 return E_OUTOFMEMORY;
315
316 object->ID3DXFileData_iface.lpVtbl = &ID3DXFileData_Vtbl;
317 object->ref = 1;
318
319 ret = IDirectXFileObject_QueryInterface(dxfile_object, &IID_IDirectXFileData, (void **)&object->dxfile_data);
320 if (FAILED(ret))
321 {
322 IDirectXFileDataReference *reference;
323
324 ret = IDirectXFileObject_QueryInterface(dxfile_object, &IID_IDirectXFileDataReference, (void **)&reference);
325 if (SUCCEEDED(ret))
326 {
327 ret = IDirectXFileDataReference_Resolve(reference, &object->dxfile_data);
328 if (FAILED(ret))
329 {
330 HeapFree(GetProcessHeap(), 0, object);
331 return E_FAIL;
332 }
333 object->reference = TRUE;
334 }
335 else
336 {
337 FIXME("Don't known what to do with binary object\n");
338 HeapFree(GetProcessHeap(), 0, object);
339 return E_FAIL;
340 }
341 }
342
343 while (SUCCEEDED(ret = IDirectXFileData_GetNextObject(object->dxfile_data, &data_object)))
344 {
345 if (object->children)
346 object->children = HeapReAlloc(GetProcessHeap(), 0, object->children, sizeof(ID3DXFileData*) * (object->nb_children + 1));
347 else
348 object->children = HeapAlloc(GetProcessHeap(), 0, sizeof(ID3DXFileData*));
349 if (!object->children)
350 {
351 ret = E_OUTOFMEMORY;
352 break;
353 }
354 ret = ID3DXFileDataImpl_Create(data_object, &object->children[object->nb_children]);
355 if (ret != S_OK)
356 break;
357 object->nb_children++;
358 }
359
360 if (ret != DXFILEERR_NOMOREOBJECTS)
361 {
362 (&object->ID3DXFileData_iface)->lpVtbl->Release(&object->ID3DXFileData_iface);
363 return ret;
364 }
365
366 TRACE("Found %u children\n", object->nb_children);
367
368 *ret_iface = &object->ID3DXFileData_iface;
369
370 return S_OK;
371 }
372
373
374 /*** IUnknown methods ***/
375
376 static HRESULT WINAPI ID3DXFileEnumObjectImpl_QueryInterface(ID3DXFileEnumObject *iface, REFIID riid, void **ret_iface)
377 {
378 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ret_iface);
379
380 if (IsEqualGUID(riid, &IID_IUnknown) ||
381 IsEqualGUID(riid, &IID_ID3DXFileEnumObject))
382 {
383 iface->lpVtbl->AddRef(iface);
384 *ret_iface = iface;
385 return S_OK;
386 }
387
388 WARN("(%p)->(%s, %p), not found\n", iface, debugstr_guid(riid), ret_iface);
389 *ret_iface = NULL;
390 return E_NOINTERFACE;
391 }
392
393 static ULONG WINAPI ID3DXFileEnumObjectImpl_AddRef(ID3DXFileEnumObject *iface)
394 {
395 ID3DXFileEnumObjectImpl *This = impl_from_ID3DXFileEnumObject(iface);
396 ULONG ref = InterlockedIncrement(&This->ref);
397
398 TRACE("(%p)->(): new ref = %u\n", iface, ref);
399
400 return ref;
401 }
402
403 static ULONG WINAPI ID3DXFileEnumObjectImpl_Release(ID3DXFileEnumObject *iface)
404 {
405 ID3DXFileEnumObjectImpl *This = impl_from_ID3DXFileEnumObject(iface);
406 ULONG ref = InterlockedDecrement(&This->ref);
407
408 TRACE("(%p)->(): new ref = %u\n", iface, ref);
409
410 if (!ref)
411 {
412 ULONG i;
413
414 for (i = 0; i < This->nb_children; i++)
415 (This->children[i])->lpVtbl->Release(This->children[i]);
416 HeapFree(GetProcessHeap(), 0, This->children);
417 HeapFree(GetProcessHeap(), 0, This);
418 }
419
420 return ref;
421 }
422
423
424 /*** ID3DXFileEnumObject methods ***/
425
426 static HRESULT WINAPI ID3DXFileEnumObjectImpl_GetFile(ID3DXFileEnumObject *iface, ID3DXFile **file)
427 {
428 FIXME("(%p)->(%p): stub\n", iface, file);
429
430 return E_NOTIMPL;
431 }
432
433
434 static HRESULT WINAPI ID3DXFileEnumObjectImpl_GetChildren(ID3DXFileEnumObject *iface, SIZE_T *children)
435 {
436 ID3DXFileEnumObjectImpl *This = impl_from_ID3DXFileEnumObject(iface);
437
438 TRACE("(%p)->(%p)\n", iface, children);
439
440 if (!children)
441 return E_POINTER;
442
443 *children = This->nb_children;
444
445 return S_OK;
446 }
447
448
449 static HRESULT WINAPI ID3DXFileEnumObjectImpl_GetChild(ID3DXFileEnumObject *iface, SIZE_T id, ID3DXFileData **object)
450 {
451 ID3DXFileEnumObjectImpl *This = impl_from_ID3DXFileEnumObject(iface);
452
453 TRACE("(%p)->(%lu, %p)\n", iface, id, object);
454
455 if (!object)
456 return E_POINTER;
457
458 *object = This->children[id];
459 (*object)->lpVtbl->AddRef(*object);
460
461 return S_OK;
462 }
463
464
465 static HRESULT WINAPI ID3DXFileEnumObjectImpl_GetDataObjectById(ID3DXFileEnumObject *iface, REFGUID guid, ID3DXFileData **object)
466 {
467 FIXME("(%p)->(%s, %p): stub\n", iface, debugstr_guid(guid), object);
468
469 return E_NOTIMPL;
470 }
471
472
473 static HRESULT WINAPI ID3DXFileEnumObjectImpl_GetDataObjectByName(ID3DXFileEnumObject *iface, const char *name, ID3DXFileData **object)
474 {
475 FIXME("(%p)->(%s, %p): stub\n", iface, debugstr_a(name), object);
476
477 return E_NOTIMPL;
478 }
479
480
481 static const ID3DXFileEnumObjectVtbl ID3DXFileEnumObject_Vtbl =
482 {
483 ID3DXFileEnumObjectImpl_QueryInterface,
484 ID3DXFileEnumObjectImpl_AddRef,
485 ID3DXFileEnumObjectImpl_Release,
486 ID3DXFileEnumObjectImpl_GetFile,
487 ID3DXFileEnumObjectImpl_GetChildren,
488 ID3DXFileEnumObjectImpl_GetChild,
489 ID3DXFileEnumObjectImpl_GetDataObjectById,
490 ID3DXFileEnumObjectImpl_GetDataObjectByName
491 };
492
493
494 /*** IUnknown methods ***/
495
496 static HRESULT WINAPI ID3DXFileImpl_QueryInterface(ID3DXFile *iface, REFIID riid, void **ret_iface)
497 {
498 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ret_iface);
499
500 if (IsEqualGUID(riid, &IID_IUnknown) ||
501 IsEqualGUID(riid, &IID_ID3DXFile))
502 {
503 iface->lpVtbl->AddRef(iface);
504 *ret_iface = iface;
505 return S_OK;
506 }
507
508 WARN("(%p)->(%s, %p), not found\n", iface, debugstr_guid(riid), ret_iface);
509 *ret_iface = NULL;
510 return E_NOINTERFACE;
511 }
512
513
514 static ULONG WINAPI ID3DXFileImpl_AddRef(ID3DXFile *iface)
515 {
516 ID3DXFileImpl *This = impl_from_ID3DXFile(iface);
517 ULONG ref = InterlockedIncrement(&This->ref);
518
519 TRACE("(%p)->(): new ref = %u\n", iface, ref);
520
521 return ref;
522 }
523
524
525 static ULONG WINAPI ID3DXFileImpl_Release(ID3DXFile *iface)
526 {
527 ID3DXFileImpl *This = impl_from_ID3DXFile(iface);
528 ULONG ref = InterlockedDecrement(&This->ref);
529
530 TRACE("(%p)->(): new ref = %u\n", iface, ref);
531
532 if (!ref)
533 {
534 IDirectXFile_Release(This->dxfile);
535 HeapFree(GetProcessHeap(), 0, This);
536 }
537
538 return ref;
539 }
540
541
542 /*** ID3DXFile methods ***/
543
544 static HRESULT WINAPI ID3DXFileImpl_CreateEnumObject(ID3DXFile *iface, const void *source, D3DXF_FILELOADOPTIONS options, ID3DXFileEnumObject **enum_object)
545 {
546 ID3DXFileImpl *This = impl_from_ID3DXFile(iface);
547 ID3DXFileEnumObjectImpl *object;
548 IDirectXFileEnumObject *dxfile_enum_object;
549 void *dxfile_source;
550 DXFILELOADOPTIONS dxfile_options;
551 DXFILELOADRESOURCE dxfile_resource;
552 DXFILELOADMEMORY dxfile_memory;
553 IDirectXFileData *data_object;
554 HRESULT ret;
555
556 TRACE("(%p)->(%p, %x, %p)\n", iface, source, options, enum_object);
557
558 if (!enum_object)
559 return E_POINTER;
560
561 *enum_object = NULL;
562
563 if (options == D3DXF_FILELOAD_FROMFILE)
564 {
565 dxfile_source = (void*)source;
566 dxfile_options = DXFILELOAD_FROMFILE;
567 }
568 else if (options == D3DXF_FILELOAD_FROMRESOURCE)
569 {
570 D3DXF_FILELOADRESOURCE *resource = (D3DXF_FILELOADRESOURCE*)source;
571
572 dxfile_resource.hModule = resource->hModule;
573 dxfile_resource.lpName = resource->lpName;
574 dxfile_resource.lpType = resource->lpType;
575 dxfile_source = &dxfile_resource;
576 dxfile_options = DXFILELOAD_FROMRESOURCE;
577 }
578 else if (options == D3DXF_FILELOAD_FROMMEMORY)
579 {
580 D3DXF_FILELOADMEMORY *memory = (D3DXF_FILELOADMEMORY*)source;
581
582 dxfile_memory.lpMemory = memory->lpMemory;
583 dxfile_memory.dSize = memory->dSize;
584 dxfile_source = &dxfile_memory;
585 dxfile_options = DXFILELOAD_FROMMEMORY;
586 }
587 else
588 {
589 FIXME("Source type %u is not handled yet\n", options);
590 return E_NOTIMPL;
591 }
592
593 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
594 if (!object)
595 return E_OUTOFMEMORY;
596
597 object->ID3DXFileEnumObject_iface.lpVtbl = &ID3DXFileEnumObject_Vtbl;
598 object->ref = 1;
599
600 ret = IDirectXFile_CreateEnumObject(This->dxfile, dxfile_source, dxfile_options, &dxfile_enum_object);
601
602 if (ret != S_OK)
603 {
604 HeapFree(GetProcessHeap(), 0, object);
605 return ret;
606 }
607
608 /* Fill enum object with top level data objects */
609 while (SUCCEEDED(ret = IDirectXFileEnumObject_GetNextDataObject(dxfile_enum_object, &data_object)))
610 {
611 if (object->children)
612 object->children = HeapReAlloc(GetProcessHeap(), 0, object->children, sizeof(*object->children) * (object->nb_children + 1));
613 else
614 object->children = HeapAlloc(GetProcessHeap(), 0, sizeof(*object->children));
615 if (!object->children)
616 {
617 ret = E_OUTOFMEMORY;
618 break;
619 }
620 ret = ID3DXFileDataImpl_Create((IDirectXFileObject*)data_object, &object->children[object->nb_children]);
621 if (ret != S_OK)
622 break;
623 object->nb_children++;
624 }
625
626 IDirectXFileEnumObject_Release(dxfile_enum_object);
627
628 if (ret != DXFILEERR_NOMOREOBJECTS)
629 WARN("Cannot get all top level data objects\n");
630
631 TRACE("Found %u children\n", object->nb_children);
632
633 *enum_object = &object->ID3DXFileEnumObject_iface;
634
635 return S_OK;
636 }
637
638
639 static HRESULT WINAPI ID3DXFileImpl_CreateSaveObject(ID3DXFile *iface, const void *data, D3DXF_FILESAVEOPTIONS options, D3DXF_FILEFORMAT format, ID3DXFileSaveObject **save_object)
640 {
641 FIXME("(%p)->(%p, %x, %u, %p): stub\n", iface, data, options, format, save_object);
642
643 return E_NOTIMPL;
644 }
645
646
647 static HRESULT WINAPI ID3DXFileImpl_RegisterTemplates(ID3DXFile *iface, const void *data, SIZE_T size)
648 {
649 ID3DXFileImpl *This = impl_from_ID3DXFile(iface);
650 HRESULT ret;
651
652 TRACE("(%p)->(%p, %lu)\n", iface, data, size);
653
654 ret = IDirectXFile_RegisterTemplates(This->dxfile, (void*)data, size);
655 if (ret != DXFILE_OK)
656 {
657 WARN("Error %#x\n", ret);
658 return error_dxfile_to_d3dxfile(ret);
659 }
660
661 return S_OK;
662 }
663
664
665 static HRESULT WINAPI ID3DXFileImpl_RegisterEnumTemplates(ID3DXFile *iface, ID3DXFileEnumObject *enum_object)
666 {
667 FIXME("(%p)->(%p): stub\n", iface, enum_object);
668
669 return E_NOTIMPL;
670 }
671
672
673 static const ID3DXFileVtbl ID3DXFile_Vtbl =
674 {
675 ID3DXFileImpl_QueryInterface,
676 ID3DXFileImpl_AddRef,
677 ID3DXFileImpl_Release,
678 ID3DXFileImpl_CreateEnumObject,
679 ID3DXFileImpl_CreateSaveObject,
680 ID3DXFileImpl_RegisterTemplates,
681 ID3DXFileImpl_RegisterEnumTemplates
682 };
683
684 HRESULT WINAPI D3DXFileCreate(ID3DXFile **d3dxfile)
685 {
686 ID3DXFileImpl *object;
687 HRESULT ret;
688
689 TRACE("(%p)\n", d3dxfile);
690
691 if (!d3dxfile)
692 return E_POINTER;
693
694 *d3dxfile = NULL;
695
696 object = HeapAlloc(GetProcessHeap(), 0, sizeof(*object));
697 if (!object)
698 return E_OUTOFMEMORY;
699
700 ret = DirectXFileCreate(&object->dxfile);
701 if (ret != S_OK)
702 {
703 HeapFree(GetProcessHeap(), 0, object);
704 if (ret == E_OUTOFMEMORY)
705 return ret;
706 return E_FAIL;
707 }
708
709 object->ID3DXFile_iface.lpVtbl = &ID3DXFile_Vtbl;
710 object->ref = 1;
711
712 *d3dxfile = &object->ID3DXFile_iface;
713
714 return S_OK;
715 }