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 "wine/debug.h"
28 #include "d3dxof_private.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(d3dxof
);
34 WINE_DECLARE_DEBUG_CHANNEL(d3dxof_dump
);
36 static const struct IDirectXFileVtbl IDirectXFile_Vtbl
;
37 static const struct IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl
;
38 static const struct IDirectXFileDataVtbl IDirectXFileData_Vtbl
;
39 static const struct IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl
;
40 static const struct IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl
;
41 static const struct IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl
;
43 static HRESULT
IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl
** ppObj
);
44 static HRESULT
IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl
** ppObj
);
45 static HRESULT
IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl
** ppObj
);
47 #define TOKEN_DWORD 41
48 #define TOKEN_FLOAT 42
50 HRESULT
IDirectXFileImpl_Create(IUnknown
* pUnkOuter
, LPVOID
* ppObj
)
52 IDirectXFileImpl
* object
;
54 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
56 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileImpl
));
58 return DXFILEERR_BADALLOC
;
60 object
->IDirectXFile_iface
.lpVtbl
= &IDirectXFile_Vtbl
;
63 /* Reserve first template to handle the case sensitive legacy type indexColor */
64 object
->nb_xtemplates
= 1;
65 strcpy(object
->xtemplates
[0].name
, "indexColor");
66 object
->xtemplates
[0].nb_members
= 2;
67 object
->xtemplates
[0].members
[0].type
= TOKEN_DWORD
;
68 object
->xtemplates
[0].members
[0].nb_dims
= 0;
69 object
->xtemplates
[0].members
[1].type
= TOKEN_FLOAT
;
70 object
->xtemplates
[0].members
[1].nb_dims
= 1;
71 object
->xtemplates
[0].members
[1].dim_fixed
[0] = TRUE
;
72 object
->xtemplates
[0].members
[1].dim_value
[0] = 4;
74 *ppObj
= &object
->IDirectXFile_iface
;
79 static inline IDirectXFileImpl
*impl_from_IDirectXFile(IDirectXFile
*iface
)
81 return CONTAINING_RECORD(iface
, IDirectXFileImpl
, IDirectXFile_iface
);
84 static HRESULT WINAPI
IDirectXFileImpl_QueryInterface(IDirectXFile
*iface
, REFIID riid
, void **out
)
86 IDirectXFileImpl
*object
= impl_from_IDirectXFile(iface
);
88 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
90 if (IsEqualGUID(riid
, &IID_IUnknown
)
91 || IsEqualGUID(riid
, &IID_IDirectXFile
))
93 *out
= &object
->IDirectXFile_iface
;
98 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
102 IUnknown_AddRef((IUnknown
*)*out
);
106 static ULONG WINAPI
IDirectXFileImpl_AddRef(IDirectXFile
*iface
)
108 IDirectXFileImpl
*object
= impl_from_IDirectXFile(iface
);
109 ULONG refcount
= InterlockedIncrement(&object
->ref
);
111 TRACE("%p increasing refcount to %lu.\n", iface
, refcount
);
116 static ULONG WINAPI
IDirectXFileImpl_Release(IDirectXFile
*iface
)
118 IDirectXFileImpl
*object
= impl_from_IDirectXFile(iface
);
119 ULONG refcount
= InterlockedDecrement(&object
->ref
);
121 TRACE("%p decreasing refcount to %lu.\n", iface
, refcount
);
124 HeapFree(GetProcessHeap(), 0, object
);
129 /*** IDirectXFile methods ***/
130 static HRESULT WINAPI
IDirectXFileImpl_CreateEnumObject(IDirectXFile
* iface
, LPVOID pvSource
, DXFILELOADOPTIONS dwLoadOptions
, LPDIRECTXFILEENUMOBJECT
* ppEnumObj
)
132 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
133 IDirectXFileEnumObjectImpl
* object
;
139 TRACE("iface %p, source %p, load_options %#lx, out %p.\n", iface
, pvSource
, dwLoadOptions
, ppEnumObj
);
142 return DXFILEERR_BADVALUE
;
144 /* Only lowest 4 bits are relevant in DXFILELOADOPTIONS */
145 dwLoadOptions
&= 0xF;
147 hr
= IDirectXFileEnumObjectImpl_Create(&object
);
151 if (dwLoadOptions
== DXFILELOAD_FROMFILE
)
153 HANDLE hFile
, file_mapping
;
155 TRACE("Open source file '%s'\n", (char*)pvSource
);
157 hFile
= CreateFileA(pvSource
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
158 if (hFile
== INVALID_HANDLE_VALUE
)
160 TRACE("File '%s' not found\n", (char*)pvSource
);
161 return DXFILEERR_FILENOTFOUND
;
164 file_size
= GetFileSize(hFile
, NULL
);
166 file_mapping
= CreateFileMappingA(hFile
, NULL
, PAGE_READONLY
, 0, 0, NULL
);
170 hr
= DXFILEERR_BADFILETYPE
;
174 object
->mapped_memory
= MapViewOfFile(file_mapping
, FILE_MAP_READ
, 0, 0, 0);
175 CloseHandle(file_mapping
);
176 if (!object
->mapped_memory
)
178 hr
= DXFILEERR_BADFILETYPE
;
181 file_buffer
= object
->mapped_memory
;
183 else if (dwLoadOptions
== DXFILELOAD_FROMRESOURCE
)
186 HGLOBAL resource_data
;
187 LPDXFILELOADRESOURCE lpdxflr
= pvSource
;
189 TRACE("Source in resource (module = %p, name = %s, type = %s)\n", lpdxflr
->hModule
, debugstr_a(lpdxflr
->lpName
), debugstr_a(lpdxflr
->lpType
));
191 resource_info
= FindResourceA(lpdxflr
->hModule
, lpdxflr
->lpName
, lpdxflr
->lpType
);
194 hr
= DXFILEERR_RESOURCENOTFOUND
;
198 file_size
= SizeofResource(lpdxflr
->hModule
, resource_info
);
200 resource_data
= LoadResource(lpdxflr
->hModule
, resource_info
);
203 hr
= DXFILEERR_BADRESOURCE
;
207 file_buffer
= LockResource(resource_data
);
210 hr
= DXFILEERR_BADRESOURCE
;
214 else if (dwLoadOptions
== DXFILELOAD_FROMMEMORY
)
216 LPDXFILELOADMEMORY lpdxflm
= pvSource
;
218 TRACE("Source in memory at %p with size %ld.\n", lpdxflm
->lpMemory
, lpdxflm
->dSize
);
220 file_buffer
= lpdxflm
->lpMemory
;
221 file_size
= lpdxflm
->dSize
;
225 FIXME("Source type %ld not handled yet.\n", dwLoadOptions
);
226 hr
= DXFILEERR_NOTDONEYET
;
230 TRACE("File size is %lu bytes.\n", file_size
);
232 if (TRACE_ON(d3dxof_dump
))
237 sprintf(tmp
, "file%05u.x", num
++);
239 file
= CreateFileA(tmp
, GENERIC_WRITE
, FILE_SHARE_READ
, NULL
, CREATE_ALWAYS
, 0, NULL
);
240 if (file
!= INVALID_HANDLE_VALUE
)
242 WriteFile(file
, file_buffer
, file_size
, &bytes_written
, NULL
);
247 object
->pDirectXFile
= This
;
249 object
->buf
.pdxf
= This
;
250 object
->buf
.token_present
= FALSE
;
251 object
->buf
.buffer
= file_buffer
;
252 object
->buf
.rem_bytes
= file_size
;
253 hr
= parse_header(&object
->buf
, &object
->decomp_buffer
);
257 /* Check if there are templates defined before the object */
258 if (!parse_templates(&object
->buf
, TRUE
))
260 hr
= DXFILEERR_PARSEERROR
;
264 if (TRACE_ON(d3dxof
))
267 TRACE("Registered templates (%lu):\n", This
->nb_xtemplates
);
268 for (i
= 1; i
< This
->nb_xtemplates
; i
++)
269 TRACE("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
272 *ppEnumObj
= &object
->IDirectXFileEnumObject_iface
;
277 IDirectXFileEnumObject_Release(&object
->IDirectXFileEnumObject_iface
);
283 static HRESULT WINAPI
IDirectXFileImpl_CreateSaveObject(IDirectXFile
*iface
, const char *filename
,
284 DXFILEFORMAT format
, LPDIRECTXFILESAVEOBJECT
*out
)
286 IDirectXFileSaveObjectImpl
*object
;
289 FIXME("iface %p, filename %s, format %lu, out %p partial stub!\n", iface
, debugstr_a(filename
),
292 if (!filename
|| !out
)
295 hr
= IDirectXFileSaveObjectImpl_Create(&object
);
297 *out
= &object
->IDirectXFileSaveObject_iface
;
301 static HRESULT WINAPI
IDirectXFileImpl_RegisterTemplates(IDirectXFile
* iface
, LPVOID pvData
, DWORD cbSize
)
303 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
306 LPBYTE decomp_buffer
= NULL
;
309 ZeroMemory(&buf
, sizeof(buf
));
311 buf
.rem_bytes
= cbSize
;
314 TRACE("iface %p, data %p, size %lu.\n", iface
, pvData
, cbSize
);
317 return DXFILEERR_BADVALUE
;
319 if (TRACE_ON(d3dxof_dump
))
324 sprintf(tmp
, "template%05u.x", num
++);
326 file
= CreateFileA(tmp
, GENERIC_WRITE
, FILE_SHARE_READ
, NULL
, CREATE_ALWAYS
, 0, NULL
);
327 if (file
!= INVALID_HANDLE_VALUE
)
329 WriteFile(file
, pvData
, cbSize
, &bytes_written
, NULL
);
334 hr
= parse_header(&buf
, &decomp_buffer
);
338 if (!parse_templates(&buf
, FALSE
))
340 hr
= DXFILEERR_PARSEERROR
;
344 if (TRACE_ON(d3dxof
))
348 TRACE("Registered templates (%lu):\n", This
->nb_xtemplates
);
349 for (i
= 1; i
< This
->nb_xtemplates
; ++i
)
350 TRACE("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
355 HeapFree(GetProcessHeap(), 0, decomp_buffer
);
359 static const IDirectXFileVtbl IDirectXFile_Vtbl
=
361 IDirectXFileImpl_QueryInterface
,
362 IDirectXFileImpl_AddRef
,
363 IDirectXFileImpl_Release
,
364 IDirectXFileImpl_CreateEnumObject
,
365 IDirectXFileImpl_CreateSaveObject
,
366 IDirectXFileImpl_RegisterTemplates
369 static HRESULT
IDirectXFileBinaryImpl_Create(IDirectXFileBinaryImpl
** ppObj
)
371 IDirectXFileBinaryImpl
* object
;
373 TRACE("(%p)\n", ppObj
);
375 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileBinaryImpl
));
377 return DXFILEERR_BADALLOC
;
379 object
->IDirectXFileBinary_iface
.lpVtbl
= &IDirectXFileBinary_Vtbl
;
387 static inline IDirectXFileBinaryImpl
*impl_from_IDirectXFileBinary(IDirectXFileBinary
*iface
)
389 return CONTAINING_RECORD(iface
, IDirectXFileBinaryImpl
, IDirectXFileBinary_iface
);
392 static HRESULT WINAPI
IDirectXFileBinaryImpl_QueryInterface(IDirectXFileBinary
*iface
,
393 REFIID riid
, void **out
)
395 IDirectXFileBinaryImpl
*object
= impl_from_IDirectXFileBinary(iface
);
397 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
399 if (IsEqualGUID(riid
, &IID_IUnknown
)
400 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
401 || IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
403 *out
= &object
->IDirectXFileBinary_iface
;
408 /* Do not print an error for interfaces that can be queried to
409 * retrieve the type of the object */
410 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
) && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
411 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
412 return E_NOINTERFACE
;
415 IUnknown_AddRef((IUnknown
*)*out
);
419 static ULONG WINAPI
IDirectXFileBinaryImpl_AddRef(IDirectXFileBinary
*iface
)
421 IDirectXFileBinaryImpl
*object
= impl_from_IDirectXFileBinary(iface
);
422 ULONG refcount
= InterlockedIncrement(&object
->ref
);
424 TRACE("%p increasing refcount to %lu.\n", iface
, refcount
);
429 static ULONG WINAPI
IDirectXFileBinaryImpl_Release(IDirectXFileBinary
*iface
)
431 IDirectXFileBinaryImpl
*object
= impl_from_IDirectXFileBinary(iface
);
432 ULONG refcount
= InterlockedDecrement(&object
->ref
);
434 TRACE("%p decreasing refcount to %lu.\n", iface
, refcount
);
437 HeapFree(GetProcessHeap(), 0, object
);
442 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetName(IDirectXFileBinary
*iface
, char *name
,
445 FIXME("iface %p, name %p, length %p stub!\n", iface
, name
, length
);
447 return DXFILEERR_BADVALUE
;
450 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetId(IDirectXFileBinary
*iface
, GUID
*guid
)
452 FIXME("iface %p, guid %p stub!\n", iface
, guid
);
454 return DXFILEERR_BADVALUE
;
457 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetSize(IDirectXFileBinary
*iface
, DWORD
*size
)
459 FIXME("iface %p, size %p stub!\n", iface
, size
);
461 return DXFILEERR_BADVALUE
;
464 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetMimeType(IDirectXFileBinary
*iface
, LPCSTR
*mimetype
)
466 FIXME("iface %p, mimetype %p stub!\n", iface
, mimetype
);
468 return DXFILEERR_BADVALUE
;
471 static HRESULT WINAPI
IDirectXFileBinaryImpl_Read(IDirectXFileBinary
*iface
, void *data
,
472 DWORD size
, DWORD
*count
)
474 FIXME("iface %p, data %p, size %lu, count %p stub!\n", iface
, data
, size
, count
);
476 return DXFILEERR_BADVALUE
;
479 static const IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl
=
481 IDirectXFileBinaryImpl_QueryInterface
,
482 IDirectXFileBinaryImpl_AddRef
,
483 IDirectXFileBinaryImpl_Release
,
484 IDirectXFileBinaryImpl_GetName
,
485 IDirectXFileBinaryImpl_GetId
,
486 IDirectXFileBinaryImpl_GetSize
,
487 IDirectXFileBinaryImpl_GetMimeType
,
488 IDirectXFileBinaryImpl_Read
491 static HRESULT
IDirectXFileDataImpl_Create(IDirectXFileDataImpl
** ppObj
)
493 IDirectXFileDataImpl
* object
;
495 TRACE("(%p)\n", ppObj
);
497 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataImpl
));
499 return DXFILEERR_BADALLOC
;
501 object
->IDirectXFileData_iface
.lpVtbl
= &IDirectXFileData_Vtbl
;
509 static inline IDirectXFileDataImpl
*impl_from_IDirectXFileData(IDirectXFileData
*iface
)
511 return CONTAINING_RECORD(iface
, IDirectXFileDataImpl
, IDirectXFileData_iface
);
514 static HRESULT WINAPI
IDirectXFileDataImpl_QueryInterface(IDirectXFileData
*iface
, REFIID riid
,
517 IDirectXFileDataImpl
*data
= impl_from_IDirectXFileData(iface
);
519 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
521 if (IsEqualGUID(riid
, &IID_IUnknown
)
522 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
523 || IsEqualGUID(riid
, &IID_IDirectXFileData
))
525 *out
= &data
->IDirectXFileData_iface
;
530 /* Do not print an error for interfaces that can be queried to
531 * retrieve the type of the object */
532 if (!IsEqualGUID(riid
, &IID_IDirectXFileBinary
) && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
533 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
534 return E_NOINTERFACE
;
537 IUnknown_AddRef((IUnknown
*)*out
);
541 static ULONG WINAPI
IDirectXFileDataImpl_AddRef(IDirectXFileData
*iface
)
543 IDirectXFileDataImpl
*data
= impl_from_IDirectXFileData(iface
);
544 ULONG refcount
= InterlockedIncrement(&data
->ref
);
546 TRACE("%p increasing refcount to %lu.\n", iface
, refcount
);
551 static ULONG WINAPI
IDirectXFileDataImpl_Release(IDirectXFileData
*iface
)
553 IDirectXFileDataImpl
*data
= impl_from_IDirectXFileData(iface
);
554 ULONG refcount
= InterlockedDecrement(&data
->ref
);
556 TRACE("%p decreasing refcount to %lu.\n", iface
, refcount
);
560 if (!data
->level
&& !data
->from_ref
)
562 HeapFree(GetProcessHeap(), 0, data
->pstrings
);
565 HeapFree(GetProcessHeap(), 0, data
->pobj
->pdata
);
566 HeapFree(GetProcessHeap(), 0, data
->pobj
);
569 HeapFree(GetProcessHeap(), 0, data
);
575 /*** IDirectXFileObject methods ***/
576 static HRESULT WINAPI
IDirectXFileDataImpl_GetName(IDirectXFileData
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
578 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
581 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
584 return DXFILEERR_BADVALUE
;
586 len
= strlen(This
->pobj
->name
);
591 if (*pdwBufLen
< len
)
592 return DXFILEERR_BADVALUE
;
593 CopyMemory(pstrNameBuf
, This
->pobj
->name
, len
);
594 /* Even if we return a size of 0, an empty string with a null byte must be returned */
595 if (*pdwBufLen
&& !len
)
603 static HRESULT WINAPI
IDirectXFileDataImpl_GetId(IDirectXFileData
* iface
, LPGUID pGuid
)
605 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
607 TRACE("(%p/%p)->(%p)\n", This
, iface
, pGuid
);
610 return DXFILEERR_BADVALUE
;
612 *pGuid
= This
->pobj
->class_id
;
617 /*** IDirectXFileData methods ***/
618 static HRESULT WINAPI
IDirectXFileDataImpl_GetData(IDirectXFileData
* iface
, LPCSTR szMember
, DWORD
* pcbSize
, void** ppvData
)
620 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
622 TRACE("(%p/%p)->(%s,%p,%p)\n", This
, iface
, debugstr_a(szMember
), pcbSize
, ppvData
);
624 if (!pcbSize
|| !ppvData
)
625 return DXFILEERR_BADVALUE
;
630 for (i
= 0; i
< This
->pobj
->nb_members
; i
++)
631 if (!strcmp(This
->pobj
->members
[i
].name
, szMember
))
633 if (i
== This
->pobj
->nb_members
)
635 WARN("Unknown member '%s'\n", szMember
);
636 return DXFILEERR_BADDATAREFERENCE
;
638 *pcbSize
= This
->pobj
->members
[i
].size
;
639 *ppvData
= This
->pobj
->root
->pdata
+ This
->pobj
->members
[i
].start
;
643 *pcbSize
= This
->pobj
->size
;
644 *ppvData
= This
->pobj
->root
->pdata
+ This
->pobj
->pos_data
;
650 static HRESULT WINAPI
IDirectXFileDataImpl_GetType(IDirectXFileData
* iface
, const GUID
** pguid
)
652 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
655 TRACE("(%p/%p)->(%p)\n", This
, iface
, pguid
);
658 return DXFILEERR_BADVALUE
;
660 guid
= This
->pobj
->type
;
666 static HRESULT WINAPI
IDirectXFileDataImpl_GetNextObject(IDirectXFileData
* iface
, LPDIRECTXFILEOBJECT
* ppChildObj
)
669 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
671 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppChildObj
);
673 if (This
->cur_enum_object
>= This
->pobj
->nb_children
)
676 return DXFILEERR_NOMOREOBJECTS
;
679 if (This
->from_ref
&& (This
->level
>= 1))
681 /* Only 2 levels can be enumerated if the object is obtained from a reference */
683 return DXFILEERR_NOMOREOBJECTS
;
686 if (This
->pobj
->children
[This
->cur_enum_object
]->binary
)
688 IDirectXFileBinaryImpl
*object
;
690 hr
= IDirectXFileBinaryImpl_Create(&object
);
694 *ppChildObj
= (LPDIRECTXFILEOBJECT
)&object
->IDirectXFileBinary_iface
;
696 else if (This
->pobj
->children
[This
->cur_enum_object
]->ptarget
)
698 IDirectXFileDataReferenceImpl
*object
;
700 hr
= IDirectXFileDataReferenceImpl_Create(&object
);
704 object
->ptarget
= This
->pobj
->children
[This
->cur_enum_object
++]->ptarget
;
706 *ppChildObj
= (LPDIRECTXFILEOBJECT
)&object
->IDirectXFileDataReference_iface
;
710 IDirectXFileDataImpl
*object
;
712 hr
= IDirectXFileDataImpl_Create(&object
);
716 object
->pobj
= This
->pobj
->children
[This
->cur_enum_object
++];
717 object
->cur_enum_object
= 0;
718 object
->from_ref
= This
->from_ref
;
719 object
->level
= This
->level
+ 1;
721 *ppChildObj
= (LPDIRECTXFILEOBJECT
)&object
->IDirectXFileData_iface
;
727 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataObject(IDirectXFileData
*iface
, LPDIRECTXFILEDATA data
)
729 FIXME("iface %p, data %p stub!\n", iface
, data
);
731 return DXFILEERR_BADVALUE
;
734 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataReference(IDirectXFileData
*iface
,
735 const char *reference
, const GUID
*guidref
)
737 FIXME("iface %p, reference %s, guid reference %s stub!\n", iface
, debugstr_a(reference
),
738 debugstr_guid(guidref
));
740 return DXFILEERR_BADVALUE
;
743 static HRESULT WINAPI
IDirectXFileDataImpl_AddBinaryObject(IDirectXFileData
*iface
, const char *name
,
744 const GUID
*guid
, const char *mimetype
, void *data
, DWORD size
)
746 FIXME("iface %p, name %s, guid %s, mimetype %s, data %p, size %lu stub!\n", iface
, debugstr_a(name
),
747 debugstr_guid(guid
), debugstr_a(mimetype
), data
, size
);
749 return DXFILEERR_BADVALUE
;
752 static const IDirectXFileDataVtbl IDirectXFileData_Vtbl
=
754 IDirectXFileDataImpl_QueryInterface
,
755 IDirectXFileDataImpl_AddRef
,
756 IDirectXFileDataImpl_Release
,
757 IDirectXFileDataImpl_GetName
,
758 IDirectXFileDataImpl_GetId
,
759 IDirectXFileDataImpl_GetData
,
760 IDirectXFileDataImpl_GetType
,
761 IDirectXFileDataImpl_GetNextObject
,
762 IDirectXFileDataImpl_AddDataObject
,
763 IDirectXFileDataImpl_AddDataReference
,
764 IDirectXFileDataImpl_AddBinaryObject
767 static HRESULT
IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl
** ppObj
)
769 IDirectXFileDataReferenceImpl
* object
;
771 TRACE("(%p)\n", ppObj
);
773 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataReferenceImpl
));
775 return DXFILEERR_BADALLOC
;
777 object
->IDirectXFileDataReference_iface
.lpVtbl
= &IDirectXFileDataReference_Vtbl
;
785 static inline IDirectXFileDataReferenceImpl
*impl_from_IDirectXFileDataReference(IDirectXFileDataReference
*iface
)
787 return CONTAINING_RECORD(iface
, IDirectXFileDataReferenceImpl
, IDirectXFileDataReference_iface
);
790 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_QueryInterface(IDirectXFileDataReference
*iface
,
791 REFIID riid
, void **out
)
793 IDirectXFileDataReferenceImpl
*object
= impl_from_IDirectXFileDataReference(iface
);
795 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
797 if (IsEqualGUID(riid
, &IID_IUnknown
)
798 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
799 || IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
801 *out
= &object
->IDirectXFileDataReference_iface
;
805 /* Do not print an error for interfaces that can be queried to
806 * retrieve the type of the object */
808 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
) && !IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
809 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
810 return E_NOINTERFACE
;
813 IUnknown_AddRef((IUnknown
*)*out
);
817 static ULONG WINAPI
IDirectXFileDataReferenceImpl_AddRef(IDirectXFileDataReference
*iface
)
819 IDirectXFileDataReferenceImpl
*object
= impl_from_IDirectXFileDataReference(iface
);
820 ULONG refcount
= InterlockedIncrement(&object
->ref
);
822 TRACE("%p increasing refcount to %lu.\n", iface
, refcount
);
827 static ULONG WINAPI
IDirectXFileDataReferenceImpl_Release(IDirectXFileDataReference
*iface
)
829 IDirectXFileDataReferenceImpl
*object
= impl_from_IDirectXFileDataReference(iface
);
830 ULONG refcount
= InterlockedDecrement(&object
->ref
);
832 TRACE("%p decreasing refcount to %lu.\n", iface
, refcount
);
835 HeapFree(GetProcessHeap(), 0, object
);
840 /*** IDirectXFileObject methods ***/
841 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetName(IDirectXFileDataReference
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
843 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
846 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
849 return DXFILEERR_BADVALUE
;
851 len
= strlen(This
->ptarget
->name
);
856 if (*pdwBufLen
< len
)
857 return DXFILEERR_BADVALUE
;
858 CopyMemory(pstrNameBuf
, This
->ptarget
->name
, len
);
859 /* Even if we return a size of 0, an empty string with a null byte must be returned */
860 if (*pdwBufLen
&& !len
)
868 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetId(IDirectXFileDataReference
*iface
,
871 IDirectXFileDataReferenceImpl
*object
= impl_from_IDirectXFileDataReference(iface
);
873 TRACE("iface %p, guid %p.\n", iface
, guid
);
876 return DXFILEERR_BADVALUE
;
878 *guid
= object
->ptarget
->class_id
;
883 /*** IDirectXFileDataReference ***/
884 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
886 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
887 IDirectXFileDataImpl
*object
;
890 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
893 return DXFILEERR_BADVALUE
;
895 hr
= IDirectXFileDataImpl_Create(&object
);
899 object
->pobj
= This
->ptarget
;
900 object
->cur_enum_object
= 0;
902 object
->from_ref
= TRUE
;
904 *ppDataObj
= &object
->IDirectXFileData_iface
;
909 static const IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl
=
911 IDirectXFileDataReferenceImpl_QueryInterface
,
912 IDirectXFileDataReferenceImpl_AddRef
,
913 IDirectXFileDataReferenceImpl_Release
,
914 IDirectXFileDataReferenceImpl_GetName
,
915 IDirectXFileDataReferenceImpl_GetId
,
916 IDirectXFileDataReferenceImpl_Resolve
919 static HRESULT
IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl
** ppObj
)
921 IDirectXFileEnumObjectImpl
* object
;
923 TRACE("(%p)\n", ppObj
);
925 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileEnumObjectImpl
));
927 return DXFILEERR_BADALLOC
;
929 object
->IDirectXFileEnumObject_iface
.lpVtbl
= &IDirectXFileEnumObject_Vtbl
;
937 static inline IDirectXFileEnumObjectImpl
*impl_from_IDirectXFileEnumObject(IDirectXFileEnumObject
*iface
)
939 return CONTAINING_RECORD(iface
, IDirectXFileEnumObjectImpl
, IDirectXFileEnumObject_iface
);
942 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_QueryInterface(IDirectXFileEnumObject
*iface
,
943 REFIID riid
, void **out
)
945 IDirectXFileEnumObjectImpl
*object
= impl_from_IDirectXFileEnumObject(iface
);
947 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
949 if (IsEqualGUID(riid
, &IID_IUnknown
)
950 || IsEqualGUID(riid
, &IID_IDirectXFileEnumObject
))
952 *out
= &object
->IDirectXFileEnumObject_iface
;
957 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
958 return E_NOINTERFACE
;
961 IUnknown_AddRef((IUnknown
*)*out
);
965 static ULONG WINAPI
IDirectXFileEnumObjectImpl_AddRef(IDirectXFileEnumObject
*iface
)
967 IDirectXFileEnumObjectImpl
*object
= impl_from_IDirectXFileEnumObject(iface
);
968 ULONG refcount
= InterlockedIncrement(&object
->ref
);
970 TRACE("%p increasing refcount to %lu.\n", iface
, refcount
);
975 static ULONG WINAPI
IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject
*iface
)
977 IDirectXFileEnumObjectImpl
*object
= impl_from_IDirectXFileEnumObject(iface
);
978 ULONG refcount
= InterlockedDecrement(&object
->ref
);
980 TRACE("%p decreasing refcount to %lu.\n", iface
, refcount
);
986 for (i
= 0; i
< object
->nb_xobjects
; ++i
)
987 IDirectXFileData_Release(object
->pRefObjects
[i
]);
988 if (object
->mapped_memory
)
989 UnmapViewOfFile(object
->mapped_memory
);
990 HeapFree(GetProcessHeap(), 0, object
->decomp_buffer
);
991 HeapFree(GetProcessHeap(), 0, object
);
997 /*** IDirectXFileEnumObject methods ***/
998 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
1000 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
1001 IDirectXFileDataImpl
* object
;
1009 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
1011 if (This
->nb_xobjects
>= MAX_OBJECTS
)
1013 ERR("Too many objects\n");
1014 return DXFILEERR_NOMOREOBJECTS
;
1017 /* Check if there are templates defined before the object */
1018 if (!parse_templates(&This
->buf
, TRUE
))
1019 return DXFILEERR_PARSEERROR
;
1021 if (!This
->buf
.rem_bytes
)
1022 return DXFILEERR_NOMOREOBJECTS
;
1024 hr
= IDirectXFileDataImpl_Create(&object
);
1028 object
->pobj
= HeapAlloc(GetProcessHeap(), 0, sizeof(xobject
)*MAX_SUBOBJECTS
);
1031 hr
= DXFILEERR_BADALLOC
;
1035 object
->pstrings
= HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER
);
1036 if (!object
->pstrings
)
1038 hr
= DXFILEERR_BADALLOC
;
1042 object
->cur_enum_object
= 0;
1044 object
->from_ref
= FALSE
;
1046 This
->buf
.pxo_globals
= This
->xobjects
;
1047 This
->buf
.nb_pxo_globals
= This
->nb_xobjects
;
1048 This
->buf
.level
= 0;
1049 This
->buf
.pdata
= NULL
;
1050 This
->buf
.capacity
= 0;
1051 This
->buf
.cur_pos_data
= 0;
1052 This
->buf
.cur_pstrings
= This
->buf
.pstrings
= object
->pstrings
;
1053 This
->buf
.pxo
= This
->xobjects
[This
->nb_xobjects
] = This
->buf
.pxo_tab
= object
->pobj
;
1054 This
->buf
.pxo
->pdata
= NULL
;
1055 This
->buf
.pxo
->nb_subobjects
= 1;
1057 if (!parse_object(&This
->buf
))
1059 WARN("Object is not correct\n");
1060 hr
= DXFILEERR_PARSEERROR
;
1064 *ppDataObj
= &object
->IDirectXFileData_iface
;
1066 /* Get a reference to created object */
1067 This
->pRefObjects
[This
->nb_xobjects
] = &object
->IDirectXFileData_iface
;
1068 IDirectXFileData_AddRef(This
->pRefObjects
[This
->nb_xobjects
]);
1070 This
->nb_xobjects
++;
1076 IDirectXFileData_Release(&object
->IDirectXFileData_iface
);
1081 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectById(IDirectXFileEnumObject
*iface
,
1082 REFGUID guid
, LPDIRECTXFILEDATA
*data
)
1084 FIXME("iface %p, guid %s, data %p stub!\n", iface
, debugstr_guid(guid
), data
);
1086 return DXFILEERR_BADVALUE
;
1089 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectByName(IDirectXFileEnumObject
*iface
,
1090 const char *name
, LPDIRECTXFILEDATA
*data
)
1092 FIXME("iface %p, name %s, data %p stub!\n", iface
, debugstr_a(name
), data
);
1094 return DXFILEERR_BADVALUE
;
1097 static const IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl
=
1099 IDirectXFileEnumObjectImpl_QueryInterface
,
1100 IDirectXFileEnumObjectImpl_AddRef
,
1101 IDirectXFileEnumObjectImpl_Release
,
1102 IDirectXFileEnumObjectImpl_GetNextDataObject
,
1103 IDirectXFileEnumObjectImpl_GetDataObjectById
,
1104 IDirectXFileEnumObjectImpl_GetDataObjectByName
1107 static HRESULT
IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl
** ppObj
)
1109 IDirectXFileSaveObjectImpl
* object
;
1111 TRACE("(%p)\n", ppObj
);
1113 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileSaveObjectImpl
));
1115 return DXFILEERR_BADALLOC
;
1117 object
->IDirectXFileSaveObject_iface
.lpVtbl
= &IDirectXFileSaveObject_Vtbl
;
1125 static inline IDirectXFileSaveObjectImpl
*impl_from_IDirectXFileSaveObject(IDirectXFileSaveObject
*iface
)
1127 return CONTAINING_RECORD(iface
, IDirectXFileSaveObjectImpl
, IDirectXFileSaveObject_iface
);
1130 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_QueryInterface(IDirectXFileSaveObject
*iface
,
1131 REFIID riid
, void **out
)
1133 IDirectXFileSaveObjectImpl
*object
= impl_from_IDirectXFileSaveObject(iface
);
1135 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
1137 if (IsEqualGUID(riid
, &IID_IUnknown
)
1138 || IsEqualGUID(riid
, &IID_IDirectXFileSaveObject
))
1140 *out
= &object
->IDirectXFileSaveObject_iface
;
1144 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1145 return E_NOINTERFACE
;
1148 IUnknown_AddRef((IUnknown
*)*out
);
1152 static ULONG WINAPI
IDirectXFileSaveObjectImpl_AddRef(IDirectXFileSaveObject
*iface
)
1154 IDirectXFileSaveObjectImpl
*object
= impl_from_IDirectXFileSaveObject(iface
);
1155 ULONG refcount
= InterlockedIncrement(&object
->ref
);
1157 TRACE("%p increasing refcount to %lu.\n", iface
, refcount
);
1162 static ULONG WINAPI
IDirectXFileSaveObjectImpl_Release(IDirectXFileSaveObject
*iface
)
1164 IDirectXFileSaveObjectImpl
*object
= impl_from_IDirectXFileSaveObject(iface
);
1165 ULONG refcount
= InterlockedDecrement(&object
->ref
);
1167 TRACE("%p decreasing refcount to %lu.\n", iface
, refcount
);
1170 HeapFree(GetProcessHeap(), 0, object
);
1175 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveTemplates(IDirectXFileSaveObject
*iface
,
1176 DWORD count
, const GUID
**templates
)
1178 FIXME("iface %p, count %lu, templates %p stub!\n", iface
, count
, templates
);
1183 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_CreateDataObject(IDirectXFileSaveObject
*iface
, REFGUID
template,
1184 const char *name
, const GUID
*guid
, DWORD size
, void *data
, LPDIRECTXFILEDATA
*dataobj
)
1186 FIXME("iface %p, template %s, name %s, guid %s, size %lu, data %p, dataobj %p stub!\n",
1187 iface
, debugstr_guid(template), debugstr_a(name
), debugstr_guid(guid
), size
, data
, dataobj
);
1189 return DXFILEERR_BADVALUE
;
1192 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveData(IDirectXFileSaveObject
*iface
, LPDIRECTXFILEDATA data
)
1194 FIXME("iface %p, data %p stub!\n", iface
, data
);
1196 return DXFILEERR_BADVALUE
;
1199 static const IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl
=
1201 IDirectXFileSaveObjectImpl_QueryInterface
,
1202 IDirectXFileSaveObjectImpl_AddRef
,
1203 IDirectXFileSaveObjectImpl_Release
,
1204 IDirectXFileSaveObjectImpl_SaveTemplates
,
1205 IDirectXFileSaveObjectImpl_CreateDataObject
,
1206 IDirectXFileSaveObjectImpl_SaveData