msi: Fix handling of components without a key path in MsiEnumComponentCostsW.
[wine/multimedia.git] / dlls / d3dxof / d3dxof.c
blob7e3eb9e5653f31dc403c171360cb299492555209
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->lpVtbl = &IDirectXFile_Vtbl;
83 object->ref = 1;
85 *ppObj = object;
87 return S_OK;
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);
101 *ppvObject = This;
102 return S_OK;
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);
116 return ref;
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);
126 if (!ref)
127 HeapFree(GetProcessHeap(), 0, This);
129 return ref;
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;
137 HRESULT hr;
138 DWORD* header;
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;
145 LPBYTE file_buffer;
146 DWORD file_size;
148 LPDXFILELOADMEMORY lpdxflm = NULL;
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 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);
172 if (!file_mapping)
174 hr = DXFILEERR_BADFILETYPE;
175 goto error;
178 buffer = MapViewOfFile(file_mapping, FILE_MAP_READ, 0, 0, 0);
179 if (!buffer)
181 hr = DXFILEERR_BADFILETYPE;
182 goto error;
184 file_buffer = buffer;
186 else if (dwLoadOptions == DXFILELOAD_FROMRESOURCE)
188 HRSRC resource_info;
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);
194 if (!resource_info)
196 hr = DXFILEERR_RESOURCENOTFOUND;
197 goto error;
200 file_size = SizeofResource(lpdxflr->hModule, resource_info);
202 resource_data = LoadResource(lpdxflr->hModule, resource_info);
203 if (!resource_data)
205 hr = DXFILEERR_BADRESOURCE;
206 goto error;
209 file_buffer = LockResource(resource_data);
210 if (!file_buffer)
212 hr = DXFILEERR_BADRESOURCE;
213 goto error;
216 else if (dwLoadOptions == DXFILELOAD_FROMMEMORY)
218 lpdxflm = pvSource;
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;
225 else
227 FIXME("Source type %d is not handled yet\n", dwLoadOptions);
228 hr = DXFILEERR_NOTDONEYET;
229 goto error;
232 header = (DWORD*)file_buffer;
234 if (TRACE_ON(d3dxof))
236 char string[17];
237 memcpy(string, header, 16);
238 string[16] = 0;
239 TRACE("header = '%s'\n", string);
242 if (file_size < 16)
244 hr = DXFILEERR_BADFILETYPE;
245 goto error;
248 if (header[0] != XOFFILE_FORMAT_MAGIC)
250 hr = DXFILEERR_BADFILETYPE;
251 goto error;
254 if ((header[1] != XOFFILE_FORMAT_VERSION_302) && (header[1] != XOFFILE_FORMAT_VERSION_303))
256 hr = DXFILEERR_BADFILEVERSION;
257 goto error;
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;
265 goto error;
268 if ((header[2] == XOFFILE_FORMAT_BINARY_MSZIP) || (header[2] == XOFFILE_FORMAT_TEXT_MSZIP))
270 int err;
271 DWORD comp_size;
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);
283 if (!decomp_buffer)
285 ERR("Out of memory\n");
286 hr = DXFILEERR_BADALLOC;
287 goto error;
289 err = mszip_decompress(comp_size, decomp_size, (char*)file_buffer + 24, (char*)decomp_buffer);
290 if (err)
292 WARN("Error while decomrpessing mszip archive %d\n", err);
293 hr = DXFILEERR_BADALLOC;
294 goto error;
298 if ((header[3] != XOFFILE_FORMAT_FLOAT_BITS_32) && (header[3] != XOFFILE_FORMAT_FLOAT_BITS_64))
300 hr = DXFILEERR_BADFILEFLOATSIZE;
301 goto error;
304 TRACE("Header is correct\n");
306 hr = IDirectXFileEnumObjectImpl_Create(&object);
307 if (FAILED(hr))
308 goto error;
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);
322 if (decomp_size)
324 /* Use decompressed data */
325 object->buf.buffer = decomp_buffer;
326 object->buf.rem_bytes = decomp_size;
328 else
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;
343 goto error;
345 else
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))
355 int i;
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));
361 return DXFILE_OK;
363 error:
364 if (buffer)
365 UnmapViewOfFile(buffer);
366 if (file_mapping)
367 CloseHandle(file_mapping);
368 if (hFile != INVALID_HANDLE_VALUE)
369 CloseHandle(hFile);
370 if (resource_data)
371 FreeResource(resource_data);
372 HeapFree(GetProcessHeap(), 0, decomp_buffer);
373 *ppEnumObj = NULL;
375 return hr;
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)
385 return E_POINTER;
387 return IDirectXFileSaveObjectImpl_Create((IDirectXFileSaveObjectImpl**)ppSaveObj);
390 static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LPVOID pvData, DWORD cbSize)
392 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
393 DWORD token_header;
394 parse_buffer buf;
395 LPBYTE decomp_buffer = NULL;
396 DWORD decomp_size = 0;
398 buf.buffer = pvData;
399 buf.rem_bytes = cbSize;
400 buf.txt = FALSE;
401 buf.token_present = FALSE;
402 buf.pdxf = This;
404 TRACE("(%p/%p)->(%p,%d)\n", This, iface, pvData, cbSize);
406 if (!pvData)
407 return DXFILEERR_BADVALUE;
409 if (cbSize < 16)
410 return DXFILEERR_BADFILETYPE;
412 if (TRACE_ON(d3dxof))
414 char string[17];
415 memcpy(string, pvData, 16);
416 string[16] = 0;
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))
441 int err;
442 DWORD comp_size;
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);
454 if (!decomp_buffer)
456 ERR("Out of memory\n");
457 return DXFILEERR_BADALLOC;
459 err = mszip_decompress(comp_size, decomp_size, (char*)pvData + 24, (char*)decomp_buffer);
460 if (err)
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))
469 buf.txt = TRUE;
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");
478 if (decomp_size)
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;
491 else
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))
501 int i;
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);
509 return DXFILE_OK;
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));
529 if (!object)
531 ERR("Out of memory\n");
532 return DXFILEERR_BADALLOC;
535 object->lpVtbl = &IDirectXFileBinary_Vtbl;
536 object->ref = 1;
538 *ppObj = object;
540 return DXFILE_OK;
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);
555 *ppvObject = This;
556 return S_OK;
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);
574 return ref;
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);
584 if (!ref)
585 HeapFree(GetProcessHeap(), 0, This);
587 return ref;
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));
657 if (!object)
659 ERR("Out of memory\n");
660 return DXFILEERR_BADALLOC;
663 object->lpVtbl = &IDirectXFileData_Vtbl;
664 object->ref = 1;
666 *ppObj = object;
668 return S_OK;
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);
683 *ppvObject = This;
684 return S_OK;
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);
702 return ref;
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);
712 if (!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);
723 return ref;
726 /*** IDirectXFileObject methods ***/
727 static HRESULT WINAPI IDirectXFileDataImpl_GetName(IDirectXFileData* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen)
730 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
731 DWORD len;
733 TRACE("(%p/%p)->(%p,%p)\n", This, iface, pstrNameBuf, pdwBufLen);
735 if (!pdwBufLen)
736 return DXFILEERR_BADVALUE;
738 len = strlen(This->pobj->name);
739 if (len)
740 len++;
742 if (pstrNameBuf) {
743 if (*pdwBufLen < len)
744 return DXFILEERR_BADVALUE;
745 CopyMemory(pstrNameBuf, This->pobj->name, len);
747 *pdwBufLen = len;
749 return DXFILE_OK;
752 static HRESULT WINAPI IDirectXFileDataImpl_GetId(IDirectXFileData* iface, LPGUID pGuid)
754 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
756 TRACE("(%p/%p)->(%p)\n", This, iface, pGuid);
758 if (!pGuid)
759 return DXFILEERR_BADVALUE;
761 memcpy(pGuid, &This->pobj->class_id, 16);
763 return DXFILE_OK;
766 /*** IDirectXFileData methods ***/
767 static HRESULT WINAPI IDirectXFileDataImpl_GetData(IDirectXFileData* iface, LPCSTR szMember, DWORD* pcbSize, void** ppvData)
769 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
771 TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, szMember, pcbSize, ppvData);
773 if (!pcbSize || !ppvData)
774 return DXFILEERR_BADVALUE;
776 if (szMember)
778 FIXME("Specifying a member is not supported yet!\n");
779 return DXFILEERR_BADVALUE;
782 *pcbSize = This->pobj->size;
783 *ppvData = This->pobj->root->pdata + This->pobj->pos_data;
785 return DXFILE_OK;
788 static HRESULT WINAPI IDirectXFileDataImpl_GetType(IDirectXFileData* iface, const GUID** pguid)
790 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
791 static GUID guid;
793 TRACE("(%p/%p)->(%p)\n", This, iface, pguid);
795 if (!pguid)
796 return DXFILEERR_BADVALUE;
798 memcpy(&guid, &This->pobj->type, 16);
799 *pguid = &guid;
801 return DXFILE_OK;
804 static HRESULT WINAPI IDirectXFileDataImpl_GetNextObject(IDirectXFileData* iface, LPDIRECTXFILEOBJECT* ppChildObj)
806 HRESULT hr;
807 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
809 TRACE("(%p/%p)->(%p)\n", This, iface, ppChildObj);
811 if (This->cur_enum_object >= This->pobj->nb_childs)
812 return DXFILEERR_NOMOREOBJECTS;
814 if (This->from_ref && (This->level >= 1))
816 /* Only 2 levels can be enumerated if the object is obtained from a reference */
817 return DXFILEERR_NOMOREOBJECTS;
820 if (This->pobj->childs[This->cur_enum_object]->binary)
822 IDirectXFileBinaryImpl *object;
824 hr = IDirectXFileBinaryImpl_Create(&object);
825 if (FAILED(hr))
826 return hr;
828 *ppChildObj = (LPDIRECTXFILEOBJECT)object;
830 else if (This->pobj->childs[This->cur_enum_object]->ptarget)
832 IDirectXFileDataReferenceImpl *object;
834 hr = IDirectXFileDataReferenceImpl_Create(&object);
835 if (FAILED(hr))
836 return hr;
838 object->ptarget = This->pobj->childs[This->cur_enum_object++]->ptarget;
840 *ppChildObj = (LPDIRECTXFILEOBJECT)object;
842 else
844 IDirectXFileDataImpl *object;
846 hr = IDirectXFileDataImpl_Create(&object);
847 if (FAILED(hr))
848 return hr;
850 object->pobj = This->pobj->childs[This->cur_enum_object++];
851 object->cur_enum_object = 0;
852 object->from_ref = This->from_ref;
853 object->level = This->level + 1;
855 *ppChildObj = (LPDIRECTXFILEOBJECT)object;
858 return DXFILE_OK;
861 static HRESULT WINAPI IDirectXFileDataImpl_AddDataObject(IDirectXFileData* iface, LPDIRECTXFILEDATA pDataObj)
863 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
865 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pDataObj);
867 return DXFILEERR_BADVALUE;
870 static HRESULT WINAPI IDirectXFileDataImpl_AddDataReference(IDirectXFileData* iface, LPCSTR szRef, const GUID* pguidRef)
872 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
874 FIXME("(%p/%p)->(%s,%p) stub!\n", This, iface, szRef, pguidRef);
876 return DXFILEERR_BADVALUE;
879 static HRESULT WINAPI IDirectXFileDataImpl_AddBinaryObject(IDirectXFileData* iface, LPCSTR szName, const GUID* pguid, LPCSTR szMimeType, LPVOID pvData, DWORD cbSize)
881 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
883 FIXME("(%p/%p)->(%s,%p,%s,%p,%d) stub!\n", This, iface, szName, pguid, szMimeType, pvData, cbSize);
885 return DXFILEERR_BADVALUE;
888 static const IDirectXFileDataVtbl IDirectXFileData_Vtbl =
890 IDirectXFileDataImpl_QueryInterface,
891 IDirectXFileDataImpl_AddRef,
892 IDirectXFileDataImpl_Release,
893 IDirectXFileDataImpl_GetName,
894 IDirectXFileDataImpl_GetId,
895 IDirectXFileDataImpl_GetData,
896 IDirectXFileDataImpl_GetType,
897 IDirectXFileDataImpl_GetNextObject,
898 IDirectXFileDataImpl_AddDataObject,
899 IDirectXFileDataImpl_AddDataReference,
900 IDirectXFileDataImpl_AddBinaryObject
903 static HRESULT IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl** ppObj)
905 IDirectXFileDataReferenceImpl* object;
907 TRACE("(%p)\n", ppObj);
909 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileDataReferenceImpl));
910 if (!object)
912 ERR("Out of memory\n");
913 return DXFILEERR_BADALLOC;
916 object->lpVtbl = &IDirectXFileDataReference_Vtbl;
917 object->ref = 1;
919 *ppObj = object;
921 return S_OK;
924 /*** IUnknown methods ***/
925 static HRESULT WINAPI IDirectXFileDataReferenceImpl_QueryInterface(IDirectXFileDataReference* iface, REFIID riid, void** ppvObject)
927 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
929 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
931 if (IsEqualGUID(riid, &IID_IUnknown)
932 || IsEqualGUID(riid, &IID_IDirectXFileObject)
933 || IsEqualGUID(riid, &IID_IDirectXFileDataReference))
935 IUnknown_AddRef(iface);
936 *ppvObject = This;
937 return S_OK;
940 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
941 if (!IsEqualGUID(riid, &IID_IDirectXFileData)
942 && !IsEqualGUID(riid, &IID_IDirectXFileBinary))
943 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
945 return E_NOINTERFACE;
948 static ULONG WINAPI IDirectXFileDataReferenceImpl_AddRef(IDirectXFileDataReference* iface)
950 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
951 ULONG ref = InterlockedIncrement(&This->ref);
953 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
955 return ref;
958 static ULONG WINAPI IDirectXFileDataReferenceImpl_Release(IDirectXFileDataReference* iface)
960 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
961 ULONG ref = InterlockedDecrement(&This->ref);
963 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
965 if (!ref)
966 HeapFree(GetProcessHeap(), 0, This);
968 return ref;
971 /*** IDirectXFileObject methods ***/
972 static HRESULT WINAPI IDirectXFileDataReferenceImpl_GetName(IDirectXFileDataReference* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen)
974 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
975 DWORD len;
977 TRACE("(%p/%p)->(%p,%p)\n", This, iface, pstrNameBuf, pdwBufLen);
979 if (!pdwBufLen)
980 return DXFILEERR_BADVALUE;
982 len = strlen(This->ptarget->name);
983 if (len)
984 len++;
986 if (pstrNameBuf) {
987 if (*pdwBufLen < len)
988 return DXFILEERR_BADVALUE;
989 CopyMemory(pstrNameBuf, This->ptarget->name, len);
991 *pdwBufLen = len;
993 return DXFILE_OK;
996 static HRESULT WINAPI IDirectXFileDataReferenceImpl_GetId(IDirectXFileDataReference* iface, LPGUID pGuid)
998 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
1000 TRACE("(%p/%p)->(%p)\n", This, iface, pGuid);
1002 if (!pGuid)
1003 return DXFILEERR_BADVALUE;
1005 memcpy(pGuid, &This->ptarget->class_id, 16);
1007 return DXFILE_OK;
1010 /*** IDirectXFileDataReference ***/
1011 static HRESULT WINAPI IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference* iface, LPDIRECTXFILEDATA* ppDataObj)
1013 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
1014 IDirectXFileDataImpl *object;
1015 HRESULT hr;
1017 TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj);
1019 if (!ppDataObj)
1020 return DXFILEERR_BADVALUE;
1022 hr = IDirectXFileDataImpl_Create(&object);
1023 if (FAILED(hr))
1024 return hr;
1026 object->pobj = This->ptarget;
1027 object->cur_enum_object = 0;
1028 object->level = 0;
1029 object->from_ref = TRUE;
1031 *ppDataObj = (LPDIRECTXFILEDATA)object;
1033 return DXFILE_OK;
1036 static const IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl =
1038 IDirectXFileDataReferenceImpl_QueryInterface,
1039 IDirectXFileDataReferenceImpl_AddRef,
1040 IDirectXFileDataReferenceImpl_Release,
1041 IDirectXFileDataReferenceImpl_GetName,
1042 IDirectXFileDataReferenceImpl_GetId,
1043 IDirectXFileDataReferenceImpl_Resolve
1046 static HRESULT IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl** ppObj)
1048 IDirectXFileEnumObjectImpl* object;
1050 TRACE("(%p)\n", ppObj);
1052 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileEnumObjectImpl));
1053 if (!object)
1055 ERR("Out of memory\n");
1056 return DXFILEERR_BADALLOC;
1059 object->lpVtbl = &IDirectXFileEnumObject_Vtbl;
1060 object->ref = 1;
1062 *ppObj = object;
1064 return S_OK;
1067 /*** IUnknown methods ***/
1068 static HRESULT WINAPI IDirectXFileEnumObjectImpl_QueryInterface(IDirectXFileEnumObject* iface, REFIID riid, void** ppvObject)
1070 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1072 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
1074 if (IsEqualGUID(riid, &IID_IUnknown)
1075 || IsEqualGUID(riid, &IID_IDirectXFileEnumObject))
1077 IUnknown_AddRef(iface);
1078 *ppvObject = This;
1079 return S_OK;
1082 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
1083 return E_NOINTERFACE;
1086 static ULONG WINAPI IDirectXFileEnumObjectImpl_AddRef(IDirectXFileEnumObject* iface)
1088 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1089 ULONG ref = InterlockedIncrement(&This->ref);
1091 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
1093 return ref;
1096 static ULONG WINAPI IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject* iface)
1098 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1099 ULONG ref = InterlockedDecrement(&This->ref);
1101 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
1103 if (!ref)
1105 int i;
1106 for (i = 0; i < This->nb_xobjects; i++)
1107 IDirectXFileData_Release(This->pRefObjects[i]);
1108 if (This->source == DXFILELOAD_FROMFILE)
1110 UnmapViewOfFile(This->buffer);
1111 CloseHandle(This->file_mapping);
1112 CloseHandle(This->hFile);
1114 else if (This->source == DXFILELOAD_FROMRESOURCE)
1115 FreeResource(This->resource_data);
1116 HeapFree(GetProcessHeap(), 0, This->decomp_buffer);
1117 HeapFree(GetProcessHeap(), 0, This);
1120 return ref;
1123 /*** IDirectXFileEnumObject methods ***/
1124 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject* iface, LPDIRECTXFILEDATA* ppDataObj)
1126 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1127 IDirectXFileDataImpl* object;
1128 HRESULT hr;
1129 LPBYTE pstrings = NULL;
1131 TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj);
1133 if (This->nb_xobjects >= MAX_OBJECTS)
1135 ERR("Too many objects\n");
1136 return DXFILEERR_NOMOREOBJECTS;
1139 /* Check if there are templates defined before the object */
1140 while (This->buf.rem_bytes && is_template_available(&This->buf))
1142 if (!parse_template(&This->buf))
1144 WARN("Template is not correct\n");
1145 hr = DXFILEERR_BADVALUE;
1146 goto error;
1148 else
1150 TRACE("Template successfully parsed:\n");
1151 if (TRACE_ON(d3dxof))
1152 dump_template(This->pDirectXFile->xtemplates, &This->pDirectXFile->xtemplates[This->pDirectXFile->nb_xtemplates - 1]);
1156 if (!This->buf.rem_bytes)
1157 return DXFILEERR_NOMOREOBJECTS;
1159 hr = IDirectXFileDataImpl_Create(&object);
1160 if (FAILED(hr))
1161 return hr;
1163 This->buf.pxo_globals = This->xobjects;
1164 This->buf.nb_pxo_globals = This->nb_xobjects;
1165 This->buf.level = 0;
1167 This->buf.pxo_tab = HeapAlloc(GetProcessHeap(), 0, sizeof(xobject)*MAX_SUBOBJECTS);
1168 if (!This->buf.pxo_tab)
1170 ERR("Out of memory\n");
1171 hr = DXFILEERR_BADALLOC;
1172 goto error;
1174 This->buf.pxo = This->xobjects[This->nb_xobjects] = This->buf.pxo_tab;
1176 This->buf.pxo->pdata = This->buf.pdata = NULL;
1177 This->buf.capacity = 0;
1178 This->buf.cur_pos_data = 0;
1179 This->buf.pxo->nb_subobjects = 1;
1181 pstrings = HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER);
1182 if (!pstrings)
1184 ERR("Out of memory\n");
1185 hr = DXFILEERR_BADALLOC;
1186 goto error;
1188 This->buf.cur_pstrings = This->buf.pstrings = object->pstrings = pstrings;
1190 if (!parse_object(&This->buf))
1192 WARN("Object is not correct\n");
1193 hr = DXFILEERR_PARSEERROR;
1194 goto error;
1197 object->pstrings = pstrings;
1198 object->pobj = This->buf.pxo;
1199 object->cur_enum_object = 0;
1200 object->level = 0;
1201 object->from_ref = FALSE;
1203 *ppDataObj = (LPDIRECTXFILEDATA)object;
1205 /* Get a reference to created object */
1206 This->pRefObjects[This->nb_xobjects] = (LPDIRECTXFILEDATA)object;
1207 IDirectXFileData_AddRef(This->pRefObjects[This->nb_xobjects]);
1209 This->nb_xobjects++;
1211 return DXFILE_OK;
1213 error:
1215 HeapFree(GetProcessHeap(), 0, This->buf.pxo_tab);
1216 HeapFree(GetProcessHeap(), 0, This->buf.pdata);
1217 HeapFree(GetProcessHeap(), 0, pstrings);
1219 return hr;
1222 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetDataObjectById(IDirectXFileEnumObject* iface, REFGUID rguid, LPDIRECTXFILEDATA* ppDataObj)
1224 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1226 FIXME("(%p/%p)->(%p,%p) stub!\n", This, iface, rguid, ppDataObj);
1228 return DXFILEERR_BADVALUE;
1231 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetDataObjectByName(IDirectXFileEnumObject* iface, LPCSTR szName, LPDIRECTXFILEDATA* ppDataObj)
1233 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1235 FIXME("(%p/%p)->(%s,%p) stub!\n", This, iface, szName, ppDataObj);
1237 return DXFILEERR_BADVALUE;
1240 static const IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl =
1242 IDirectXFileEnumObjectImpl_QueryInterface,
1243 IDirectXFileEnumObjectImpl_AddRef,
1244 IDirectXFileEnumObjectImpl_Release,
1245 IDirectXFileEnumObjectImpl_GetNextDataObject,
1246 IDirectXFileEnumObjectImpl_GetDataObjectById,
1247 IDirectXFileEnumObjectImpl_GetDataObjectByName
1250 static HRESULT IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl** ppObj)
1252 IDirectXFileSaveObjectImpl* object;
1254 TRACE("(%p)\n", ppObj);
1256 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileSaveObjectImpl));
1257 if (!object)
1259 ERR("Out of memory\n");
1260 return DXFILEERR_BADALLOC;
1263 object->lpVtbl = &IDirectXFileSaveObject_Vtbl;
1264 object->ref = 1;
1266 *ppObj = object;
1268 return S_OK;
1271 /*** IUnknown methods ***/
1272 static HRESULT WINAPI IDirectXFileSaveObjectImpl_QueryInterface(IDirectXFileSaveObject* iface, REFIID riid, void** ppvObject)
1274 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1276 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
1278 if (IsEqualGUID(riid, &IID_IUnknown)
1279 || IsEqualGUID(riid, &IID_IDirectXFileSaveObject))
1281 IUnknown_AddRef(iface);
1282 *ppvObject = This;
1283 return S_OK;
1286 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
1287 return E_NOINTERFACE;
1290 static ULONG WINAPI IDirectXFileSaveObjectImpl_AddRef(IDirectXFileSaveObject* iface)
1292 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1293 ULONG ref = InterlockedIncrement(&This->ref);
1295 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
1297 return ref;
1300 static ULONG WINAPI IDirectXFileSaveObjectImpl_Release(IDirectXFileSaveObject* iface)
1302 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1303 ULONG ref = InterlockedDecrement(&This->ref);
1305 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
1307 if (!ref)
1308 HeapFree(GetProcessHeap(), 0, This);
1310 return ref;
1313 static HRESULT WINAPI IDirectXFileSaveObjectImpl_SaveTemplates(IDirectXFileSaveObject* iface, DWORD cTemplates, const GUID** ppguidTemplates)
1315 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1317 FIXME("(%p/%p)->(%d,%p) stub!\n", This, iface, cTemplates, ppguidTemplates);
1319 return DXFILEERR_BADVALUE;
1322 static HRESULT WINAPI IDirectXFileSaveObjectImpl_CreateDataObject(IDirectXFileSaveObject* iface, REFGUID rguidTemplate, LPCSTR szName, const GUID* pguid, DWORD cbSize, LPVOID pvData, LPDIRECTXFILEDATA* ppDataObj)
1324 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1326 FIXME("(%p/%p)->(%p,%s,%p,%d,%p,%p) stub!\n", This, iface, rguidTemplate, szName, pguid, cbSize, pvData, ppDataObj);
1328 return DXFILEERR_BADVALUE;
1331 static HRESULT WINAPI IDirectXFileSaveObjectImpl_SaveData(IDirectXFileSaveObject* iface, LPDIRECTXFILEDATA ppDataObj)
1333 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
1335 FIXME("(%p/%p)->(%p) stub!\n", This, iface, ppDataObj);
1337 return DXFILEERR_BADVALUE;
1340 static const IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl =
1342 IDirectXFileSaveObjectImpl_QueryInterface,
1343 IDirectXFileSaveObjectImpl_AddRef,
1344 IDirectXFileSaveObjectImpl_Release,
1345 IDirectXFileSaveObjectImpl_SaveTemplates,
1346 IDirectXFileSaveObjectImpl_CreateDataObject,
1347 IDirectXFileSaveObjectImpl_SaveData