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
22 #include "wine/debug.h"
29 #include "d3dxof_private.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(d3dxof
);
35 WINE_DECLARE_DEBUG_CHANNEL(d3dxof_dump
);
37 static const struct IDirectXFileVtbl IDirectXFile_Vtbl
;
38 static const struct IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl
;
39 static const struct IDirectXFileDataVtbl IDirectXFileData_Vtbl
;
40 static const struct IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl
;
41 static const struct IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl
;
42 static const struct IDirectXFileObjectVtbl IDirectXFileObject_Vtbl
;
43 static const struct IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl
;
45 static HRESULT
IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl
** ppObj
);
46 static HRESULT
IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl
** ppObj
);
47 static HRESULT
IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl
** ppObj
);
49 #define TOKEN_DWORD 41
50 #define TOKEN_FLOAT 42
52 HRESULT
IDirectXFileImpl_Create(IUnknown
* pUnkOuter
, LPVOID
* ppObj
)
54 IDirectXFileImpl
* object
;
56 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
58 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileImpl
));
61 ERR("Out of memory\n");
62 return DXFILEERR_BADALLOC
;
65 object
->IDirectXFile_iface
.lpVtbl
= &IDirectXFile_Vtbl
;
68 /* Reserve first template to handle the case sensitive legacy type indexColor */
69 object
->nb_xtemplates
= 1;
70 strcpy(object
->xtemplates
[0].name
, "indexColor");
71 object
->xtemplates
[0].nb_members
= 2;
72 object
->xtemplates
[0].members
[0].type
= TOKEN_DWORD
;
73 object
->xtemplates
[0].members
[0].nb_dims
= 0;
74 object
->xtemplates
[0].members
[1].type
= TOKEN_FLOAT
;
75 object
->xtemplates
[0].members
[1].nb_dims
= 1;
76 object
->xtemplates
[0].members
[1].dim_fixed
[0] = TRUE
;
77 object
->xtemplates
[0].members
[1].dim_value
[0] = 4;
79 *ppObj
= &object
->IDirectXFile_iface
;
84 static inline IDirectXFileImpl
*impl_from_IDirectXFile(IDirectXFile
*iface
)
86 return CONTAINING_RECORD(iface
, IDirectXFileImpl
, IDirectXFile_iface
);
89 /*** IUnknown methods ***/
90 static HRESULT WINAPI
IDirectXFileImpl_QueryInterface(IDirectXFile
* iface
, REFIID riid
, void** ppvObject
)
92 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
94 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
96 if (IsEqualGUID(riid
, &IID_IUnknown
)
97 || IsEqualGUID(riid
, &IID_IDirectXFile
))
99 IUnknown_AddRef(iface
);
100 *ppvObject
= &This
->IDirectXFile_iface
;
104 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
105 return E_NOINTERFACE
;
108 static ULONG WINAPI
IDirectXFileImpl_AddRef(IDirectXFile
* iface
)
110 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
111 ULONG ref
= InterlockedIncrement(&This
->ref
);
113 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
118 static ULONG WINAPI
IDirectXFileImpl_Release(IDirectXFile
* iface
)
120 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
121 ULONG ref
= InterlockedDecrement(&This
->ref
);
123 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
126 HeapFree(GetProcessHeap(), 0, This
);
131 /*** IDirectXFile methods ***/
132 static HRESULT WINAPI
IDirectXFileImpl_CreateEnumObject(IDirectXFile
* iface
, LPVOID pvSource
, DXFILELOADOPTIONS dwLoadOptions
, LPDIRECTXFILEENUMOBJECT
* ppEnumObj
)
134 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
135 IDirectXFileEnumObjectImpl
* object
;
141 TRACE("(%p/%p)->(%p,%x,%p)\n", This
, iface
, pvSource
, dwLoadOptions
, ppEnumObj
);
144 return DXFILEERR_BADVALUE
;
146 /* Only lowest 4 bits are relevant in DXFILELOADOPTIONS */
147 dwLoadOptions
&= 0xF;
149 hr
= IDirectXFileEnumObjectImpl_Create(&object
);
153 if (dwLoadOptions
== DXFILELOAD_FROMFILE
)
155 HANDLE hFile
, file_mapping
;
157 TRACE("Open source file '%s'\n", (char*)pvSource
);
159 hFile
= CreateFileA(pvSource
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
160 if (hFile
== INVALID_HANDLE_VALUE
)
162 TRACE("File '%s' not found\n", (char*)pvSource
);
163 return DXFILEERR_FILENOTFOUND
;
166 file_size
= GetFileSize(hFile
, NULL
);
168 file_mapping
= CreateFileMappingA(hFile
, NULL
, PAGE_READONLY
, 0, 0, NULL
);
172 hr
= DXFILEERR_BADFILETYPE
;
176 object
->mapped_memory
= MapViewOfFile(file_mapping
, FILE_MAP_READ
, 0, 0, 0);
177 CloseHandle(file_mapping
);
178 if (!object
->mapped_memory
)
180 hr
= DXFILEERR_BADFILETYPE
;
183 file_buffer
= object
->mapped_memory
;
185 else if (dwLoadOptions
== DXFILELOAD_FROMRESOURCE
)
188 HGLOBAL resource_data
;
189 LPDXFILELOADRESOURCE lpdxflr
= pvSource
;
191 TRACE("Source in resource (module = %p, name = %s, type = %s)\n", lpdxflr
->hModule
, debugstr_a(lpdxflr
->lpName
), debugstr_a(lpdxflr
->lpType
));
193 resource_info
= FindResourceA(lpdxflr
->hModule
, lpdxflr
->lpName
, lpdxflr
->lpType
);
196 hr
= DXFILEERR_RESOURCENOTFOUND
;
200 file_size
= SizeofResource(lpdxflr
->hModule
, resource_info
);
202 resource_data
= LoadResource(lpdxflr
->hModule
, resource_info
);
205 hr
= DXFILEERR_BADRESOURCE
;
209 file_buffer
= LockResource(resource_data
);
212 hr
= DXFILEERR_BADRESOURCE
;
216 else if (dwLoadOptions
== DXFILELOAD_FROMMEMORY
)
218 LPDXFILELOADMEMORY lpdxflm
= pvSource
;
220 TRACE("Source in memory at %p with size %d\n", lpdxflm
->lpMemory
, lpdxflm
->dSize
);
222 file_buffer
= lpdxflm
->lpMemory
;
223 file_size
= lpdxflm
->dSize
;
227 FIXME("Source type %d is not handled yet\n", dwLoadOptions
);
228 hr
= DXFILEERR_NOTDONEYET
;
232 TRACE("File size is %d bytes\n", file_size
);
234 if (TRACE_ON(d3dxof_dump
))
239 sprintf(tmp
, "file%05u.x", num
++);
241 file
= CreateFileA(tmp
, GENERIC_WRITE
, FILE_SHARE_READ
, NULL
, CREATE_ALWAYS
, 0, NULL
);
242 if (file
!= INVALID_HANDLE_VALUE
)
244 WriteFile(file
, file_buffer
, file_size
, &bytes_written
, NULL
);
249 object
->pDirectXFile
= This
;
251 object
->buf
.pdxf
= This
;
252 object
->buf
.token_present
= FALSE
;
253 object
->buf
.buffer
= file_buffer
;
254 object
->buf
.rem_bytes
= file_size
;
255 hr
= parse_header(&object
->buf
, &object
->decomp_buffer
);
259 /* Check if there are templates defined before the object */
260 if (!parse_templates(&object
->buf
, TRUE
))
262 hr
= DXFILEERR_PARSEERROR
;
266 if (TRACE_ON(d3dxof
))
269 TRACE("Registered templates (%d):\n", This
->nb_xtemplates
);
270 for (i
= 1; i
< This
->nb_xtemplates
; i
++)
271 DPRINTF("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
274 *ppEnumObj
= &object
->IDirectXFileEnumObject_iface
;
279 IDirectXFileEnumObject_Release(&object
->IDirectXFileEnumObject_iface
);
285 static HRESULT WINAPI
IDirectXFileImpl_CreateSaveObject(IDirectXFile
* iface
, LPCSTR szFileName
, DXFILEFORMAT dwFileFormat
, LPDIRECTXFILESAVEOBJECT
* ppSaveObj
)
287 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
288 IDirectXFileSaveObjectImpl
*object
;
291 FIXME("(%p/%p)->(%s,%x,%p) partial stub!\n", This
, iface
, szFileName
, dwFileFormat
, ppSaveObj
);
293 if (!szFileName
|| !ppSaveObj
)
296 hr
= IDirectXFileSaveObjectImpl_Create(&object
);
298 *ppSaveObj
= &object
->IDirectXFileSaveObject_iface
;
302 static HRESULT WINAPI
IDirectXFileImpl_RegisterTemplates(IDirectXFile
* iface
, LPVOID pvData
, DWORD cbSize
)
304 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
307 LPBYTE decomp_buffer
= NULL
;
310 ZeroMemory(&buf
, sizeof(buf
));
312 buf
.rem_bytes
= cbSize
;
315 TRACE("(%p/%p)->(%p,%d)\n", This
, iface
, pvData
, cbSize
);
318 return DXFILEERR_BADVALUE
;
320 if (TRACE_ON(d3dxof_dump
))
325 sprintf(tmp
, "template%05u.x", num
++);
327 file
= CreateFileA(tmp
, GENERIC_WRITE
, FILE_SHARE_READ
, NULL
, CREATE_ALWAYS
, 0, NULL
);
328 if (file
!= INVALID_HANDLE_VALUE
)
330 WriteFile(file
, pvData
, cbSize
, &bytes_written
, NULL
);
335 hr
= parse_header(&buf
, &decomp_buffer
);
339 if (!parse_templates(&buf
, FALSE
))
341 hr
= DXFILEERR_PARSEERROR
;
345 if (TRACE_ON(d3dxof
))
348 TRACE("Registered templates (%d):\n", This
->nb_xtemplates
);
349 for (i
= 1; i
< This
->nb_xtemplates
; i
++)
350 DPRINTF("%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
));
378 ERR("Out of memory\n");
379 return DXFILEERR_BADALLOC
;
382 object
->IDirectXFileBinary_iface
.lpVtbl
= &IDirectXFileBinary_Vtbl
;
390 static inline IDirectXFileBinaryImpl
*impl_from_IDirectXFileBinary(IDirectXFileBinary
*iface
)
392 return CONTAINING_RECORD(iface
, IDirectXFileBinaryImpl
, IDirectXFileBinary_iface
);
395 /*** IUnknown methods ***/
396 static HRESULT WINAPI
IDirectXFileBinaryImpl_QueryInterface(IDirectXFileBinary
* iface
, REFIID riid
, void** ppvObject
)
398 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
400 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
402 if (IsEqualGUID(riid
, &IID_IUnknown
)
403 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
404 || IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
406 IUnknown_AddRef(iface
);
407 *ppvObject
= &This
->IDirectXFileBinary_iface
;
411 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
412 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
)
413 && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
414 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
416 return E_NOINTERFACE
;
419 static ULONG WINAPI
IDirectXFileBinaryImpl_AddRef(IDirectXFileBinary
* iface
)
421 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
422 ULONG ref
= InterlockedIncrement(&This
->ref
);
424 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
429 static ULONG WINAPI
IDirectXFileBinaryImpl_Release(IDirectXFileBinary
* iface
)
431 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
432 ULONG ref
= InterlockedDecrement(&This
->ref
);
434 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
437 HeapFree(GetProcessHeap(), 0, This
);
442 /*** IDirectXFileObject methods ***/
443 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetName(IDirectXFileBinary
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
446 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
448 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
450 return DXFILEERR_BADVALUE
;
453 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetId(IDirectXFileBinary
* iface
, LPGUID pGuid
)
455 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
457 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pGuid
);
459 return DXFILEERR_BADVALUE
;
462 /*** IDirectXFileBinary methods ***/
463 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetSize(IDirectXFileBinary
* iface
, DWORD
* pcbSize
)
465 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
467 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pcbSize
);
469 return DXFILEERR_BADVALUE
;
472 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetMimeType(IDirectXFileBinary
* iface
, LPCSTR
* pszMimeType
)
474 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
476 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pszMimeType
);
478 return DXFILEERR_BADVALUE
;
481 static HRESULT WINAPI
IDirectXFileBinaryImpl_Read(IDirectXFileBinary
* iface
, LPVOID pvData
, DWORD cbSize
, LPDWORD pcbRead
)
483 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
485 FIXME("(%p/%p)->(%p, %d, %p) stub!\n", This
, iface
, pvData
, cbSize
, pcbRead
);
487 return DXFILEERR_BADVALUE
;
490 static const IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl
=
492 IDirectXFileBinaryImpl_QueryInterface
,
493 IDirectXFileBinaryImpl_AddRef
,
494 IDirectXFileBinaryImpl_Release
,
495 IDirectXFileBinaryImpl_GetName
,
496 IDirectXFileBinaryImpl_GetId
,
497 IDirectXFileBinaryImpl_GetSize
,
498 IDirectXFileBinaryImpl_GetMimeType
,
499 IDirectXFileBinaryImpl_Read
502 static HRESULT
IDirectXFileDataImpl_Create(IDirectXFileDataImpl
** ppObj
)
504 IDirectXFileDataImpl
* object
;
506 TRACE("(%p)\n", ppObj
);
508 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataImpl
));
511 ERR("Out of memory\n");
512 return DXFILEERR_BADALLOC
;
515 object
->IDirectXFileData_iface
.lpVtbl
= &IDirectXFileData_Vtbl
;
523 static inline IDirectXFileDataImpl
*impl_from_IDirectXFileData(IDirectXFileData
*iface
)
525 return CONTAINING_RECORD(iface
, IDirectXFileDataImpl
, IDirectXFileData_iface
);
528 /*** IUnknown methods ***/
529 static HRESULT WINAPI
IDirectXFileDataImpl_QueryInterface(IDirectXFileData
* iface
, REFIID riid
, void** ppvObject
)
531 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
533 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
535 if (IsEqualGUID(riid
, &IID_IUnknown
)
536 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
537 || IsEqualGUID(riid
, &IID_IDirectXFileData
))
539 IUnknown_AddRef(iface
);
540 *ppvObject
= &This
->IDirectXFileData_iface
;
544 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
545 if (!IsEqualGUID(riid
, &IID_IDirectXFileBinary
)
546 && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
547 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
549 return E_NOINTERFACE
;
552 static ULONG WINAPI
IDirectXFileDataImpl_AddRef(IDirectXFileData
* iface
)
554 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
555 ULONG ref
= InterlockedIncrement(&This
->ref
);
557 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
562 static ULONG WINAPI
IDirectXFileDataImpl_Release(IDirectXFileData
* iface
)
564 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
565 ULONG ref
= InterlockedDecrement(&This
->ref
);
567 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
571 if (!This
->level
&& !This
->from_ref
)
573 HeapFree(GetProcessHeap(), 0, This
->pstrings
);
576 HeapFree(GetProcessHeap(), 0, This
->pobj
->pdata
);
577 HeapFree(GetProcessHeap(), 0, This
->pobj
);
580 HeapFree(GetProcessHeap(), 0, This
);
586 /*** IDirectXFileObject methods ***/
587 static HRESULT WINAPI
IDirectXFileDataImpl_GetName(IDirectXFileData
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
589 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
592 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
595 return DXFILEERR_BADVALUE
;
597 len
= strlen(This
->pobj
->name
);
602 if (*pdwBufLen
< len
)
603 return DXFILEERR_BADVALUE
;
604 CopyMemory(pstrNameBuf
, This
->pobj
->name
, len
);
605 /* Even if we return a size of 0, an empty string with a null byte must be returned */
606 if (*pdwBufLen
&& !len
)
614 static HRESULT WINAPI
IDirectXFileDataImpl_GetId(IDirectXFileData
* iface
, LPGUID pGuid
)
616 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
618 TRACE("(%p/%p)->(%p)\n", This
, iface
, pGuid
);
621 return DXFILEERR_BADVALUE
;
623 memcpy(pGuid
, &This
->pobj
->class_id
, 16);
628 /*** IDirectXFileData methods ***/
629 static HRESULT WINAPI
IDirectXFileDataImpl_GetData(IDirectXFileData
* iface
, LPCSTR szMember
, DWORD
* pcbSize
, void** ppvData
)
631 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
633 TRACE("(%p/%p)->(%s,%p,%p)\n", This
, iface
, debugstr_a(szMember
), pcbSize
, ppvData
);
635 if (!pcbSize
|| !ppvData
)
636 return DXFILEERR_BADVALUE
;
641 for (i
= 0; i
< This
->pobj
->nb_members
; i
++)
642 if (!strcmp(This
->pobj
->members
[i
].name
, szMember
))
644 if (i
== This
->pobj
->nb_members
)
646 WARN("Unknown member '%s'\n", szMember
);
647 return DXFILEERR_BADDATAREFERENCE
;
649 *pcbSize
= This
->pobj
->members
[i
].size
;
650 *ppvData
= This
->pobj
->root
->pdata
+ This
->pobj
->members
[i
].start
;
654 *pcbSize
= This
->pobj
->size
;
655 *ppvData
= This
->pobj
->root
->pdata
+ This
->pobj
->pos_data
;
661 static HRESULT WINAPI
IDirectXFileDataImpl_GetType(IDirectXFileData
* iface
, const GUID
** pguid
)
663 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
666 TRACE("(%p/%p)->(%p)\n", This
, iface
, pguid
);
669 return DXFILEERR_BADVALUE
;
671 memcpy(&guid
, &This
->pobj
->type
, 16);
677 static HRESULT WINAPI
IDirectXFileDataImpl_GetNextObject(IDirectXFileData
* iface
, LPDIRECTXFILEOBJECT
* ppChildObj
)
680 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
682 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppChildObj
);
684 if (This
->cur_enum_object
>= This
->pobj
->nb_children
)
687 return DXFILEERR_NOMOREOBJECTS
;
690 if (This
->from_ref
&& (This
->level
>= 1))
692 /* Only 2 levels can be enumerated if the object is obtained from a reference */
694 return DXFILEERR_NOMOREOBJECTS
;
697 if (This
->pobj
->children
[This
->cur_enum_object
]->binary
)
699 IDirectXFileBinaryImpl
*object
;
701 hr
= IDirectXFileBinaryImpl_Create(&object
);
705 *ppChildObj
= (LPDIRECTXFILEOBJECT
)&object
->IDirectXFileBinary_iface
;
707 else if (This
->pobj
->children
[This
->cur_enum_object
]->ptarget
)
709 IDirectXFileDataReferenceImpl
*object
;
711 hr
= IDirectXFileDataReferenceImpl_Create(&object
);
715 object
->ptarget
= This
->pobj
->children
[This
->cur_enum_object
++]->ptarget
;
717 *ppChildObj
= (LPDIRECTXFILEOBJECT
)&object
->IDirectXFileDataReference_iface
;
721 IDirectXFileDataImpl
*object
;
723 hr
= IDirectXFileDataImpl_Create(&object
);
727 object
->pobj
= This
->pobj
->children
[This
->cur_enum_object
++];
728 object
->cur_enum_object
= 0;
729 object
->from_ref
= This
->from_ref
;
730 object
->level
= This
->level
+ 1;
732 *ppChildObj
= (LPDIRECTXFILEOBJECT
)&object
->IDirectXFileData_iface
;
738 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataObject(IDirectXFileData
* iface
, LPDIRECTXFILEDATA pDataObj
)
740 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
742 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pDataObj
);
744 return DXFILEERR_BADVALUE
;
747 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataReference(IDirectXFileData
* iface
, LPCSTR szRef
, const GUID
* pguidRef
)
749 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
751 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szRef
, pguidRef
);
753 return DXFILEERR_BADVALUE
;
756 static HRESULT WINAPI
IDirectXFileDataImpl_AddBinaryObject(IDirectXFileData
* iface
, LPCSTR szName
, const GUID
* pguid
, LPCSTR szMimeType
, LPVOID pvData
, DWORD cbSize
)
758 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
760 FIXME("(%p/%p)->(%s,%p,%s,%p,%d) stub!\n", This
, iface
, szName
, pguid
, szMimeType
, pvData
, cbSize
);
762 return DXFILEERR_BADVALUE
;
765 static const IDirectXFileDataVtbl IDirectXFileData_Vtbl
=
767 IDirectXFileDataImpl_QueryInterface
,
768 IDirectXFileDataImpl_AddRef
,
769 IDirectXFileDataImpl_Release
,
770 IDirectXFileDataImpl_GetName
,
771 IDirectXFileDataImpl_GetId
,
772 IDirectXFileDataImpl_GetData
,
773 IDirectXFileDataImpl_GetType
,
774 IDirectXFileDataImpl_GetNextObject
,
775 IDirectXFileDataImpl_AddDataObject
,
776 IDirectXFileDataImpl_AddDataReference
,
777 IDirectXFileDataImpl_AddBinaryObject
780 static HRESULT
IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl
** ppObj
)
782 IDirectXFileDataReferenceImpl
* object
;
784 TRACE("(%p)\n", ppObj
);
786 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataReferenceImpl
));
789 ERR("Out of memory\n");
790 return DXFILEERR_BADALLOC
;
793 object
->IDirectXFileDataReference_iface
.lpVtbl
= &IDirectXFileDataReference_Vtbl
;
801 static inline IDirectXFileDataReferenceImpl
*impl_from_IDirectXFileDataReference(IDirectXFileDataReference
*iface
)
803 return CONTAINING_RECORD(iface
, IDirectXFileDataReferenceImpl
, IDirectXFileDataReference_iface
);
806 /*** IUnknown methods ***/
807 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_QueryInterface(IDirectXFileDataReference
* iface
, REFIID riid
, void** ppvObject
)
809 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
811 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
813 if (IsEqualGUID(riid
, &IID_IUnknown
)
814 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
815 || IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
817 IUnknown_AddRef(iface
);
818 *ppvObject
= &This
->IDirectXFileDataReference_iface
;
822 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
823 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
)
824 && !IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
825 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
827 return E_NOINTERFACE
;
830 static ULONG WINAPI
IDirectXFileDataReferenceImpl_AddRef(IDirectXFileDataReference
* iface
)
832 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
833 ULONG ref
= InterlockedIncrement(&This
->ref
);
835 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
840 static ULONG WINAPI
IDirectXFileDataReferenceImpl_Release(IDirectXFileDataReference
* iface
)
842 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
843 ULONG ref
= InterlockedDecrement(&This
->ref
);
845 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
848 HeapFree(GetProcessHeap(), 0, This
);
853 /*** IDirectXFileObject methods ***/
854 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetName(IDirectXFileDataReference
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
856 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
859 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
862 return DXFILEERR_BADVALUE
;
864 len
= strlen(This
->ptarget
->name
);
869 if (*pdwBufLen
< len
)
870 return DXFILEERR_BADVALUE
;
871 CopyMemory(pstrNameBuf
, This
->ptarget
->name
, len
);
872 /* Even if we return a size of 0, an empty string with a null byte must be returned */
873 if (*pdwBufLen
&& !len
)
881 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetId(IDirectXFileDataReference
* iface
, LPGUID pGuid
)
883 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
885 TRACE("(%p/%p)->(%p)\n", This
, iface
, pGuid
);
888 return DXFILEERR_BADVALUE
;
890 memcpy(pGuid
, &This
->ptarget
->class_id
, 16);
895 /*** IDirectXFileDataReference ***/
896 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
898 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
899 IDirectXFileDataImpl
*object
;
902 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
905 return DXFILEERR_BADVALUE
;
907 hr
= IDirectXFileDataImpl_Create(&object
);
911 object
->pobj
= This
->ptarget
;
912 object
->cur_enum_object
= 0;
914 object
->from_ref
= TRUE
;
916 *ppDataObj
= (LPDIRECTXFILEDATA
)object
;
921 static const IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl
=
923 IDirectXFileDataReferenceImpl_QueryInterface
,
924 IDirectXFileDataReferenceImpl_AddRef
,
925 IDirectXFileDataReferenceImpl_Release
,
926 IDirectXFileDataReferenceImpl_GetName
,
927 IDirectXFileDataReferenceImpl_GetId
,
928 IDirectXFileDataReferenceImpl_Resolve
931 static HRESULT
IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl
** ppObj
)
933 IDirectXFileEnumObjectImpl
* object
;
935 TRACE("(%p)\n", ppObj
);
937 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileEnumObjectImpl
));
940 ERR("Out of memory\n");
941 return DXFILEERR_BADALLOC
;
944 object
->IDirectXFileEnumObject_iface
.lpVtbl
= &IDirectXFileEnumObject_Vtbl
;
952 static inline IDirectXFileEnumObjectImpl
*impl_from_IDirectXFileEnumObject(IDirectXFileEnumObject
*iface
)
954 return CONTAINING_RECORD(iface
, IDirectXFileEnumObjectImpl
, IDirectXFileEnumObject_iface
);
957 /*** IUnknown methods ***/
958 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_QueryInterface(IDirectXFileEnumObject
* iface
, REFIID riid
, void** ppvObject
)
960 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
962 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
964 if (IsEqualGUID(riid
, &IID_IUnknown
)
965 || IsEqualGUID(riid
, &IID_IDirectXFileEnumObject
))
967 IUnknown_AddRef(iface
);
968 *ppvObject
= &This
->IDirectXFileEnumObject_iface
;
972 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
973 return E_NOINTERFACE
;
976 static ULONG WINAPI
IDirectXFileEnumObjectImpl_AddRef(IDirectXFileEnumObject
* iface
)
978 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
979 ULONG ref
= InterlockedIncrement(&This
->ref
);
981 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
986 static ULONG WINAPI
IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject
* iface
)
988 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
989 ULONG ref
= InterlockedDecrement(&This
->ref
);
991 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
996 for (i
= 0; i
< This
->nb_xobjects
; i
++)
997 IDirectXFileData_Release(This
->pRefObjects
[i
]);
998 if (This
->mapped_memory
)
999 UnmapViewOfFile(This
->mapped_memory
);
1000 HeapFree(GetProcessHeap(), 0, This
->decomp_buffer
);
1001 HeapFree(GetProcessHeap(), 0, This
);
1007 /*** IDirectXFileEnumObject methods ***/
1008 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
1010 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
1011 IDirectXFileDataImpl
* object
;
1019 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
1021 if (This
->nb_xobjects
>= MAX_OBJECTS
)
1023 ERR("Too many objects\n");
1024 return DXFILEERR_NOMOREOBJECTS
;
1027 /* Check if there are templates defined before the object */
1028 if (!parse_templates(&This
->buf
, TRUE
))
1029 return DXFILEERR_PARSEERROR
;
1031 if (!This
->buf
.rem_bytes
)
1032 return DXFILEERR_NOMOREOBJECTS
;
1034 hr
= IDirectXFileDataImpl_Create(&object
);
1038 object
->pobj
= HeapAlloc(GetProcessHeap(), 0, sizeof(xobject
)*MAX_SUBOBJECTS
);
1041 ERR("Out of memory\n");
1042 hr
= DXFILEERR_BADALLOC
;
1046 object
->pstrings
= HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER
);
1047 if (!object
->pstrings
)
1049 ERR("Out of memory\n");
1050 hr
= DXFILEERR_BADALLOC
;
1054 object
->cur_enum_object
= 0;
1056 object
->from_ref
= FALSE
;
1058 This
->buf
.pxo_globals
= This
->xobjects
;
1059 This
->buf
.nb_pxo_globals
= This
->nb_xobjects
;
1060 This
->buf
.level
= 0;
1061 This
->buf
.pdata
= NULL
;
1062 This
->buf
.capacity
= 0;
1063 This
->buf
.cur_pos_data
= 0;
1064 This
->buf
.cur_pstrings
= This
->buf
.pstrings
= object
->pstrings
;
1065 This
->buf
.pxo
= This
->xobjects
[This
->nb_xobjects
] = This
->buf
.pxo_tab
= object
->pobj
;
1066 This
->buf
.pxo
->pdata
= NULL
;
1067 This
->buf
.pxo
->nb_subobjects
= 1;
1069 if (!parse_object(&This
->buf
))
1071 WARN("Object is not correct\n");
1072 hr
= DXFILEERR_PARSEERROR
;
1076 *ppDataObj
= (LPDIRECTXFILEDATA
)object
;
1078 /* Get a reference to created object */
1079 This
->pRefObjects
[This
->nb_xobjects
] = (LPDIRECTXFILEDATA
)object
;
1080 IDirectXFileData_AddRef(This
->pRefObjects
[This
->nb_xobjects
]);
1082 This
->nb_xobjects
++;
1088 IDirectXFileData_Release(&object
->IDirectXFileData_iface
);
1093 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectById(IDirectXFileEnumObject
* iface
, REFGUID rguid
, LPDIRECTXFILEDATA
* ppDataObj
)
1095 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
1097 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, rguid
, ppDataObj
);
1099 return DXFILEERR_BADVALUE
;
1102 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectByName(IDirectXFileEnumObject
* iface
, LPCSTR szName
, LPDIRECTXFILEDATA
* ppDataObj
)
1104 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
1106 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szName
, ppDataObj
);
1108 return DXFILEERR_BADVALUE
;
1111 static const IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl
=
1113 IDirectXFileEnumObjectImpl_QueryInterface
,
1114 IDirectXFileEnumObjectImpl_AddRef
,
1115 IDirectXFileEnumObjectImpl_Release
,
1116 IDirectXFileEnumObjectImpl_GetNextDataObject
,
1117 IDirectXFileEnumObjectImpl_GetDataObjectById
,
1118 IDirectXFileEnumObjectImpl_GetDataObjectByName
1121 static HRESULT
IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl
** ppObj
)
1123 IDirectXFileSaveObjectImpl
* object
;
1125 TRACE("(%p)\n", ppObj
);
1127 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileSaveObjectImpl
));
1130 ERR("Out of memory\n");
1131 return DXFILEERR_BADALLOC
;
1134 object
->IDirectXFileSaveObject_iface
.lpVtbl
= &IDirectXFileSaveObject_Vtbl
;
1142 static inline IDirectXFileSaveObjectImpl
*impl_from_IDirectXFileSaveObject(IDirectXFileSaveObject
*iface
)
1144 return CONTAINING_RECORD(iface
, IDirectXFileSaveObjectImpl
, IDirectXFileSaveObject_iface
);
1147 /*** IUnknown methods ***/
1148 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_QueryInterface(IDirectXFileSaveObject
* iface
, REFIID riid
, void** ppvObject
)
1150 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1152 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1154 if (IsEqualGUID(riid
, &IID_IUnknown
)
1155 || IsEqualGUID(riid
, &IID_IDirectXFileSaveObject
))
1157 IUnknown_AddRef(iface
);
1158 *ppvObject
= &This
->IDirectXFileSaveObject_iface
;
1162 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1163 return E_NOINTERFACE
;
1166 static ULONG WINAPI
IDirectXFileSaveObjectImpl_AddRef(IDirectXFileSaveObject
* iface
)
1168 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1169 ULONG ref
= InterlockedIncrement(&This
->ref
);
1171 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
1176 static ULONG WINAPI
IDirectXFileSaveObjectImpl_Release(IDirectXFileSaveObject
* iface
)
1178 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1179 ULONG ref
= InterlockedDecrement(&This
->ref
);
1181 TRACE("(%p/%p)->(): new ref %d\n", iface
, This
, ref
);
1184 HeapFree(GetProcessHeap(), 0, This
);
1189 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveTemplates(IDirectXFileSaveObject
* iface
, DWORD cTemplates
, const GUID
** ppguidTemplates
)
1191 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1193 FIXME("(%p/%p)->(%d,%p) stub!\n", This
, iface
, cTemplates
, ppguidTemplates
);
1198 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_CreateDataObject(IDirectXFileSaveObject
* iface
, REFGUID rguidTemplate
, LPCSTR szName
, const GUID
* pguid
, DWORD cbSize
, LPVOID pvData
, LPDIRECTXFILEDATA
* ppDataObj
)
1200 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1202 FIXME("(%p/%p)->(%p,%s,%p,%d,%p,%p) stub!\n", This
, iface
, rguidTemplate
, szName
, pguid
, cbSize
, pvData
, ppDataObj
);
1204 return DXFILEERR_BADVALUE
;
1207 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveData(IDirectXFileSaveObject
* iface
, LPDIRECTXFILEDATA ppDataObj
)
1209 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1211 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, ppDataObj
);
1213 return DXFILEERR_BADVALUE
;
1216 static const IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl
=
1218 IDirectXFileSaveObjectImpl_QueryInterface
,
1219 IDirectXFileSaveObjectImpl_AddRef
,
1220 IDirectXFileSaveObjectImpl_Release
,
1221 IDirectXFileSaveObjectImpl_SaveTemplates
,
1222 IDirectXFileSaveObjectImpl_CreateDataObject
,
1223 IDirectXFileSaveObjectImpl_SaveData