2 * Implementation of DirectX File Interfaces
4 * Copyright 2004, 2008 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 #define MAKEFOUR(a,b,c,d) ((DWORD)a + ((DWORD)b << 8) + ((DWORD)c << 16) + ((DWORD)d << 24))
37 #define XOFFILE_FORMAT_MAGIC MAKEFOUR('x','o','f',' ')
38 #define XOFFILE_FORMAT_VERSION_302 MAKEFOUR('0','3','0','2')
39 #define XOFFILE_FORMAT_VERSION_303 MAKEFOUR('0','3','0','3')
40 #define XOFFILE_FORMAT_BINARY MAKEFOUR('b','i','n',' ')
41 #define XOFFILE_FORMAT_TEXT MAKEFOUR('t','x','t',' ')
42 #define XOFFILE_FORMAT_BINARY_MSZIP MAKEFOUR('b','z','i','p')
43 #define XOFFILE_FORMAT_TEXT_MSZIP MAKEFOUR('t','z','i','p')
44 #define XOFFILE_FORMAT_COMPRESSED MAKEFOUR('c','m','p',' ')
45 #define XOFFILE_FORMAT_FLOAT_BITS_32 MAKEFOUR('0','0','3','2')
46 #define XOFFILE_FORMAT_FLOAT_BITS_64 MAKEFOUR('0','0','6','4')
48 static const struct IDirectXFileVtbl IDirectXFile_Vtbl
;
49 static const struct IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl
;
50 static const struct IDirectXFileDataVtbl IDirectXFileData_Vtbl
;
51 static const struct IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl
;
52 static const struct IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl
;
53 static const struct IDirectXFileObjectVtbl IDirectXFileObject_Vtbl
;
54 static const struct IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl
;
56 static HRESULT
IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl
** ppObj
);
57 static HRESULT
IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl
** ppObj
);
58 static HRESULT
IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl
** ppObj
);
60 /* FOURCC to string conversion for debug messages */
61 const char *debugstr_fourcc(DWORD fourcc
)
63 if (!fourcc
) return "'null'";
64 return wine_dbg_sprintf ("\'%c%c%c%c\'",
65 (char)(fourcc
), (char)(fourcc
>> 8),
66 (char)(fourcc
>> 16), (char)(fourcc
>> 24));
69 HRESULT
IDirectXFileImpl_Create(IUnknown
* pUnkOuter
, LPVOID
* ppObj
)
71 IDirectXFileImpl
* object
;
73 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
75 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileImpl
));
78 ERR("Out of memory\n");
79 return DXFILEERR_BADALLOC
;
82 object
->lpVtbl
= &IDirectXFile_Vtbl
;
90 /*** IUnknown methods ***/
91 static HRESULT WINAPI
IDirectXFileImpl_QueryInterface(IDirectXFile
* iface
, REFIID riid
, void** ppvObject
)
93 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
95 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
97 if (IsEqualGUID(riid
, &IID_IUnknown
)
98 || IsEqualGUID(riid
, &IID_IDirectXFile
))
100 IUnknown_AddRef(iface
);
105 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
106 return E_NOINTERFACE
;
109 static ULONG WINAPI
IDirectXFileImpl_AddRef(IDirectXFile
* iface
)
111 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
112 ULONG ref
= InterlockedIncrement(&This
->ref
);
114 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
119 static ULONG WINAPI
IDirectXFileImpl_Release(IDirectXFile
* iface
)
121 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
122 ULONG ref
= InterlockedDecrement(&This
->ref
);
124 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
127 HeapFree(GetProcessHeap(), 0, This
);
132 /*** IDirectXFile methods ***/
133 static HRESULT WINAPI
IDirectXFileImpl_CreateEnumObject(IDirectXFile
* iface
, LPVOID pvSource
, DXFILELOADOPTIONS dwLoadOptions
, LPDIRECTXFILEENUMOBJECT
* ppEnumObj
)
135 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
136 IDirectXFileEnumObjectImpl
* object
;
139 HANDLE hFile
= INVALID_HANDLE_VALUE
;
140 HANDLE file_mapping
= 0;
141 LPBYTE buffer
= NULL
;
142 HGLOBAL resource_data
= 0;
146 LPDXFILELOADMEMORY lpdxflm
= NULL
;
148 TRACE("(%p/%p)->(%p,%x,%p)\n", This
, iface
, pvSource
, dwLoadOptions
, ppEnumObj
);
151 return DXFILEERR_BADVALUE
;
153 /* Only lowest 4 bits are relevant in DXFILELOADOPTIONS */
154 dwLoadOptions
&= 0xF;
156 if (dwLoadOptions
== DXFILELOAD_FROMFILE
)
158 TRACE("Open source file '%s'\n", (char*)pvSource
);
160 hFile
= CreateFileA(pvSource
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
161 if (hFile
== INVALID_HANDLE_VALUE
)
163 TRACE("File '%s' not found\n", (char*)pvSource
);
164 return DXFILEERR_FILENOTFOUND
;
167 file_size
= GetFileSize(hFile
, NULL
);
169 file_mapping
= CreateFileMappingA(hFile
, NULL
, PAGE_READONLY
, 0, 0, NULL
);
172 hr
= DXFILEERR_BADFILETYPE
;
176 buffer
= MapViewOfFile(file_mapping
, FILE_MAP_READ
, 0, 0, 0);
179 hr
= DXFILEERR_BADFILETYPE
;
182 file_buffer
= buffer
;
184 else if (dwLoadOptions
== DXFILELOAD_FROMRESOURCE
)
187 LPDXFILELOADRESOURCE lpdxflr
= pvSource
;
189 TRACE("Source in resource (module = %p, name = %s, type = %s\n", lpdxflr
->hModule
, debugstr_a(lpdxflr
->lpName
), debugstr_a(lpdxflr
->lpType
));
191 resource_info
= FindResourceA(lpdxflr
->hModule
, lpdxflr
->lpName
, lpdxflr
->lpType
);
194 hr
= DXFILEERR_RESOURCENOTFOUND
;
198 file_size
= SizeofResource(lpdxflr
->hModule
, resource_info
);
200 resource_data
= LoadResource(lpdxflr
->hModule
, resource_info
);
203 hr
= DXFILEERR_BADRESOURCE
;
207 file_buffer
= LockResource(resource_data
);
210 hr
= DXFILEERR_BADRESOURCE
;
214 else if (dwLoadOptions
== DXFILELOAD_FROMMEMORY
)
218 TRACE("Source in memory at %p with size %d\n", lpdxflm
->lpMemory
, lpdxflm
->dSize
);
220 file_buffer
= lpdxflm
->lpMemory
;
221 file_size
= lpdxflm
->dSize
;
225 FIXME("Source type %d is not handled yet\n", dwLoadOptions
);
226 hr
= DXFILEERR_NOTDONEYET
;
230 header
= (DWORD
*)file_buffer
;
232 if (TRACE_ON(d3dxof
))
235 memcpy(string
, header
, 16);
237 TRACE("header = '%s'\n", string
);
242 hr
= DXFILEERR_BADFILETYPE
;
246 if (header
[0] != XOFFILE_FORMAT_MAGIC
)
248 hr
= DXFILEERR_BADFILETYPE
;
252 if ((header
[1] != XOFFILE_FORMAT_VERSION_302
) && (header
[1] != XOFFILE_FORMAT_VERSION_303
))
254 hr
= DXFILEERR_BADFILEVERSION
;
258 if ((header
[2] != XOFFILE_FORMAT_BINARY
) && (header
[2] != XOFFILE_FORMAT_TEXT
) &&
259 (header
[2] != XOFFILE_FORMAT_BINARY_MSZIP
) && (header
[2] != XOFFILE_FORMAT_TEXT_MSZIP
))
261 WARN("File type %s unknown\n", debugstr_fourcc(header
[2]));
262 hr
= DXFILEERR_BADFILETYPE
;
266 if ((header
[2] == XOFFILE_FORMAT_BINARY_MSZIP
) || (header
[2] == XOFFILE_FORMAT_TEXT_MSZIP
))
268 FIXME("Compressed format %s not supported yet\n", debugstr_fourcc(header
[2]));
269 hr
= DXFILEERR_BADALLOC
;
273 if ((header
[3] != XOFFILE_FORMAT_FLOAT_BITS_32
) && (header
[3] != XOFFILE_FORMAT_FLOAT_BITS_64
))
275 hr
= DXFILEERR_BADFILEFLOATSIZE
;
279 TRACE("Header is correct\n");
281 hr
= IDirectXFileEnumObjectImpl_Create(&object
);
285 object
->source
= dwLoadOptions
;
286 object
->hFile
= hFile
;
287 object
->file_mapping
= file_mapping
;
288 object
->buffer
= buffer
;
289 object
->pDirectXFile
= This
;
290 object
->buf
.pdxf
= This
;
291 object
->buf
.txt
= (header
[2] == XOFFILE_FORMAT_TEXT
);
292 object
->buf
.token_present
= FALSE
;
294 TRACE("File size is %d bytes\n", file_size
);
296 /* Go to data after header */
297 object
->buf
.buffer
= file_buffer
+ 16;
298 object
->buf
.rem_bytes
= file_size
- 16;
300 *ppEnumObj
= (LPDIRECTXFILEENUMOBJECT
)object
;
302 while (object
->buf
.rem_bytes
&& is_template_available(&object
->buf
))
304 if (!parse_template(&object
->buf
))
306 WARN("Template is not correct\n");
307 hr
= DXFILEERR_BADVALUE
;
312 TRACE("Template successfully parsed:\n");
313 if (TRACE_ON(d3dxof
))
314 dump_template(This
->xtemplates
, &This
->xtemplates
[This
->nb_xtemplates
- 1]);
318 if (TRACE_ON(d3dxof
))
321 TRACE("Registered templates (%d):\n", This
->nb_xtemplates
);
322 for (i
= 0; i
< This
->nb_xtemplates
; i
++)
323 DPRINTF("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
330 UnmapViewOfFile(buffer
);
332 CloseHandle(file_mapping
);
333 if (hFile
!= INVALID_HANDLE_VALUE
)
336 FreeResource(resource_data
);
342 static HRESULT WINAPI
IDirectXFileImpl_CreateSaveObject(IDirectXFile
* iface
, LPCSTR szFileName
, DXFILEFORMAT dwFileFormat
, LPDIRECTXFILESAVEOBJECT
* ppSaveObj
)
344 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
346 FIXME("(%p/%p)->(%s,%x,%p) partial stub!\n", This
, iface
, szFileName
, dwFileFormat
, ppSaveObj
);
348 if (!szFileName
|| !ppSaveObj
)
351 return IDirectXFileSaveObjectImpl_Create((IDirectXFileSaveObjectImpl
**)ppSaveObj
);
354 static HRESULT WINAPI
IDirectXFileImpl_RegisterTemplates(IDirectXFile
* iface
, LPVOID pvData
, DWORD cbSize
)
356 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
361 buf
.rem_bytes
= cbSize
;
363 buf
.token_present
= FALSE
;
366 TRACE("(%p/%p)->(%p,%d)\n", This
, iface
, pvData
, cbSize
);
369 return DXFILEERR_BADVALUE
;
372 return DXFILEERR_BADFILETYPE
;
374 if (TRACE_ON(d3dxof
))
377 memcpy(string
, pvData
, 16);
379 TRACE("header = '%s'\n", string
);
382 read_bytes(&buf
, &token_header
, 4);
384 if (token_header
!= XOFFILE_FORMAT_MAGIC
)
385 return DXFILEERR_BADFILETYPE
;
387 read_bytes(&buf
, &token_header
, 4);
389 if ((token_header
!= XOFFILE_FORMAT_VERSION_302
) && (token_header
!= XOFFILE_FORMAT_VERSION_303
))
390 return DXFILEERR_BADFILEVERSION
;
392 read_bytes(&buf
, &token_header
, 4);
394 if ((token_header
!= XOFFILE_FORMAT_BINARY
) && (token_header
!= XOFFILE_FORMAT_TEXT
) &&
395 (token_header
!= XOFFILE_FORMAT_BINARY_MSZIP
) && (token_header
!= XOFFILE_FORMAT_TEXT_MSZIP
))
397 WARN("File type %s unknown\n", debugstr_fourcc(token_header
));
398 return DXFILEERR_BADFILETYPE
;
401 if ((token_header
== XOFFILE_FORMAT_BINARY_MSZIP
) || (token_header
== XOFFILE_FORMAT_TEXT_MSZIP
))
403 FIXME("Compressed format %s not supported yet\n", debugstr_fourcc(token_header
));
404 return DXFILEERR_BADALLOC
;
407 if (token_header
== XOFFILE_FORMAT_TEXT
)
410 read_bytes(&buf
, &token_header
, 4);
412 if ((token_header
!= XOFFILE_FORMAT_FLOAT_BITS_32
) && (token_header
!= XOFFILE_FORMAT_FLOAT_BITS_64
))
413 return DXFILEERR_BADFILEFLOATSIZE
;
415 TRACE("Header is correct\n");
417 while (buf
.rem_bytes
)
419 if (!parse_template(&buf
))
421 WARN("Template is not correct\n");
422 return DXFILEERR_BADVALUE
;
426 TRACE("Template successfully parsed:\n");
427 if (TRACE_ON(d3dxof
))
428 dump_template(This
->xtemplates
, &This
->xtemplates
[This
->nb_xtemplates
- 1]);
432 if (TRACE_ON(d3dxof
))
435 TRACE("Registered templates (%d):\n", This
->nb_xtemplates
);
436 for (i
= 0; i
< This
->nb_xtemplates
; i
++)
437 DPRINTF("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
443 static const IDirectXFileVtbl IDirectXFile_Vtbl
=
445 IDirectXFileImpl_QueryInterface
,
446 IDirectXFileImpl_AddRef
,
447 IDirectXFileImpl_Release
,
448 IDirectXFileImpl_CreateEnumObject
,
449 IDirectXFileImpl_CreateSaveObject
,
450 IDirectXFileImpl_RegisterTemplates
453 static HRESULT
IDirectXFileBinaryImpl_Create(IDirectXFileBinaryImpl
** ppObj
)
455 IDirectXFileBinaryImpl
* object
;
457 TRACE("(%p)\n", ppObj
);
459 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileBinaryImpl
));
462 ERR("Out of memory\n");
463 return DXFILEERR_BADALLOC
;
466 object
->lpVtbl
= &IDirectXFileBinary_Vtbl
;
474 /*** IUnknown methods ***/
475 static HRESULT WINAPI
IDirectXFileBinaryImpl_QueryInterface(IDirectXFileBinary
* iface
, REFIID riid
, void** ppvObject
)
477 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
479 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
481 if (IsEqualGUID(riid
, &IID_IUnknown
)
482 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
483 || IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
485 IUnknown_AddRef(iface
);
490 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
491 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
)
492 && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
493 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
495 return E_NOINTERFACE
;
498 static ULONG WINAPI
IDirectXFileBinaryImpl_AddRef(IDirectXFileBinary
* iface
)
500 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
501 ULONG ref
= InterlockedIncrement(&This
->ref
);
503 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
508 static ULONG WINAPI
IDirectXFileBinaryImpl_Release(IDirectXFileBinary
* iface
)
510 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
511 ULONG ref
= InterlockedDecrement(&This
->ref
);
513 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
516 HeapFree(GetProcessHeap(), 0, This
);
521 /*** IDirectXFileObject methods ***/
522 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetName(IDirectXFileBinary
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
525 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
527 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
529 return DXFILEERR_BADVALUE
;
532 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetId(IDirectXFileBinary
* iface
, LPGUID pGuid
)
534 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
536 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pGuid
);
538 return DXFILEERR_BADVALUE
;
541 /*** IDirectXFileBinary methods ***/
542 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetSize(IDirectXFileBinary
* iface
, DWORD
* pcbSize
)
544 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
546 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pcbSize
);
548 return DXFILEERR_BADVALUE
;
551 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetMimeType(IDirectXFileBinary
* iface
, LPCSTR
* pszMimeType
)
553 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
555 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pszMimeType
);
557 return DXFILEERR_BADVALUE
;
560 static HRESULT WINAPI
IDirectXFileBinaryImpl_Read(IDirectXFileBinary
* iface
, LPVOID pvData
, DWORD cbSize
, LPDWORD pcbRead
)
562 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
564 FIXME("(%p/%p)->(%p, %d, %p) stub!\n", This
, iface
, pvData
, cbSize
, pcbRead
);
566 return DXFILEERR_BADVALUE
;
569 static const IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl
=
571 IDirectXFileBinaryImpl_QueryInterface
,
572 IDirectXFileBinaryImpl_AddRef
,
573 IDirectXFileBinaryImpl_Release
,
574 IDirectXFileBinaryImpl_GetName
,
575 IDirectXFileBinaryImpl_GetId
,
576 IDirectXFileBinaryImpl_GetSize
,
577 IDirectXFileBinaryImpl_GetMimeType
,
578 IDirectXFileBinaryImpl_Read
581 static HRESULT
IDirectXFileDataImpl_Create(IDirectXFileDataImpl
** ppObj
)
583 IDirectXFileDataImpl
* object
;
585 TRACE("(%p)\n", ppObj
);
587 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataImpl
));
590 ERR("Out of memory\n");
591 return DXFILEERR_BADALLOC
;
594 object
->lpVtbl
= &IDirectXFileData_Vtbl
;
602 /*** IUnknown methods ***/
603 static HRESULT WINAPI
IDirectXFileDataImpl_QueryInterface(IDirectXFileData
* iface
, REFIID riid
, void** ppvObject
)
605 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
607 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
609 if (IsEqualGUID(riid
, &IID_IUnknown
)
610 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
611 || IsEqualGUID(riid
, &IID_IDirectXFileData
))
613 IUnknown_AddRef(iface
);
618 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
619 if (!IsEqualGUID(riid
, &IID_IDirectXFileBinary
)
620 && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
621 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
623 return E_NOINTERFACE
;
626 static ULONG WINAPI
IDirectXFileDataImpl_AddRef(IDirectXFileData
* iface
)
628 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
629 ULONG ref
= InterlockedIncrement(&This
->ref
);
631 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
636 static ULONG WINAPI
IDirectXFileDataImpl_Release(IDirectXFileData
* iface
)
638 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
639 ULONG ref
= InterlockedDecrement(&This
->ref
);
641 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
645 if (!This
->level
&& !This
->from_ref
)
647 HeapFree(GetProcessHeap(), 0, This
->pstrings
);
648 HeapFree(GetProcessHeap(), 0, This
->pobj
->pdata
);
649 HeapFree(GetProcessHeap(), 0, This
->pobj
);
651 HeapFree(GetProcessHeap(), 0, This
);
657 /*** IDirectXFileObject methods ***/
658 static HRESULT WINAPI
IDirectXFileDataImpl_GetName(IDirectXFileData
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
661 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
663 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
666 return DXFILEERR_BADVALUE
;
668 strcpy(pstrNameBuf
, This
->pobj
->name
);
673 static HRESULT WINAPI
IDirectXFileDataImpl_GetId(IDirectXFileData
* iface
, LPGUID pGuid
)
675 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
677 TRACE("(%p/%p)->(%p)\n", This
, iface
, pGuid
);
680 return DXFILEERR_BADVALUE
;
682 memcpy(pGuid
, &This
->pobj
->class_id
, 16);
687 /*** IDirectXFileData methods ***/
688 static HRESULT WINAPI
IDirectXFileDataImpl_GetData(IDirectXFileData
* iface
, LPCSTR szMember
, DWORD
* pcbSize
, void** ppvData
)
690 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
692 TRACE("(%p/%p)->(%s,%p,%p)\n", This
, iface
, szMember
, pcbSize
, ppvData
);
694 if (!pcbSize
|| !ppvData
)
695 return DXFILEERR_BADVALUE
;
699 FIXME("Specifying a member is not supported yet!\n");
700 return DXFILEERR_BADVALUE
;
703 *pcbSize
= This
->pobj
->size
;
704 *ppvData
= This
->pobj
->root
->pdata
+ This
->pobj
->pos_data
;
709 static HRESULT WINAPI
IDirectXFileDataImpl_GetType(IDirectXFileData
* iface
, const GUID
** pguid
)
711 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
714 TRACE("(%p/%p)->(%p)\n", This
, iface
, pguid
);
717 return DXFILEERR_BADVALUE
;
719 memcpy(&guid
, &This
->pobj
->type
, 16);
725 static HRESULT WINAPI
IDirectXFileDataImpl_GetNextObject(IDirectXFileData
* iface
, LPDIRECTXFILEOBJECT
* ppChildObj
)
728 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
730 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppChildObj
);
732 if (This
->cur_enum_object
>= This
->pobj
->nb_childs
)
733 return DXFILEERR_NOMOREOBJECTS
;
735 if (This
->from_ref
&& (This
->level
>= 1))
737 /* Only 2 levels can be enumerated if the object is obtained from a reference */
738 return DXFILEERR_NOMOREOBJECTS
;
741 if (This
->pobj
->childs
[This
->cur_enum_object
]->binary
)
743 IDirectXFileBinaryImpl
*object
;
745 hr
= IDirectXFileBinaryImpl_Create(&object
);
749 *ppChildObj
= (LPDIRECTXFILEOBJECT
)object
;
751 else if (This
->pobj
->childs
[This
->cur_enum_object
]->ptarget
)
753 IDirectXFileDataReferenceImpl
*object
;
755 hr
= IDirectXFileDataReferenceImpl_Create(&object
);
759 object
->ptarget
= This
->pobj
->childs
[This
->cur_enum_object
++]->ptarget
;
761 *ppChildObj
= (LPDIRECTXFILEOBJECT
)object
;
765 IDirectXFileDataImpl
*object
;
767 hr
= IDirectXFileDataImpl_Create(&object
);
771 object
->pobj
= This
->pobj
->childs
[This
->cur_enum_object
++];
772 object
->cur_enum_object
= 0;
773 object
->from_ref
= This
->from_ref
;
774 object
->level
= This
->level
+ 1;
776 *ppChildObj
= (LPDIRECTXFILEOBJECT
)object
;
782 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataObject(IDirectXFileData
* iface
, LPDIRECTXFILEDATA pDataObj
)
784 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
786 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pDataObj
);
788 return DXFILEERR_BADVALUE
;
791 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataReference(IDirectXFileData
* iface
, LPCSTR szRef
, const GUID
* pguidRef
)
793 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
795 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szRef
, pguidRef
);
797 return DXFILEERR_BADVALUE
;
800 static HRESULT WINAPI
IDirectXFileDataImpl_AddBinaryObject(IDirectXFileData
* iface
, LPCSTR szName
, const GUID
* pguid
, LPCSTR szMimeType
, LPVOID pvData
, DWORD cbSize
)
802 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
804 FIXME("(%p/%p)->(%s,%p,%s,%p,%d) stub!\n", This
, iface
, szName
, pguid
, szMimeType
, pvData
, cbSize
);
806 return DXFILEERR_BADVALUE
;
809 static const IDirectXFileDataVtbl IDirectXFileData_Vtbl
=
811 IDirectXFileDataImpl_QueryInterface
,
812 IDirectXFileDataImpl_AddRef
,
813 IDirectXFileDataImpl_Release
,
814 IDirectXFileDataImpl_GetName
,
815 IDirectXFileDataImpl_GetId
,
816 IDirectXFileDataImpl_GetData
,
817 IDirectXFileDataImpl_GetType
,
818 IDirectXFileDataImpl_GetNextObject
,
819 IDirectXFileDataImpl_AddDataObject
,
820 IDirectXFileDataImpl_AddDataReference
,
821 IDirectXFileDataImpl_AddBinaryObject
824 static HRESULT
IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl
** ppObj
)
826 IDirectXFileDataReferenceImpl
* object
;
828 TRACE("(%p)\n", ppObj
);
830 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataReferenceImpl
));
833 ERR("Out of memory\n");
834 return DXFILEERR_BADALLOC
;
837 object
->lpVtbl
= &IDirectXFileDataReference_Vtbl
;
845 /*** IUnknown methods ***/
846 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_QueryInterface(IDirectXFileDataReference
* iface
, REFIID riid
, void** ppvObject
)
848 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
850 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
852 if (IsEqualGUID(riid
, &IID_IUnknown
)
853 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
854 || IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
856 IUnknown_AddRef(iface
);
861 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
862 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
)
863 && !IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
864 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
866 return E_NOINTERFACE
;
869 static ULONG WINAPI
IDirectXFileDataReferenceImpl_AddRef(IDirectXFileDataReference
* iface
)
871 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
872 ULONG ref
= InterlockedIncrement(&This
->ref
);
874 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
879 static ULONG WINAPI
IDirectXFileDataReferenceImpl_Release(IDirectXFileDataReference
* iface
)
881 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
882 ULONG ref
= InterlockedDecrement(&This
->ref
);
884 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
887 HeapFree(GetProcessHeap(), 0, This
);
892 /*** IDirectXFileObject methods ***/
893 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetName(IDirectXFileDataReference
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
895 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
897 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
900 return DXFILEERR_BADVALUE
;
902 strcpy(pstrNameBuf
, This
->ptarget
->name
);
904 return DXFILEERR_BADVALUE
;
907 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetId(IDirectXFileDataReference
* iface
, LPGUID pGuid
)
909 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
911 TRACE("(%p/%p)->(%p)\n", This
, iface
, pGuid
);
914 return DXFILEERR_BADVALUE
;
916 memcpy(pGuid
, &This
->ptarget
->class_id
, 16);
921 /*** IDirectXFileDataReference ***/
922 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
924 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
925 IDirectXFileDataImpl
*object
;
928 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
931 return DXFILEERR_BADVALUE
;
933 hr
= IDirectXFileDataImpl_Create(&object
);
937 object
->pobj
= This
->ptarget
;
938 object
->cur_enum_object
= 0;
940 object
->from_ref
= TRUE
;
942 *ppDataObj
= (LPDIRECTXFILEDATA
)object
;
947 static const IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl
=
949 IDirectXFileDataReferenceImpl_QueryInterface
,
950 IDirectXFileDataReferenceImpl_AddRef
,
951 IDirectXFileDataReferenceImpl_Release
,
952 IDirectXFileDataReferenceImpl_GetName
,
953 IDirectXFileDataReferenceImpl_GetId
,
954 IDirectXFileDataReferenceImpl_Resolve
957 static HRESULT
IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl
** ppObj
)
959 IDirectXFileEnumObjectImpl
* object
;
961 TRACE("(%p)\n", ppObj
);
963 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileEnumObjectImpl
));
966 ERR("Out of memory\n");
967 return DXFILEERR_BADALLOC
;
970 object
->lpVtbl
= &IDirectXFileEnumObject_Vtbl
;
978 /*** IUnknown methods ***/
979 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_QueryInterface(IDirectXFileEnumObject
* iface
, REFIID riid
, void** ppvObject
)
981 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
983 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
985 if (IsEqualGUID(riid
, &IID_IUnknown
)
986 || IsEqualGUID(riid
, &IID_IDirectXFileEnumObject
))
988 IUnknown_AddRef(iface
);
993 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
994 return E_NOINTERFACE
;
997 static ULONG WINAPI
IDirectXFileEnumObjectImpl_AddRef(IDirectXFileEnumObject
* iface
)
999 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1000 ULONG ref
= InterlockedIncrement(&This
->ref
);
1002 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
1007 static ULONG WINAPI
IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject
* iface
)
1009 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1010 ULONG ref
= InterlockedDecrement(&This
->ref
);
1012 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
1017 for (i
= 0; i
< This
->nb_xobjects
; i
++)
1018 IDirectXFileData_Release(This
->pRefObjects
[i
]);
1019 if (This
->source
== DXFILELOAD_FROMFILE
)
1021 UnmapViewOfFile(This
->buffer
);
1022 CloseHandle(This
->file_mapping
);
1023 CloseHandle(This
->hFile
);
1025 else if (This
->source
== DXFILELOAD_FROMRESOURCE
)
1026 FreeResource(This
->resource_data
);
1027 HeapFree(GetProcessHeap(), 0, This
);
1033 /*** IDirectXFileEnumObject methods ***/
1034 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
1036 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1037 IDirectXFileDataImpl
* object
;
1039 LPBYTE pstrings
= NULL
;
1041 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
1043 if (This
->nb_xobjects
>= MAX_OBJECTS
)
1045 ERR("Too many objects\n");
1046 return DXFILEERR_NOMOREOBJECTS
;
1049 /* Check if there are templates defined before the object */
1050 while (This
->buf
.rem_bytes
&& is_template_available(&This
->buf
))
1052 if (!parse_template(&This
->buf
))
1054 WARN("Template is not correct\n");
1055 hr
= DXFILEERR_BADVALUE
;
1060 TRACE("Template successfully parsed:\n");
1061 if (TRACE_ON(d3dxof
))
1062 dump_template(This
->pDirectXFile
->xtemplates
, &This
->pDirectXFile
->xtemplates
[This
->pDirectXFile
->nb_xtemplates
- 1]);
1066 if (!This
->buf
.rem_bytes
)
1067 return DXFILEERR_NOMOREOBJECTS
;
1069 hr
= IDirectXFileDataImpl_Create(&object
);
1073 This
->buf
.pxo_globals
= This
->xobjects
;
1074 This
->buf
.nb_pxo_globals
= This
->nb_xobjects
;
1075 This
->buf
.level
= 0;
1077 This
->buf
.pxo_tab
= HeapAlloc(GetProcessHeap(), 0, sizeof(xobject
)*MAX_SUBOBJECTS
);
1078 if (!This
->buf
.pxo_tab
)
1080 ERR("Out of memory\n");
1081 hr
= DXFILEERR_BADALLOC
;
1084 This
->buf
.pxo
= This
->xobjects
[This
->nb_xobjects
] = This
->buf
.pxo_tab
;
1086 This
->buf
.pxo
->pdata
= This
->buf
.pdata
= NULL
;
1087 This
->buf
.capacity
= 0;
1088 This
->buf
.cur_pos_data
= 0;
1089 This
->buf
.pxo
->nb_subobjects
= 1;
1091 pstrings
= HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER
);
1094 ERR("Out of memory\n");
1095 hr
= DXFILEERR_BADALLOC
;
1098 This
->buf
.cur_pstrings
= This
->buf
.pstrings
= object
->pstrings
= pstrings
;
1100 if (!parse_object(&This
->buf
))
1102 WARN("Object is not correct\n");
1103 hr
= DXFILEERR_PARSEERROR
;
1107 if (This
->buf
.pxo
->nb_subobjects
> MAX_SUBOBJECTS
)
1109 FIXME("Too many subobjects %d\n", This
->buf
.pxo
->nb_subobjects
);
1110 hr
= DXFILEERR_BADALLOC
;
1114 object
->pstrings
= pstrings
;
1115 object
->pobj
= This
->buf
.pxo
;
1116 object
->cur_enum_object
= 0;
1118 object
->from_ref
= FALSE
;
1120 *ppDataObj
= (LPDIRECTXFILEDATA
)object
;
1122 /* Get a reference to created object */
1123 This
->pRefObjects
[This
->nb_xobjects
] = (LPDIRECTXFILEDATA
)object
;
1124 IDirectXFileData_AddRef(This
->pRefObjects
[This
->nb_xobjects
]);
1126 This
->nb_xobjects
++;
1132 HeapFree(GetProcessHeap(), 0, This
->buf
.pxo_tab
);
1133 HeapFree(GetProcessHeap(), 0, This
->buf
.pdata
);
1134 HeapFree(GetProcessHeap(), 0, pstrings
);
1139 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectById(IDirectXFileEnumObject
* iface
, REFGUID rguid
, LPDIRECTXFILEDATA
* ppDataObj
)
1141 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1143 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, rguid
, ppDataObj
);
1145 return DXFILEERR_BADVALUE
;
1148 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectByName(IDirectXFileEnumObject
* iface
, LPCSTR szName
, LPDIRECTXFILEDATA
* ppDataObj
)
1150 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1152 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szName
, ppDataObj
);
1154 return DXFILEERR_BADVALUE
;
1157 static const IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl
=
1159 IDirectXFileEnumObjectImpl_QueryInterface
,
1160 IDirectXFileEnumObjectImpl_AddRef
,
1161 IDirectXFileEnumObjectImpl_Release
,
1162 IDirectXFileEnumObjectImpl_GetNextDataObject
,
1163 IDirectXFileEnumObjectImpl_GetDataObjectById
,
1164 IDirectXFileEnumObjectImpl_GetDataObjectByName
1167 static HRESULT
IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl
** ppObj
)
1169 IDirectXFileSaveObjectImpl
* object
;
1171 TRACE("(%p)\n", ppObj
);
1173 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileSaveObjectImpl
));
1176 ERR("Out of memory\n");
1177 return DXFILEERR_BADALLOC
;
1180 object
->lpVtbl
= &IDirectXFileSaveObject_Vtbl
;
1188 /*** IUnknown methods ***/
1189 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_QueryInterface(IDirectXFileSaveObject
* iface
, REFIID riid
, void** ppvObject
)
1191 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
1193 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1195 if (IsEqualGUID(riid
, &IID_IUnknown
)
1196 || IsEqualGUID(riid
, &IID_IDirectXFileSaveObject
))
1198 IUnknown_AddRef(iface
);
1203 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1204 return E_NOINTERFACE
;
1207 static ULONG WINAPI
IDirectXFileSaveObjectImpl_AddRef(IDirectXFileSaveObject
* iface
)
1209 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
1210 ULONG ref
= InterlockedIncrement(&This
->ref
);
1212 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
1217 static ULONG WINAPI
IDirectXFileSaveObjectImpl_Release(IDirectXFileSaveObject
* iface
)
1219 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
1220 ULONG ref
= InterlockedDecrement(&This
->ref
);
1222 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
1225 HeapFree(GetProcessHeap(), 0, This
);
1230 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveTemplates(IDirectXFileSaveObject
* iface
, DWORD cTemplates
, const GUID
** ppguidTemplates
)
1232 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
1234 FIXME("(%p/%p)->(%d,%p) stub!\n", This
, iface
, cTemplates
, ppguidTemplates
);
1236 return DXFILEERR_BADVALUE
;
1239 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_CreateDataObject(IDirectXFileSaveObject
* iface
, REFGUID rguidTemplate
, LPCSTR szName
, const GUID
* pguid
, DWORD cbSize
, LPVOID pvData
, LPDIRECTXFILEDATA
* ppDataObj
)
1241 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
1243 FIXME("(%p/%p)->(%p,%s,%p,%d,%p,%p) stub!\n", This
, iface
, rguidTemplate
, szName
, pguid
, cbSize
, pvData
, ppDataObj
);
1245 return DXFILEERR_BADVALUE
;
1248 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveData(IDirectXFileSaveObject
* iface
, LPDIRECTXFILEDATA ppDataObj
)
1250 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
1252 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, ppDataObj
);
1254 return DXFILEERR_BADVALUE
;
1257 static const IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl
=
1259 IDirectXFileSaveObjectImpl_QueryInterface
,
1260 IDirectXFileSaveObjectImpl_AddRef
,
1261 IDirectXFileSaveObjectImpl_Release
,
1262 IDirectXFileSaveObjectImpl_SaveTemplates
,
1263 IDirectXFileSaveObjectImpl_CreateDataObject
,
1264 IDirectXFileSaveObjectImpl_SaveData