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
);
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 IDirectXFileObjectVtbl IDirectXFileObject_Vtbl
;
42 static const struct IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl
;
44 static HRESULT
IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl
** ppObj
);
45 static HRESULT
IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl
** ppObj
);
46 static HRESULT
IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl
** ppObj
);
48 HRESULT
IDirectXFileImpl_Create(IUnknown
* pUnkOuter
, LPVOID
* ppObj
)
50 IDirectXFileImpl
* object
;
52 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
54 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileImpl
));
57 ERR("Out of memory\n");
58 return DXFILEERR_BADALLOC
;
61 object
->IDirectXFile_iface
.lpVtbl
= &IDirectXFile_Vtbl
;
64 *ppObj
= &object
->IDirectXFile_iface
;
69 static inline IDirectXFileImpl
*impl_from_IDirectXFile(IDirectXFile
*iface
)
71 return CONTAINING_RECORD(iface
, IDirectXFileImpl
, IDirectXFile_iface
);
74 /*** IUnknown methods ***/
75 static HRESULT WINAPI
IDirectXFileImpl_QueryInterface(IDirectXFile
* iface
, REFIID riid
, void** ppvObject
)
77 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
79 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
81 if (IsEqualGUID(riid
, &IID_IUnknown
)
82 || IsEqualGUID(riid
, &IID_IDirectXFile
))
84 IUnknown_AddRef(iface
);
85 *ppvObject
= &This
->IDirectXFile_iface
;
89 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
93 static ULONG WINAPI
IDirectXFileImpl_AddRef(IDirectXFile
* iface
)
95 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
96 ULONG ref
= InterlockedIncrement(&This
->ref
);
98 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
103 static ULONG WINAPI
IDirectXFileImpl_Release(IDirectXFile
* iface
)
105 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
106 ULONG ref
= InterlockedDecrement(&This
->ref
);
108 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
111 HeapFree(GetProcessHeap(), 0, This
);
116 /*** IDirectXFile methods ***/
117 static HRESULT WINAPI
IDirectXFileImpl_CreateEnumObject(IDirectXFile
* iface
, LPVOID pvSource
, DXFILELOADOPTIONS dwLoadOptions
, LPDIRECTXFILEENUMOBJECT
* ppEnumObj
)
119 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
120 IDirectXFileEnumObjectImpl
* object
;
125 TRACE("(%p/%p)->(%p,%x,%p)\n", This
, iface
, pvSource
, dwLoadOptions
, ppEnumObj
);
128 return DXFILEERR_BADVALUE
;
130 /* Only lowest 4 bits are relevant in DXFILELOADOPTIONS */
131 dwLoadOptions
&= 0xF;
133 hr
= IDirectXFileEnumObjectImpl_Create(&object
);
137 if (dwLoadOptions
== DXFILELOAD_FROMFILE
)
139 HANDLE hFile
, file_mapping
;
141 TRACE("Open source file '%s'\n", (char*)pvSource
);
143 hFile
= CreateFileA(pvSource
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
144 if (hFile
== INVALID_HANDLE_VALUE
)
146 TRACE("File '%s' not found\n", (char*)pvSource
);
147 return DXFILEERR_FILENOTFOUND
;
150 file_size
= GetFileSize(hFile
, NULL
);
152 file_mapping
= CreateFileMappingA(hFile
, NULL
, PAGE_READONLY
, 0, 0, NULL
);
156 hr
= DXFILEERR_BADFILETYPE
;
160 object
->mapped_memory
= MapViewOfFile(file_mapping
, FILE_MAP_READ
, 0, 0, 0);
161 CloseHandle(file_mapping
);
162 if (!object
->mapped_memory
)
164 hr
= DXFILEERR_BADFILETYPE
;
167 file_buffer
= object
->mapped_memory
;
169 else if (dwLoadOptions
== DXFILELOAD_FROMRESOURCE
)
172 HGLOBAL resource_data
;
173 LPDXFILELOADRESOURCE lpdxflr
= pvSource
;
175 TRACE("Source in resource (module = %p, name = %s, type = %s\n", lpdxflr
->hModule
, debugstr_a(lpdxflr
->lpName
), debugstr_a(lpdxflr
->lpType
));
177 resource_info
= FindResourceA(lpdxflr
->hModule
, lpdxflr
->lpName
, lpdxflr
->lpType
);
180 hr
= DXFILEERR_RESOURCENOTFOUND
;
184 file_size
= SizeofResource(lpdxflr
->hModule
, resource_info
);
186 resource_data
= LoadResource(lpdxflr
->hModule
, resource_info
);
189 hr
= DXFILEERR_BADRESOURCE
;
193 file_buffer
= LockResource(resource_data
);
196 hr
= DXFILEERR_BADRESOURCE
;
200 else if (dwLoadOptions
== DXFILELOAD_FROMMEMORY
)
202 LPDXFILELOADMEMORY lpdxflm
= pvSource
;
204 TRACE("Source in memory at %p with size %d\n", lpdxflm
->lpMemory
, lpdxflm
->dSize
);
206 file_buffer
= lpdxflm
->lpMemory
;
207 file_size
= lpdxflm
->dSize
;
211 FIXME("Source type %d is not handled yet\n", dwLoadOptions
);
212 hr
= DXFILEERR_NOTDONEYET
;
216 TRACE("File size is %d bytes\n", file_size
);
218 object
->pDirectXFile
= This
;
220 object
->buf
.pdxf
= This
;
221 object
->buf
.token_present
= FALSE
;
222 object
->buf
.buffer
= file_buffer
;
223 object
->buf
.rem_bytes
= file_size
;
224 hr
= parse_header(&object
->buf
, &object
->decomp_buffer
);
228 if (!parse_templates(&object
->buf
)) {
229 hr
= DXFILEERR_BADVALUE
;
233 if (TRACE_ON(d3dxof
))
236 TRACE("Registered templates (%d):\n", This
->nb_xtemplates
);
237 for (i
= 0; i
< This
->nb_xtemplates
; i
++)
238 DPRINTF("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
241 *ppEnumObj
= &object
->IDirectXFileEnumObject_iface
;
246 IDirectXFileEnumObject_Release(&object
->IDirectXFileEnumObject_iface
);
252 static HRESULT WINAPI
IDirectXFileImpl_CreateSaveObject(IDirectXFile
* iface
, LPCSTR szFileName
, DXFILEFORMAT dwFileFormat
, LPDIRECTXFILESAVEOBJECT
* ppSaveObj
)
254 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
255 IDirectXFileSaveObjectImpl
*object
;
258 FIXME("(%p/%p)->(%s,%x,%p) partial stub!\n", This
, iface
, szFileName
, dwFileFormat
, ppSaveObj
);
260 if (!szFileName
|| !ppSaveObj
)
263 hr
= IDirectXFileSaveObjectImpl_Create(&object
);
265 *ppSaveObj
= &object
->IDirectXFileSaveObject_iface
;
269 static HRESULT WINAPI
IDirectXFileImpl_RegisterTemplates(IDirectXFile
* iface
, LPVOID pvData
, DWORD cbSize
)
271 IDirectXFileImpl
*This
= impl_from_IDirectXFile(iface
);
274 LPBYTE decomp_buffer
= NULL
;
277 buf
.rem_bytes
= cbSize
;
279 buf
.token_present
= FALSE
;
282 TRACE("(%p/%p)->(%p,%d)\n", This
, iface
, pvData
, cbSize
);
285 return DXFILEERR_BADVALUE
;
287 hr
= parse_header(&buf
, &decomp_buffer
);
291 if (!parse_templates(&buf
)) {
292 hr
= DXFILEERR_BADVALUE
;
296 if (TRACE_ON(d3dxof
))
299 TRACE("Registered templates (%d):\n", This
->nb_xtemplates
);
300 for (i
= 0; i
< This
->nb_xtemplates
; i
++)
301 DPRINTF("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
306 HeapFree(GetProcessHeap(), 0, decomp_buffer
);
310 static const IDirectXFileVtbl IDirectXFile_Vtbl
=
312 IDirectXFileImpl_QueryInterface
,
313 IDirectXFileImpl_AddRef
,
314 IDirectXFileImpl_Release
,
315 IDirectXFileImpl_CreateEnumObject
,
316 IDirectXFileImpl_CreateSaveObject
,
317 IDirectXFileImpl_RegisterTemplates
320 static HRESULT
IDirectXFileBinaryImpl_Create(IDirectXFileBinaryImpl
** ppObj
)
322 IDirectXFileBinaryImpl
* object
;
324 TRACE("(%p)\n", ppObj
);
326 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileBinaryImpl
));
329 ERR("Out of memory\n");
330 return DXFILEERR_BADALLOC
;
333 object
->IDirectXFileBinary_iface
.lpVtbl
= &IDirectXFileBinary_Vtbl
;
341 static inline IDirectXFileBinaryImpl
*impl_from_IDirectXFileBinary(IDirectXFileBinary
*iface
)
343 return CONTAINING_RECORD(iface
, IDirectXFileBinaryImpl
, IDirectXFileBinary_iface
);
346 /*** IUnknown methods ***/
347 static HRESULT WINAPI
IDirectXFileBinaryImpl_QueryInterface(IDirectXFileBinary
* iface
, REFIID riid
, void** ppvObject
)
349 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
351 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
353 if (IsEqualGUID(riid
, &IID_IUnknown
)
354 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
355 || IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
357 IUnknown_AddRef(iface
);
358 *ppvObject
= &This
->IDirectXFileBinary_iface
;
362 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
363 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
)
364 && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
365 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
367 return E_NOINTERFACE
;
370 static ULONG WINAPI
IDirectXFileBinaryImpl_AddRef(IDirectXFileBinary
* iface
)
372 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
373 ULONG ref
= InterlockedIncrement(&This
->ref
);
375 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
380 static ULONG WINAPI
IDirectXFileBinaryImpl_Release(IDirectXFileBinary
* iface
)
382 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
383 ULONG ref
= InterlockedDecrement(&This
->ref
);
385 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
388 HeapFree(GetProcessHeap(), 0, This
);
393 /*** IDirectXFileObject methods ***/
394 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetName(IDirectXFileBinary
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
397 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
399 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
401 return DXFILEERR_BADVALUE
;
404 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetId(IDirectXFileBinary
* iface
, LPGUID pGuid
)
406 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
408 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pGuid
);
410 return DXFILEERR_BADVALUE
;
413 /*** IDirectXFileBinary methods ***/
414 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetSize(IDirectXFileBinary
* iface
, DWORD
* pcbSize
)
416 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
418 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pcbSize
);
420 return DXFILEERR_BADVALUE
;
423 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetMimeType(IDirectXFileBinary
* iface
, LPCSTR
* pszMimeType
)
425 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
427 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pszMimeType
);
429 return DXFILEERR_BADVALUE
;
432 static HRESULT WINAPI
IDirectXFileBinaryImpl_Read(IDirectXFileBinary
* iface
, LPVOID pvData
, DWORD cbSize
, LPDWORD pcbRead
)
434 IDirectXFileBinaryImpl
*This
= impl_from_IDirectXFileBinary(iface
);
436 FIXME("(%p/%p)->(%p, %d, %p) stub!\n", This
, iface
, pvData
, cbSize
, pcbRead
);
438 return DXFILEERR_BADVALUE
;
441 static const IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl
=
443 IDirectXFileBinaryImpl_QueryInterface
,
444 IDirectXFileBinaryImpl_AddRef
,
445 IDirectXFileBinaryImpl_Release
,
446 IDirectXFileBinaryImpl_GetName
,
447 IDirectXFileBinaryImpl_GetId
,
448 IDirectXFileBinaryImpl_GetSize
,
449 IDirectXFileBinaryImpl_GetMimeType
,
450 IDirectXFileBinaryImpl_Read
453 static HRESULT
IDirectXFileDataImpl_Create(IDirectXFileDataImpl
** ppObj
)
455 IDirectXFileDataImpl
* object
;
457 TRACE("(%p)\n", ppObj
);
459 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataImpl
));
462 ERR("Out of memory\n");
463 return DXFILEERR_BADALLOC
;
466 object
->IDirectXFileData_iface
.lpVtbl
= &IDirectXFileData_Vtbl
;
474 static inline IDirectXFileDataImpl
*impl_from_IDirectXFileData(IDirectXFileData
*iface
)
476 return CONTAINING_RECORD(iface
, IDirectXFileDataImpl
, IDirectXFileData_iface
);
479 /*** IUnknown methods ***/
480 static HRESULT WINAPI
IDirectXFileDataImpl_QueryInterface(IDirectXFileData
* iface
, REFIID riid
, void** ppvObject
)
482 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
484 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
486 if (IsEqualGUID(riid
, &IID_IUnknown
)
487 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
488 || IsEqualGUID(riid
, &IID_IDirectXFileData
))
490 IUnknown_AddRef(iface
);
491 *ppvObject
= &This
->IDirectXFileData_iface
;
495 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
496 if (!IsEqualGUID(riid
, &IID_IDirectXFileBinary
)
497 && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
498 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
500 return E_NOINTERFACE
;
503 static ULONG WINAPI
IDirectXFileDataImpl_AddRef(IDirectXFileData
* iface
)
505 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
506 ULONG ref
= InterlockedIncrement(&This
->ref
);
508 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
513 static ULONG WINAPI
IDirectXFileDataImpl_Release(IDirectXFileData
* iface
)
515 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
516 ULONG ref
= InterlockedDecrement(&This
->ref
);
518 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
522 if (!This
->level
&& !This
->from_ref
)
524 HeapFree(GetProcessHeap(), 0, This
->pstrings
);
525 HeapFree(GetProcessHeap(), 0, This
->pobj
->pdata
);
526 HeapFree(GetProcessHeap(), 0, This
->pobj
);
528 HeapFree(GetProcessHeap(), 0, This
);
534 /*** IDirectXFileObject methods ***/
535 static HRESULT WINAPI
IDirectXFileDataImpl_GetName(IDirectXFileData
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
537 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
540 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
543 return DXFILEERR_BADVALUE
;
545 len
= strlen(This
->pobj
->name
);
550 if (*pdwBufLen
< len
)
551 return DXFILEERR_BADVALUE
;
552 CopyMemory(pstrNameBuf
, This
->pobj
->name
, len
);
559 static HRESULT WINAPI
IDirectXFileDataImpl_GetId(IDirectXFileData
* iface
, LPGUID pGuid
)
561 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
563 TRACE("(%p/%p)->(%p)\n", This
, iface
, pGuid
);
566 return DXFILEERR_BADVALUE
;
568 memcpy(pGuid
, &This
->pobj
->class_id
, 16);
573 /*** IDirectXFileData methods ***/
574 static HRESULT WINAPI
IDirectXFileDataImpl_GetData(IDirectXFileData
* iface
, LPCSTR szMember
, DWORD
* pcbSize
, void** ppvData
)
576 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
578 TRACE("(%p/%p)->(%s,%p,%p)\n", This
, iface
, debugstr_a(szMember
), pcbSize
, ppvData
);
580 if (!pcbSize
|| !ppvData
)
581 return DXFILEERR_BADVALUE
;
585 FIXME("Specifying a member is not supported yet!\n");
586 return DXFILEERR_BADVALUE
;
589 *pcbSize
= This
->pobj
->size
;
590 *ppvData
= This
->pobj
->root
->pdata
+ This
->pobj
->pos_data
;
595 static HRESULT WINAPI
IDirectXFileDataImpl_GetType(IDirectXFileData
* iface
, const GUID
** pguid
)
597 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
600 TRACE("(%p/%p)->(%p)\n", This
, iface
, pguid
);
603 return DXFILEERR_BADVALUE
;
605 memcpy(&guid
, &This
->pobj
->type
, 16);
611 static HRESULT WINAPI
IDirectXFileDataImpl_GetNextObject(IDirectXFileData
* iface
, LPDIRECTXFILEOBJECT
* ppChildObj
)
614 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
616 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppChildObj
);
618 if (This
->cur_enum_object
>= This
->pobj
->nb_children
)
619 return DXFILEERR_NOMOREOBJECTS
;
621 if (This
->from_ref
&& (This
->level
>= 1))
623 /* Only 2 levels can be enumerated if the object is obtained from a reference */
624 return DXFILEERR_NOMOREOBJECTS
;
627 if (This
->pobj
->children
[This
->cur_enum_object
]->binary
)
629 IDirectXFileBinaryImpl
*object
;
631 hr
= IDirectXFileBinaryImpl_Create(&object
);
635 *ppChildObj
= (LPDIRECTXFILEOBJECT
)&object
->IDirectXFileBinary_iface
;
637 else if (This
->pobj
->children
[This
->cur_enum_object
]->ptarget
)
639 IDirectXFileDataReferenceImpl
*object
;
641 hr
= IDirectXFileDataReferenceImpl_Create(&object
);
645 object
->ptarget
= This
->pobj
->children
[This
->cur_enum_object
++]->ptarget
;
647 *ppChildObj
= (LPDIRECTXFILEOBJECT
)&object
->IDirectXFileDataReference_iface
;
651 IDirectXFileDataImpl
*object
;
653 hr
= IDirectXFileDataImpl_Create(&object
);
657 object
->pobj
= This
->pobj
->children
[This
->cur_enum_object
++];
658 object
->cur_enum_object
= 0;
659 object
->from_ref
= This
->from_ref
;
660 object
->level
= This
->level
+ 1;
662 *ppChildObj
= (LPDIRECTXFILEOBJECT
)&object
->IDirectXFileData_iface
;
668 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataObject(IDirectXFileData
* iface
, LPDIRECTXFILEDATA pDataObj
)
670 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
672 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pDataObj
);
674 return DXFILEERR_BADVALUE
;
677 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataReference(IDirectXFileData
* iface
, LPCSTR szRef
, const GUID
* pguidRef
)
679 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
681 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szRef
, pguidRef
);
683 return DXFILEERR_BADVALUE
;
686 static HRESULT WINAPI
IDirectXFileDataImpl_AddBinaryObject(IDirectXFileData
* iface
, LPCSTR szName
, const GUID
* pguid
, LPCSTR szMimeType
, LPVOID pvData
, DWORD cbSize
)
688 IDirectXFileDataImpl
*This
= impl_from_IDirectXFileData(iface
);
690 FIXME("(%p/%p)->(%s,%p,%s,%p,%d) stub!\n", This
, iface
, szName
, pguid
, szMimeType
, pvData
, cbSize
);
692 return DXFILEERR_BADVALUE
;
695 static const IDirectXFileDataVtbl IDirectXFileData_Vtbl
=
697 IDirectXFileDataImpl_QueryInterface
,
698 IDirectXFileDataImpl_AddRef
,
699 IDirectXFileDataImpl_Release
,
700 IDirectXFileDataImpl_GetName
,
701 IDirectXFileDataImpl_GetId
,
702 IDirectXFileDataImpl_GetData
,
703 IDirectXFileDataImpl_GetType
,
704 IDirectXFileDataImpl_GetNextObject
,
705 IDirectXFileDataImpl_AddDataObject
,
706 IDirectXFileDataImpl_AddDataReference
,
707 IDirectXFileDataImpl_AddBinaryObject
710 static HRESULT
IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl
** ppObj
)
712 IDirectXFileDataReferenceImpl
* object
;
714 TRACE("(%p)\n", ppObj
);
716 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataReferenceImpl
));
719 ERR("Out of memory\n");
720 return DXFILEERR_BADALLOC
;
723 object
->IDirectXFileDataReference_iface
.lpVtbl
= &IDirectXFileDataReference_Vtbl
;
731 static inline IDirectXFileDataReferenceImpl
*impl_from_IDirectXFileDataReference(IDirectXFileDataReference
*iface
)
733 return CONTAINING_RECORD(iface
, IDirectXFileDataReferenceImpl
, IDirectXFileDataReference_iface
);
736 /*** IUnknown methods ***/
737 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_QueryInterface(IDirectXFileDataReference
* iface
, REFIID riid
, void** ppvObject
)
739 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
741 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
743 if (IsEqualGUID(riid
, &IID_IUnknown
)
744 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
745 || IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
747 IUnknown_AddRef(iface
);
748 *ppvObject
= &This
->IDirectXFileDataReference_iface
;
752 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
753 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
)
754 && !IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
755 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
757 return E_NOINTERFACE
;
760 static ULONG WINAPI
IDirectXFileDataReferenceImpl_AddRef(IDirectXFileDataReference
* iface
)
762 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
763 ULONG ref
= InterlockedIncrement(&This
->ref
);
765 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
770 static ULONG WINAPI
IDirectXFileDataReferenceImpl_Release(IDirectXFileDataReference
* iface
)
772 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
773 ULONG ref
= InterlockedDecrement(&This
->ref
);
775 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
778 HeapFree(GetProcessHeap(), 0, This
);
783 /*** IDirectXFileObject methods ***/
784 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetName(IDirectXFileDataReference
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
786 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
789 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
792 return DXFILEERR_BADVALUE
;
794 len
= strlen(This
->ptarget
->name
);
799 if (*pdwBufLen
< len
)
800 return DXFILEERR_BADVALUE
;
801 CopyMemory(pstrNameBuf
, This
->ptarget
->name
, len
);
808 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetId(IDirectXFileDataReference
* iface
, LPGUID pGuid
)
810 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
812 TRACE("(%p/%p)->(%p)\n", This
, iface
, pGuid
);
815 return DXFILEERR_BADVALUE
;
817 memcpy(pGuid
, &This
->ptarget
->class_id
, 16);
822 /*** IDirectXFileDataReference ***/
823 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
825 IDirectXFileDataReferenceImpl
*This
= impl_from_IDirectXFileDataReference(iface
);
826 IDirectXFileDataImpl
*object
;
829 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
832 return DXFILEERR_BADVALUE
;
834 hr
= IDirectXFileDataImpl_Create(&object
);
838 object
->pobj
= This
->ptarget
;
839 object
->cur_enum_object
= 0;
841 object
->from_ref
= TRUE
;
843 *ppDataObj
= (LPDIRECTXFILEDATA
)object
;
848 static const IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl
=
850 IDirectXFileDataReferenceImpl_QueryInterface
,
851 IDirectXFileDataReferenceImpl_AddRef
,
852 IDirectXFileDataReferenceImpl_Release
,
853 IDirectXFileDataReferenceImpl_GetName
,
854 IDirectXFileDataReferenceImpl_GetId
,
855 IDirectXFileDataReferenceImpl_Resolve
858 static HRESULT
IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl
** ppObj
)
860 IDirectXFileEnumObjectImpl
* object
;
862 TRACE("(%p)\n", ppObj
);
864 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileEnumObjectImpl
));
867 ERR("Out of memory\n");
868 return DXFILEERR_BADALLOC
;
871 object
->IDirectXFileEnumObject_iface
.lpVtbl
= &IDirectXFileEnumObject_Vtbl
;
879 static inline IDirectXFileEnumObjectImpl
*impl_from_IDirectXFileEnumObject(IDirectXFileEnumObject
*iface
)
881 return CONTAINING_RECORD(iface
, IDirectXFileEnumObjectImpl
, IDirectXFileEnumObject_iface
);
884 /*** IUnknown methods ***/
885 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_QueryInterface(IDirectXFileEnumObject
* iface
, REFIID riid
, void** ppvObject
)
887 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
889 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
891 if (IsEqualGUID(riid
, &IID_IUnknown
)
892 || IsEqualGUID(riid
, &IID_IDirectXFileEnumObject
))
894 IUnknown_AddRef(iface
);
895 *ppvObject
= &This
->IDirectXFileEnumObject_iface
;
899 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
900 return E_NOINTERFACE
;
903 static ULONG WINAPI
IDirectXFileEnumObjectImpl_AddRef(IDirectXFileEnumObject
* iface
)
905 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
906 ULONG ref
= InterlockedIncrement(&This
->ref
);
908 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
913 static ULONG WINAPI
IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject
* iface
)
915 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
916 ULONG ref
= InterlockedDecrement(&This
->ref
);
918 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
923 for (i
= 0; i
< This
->nb_xobjects
; i
++)
924 IDirectXFileData_Release(This
->pRefObjects
[i
]);
925 if (This
->mapped_memory
)
926 UnmapViewOfFile(This
->mapped_memory
);
927 HeapFree(GetProcessHeap(), 0, This
->decomp_buffer
);
928 HeapFree(GetProcessHeap(), 0, This
);
934 /*** IDirectXFileEnumObject methods ***/
935 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
937 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
938 IDirectXFileDataImpl
* object
;
940 LPBYTE pstrings
= NULL
;
942 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
944 if (This
->nb_xobjects
>= MAX_OBJECTS
)
946 ERR("Too many objects\n");
947 return DXFILEERR_NOMOREOBJECTS
;
950 /* Check if there are templates defined before the object */
951 if (!parse_templates(&This
->buf
)) {
952 hr
= DXFILEERR_BADVALUE
;
956 if (!This
->buf
.rem_bytes
)
957 return DXFILEERR_NOMOREOBJECTS
;
959 hr
= IDirectXFileDataImpl_Create(&object
);
963 This
->buf
.pxo_globals
= This
->xobjects
;
964 This
->buf
.nb_pxo_globals
= This
->nb_xobjects
;
967 This
->buf
.pxo_tab
= HeapAlloc(GetProcessHeap(), 0, sizeof(xobject
)*MAX_SUBOBJECTS
);
968 if (!This
->buf
.pxo_tab
)
970 ERR("Out of memory\n");
971 hr
= DXFILEERR_BADALLOC
;
974 This
->buf
.pxo
= This
->xobjects
[This
->nb_xobjects
] = This
->buf
.pxo_tab
;
976 This
->buf
.pxo
->pdata
= This
->buf
.pdata
= NULL
;
977 This
->buf
.capacity
= 0;
978 This
->buf
.cur_pos_data
= 0;
979 This
->buf
.pxo
->nb_subobjects
= 1;
981 pstrings
= HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER
);
984 ERR("Out of memory\n");
985 hr
= DXFILEERR_BADALLOC
;
988 This
->buf
.cur_pstrings
= This
->buf
.pstrings
= object
->pstrings
= pstrings
;
990 if (!parse_object(&This
->buf
))
992 WARN("Object is not correct\n");
993 hr
= DXFILEERR_PARSEERROR
;
997 object
->pstrings
= pstrings
;
998 object
->pobj
= This
->buf
.pxo
;
999 object
->cur_enum_object
= 0;
1001 object
->from_ref
= FALSE
;
1003 *ppDataObj
= (LPDIRECTXFILEDATA
)object
;
1005 /* Get a reference to created object */
1006 This
->pRefObjects
[This
->nb_xobjects
] = (LPDIRECTXFILEDATA
)object
;
1007 IDirectXFileData_AddRef(This
->pRefObjects
[This
->nb_xobjects
]);
1009 This
->nb_xobjects
++;
1015 HeapFree(GetProcessHeap(), 0, This
->buf
.pxo_tab
);
1016 HeapFree(GetProcessHeap(), 0, This
->buf
.pdata
);
1017 HeapFree(GetProcessHeap(), 0, pstrings
);
1022 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectById(IDirectXFileEnumObject
* iface
, REFGUID rguid
, LPDIRECTXFILEDATA
* ppDataObj
)
1024 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
1026 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, rguid
, ppDataObj
);
1028 return DXFILEERR_BADVALUE
;
1031 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectByName(IDirectXFileEnumObject
* iface
, LPCSTR szName
, LPDIRECTXFILEDATA
* ppDataObj
)
1033 IDirectXFileEnumObjectImpl
*This
= impl_from_IDirectXFileEnumObject(iface
);
1035 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szName
, ppDataObj
);
1037 return DXFILEERR_BADVALUE
;
1040 static const IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl
=
1042 IDirectXFileEnumObjectImpl_QueryInterface
,
1043 IDirectXFileEnumObjectImpl_AddRef
,
1044 IDirectXFileEnumObjectImpl_Release
,
1045 IDirectXFileEnumObjectImpl_GetNextDataObject
,
1046 IDirectXFileEnumObjectImpl_GetDataObjectById
,
1047 IDirectXFileEnumObjectImpl_GetDataObjectByName
1050 static HRESULT
IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl
** ppObj
)
1052 IDirectXFileSaveObjectImpl
* object
;
1054 TRACE("(%p)\n", ppObj
);
1056 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileSaveObjectImpl
));
1059 ERR("Out of memory\n");
1060 return DXFILEERR_BADALLOC
;
1063 object
->IDirectXFileSaveObject_iface
.lpVtbl
= &IDirectXFileSaveObject_Vtbl
;
1071 static inline IDirectXFileSaveObjectImpl
*impl_from_IDirectXFileSaveObject(IDirectXFileSaveObject
*iface
)
1073 return CONTAINING_RECORD(iface
, IDirectXFileSaveObjectImpl
, IDirectXFileSaveObject_iface
);
1076 /*** IUnknown methods ***/
1077 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_QueryInterface(IDirectXFileSaveObject
* iface
, REFIID riid
, void** ppvObject
)
1079 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1081 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1083 if (IsEqualGUID(riid
, &IID_IUnknown
)
1084 || IsEqualGUID(riid
, &IID_IDirectXFileSaveObject
))
1086 IUnknown_AddRef(iface
);
1087 *ppvObject
= &This
->IDirectXFileSaveObject_iface
;
1091 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1092 return E_NOINTERFACE
;
1095 static ULONG WINAPI
IDirectXFileSaveObjectImpl_AddRef(IDirectXFileSaveObject
* iface
)
1097 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1098 ULONG ref
= InterlockedIncrement(&This
->ref
);
1100 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
1105 static ULONG WINAPI
IDirectXFileSaveObjectImpl_Release(IDirectXFileSaveObject
* iface
)
1107 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1108 ULONG ref
= InterlockedDecrement(&This
->ref
);
1110 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
1113 HeapFree(GetProcessHeap(), 0, This
);
1118 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveTemplates(IDirectXFileSaveObject
* iface
, DWORD cTemplates
, const GUID
** ppguidTemplates
)
1120 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1122 FIXME("(%p/%p)->(%d,%p) stub!\n", This
, iface
, cTemplates
, ppguidTemplates
);
1124 return DXFILEERR_BADVALUE
;
1127 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_CreateDataObject(IDirectXFileSaveObject
* iface
, REFGUID rguidTemplate
, LPCSTR szName
, const GUID
* pguid
, DWORD cbSize
, LPVOID pvData
, LPDIRECTXFILEDATA
* ppDataObj
)
1129 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1131 FIXME("(%p/%p)->(%p,%s,%p,%d,%p,%p) stub!\n", This
, iface
, rguidTemplate
, szName
, pguid
, cbSize
, pvData
, ppDataObj
);
1133 return DXFILEERR_BADVALUE
;
1136 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveData(IDirectXFileSaveObject
* iface
, LPDIRECTXFILEDATA ppDataObj
)
1138 IDirectXFileSaveObjectImpl
*This
= impl_from_IDirectXFileSaveObject(iface
);
1140 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, ppDataObj
);
1142 return DXFILEERR_BADVALUE
;
1145 static const IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl
=
1147 IDirectXFileSaveObjectImpl_QueryInterface
,
1148 IDirectXFileSaveObjectImpl_AddRef
,
1149 IDirectXFileSaveObjectImpl_Release
,
1150 IDirectXFileSaveObjectImpl_SaveTemplates
,
1151 IDirectXFileSaveObjectImpl_CreateDataObject
,
1152 IDirectXFileSaveObjectImpl_SaveData