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 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 77 static inline struct d3dx9_file *impl_from_ID3DXFile(ID3DXFile *iface) 78 { 79 return CONTAINING_RECORD(iface, struct d3dx9_file, ID3DXFile_iface); 80 } 81 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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