2 * Implementation of DirectX File Interfaces
4 * Copyright 2004, 2008 Christian Costa
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/debug.h"
29 #include "d3dxof_private.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(d3dxof);
36 #define MAKEFOUR(a,b,c,d) ((DWORD)a + ((DWORD)b << 8) + ((DWORD)c << 16) + ((DWORD)d << 24))
37 #define XOFFILE_FORMAT_MAGIC MAKEFOUR('x','o','f',' ')
38 #define XOFFILE_FORMAT_VERSION_302 MAKEFOUR('0','3','0','2')
39 #define XOFFILE_FORMAT_VERSION_303 MAKEFOUR('0','3','0','3')
40 #define XOFFILE_FORMAT_BINARY MAKEFOUR('b','i','n',' ')
41 #define XOFFILE_FORMAT_TEXT MAKEFOUR('t','x','t',' ')
42 #define XOFFILE_FORMAT_BINARY_MSZIP MAKEFOUR('b','z','i','p')
43 #define XOFFILE_FORMAT_TEXT_MSZIP MAKEFOUR('t','z','i','p')
44 #define XOFFILE_FORMAT_COMPRESSED MAKEFOUR('c','m','p',' ')
45 #define XOFFILE_FORMAT_FLOAT_BITS_32 MAKEFOUR('0','0','3','2')
46 #define XOFFILE_FORMAT_FLOAT_BITS_64 MAKEFOUR('0','0','6','4')
48 static const struct IDirectXFileVtbl IDirectXFile_Vtbl;
49 static const struct IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl;
50 static const struct IDirectXFileDataVtbl IDirectXFileData_Vtbl;
51 static const struct IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl;
52 static const struct IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl;
53 static const struct IDirectXFileObjectVtbl IDirectXFileObject_Vtbl;
54 static const struct IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl;
56 static HRESULT IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl** ppObj);
57 static HRESULT IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl** ppObj);
58 static HRESULT IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl** ppObj);
60 /* FOURCC to string conversion for debug messages */
61 const char *debugstr_fourcc(DWORD fourcc)
63 if (!fourcc) return "'null'";
64 return wine_dbg_sprintf ("\'%c%c%c%c\'",
65 (char)(fourcc), (char)(fourcc >> 8),
66 (char)(fourcc >> 16), (char)(fourcc >> 24));
69 HRESULT IDirectXFileImpl_Create(IUnknown* pUnkOuter, LPVOID* ppObj)
71 IDirectXFileImpl* object;
73 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
75 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileImpl));
78 ERR("Out of memory\n");
79 return DXFILEERR_BADALLOC;
82 object->lpVtbl = &IDirectXFile_Vtbl;
90 /*** IUnknown methods ***/
91 static HRESULT WINAPI IDirectXFileImpl_QueryInterface(IDirectXFile* iface, REFIID riid, void** ppvObject)
93 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
95 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
97 if (IsEqualGUID(riid, &IID_IUnknown)
98 || IsEqualGUID(riid, &IID_IDirectXFile))
100 IUnknown_AddRef(iface);
105 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
106 return E_NOINTERFACE;
109 static ULONG WINAPI IDirectXFileImpl_AddRef(IDirectXFile* iface)
111 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
112 ULONG ref = InterlockedIncrement(&This->ref);
114 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
119 static ULONG WINAPI IDirectXFileImpl_Release(IDirectXFile* iface)
121 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
122 ULONG ref = InterlockedDecrement(&This->ref);
124 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
127 HeapFree(GetProcessHeap(), 0, This);
132 /*** IDirectXFile methods ***/
133 static HRESULT WINAPI IDirectXFileImpl_CreateEnumObject(IDirectXFile* iface, LPVOID pvSource, DXFILELOADOPTIONS dwLoadOptions, LPDIRECTXFILEENUMOBJECT* ppEnumObj)
135 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
136 IDirectXFileEnumObjectImpl* object;
139 HANDLE hFile = INVALID_HANDLE_VALUE;
140 HANDLE file_mapping = 0;
141 LPBYTE buffer = NULL;
142 HGLOBAL resource_data = 0;
146 LPDXFILELOADMEMORY lpdxflm = NULL;
148 TRACE("(%p/%p)->(%p,%x,%p)\n", This, iface, pvSource, dwLoadOptions, ppEnumObj);
151 return DXFILEERR_BADVALUE;
153 /* Only lowest 4 bits are relevant in DXFILELOADOPTIONS */
154 dwLoadOptions &= 0xF;
156 if (dwLoadOptions == DXFILELOAD_FROMFILE)
158 TRACE("Open source file '%s'\n", (char*)pvSource);
160 hFile = CreateFileA(pvSource, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
161 if (hFile == INVALID_HANDLE_VALUE)
163 TRACE("File '%s' not found\n", (char*)pvSource);
164 return DXFILEERR_FILENOTFOUND;
167 file_size = GetFileSize(hFile, NULL);
169 file_mapping = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
172 hr = DXFILEERR_BADFILETYPE;
176 buffer = MapViewOfFile(file_mapping, FILE_MAP_READ, 0, 0, 0);
179 hr = DXFILEERR_BADFILETYPE;
182 file_buffer = buffer;
184 else if (dwLoadOptions == DXFILELOAD_FROMRESOURCE)
187 LPDXFILELOADRESOURCE lpdxflr = pvSource;
189 TRACE("Source in resource (module = %p, name = %s, type = %s\n", lpdxflr->hModule, debugstr_a(lpdxflr->lpName), debugstr_a(lpdxflr->lpType));
191 resource_info = FindResourceA(lpdxflr->hModule, lpdxflr->lpName, lpdxflr->lpType);
194 hr = DXFILEERR_RESOURCENOTFOUND;
198 file_size = SizeofResource(lpdxflr->hModule, resource_info);
200 resource_data = LoadResource(lpdxflr->hModule, resource_info);
203 hr = DXFILEERR_BADRESOURCE;
207 file_buffer = LockResource(resource_data);
210 hr = DXFILEERR_BADRESOURCE;
214 else if (dwLoadOptions == DXFILELOAD_FROMMEMORY)
218 TRACE("Source in memory at %p with size %d\n", lpdxflm->lpMemory, lpdxflm->dSize);
220 file_buffer = lpdxflm->lpMemory;
221 file_size = lpdxflm->dSize;
225 FIXME("Source type %d is not handled yet\n", dwLoadOptions);
226 hr = DXFILEERR_NOTDONEYET;
230 header = (DWORD*)file_buffer;
232 if (TRACE_ON(d3dxof))
235 memcpy(string, header, 16);
237 TRACE("header = '%s'\n", string);
242 hr = DXFILEERR_BADFILETYPE;
246 if (header[0] != XOFFILE_FORMAT_MAGIC)
248 hr = DXFILEERR_BADFILETYPE;
252 if ((header[1] != XOFFILE_FORMAT_VERSION_302) && (header[1] != XOFFILE_FORMAT_VERSION_303))
254 hr = DXFILEERR_BADFILEVERSION;
258 if ((header[2] != XOFFILE_FORMAT_BINARY) && (header[2] != XOFFILE_FORMAT_TEXT) &&
259 (header[2] != XOFFILE_FORMAT_BINARY_MSZIP) && (header[2] != XOFFILE_FORMAT_TEXT_MSZIP))
261 WARN("File type %s unknown\n", debugstr_fourcc(header[2]));
262 hr = DXFILEERR_BADFILETYPE;
266 if ((header[2] == XOFFILE_FORMAT_BINARY_MSZIP) || (header[2] == XOFFILE_FORMAT_TEXT_MSZIP))
268 FIXME("Compressed format %s not supported yet\n", debugstr_fourcc(header[2]));
269 hr = DXFILEERR_BADALLOC;
273 if ((header[3] != XOFFILE_FORMAT_FLOAT_BITS_32) && (header[3] != XOFFILE_FORMAT_FLOAT_BITS_64))
275 hr = DXFILEERR_BADFILEFLOATSIZE;
279 TRACE("Header is correct\n");
281 hr = IDirectXFileEnumObjectImpl_Create(&object);
285 object->source = dwLoadOptions;
286 object->hFile = hFile;
287 object->file_mapping = file_mapping;
288 object->buffer = buffer;
289 object->pDirectXFile = This;
290 object->buf.pdxf = This;
291 object->buf.txt = (header[2] == XOFFILE_FORMAT_TEXT);
292 object->buf.token_present = FALSE;
294 TRACE("File size is %d bytes\n", file_size);
296 /* Go to data after header */
297 object->buf.buffer = file_buffer + 16;
298 object->buf.rem_bytes = file_size - 16;
300 *ppEnumObj = (LPDIRECTXFILEENUMOBJECT)object;
302 while (object->buf.rem_bytes && is_template_available(&object->buf))
304 if (!parse_template(&object->buf))
306 WARN("Template is not correct\n");
307 hr = DXFILEERR_BADVALUE;
312 TRACE("Template successfully parsed:\n");
313 if (TRACE_ON(d3dxof))
314 dump_template(This->xtemplates, &This->xtemplates[This->nb_xtemplates - 1]);
318 if (TRACE_ON(d3dxof))
321 TRACE("Registered templates (%d):\n", This->nb_xtemplates);
322 for (i = 0; i < This->nb_xtemplates; i++)
323 DPRINTF("%s - %s\n", This->xtemplates[i].name, debugstr_guid(&This->xtemplates[i].class_id));
330 UnmapViewOfFile(buffer);
332 CloseHandle(file_mapping);
333 if (hFile != INVALID_HANDLE_VALUE)
336 FreeResource(resource_data);
342 static HRESULT WINAPI IDirectXFileImpl_CreateSaveObject(IDirectXFile* iface, LPCSTR szFileName, DXFILEFORMAT dwFileFormat, LPDIRECTXFILESAVEOBJECT* ppSaveObj)
344 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
346 FIXME("(%p/%p)->(%s,%x,%p) partial stub!\n", This, iface, szFileName, dwFileFormat, ppSaveObj);
348 if (!szFileName || !ppSaveObj)
351 return IDirectXFileSaveObjectImpl_Create((IDirectXFileSaveObjectImpl**)ppSaveObj);
354 static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LPVOID pvData, DWORD cbSize)
356 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
361 buf.rem_bytes = cbSize;
363 buf.token_present = FALSE;
366 TRACE("(%p/%p)->(%p,%d)\n", This, iface, pvData, cbSize);
369 return DXFILEERR_BADVALUE;
372 return DXFILEERR_BADFILETYPE;
374 if (TRACE_ON(d3dxof))
377 memcpy(string, pvData, 16);
379 TRACE("header = '%s'\n", string);
382 read_bytes(&buf, &token_header, 4);
384 if (token_header != XOFFILE_FORMAT_MAGIC)
385 return DXFILEERR_BADFILETYPE;
387 read_bytes(&buf, &token_header, 4);
389 if ((token_header != XOFFILE_FORMAT_VERSION_302) && (token_header != XOFFILE_FORMAT_VERSION_303))
390 return DXFILEERR_BADFILEVERSION;
392 read_bytes(&buf, &token_header, 4);
394 if ((token_header != XOFFILE_FORMAT_BINARY) && (token_header != XOFFILE_FORMAT_TEXT) &&
395 (token_header != XOFFILE_FORMAT_BINARY_MSZIP) && (token_header != XOFFILE_FORMAT_TEXT_MSZIP))
397 WARN("File type %s unknown\n", debugstr_fourcc(token_header));
398 return DXFILEERR_BADFILETYPE;
401 if ((token_header == XOFFILE_FORMAT_BINARY_MSZIP) || (token_header == XOFFILE_FORMAT_TEXT_MSZIP))
403 FIXME("Compressed format %s not supported yet\n", debugstr_fourcc(token_header));
404 return DXFILEERR_BADALLOC;
407 if (token_header == XOFFILE_FORMAT_TEXT)
410 read_bytes(&buf, &token_header, 4);
412 if ((token_header != XOFFILE_FORMAT_FLOAT_BITS_32) && (token_header != XOFFILE_FORMAT_FLOAT_BITS_64))
413 return DXFILEERR_BADFILEFLOATSIZE;
415 TRACE("Header is correct\n");
417 while (buf.rem_bytes)
419 if (!parse_template(&buf))
421 WARN("Template is not correct\n");
422 return DXFILEERR_BADVALUE;
426 TRACE("Template successfully parsed:\n");
427 if (TRACE_ON(d3dxof))
428 dump_template(This->xtemplates, &This->xtemplates[This->nb_xtemplates - 1]);
432 if (TRACE_ON(d3dxof))
435 TRACE("Registered templates (%d):\n", This->nb_xtemplates);
436 for (i = 0; i < This->nb_xtemplates; i++)
437 DPRINTF("%s - %s\n", This->xtemplates[i].name, debugstr_guid(&This->xtemplates[i].class_id));
443 static const IDirectXFileVtbl IDirectXFile_Vtbl =
445 IDirectXFileImpl_QueryInterface,
446 IDirectXFileImpl_AddRef,
447 IDirectXFileImpl_Release,
448 IDirectXFileImpl_CreateEnumObject,
449 IDirectXFileImpl_CreateSaveObject,
450 IDirectXFileImpl_RegisterTemplates
453 static HRESULT IDirectXFileBinaryImpl_Create(IDirectXFileBinaryImpl** ppObj)
455 IDirectXFileBinaryImpl* object;
457 TRACE("(%p)\n", ppObj);
459 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileBinaryImpl));
462 ERR("Out of memory\n");
463 return DXFILEERR_BADALLOC;
466 object->lpVtbl = &IDirectXFileBinary_Vtbl;
474 /*** IUnknown methods ***/
475 static HRESULT WINAPI IDirectXFileBinaryImpl_QueryInterface(IDirectXFileBinary* iface, REFIID riid, void** ppvObject)
477 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
479 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
481 if (IsEqualGUID(riid, &IID_IUnknown)
482 || IsEqualGUID(riid, &IID_IDirectXFileObject)
483 || IsEqualGUID(riid, &IID_IDirectXFileBinary))
485 IUnknown_AddRef(iface);
490 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
491 if (!IsEqualGUID(riid, &IID_IDirectXFileData)
492 && !IsEqualGUID(riid, &IID_IDirectXFileDataReference))
493 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
495 return E_NOINTERFACE;
498 static ULONG WINAPI IDirectXFileBinaryImpl_AddRef(IDirectXFileBinary* iface)
500 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
501 ULONG ref = InterlockedIncrement(&This->ref);
503 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
508 static ULONG WINAPI IDirectXFileBinaryImpl_Release(IDirectXFileBinary* iface)
510 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
511 ULONG ref = InterlockedDecrement(&This->ref);
513 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
516 HeapFree(GetProcessHeap(), 0, This);
521 /*** IDirectXFileObject methods ***/
522 static HRESULT WINAPI IDirectXFileBinaryImpl_GetName(IDirectXFileBinary* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen)
525 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
527 FIXME("(%p/%p)->(%p,%p) stub!\n", This, iface, pstrNameBuf, pdwBufLen);
529 return DXFILEERR_BADVALUE;
532 static HRESULT WINAPI IDirectXFileBinaryImpl_GetId(IDirectXFileBinary* iface, LPGUID pGuid)
534 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
536 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pGuid);
538 return DXFILEERR_BADVALUE;
541 /*** IDirectXFileBinary methods ***/
542 static HRESULT WINAPI IDirectXFileBinaryImpl_GetSize(IDirectXFileBinary* iface, DWORD* pcbSize)
544 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
546 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pcbSize);
548 return DXFILEERR_BADVALUE;
551 static HRESULT WINAPI IDirectXFileBinaryImpl_GetMimeType(IDirectXFileBinary* iface, LPCSTR* pszMimeType)
553 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
555 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pszMimeType);
557 return DXFILEERR_BADVALUE;
560 static HRESULT WINAPI IDirectXFileBinaryImpl_Read(IDirectXFileBinary* iface, LPVOID pvData, DWORD cbSize, LPDWORD pcbRead)
562 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
564 FIXME("(%p/%p)->(%p, %d, %p) stub!\n", This, iface, pvData, cbSize, pcbRead);
566 return DXFILEERR_BADVALUE;
569 static const IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl =
571 IDirectXFileBinaryImpl_QueryInterface,
572 IDirectXFileBinaryImpl_AddRef,
573 IDirectXFileBinaryImpl_Release,
574 IDirectXFileBinaryImpl_GetName,
575 IDirectXFileBinaryImpl_GetId,
576 IDirectXFileBinaryImpl_GetSize,
577 IDirectXFileBinaryImpl_GetMimeType,
578 IDirectXFileBinaryImpl_Read
581 static HRESULT IDirectXFileDataImpl_Create(IDirectXFileDataImpl** ppObj)
583 IDirectXFileDataImpl* object;
585 TRACE("(%p)\n", ppObj);
587 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileDataImpl));
590 ERR("Out of memory\n");
591 return DXFILEERR_BADALLOC;
594 object->lpVtbl = &IDirectXFileData_Vtbl;
602 /*** IUnknown methods ***/
603 static HRESULT WINAPI IDirectXFileDataImpl_QueryInterface(IDirectXFileData* iface, REFIID riid, void** ppvObject)
605 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
607 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
609 if (IsEqualGUID(riid, &IID_IUnknown)
610 || IsEqualGUID(riid, &IID_IDirectXFileObject)
611 || IsEqualGUID(riid, &IID_IDirectXFileData))
613 IUnknown_AddRef(iface);
618 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
619 if (!IsEqualGUID(riid, &IID_IDirectXFileBinary)
620 && !IsEqualGUID(riid, &IID_IDirectXFileDataReference))
621 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
623 return E_NOINTERFACE;
626 static ULONG WINAPI IDirectXFileDataImpl_AddRef(IDirectXFileData* iface)
628 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
629 ULONG ref = InterlockedIncrement(&This->ref);
631 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
636 static ULONG WINAPI IDirectXFileDataImpl_Release(IDirectXFileData* iface)
638 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
639 ULONG ref = InterlockedDecrement(&This->ref);
641 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
645 if (!This->level && !This->from_ref)
647 HeapFree(GetProcessHeap(), 0, This->pstrings);
648 HeapFree(GetProcessHeap(), 0, This->pobj->pdata);
649 HeapFree(GetProcessHeap(), 0, This->pobj);
651 HeapFree(GetProcessHeap(), 0, This);
657 /*** IDirectXFileObject methods ***/
658 static HRESULT WINAPI IDirectXFileDataImpl_GetName(IDirectXFileData* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen)
661 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
663 TRACE("(%p/%p)->(%p,%p)\n", This, iface, pstrNameBuf, pdwBufLen);
666 return DXFILEERR_BADVALUE;
668 strcpy(pstrNameBuf, This->pobj->name);
673 static HRESULT WINAPI IDirectXFileDataImpl_GetId(IDirectXFileData* iface, LPGUID pGuid)
675 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
677 TRACE("(%p/%p)->(%p)\n", This, iface, pGuid);
680 return DXFILEERR_BADVALUE;
682 memcpy(pGuid, &This->pobj->class_id, 16);
687 /*** IDirectXFileData methods ***/
688 static HRESULT WINAPI IDirectXFileDataImpl_GetData(IDirectXFileData* iface, LPCSTR szMember, DWORD* pcbSize, void** ppvData)
690 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
692 TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, szMember, pcbSize, ppvData);
694 if (!pcbSize || !ppvData)
695 return DXFILEERR_BADVALUE;
699 FIXME("Specifying a member is not supported yet!\n");
700 return DXFILEERR_BADVALUE;
703 *pcbSize = This->pobj->size;
704 *ppvData = This->pobj->root->pdata + This->pobj->pos_data;
709 static HRESULT WINAPI IDirectXFileDataImpl_GetType(IDirectXFileData* iface, const GUID** pguid)
711 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
714 TRACE("(%p/%p)->(%p)\n", This, iface, pguid);
717 return DXFILEERR_BADVALUE;
719 memcpy(&guid, &This->pobj->type, 16);
725 static HRESULT WINAPI IDirectXFileDataImpl_GetNextObject(IDirectXFileData* iface, LPDIRECTXFILEOBJECT* ppChildObj)
728 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
730 TRACE("(%p/%p)->(%p)\n", This, iface, ppChildObj);
732 if (This->cur_enum_object >= This->pobj->nb_childs)
733 return DXFILEERR_NOMOREOBJECTS;
735 if (This->from_ref && (This->level >= 1))
737 /* Only 2 levels can be enumerated if the object is obtained from a reference */
738 return DXFILEERR_NOMOREOBJECTS;
741 if (This->pobj->childs[This->cur_enum_object]->binary)
743 IDirectXFileBinaryImpl *object;
745 hr = IDirectXFileBinaryImpl_Create(&object);
749 *ppChildObj = (LPDIRECTXFILEOBJECT)object;
751 else if (This->pobj->childs[This->cur_enum_object]->ptarget)
753 IDirectXFileDataReferenceImpl *object;
755 hr = IDirectXFileDataReferenceImpl_Create(&object);
759 object->ptarget = This->pobj->childs[This->cur_enum_object++]->ptarget;
761 *ppChildObj = (LPDIRECTXFILEOBJECT)object;
765 IDirectXFileDataImpl *object;
767 hr = IDirectXFileDataImpl_Create(&object);
771 object->pobj = This->pobj->childs[This->cur_enum_object++];
772 object->cur_enum_object = 0;
773 object->from_ref = This->from_ref;
774 object->level = This->level + 1;
776 *ppChildObj = (LPDIRECTXFILEOBJECT)object;
782 static HRESULT WINAPI IDirectXFileDataImpl_AddDataObject(IDirectXFileData* iface, LPDIRECTXFILEDATA pDataObj)
784 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
786 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pDataObj);
788 return DXFILEERR_BADVALUE;
791 static HRESULT WINAPI IDirectXFileDataImpl_AddDataReference(IDirectXFileData* iface, LPCSTR szRef, const GUID* pguidRef)
793 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
795 FIXME("(%p/%p)->(%s,%p) stub!\n", This, iface, szRef, pguidRef);
797 return DXFILEERR_BADVALUE;
800 static HRESULT WINAPI IDirectXFileDataImpl_AddBinaryObject(IDirectXFileData* iface, LPCSTR szName, const GUID* pguid, LPCSTR szMimeType, LPVOID pvData, DWORD cbSize)
802 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
804 FIXME("(%p/%p)->(%s,%p,%s,%p,%d) stub!\n", This, iface, szName, pguid, szMimeType, pvData, cbSize);
806 return DXFILEERR_BADVALUE;
809 static const IDirectXFileDataVtbl IDirectXFileData_Vtbl =
811 IDirectXFileDataImpl_QueryInterface,
812 IDirectXFileDataImpl_AddRef,
813 IDirectXFileDataImpl_Release,
814 IDirectXFileDataImpl_GetName,
815 IDirectXFileDataImpl_GetId,
816 IDirectXFileDataImpl_GetData,
817 IDirectXFileDataImpl_GetType,
818 IDirectXFileDataImpl_GetNextObject,
819 IDirectXFileDataImpl_AddDataObject,
820 IDirectXFileDataImpl_AddDataReference,
821 IDirectXFileDataImpl_AddBinaryObject
824 static HRESULT IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl** ppObj)
826 IDirectXFileDataReferenceImpl* object;
828 TRACE("(%p)\n", ppObj);
830 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileDataReferenceImpl));
833 ERR("Out of memory\n");
834 return DXFILEERR_BADALLOC;
837 object->lpVtbl = &IDirectXFileDataReference_Vtbl;
845 /*** IUnknown methods ***/
846 static HRESULT WINAPI IDirectXFileDataReferenceImpl_QueryInterface(IDirectXFileDataReference* iface, REFIID riid, void** ppvObject)
848 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
850 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
852 if (IsEqualGUID(riid, &IID_IUnknown)
853 || IsEqualGUID(riid, &IID_IDirectXFileObject)
854 || IsEqualGUID(riid, &IID_IDirectXFileDataReference))
856 IUnknown_AddRef(iface);
861 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
862 if (!IsEqualGUID(riid, &IID_IDirectXFileData)
863 && !IsEqualGUID(riid, &IID_IDirectXFileBinary))
864 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
866 return E_NOINTERFACE;
869 static ULONG WINAPI IDirectXFileDataReferenceImpl_AddRef(IDirectXFileDataReference* iface)
871 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
872 ULONG ref = InterlockedIncrement(&This->ref);
874 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
879 static ULONG WINAPI IDirectXFileDataReferenceImpl_Release(IDirectXFileDataReference* iface)
881 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
882 ULONG ref = InterlockedDecrement(&This->ref);
884 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
887 HeapFree(GetProcessHeap(), 0, This);
892 /*** IDirectXFileObject methods ***/
893 static HRESULT WINAPI IDirectXFileDataReferenceImpl_GetName(IDirectXFileDataReference* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen)
895 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
897 TRACE("(%p/%p)->(%p,%p)\n", This, iface, pstrNameBuf, pdwBufLen);
900 return DXFILEERR_BADVALUE;
902 strcpy(pstrNameBuf, This->ptarget->name);
904 return DXFILEERR_BADVALUE;
907 static HRESULT WINAPI IDirectXFileDataReferenceImpl_GetId(IDirectXFileDataReference* iface, LPGUID pGuid)
909 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
911 TRACE("(%p/%p)->(%p)\n", This, iface, pGuid);
914 return DXFILEERR_BADVALUE;
916 memcpy(pGuid, &This->ptarget->class_id, 16);
921 /*** IDirectXFileDataReference ***/
922 static HRESULT WINAPI IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference* iface, LPDIRECTXFILEDATA* ppDataObj)
924 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
925 IDirectXFileDataImpl *object;
928 TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj);
931 return DXFILEERR_BADVALUE;
933 hr = IDirectXFileDataImpl_Create(&object);
937 object->pobj = This->ptarget;
938 object->cur_enum_object = 0;
940 object->from_ref = TRUE;
942 *ppDataObj = (LPDIRECTXFILEDATA)object;
947 static const IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl =
949 IDirectXFileDataReferenceImpl_QueryInterface,
950 IDirectXFileDataReferenceImpl_AddRef,
951 IDirectXFileDataReferenceImpl_Release,
952 IDirectXFileDataReferenceImpl_GetName,
953 IDirectXFileDataReferenceImpl_GetId,
954 IDirectXFileDataReferenceImpl_Resolve
957 static HRESULT IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl** ppObj)
959 IDirectXFileEnumObjectImpl* object;
961 TRACE("(%p)\n", ppObj);
963 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileEnumObjectImpl));
966 ERR("Out of memory\n");
967 return DXFILEERR_BADALLOC;
970 object->lpVtbl = &IDirectXFileEnumObject_Vtbl;
978 /*** IUnknown methods ***/
979 static HRESULT WINAPI IDirectXFileEnumObjectImpl_QueryInterface(IDirectXFileEnumObject* iface, REFIID riid, void** ppvObject)
981 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
983 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
985 if (IsEqualGUID(riid, &IID_IUnknown)
986 || IsEqualGUID(riid, &IID_IDirectXFileEnumObject))
988 IUnknown_AddRef(iface);
993 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
994 return E_NOINTERFACE;
997 static ULONG WINAPI IDirectXFileEnumObjectImpl_AddRef(IDirectXFileEnumObject* iface)
999 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1000 ULONG ref = InterlockedIncrement(&This->ref);
1002 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
1007 static ULONG WINAPI IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject* iface)
1009 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1010 ULONG ref = InterlockedDecrement(&This->ref);
1012 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
1017 for (i = 0; i < This->nb_xobjects; i++)
1018 IDirectXFileData_Release(This->pRefObjects[i]);
1019 if (This->source == DXFILELOAD_FROMFILE)
1021 UnmapViewOfFile(This->buffer);
1022 CloseHandle(This->file_mapping);
1023 CloseHandle(This->hFile);
1025 else if (This->source == DXFILELOAD_FROMRESOURCE)
1026 FreeResource(This->resource_data);
1027 HeapFree(GetProcessHeap(), 0, This);
1033 /*** IDirectXFileEnumObject methods ***/
1034 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject* iface, LPDIRECTXFILEDATA* ppDataObj)
1036 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1037 IDirectXFileDataImpl* object;
1039 LPBYTE pstrings = NULL;
1041 TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj);
1043 if (This->nb_xobjects >= MAX_OBJECTS)
1045 ERR("Too many objects\n");
1046 return DXFILEERR_NOMOREOBJECTS;
1049 /* Check if there are templates defined before the object */
1050 while (This->buf.rem_bytes && is_template_available(&This->buf))
1052 if (!parse_template(&This->buf))
1054 WARN("Template is not correct\n");
1055 hr = DXFILEERR_BADVALUE;
1060 TRACE("Template successfully parsed:\n");
1061 if (TRACE_ON(d3dxof))
1062 dump_template(This->pDirectXFile->xtemplates, &This->pDirectXFile->xtemplates[This->pDirectXFile->nb_xtemplates - 1]);
1066 if (!This->buf.rem_bytes)
1067 return DXFILEERR_NOMOREOBJECTS;
1069 hr = IDirectXFileDataImpl_Create(&object);
1073 This->buf.pxo_globals = This->xobjects;
1074 This->buf.nb_pxo_globals = This->nb_xobjects;
1075 This->buf.level = 0;
1077 This->buf.pxo_tab = HeapAlloc(GetProcessHeap(), 0, sizeof(xobject)*MAX_SUBOBJECTS);
1078 if (!This->buf.pxo_tab)
1080 ERR("Out of memory\n");
1081 hr = DXFILEERR_BADALLOC;
1084 This->buf.pxo = This->xobjects[This->nb_xobjects] = This->buf.pxo_tab;
1086 This->buf.pxo->pdata = This->buf.pdata = NULL;
1087 This->buf.capacity = 0;
1088 This->buf.cur_pos_data = 0;
1089 This->buf.pxo->nb_subobjects = 1;
1091 pstrings = HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER);
1094 ERR("Out of memory\n");
1095 hr = DXFILEERR_BADALLOC;
1098 This->buf.cur_pstrings = This->buf.pstrings = object->pstrings = pstrings;
1100 if (!parse_object(&This->buf))
1102 WARN("Object is not correct\n");
1103 hr = DXFILEERR_PARSEERROR;
1107 if (This->buf.pxo->nb_subobjects > MAX_SUBOBJECTS)
1109 FIXME("Too many subobjects %d\n", This->buf.pxo->nb_subobjects);
1110 hr = DXFILEERR_BADALLOC;
1114 object->pstrings = pstrings;
1115 object->pobj = This->buf.pxo;
1116 object->cur_enum_object = 0;
1118 object->from_ref = FALSE;
1120 *ppDataObj = (LPDIRECTXFILEDATA)object;
1122 /* Get a reference to created object */
1123 This->pRefObjects[This->nb_xobjects] = (LPDIRECTXFILEDATA)object;
1124 IDirectXFileData_AddRef(This->pRefObjects[This->nb_xobjects]);
1126 This->nb_xobjects++;
1132 HeapFree(GetProcessHeap(), 0, This->buf.pxo_tab);
1133 HeapFree(GetProcessHeap(), 0, This->buf.pdata);
1134 HeapFree(GetProcessHeap(), 0, pstrings);
1139 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetDataObjectById(IDirectXFileEnumObject* iface, REFGUID rguid, LPDIRECTXFILEDATA* ppDataObj)
1141 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1143 FIXME("(%p/%p)->(%p,%p) stub!\n", This, iface, rguid, ppDataObj);
1145 return DXFILEERR_BADVALUE;
1148 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetDataObjectByName(IDirectXFileEnumObject* iface, LPCSTR szName, LPDIRECTXFILEDATA* ppDataObj)
1150 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1152 FIXME("(%p/%p)->(%s,%p) stub!\n", This, iface, szName, ppDataObj);
1154 return DXFILEERR_BADVALUE;
1157 static const IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl =
1159 IDirectXFileEnumObjectImpl_QueryInterface,
1160 IDirectXFileEnumObjectImpl_AddRef,
1161 IDirectXFileEnumObjectImpl_Release,
1162 IDirectXFileEnumObjectImpl_GetNextDataObject,
1163 IDirectXFileEnumObjectImpl_GetDataObjectById,
1164 IDirectXFileEnumObjectImpl_GetDataObjectByName
1167 static HRESULT IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl** ppObj)
1169 IDirectXFileSaveObjectImpl* object;
1171 TRACE("(%p)\n", ppObj);
1173 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileSaveObjectImpl));
1176 ERR("Out of memory\n");
1177 return DXFILEERR_BADALLOC;
1180 object->lpVtbl = &IDirectXFileSaveObject_Vtbl;
1188 /*** IUnknown methods ***/
1189 static HRESULT WINAPI IDirectXFileSaveObjectImpl_QueryInterface(IDirectXFileSaveObject* iface, REFIID riid, void** ppvObject)
1191 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1193 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
1195 if (IsEqualGUID(riid, &IID_IUnknown)
1196 || IsEqualGUID(riid, &IID_IDirectXFileSaveObject))
1198 IUnknown_AddRef(iface);
1203 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
1204 return E_NOINTERFACE;
1207 static ULONG WINAPI IDirectXFileSaveObjectImpl_AddRef(IDirectXFileSaveObject* iface)
1209 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1210 ULONG ref = InterlockedIncrement(&This->ref);
1212 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
1217 static ULONG WINAPI IDirectXFileSaveObjectImpl_Release(IDirectXFileSaveObject* iface)
1219 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1220 ULONG ref = InterlockedDecrement(&This->ref);
1222 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
1225 HeapFree(GetProcessHeap(), 0, This);
1230 static HRESULT WINAPI IDirectXFileSaveObjectImpl_SaveTemplates(IDirectXFileSaveObject* iface, DWORD cTemplates, const GUID** ppguidTemplates)
1232 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1234 FIXME("(%p/%p)->(%d,%p) stub!\n", This, iface, cTemplates, ppguidTemplates);
1236 return DXFILEERR_BADVALUE;
1239 static HRESULT WINAPI IDirectXFileSaveObjectImpl_CreateDataObject(IDirectXFileSaveObject* iface, REFGUID rguidTemplate, LPCSTR szName, const GUID* pguid, DWORD cbSize, LPVOID pvData, LPDIRECTXFILEDATA* ppDataObj)
1241 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1243 FIXME("(%p/%p)->(%p,%s,%p,%d,%p,%p) stub!\n", This, iface, rguidTemplate, szName, pguid, cbSize, pvData, ppDataObj);
1245 return DXFILEERR_BADVALUE;
1248 static HRESULT WINAPI IDirectXFileSaveObjectImpl_SaveData(IDirectXFileSaveObject* iface, LPDIRECTXFILEDATA ppDataObj)
1250 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1252 FIXME("(%p/%p)->(%p) stub!\n", This, iface, ppDataObj);
1254 return DXFILEERR_BADVALUE;
1257 static const IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl =
1259 IDirectXFileSaveObjectImpl_QueryInterface,
1260 IDirectXFileSaveObjectImpl_AddRef,
1261 IDirectXFileSaveObjectImpl_Release,
1262 IDirectXFileSaveObjectImpl_SaveTemplates,
1263 IDirectXFileSaveObjectImpl_CreateDataObject,
1264 IDirectXFileSaveObjectImpl_SaveData