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