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 "d3dxof_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(d3dxof
);
24 WINE_DECLARE_DEBUG_CHANNEL(d3dxof_dump
);
26 static const struct IDirectXFileVtbl IDirectXFile_Vtbl
;
27 static const struct IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl
;
28 static const struct IDirectXFileDataVtbl IDirectXFileData_Vtbl
;
29 static const struct IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl
;
30 static const struct IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl
;
31 static const struct IDirectXFileObjectVtbl IDirectXFileObject_Vtbl
;
32 static const struct IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl
;
34 static HRESULT
IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl
** ppObj
);
35 static HRESULT
IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl
** ppObj
);
36 static HRESULT
IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl
** ppObj
);
38 #define TOKEN_DWORD 41
39 #define TOKEN_FLOAT 42
41 HRESULT
IDirectXFileImpl_Create(IUnknown
* pUnkOuter
, LPVOID
* ppObj
)
43 IDirectXFileImpl
* object
;
45 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
47 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileImpl
));
50 ERR("Out of memory\n");
51 return DXFILEERR_BADALLOC
;
54 object
->IDirectXFile_iface
.lpVtbl
= &IDirectXFile_Vtbl
;
57 /* Reserve first template to handle the case sensitive legacy type indexColor */
58 object
->nb_xtemplates
= 1;
59 strcpy(object
->xtemplates
[0].name
, "indexColor");
60 object
->xtemplates
[0].nb_members
= 2;
61 object
->xtemplates
[0].members
[0].type
= TOKEN_DWORD
;
62 object
->xtemplates
[0].members
[0].nb_dims
= 0;
63 object
->xtemplates
[0].members
[1].type
= TOKEN_FLOAT
;
64 object
->xtemplates
[0].members
[1].nb_dims
= 1;
65 object
->xtemplates
[0].members
[1].dim_fixed
[0] = TRUE
;
66 object
->xtemplates
[0].members
[1].dim_value
[0] = 4;
68 *ppObj
= &object
->IDirectXFile_iface
;
73 static inline IDirectXFileImpl
*impl_from_IDirectXFile(IDirectXFile
*iface
)
75 return CONTAINING_RECORD(iface
, IDirectXFileImpl
, IDirectXFile_iface
);
78 /*** IUnknown methods ***/
79 static HRESULT WINAPI
IDirectXFileImpl_QueryInterface(IDirectXFile
* iface
, REFIID riid
, void** ppvObject
)
81 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
83 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
85 if (IsEqualGUID(riid
, &IID_IUnknown
)
86 || IsEqualGUID(riid
, &IID_IDirectXFile
))
88 IUnknown_AddRef(iface
);
89 *ppvObject
= &This
->IDirectXFile_iface
;
93 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
97 static ULONG WINAPI
IDirectXFileImpl_AddRef(IDirectXFile
* iface
)
99 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
100 ULONG ref
= InterlockedIncrement(&This
->ref
);
102 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
107 static ULONG WINAPI
IDirectXFileImpl_Release(IDirectXFile
* iface
)
109 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
110 ULONG ref
= InterlockedDecrement(&This
->ref
);
112 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
115 HeapFree(GetProcessHeap(), 0, This
);
120 /*** IDirectXFile methods ***/
121 static HRESULT WINAPI
IDirectXFileImpl_CreateEnumObject(IDirectXFile
* iface
, LPVOID pvSource
, DXFILELOADOPTIONS dwLoadOptions
, LPDIRECTXFILEENUMOBJECT
* ppEnumObj
)
123 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
124 IDirectXFileEnumObjectImpl
* object
;
129 TRACE("(%p/%p)->(%p,%x,%p)\n", This
, iface
, pvSource
, dwLoadOptions
, ppEnumObj
);
132 return DXFILEERR_BADVALUE
;
134 /* Only lowest 4 bits are relevant in DXFILELOADOPTIONS */
135 dwLoadOptions
&= 0xF;
137 hr
= IDirectXFileEnumObjectImpl_Create(&object
);
141 if (dwLoadOptions
== DXFILELOAD_FROMFILE
)
143 HANDLE hFile
, file_mapping
;
145 TRACE("Open source file '%s'\n", (char*)pvSource
);
147 hFile
= CreateFileA(pvSource
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
148 if (hFile
== INVALID_HANDLE_VALUE
)
150 TRACE("File '%s' not found\n", (char*)pvSource
);
151 return DXFILEERR_FILENOTFOUND
;
154 file_size
= GetFileSize(hFile
, NULL
);
156 file_mapping
= CreateFileMappingA(hFile
, NULL
, PAGE_READONLY
, 0, 0, NULL
);
160 hr
= DXFILEERR_BADFILETYPE
;
164 object
->mapped_memory
= MapViewOfFile(file_mapping
, FILE_MAP_READ
, 0, 0, 0);
165 CloseHandle(file_mapping
);
166 if (!object
->mapped_memory
)
168 hr
= DXFILEERR_BADFILETYPE
;
171 file_buffer
= object
->mapped_memory
;
173 else if (dwLoadOptions
== DXFILELOAD_FROMRESOURCE
)
176 HGLOBAL resource_data
;
177 LPDXFILELOADRESOURCE lpdxflr
= pvSource
;
179 TRACE("Source in resource (module = %p, name = %s, type = %s)\n", lpdxflr
->hModule
, debugstr_a(lpdxflr
->lpName
), debugstr_a(lpdxflr
->lpType
));
181 resource_info
= FindResourceA(lpdxflr
->hModule
, lpdxflr
->lpName
, lpdxflr
->lpType
);
184 hr
= DXFILEERR_RESOURCENOTFOUND
;
188 file_size
= SizeofResource(lpdxflr
->hModule
, resource_info
);
190 resource_data
= LoadResource(lpdxflr
->hModule
, resource_info
);
193 hr
= DXFILEERR_BADRESOURCE
;
197 file_buffer
= LockResource(resource_data
);
200 hr
= DXFILEERR_BADRESOURCE
;
204 else if (dwLoadOptions
== DXFILELOAD_FROMMEMORY
)
206 LPDXFILELOADMEMORY lpdxflm
= pvSource
;
208 TRACE("Source in memory at %p with size %d\n", lpdxflm
->lpMemory
, lpdxflm
->dSize
);
210 file_buffer
= lpdxflm
->lpMemory
;
211 file_size
= lpdxflm
->dSize
;
215 FIXME("Source type %d is not handled yet\n", dwLoadOptions
);
216 hr
= DXFILEERR_NOTDONEYET
;
220 TRACE("File size is %d bytes\n", file_size
);
222 if (TRACE_ON(d3dxof_dump
))
227 sprintf(tmp
, "file%05u.x", num
++);
229 file
= CreateFileA(tmp
, GENERIC_WRITE
, FILE_SHARE_READ
, NULL
, CREATE_ALWAYS
, 0, NULL
);
230 if (file
!= INVALID_HANDLE_VALUE
)
232 WriteFile(file
, file_buffer
, file_size
, NULL
, NULL
);
237 object
->pDirectXFile
= This
;
239 object
->buf
.pdxf
= This
;
240 object
->buf
.token_present
= FALSE
;
241 object
->buf
.buffer
= file_buffer
;
242 object
->buf
.rem_bytes
= file_size
;
243 hr
= parse_header(&object
->buf
, &object
->decomp_buffer
);
247 /* Check if there are templates defined before the object */
248 if (!parse_templates(&object
->buf
, TRUE
))
250 hr
= DXFILEERR_PARSEERROR
;
254 if (TRACE_ON(d3dxof
))
257 TRACE("Registered templates (%d):\n", This
->nb_xtemplates
);
258 for (i
= 1; i
< This
->nb_xtemplates
; i
++)
259 DPRINTF("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
262 *ppEnumObj
= &object
->IDirectXFileEnumObject_iface
;
267 IDirectXFileEnumObject_Release(&object
->IDirectXFileEnumObject_iface
);
273 static HRESULT WINAPI
IDirectXFileImpl_CreateSaveObject(IDirectXFile
* iface
, LPCSTR szFileName
, DXFILEFORMAT dwFileFormat
, LPDIRECTXFILESAVEOBJECT
* ppSaveObj
)
275 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
276 IDirectXFileSaveObjectImpl
*object
;
279 FIXME("(%p/%p)->(%s,%x,%p) partial stub!\n", This
, iface
, szFileName
, dwFileFormat
, ppSaveObj
);
281 if (!szFileName
|| !ppSaveObj
)
284 hr
= IDirectXFileSaveObjectImpl_Create(&object
);
286 *ppSaveObj
= &object
->IDirectXFileSaveObject_iface
;
290 static HRESULT WINAPI
IDirectXFileImpl_RegisterTemplates(IDirectXFile
* iface
, LPVOID pvData
, DWORD cbSize
)
292 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
295 LPBYTE decomp_buffer
= NULL
;
297 ZeroMemory(&buf
, sizeof(buf
));
299 buf
.rem_bytes
= cbSize
;
302 TRACE("(%p/%p)->(%p,%d)\n", This
, iface
, pvData
, cbSize
);
305 return DXFILEERR_BADVALUE
;
307 if (TRACE_ON(d3dxof_dump
))
312 sprintf(tmp
, "template%05u.x", num
++);
314 file
= CreateFileA(tmp
, GENERIC_WRITE
, FILE_SHARE_READ
, NULL
, CREATE_ALWAYS
, 0, NULL
);
315 if (file
!= INVALID_HANDLE_VALUE
)
317 WriteFile(file
, pvData
, cbSize
, NULL
, NULL
);
322 hr
= parse_header(&buf
, &decomp_buffer
);
326 if (!parse_templates(&buf
, FALSE
))
328 hr
= DXFILEERR_PARSEERROR
;
332 if (TRACE_ON(d3dxof
))
335 TRACE("Registered templates (%d):\n", This
->nb_xtemplates
);
336 for (i
= 1; i
< This
->nb_xtemplates
; i
++)
337 DPRINTF("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
342 HeapFree(GetProcessHeap(), 0, decomp_buffer
);
346 static const IDirectXFileVtbl IDirectXFile_Vtbl
=
348 IDirectXFileImpl_QueryInterface
,
349 IDirectXFileImpl_AddRef
,
350 IDirectXFileImpl_Release
,
351 IDirectXFileImpl_CreateEnumObject
,
352 IDirectXFileImpl_CreateSaveObject
,
353 IDirectXFileImpl_RegisterTemplates
356 static HRESULT
IDirectXFileBinaryImpl_Create(IDirectXFileBinaryImpl
** ppObj
)
358 IDirectXFileBinaryImpl
* object
;
360 TRACE("(%p)\n", ppObj
);
362 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileBinaryImpl
));
365 ERR("Out of memory\n");
366 return DXFILEERR_BADALLOC
;
369 object
->IDirectXFileBinary_iface
.lpVtbl
= &IDirectXFileBinary_Vtbl
;
377 static inline IDirectXFileBinaryImpl
*impl_from_IDirectXFileBinary(IDirectXFileBinary
*iface
)
379 return CONTAINING_RECORD(iface
, IDirectXFileBinaryImpl
, IDirectXFileBinary_iface
);
382 /*** IUnknown methods ***/
383 static HRESULT WINAPI
IDirectXFileBinaryImpl_QueryInterface(IDirectXFileBinary
* iface
, REFIID riid
, void** ppvObject
)
385 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
387 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
389 if (IsEqualGUID(riid
, &IID_IUnknown
)
390 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
391 || IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
393 IUnknown_AddRef(iface
);
394 *ppvObject
= &This
->IDirectXFileBinary_iface
;
398 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
399 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
)
400 && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
401 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
403 return E_NOINTERFACE
;
406 static ULONG WINAPI
IDirectXFileBinaryImpl_AddRef(IDirectXFileBinary
* iface
)
408 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
409 ULONG ref
= InterlockedIncrement(&This
->ref
);
411 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
416 static ULONG WINAPI
IDirectXFileBinaryImpl_Release(IDirectXFileBinary
* iface
)
418 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
419 ULONG ref
= InterlockedDecrement(&This
->ref
);
421 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
424 HeapFree(GetProcessHeap(), 0, This
);
429 /*** IDirectXFileObject methods ***/
430 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetName(IDirectXFileBinary
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
433 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
435 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
437 return DXFILEERR_BADVALUE
;
440 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetId(IDirectXFileBinary
* iface
, LPGUID pGuid
)
442 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
444 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pGuid
);
446 return DXFILEERR_BADVALUE
;
449 /*** IDirectXFileBinary methods ***/
450 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetSize(IDirectXFileBinary
* iface
, DWORD
* pcbSize
)
452 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
454 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pcbSize
);
456 return DXFILEERR_BADVALUE
;
459 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetMimeType(IDirectXFileBinary
* iface
, LPCSTR
* pszMimeType
)
461 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
463 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pszMimeType
);
465 return DXFILEERR_BADVALUE
;
468 static HRESULT WINAPI
IDirectXFileBinaryImpl_Read(IDirectXFileBinary
* iface
, LPVOID pvData
, DWORD cbSize
, LPDWORD pcbRead
)
470 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
472 FIXME("(%p/%p)->(%p, %d, %p) stub!\n", This
, iface
, pvData
, cbSize
, pcbRead
);
474 return DXFILEERR_BADVALUE
;
477 static const IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl
=
479 IDirectXFileBinaryImpl_QueryInterface
,
480 IDirectXFileBinaryImpl_AddRef
,
481 IDirectXFileBinaryImpl_Release
,
482 IDirectXFileBinaryImpl_GetName
,
483 IDirectXFileBinaryImpl_GetId
,
484 IDirectXFileBinaryImpl_GetSize
,
485 IDirectXFileBinaryImpl_GetMimeType
,
486 IDirectXFileBinaryImpl_Read
489 static HRESULT
IDirectXFileDataImpl_Create(IDirectXFileDataImpl
** ppObj
)
491 IDirectXFileDataImpl
* object
;
493 TRACE("(%p)\n", ppObj
);
495 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataImpl
));
498 ERR("Out of memory\n");
499 return DXFILEERR_BADALLOC
;
502 object
->IDirectXFileData_iface
.lpVtbl
= &IDirectXFileData_Vtbl
;
510 static inline IDirectXFileDataImpl
*impl_from_IDirectXFileData(IDirectXFileData
*iface
)
512 return CONTAINING_RECORD(iface
, IDirectXFileDataImpl
, IDirectXFileData_iface
);
515 /*** IUnknown methods ***/
516 static HRESULT WINAPI
IDirectXFileDataImpl_QueryInterface(IDirectXFileData
* iface
, REFIID riid
, void** ppvObject
)
518 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
520 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
522 if (IsEqualGUID(riid
, &IID_IUnknown
)
523 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
524 || IsEqualGUID(riid
, &IID_IDirectXFileData
))
526 IUnknown_AddRef(iface
);
527 *ppvObject
= &This
->IDirectXFileData_iface
;
531 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
532 if (!IsEqualGUID(riid
, &IID_IDirectXFileBinary
)
533 && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
534 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
536 return E_NOINTERFACE
;
539 static ULONG WINAPI
IDirectXFileDataImpl_AddRef(IDirectXFileData
* iface
)
541 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
542 ULONG ref
= InterlockedIncrement(&This
->ref
);
544 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
549 static ULONG WINAPI
IDirectXFileDataImpl_Release(IDirectXFileData
* iface
)
551 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
552 ULONG ref
= InterlockedDecrement(&This
->ref
);
554 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
558 if (!This
->level
&& !This
->from_ref
)
560 HeapFree(GetProcessHeap(), 0, This
->pstrings
);
563 HeapFree(GetProcessHeap(), 0, This
->pobj
->pdata
);
564 HeapFree(GetProcessHeap(), 0, This
->pobj
);
567 HeapFree(GetProcessHeap(), 0, This
);
573 /*** IDirectXFileObject methods ***/
574 static HRESULT WINAPI
IDirectXFileDataImpl_GetName(IDirectXFileData
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
576 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
579 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
582 return DXFILEERR_BADVALUE
;
584 len
= strlen(This
->pobj
->name
);
589 if (*pdwBufLen
< len
)
590 return DXFILEERR_BADVALUE
;
591 CopyMemory(pstrNameBuf
, This
->pobj
->name
, len
);
592 /* Even if we return a size of 0, an empty string with a null byte must be returned */
593 if (*pdwBufLen
&& !len
)
601 static HRESULT WINAPI
IDirectXFileDataImpl_GetId(IDirectXFileData
* iface
, LPGUID pGuid
)
603 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
605 TRACE("(%p/%p)->(%p)\n", This
, iface
, pGuid
);
608 return DXFILEERR_BADVALUE
;
610 memcpy(pGuid
, &This
->pobj
->class_id
, 16);
615 /*** IDirectXFileData methods ***/
616 static HRESULT WINAPI
IDirectXFileDataImpl_GetData(IDirectXFileData
* iface
, LPCSTR szMember
, DWORD
* pcbSize
, void** ppvData
)
618 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
620 TRACE("(%p/%p)->(%s,%p,%p)\n", This
, iface
, debugstr_a(szMember
), pcbSize
, ppvData
);
622 if (!pcbSize
|| !ppvData
)
623 return DXFILEERR_BADVALUE
;
628 for (i
= 0; i
< This
->pobj
->nb_members
; i
++)
629 if (!strcmp(This
->pobj
->members
[i
].name
, szMember
))
631 if (i
== This
->pobj
->nb_members
)
633 WARN("Unknown member '%s'\n", szMember
);
634 return DXFILEERR_BADDATAREFERENCE
;
636 *pcbSize
= This
->pobj
->members
[i
].size
;
637 *ppvData
= This
->pobj
->root
->pdata
+ This
->pobj
->members
[i
].start
;
641 *pcbSize
= This
->pobj
->size
;
642 *ppvData
= This
->pobj
->root
->pdata
+ This
->pobj
->pos_data
;
648 static HRESULT WINAPI
IDirectXFileDataImpl_GetType(IDirectXFileData
* iface
, const GUID
** pguid
)
650 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
653 TRACE("(%p/%p)->(%p)\n", This
, iface
, pguid
);
656 return DXFILEERR_BADVALUE
;
658 memcpy(&guid
, &This
->pobj
->type
, 16);
664 static HRESULT WINAPI
IDirectXFileDataImpl_GetNextObject(IDirectXFileData
* iface
, LPDIRECTXFILEOBJECT
* ppChildObj
)
667 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
669 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppChildObj
);
671 if (This
->cur_enum_object
>= This
->pobj
->nb_children
)
674 return DXFILEERR_NOMOREOBJECTS
;
677 if (This
->from_ref
&& (This
->level
>= 1))
679 /* Only 2 levels can be enumerated if the object is obtained from a reference */
681 return DXFILEERR_NOMOREOBJECTS
;
684 if (This
->pobj
->children
[This
->cur_enum_object
]->binary
)
686 IDirectXFileBinaryImpl
*object
;
688 hr
= IDirectXFileBinaryImpl_Create(&object
);
692 *ppChildObj
= (LPDIRECTXFILEOBJECT
)&object
->IDirectXFileBinary_iface
;
694 else if (This
->pobj
->children
[This
->cur_enum_object
]->ptarget
)
696 IDirectXFileDataReferenceImpl
*object
;
698 hr
= IDirectXFileDataReferenceImpl_Create(&object
);
702 object
->ptarget
= This
->pobj
->children
[This
->cur_enum_object
++]->ptarget
;
704 *ppChildObj
= (LPDIRECTXFILEOBJECT
)&object
->IDirectXFileDataReference_iface
;
708 IDirectXFileDataImpl
*object
;
710 hr
= IDirectXFileDataImpl_Create(&object
);
714 object
->pobj
= This
->pobj
->children
[This
->cur_enum_object
++];
715 object
->cur_enum_object
= 0;
716 object
->from_ref
= This
->from_ref
;
717 object
->level
= This
->level
+ 1;
719 *ppChildObj
= (LPDIRECTXFILEOBJECT
)&object
->IDirectXFileData_iface
;
725 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataObject(IDirectXFileData
* iface
, LPDIRECTXFILEDATA pDataObj
)
727 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
729 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pDataObj
);
731 return DXFILEERR_BADVALUE
;
734 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataReference(IDirectXFileData
* iface
, LPCSTR szRef
, const GUID
* pguidRef
)
736 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
738 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szRef
, pguidRef
);
740 return DXFILEERR_BADVALUE
;
743 static HRESULT WINAPI
IDirectXFileDataImpl_AddBinaryObject(IDirectXFileData
* iface
, LPCSTR szName
, const GUID
* pguid
, LPCSTR szMimeType
, LPVOID pvData
, DWORD cbSize
)
745 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
747 FIXME("(%p/%p)->(%s,%p,%s,%p,%d) stub!\n", This
, iface
, szName
, pguid
, szMimeType
, pvData
, cbSize
);
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
));
776 ERR("Out of memory\n");
777 return DXFILEERR_BADALLOC
;
780 object
->IDirectXFileDataReference_iface
.lpVtbl
= &IDirectXFileDataReference_Vtbl
;
788 static inline IDirectXFileDataReferenceImpl
*impl_from_IDirectXFileDataReference(IDirectXFileDataReference
*iface
)
790 return CONTAINING_RECORD(iface
, IDirectXFileDataReferenceImpl
, IDirectXFileDataReference_iface
);
793 /*** IUnknown methods ***/
794 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_QueryInterface(IDirectXFileDataReference
* iface
, REFIID riid
, void** ppvObject
)
796 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
798 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
800 if (IsEqualGUID(riid
, &IID_IUnknown
)
801 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
802 || IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
804 IUnknown_AddRef(iface
);
805 *ppvObject
= &This
->IDirectXFileDataReference_iface
;
809 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
810 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
)
811 && !IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
812 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
814 return E_NOINTERFACE
;
817 static ULONG WINAPI
IDirectXFileDataReferenceImpl_AddRef(IDirectXFileDataReference
* iface
)
819 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
820 ULONG ref
= InterlockedIncrement(&This
->ref
);
822 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
827 static ULONG WINAPI
IDirectXFileDataReferenceImpl_Release(IDirectXFileDataReference
* iface
)
829 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
830 ULONG ref
= InterlockedDecrement(&This
->ref
);
832 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
835 HeapFree(GetProcessHeap(), 0, This
);
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
, LPGUID pGuid
)
870 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
872 TRACE("(%p/%p)->(%p)\n", This
, iface
, pGuid
);
875 return DXFILEERR_BADVALUE
;
877 memcpy(pGuid
, &This
->ptarget
->class_id
, 16);
882 /*** IDirectXFileDataReference ***/
883 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
885 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
886 IDirectXFileDataImpl
*object
;
889 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
892 return DXFILEERR_BADVALUE
;
894 hr
= IDirectXFileDataImpl_Create(&object
);
898 object
->pobj
= This
->ptarget
;
899 object
->cur_enum_object
= 0;
901 object
->from_ref
= TRUE
;
903 *ppDataObj
= (LPDIRECTXFILEDATA
)object
;
908 static const IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl
=
910 IDirectXFileDataReferenceImpl_QueryInterface
,
911 IDirectXFileDataReferenceImpl_AddRef
,
912 IDirectXFileDataReferenceImpl_Release
,
913 IDirectXFileDataReferenceImpl_GetName
,
914 IDirectXFileDataReferenceImpl_GetId
,
915 IDirectXFileDataReferenceImpl_Resolve
918 static HRESULT
IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl
** ppObj
)
920 IDirectXFileEnumObjectImpl
* object
;
922 TRACE("(%p)\n", ppObj
);
924 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileEnumObjectImpl
));
927 ERR("Out of memory\n");
928 return DXFILEERR_BADALLOC
;
931 object
->IDirectXFileEnumObject_iface
.lpVtbl
= &IDirectXFileEnumObject_Vtbl
;
939 static inline IDirectXFileEnumObjectImpl
*impl_from_IDirectXFileEnumObject(IDirectXFileEnumObject
*iface
)
941 return CONTAINING_RECORD(iface
, IDirectXFileEnumObjectImpl
, IDirectXFileEnumObject_iface
);
944 /*** IUnknown methods ***/
945 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_QueryInterface(IDirectXFileEnumObject
* iface
, REFIID riid
, void** ppvObject
)
947 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
949 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
951 if (IsEqualGUID(riid
, &IID_IUnknown
)
952 || IsEqualGUID(riid
, &IID_IDirectXFileEnumObject
))
954 IUnknown_AddRef(iface
);
955 *ppvObject
= &This
->IDirectXFileEnumObject_iface
;
959 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
960 return E_NOINTERFACE
;
963 static ULONG WINAPI
IDirectXFileEnumObjectImpl_AddRef(IDirectXFileEnumObject
* iface
)
965 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
966 ULONG ref
= InterlockedIncrement(&This
->ref
);
968 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
973 static ULONG WINAPI
IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject
* iface
)
975 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
976 ULONG ref
= InterlockedDecrement(&This
->ref
);
978 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
983 for (i
= 0; i
< This
->nb_xobjects
; i
++)
984 IDirectXFileData_Release(This
->pRefObjects
[i
]);
985 if (This
->mapped_memory
)
986 UnmapViewOfFile(This
->mapped_memory
);
987 HeapFree(GetProcessHeap(), 0, This
->decomp_buffer
);
988 HeapFree(GetProcessHeap(), 0, This
);
994 /*** IDirectXFileEnumObject methods ***/
995 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
997 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
998 IDirectXFileDataImpl
* object
;
1006 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
1008 if (This
->nb_xobjects
>= MAX_OBJECTS
)
1010 ERR("Too many objects\n");
1011 return DXFILEERR_NOMOREOBJECTS
;
1014 /* Check if there are templates defined before the object */
1015 if (!parse_templates(&This
->buf
, TRUE
))
1016 return DXFILEERR_PARSEERROR
;
1018 if (!This
->buf
.rem_bytes
)
1019 return DXFILEERR_NOMOREOBJECTS
;
1021 hr
= IDirectXFileDataImpl_Create(&object
);
1025 object
->pobj
= HeapAlloc(GetProcessHeap(), 0, sizeof(xobject
)*MAX_SUBOBJECTS
);
1028 ERR("Out of memory\n");
1029 hr
= DXFILEERR_BADALLOC
;
1033 object
->pstrings
= HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER
);
1034 if (!object
->pstrings
)
1036 ERR("Out of memory\n");
1037 hr
= DXFILEERR_BADALLOC
;
1041 object
->cur_enum_object
= 0;
1043 object
->from_ref
= FALSE
;
1045 This
->buf
.pxo_globals
= This
->xobjects
;
1046 This
->buf
.nb_pxo_globals
= This
->nb_xobjects
;
1047 This
->buf
.level
= 0;
1048 This
->buf
.pdata
= NULL
;
1049 This
->buf
.capacity
= 0;
1050 This
->buf
.cur_pos_data
= 0;
1051 This
->buf
.cur_pstrings
= This
->buf
.pstrings
= object
->pstrings
;
1052 This
->buf
.pxo
= This
->xobjects
[This
->nb_xobjects
] = This
->buf
.pxo_tab
= object
->pobj
;
1053 This
->buf
.pxo
->pdata
= NULL
;
1054 This
->buf
.pxo
->nb_subobjects
= 1;
1056 if (!parse_object(&This
->buf
))
1058 WARN("Object is not correct\n");
1059 hr
= DXFILEERR_PARSEERROR
;
1063 *ppDataObj
= (LPDIRECTXFILEDATA
)object
;
1065 /* Get a reference to created object */
1066 This
->pRefObjects
[This
->nb_xobjects
] = (LPDIRECTXFILEDATA
)object
;
1067 IDirectXFileData_AddRef(This
->pRefObjects
[This
->nb_xobjects
]);
1069 This
->nb_xobjects
++;
1075 IDirectXFileData_Release(&object
->IDirectXFileData_iface
);
1080 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectById(IDirectXFileEnumObject
* iface
, REFGUID rguid
, LPDIRECTXFILEDATA
* ppDataObj
)
1082 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
1084 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, rguid
, ppDataObj
);
1086 return DXFILEERR_BADVALUE
;
1089 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectByName(IDirectXFileEnumObject
* iface
, LPCSTR szName
, LPDIRECTXFILEDATA
* ppDataObj
)
1091 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
1093 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szName
, ppDataObj
);
1095 return DXFILEERR_BADVALUE
;
1098 static const IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl
=
1100 IDirectXFileEnumObjectImpl_QueryInterface
,
1101 IDirectXFileEnumObjectImpl_AddRef
,
1102 IDirectXFileEnumObjectImpl_Release
,
1103 IDirectXFileEnumObjectImpl_GetNextDataObject
,
1104 IDirectXFileEnumObjectImpl_GetDataObjectById
,
1105 IDirectXFileEnumObjectImpl_GetDataObjectByName
1108 static HRESULT
IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl
** ppObj
)
1110 IDirectXFileSaveObjectImpl
* object
;
1112 TRACE("(%p)\n", ppObj
);
1114 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileSaveObjectImpl
));
1117 ERR("Out of memory\n");
1118 return DXFILEERR_BADALLOC
;
1121 object
->IDirectXFileSaveObject_iface
.lpVtbl
= &IDirectXFileSaveObject_Vtbl
;
1129 static inline IDirectXFileSaveObjectImpl
*impl_from_IDirectXFileSaveObject(IDirectXFileSaveObject
*iface
)
1131 return CONTAINING_RECORD(iface
, IDirectXFileSaveObjectImpl
, IDirectXFileSaveObject_iface
);
1134 /*** IUnknown methods ***/
1135 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_QueryInterface(IDirectXFileSaveObject
* iface
, REFIID riid
, void** ppvObject
)
1137 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1139 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1141 if (IsEqualGUID(riid
, &IID_IUnknown
)
1142 || IsEqualGUID(riid
, &IID_IDirectXFileSaveObject
))
1144 IUnknown_AddRef(iface
);
1145 *ppvObject
= &This
->IDirectXFileSaveObject_iface
;
1149 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1150 return E_NOINTERFACE
;
1153 static ULONG WINAPI
IDirectXFileSaveObjectImpl_AddRef(IDirectXFileSaveObject
* iface
)
1155 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1156 ULONG ref
= InterlockedIncrement(&This
->ref
);
1158 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
1163 static ULONG WINAPI
IDirectXFileSaveObjectImpl_Release(IDirectXFileSaveObject
* iface
)
1165 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1166 ULONG ref
= InterlockedDecrement(&This
->ref
);
1168 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
1171 HeapFree(GetProcessHeap(), 0, This
);
1176 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveTemplates(IDirectXFileSaveObject
* iface
, DWORD cTemplates
, const GUID
** ppguidTemplates
)
1178 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1180 FIXME("(%p/%p)->(%d,%p) stub!\n", This
, iface
, cTemplates
, ppguidTemplates
);
1185 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_CreateDataObject(IDirectXFileSaveObject
* iface
, REFGUID rguidTemplate
, LPCSTR szName
, const GUID
* pguid
, DWORD cbSize
, LPVOID pvData
, LPDIRECTXFILEDATA
* ppDataObj
)
1187 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1189 FIXME("(%p/%p)->(%p,%s,%p,%d,%p,%p) stub!\n", This
, iface
, rguidTemplate
, szName
, pguid
, cbSize
, pvData
, ppDataObj
);
1191 return DXFILEERR_BADVALUE
;
1194 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveData(IDirectXFileSaveObject
* iface
, LPDIRECTXFILEDATA ppDataObj
)
1196 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1198 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, ppDataObj
);
1200 return DXFILEERR_BADVALUE
;
1203 static const IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl
=
1205 IDirectXFileSaveObjectImpl_QueryInterface
,
1206 IDirectXFileSaveObjectImpl_AddRef
,
1207 IDirectXFileSaveObjectImpl_Release
,
1208 IDirectXFileSaveObjectImpl_SaveTemplates
,
1209 IDirectXFileSaveObjectImpl_CreateDataObject
,
1210 IDirectXFileSaveObjectImpl_SaveData