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 /*** IUnknown methods ***/
85 static HRESULT WINAPI
IDirectXFileImpl_QueryInterface(IDirectXFile
* iface
, REFIID riid
, void** ppvObject
)
87 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
89 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
91 if (IsEqualGUID(riid
, &IID_IUnknown
)
92 || IsEqualGUID(riid
, &IID_IDirectXFile
))
94 IUnknown_AddRef(iface
);
95 *ppvObject
= &This
->IDirectXFile_iface
;
99 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
100 return E_NOINTERFACE
;
103 static ULONG WINAPI
IDirectXFileImpl_AddRef(IDirectXFile
* iface
)
105 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
106 ULONG ref
= InterlockedIncrement(&This
->ref
);
108 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
113 static ULONG WINAPI
IDirectXFileImpl_Release(IDirectXFile
* iface
)
115 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
116 ULONG ref
= InterlockedDecrement(&This
->ref
);
118 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
121 HeapFree(GetProcessHeap(), 0, This
);
126 /*** IDirectXFile methods ***/
127 static HRESULT WINAPI
IDirectXFileImpl_CreateEnumObject(IDirectXFile
* iface
, LPVOID pvSource
, DXFILELOADOPTIONS dwLoadOptions
, LPDIRECTXFILEENUMOBJECT
* ppEnumObj
)
129 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
130 IDirectXFileEnumObjectImpl
* object
;
136 TRACE("(%p/%p)->(%p,%x,%p)\n", This
, iface
, pvSource
, dwLoadOptions
, ppEnumObj
);
139 return DXFILEERR_BADVALUE
;
141 /* Only lowest 4 bits are relevant in DXFILELOADOPTIONS */
142 dwLoadOptions
&= 0xF;
144 hr
= IDirectXFileEnumObjectImpl_Create(&object
);
148 if (dwLoadOptions
== DXFILELOAD_FROMFILE
)
150 HANDLE hFile
, file_mapping
;
152 TRACE("Open source file '%s'\n", (char*)pvSource
);
154 hFile
= CreateFileA(pvSource
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
155 if (hFile
== INVALID_HANDLE_VALUE
)
157 TRACE("File '%s' not found\n", (char*)pvSource
);
158 return DXFILEERR_FILENOTFOUND
;
161 file_size
= GetFileSize(hFile
, NULL
);
163 file_mapping
= CreateFileMappingA(hFile
, NULL
, PAGE_READONLY
, 0, 0, NULL
);
167 hr
= DXFILEERR_BADFILETYPE
;
171 object
->mapped_memory
= MapViewOfFile(file_mapping
, FILE_MAP_READ
, 0, 0, 0);
172 CloseHandle(file_mapping
);
173 if (!object
->mapped_memory
)
175 hr
= DXFILEERR_BADFILETYPE
;
178 file_buffer
= object
->mapped_memory
;
180 else if (dwLoadOptions
== DXFILELOAD_FROMRESOURCE
)
183 HGLOBAL resource_data
;
184 LPDXFILELOADRESOURCE lpdxflr
= pvSource
;
186 TRACE("Source in resource (module = %p, name = %s, type = %s)\n", lpdxflr
->hModule
, debugstr_a(lpdxflr
->lpName
), debugstr_a(lpdxflr
->lpType
));
188 resource_info
= FindResourceA(lpdxflr
->hModule
, lpdxflr
->lpName
, lpdxflr
->lpType
);
191 hr
= DXFILEERR_RESOURCENOTFOUND
;
195 file_size
= SizeofResource(lpdxflr
->hModule
, resource_info
);
197 resource_data
= LoadResource(lpdxflr
->hModule
, resource_info
);
200 hr
= DXFILEERR_BADRESOURCE
;
204 file_buffer
= LockResource(resource_data
);
207 hr
= DXFILEERR_BADRESOURCE
;
211 else if (dwLoadOptions
== DXFILELOAD_FROMMEMORY
)
213 LPDXFILELOADMEMORY lpdxflm
= pvSource
;
215 TRACE("Source in memory at %p with size %d\n", lpdxflm
->lpMemory
, lpdxflm
->dSize
);
217 file_buffer
= lpdxflm
->lpMemory
;
218 file_size
= lpdxflm
->dSize
;
222 FIXME("Source type %d is not handled yet\n", dwLoadOptions
);
223 hr
= DXFILEERR_NOTDONEYET
;
227 TRACE("File size is %d bytes\n", file_size
);
229 if (TRACE_ON(d3dxof_dump
))
234 sprintf(tmp
, "file%05u.x", num
++);
236 file
= CreateFileA(tmp
, GENERIC_WRITE
, FILE_SHARE_READ
, NULL
, CREATE_ALWAYS
, 0, NULL
);
237 if (file
!= INVALID_HANDLE_VALUE
)
239 WriteFile(file
, file_buffer
, file_size
, &bytes_written
, NULL
);
244 object
->pDirectXFile
= This
;
246 object
->buf
.pdxf
= This
;
247 object
->buf
.token_present
= FALSE
;
248 object
->buf
.buffer
= file_buffer
;
249 object
->buf
.rem_bytes
= file_size
;
250 hr
= parse_header(&object
->buf
, &object
->decomp_buffer
);
254 /* Check if there are templates defined before the object */
255 if (!parse_templates(&object
->buf
, TRUE
))
257 hr
= DXFILEERR_PARSEERROR
;
261 if (TRACE_ON(d3dxof
))
264 TRACE("Registered templates (%d):\n", This
->nb_xtemplates
);
265 for (i
= 1; i
< This
->nb_xtemplates
; i
++)
266 TRACE("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
269 *ppEnumObj
= &object
->IDirectXFileEnumObject_iface
;
274 IDirectXFileEnumObject_Release(&object
->IDirectXFileEnumObject_iface
);
280 static HRESULT WINAPI
IDirectXFileImpl_CreateSaveObject(IDirectXFile
* iface
, LPCSTR szFileName
, DXFILEFORMAT dwFileFormat
, LPDIRECTXFILESAVEOBJECT
* ppSaveObj
)
282 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
283 IDirectXFileSaveObjectImpl
*object
;
286 FIXME("(%p/%p)->(%s,%x,%p) partial stub!\n", This
, iface
, szFileName
, dwFileFormat
, ppSaveObj
);
288 if (!szFileName
|| !ppSaveObj
)
291 hr
= IDirectXFileSaveObjectImpl_Create(&object
);
293 *ppSaveObj
= &object
->IDirectXFileSaveObject_iface
;
297 static HRESULT WINAPI
IDirectXFileImpl_RegisterTemplates(IDirectXFile
* iface
, LPVOID pvData
, DWORD cbSize
)
299 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
302 LPBYTE decomp_buffer
= NULL
;
305 ZeroMemory(&buf
, sizeof(buf
));
307 buf
.rem_bytes
= cbSize
;
310 TRACE("(%p/%p)->(%p,%d)\n", This
, iface
, pvData
, cbSize
);
313 return DXFILEERR_BADVALUE
;
315 if (TRACE_ON(d3dxof_dump
))
320 sprintf(tmp
, "template%05u.x", num
++);
322 file
= CreateFileA(tmp
, GENERIC_WRITE
, FILE_SHARE_READ
, NULL
, CREATE_ALWAYS
, 0, NULL
);
323 if (file
!= INVALID_HANDLE_VALUE
)
325 WriteFile(file
, pvData
, cbSize
, &bytes_written
, NULL
);
330 hr
= parse_header(&buf
, &decomp_buffer
);
334 if (!parse_templates(&buf
, FALSE
))
336 hr
= DXFILEERR_PARSEERROR
;
340 if (TRACE_ON(d3dxof
))
343 TRACE("Registered templates (%d):\n", This
->nb_xtemplates
);
344 for (i
= 1; i
< This
->nb_xtemplates
; i
++)
345 TRACE("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
350 HeapFree(GetProcessHeap(), 0, decomp_buffer
);
354 static const IDirectXFileVtbl IDirectXFile_Vtbl
=
356 IDirectXFileImpl_QueryInterface
,
357 IDirectXFileImpl_AddRef
,
358 IDirectXFileImpl_Release
,
359 IDirectXFileImpl_CreateEnumObject
,
360 IDirectXFileImpl_CreateSaveObject
,
361 IDirectXFileImpl_RegisterTemplates
364 static HRESULT
IDirectXFileBinaryImpl_Create(IDirectXFileBinaryImpl
** ppObj
)
366 IDirectXFileBinaryImpl
* object
;
368 TRACE("(%p)\n", ppObj
);
370 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileBinaryImpl
));
372 return DXFILEERR_BADALLOC
;
374 object
->IDirectXFileBinary_iface
.lpVtbl
= &IDirectXFileBinary_Vtbl
;
382 static inline IDirectXFileBinaryImpl
*impl_from_IDirectXFileBinary(IDirectXFileBinary
*iface
)
384 return CONTAINING_RECORD(iface
, IDirectXFileBinaryImpl
, IDirectXFileBinary_iface
);
387 /*** IUnknown methods ***/
388 static HRESULT WINAPI
IDirectXFileBinaryImpl_QueryInterface(IDirectXFileBinary
* iface
, REFIID riid
, void** ppvObject
)
390 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
392 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
394 if (IsEqualGUID(riid
, &IID_IUnknown
)
395 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
396 || IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
398 IUnknown_AddRef(iface
);
399 *ppvObject
= &This
->IDirectXFileBinary_iface
;
403 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
404 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
)
405 && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
406 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
408 return E_NOINTERFACE
;
411 static ULONG WINAPI
IDirectXFileBinaryImpl_AddRef(IDirectXFileBinary
* iface
)
413 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
414 ULONG ref
= InterlockedIncrement(&This
->ref
);
416 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
421 static ULONG WINAPI
IDirectXFileBinaryImpl_Release(IDirectXFileBinary
* iface
)
423 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
424 ULONG ref
= InterlockedDecrement(&This
->ref
);
426 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
429 HeapFree(GetProcessHeap(), 0, This
);
434 /*** IDirectXFileObject methods ***/
435 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetName(IDirectXFileBinary
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
438 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
440 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
442 return DXFILEERR_BADVALUE
;
445 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetId(IDirectXFileBinary
* iface
, LPGUID pGuid
)
447 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
449 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pGuid
);
451 return DXFILEERR_BADVALUE
;
454 /*** IDirectXFileBinary methods ***/
455 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetSize(IDirectXFileBinary
* iface
, DWORD
* pcbSize
)
457 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
459 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pcbSize
);
461 return DXFILEERR_BADVALUE
;
464 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetMimeType(IDirectXFileBinary
* iface
, LPCSTR
* pszMimeType
)
466 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
468 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pszMimeType
);
470 return DXFILEERR_BADVALUE
;
473 static HRESULT WINAPI
IDirectXFileBinaryImpl_Read(IDirectXFileBinary
* iface
, LPVOID pvData
, DWORD cbSize
, LPDWORD pcbRead
)
475 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
477 FIXME("(%p/%p)->(%p, %d, %p) stub!\n", This
, iface
, pvData
, cbSize
, pcbRead
);
479 return DXFILEERR_BADVALUE
;
482 static const IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl
=
484 IDirectXFileBinaryImpl_QueryInterface
,
485 IDirectXFileBinaryImpl_AddRef
,
486 IDirectXFileBinaryImpl_Release
,
487 IDirectXFileBinaryImpl_GetName
,
488 IDirectXFileBinaryImpl_GetId
,
489 IDirectXFileBinaryImpl_GetSize
,
490 IDirectXFileBinaryImpl_GetMimeType
,
491 IDirectXFileBinaryImpl_Read
494 static HRESULT
IDirectXFileDataImpl_Create(IDirectXFileDataImpl
** ppObj
)
496 IDirectXFileDataImpl
* object
;
498 TRACE("(%p)\n", ppObj
);
500 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataImpl
));
502 return DXFILEERR_BADALLOC
;
504 object
->IDirectXFileData_iface
.lpVtbl
= &IDirectXFileData_Vtbl
;
512 static inline IDirectXFileDataImpl
*impl_from_IDirectXFileData(IDirectXFileData
*iface
)
514 return CONTAINING_RECORD(iface
, IDirectXFileDataImpl
, IDirectXFileData_iface
);
517 /*** IUnknown methods ***/
518 static HRESULT WINAPI
IDirectXFileDataImpl_QueryInterface(IDirectXFileData
* iface
, REFIID riid
, void** ppvObject
)
520 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
522 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
524 if (IsEqualGUID(riid
, &IID_IUnknown
)
525 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
526 || IsEqualGUID(riid
, &IID_IDirectXFileData
))
528 IUnknown_AddRef(iface
);
529 *ppvObject
= &This
->IDirectXFileData_iface
;
533 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
534 if (!IsEqualGUID(riid
, &IID_IDirectXFileBinary
)
535 && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
536 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
538 return E_NOINTERFACE
;
541 static ULONG WINAPI
IDirectXFileDataImpl_AddRef(IDirectXFileData
* iface
)
543 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
544 ULONG ref
= InterlockedIncrement(&This
->ref
);
546 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
551 static ULONG WINAPI
IDirectXFileDataImpl_Release(IDirectXFileData
* iface
)
553 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
554 ULONG ref
= InterlockedDecrement(&This
->ref
);
556 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
560 if (!This
->level
&& !This
->from_ref
)
562 HeapFree(GetProcessHeap(), 0, This
->pstrings
);
565 HeapFree(GetProcessHeap(), 0, This
->pobj
->pdata
);
566 HeapFree(GetProcessHeap(), 0, This
->pobj
);
569 HeapFree(GetProcessHeap(), 0, This
);
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 pDataObj
)
729 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
731 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pDataObj
);
733 return DXFILEERR_BADVALUE
;
736 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataReference(IDirectXFileData
* iface
, LPCSTR szRef
, const GUID
* pguidRef
)
738 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
740 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szRef
, pguidRef
);
742 return DXFILEERR_BADVALUE
;
745 static HRESULT WINAPI
IDirectXFileDataImpl_AddBinaryObject(IDirectXFileData
* iface
, LPCSTR szName
, const GUID
* pguid
, LPCSTR szMimeType
, LPVOID pvData
, DWORD cbSize
)
747 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
749 FIXME("(%p/%p)->(%s,%p,%s,%p,%d) stub!\n", This
, iface
, szName
, pguid
, szMimeType
, pvData
, cbSize
);
751 return DXFILEERR_BADVALUE
;
754 static const IDirectXFileDataVtbl IDirectXFileData_Vtbl
=
756 IDirectXFileDataImpl_QueryInterface
,
757 IDirectXFileDataImpl_AddRef
,
758 IDirectXFileDataImpl_Release
,
759 IDirectXFileDataImpl_GetName
,
760 IDirectXFileDataImpl_GetId
,
761 IDirectXFileDataImpl_GetData
,
762 IDirectXFileDataImpl_GetType
,
763 IDirectXFileDataImpl_GetNextObject
,
764 IDirectXFileDataImpl_AddDataObject
,
765 IDirectXFileDataImpl_AddDataReference
,
766 IDirectXFileDataImpl_AddBinaryObject
769 static HRESULT
IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl
** ppObj
)
771 IDirectXFileDataReferenceImpl
* object
;
773 TRACE("(%p)\n", ppObj
);
775 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataReferenceImpl
));
777 return DXFILEERR_BADALLOC
;
779 object
->IDirectXFileDataReference_iface
.lpVtbl
= &IDirectXFileDataReference_Vtbl
;
787 static inline IDirectXFileDataReferenceImpl
*impl_from_IDirectXFileDataReference(IDirectXFileDataReference
*iface
)
789 return CONTAINING_RECORD(iface
, IDirectXFileDataReferenceImpl
, IDirectXFileDataReference_iface
);
792 /*** IUnknown methods ***/
793 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_QueryInterface(IDirectXFileDataReference
* iface
, REFIID riid
, void** ppvObject
)
795 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
797 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
799 if (IsEqualGUID(riid
, &IID_IUnknown
)
800 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
801 || IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
803 IUnknown_AddRef(iface
);
804 *ppvObject
= &This
->IDirectXFileDataReference_iface
;
808 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
809 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
)
810 && !IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
811 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
813 return E_NOINTERFACE
;
816 static ULONG WINAPI
IDirectXFileDataReferenceImpl_AddRef(IDirectXFileDataReference
* iface
)
818 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
819 ULONG ref
= InterlockedIncrement(&This
->ref
);
821 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
826 static ULONG WINAPI
IDirectXFileDataReferenceImpl_Release(IDirectXFileDataReference
* iface
)
828 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
829 ULONG ref
= InterlockedDecrement(&This
->ref
);
831 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
834 HeapFree(GetProcessHeap(), 0, This
);
839 /*** IDirectXFileObject methods ***/
840 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetName(IDirectXFileDataReference
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
842 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
845 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
848 return DXFILEERR_BADVALUE
;
850 len
= strlen(This
->ptarget
->name
);
855 if (*pdwBufLen
< len
)
856 return DXFILEERR_BADVALUE
;
857 CopyMemory(pstrNameBuf
, This
->ptarget
->name
, len
);
858 /* Even if we return a size of 0, an empty string with a null byte must be returned */
859 if (*pdwBufLen
&& !len
)
867 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetId(IDirectXFileDataReference
* iface
, LPGUID pGuid
)
869 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
871 TRACE("(%p/%p)->(%p)\n", This
, iface
, pGuid
);
874 return DXFILEERR_BADVALUE
;
876 *pGuid
= This
->ptarget
->class_id
;
881 /*** IDirectXFileDataReference ***/
882 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
884 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
885 IDirectXFileDataImpl
*object
;
888 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
891 return DXFILEERR_BADVALUE
;
893 hr
= IDirectXFileDataImpl_Create(&object
);
897 object
->pobj
= This
->ptarget
;
898 object
->cur_enum_object
= 0;
900 object
->from_ref
= TRUE
;
902 *ppDataObj
= &object
->IDirectXFileData_iface
;
907 static const IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl
=
909 IDirectXFileDataReferenceImpl_QueryInterface
,
910 IDirectXFileDataReferenceImpl_AddRef
,
911 IDirectXFileDataReferenceImpl_Release
,
912 IDirectXFileDataReferenceImpl_GetName
,
913 IDirectXFileDataReferenceImpl_GetId
,
914 IDirectXFileDataReferenceImpl_Resolve
917 static HRESULT
IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl
** ppObj
)
919 IDirectXFileEnumObjectImpl
* object
;
921 TRACE("(%p)\n", ppObj
);
923 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileEnumObjectImpl
));
925 return DXFILEERR_BADALLOC
;
927 object
->IDirectXFileEnumObject_iface
.lpVtbl
= &IDirectXFileEnumObject_Vtbl
;
935 static inline IDirectXFileEnumObjectImpl
*impl_from_IDirectXFileEnumObject(IDirectXFileEnumObject
*iface
)
937 return CONTAINING_RECORD(iface
, IDirectXFileEnumObjectImpl
, IDirectXFileEnumObject_iface
);
940 /*** IUnknown methods ***/
941 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_QueryInterface(IDirectXFileEnumObject
* iface
, REFIID riid
, void** ppvObject
)
943 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
945 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
947 if (IsEqualGUID(riid
, &IID_IUnknown
)
948 || IsEqualGUID(riid
, &IID_IDirectXFileEnumObject
))
950 IUnknown_AddRef(iface
);
951 *ppvObject
= &This
->IDirectXFileEnumObject_iface
;
955 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
956 return E_NOINTERFACE
;
959 static ULONG WINAPI
IDirectXFileEnumObjectImpl_AddRef(IDirectXFileEnumObject
* iface
)
961 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
962 ULONG ref
= InterlockedIncrement(&This
->ref
);
964 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
969 static ULONG WINAPI
IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject
* iface
)
971 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
972 ULONG ref
= InterlockedDecrement(&This
->ref
);
974 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
979 for (i
= 0; i
< This
->nb_xobjects
; i
++)
980 IDirectXFileData_Release(This
->pRefObjects
[i
]);
981 if (This
->mapped_memory
)
982 UnmapViewOfFile(This
->mapped_memory
);
983 HeapFree(GetProcessHeap(), 0, This
->decomp_buffer
);
984 HeapFree(GetProcessHeap(), 0, This
);
990 /*** IDirectXFileEnumObject methods ***/
991 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
993 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
994 IDirectXFileDataImpl
* object
;
1002 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
1004 if (This
->nb_xobjects
>= MAX_OBJECTS
)
1006 ERR("Too many objects\n");
1007 return DXFILEERR_NOMOREOBJECTS
;
1010 /* Check if there are templates defined before the object */
1011 if (!parse_templates(&This
->buf
, TRUE
))
1012 return DXFILEERR_PARSEERROR
;
1014 if (!This
->buf
.rem_bytes
)
1015 return DXFILEERR_NOMOREOBJECTS
;
1017 hr
= IDirectXFileDataImpl_Create(&object
);
1021 object
->pobj
= HeapAlloc(GetProcessHeap(), 0, sizeof(xobject
)*MAX_SUBOBJECTS
);
1024 hr
= DXFILEERR_BADALLOC
;
1028 object
->pstrings
= HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER
);
1029 if (!object
->pstrings
)
1031 hr
= DXFILEERR_BADALLOC
;
1035 object
->cur_enum_object
= 0;
1037 object
->from_ref
= FALSE
;
1039 This
->buf
.pxo_globals
= This
->xobjects
;
1040 This
->buf
.nb_pxo_globals
= This
->nb_xobjects
;
1041 This
->buf
.level
= 0;
1042 This
->buf
.pdata
= NULL
;
1043 This
->buf
.capacity
= 0;
1044 This
->buf
.cur_pos_data
= 0;
1045 This
->buf
.cur_pstrings
= This
->buf
.pstrings
= object
->pstrings
;
1046 This
->buf
.pxo
= This
->xobjects
[This
->nb_xobjects
] = This
->buf
.pxo_tab
= object
->pobj
;
1047 This
->buf
.pxo
->pdata
= NULL
;
1048 This
->buf
.pxo
->nb_subobjects
= 1;
1050 if (!parse_object(&This
->buf
))
1052 WARN("Object is not correct\n");
1053 hr
= DXFILEERR_PARSEERROR
;
1057 *ppDataObj
= &object
->IDirectXFileData_iface
;
1059 /* Get a reference to created object */
1060 This
->pRefObjects
[This
->nb_xobjects
] = &object
->IDirectXFileData_iface
;
1061 IDirectXFileData_AddRef(This
->pRefObjects
[This
->nb_xobjects
]);
1063 This
->nb_xobjects
++;
1069 IDirectXFileData_Release(&object
->IDirectXFileData_iface
);
1074 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectById(IDirectXFileEnumObject
* iface
, REFGUID rguid
, LPDIRECTXFILEDATA
* ppDataObj
)
1076 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
1078 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, rguid
, ppDataObj
);
1080 return DXFILEERR_BADVALUE
;
1083 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectByName(IDirectXFileEnumObject
* iface
, LPCSTR szName
, LPDIRECTXFILEDATA
* ppDataObj
)
1085 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
1087 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szName
, ppDataObj
);
1089 return DXFILEERR_BADVALUE
;
1092 static const IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl
=
1094 IDirectXFileEnumObjectImpl_QueryInterface
,
1095 IDirectXFileEnumObjectImpl_AddRef
,
1096 IDirectXFileEnumObjectImpl_Release
,
1097 IDirectXFileEnumObjectImpl_GetNextDataObject
,
1098 IDirectXFileEnumObjectImpl_GetDataObjectById
,
1099 IDirectXFileEnumObjectImpl_GetDataObjectByName
1102 static HRESULT
IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl
** ppObj
)
1104 IDirectXFileSaveObjectImpl
* object
;
1106 TRACE("(%p)\n", ppObj
);
1108 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileSaveObjectImpl
));
1110 return DXFILEERR_BADALLOC
;
1112 object
->IDirectXFileSaveObject_iface
.lpVtbl
= &IDirectXFileSaveObject_Vtbl
;
1120 static inline IDirectXFileSaveObjectImpl
*impl_from_IDirectXFileSaveObject(IDirectXFileSaveObject
*iface
)
1122 return CONTAINING_RECORD(iface
, IDirectXFileSaveObjectImpl
, IDirectXFileSaveObject_iface
);
1125 /*** IUnknown methods ***/
1126 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_QueryInterface(IDirectXFileSaveObject
* iface
, REFIID riid
, void** ppvObject
)
1128 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1130 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1132 if (IsEqualGUID(riid
, &IID_IUnknown
)
1133 || IsEqualGUID(riid
, &IID_IDirectXFileSaveObject
))
1135 IUnknown_AddRef(iface
);
1136 *ppvObject
= &This
->IDirectXFileSaveObject_iface
;
1140 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1141 return E_NOINTERFACE
;
1144 static ULONG WINAPI
IDirectXFileSaveObjectImpl_AddRef(IDirectXFileSaveObject
* iface
)
1146 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1147 ULONG ref
= InterlockedIncrement(&This
->ref
);
1149 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
1154 static ULONG WINAPI
IDirectXFileSaveObjectImpl_Release(IDirectXFileSaveObject
* iface
)
1156 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1157 ULONG ref
= InterlockedDecrement(&This
->ref
);
1159 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
1162 HeapFree(GetProcessHeap(), 0, This
);
1167 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveTemplates(IDirectXFileSaveObject
* iface
, DWORD cTemplates
, const GUID
** ppguidTemplates
)
1169 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1171 FIXME("(%p/%p)->(%d,%p) stub!\n", This
, iface
, cTemplates
, ppguidTemplates
);
1176 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_CreateDataObject(IDirectXFileSaveObject
* iface
, REFGUID rguidTemplate
, LPCSTR szName
, const GUID
* pguid
, DWORD cbSize
, LPVOID pvData
, LPDIRECTXFILEDATA
* ppDataObj
)
1178 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1180 FIXME("(%p/%p)->(%p,%s,%p,%d,%p,%p) stub!\n", This
, iface
, rguidTemplate
, szName
, pguid
, cbSize
, pvData
, ppDataObj
);
1182 return DXFILEERR_BADVALUE
;
1185 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveData(IDirectXFileSaveObject
* iface
, LPDIRECTXFILEDATA ppDataObj
)
1187 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1189 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, ppDataObj
);
1191 return DXFILEERR_BADVALUE
;
1194 static const IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl
=
1196 IDirectXFileSaveObjectImpl_QueryInterface
,
1197 IDirectXFileSaveObjectImpl_AddRef
,
1198 IDirectXFileSaveObjectImpl_Release
,
1199 IDirectXFileSaveObjectImpl_SaveTemplates
,
1200 IDirectXFileSaveObjectImpl_CreateDataObject
,
1201 IDirectXFileSaveObjectImpl_SaveData