d3dxof: Remove unnecessary fields from IDirectXFileEnumObjectImpl.
[wine/multimedia.git] / dlls / d3dxof / d3dxof.c
blob8392c3192f4acd752ee3c637a75bd09c84582f1f
1 /*
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
21 #include "config.h"
22 #include "wine/debug.h"
24 #define COBJMACROS
26 #include "winbase.h"
27 #include "wingdi.h"
29 #include "d3dxof_private.h"
30 #include "dxfile.h"
32 #include <stdio.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));
76 if (!object)
78 ERR("Out of memory\n");
79 return DXFILEERR_BADALLOC;
82 object->IDirectXFile_iface.lpVtbl = &IDirectXFile_Vtbl;
83 object->ref = 1;
85 *ppObj = &object->IDirectXFile_iface;
87 return S_OK;
90 static inline IDirectXFileImpl *impl_from_IDirectXFile(IDirectXFile *iface)
92 return CONTAINING_RECORD(iface, IDirectXFileImpl, IDirectXFile_iface);
95 /*** IUnknown methods ***/
96 static HRESULT WINAPI IDirectXFileImpl_QueryInterface(IDirectXFile* iface, REFIID riid, void** ppvObject)
98 IDirectXFileImpl *This = impl_from_IDirectXFile(iface);
100 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
102 if (IsEqualGUID(riid, &IID_IUnknown)
103 || IsEqualGUID(riid, &IID_IDirectXFile))
105 IUnknown_AddRef(iface);
106 *ppvObject = &This->IDirectXFile_iface;
107 return S_OK;
110 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
111 return E_NOINTERFACE;
114 static ULONG WINAPI IDirectXFileImpl_AddRef(IDirectXFile* iface)
116 IDirectXFileImpl *This = impl_from_IDirectXFile(iface);
117 ULONG ref = InterlockedIncrement(&This->ref);
119 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
121 return ref;
124 static ULONG WINAPI IDirectXFileImpl_Release(IDirectXFile* iface)
126 IDirectXFileImpl *This = impl_from_IDirectXFile(iface);
127 ULONG ref = InterlockedDecrement(&This->ref);
129 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
131 if (!ref)
132 HeapFree(GetProcessHeap(), 0, This);
134 return ref;
137 /*** IDirectXFile methods ***/
138 static HRESULT WINAPI IDirectXFileImpl_CreateEnumObject(IDirectXFile* iface, LPVOID pvSource, DXFILELOADOPTIONS dwLoadOptions, LPDIRECTXFILEENUMOBJECT* ppEnumObj)
140 IDirectXFileImpl *This = impl_from_IDirectXFile(iface);
141 IDirectXFileEnumObjectImpl* object;
142 HRESULT hr;
143 DWORD* header;
144 LPBYTE mapped_memory = NULL;
145 LPBYTE decomp_buffer = NULL;
146 DWORD decomp_size = 0;
147 LPBYTE file_buffer;
148 DWORD file_size;
150 TRACE("(%p/%p)->(%p,%x,%p)\n", This, iface, pvSource, dwLoadOptions, ppEnumObj);
152 if (!ppEnumObj)
153 return DXFILEERR_BADVALUE;
155 /* Only lowest 4 bits are relevant in DXFILELOADOPTIONS */
156 dwLoadOptions &= 0xF;
158 if (dwLoadOptions == DXFILELOAD_FROMFILE)
160 HANDLE hFile, file_mapping;
162 TRACE("Open source file '%s'\n", (char*)pvSource);
164 hFile = CreateFileA(pvSource, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
165 if (hFile == INVALID_HANDLE_VALUE)
167 TRACE("File '%s' not found\n", (char*)pvSource);
168 return DXFILEERR_FILENOTFOUND;
171 file_size = GetFileSize(hFile, NULL);
173 file_mapping = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
174 if (!file_mapping)
176 CloseHandle(hFile);
177 hr = DXFILEERR_BADFILETYPE;
178 goto error;
181 mapped_memory = MapViewOfFile(file_mapping, FILE_MAP_READ, 0, 0, 0);
182 CloseHandle(file_mapping);
183 CloseHandle(hFile);
184 if (!mapped_memory)
186 hr = DXFILEERR_BADFILETYPE;
187 goto error;
189 file_buffer = mapped_memory;
191 else if (dwLoadOptions == DXFILELOAD_FROMRESOURCE)
193 HRSRC resource_info;
194 HGLOBAL resource_data;
195 LPDXFILELOADRESOURCE lpdxflr = pvSource;
197 TRACE("Source in resource (module = %p, name = %s, type = %s\n", lpdxflr->hModule, debugstr_a(lpdxflr->lpName), debugstr_a(lpdxflr->lpType));
199 resource_info = FindResourceA(lpdxflr->hModule, lpdxflr->lpName, lpdxflr->lpType);
200 if (!resource_info)
202 hr = DXFILEERR_RESOURCENOTFOUND;
203 goto error;
206 file_size = SizeofResource(lpdxflr->hModule, resource_info);
208 resource_data = LoadResource(lpdxflr->hModule, resource_info);
209 if (!resource_data)
211 hr = DXFILEERR_BADRESOURCE;
212 goto error;
215 file_buffer = LockResource(resource_data);
216 if (!file_buffer)
218 hr = DXFILEERR_BADRESOURCE;
219 goto error;
222 else if (dwLoadOptions == DXFILELOAD_FROMMEMORY)
224 LPDXFILELOADMEMORY lpdxflm = pvSource;
226 TRACE("Source in memory at %p with size %d\n", lpdxflm->lpMemory, lpdxflm->dSize);
228 file_buffer = lpdxflm->lpMemory;
229 file_size = lpdxflm->dSize;
231 else
233 FIXME("Source type %d is not handled yet\n", dwLoadOptions);
234 hr = DXFILEERR_NOTDONEYET;
235 goto error;
238 header = (DWORD*)file_buffer;
240 if (TRACE_ON(d3dxof))
242 char string[17];
243 memcpy(string, header, 16);
244 string[16] = 0;
245 TRACE("header = '%s'\n", string);
248 if (file_size < 16)
250 hr = DXFILEERR_BADFILETYPE;
251 goto error;
254 if (header[0] != XOFFILE_FORMAT_MAGIC)
256 hr = DXFILEERR_BADFILETYPE;
257 goto error;
260 if ((header[1] != XOFFILE_FORMAT_VERSION_302) && (header[1] != XOFFILE_FORMAT_VERSION_303))
262 hr = DXFILEERR_BADFILEVERSION;
263 goto error;
266 if ((header[2] != XOFFILE_FORMAT_BINARY) && (header[2] != XOFFILE_FORMAT_TEXT) &&
267 (header[2] != XOFFILE_FORMAT_BINARY_MSZIP) && (header[2] != XOFFILE_FORMAT_TEXT_MSZIP))
269 WARN("File type %s unknown\n", debugstr_fourcc(header[2]));
270 hr = DXFILEERR_BADFILETYPE;
271 goto error;
274 if ((header[2] == XOFFILE_FORMAT_BINARY_MSZIP) || (header[2] == XOFFILE_FORMAT_TEXT_MSZIP))
276 int err;
277 DWORD comp_size;
279 /* 0-15 -> xfile header, 16-17 -> decompressed size w/ header, 18-19 -> null,
280 20-21 -> decompressed size w/o header, 22-23 -> size of MSZIP compressed data,
281 24-xx -> compressed MSZIP data */
282 decomp_size = ((WORD*)file_buffer)[10];
283 comp_size = ((WORD*)file_buffer)[11];
285 TRACE("Compressed format %s detected: compressed_size = %x, decompressed_size = %x\n",
286 debugstr_fourcc(header[2]), comp_size, decomp_size);
288 decomp_buffer = HeapAlloc(GetProcessHeap(), 0, decomp_size);
289 if (!decomp_buffer)
291 ERR("Out of memory\n");
292 hr = DXFILEERR_BADALLOC;
293 goto error;
295 err = mszip_decompress(comp_size, decomp_size, (char*)file_buffer + 24, (char*)decomp_buffer);
296 if (err)
298 WARN("Error while decomrpessing mszip archive %d\n", err);
299 hr = DXFILEERR_BADALLOC;
300 goto error;
304 if ((header[3] != XOFFILE_FORMAT_FLOAT_BITS_32) && (header[3] != XOFFILE_FORMAT_FLOAT_BITS_64))
306 hr = DXFILEERR_BADFILEFLOATSIZE;
307 goto error;
310 TRACE("Header is correct\n");
312 hr = IDirectXFileEnumObjectImpl_Create(&object);
313 if (FAILED(hr))
314 goto error;
316 object->mapped_memory = mapped_memory;
317 object->decomp_buffer = decomp_buffer;
318 object->pDirectXFile = This;
319 object->buf.pdxf = This;
320 object->buf.txt = (header[2] == XOFFILE_FORMAT_TEXT) || (header[2] == XOFFILE_FORMAT_TEXT_MSZIP);
321 object->buf.token_present = FALSE;
323 TRACE("File size is %d bytes\n", file_size);
325 if (decomp_size)
327 /* Use decompressed data */
328 object->buf.buffer = decomp_buffer;
329 object->buf.rem_bytes = decomp_size;
331 else
333 /* Go to data after header */
334 object->buf.buffer = file_buffer + 16;
335 object->buf.rem_bytes = file_size - 16;
338 *ppEnumObj = &object->IDirectXFileEnumObject_iface;
340 while (object->buf.rem_bytes && is_template_available(&object->buf))
342 if (!parse_template(&object->buf))
344 WARN("Template is not correct\n");
345 hr = DXFILEERR_BADVALUE;
346 goto error;
348 else
350 TRACE("Template successfully parsed:\n");
351 if (TRACE_ON(d3dxof))
352 dump_template(This->xtemplates, &This->xtemplates[This->nb_xtemplates - 1]);
356 if (TRACE_ON(d3dxof))
358 int i;
359 TRACE("Registered templates (%d):\n", This->nb_xtemplates);
360 for (i = 0; i < This->nb_xtemplates; i++)
361 DPRINTF("%s - %s\n", This->xtemplates[i].name, debugstr_guid(&This->xtemplates[i].class_id));
364 return DXFILE_OK;
366 error:
367 if (mapped_memory)
368 UnmapViewOfFile(mapped_memory);
369 HeapFree(GetProcessHeap(), 0, decomp_buffer);
370 *ppEnumObj = NULL;
372 return hr;
375 static HRESULT WINAPI IDirectXFileImpl_CreateSaveObject(IDirectXFile* iface, LPCSTR szFileName, DXFILEFORMAT dwFileFormat, LPDIRECTXFILESAVEOBJECT* ppSaveObj)
377 IDirectXFileImpl *This = impl_from_IDirectXFile(iface);
378 IDirectXFileSaveObjectImpl *object;
379 HRESULT hr;
381 FIXME("(%p/%p)->(%s,%x,%p) partial stub!\n", This, iface, szFileName, dwFileFormat, ppSaveObj);
383 if (!szFileName || !ppSaveObj)
384 return E_POINTER;
386 hr = IDirectXFileSaveObjectImpl_Create(&object);
387 if (SUCCEEDED(hr))
388 *ppSaveObj = &object->IDirectXFileSaveObject_iface;
389 return hr;
392 static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LPVOID pvData, DWORD cbSize)
394 IDirectXFileImpl *This = impl_from_IDirectXFile(iface);
395 DWORD token_header;
396 parse_buffer buf;
397 LPBYTE decomp_buffer = NULL;
398 DWORD decomp_size = 0;
400 buf.buffer = pvData;
401 buf.rem_bytes = cbSize;
402 buf.txt = FALSE;
403 buf.token_present = FALSE;
404 buf.pdxf = This;
406 TRACE("(%p/%p)->(%p,%d)\n", This, iface, pvData, cbSize);
408 if (!pvData)
409 return DXFILEERR_BADVALUE;
411 if (cbSize < 16)
412 return DXFILEERR_BADFILETYPE;
414 if (TRACE_ON(d3dxof))
416 char string[17];
417 memcpy(string, pvData, 16);
418 string[16] = 0;
419 TRACE("header = '%s'\n", string);
422 read_bytes(&buf, &token_header, 4);
424 if (token_header != XOFFILE_FORMAT_MAGIC)
425 return DXFILEERR_BADFILETYPE;
427 read_bytes(&buf, &token_header, 4);
429 if ((token_header != XOFFILE_FORMAT_VERSION_302) && (token_header != XOFFILE_FORMAT_VERSION_303))
430 return DXFILEERR_BADFILEVERSION;
432 read_bytes(&buf, &token_header, 4);
434 if ((token_header != XOFFILE_FORMAT_BINARY) && (token_header != XOFFILE_FORMAT_TEXT) &&
435 (token_header != XOFFILE_FORMAT_BINARY_MSZIP) && (token_header != XOFFILE_FORMAT_TEXT_MSZIP))
437 WARN("File type %s unknown\n", debugstr_fourcc(token_header));
438 return DXFILEERR_BADFILETYPE;
441 if ((token_header == XOFFILE_FORMAT_BINARY_MSZIP) || (token_header == XOFFILE_FORMAT_TEXT_MSZIP))
443 int err;
444 DWORD comp_size;
446 /* 0-15 -> xfile header, 16-17 -> decompressed size w/ header, 18-19 -> null,
447 20-21 -> decompressed size w/o header, 22-23 -> size of MSZIP compressed data,
448 24-xx -> compressed MSZIP data */
449 decomp_size = ((WORD*)pvData)[10];
450 comp_size = ((WORD*)pvData)[11];
452 TRACE("Compressed format %s detected: compressed_size = %x, decompressed_size = %x\n",
453 debugstr_fourcc(token_header), comp_size, decomp_size);
455 decomp_buffer = HeapAlloc(GetProcessHeap(), 0, decomp_size);
456 if (!decomp_buffer)
458 ERR("Out of memory\n");
459 return DXFILEERR_BADALLOC;
461 err = mszip_decompress(comp_size, decomp_size, (char*)pvData + 24, (char*)decomp_buffer);
462 if (err)
464 WARN("Error while decomrpessing mszip archive %d\n", err);
465 HeapFree(GetProcessHeap(), 0, decomp_buffer);
466 return DXFILEERR_BADALLOC;
470 if ((token_header == XOFFILE_FORMAT_TEXT) || (token_header == XOFFILE_FORMAT_TEXT_MSZIP))
471 buf.txt = TRUE;
473 read_bytes(&buf, &token_header, 4);
475 if ((token_header != XOFFILE_FORMAT_FLOAT_BITS_32) && (token_header != XOFFILE_FORMAT_FLOAT_BITS_64))
476 return DXFILEERR_BADFILEFLOATSIZE;
478 TRACE("Header is correct\n");
480 if (decomp_size)
482 buf.buffer = decomp_buffer;
483 buf.rem_bytes = decomp_size;
486 while (buf.rem_bytes && is_template_available(&buf))
488 if (!parse_template(&buf))
490 WARN("Template is not correct\n");
491 return DXFILEERR_BADVALUE;
493 else
495 TRACE("Template successfully parsed:\n");
496 if (TRACE_ON(d3dxof))
497 dump_template(This->xtemplates, &This->xtemplates[This->nb_xtemplates - 1]);
501 if (TRACE_ON(d3dxof))
503 int i;
504 TRACE("Registered templates (%d):\n", This->nb_xtemplates);
505 for (i = 0; i < This->nb_xtemplates; i++)
506 DPRINTF("%s - %s\n", This->xtemplates[i].name, debugstr_guid(&This->xtemplates[i].class_id));
509 HeapFree(GetProcessHeap(), 0, decomp_buffer);
511 return DXFILE_OK;
514 static const IDirectXFileVtbl IDirectXFile_Vtbl =
516 IDirectXFileImpl_QueryInterface,
517 IDirectXFileImpl_AddRef,
518 IDirectXFileImpl_Release,
519 IDirectXFileImpl_CreateEnumObject,
520 IDirectXFileImpl_CreateSaveObject,
521 IDirectXFileImpl_RegisterTemplates
524 static HRESULT IDirectXFileBinaryImpl_Create(IDirectXFileBinaryImpl** ppObj)
526 IDirectXFileBinaryImpl* object;
528 TRACE("(%p)\n", ppObj);
530 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileBinaryImpl));
531 if (!object)
533 ERR("Out of memory\n");
534 return DXFILEERR_BADALLOC;
537 object->IDirectXFileBinary_iface.lpVtbl = &IDirectXFileBinary_Vtbl;
538 object->ref = 1;
540 *ppObj = object;
542 return DXFILE_OK;
545 static inline IDirectXFileBinaryImpl *impl_from_IDirectXFileBinary(IDirectXFileBinary *iface)
547 return CONTAINING_RECORD(iface, IDirectXFileBinaryImpl, IDirectXFileBinary_iface);
550 /*** IUnknown methods ***/
551 static HRESULT WINAPI IDirectXFileBinaryImpl_QueryInterface(IDirectXFileBinary* iface, REFIID riid, void** ppvObject)
553 IDirectXFileBinaryImpl *This = impl_from_IDirectXFileBinary(iface);
555 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
557 if (IsEqualGUID(riid, &IID_IUnknown)
558 || IsEqualGUID(riid, &IID_IDirectXFileObject)
559 || IsEqualGUID(riid, &IID_IDirectXFileBinary))
561 IUnknown_AddRef(iface);
562 *ppvObject = &This->IDirectXFileBinary_iface;
563 return S_OK;
566 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
567 if (!IsEqualGUID(riid, &IID_IDirectXFileData)
568 && !IsEqualGUID(riid, &IID_IDirectXFileDataReference))
569 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
571 return E_NOINTERFACE;
574 static ULONG WINAPI IDirectXFileBinaryImpl_AddRef(IDirectXFileBinary* iface)
576 IDirectXFileBinaryImpl *This = impl_from_IDirectXFileBinary(iface);
577 ULONG ref = InterlockedIncrement(&This->ref);
579 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
581 return ref;
584 static ULONG WINAPI IDirectXFileBinaryImpl_Release(IDirectXFileBinary* iface)
586 IDirectXFileBinaryImpl *This = impl_from_IDirectXFileBinary(iface);
587 ULONG ref = InterlockedDecrement(&This->ref);
589 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
591 if (!ref)
592 HeapFree(GetProcessHeap(), 0, This);
594 return ref;
597 /*** IDirectXFileObject methods ***/
598 static HRESULT WINAPI IDirectXFileBinaryImpl_GetName(IDirectXFileBinary* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen)
601 IDirectXFileBinaryImpl *This = impl_from_IDirectXFileBinary(iface);
603 FIXME("(%p/%p)->(%p,%p) stub!\n", This, iface, pstrNameBuf, pdwBufLen);
605 return DXFILEERR_BADVALUE;
608 static HRESULT WINAPI IDirectXFileBinaryImpl_GetId(IDirectXFileBinary* iface, LPGUID pGuid)
610 IDirectXFileBinaryImpl *This = impl_from_IDirectXFileBinary(iface);
612 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pGuid);
614 return DXFILEERR_BADVALUE;
617 /*** IDirectXFileBinary methods ***/
618 static HRESULT WINAPI IDirectXFileBinaryImpl_GetSize(IDirectXFileBinary* iface, DWORD* pcbSize)
620 IDirectXFileBinaryImpl *This = impl_from_IDirectXFileBinary(iface);
622 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pcbSize);
624 return DXFILEERR_BADVALUE;
627 static HRESULT WINAPI IDirectXFileBinaryImpl_GetMimeType(IDirectXFileBinary* iface, LPCSTR* pszMimeType)
629 IDirectXFileBinaryImpl *This = impl_from_IDirectXFileBinary(iface);
631 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pszMimeType);
633 return DXFILEERR_BADVALUE;
636 static HRESULT WINAPI IDirectXFileBinaryImpl_Read(IDirectXFileBinary* iface, LPVOID pvData, DWORD cbSize, LPDWORD pcbRead)
638 IDirectXFileBinaryImpl *This = impl_from_IDirectXFileBinary(iface);
640 FIXME("(%p/%p)->(%p, %d, %p) stub!\n", This, iface, pvData, cbSize, pcbRead);
642 return DXFILEERR_BADVALUE;
645 static const IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl =
647 IDirectXFileBinaryImpl_QueryInterface,
648 IDirectXFileBinaryImpl_AddRef,
649 IDirectXFileBinaryImpl_Release,
650 IDirectXFileBinaryImpl_GetName,
651 IDirectXFileBinaryImpl_GetId,
652 IDirectXFileBinaryImpl_GetSize,
653 IDirectXFileBinaryImpl_GetMimeType,
654 IDirectXFileBinaryImpl_Read
657 static HRESULT IDirectXFileDataImpl_Create(IDirectXFileDataImpl** ppObj)
659 IDirectXFileDataImpl* object;
661 TRACE("(%p)\n", ppObj);
663 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileDataImpl));
664 if (!object)
666 ERR("Out of memory\n");
667 return DXFILEERR_BADALLOC;
670 object->IDirectXFileData_iface.lpVtbl = &IDirectXFileData_Vtbl;
671 object->ref = 1;
673 *ppObj = object;
675 return S_OK;
678 static inline IDirectXFileDataImpl *impl_from_IDirectXFileData(IDirectXFileData *iface)
680 return CONTAINING_RECORD(iface, IDirectXFileDataImpl, IDirectXFileData_iface);
683 /*** IUnknown methods ***/
684 static HRESULT WINAPI IDirectXFileDataImpl_QueryInterface(IDirectXFileData* iface, REFIID riid, void** ppvObject)
686 IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface);
688 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
690 if (IsEqualGUID(riid, &IID_IUnknown)
691 || IsEqualGUID(riid, &IID_IDirectXFileObject)
692 || IsEqualGUID(riid, &IID_IDirectXFileData))
694 IUnknown_AddRef(iface);
695 *ppvObject = &This->IDirectXFileData_iface;
696 return S_OK;
699 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
700 if (!IsEqualGUID(riid, &IID_IDirectXFileBinary)
701 && !IsEqualGUID(riid, &IID_IDirectXFileDataReference))
702 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
704 return E_NOINTERFACE;
707 static ULONG WINAPI IDirectXFileDataImpl_AddRef(IDirectXFileData* iface)
709 IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface);
710 ULONG ref = InterlockedIncrement(&This->ref);
712 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
714 return ref;
717 static ULONG WINAPI IDirectXFileDataImpl_Release(IDirectXFileData* iface)
719 IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface);
720 ULONG ref = InterlockedDecrement(&This->ref);
722 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
724 if (!ref)
726 if (!This->level && !This->from_ref)
728 HeapFree(GetProcessHeap(), 0, This->pstrings);
729 HeapFree(GetProcessHeap(), 0, This->pobj->pdata);
730 HeapFree(GetProcessHeap(), 0, This->pobj);
732 HeapFree(GetProcessHeap(), 0, This);
735 return ref;
738 /*** IDirectXFileObject methods ***/
739 static HRESULT WINAPI IDirectXFileDataImpl_GetName(IDirectXFileData* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen)
741 IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface);
742 DWORD len;
744 TRACE("(%p/%p)->(%p,%p)\n", This, iface, pstrNameBuf, pdwBufLen);
746 if (!pdwBufLen)
747 return DXFILEERR_BADVALUE;
749 len = strlen(This->pobj->name);
750 if (len)
751 len++;
753 if (pstrNameBuf) {
754 if (*pdwBufLen < len)
755 return DXFILEERR_BADVALUE;
756 CopyMemory(pstrNameBuf, This->pobj->name, len);
758 *pdwBufLen = len;
760 return DXFILE_OK;
763 static HRESULT WINAPI IDirectXFileDataImpl_GetId(IDirectXFileData* iface, LPGUID pGuid)
765 IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface);
767 TRACE("(%p/%p)->(%p)\n", This, iface, pGuid);
769 if (!pGuid)
770 return DXFILEERR_BADVALUE;
772 memcpy(pGuid, &This->pobj->class_id, 16);
774 return DXFILE_OK;
777 /*** IDirectXFileData methods ***/
778 static HRESULT WINAPI IDirectXFileDataImpl_GetData(IDirectXFileData* iface, LPCSTR szMember, DWORD* pcbSize, void** ppvData)
780 IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface);
782 TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, szMember, pcbSize, ppvData);
784 if (!pcbSize || !ppvData)
785 return DXFILEERR_BADVALUE;
787 if (szMember)
789 FIXME("Specifying a member is not supported yet!\n");
790 return DXFILEERR_BADVALUE;
793 *pcbSize = This->pobj->size;
794 *ppvData = This->pobj->root->pdata + This->pobj->pos_data;
796 return DXFILE_OK;
799 static HRESULT WINAPI IDirectXFileDataImpl_GetType(IDirectXFileData* iface, const GUID** pguid)
801 IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface);
802 static GUID guid;
804 TRACE("(%p/%p)->(%p)\n", This, iface, pguid);
806 if (!pguid)
807 return DXFILEERR_BADVALUE;
809 memcpy(&guid, &This->pobj->type, 16);
810 *pguid = &guid;
812 return DXFILE_OK;
815 static HRESULT WINAPI IDirectXFileDataImpl_GetNextObject(IDirectXFileData* iface, LPDIRECTXFILEOBJECT* ppChildObj)
817 HRESULT hr;
818 IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface);
820 TRACE("(%p/%p)->(%p)\n", This, iface, ppChildObj);
822 if (This->cur_enum_object >= This->pobj->nb_childs)
823 return DXFILEERR_NOMOREOBJECTS;
825 if (This->from_ref && (This->level >= 1))
827 /* Only 2 levels can be enumerated if the object is obtained from a reference */
828 return DXFILEERR_NOMOREOBJECTS;
831 if (This->pobj->childs[This->cur_enum_object]->binary)
833 IDirectXFileBinaryImpl *object;
835 hr = IDirectXFileBinaryImpl_Create(&object);
836 if (FAILED(hr))
837 return hr;
839 *ppChildObj = (LPDIRECTXFILEOBJECT)&object->IDirectXFileBinary_iface;
841 else if (This->pobj->childs[This->cur_enum_object]->ptarget)
843 IDirectXFileDataReferenceImpl *object;
845 hr = IDirectXFileDataReferenceImpl_Create(&object);
846 if (FAILED(hr))
847 return hr;
849 object->ptarget = This->pobj->childs[This->cur_enum_object++]->ptarget;
851 *ppChildObj = (LPDIRECTXFILEOBJECT)&object->IDirectXFileDataReference_iface;
853 else
855 IDirectXFileDataImpl *object;
857 hr = IDirectXFileDataImpl_Create(&object);
858 if (FAILED(hr))
859 return hr;
861 object->pobj = This->pobj->childs[This->cur_enum_object++];
862 object->cur_enum_object = 0;
863 object->from_ref = This->from_ref;
864 object->level = This->level + 1;
866 *ppChildObj = (LPDIRECTXFILEOBJECT)&object->IDirectXFileData_iface;
869 return DXFILE_OK;
872 static HRESULT WINAPI IDirectXFileDataImpl_AddDataObject(IDirectXFileData* iface, LPDIRECTXFILEDATA pDataObj)
874 IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface);
876 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pDataObj);
878 return DXFILEERR_BADVALUE;
881 static HRESULT WINAPI IDirectXFileDataImpl_AddDataReference(IDirectXFileData* iface, LPCSTR szRef, const GUID* pguidRef)
883 IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface);
885 FIXME("(%p/%p)->(%s,%p) stub!\n", This, iface, szRef, pguidRef);
887 return DXFILEERR_BADVALUE;
890 static HRESULT WINAPI IDirectXFileDataImpl_AddBinaryObject(IDirectXFileData* iface, LPCSTR szName, const GUID* pguid, LPCSTR szMimeType, LPVOID pvData, DWORD cbSize)
892 IDirectXFileDataImpl *This = impl_from_IDirectXFileData(iface);
894 FIXME("(%p/%p)->(%s,%p,%s,%p,%d) stub!\n", This, iface, szName, pguid, szMimeType, pvData, cbSize);
896 return DXFILEERR_BADVALUE;
899 static const IDirectXFileDataVtbl IDirectXFileData_Vtbl =
901 IDirectXFileDataImpl_QueryInterface,
902 IDirectXFileDataImpl_AddRef,
903 IDirectXFileDataImpl_Release,
904 IDirectXFileDataImpl_GetName,
905 IDirectXFileDataImpl_GetId,
906 IDirectXFileDataImpl_GetData,
907 IDirectXFileDataImpl_GetType,
908 IDirectXFileDataImpl_GetNextObject,
909 IDirectXFileDataImpl_AddDataObject,
910 IDirectXFileDataImpl_AddDataReference,
911 IDirectXFileDataImpl_AddBinaryObject
914 static HRESULT IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl** ppObj)
916 IDirectXFileDataReferenceImpl* object;
918 TRACE("(%p)\n", ppObj);
920 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileDataReferenceImpl));
921 if (!object)
923 ERR("Out of memory\n");
924 return DXFILEERR_BADALLOC;
927 object->IDirectXFileDataReference_iface.lpVtbl = &IDirectXFileDataReference_Vtbl;
928 object->ref = 1;
930 *ppObj = object;
932 return S_OK;
935 static inline IDirectXFileDataReferenceImpl *impl_from_IDirectXFileDataReference(IDirectXFileDataReference *iface)
937 return CONTAINING_RECORD(iface, IDirectXFileDataReferenceImpl, IDirectXFileDataReference_iface);
940 /*** IUnknown methods ***/
941 static HRESULT WINAPI IDirectXFileDataReferenceImpl_QueryInterface(IDirectXFileDataReference* iface, REFIID riid, void** ppvObject)
943 IDirectXFileDataReferenceImpl *This = impl_from_IDirectXFileDataReference(iface);
945 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
947 if (IsEqualGUID(riid, &IID_IUnknown)
948 || IsEqualGUID(riid, &IID_IDirectXFileObject)
949 || IsEqualGUID(riid, &IID_IDirectXFileDataReference))
951 IUnknown_AddRef(iface);
952 *ppvObject = &This->IDirectXFileDataReference_iface;
953 return S_OK;
956 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
957 if (!IsEqualGUID(riid, &IID_IDirectXFileData)
958 && !IsEqualGUID(riid, &IID_IDirectXFileBinary))
959 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
961 return E_NOINTERFACE;
964 static ULONG WINAPI IDirectXFileDataReferenceImpl_AddRef(IDirectXFileDataReference* iface)
966 IDirectXFileDataReferenceImpl *This = impl_from_IDirectXFileDataReference(iface);
967 ULONG ref = InterlockedIncrement(&This->ref);
969 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
971 return ref;
974 static ULONG WINAPI IDirectXFileDataReferenceImpl_Release(IDirectXFileDataReference* iface)
976 IDirectXFileDataReferenceImpl *This = impl_from_IDirectXFileDataReference(iface);
977 ULONG ref = InterlockedDecrement(&This->ref);
979 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
981 if (!ref)
982 HeapFree(GetProcessHeap(), 0, This);
984 return ref;
987 /*** IDirectXFileObject methods ***/
988 static HRESULT WINAPI IDirectXFileDataReferenceImpl_GetName(IDirectXFileDataReference* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen)
990 IDirectXFileDataReferenceImpl *This = impl_from_IDirectXFileDataReference(iface);
991 DWORD len;
993 TRACE("(%p/%p)->(%p,%p)\n", This, iface, pstrNameBuf, pdwBufLen);
995 if (!pdwBufLen)
996 return DXFILEERR_BADVALUE;
998 len = strlen(This->ptarget->name);
999 if (len)
1000 len++;
1002 if (pstrNameBuf) {
1003 if (*pdwBufLen < len)
1004 return DXFILEERR_BADVALUE;
1005 CopyMemory(pstrNameBuf, This->ptarget->name, len);
1007 *pdwBufLen = len;
1009 return DXFILE_OK;
1012 static HRESULT WINAPI IDirectXFileDataReferenceImpl_GetId(IDirectXFileDataReference* iface, LPGUID pGuid)
1014 IDirectXFileDataReferenceImpl *This = impl_from_IDirectXFileDataReference(iface);
1016 TRACE("(%p/%p)->(%p)\n", This, iface, pGuid);
1018 if (!pGuid)
1019 return DXFILEERR_BADVALUE;
1021 memcpy(pGuid, &This->ptarget->class_id, 16);
1023 return DXFILE_OK;
1026 /*** IDirectXFileDataReference ***/
1027 static HRESULT WINAPI IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference* iface, LPDIRECTXFILEDATA* ppDataObj)
1029 IDirectXFileDataReferenceImpl *This = impl_from_IDirectXFileDataReference(iface);
1030 IDirectXFileDataImpl *object;
1031 HRESULT hr;
1033 TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj);
1035 if (!ppDataObj)
1036 return DXFILEERR_BADVALUE;
1038 hr = IDirectXFileDataImpl_Create(&object);
1039 if (FAILED(hr))
1040 return hr;
1042 object->pobj = This->ptarget;
1043 object->cur_enum_object = 0;
1044 object->level = 0;
1045 object->from_ref = TRUE;
1047 *ppDataObj = (LPDIRECTXFILEDATA)object;
1049 return DXFILE_OK;
1052 static const IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl =
1054 IDirectXFileDataReferenceImpl_QueryInterface,
1055 IDirectXFileDataReferenceImpl_AddRef,
1056 IDirectXFileDataReferenceImpl_Release,
1057 IDirectXFileDataReferenceImpl_GetName,
1058 IDirectXFileDataReferenceImpl_GetId,
1059 IDirectXFileDataReferenceImpl_Resolve
1062 static HRESULT IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl** ppObj)
1064 IDirectXFileEnumObjectImpl* object;
1066 TRACE("(%p)\n", ppObj);
1068 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileEnumObjectImpl));
1069 if (!object)
1071 ERR("Out of memory\n");
1072 return DXFILEERR_BADALLOC;
1075 object->IDirectXFileEnumObject_iface.lpVtbl = &IDirectXFileEnumObject_Vtbl;
1076 object->ref = 1;
1078 *ppObj = object;
1080 return S_OK;
1083 static inline IDirectXFileEnumObjectImpl *impl_from_IDirectXFileEnumObject(IDirectXFileEnumObject *iface)
1085 return CONTAINING_RECORD(iface, IDirectXFileEnumObjectImpl, IDirectXFileEnumObject_iface);
1088 /*** IUnknown methods ***/
1089 static HRESULT WINAPI IDirectXFileEnumObjectImpl_QueryInterface(IDirectXFileEnumObject* iface, REFIID riid, void** ppvObject)
1091 IDirectXFileEnumObjectImpl *This = impl_from_IDirectXFileEnumObject(iface);
1093 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
1095 if (IsEqualGUID(riid, &IID_IUnknown)
1096 || IsEqualGUID(riid, &IID_IDirectXFileEnumObject))
1098 IUnknown_AddRef(iface);
1099 *ppvObject = &This->IDirectXFileEnumObject_iface;
1100 return S_OK;
1103 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
1104 return E_NOINTERFACE;
1107 static ULONG WINAPI IDirectXFileEnumObjectImpl_AddRef(IDirectXFileEnumObject* iface)
1109 IDirectXFileEnumObjectImpl *This = impl_from_IDirectXFileEnumObject(iface);
1110 ULONG ref = InterlockedIncrement(&This->ref);
1112 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
1114 return ref;
1117 static ULONG WINAPI IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject* iface)
1119 IDirectXFileEnumObjectImpl *This = impl_from_IDirectXFileEnumObject(iface);
1120 ULONG ref = InterlockedDecrement(&This->ref);
1122 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
1124 if (!ref)
1126 int i;
1127 for (i = 0; i < This->nb_xobjects; i++)
1128 IDirectXFileData_Release(This->pRefObjects[i]);
1129 if (This->mapped_memory)
1130 UnmapViewOfFile(This->mapped_memory);
1131 HeapFree(GetProcessHeap(), 0, This->decomp_buffer);
1132 HeapFree(GetProcessHeap(), 0, This);
1135 return ref;
1138 /*** IDirectXFileEnumObject methods ***/
1139 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject* iface, LPDIRECTXFILEDATA* ppDataObj)
1141 IDirectXFileEnumObjectImpl *This = impl_from_IDirectXFileEnumObject(iface);
1142 IDirectXFileDataImpl* object;
1143 HRESULT hr;
1144 LPBYTE pstrings = NULL;
1146 TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj);
1148 if (This->nb_xobjects >= MAX_OBJECTS)
1150 ERR("Too many objects\n");
1151 return DXFILEERR_NOMOREOBJECTS;
1154 /* Check if there are templates defined before the object */
1155 while (This->buf.rem_bytes && is_template_available(&This->buf))
1157 if (!parse_template(&This->buf))
1159 WARN("Template is not correct\n");
1160 hr = DXFILEERR_BADVALUE;
1161 goto error;
1163 else
1165 TRACE("Template successfully parsed:\n");
1166 if (TRACE_ON(d3dxof))
1167 dump_template(This->pDirectXFile->xtemplates, &This->pDirectXFile->xtemplates[This->pDirectXFile->nb_xtemplates - 1]);
1171 if (!This->buf.rem_bytes)
1172 return DXFILEERR_NOMOREOBJECTS;
1174 hr = IDirectXFileDataImpl_Create(&object);
1175 if (FAILED(hr))
1176 return hr;
1178 This->buf.pxo_globals = This->xobjects;
1179 This->buf.nb_pxo_globals = This->nb_xobjects;
1180 This->buf.level = 0;
1182 This->buf.pxo_tab = HeapAlloc(GetProcessHeap(), 0, sizeof(xobject)*MAX_SUBOBJECTS);
1183 if (!This->buf.pxo_tab)
1185 ERR("Out of memory\n");
1186 hr = DXFILEERR_BADALLOC;
1187 goto error;
1189 This->buf.pxo = This->xobjects[This->nb_xobjects] = This->buf.pxo_tab;
1191 This->buf.pxo->pdata = This->buf.pdata = NULL;
1192 This->buf.capacity = 0;
1193 This->buf.cur_pos_data = 0;
1194 This->buf.pxo->nb_subobjects = 1;
1196 pstrings = HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER);
1197 if (!pstrings)
1199 ERR("Out of memory\n");
1200 hr = DXFILEERR_BADALLOC;
1201 goto error;
1203 This->buf.cur_pstrings = This->buf.pstrings = object->pstrings = pstrings;
1205 if (!parse_object(&This->buf))
1207 WARN("Object is not correct\n");
1208 hr = DXFILEERR_PARSEERROR;
1209 goto error;
1212 object->pstrings = pstrings;
1213 object->pobj = This->buf.pxo;
1214 object->cur_enum_object = 0;
1215 object->level = 0;
1216 object->from_ref = FALSE;
1218 *ppDataObj = (LPDIRECTXFILEDATA)object;
1220 /* Get a reference to created object */
1221 This->pRefObjects[This->nb_xobjects] = (LPDIRECTXFILEDATA)object;
1222 IDirectXFileData_AddRef(This->pRefObjects[This->nb_xobjects]);
1224 This->nb_xobjects++;
1226 return DXFILE_OK;
1228 error:
1230 HeapFree(GetProcessHeap(), 0, This->buf.pxo_tab);
1231 HeapFree(GetProcessHeap(), 0, This->buf.pdata);
1232 HeapFree(GetProcessHeap(), 0, pstrings);
1234 return hr;
1237 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetDataObjectById(IDirectXFileEnumObject* iface, REFGUID rguid, LPDIRECTXFILEDATA* ppDataObj)
1239 IDirectXFileEnumObjectImpl *This = impl_from_IDirectXFileEnumObject(iface);
1241 FIXME("(%p/%p)->(%p,%p) stub!\n", This, iface, rguid, ppDataObj);
1243 return DXFILEERR_BADVALUE;
1246 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetDataObjectByName(IDirectXFileEnumObject* iface, LPCSTR szName, LPDIRECTXFILEDATA* ppDataObj)
1248 IDirectXFileEnumObjectImpl *This = impl_from_IDirectXFileEnumObject(iface);
1250 FIXME("(%p/%p)->(%s,%p) stub!\n", This, iface, szName, ppDataObj);
1252 return DXFILEERR_BADVALUE;
1255 static const IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl =
1257 IDirectXFileEnumObjectImpl_QueryInterface,
1258 IDirectXFileEnumObjectImpl_AddRef,
1259 IDirectXFileEnumObjectImpl_Release,
1260 IDirectXFileEnumObjectImpl_GetNextDataObject,
1261 IDirectXFileEnumObjectImpl_GetDataObjectById,
1262 IDirectXFileEnumObjectImpl_GetDataObjectByName
1265 static HRESULT IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl** ppObj)
1267 IDirectXFileSaveObjectImpl* object;
1269 TRACE("(%p)\n", ppObj);
1271 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileSaveObjectImpl));
1272 if (!object)
1274 ERR("Out of memory\n");
1275 return DXFILEERR_BADALLOC;
1278 object->IDirectXFileSaveObject_iface.lpVtbl = &IDirectXFileSaveObject_Vtbl;
1279 object->ref = 1;
1281 *ppObj = object;
1283 return S_OK;
1286 static inline IDirectXFileSaveObjectImpl *impl_from_IDirectXFileSaveObject(IDirectXFileSaveObject *iface)
1288 return CONTAINING_RECORD(iface, IDirectXFileSaveObjectImpl, IDirectXFileSaveObject_iface);
1291 /*** IUnknown methods ***/
1292 static HRESULT WINAPI IDirectXFileSaveObjectImpl_QueryInterface(IDirectXFileSaveObject* iface, REFIID riid, void** ppvObject)
1294 IDirectXFileSaveObjectImpl *This = impl_from_IDirectXFileSaveObject(iface);
1296 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
1298 if (IsEqualGUID(riid, &IID_IUnknown)
1299 || IsEqualGUID(riid, &IID_IDirectXFileSaveObject))
1301 IUnknown_AddRef(iface);
1302 *ppvObject = &This->IDirectXFileSaveObject_iface;
1303 return S_OK;
1306 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
1307 return E_NOINTERFACE;
1310 static ULONG WINAPI IDirectXFileSaveObjectImpl_AddRef(IDirectXFileSaveObject* iface)
1312 IDirectXFileSaveObjectImpl *This = impl_from_IDirectXFileSaveObject(iface);
1313 ULONG ref = InterlockedIncrement(&This->ref);
1315 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
1317 return ref;
1320 static ULONG WINAPI IDirectXFileSaveObjectImpl_Release(IDirectXFileSaveObject* iface)
1322 IDirectXFileSaveObjectImpl *This = impl_from_IDirectXFileSaveObject(iface);
1323 ULONG ref = InterlockedDecrement(&This->ref);
1325 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
1327 if (!ref)
1328 HeapFree(GetProcessHeap(), 0, This);
1330 return ref;
1333 static HRESULT WINAPI IDirectXFileSaveObjectImpl_SaveTemplates(IDirectXFileSaveObject* iface, DWORD cTemplates, const GUID** ppguidTemplates)
1335 IDirectXFileSaveObjectImpl *This = impl_from_IDirectXFileSaveObject(iface);
1337 FIXME("(%p/%p)->(%d,%p) stub!\n", This, iface, cTemplates, ppguidTemplates);
1339 return DXFILEERR_BADVALUE;
1342 static HRESULT WINAPI IDirectXFileSaveObjectImpl_CreateDataObject(IDirectXFileSaveObject* iface, REFGUID rguidTemplate, LPCSTR szName, const GUID* pguid, DWORD cbSize, LPVOID pvData, LPDIRECTXFILEDATA* ppDataObj)
1344 IDirectXFileSaveObjectImpl *This = impl_from_IDirectXFileSaveObject(iface);
1346 FIXME("(%p/%p)->(%p,%s,%p,%d,%p,%p) stub!\n", This, iface, rguidTemplate, szName, pguid, cbSize, pvData, ppDataObj);
1348 return DXFILEERR_BADVALUE;
1351 static HRESULT WINAPI IDirectXFileSaveObjectImpl_SaveData(IDirectXFileSaveObject* iface, LPDIRECTXFILEDATA ppDataObj)
1353 IDirectXFileSaveObjectImpl *This = impl_from_IDirectXFileSaveObject(iface);
1355 FIXME("(%p/%p)->(%p) stub!\n", This, iface, ppDataObj);
1357 return DXFILEERR_BADVALUE;
1360 static const IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl =
1362 IDirectXFileSaveObjectImpl_QueryInterface,
1363 IDirectXFileSaveObjectImpl_AddRef,
1364 IDirectXFileSaveObjectImpl_Release,
1365 IDirectXFileSaveObjectImpl_SaveTemplates,
1366 IDirectXFileSaveObjectImpl_CreateDataObject,
1367 IDirectXFileSaveObjectImpl_SaveData