2 * Implementation of DirectX File Interfaces
4 * Copyright 2004, 2008, 2010 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 static 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;
143 LPBYTE decomp_buffer = NULL;
144 DWORD decomp_size = 0;
148 LPDXFILELOADMEMORY lpdxflm = NULL;
150 TRACE("(%p/%p)->(%p,%x,%p)\n", This, iface, pvSource, dwLoadOptions, ppEnumObj);
153 return DXFILEERR_BADVALUE;
155 /* Only lowest 4 bits are relevant in DXFILELOADOPTIONS */
156 dwLoadOptions &= 0xF;
158 if (dwLoadOptions == DXFILELOAD_FROMFILE)
160 TRACE("Open source file '%s'\n", (char*)pvSource);
162 hFile = CreateFileA(pvSource, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
163 if (hFile == INVALID_HANDLE_VALUE)
165 TRACE("File '%s' not found\n", (char*)pvSource);
166 return DXFILEERR_FILENOTFOUND;
169 file_size = GetFileSize(hFile, NULL);
171 file_mapping = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
174 hr = DXFILEERR_BADFILETYPE;
178 buffer = MapViewOfFile(file_mapping, FILE_MAP_READ, 0, 0, 0);
181 hr = DXFILEERR_BADFILETYPE;
184 file_buffer = buffer;
186 else if (dwLoadOptions == DXFILELOAD_FROMRESOURCE)
189 LPDXFILELOADRESOURCE lpdxflr = pvSource;
191 TRACE("Source in resource (module = %p, name = %s, type = %s\n", lpdxflr->hModule, debugstr_a(lpdxflr->lpName), debugstr_a(lpdxflr->lpType));
193 resource_info = FindResourceA(lpdxflr->hModule, lpdxflr->lpName, lpdxflr->lpType);
196 hr = DXFILEERR_RESOURCENOTFOUND;
200 file_size = SizeofResource(lpdxflr->hModule, resource_info);
202 resource_data = LoadResource(lpdxflr->hModule, resource_info);
205 hr = DXFILEERR_BADRESOURCE;
209 file_buffer = LockResource(resource_data);
212 hr = DXFILEERR_BADRESOURCE;
216 else if (dwLoadOptions == DXFILELOAD_FROMMEMORY)
220 TRACE("Source in memory at %p with size %d\n", lpdxflm->lpMemory, lpdxflm->dSize);
222 file_buffer = lpdxflm->lpMemory;
223 file_size = lpdxflm->dSize;
227 FIXME("Source type %d is not handled yet\n", dwLoadOptions);
228 hr = DXFILEERR_NOTDONEYET;
232 header = (DWORD*)file_buffer;
234 if (TRACE_ON(d3dxof))
237 memcpy(string, header, 16);
239 TRACE("header = '%s'\n", string);
244 hr = DXFILEERR_BADFILETYPE;
248 if (header[0] != XOFFILE_FORMAT_MAGIC)
250 hr = DXFILEERR_BADFILETYPE;
254 if ((header[1] != XOFFILE_FORMAT_VERSION_302) && (header[1] != XOFFILE_FORMAT_VERSION_303))
256 hr = DXFILEERR_BADFILEVERSION;
260 if ((header[2] != XOFFILE_FORMAT_BINARY) && (header[2] != XOFFILE_FORMAT_TEXT) &&
261 (header[2] != XOFFILE_FORMAT_BINARY_MSZIP) && (header[2] != XOFFILE_FORMAT_TEXT_MSZIP))
263 WARN("File type %s unknown\n", debugstr_fourcc(header[2]));
264 hr = DXFILEERR_BADFILETYPE;
268 if ((header[2] == XOFFILE_FORMAT_BINARY_MSZIP) || (header[2] == XOFFILE_FORMAT_TEXT_MSZIP))
273 /* 0-15 -> xfile header, 16-17 -> decompressed size w/ header, 18-19 -> null,
274 20-21 -> decompressed size w/o header, 22-23 -> size of MSZIP compressed data,
275 24-xx -> compressed MSZIP data */
276 decomp_size = ((WORD*)file_buffer)[10];
277 comp_size = ((WORD*)file_buffer)[11];
279 TRACE("Compressed format %s detected: compressed_size = %x, decompressed_size = %x\n",
280 debugstr_fourcc(header[2]), comp_size, decomp_size);
282 decomp_buffer = HeapAlloc(GetProcessHeap(), 0, decomp_size);
285 ERR("Out of memory\n");
286 hr = DXFILEERR_BADALLOC;
289 err = mszip_decompress(comp_size, decomp_size, (char*)file_buffer + 24, (char*)decomp_buffer);
292 WARN("Error while decomrpessing mszip archive %d\n", err);
293 hr = DXFILEERR_BADALLOC;
298 if ((header[3] != XOFFILE_FORMAT_FLOAT_BITS_32) && (header[3] != XOFFILE_FORMAT_FLOAT_BITS_64))
300 hr = DXFILEERR_BADFILEFLOATSIZE;
304 TRACE("Header is correct\n");
306 hr = IDirectXFileEnumObjectImpl_Create(&object);
310 object->source = dwLoadOptions;
311 object->hFile = hFile;
312 object->file_mapping = file_mapping;
313 object->buffer = buffer;
314 object->decomp_buffer = decomp_buffer;
315 object->pDirectXFile = This;
316 object->buf.pdxf = This;
317 object->buf.txt = (header[2] == XOFFILE_FORMAT_TEXT) || (header[2] == XOFFILE_FORMAT_TEXT_MSZIP);
318 object->buf.token_present = FALSE;
320 TRACE("File size is %d bytes\n", file_size);
324 /* Use decompressed data */
325 object->buf.buffer = decomp_buffer;
326 object->buf.rem_bytes = decomp_size;
330 /* Go to data after header */
331 object->buf.buffer = file_buffer + 16;
332 object->buf.rem_bytes = file_size - 16;
335 *ppEnumObj = (LPDIRECTXFILEENUMOBJECT)object;
337 while (object->buf.rem_bytes && is_template_available(&object->buf))
339 if (!parse_template(&object->buf))
341 WARN("Template is not correct\n");
342 hr = DXFILEERR_BADVALUE;
347 TRACE("Template successfully parsed:\n");
348 if (TRACE_ON(d3dxof))
349 dump_template(This->xtemplates, &This->xtemplates[This->nb_xtemplates - 1]);
353 if (TRACE_ON(d3dxof))
356 TRACE("Registered templates (%d):\n", This->nb_xtemplates);
357 for (i = 0; i < This->nb_xtemplates; i++)
358 DPRINTF("%s - %s\n", This->xtemplates[i].name, debugstr_guid(&This->xtemplates[i].class_id));
365 UnmapViewOfFile(buffer);
367 CloseHandle(file_mapping);
368 if (hFile != INVALID_HANDLE_VALUE)
371 FreeResource(resource_data);
372 HeapFree(GetProcessHeap(), 0, decomp_buffer);
378 static HRESULT WINAPI IDirectXFileImpl_CreateSaveObject(IDirectXFile* iface, LPCSTR szFileName, DXFILEFORMAT dwFileFormat, LPDIRECTXFILESAVEOBJECT* ppSaveObj)
380 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
382 FIXME("(%p/%p)->(%s,%x,%p) partial stub!\n", This, iface, szFileName, dwFileFormat, ppSaveObj);
384 if (!szFileName || !ppSaveObj)
387 return IDirectXFileSaveObjectImpl_Create((IDirectXFileSaveObjectImpl**)ppSaveObj);
390 static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LPVOID pvData, DWORD cbSize)
392 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
395 LPBYTE decomp_buffer = NULL;
396 DWORD decomp_size = 0;
399 buf.rem_bytes = cbSize;
401 buf.token_present = FALSE;
404 TRACE("(%p/%p)->(%p,%d)\n", This, iface, pvData, cbSize);
407 return DXFILEERR_BADVALUE;
410 return DXFILEERR_BADFILETYPE;
412 if (TRACE_ON(d3dxof))
415 memcpy(string, pvData, 16);
417 TRACE("header = '%s'\n", string);
420 read_bytes(&buf, &token_header, 4);
422 if (token_header != XOFFILE_FORMAT_MAGIC)
423 return DXFILEERR_BADFILETYPE;
425 read_bytes(&buf, &token_header, 4);
427 if ((token_header != XOFFILE_FORMAT_VERSION_302) && (token_header != XOFFILE_FORMAT_VERSION_303))
428 return DXFILEERR_BADFILEVERSION;
430 read_bytes(&buf, &token_header, 4);
432 if ((token_header != XOFFILE_FORMAT_BINARY) && (token_header != XOFFILE_FORMAT_TEXT) &&
433 (token_header != XOFFILE_FORMAT_BINARY_MSZIP) && (token_header != XOFFILE_FORMAT_TEXT_MSZIP))
435 WARN("File type %s unknown\n", debugstr_fourcc(token_header));
436 return DXFILEERR_BADFILETYPE;
439 if ((token_header == XOFFILE_FORMAT_BINARY_MSZIP) || (token_header == XOFFILE_FORMAT_TEXT_MSZIP))
444 /* 0-15 -> xfile header, 16-17 -> decompressed size w/ header, 18-19 -> null,
445 20-21 -> decompressed size w/o header, 22-23 -> size of MSZIP compressed data,
446 24-xx -> compressed MSZIP data */
447 decomp_size = ((WORD*)pvData)[10];
448 comp_size = ((WORD*)pvData)[11];
450 TRACE("Compressed format %s detected: compressed_size = %x, decompressed_size = %x\n",
451 debugstr_fourcc(token_header), comp_size, decomp_size);
453 decomp_buffer = HeapAlloc(GetProcessHeap(), 0, decomp_size);
456 ERR("Out of memory\n");
457 return DXFILEERR_BADALLOC;
459 err = mszip_decompress(comp_size, decomp_size, (char*)pvData + 24, (char*)decomp_buffer);
462 WARN("Error while decomrpessing mszip archive %d\n", err);
463 HeapFree(GetProcessHeap(), 0, decomp_buffer);
464 return DXFILEERR_BADALLOC;
468 if ((token_header == XOFFILE_FORMAT_TEXT) || (token_header == XOFFILE_FORMAT_TEXT_MSZIP))
471 read_bytes(&buf, &token_header, 4);
473 if ((token_header != XOFFILE_FORMAT_FLOAT_BITS_32) && (token_header != XOFFILE_FORMAT_FLOAT_BITS_64))
474 return DXFILEERR_BADFILEFLOATSIZE;
476 TRACE("Header is correct\n");
480 buf.buffer = decomp_buffer;
481 buf.rem_bytes = decomp_size;
484 while (buf.rem_bytes && is_template_available(&buf))
486 if (!parse_template(&buf))
488 WARN("Template is not correct\n");
489 return DXFILEERR_BADVALUE;
493 TRACE("Template successfully parsed:\n");
494 if (TRACE_ON(d3dxof))
495 dump_template(This->xtemplates, &This->xtemplates[This->nb_xtemplates - 1]);
499 if (TRACE_ON(d3dxof))
502 TRACE("Registered templates (%d):\n", This->nb_xtemplates);
503 for (i = 0; i < This->nb_xtemplates; i++)
504 DPRINTF("%s - %s\n", This->xtemplates[i].name, debugstr_guid(&This->xtemplates[i].class_id));
507 HeapFree(GetProcessHeap(), 0, decomp_buffer);
512 static const IDirectXFileVtbl IDirectXFile_Vtbl =
514 IDirectXFileImpl_QueryInterface,
515 IDirectXFileImpl_AddRef,
516 IDirectXFileImpl_Release,
517 IDirectXFileImpl_CreateEnumObject,
518 IDirectXFileImpl_CreateSaveObject,
519 IDirectXFileImpl_RegisterTemplates
522 static HRESULT IDirectXFileBinaryImpl_Create(IDirectXFileBinaryImpl** ppObj)
524 IDirectXFileBinaryImpl* object;
526 TRACE("(%p)\n", ppObj);
528 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileBinaryImpl));
531 ERR("Out of memory\n");
532 return DXFILEERR_BADALLOC;
535 object->lpVtbl = &IDirectXFileBinary_Vtbl;
543 /*** IUnknown methods ***/
544 static HRESULT WINAPI IDirectXFileBinaryImpl_QueryInterface(IDirectXFileBinary* iface, REFIID riid, void** ppvObject)
546 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
548 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
550 if (IsEqualGUID(riid, &IID_IUnknown)
551 || IsEqualGUID(riid, &IID_IDirectXFileObject)
552 || IsEqualGUID(riid, &IID_IDirectXFileBinary))
554 IUnknown_AddRef(iface);
559 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
560 if (!IsEqualGUID(riid, &IID_IDirectXFileData)
561 && !IsEqualGUID(riid, &IID_IDirectXFileDataReference))
562 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
564 return E_NOINTERFACE;
567 static ULONG WINAPI IDirectXFileBinaryImpl_AddRef(IDirectXFileBinary* iface)
569 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
570 ULONG ref = InterlockedIncrement(&This->ref);
572 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
577 static ULONG WINAPI IDirectXFileBinaryImpl_Release(IDirectXFileBinary* iface)
579 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
580 ULONG ref = InterlockedDecrement(&This->ref);
582 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
585 HeapFree(GetProcessHeap(), 0, This);
590 /*** IDirectXFileObject methods ***/
591 static HRESULT WINAPI IDirectXFileBinaryImpl_GetName(IDirectXFileBinary* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen)
594 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
596 FIXME("(%p/%p)->(%p,%p) stub!\n", This, iface, pstrNameBuf, pdwBufLen);
598 return DXFILEERR_BADVALUE;
601 static HRESULT WINAPI IDirectXFileBinaryImpl_GetId(IDirectXFileBinary* iface, LPGUID pGuid)
603 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
605 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pGuid);
607 return DXFILEERR_BADVALUE;
610 /*** IDirectXFileBinary methods ***/
611 static HRESULT WINAPI IDirectXFileBinaryImpl_GetSize(IDirectXFileBinary* iface, DWORD* pcbSize)
613 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
615 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pcbSize);
617 return DXFILEERR_BADVALUE;
620 static HRESULT WINAPI IDirectXFileBinaryImpl_GetMimeType(IDirectXFileBinary* iface, LPCSTR* pszMimeType)
622 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
624 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pszMimeType);
626 return DXFILEERR_BADVALUE;
629 static HRESULT WINAPI IDirectXFileBinaryImpl_Read(IDirectXFileBinary* iface, LPVOID pvData, DWORD cbSize, LPDWORD pcbRead)
631 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
633 FIXME("(%p/%p)->(%p, %d, %p) stub!\n", This, iface, pvData, cbSize, pcbRead);
635 return DXFILEERR_BADVALUE;
638 static const IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl =
640 IDirectXFileBinaryImpl_QueryInterface,
641 IDirectXFileBinaryImpl_AddRef,
642 IDirectXFileBinaryImpl_Release,
643 IDirectXFileBinaryImpl_GetName,
644 IDirectXFileBinaryImpl_GetId,
645 IDirectXFileBinaryImpl_GetSize,
646 IDirectXFileBinaryImpl_GetMimeType,
647 IDirectXFileBinaryImpl_Read
650 static HRESULT IDirectXFileDataImpl_Create(IDirectXFileDataImpl** ppObj)
652 IDirectXFileDataImpl* object;
654 TRACE("(%p)\n", ppObj);
656 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileDataImpl));
659 ERR("Out of memory\n");
660 return DXFILEERR_BADALLOC;
663 object->lpVtbl = &IDirectXFileData_Vtbl;
671 /*** IUnknown methods ***/
672 static HRESULT WINAPI IDirectXFileDataImpl_QueryInterface(IDirectXFileData* iface, REFIID riid, void** ppvObject)
674 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
676 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
678 if (IsEqualGUID(riid, &IID_IUnknown)
679 || IsEqualGUID(riid, &IID_IDirectXFileObject)
680 || IsEqualGUID(riid, &IID_IDirectXFileData))
682 IUnknown_AddRef(iface);
687 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
688 if (!IsEqualGUID(riid, &IID_IDirectXFileBinary)
689 && !IsEqualGUID(riid, &IID_IDirectXFileDataReference))
690 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
692 return E_NOINTERFACE;
695 static ULONG WINAPI IDirectXFileDataImpl_AddRef(IDirectXFileData* iface)
697 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
698 ULONG ref = InterlockedIncrement(&This->ref);
700 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
705 static ULONG WINAPI IDirectXFileDataImpl_Release(IDirectXFileData* iface)
707 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
708 ULONG ref = InterlockedDecrement(&This->ref);
710 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
714 if (!This->level && !This->from_ref)
716 HeapFree(GetProcessHeap(), 0, This->pstrings);
717 HeapFree(GetProcessHeap(), 0, This->pobj->pdata);
718 HeapFree(GetProcessHeap(), 0, This->pobj);
720 HeapFree(GetProcessHeap(), 0, This);
726 /*** IDirectXFileObject methods ***/
727 static HRESULT WINAPI IDirectXFileDataImpl_GetName(IDirectXFileData* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen)
730 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
732 TRACE("(%p/%p)->(%p,%p)\n", This, iface, pstrNameBuf, pdwBufLen);
735 return DXFILEERR_BADVALUE;
737 strcpy(pstrNameBuf, This->pobj->name);
742 static HRESULT WINAPI IDirectXFileDataImpl_GetId(IDirectXFileData* iface, LPGUID pGuid)
744 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
746 TRACE("(%p/%p)->(%p)\n", This, iface, pGuid);
749 return DXFILEERR_BADVALUE;
751 memcpy(pGuid, &This->pobj->class_id, 16);
756 /*** IDirectXFileData methods ***/
757 static HRESULT WINAPI IDirectXFileDataImpl_GetData(IDirectXFileData* iface, LPCSTR szMember, DWORD* pcbSize, void** ppvData)
759 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
761 TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, szMember, pcbSize, ppvData);
763 if (!pcbSize || !ppvData)
764 return DXFILEERR_BADVALUE;
768 FIXME("Specifying a member is not supported yet!\n");
769 return DXFILEERR_BADVALUE;
772 *pcbSize = This->pobj->size;
773 *ppvData = This->pobj->root->pdata + This->pobj->pos_data;
778 static HRESULT WINAPI IDirectXFileDataImpl_GetType(IDirectXFileData* iface, const GUID** pguid)
780 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
783 TRACE("(%p/%p)->(%p)\n", This, iface, pguid);
786 return DXFILEERR_BADVALUE;
788 memcpy(&guid, &This->pobj->type, 16);
794 static HRESULT WINAPI IDirectXFileDataImpl_GetNextObject(IDirectXFileData* iface, LPDIRECTXFILEOBJECT* ppChildObj)
797 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
799 TRACE("(%p/%p)->(%p)\n", This, iface, ppChildObj);
801 if (This->cur_enum_object >= This->pobj->nb_childs)
802 return DXFILEERR_NOMOREOBJECTS;
804 if (This->from_ref && (This->level >= 1))
806 /* Only 2 levels can be enumerated if the object is obtained from a reference */
807 return DXFILEERR_NOMOREOBJECTS;
810 if (This->pobj->childs[This->cur_enum_object]->binary)
812 IDirectXFileBinaryImpl *object;
814 hr = IDirectXFileBinaryImpl_Create(&object);
818 *ppChildObj = (LPDIRECTXFILEOBJECT)object;
820 else if (This->pobj->childs[This->cur_enum_object]->ptarget)
822 IDirectXFileDataReferenceImpl *object;
824 hr = IDirectXFileDataReferenceImpl_Create(&object);
828 object->ptarget = This->pobj->childs[This->cur_enum_object++]->ptarget;
830 *ppChildObj = (LPDIRECTXFILEOBJECT)object;
834 IDirectXFileDataImpl *object;
836 hr = IDirectXFileDataImpl_Create(&object);
840 object->pobj = This->pobj->childs[This->cur_enum_object++];
841 object->cur_enum_object = 0;
842 object->from_ref = This->from_ref;
843 object->level = This->level + 1;
845 *ppChildObj = (LPDIRECTXFILEOBJECT)object;
851 static HRESULT WINAPI IDirectXFileDataImpl_AddDataObject(IDirectXFileData* iface, LPDIRECTXFILEDATA pDataObj)
853 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
855 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pDataObj);
857 return DXFILEERR_BADVALUE;
860 static HRESULT WINAPI IDirectXFileDataImpl_AddDataReference(IDirectXFileData* iface, LPCSTR szRef, const GUID* pguidRef)
862 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
864 FIXME("(%p/%p)->(%s,%p) stub!\n", This, iface, szRef, pguidRef);
866 return DXFILEERR_BADVALUE;
869 static HRESULT WINAPI IDirectXFileDataImpl_AddBinaryObject(IDirectXFileData* iface, LPCSTR szName, const GUID* pguid, LPCSTR szMimeType, LPVOID pvData, DWORD cbSize)
871 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
873 FIXME("(%p/%p)->(%s,%p,%s,%p,%d) stub!\n", This, iface, szName, pguid, szMimeType, pvData, cbSize);
875 return DXFILEERR_BADVALUE;
878 static const IDirectXFileDataVtbl IDirectXFileData_Vtbl =
880 IDirectXFileDataImpl_QueryInterface,
881 IDirectXFileDataImpl_AddRef,
882 IDirectXFileDataImpl_Release,
883 IDirectXFileDataImpl_GetName,
884 IDirectXFileDataImpl_GetId,
885 IDirectXFileDataImpl_GetData,
886 IDirectXFileDataImpl_GetType,
887 IDirectXFileDataImpl_GetNextObject,
888 IDirectXFileDataImpl_AddDataObject,
889 IDirectXFileDataImpl_AddDataReference,
890 IDirectXFileDataImpl_AddBinaryObject
893 static HRESULT IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl** ppObj)
895 IDirectXFileDataReferenceImpl* object;
897 TRACE("(%p)\n", ppObj);
899 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileDataReferenceImpl));
902 ERR("Out of memory\n");
903 return DXFILEERR_BADALLOC;
906 object->lpVtbl = &IDirectXFileDataReference_Vtbl;
914 /*** IUnknown methods ***/
915 static HRESULT WINAPI IDirectXFileDataReferenceImpl_QueryInterface(IDirectXFileDataReference* iface, REFIID riid, void** ppvObject)
917 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
919 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
921 if (IsEqualGUID(riid, &IID_IUnknown)
922 || IsEqualGUID(riid, &IID_IDirectXFileObject)
923 || IsEqualGUID(riid, &IID_IDirectXFileDataReference))
925 IUnknown_AddRef(iface);
930 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
931 if (!IsEqualGUID(riid, &IID_IDirectXFileData)
932 && !IsEqualGUID(riid, &IID_IDirectXFileBinary))
933 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
935 return E_NOINTERFACE;
938 static ULONG WINAPI IDirectXFileDataReferenceImpl_AddRef(IDirectXFileDataReference* iface)
940 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
941 ULONG ref = InterlockedIncrement(&This->ref);
943 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
948 static ULONG WINAPI IDirectXFileDataReferenceImpl_Release(IDirectXFileDataReference* iface)
950 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
951 ULONG ref = InterlockedDecrement(&This->ref);
953 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
956 HeapFree(GetProcessHeap(), 0, This);
961 /*** IDirectXFileObject methods ***/
962 static HRESULT WINAPI IDirectXFileDataReferenceImpl_GetName(IDirectXFileDataReference* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen)
964 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
966 TRACE("(%p/%p)->(%p,%p)\n", This, iface, pstrNameBuf, pdwBufLen);
969 return DXFILEERR_BADVALUE;
971 strcpy(pstrNameBuf, This->ptarget->name);
973 return DXFILEERR_BADVALUE;
976 static HRESULT WINAPI IDirectXFileDataReferenceImpl_GetId(IDirectXFileDataReference* iface, LPGUID pGuid)
978 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
980 TRACE("(%p/%p)->(%p)\n", This, iface, pGuid);
983 return DXFILEERR_BADVALUE;
985 memcpy(pGuid, &This->ptarget->class_id, 16);
990 /*** IDirectXFileDataReference ***/
991 static HRESULT WINAPI IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference* iface, LPDIRECTXFILEDATA* ppDataObj)
993 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
994 IDirectXFileDataImpl *object;
997 TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj);
1000 return DXFILEERR_BADVALUE;
1002 hr = IDirectXFileDataImpl_Create(&object);
1006 object->pobj = This->ptarget;
1007 object->cur_enum_object = 0;
1009 object->from_ref = TRUE;
1011 *ppDataObj = (LPDIRECTXFILEDATA)object;
1016 static const IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl =
1018 IDirectXFileDataReferenceImpl_QueryInterface,
1019 IDirectXFileDataReferenceImpl_AddRef,
1020 IDirectXFileDataReferenceImpl_Release,
1021 IDirectXFileDataReferenceImpl_GetName,
1022 IDirectXFileDataReferenceImpl_GetId,
1023 IDirectXFileDataReferenceImpl_Resolve
1026 static HRESULT IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl** ppObj)
1028 IDirectXFileEnumObjectImpl* object;
1030 TRACE("(%p)\n", ppObj);
1032 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileEnumObjectImpl));
1035 ERR("Out of memory\n");
1036 return DXFILEERR_BADALLOC;
1039 object->lpVtbl = &IDirectXFileEnumObject_Vtbl;
1047 /*** IUnknown methods ***/
1048 static HRESULT WINAPI IDirectXFileEnumObjectImpl_QueryInterface(IDirectXFileEnumObject* iface, REFIID riid, void** ppvObject)
1050 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1052 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
1054 if (IsEqualGUID(riid, &IID_IUnknown)
1055 || IsEqualGUID(riid, &IID_IDirectXFileEnumObject))
1057 IUnknown_AddRef(iface);
1062 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
1063 return E_NOINTERFACE;
1066 static ULONG WINAPI IDirectXFileEnumObjectImpl_AddRef(IDirectXFileEnumObject* iface)
1068 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1069 ULONG ref = InterlockedIncrement(&This->ref);
1071 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
1076 static ULONG WINAPI IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject* iface)
1078 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1079 ULONG ref = InterlockedDecrement(&This->ref);
1081 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
1086 for (i = 0; i < This->nb_xobjects; i++)
1087 IDirectXFileData_Release(This->pRefObjects[i]);
1088 if (This->source == DXFILELOAD_FROMFILE)
1090 UnmapViewOfFile(This->buffer);
1091 CloseHandle(This->file_mapping);
1092 CloseHandle(This->hFile);
1094 else if (This->source == DXFILELOAD_FROMRESOURCE)
1095 FreeResource(This->resource_data);
1096 HeapFree(GetProcessHeap(), 0, This->decomp_buffer);
1097 HeapFree(GetProcessHeap(), 0, This);
1103 /*** IDirectXFileEnumObject methods ***/
1104 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject* iface, LPDIRECTXFILEDATA* ppDataObj)
1106 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1107 IDirectXFileDataImpl* object;
1109 LPBYTE pstrings = NULL;
1111 TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj);
1113 if (This->nb_xobjects >= MAX_OBJECTS)
1115 ERR("Too many objects\n");
1116 return DXFILEERR_NOMOREOBJECTS;
1119 /* Check if there are templates defined before the object */
1120 while (This->buf.rem_bytes && is_template_available(&This->buf))
1122 if (!parse_template(&This->buf))
1124 WARN("Template is not correct\n");
1125 hr = DXFILEERR_BADVALUE;
1130 TRACE("Template successfully parsed:\n");
1131 if (TRACE_ON(d3dxof))
1132 dump_template(This->pDirectXFile->xtemplates, &This->pDirectXFile->xtemplates[This->pDirectXFile->nb_xtemplates - 1]);
1136 if (!This->buf.rem_bytes)
1137 return DXFILEERR_NOMOREOBJECTS;
1139 hr = IDirectXFileDataImpl_Create(&object);
1143 This->buf.pxo_globals = This->xobjects;
1144 This->buf.nb_pxo_globals = This->nb_xobjects;
1145 This->buf.level = 0;
1147 This->buf.pxo_tab = HeapAlloc(GetProcessHeap(), 0, sizeof(xobject)*MAX_SUBOBJECTS);
1148 if (!This->buf.pxo_tab)
1150 ERR("Out of memory\n");
1151 hr = DXFILEERR_BADALLOC;
1154 This->buf.pxo = This->xobjects[This->nb_xobjects] = This->buf.pxo_tab;
1156 This->buf.pxo->pdata = This->buf.pdata = NULL;
1157 This->buf.capacity = 0;
1158 This->buf.cur_pos_data = 0;
1159 This->buf.pxo->nb_subobjects = 1;
1161 pstrings = HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER);
1164 ERR("Out of memory\n");
1165 hr = DXFILEERR_BADALLOC;
1168 This->buf.cur_pstrings = This->buf.pstrings = object->pstrings = pstrings;
1170 if (!parse_object(&This->buf))
1172 WARN("Object is not correct\n");
1173 hr = DXFILEERR_PARSEERROR;
1177 object->pstrings = pstrings;
1178 object->pobj = This->buf.pxo;
1179 object->cur_enum_object = 0;
1181 object->from_ref = FALSE;
1183 *ppDataObj = (LPDIRECTXFILEDATA)object;
1185 /* Get a reference to created object */
1186 This->pRefObjects[This->nb_xobjects] = (LPDIRECTXFILEDATA)object;
1187 IDirectXFileData_AddRef(This->pRefObjects[This->nb_xobjects]);
1189 This->nb_xobjects++;
1195 HeapFree(GetProcessHeap(), 0, This->buf.pxo_tab);
1196 HeapFree(GetProcessHeap(), 0, This->buf.pdata);
1197 HeapFree(GetProcessHeap(), 0, pstrings);
1202 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetDataObjectById(IDirectXFileEnumObject* iface, REFGUID rguid, LPDIRECTXFILEDATA* ppDataObj)
1204 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1206 FIXME("(%p/%p)->(%p,%p) stub!\n", This, iface, rguid, ppDataObj);
1208 return DXFILEERR_BADVALUE;
1211 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetDataObjectByName(IDirectXFileEnumObject* iface, LPCSTR szName, LPDIRECTXFILEDATA* ppDataObj)
1213 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1215 FIXME("(%p/%p)->(%s,%p) stub!\n", This, iface, szName, ppDataObj);
1217 return DXFILEERR_BADVALUE;
1220 static const IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl =
1222 IDirectXFileEnumObjectImpl_QueryInterface,
1223 IDirectXFileEnumObjectImpl_AddRef,
1224 IDirectXFileEnumObjectImpl_Release,
1225 IDirectXFileEnumObjectImpl_GetNextDataObject,
1226 IDirectXFileEnumObjectImpl_GetDataObjectById,
1227 IDirectXFileEnumObjectImpl_GetDataObjectByName
1230 static HRESULT IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl** ppObj)
1232 IDirectXFileSaveObjectImpl* object;
1234 TRACE("(%p)\n", ppObj);
1236 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileSaveObjectImpl));
1239 ERR("Out of memory\n");
1240 return DXFILEERR_BADALLOC;
1243 object->lpVtbl = &IDirectXFileSaveObject_Vtbl;
1251 /*** IUnknown methods ***/
1252 static HRESULT WINAPI IDirectXFileSaveObjectImpl_QueryInterface(IDirectXFileSaveObject* iface, REFIID riid, void** ppvObject)
1254 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1256 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
1258 if (IsEqualGUID(riid, &IID_IUnknown)
1259 || IsEqualGUID(riid, &IID_IDirectXFileSaveObject))
1261 IUnknown_AddRef(iface);
1266 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
1267 return E_NOINTERFACE;
1270 static ULONG WINAPI IDirectXFileSaveObjectImpl_AddRef(IDirectXFileSaveObject* iface)
1272 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1273 ULONG ref = InterlockedIncrement(&This->ref);
1275 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
1280 static ULONG WINAPI IDirectXFileSaveObjectImpl_Release(IDirectXFileSaveObject* iface)
1282 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1283 ULONG ref = InterlockedDecrement(&This->ref);
1285 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
1288 HeapFree(GetProcessHeap(), 0, This);
1293 static HRESULT WINAPI IDirectXFileSaveObjectImpl_SaveTemplates(IDirectXFileSaveObject* iface, DWORD cTemplates, const GUID** ppguidTemplates)
1295 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1297 FIXME("(%p/%p)->(%d,%p) stub!\n", This, iface, cTemplates, ppguidTemplates);
1299 return DXFILEERR_BADVALUE;
1302 static HRESULT WINAPI IDirectXFileSaveObjectImpl_CreateDataObject(IDirectXFileSaveObject* iface, REFGUID rguidTemplate, LPCSTR szName, const GUID* pguid, DWORD cbSize, LPVOID pvData, LPDIRECTXFILEDATA* ppDataObj)
1304 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1306 FIXME("(%p/%p)->(%p,%s,%p,%d,%p,%p) stub!\n", This, iface, rguidTemplate, szName, pguid, cbSize, pvData, ppDataObj);
1308 return DXFILEERR_BADVALUE;
1311 static HRESULT WINAPI IDirectXFileSaveObjectImpl_SaveData(IDirectXFileSaveObject* iface, LPDIRECTXFILEDATA ppDataObj)
1313 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1315 FIXME("(%p/%p)->(%p) stub!\n", This, iface, ppDataObj);
1317 return DXFILEERR_BADVALUE;
1320 static const IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl =
1322 IDirectXFileSaveObjectImpl_QueryInterface,
1323 IDirectXFileSaveObjectImpl_AddRef,
1324 IDirectXFileSaveObjectImpl_Release,
1325 IDirectXFileSaveObjectImpl_SaveTemplates,
1326 IDirectXFileSaveObjectImpl_CreateDataObject,
1327 IDirectXFileSaveObjectImpl_SaveData