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 HRESULT
IDirectXFileImpl_Create(IUnknown
* pUnkOuter
, LPVOID
* ppObj
)
51 IDirectXFileImpl
* object
;
53 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
55 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileImpl
));
58 ERR("Out of memory\n");
59 return DXFILEERR_BADALLOC
;
62 object
->IDirectXFile_iface
.lpVtbl
= &IDirectXFile_Vtbl
;
65 *ppObj
= &object
->IDirectXFile_iface
;
70 static inline IDirectXFileImpl
*impl_from_IDirectXFile(IDirectXFile
*iface
)
72 return CONTAINING_RECORD(iface
, IDirectXFileImpl
, IDirectXFile_iface
);
75 /*** IUnknown methods ***/
76 static HRESULT WINAPI
IDirectXFileImpl_QueryInterface(IDirectXFile
* iface
, REFIID riid
, void** ppvObject
)
78 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
80 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
82 if (IsEqualGUID(riid
, &IID_IUnknown
)
83 || IsEqualGUID(riid
, &IID_IDirectXFile
))
85 IUnknown_AddRef(iface
);
86 *ppvObject
= &This
->IDirectXFile_iface
;
90 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
94 static ULONG WINAPI
IDirectXFileImpl_AddRef(IDirectXFile
* iface
)
96 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
97 ULONG ref
= InterlockedIncrement(&This
->ref
);
99 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
104 static ULONG WINAPI
IDirectXFileImpl_Release(IDirectXFile
* iface
)
106 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
107 ULONG ref
= InterlockedDecrement(&This
->ref
);
109 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
112 HeapFree(GetProcessHeap(), 0, This
);
117 /*** IDirectXFile methods ***/
118 static HRESULT WINAPI
IDirectXFileImpl_CreateEnumObject(IDirectXFile
* iface
, LPVOID pvSource
, DXFILELOADOPTIONS dwLoadOptions
, LPDIRECTXFILEENUMOBJECT
* ppEnumObj
)
120 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
121 IDirectXFileEnumObjectImpl
* object
;
126 TRACE("(%p/%p)->(%p,%x,%p)\n", This
, iface
, pvSource
, dwLoadOptions
, ppEnumObj
);
129 return DXFILEERR_BADVALUE
;
131 /* Only lowest 4 bits are relevant in DXFILELOADOPTIONS */
132 dwLoadOptions
&= 0xF;
134 hr
= IDirectXFileEnumObjectImpl_Create(&object
);
138 if (dwLoadOptions
== DXFILELOAD_FROMFILE
)
140 HANDLE hFile
, file_mapping
;
142 TRACE("Open source file '%s'\n", (char*)pvSource
);
144 hFile
= CreateFileA(pvSource
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
145 if (hFile
== INVALID_HANDLE_VALUE
)
147 TRACE("File '%s' not found\n", (char*)pvSource
);
148 return DXFILEERR_FILENOTFOUND
;
151 file_size
= GetFileSize(hFile
, NULL
);
153 file_mapping
= CreateFileMappingA(hFile
, NULL
, PAGE_READONLY
, 0, 0, NULL
);
157 hr
= DXFILEERR_BADFILETYPE
;
161 object
->mapped_memory
= MapViewOfFile(file_mapping
, FILE_MAP_READ
, 0, 0, 0);
162 CloseHandle(file_mapping
);
163 if (!object
->mapped_memory
)
165 hr
= DXFILEERR_BADFILETYPE
;
168 file_buffer
= object
->mapped_memory
;
170 else if (dwLoadOptions
== DXFILELOAD_FROMRESOURCE
)
173 HGLOBAL resource_data
;
174 LPDXFILELOADRESOURCE lpdxflr
= pvSource
;
176 TRACE("Source in resource (module = %p, name = %s, type = %s\n", lpdxflr
->hModule
, debugstr_a(lpdxflr
->lpName
), debugstr_a(lpdxflr
->lpType
));
178 resource_info
= FindResourceA(lpdxflr
->hModule
, lpdxflr
->lpName
, lpdxflr
->lpType
);
181 hr
= DXFILEERR_RESOURCENOTFOUND
;
185 file_size
= SizeofResource(lpdxflr
->hModule
, resource_info
);
187 resource_data
= LoadResource(lpdxflr
->hModule
, resource_info
);
190 hr
= DXFILEERR_BADRESOURCE
;
194 file_buffer
= LockResource(resource_data
);
197 hr
= DXFILEERR_BADRESOURCE
;
201 else if (dwLoadOptions
== DXFILELOAD_FROMMEMORY
)
203 LPDXFILELOADMEMORY lpdxflm
= pvSource
;
205 TRACE("Source in memory at %p with size %d\n", lpdxflm
->lpMemory
, lpdxflm
->dSize
);
207 file_buffer
= lpdxflm
->lpMemory
;
208 file_size
= lpdxflm
->dSize
;
212 FIXME("Source type %d is not handled yet\n", dwLoadOptions
);
213 hr
= DXFILEERR_NOTDONEYET
;
217 TRACE("File size is %d bytes\n", file_size
);
219 if (TRACE_ON(d3dxof_dump
))
224 sprintf(tmp
, "file%05u.x", num
++);
226 file
= CreateFileA(tmp
, GENERIC_WRITE
, FILE_SHARE_READ
, NULL
, CREATE_ALWAYS
, 0, NULL
);
227 if (file
!= INVALID_HANDLE_VALUE
)
229 WriteFile(file
, file_buffer
, file_size
, NULL
, NULL
);
234 object
->pDirectXFile
= This
;
236 object
->buf
.pdxf
= This
;
237 object
->buf
.token_present
= FALSE
;
238 object
->buf
.buffer
= file_buffer
;
239 object
->buf
.rem_bytes
= file_size
;
240 hr
= parse_header(&object
->buf
, &object
->decomp_buffer
);
244 if (!parse_templates(&object
->buf
)) {
245 hr
= DXFILEERR_BADVALUE
;
249 if (TRACE_ON(d3dxof
))
252 TRACE("Registered templates (%d):\n", This
->nb_xtemplates
);
253 for (i
= 0; i
< This
->nb_xtemplates
; i
++)
254 DPRINTF("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
257 *ppEnumObj
= &object
->IDirectXFileEnumObject_iface
;
262 IDirectXFileEnumObject_Release(&object
->IDirectXFileEnumObject_iface
);
268 static HRESULT WINAPI
IDirectXFileImpl_CreateSaveObject(IDirectXFile
* iface
, LPCSTR szFileName
, DXFILEFORMAT dwFileFormat
, LPDIRECTXFILESAVEOBJECT
* ppSaveObj
)
270 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
271 IDirectXFileSaveObjectImpl
*object
;
274 FIXME("(%p/%p)->(%s,%x,%p) partial stub!\n", This
, iface
, szFileName
, dwFileFormat
, ppSaveObj
);
276 if (!szFileName
|| !ppSaveObj
)
279 hr
= IDirectXFileSaveObjectImpl_Create(&object
);
281 *ppSaveObj
= &object
->IDirectXFileSaveObject_iface
;
285 static HRESULT WINAPI
IDirectXFileImpl_RegisterTemplates(IDirectXFile
* iface
, LPVOID pvData
, DWORD cbSize
)
287 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
290 LPBYTE decomp_buffer
= NULL
;
293 buf
.rem_bytes
= cbSize
;
295 buf
.token_present
= FALSE
;
298 TRACE("(%p/%p)->(%p,%d)\n", This
, iface
, pvData
, cbSize
);
301 return DXFILEERR_BADVALUE
;
303 if (TRACE_ON(d3dxof_dump
))
308 sprintf(tmp
, "template%05u.x", num
++);
310 file
= CreateFileA(tmp
, GENERIC_WRITE
, FILE_SHARE_READ
, NULL
, CREATE_ALWAYS
, 0, NULL
);
311 if (file
!= INVALID_HANDLE_VALUE
)
313 WriteFile(file
, pvData
, cbSize
, NULL
, NULL
);
318 hr
= parse_header(&buf
, &decomp_buffer
);
322 if (!parse_templates(&buf
)) {
323 hr
= DXFILEERR_BADVALUE
;
327 if (TRACE_ON(d3dxof
))
330 TRACE("Registered templates (%d):\n", This
->nb_xtemplates
);
331 for (i
= 0; i
< This
->nb_xtemplates
; i
++)
332 DPRINTF("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
337 HeapFree(GetProcessHeap(), 0, decomp_buffer
);
341 static const IDirectXFileVtbl IDirectXFile_Vtbl
=
343 IDirectXFileImpl_QueryInterface
,
344 IDirectXFileImpl_AddRef
,
345 IDirectXFileImpl_Release
,
346 IDirectXFileImpl_CreateEnumObject
,
347 IDirectXFileImpl_CreateSaveObject
,
348 IDirectXFileImpl_RegisterTemplates
351 static HRESULT
IDirectXFileBinaryImpl_Create(IDirectXFileBinaryImpl
** ppObj
)
353 IDirectXFileBinaryImpl
* object
;
355 TRACE("(%p)\n", ppObj
);
357 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileBinaryImpl
));
360 ERR("Out of memory\n");
361 return DXFILEERR_BADALLOC
;
364 object
->IDirectXFileBinary_iface
.lpVtbl
= &IDirectXFileBinary_Vtbl
;
372 static inline IDirectXFileBinaryImpl
*impl_from_IDirectXFileBinary(IDirectXFileBinary
*iface
)
374 return CONTAINING_RECORD(iface
, IDirectXFileBinaryImpl
, IDirectXFileBinary_iface
);
377 /*** IUnknown methods ***/
378 static HRESULT WINAPI
IDirectXFileBinaryImpl_QueryInterface(IDirectXFileBinary
* iface
, REFIID riid
, void** ppvObject
)
380 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
382 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
384 if (IsEqualGUID(riid
, &IID_IUnknown
)
385 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
386 || IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
388 IUnknown_AddRef(iface
);
389 *ppvObject
= &This
->IDirectXFileBinary_iface
;
393 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
394 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
)
395 && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
396 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
398 return E_NOINTERFACE
;
401 static ULONG WINAPI
IDirectXFileBinaryImpl_AddRef(IDirectXFileBinary
* iface
)
403 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
404 ULONG ref
= InterlockedIncrement(&This
->ref
);
406 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
411 static ULONG WINAPI
IDirectXFileBinaryImpl_Release(IDirectXFileBinary
* iface
)
413 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
414 ULONG ref
= InterlockedDecrement(&This
->ref
);
416 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
419 HeapFree(GetProcessHeap(), 0, This
);
424 /*** IDirectXFileObject methods ***/
425 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetName(IDirectXFileBinary
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
428 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
430 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
432 return DXFILEERR_BADVALUE
;
435 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetId(IDirectXFileBinary
* iface
, LPGUID pGuid
)
437 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
439 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pGuid
);
441 return DXFILEERR_BADVALUE
;
444 /*** IDirectXFileBinary methods ***/
445 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetSize(IDirectXFileBinary
* iface
, DWORD
* pcbSize
)
447 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
449 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pcbSize
);
451 return DXFILEERR_BADVALUE
;
454 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetMimeType(IDirectXFileBinary
* iface
, LPCSTR
* pszMimeType
)
456 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
458 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pszMimeType
);
460 return DXFILEERR_BADVALUE
;
463 static HRESULT WINAPI
IDirectXFileBinaryImpl_Read(IDirectXFileBinary
* iface
, LPVOID pvData
, DWORD cbSize
, LPDWORD pcbRead
)
465 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
467 FIXME("(%p/%p)->(%p, %d, %p) stub!\n", This
, iface
, pvData
, cbSize
, pcbRead
);
469 return DXFILEERR_BADVALUE
;
472 static const IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl
=
474 IDirectXFileBinaryImpl_QueryInterface
,
475 IDirectXFileBinaryImpl_AddRef
,
476 IDirectXFileBinaryImpl_Release
,
477 IDirectXFileBinaryImpl_GetName
,
478 IDirectXFileBinaryImpl_GetId
,
479 IDirectXFileBinaryImpl_GetSize
,
480 IDirectXFileBinaryImpl_GetMimeType
,
481 IDirectXFileBinaryImpl_Read
484 static HRESULT
IDirectXFileDataImpl_Create(IDirectXFileDataImpl
** ppObj
)
486 IDirectXFileDataImpl
* object
;
488 TRACE("(%p)\n", ppObj
);
490 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataImpl
));
493 ERR("Out of memory\n");
494 return DXFILEERR_BADALLOC
;
497 object
->IDirectXFileData_iface
.lpVtbl
= &IDirectXFileData_Vtbl
;
505 static inline IDirectXFileDataImpl
*impl_from_IDirectXFileData(IDirectXFileData
*iface
)
507 return CONTAINING_RECORD(iface
, IDirectXFileDataImpl
, IDirectXFileData_iface
);
510 /*** IUnknown methods ***/
511 static HRESULT WINAPI
IDirectXFileDataImpl_QueryInterface(IDirectXFileData
* iface
, REFIID riid
, void** ppvObject
)
513 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
515 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
517 if (IsEqualGUID(riid
, &IID_IUnknown
)
518 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
519 || IsEqualGUID(riid
, &IID_IDirectXFileData
))
521 IUnknown_AddRef(iface
);
522 *ppvObject
= &This
->IDirectXFileData_iface
;
526 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
527 if (!IsEqualGUID(riid
, &IID_IDirectXFileBinary
)
528 && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
529 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
531 return E_NOINTERFACE
;
534 static ULONG WINAPI
IDirectXFileDataImpl_AddRef(IDirectXFileData
* iface
)
536 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
537 ULONG ref
= InterlockedIncrement(&This
->ref
);
539 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
544 static ULONG WINAPI
IDirectXFileDataImpl_Release(IDirectXFileData
* iface
)
546 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
547 ULONG ref
= InterlockedDecrement(&This
->ref
);
549 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
553 if (!This
->level
&& !This
->from_ref
)
555 HeapFree(GetProcessHeap(), 0, This
->pstrings
);
558 HeapFree(GetProcessHeap(), 0, This
->pobj
->pdata
);
559 HeapFree(GetProcessHeap(), 0, This
->pobj
);
562 HeapFree(GetProcessHeap(), 0, This
);
568 /*** IDirectXFileObject methods ***/
569 static HRESULT WINAPI
IDirectXFileDataImpl_GetName(IDirectXFileData
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
571 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
574 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
577 return DXFILEERR_BADVALUE
;
579 len
= strlen(This
->pobj
->name
);
584 if (*pdwBufLen
< len
)
585 return DXFILEERR_BADVALUE
;
586 CopyMemory(pstrNameBuf
, This
->pobj
->name
, len
);
593 static HRESULT WINAPI
IDirectXFileDataImpl_GetId(IDirectXFileData
* iface
, LPGUID pGuid
)
595 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
597 TRACE("(%p/%p)->(%p)\n", This
, iface
, pGuid
);
600 return DXFILEERR_BADVALUE
;
602 memcpy(pGuid
, &This
->pobj
->class_id
, 16);
607 /*** IDirectXFileData methods ***/
608 static HRESULT WINAPI
IDirectXFileDataImpl_GetData(IDirectXFileData
* iface
, LPCSTR szMember
, DWORD
* pcbSize
, void** ppvData
)
610 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
612 TRACE("(%p/%p)->(%s,%p,%p)\n", This
, iface
, debugstr_a(szMember
), pcbSize
, ppvData
);
614 if (!pcbSize
|| !ppvData
)
615 return DXFILEERR_BADVALUE
;
620 for (i
= 0; i
< This
->pobj
->nb_members
; i
++)
621 if (!strcmp(This
->pobj
->members
[i
].name
, szMember
))
623 if (i
== This
->pobj
->nb_members
)
625 WARN("Unknown member '%s'\n", szMember
);
626 return DXFILEERR_BADDATAREFERENCE
;
628 *pcbSize
= This
->pobj
->members
[i
].size
;
629 *ppvData
= This
->pobj
->root
->pdata
+ This
->pobj
->members
[i
].start
;
633 *pcbSize
= This
->pobj
->size
;
634 *ppvData
= This
->pobj
->root
->pdata
+ This
->pobj
->pos_data
;
640 static HRESULT WINAPI
IDirectXFileDataImpl_GetType(IDirectXFileData
* iface
, const GUID
** pguid
)
642 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
645 TRACE("(%p/%p)->(%p)\n", This
, iface
, pguid
);
648 return DXFILEERR_BADVALUE
;
650 memcpy(&guid
, &This
->pobj
->type
, 16);
656 static HRESULT WINAPI
IDirectXFileDataImpl_GetNextObject(IDirectXFileData
* iface
, LPDIRECTXFILEOBJECT
* ppChildObj
)
659 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
661 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppChildObj
);
663 if (This
->cur_enum_object
>= This
->pobj
->nb_children
)
666 return DXFILEERR_NOMOREOBJECTS
;
669 if (This
->from_ref
&& (This
->level
>= 1))
671 /* Only 2 levels can be enumerated if the object is obtained from a reference */
673 return DXFILEERR_NOMOREOBJECTS
;
676 if (This
->pobj
->children
[This
->cur_enum_object
]->binary
)
678 IDirectXFileBinaryImpl
*object
;
680 hr
= IDirectXFileBinaryImpl_Create(&object
);
684 *ppChildObj
= (LPDIRECTXFILEOBJECT
)&object
->IDirectXFileBinary_iface
;
686 else if (This
->pobj
->children
[This
->cur_enum_object
]->ptarget
)
688 IDirectXFileDataReferenceImpl
*object
;
690 hr
= IDirectXFileDataReferenceImpl_Create(&object
);
694 object
->ptarget
= This
->pobj
->children
[This
->cur_enum_object
++]->ptarget
;
696 *ppChildObj
= (LPDIRECTXFILEOBJECT
)&object
->IDirectXFileDataReference_iface
;
700 IDirectXFileDataImpl
*object
;
702 hr
= IDirectXFileDataImpl_Create(&object
);
706 object
->pobj
= This
->pobj
->children
[This
->cur_enum_object
++];
707 object
->cur_enum_object
= 0;
708 object
->from_ref
= This
->from_ref
;
709 object
->level
= This
->level
+ 1;
711 *ppChildObj
= (LPDIRECTXFILEOBJECT
)&object
->IDirectXFileData_iface
;
717 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataObject(IDirectXFileData
* iface
, LPDIRECTXFILEDATA pDataObj
)
719 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
721 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pDataObj
);
723 return DXFILEERR_BADVALUE
;
726 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataReference(IDirectXFileData
* iface
, LPCSTR szRef
, const GUID
* pguidRef
)
728 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
730 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szRef
, pguidRef
);
732 return DXFILEERR_BADVALUE
;
735 static HRESULT WINAPI
IDirectXFileDataImpl_AddBinaryObject(IDirectXFileData
* iface
, LPCSTR szName
, const GUID
* pguid
, LPCSTR szMimeType
, LPVOID pvData
, DWORD cbSize
)
737 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
739 FIXME("(%p/%p)->(%s,%p,%s,%p,%d) stub!\n", This
, iface
, szName
, pguid
, szMimeType
, pvData
, cbSize
);
741 return DXFILEERR_BADVALUE
;
744 static const IDirectXFileDataVtbl IDirectXFileData_Vtbl
=
746 IDirectXFileDataImpl_QueryInterface
,
747 IDirectXFileDataImpl_AddRef
,
748 IDirectXFileDataImpl_Release
,
749 IDirectXFileDataImpl_GetName
,
750 IDirectXFileDataImpl_GetId
,
751 IDirectXFileDataImpl_GetData
,
752 IDirectXFileDataImpl_GetType
,
753 IDirectXFileDataImpl_GetNextObject
,
754 IDirectXFileDataImpl_AddDataObject
,
755 IDirectXFileDataImpl_AddDataReference
,
756 IDirectXFileDataImpl_AddBinaryObject
759 static HRESULT
IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl
** ppObj
)
761 IDirectXFileDataReferenceImpl
* object
;
763 TRACE("(%p)\n", ppObj
);
765 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataReferenceImpl
));
768 ERR("Out of memory\n");
769 return DXFILEERR_BADALLOC
;
772 object
->IDirectXFileDataReference_iface
.lpVtbl
= &IDirectXFileDataReference_Vtbl
;
780 static inline IDirectXFileDataReferenceImpl
*impl_from_IDirectXFileDataReference(IDirectXFileDataReference
*iface
)
782 return CONTAINING_RECORD(iface
, IDirectXFileDataReferenceImpl
, IDirectXFileDataReference_iface
);
785 /*** IUnknown methods ***/
786 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_QueryInterface(IDirectXFileDataReference
* iface
, REFIID riid
, void** ppvObject
)
788 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
790 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
792 if (IsEqualGUID(riid
, &IID_IUnknown
)
793 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
794 || IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
796 IUnknown_AddRef(iface
);
797 *ppvObject
= &This
->IDirectXFileDataReference_iface
;
801 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
802 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
)
803 && !IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
804 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
806 return E_NOINTERFACE
;
809 static ULONG WINAPI
IDirectXFileDataReferenceImpl_AddRef(IDirectXFileDataReference
* iface
)
811 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
812 ULONG ref
= InterlockedIncrement(&This
->ref
);
814 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
819 static ULONG WINAPI
IDirectXFileDataReferenceImpl_Release(IDirectXFileDataReference
* iface
)
821 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
822 ULONG ref
= InterlockedDecrement(&This
->ref
);
824 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
827 HeapFree(GetProcessHeap(), 0, This
);
832 /*** IDirectXFileObject methods ***/
833 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetName(IDirectXFileDataReference
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
835 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
838 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
841 return DXFILEERR_BADVALUE
;
843 len
= strlen(This
->ptarget
->name
);
848 if (*pdwBufLen
< len
)
849 return DXFILEERR_BADVALUE
;
850 CopyMemory(pstrNameBuf
, This
->ptarget
->name
, len
);
857 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetId(IDirectXFileDataReference
* iface
, LPGUID pGuid
)
859 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
861 TRACE("(%p/%p)->(%p)\n", This
, iface
, pGuid
);
864 return DXFILEERR_BADVALUE
;
866 memcpy(pGuid
, &This
->ptarget
->class_id
, 16);
871 /*** IDirectXFileDataReference ***/
872 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
874 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
875 IDirectXFileDataImpl
*object
;
878 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
881 return DXFILEERR_BADVALUE
;
883 hr
= IDirectXFileDataImpl_Create(&object
);
887 object
->pobj
= This
->ptarget
;
888 object
->cur_enum_object
= 0;
890 object
->from_ref
= TRUE
;
892 *ppDataObj
= (LPDIRECTXFILEDATA
)object
;
897 static const IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl
=
899 IDirectXFileDataReferenceImpl_QueryInterface
,
900 IDirectXFileDataReferenceImpl_AddRef
,
901 IDirectXFileDataReferenceImpl_Release
,
902 IDirectXFileDataReferenceImpl_GetName
,
903 IDirectXFileDataReferenceImpl_GetId
,
904 IDirectXFileDataReferenceImpl_Resolve
907 static HRESULT
IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl
** ppObj
)
909 IDirectXFileEnumObjectImpl
* object
;
911 TRACE("(%p)\n", ppObj
);
913 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileEnumObjectImpl
));
916 ERR("Out of memory\n");
917 return DXFILEERR_BADALLOC
;
920 object
->IDirectXFileEnumObject_iface
.lpVtbl
= &IDirectXFileEnumObject_Vtbl
;
928 static inline IDirectXFileEnumObjectImpl
*impl_from_IDirectXFileEnumObject(IDirectXFileEnumObject
*iface
)
930 return CONTAINING_RECORD(iface
, IDirectXFileEnumObjectImpl
, IDirectXFileEnumObject_iface
);
933 /*** IUnknown methods ***/
934 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_QueryInterface(IDirectXFileEnumObject
* iface
, REFIID riid
, void** ppvObject
)
936 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
938 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
940 if (IsEqualGUID(riid
, &IID_IUnknown
)
941 || IsEqualGUID(riid
, &IID_IDirectXFileEnumObject
))
943 IUnknown_AddRef(iface
);
944 *ppvObject
= &This
->IDirectXFileEnumObject_iface
;
948 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
949 return E_NOINTERFACE
;
952 static ULONG WINAPI
IDirectXFileEnumObjectImpl_AddRef(IDirectXFileEnumObject
* iface
)
954 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
955 ULONG ref
= InterlockedIncrement(&This
->ref
);
957 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
962 static ULONG WINAPI
IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject
* iface
)
964 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
965 ULONG ref
= InterlockedDecrement(&This
->ref
);
967 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
972 for (i
= 0; i
< This
->nb_xobjects
; i
++)
973 IDirectXFileData_Release(This
->pRefObjects
[i
]);
974 if (This
->mapped_memory
)
975 UnmapViewOfFile(This
->mapped_memory
);
976 HeapFree(GetProcessHeap(), 0, This
->decomp_buffer
);
977 HeapFree(GetProcessHeap(), 0, This
);
983 /*** IDirectXFileEnumObject methods ***/
984 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
986 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
987 IDirectXFileDataImpl
* object
;
990 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
992 if (This
->nb_xobjects
>= MAX_OBJECTS
)
994 ERR("Too many objects\n");
996 return DXFILEERR_NOMOREOBJECTS
;
999 /* Check if there are templates defined before the object */
1000 if (!parse_templates(&This
->buf
))
1002 hr
= DXFILEERR_BADVALUE
;
1006 if (!This
->buf
.rem_bytes
)
1009 return DXFILEERR_NOMOREOBJECTS
;
1012 hr
= IDirectXFileDataImpl_Create(&object
);
1016 object
->pobj
= HeapAlloc(GetProcessHeap(), 0, sizeof(xobject
)*MAX_SUBOBJECTS
);
1019 ERR("Out of memory\n");
1020 hr
= DXFILEERR_BADALLOC
;
1024 object
->pstrings
= HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER
);
1025 if (!object
->pstrings
)
1027 ERR("Out of memory\n");
1028 hr
= DXFILEERR_BADALLOC
;
1032 object
->cur_enum_object
= 0;
1034 object
->from_ref
= FALSE
;
1036 This
->buf
.pxo_globals
= This
->xobjects
;
1037 This
->buf
.nb_pxo_globals
= This
->nb_xobjects
;
1038 This
->buf
.level
= 0;
1039 This
->buf
.pdata
= NULL
;
1040 This
->buf
.capacity
= 0;
1041 This
->buf
.cur_pos_data
= 0;
1042 This
->buf
.cur_pstrings
= This
->buf
.pstrings
= object
->pstrings
;
1043 This
->buf
.pxo
= This
->xobjects
[This
->nb_xobjects
] = This
->buf
.pxo_tab
= object
->pobj
;
1044 This
->buf
.pxo
->pdata
= NULL
;
1045 This
->buf
.pxo
->nb_subobjects
= 1;
1047 if (!parse_object(&This
->buf
))
1049 WARN("Object is not correct\n");
1050 hr
= DXFILEERR_PARSEERROR
;
1054 *ppDataObj
= (LPDIRECTXFILEDATA
)object
;
1056 /* Get a reference to created object */
1057 This
->pRefObjects
[This
->nb_xobjects
] = (LPDIRECTXFILEDATA
)object
;
1058 IDirectXFileData_AddRef(This
->pRefObjects
[This
->nb_xobjects
]);
1060 This
->nb_xobjects
++;
1066 IDirectXFileData_Release(&object
->IDirectXFileData_iface
);
1072 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectById(IDirectXFileEnumObject
* iface
, REFGUID rguid
, LPDIRECTXFILEDATA
* ppDataObj
)
1074 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
1076 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, rguid
, ppDataObj
);
1078 return DXFILEERR_BADVALUE
;
1081 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectByName(IDirectXFileEnumObject
* iface
, LPCSTR szName
, LPDIRECTXFILEDATA
* ppDataObj
)
1083 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
1085 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szName
, ppDataObj
);
1087 return DXFILEERR_BADVALUE
;
1090 static const IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl
=
1092 IDirectXFileEnumObjectImpl_QueryInterface
,
1093 IDirectXFileEnumObjectImpl_AddRef
,
1094 IDirectXFileEnumObjectImpl_Release
,
1095 IDirectXFileEnumObjectImpl_GetNextDataObject
,
1096 IDirectXFileEnumObjectImpl_GetDataObjectById
,
1097 IDirectXFileEnumObjectImpl_GetDataObjectByName
1100 static HRESULT
IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl
** ppObj
)
1102 IDirectXFileSaveObjectImpl
* object
;
1104 TRACE("(%p)\n", ppObj
);
1106 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileSaveObjectImpl
));
1109 ERR("Out of memory\n");
1110 return DXFILEERR_BADALLOC
;
1113 object
->IDirectXFileSaveObject_iface
.lpVtbl
= &IDirectXFileSaveObject_Vtbl
;
1121 static inline IDirectXFileSaveObjectImpl
*impl_from_IDirectXFileSaveObject(IDirectXFileSaveObject
*iface
)
1123 return CONTAINING_RECORD(iface
, IDirectXFileSaveObjectImpl
, IDirectXFileSaveObject_iface
);
1126 /*** IUnknown methods ***/
1127 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_QueryInterface(IDirectXFileSaveObject
* iface
, REFIID riid
, void** ppvObject
)
1129 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1131 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1133 if (IsEqualGUID(riid
, &IID_IUnknown
)
1134 || IsEqualGUID(riid
, &IID_IDirectXFileSaveObject
))
1136 IUnknown_AddRef(iface
);
1137 *ppvObject
= &This
->IDirectXFileSaveObject_iface
;
1141 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1142 return E_NOINTERFACE
;
1145 static ULONG WINAPI
IDirectXFileSaveObjectImpl_AddRef(IDirectXFileSaveObject
* iface
)
1147 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1148 ULONG ref
= InterlockedIncrement(&This
->ref
);
1150 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
1155 static ULONG WINAPI
IDirectXFileSaveObjectImpl_Release(IDirectXFileSaveObject
* iface
)
1157 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1158 ULONG ref
= InterlockedDecrement(&This
->ref
);
1160 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
1163 HeapFree(GetProcessHeap(), 0, This
);
1168 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveTemplates(IDirectXFileSaveObject
* iface
, DWORD cTemplates
, const GUID
** ppguidTemplates
)
1170 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1172 FIXME("(%p/%p)->(%d,%p) stub!\n", This
, iface
, cTemplates
, ppguidTemplates
);
1177 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_CreateDataObject(IDirectXFileSaveObject
* iface
, REFGUID rguidTemplate
, LPCSTR szName
, const GUID
* pguid
, DWORD cbSize
, LPVOID pvData
, LPDIRECTXFILEDATA
* ppDataObj
)
1179 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1181 FIXME("(%p/%p)->(%p,%s,%p,%d,%p,%p) stub!\n", This
, iface
, rguidTemplate
, szName
, pguid
, cbSize
, pvData
, ppDataObj
);
1183 return DXFILEERR_BADVALUE
;
1186 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveData(IDirectXFileSaveObject
* iface
, LPDIRECTXFILEDATA ppDataObj
)
1188 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1190 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, ppDataObj
);
1192 return DXFILEERR_BADVALUE
;
1195 static const IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl
=
1197 IDirectXFileSaveObjectImpl_QueryInterface
,
1198 IDirectXFileSaveObjectImpl_AddRef
,
1199 IDirectXFileSaveObjectImpl_Release
,
1200 IDirectXFileSaveObjectImpl_SaveTemplates
,
1201 IDirectXFileSaveObjectImpl_CreateDataObject
,
1202 IDirectXFileSaveObjectImpl_SaveData