2 * Implementation of DirectX File Interfaces
4 * Copyright 2004, 2008 Christian Costa
6 * This file contains the (internal) driver registration functions,
7 * driver enumeration APIs and DirectDraw creation functions.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/debug.h"
32 #include "d3dxof_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(d3dxof
);
39 #define MAKEFOUR(a,b,c,d) ((DWORD)a + ((DWORD)b << 8) + ((DWORD)c << 16) + ((DWORD)d << 24))
40 #define XOFFILE_FORMAT_MAGIC MAKEFOUR('x','o','f',' ')
41 #define XOFFILE_FORMAT_VERSION_302 MAKEFOUR('0','3','0','2')
42 #define XOFFILE_FORMAT_VERSION_303 MAKEFOUR('0','3','0','3')
43 #define XOFFILE_FORMAT_BINARY MAKEFOUR('b','i','n',' ')
44 #define XOFFILE_FORMAT_TEXT MAKEFOUR('t','x','t',' ')
45 #define XOFFILE_FORMAT_COMPRESSED MAKEFOUR('c','m','p',' ')
46 #define XOFFILE_FORMAT_FLOAT_BITS_32 MAKEFOUR('0','0','3','2')
47 #define XOFFILE_FORMAT_FLOAT_BITS_64 MAKEFOUR('0','0','6','4')
49 static const struct IDirectXFileVtbl IDirectXFile_Vtbl
;
50 static const struct IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl
;
51 static const struct IDirectXFileDataVtbl IDirectXFileData_Vtbl
;
52 static const struct IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl
;
53 static const struct IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl
;
54 static const struct IDirectXFileObjectVtbl IDirectXFileObject_Vtbl
;
55 static const struct IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl
;
57 static HRESULT
IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl
** ppObj
);
58 static HRESULT
IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl
** ppObj
);
59 static HRESULT
IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl
** ppObj
);
61 HRESULT
IDirectXFileImpl_Create(IUnknown
* pUnkOuter
, LPVOID
* ppObj
)
63 IDirectXFileImpl
* object
;
65 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
67 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileImpl
));
70 ERR("Out of memory\n");
71 return DXFILEERR_BADALLOC
;
74 object
->lpVtbl
.lpVtbl
= &IDirectXFile_Vtbl
;
82 /*** IUnknown methods ***/
83 static HRESULT WINAPI
IDirectXFileImpl_QueryInterface(IDirectXFile
* iface
, REFIID riid
, void** ppvObject
)
85 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
87 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
89 if (IsEqualGUID(riid
, &IID_IUnknown
)
90 || IsEqualGUID(riid
, &IID_IDirectXFile
))
92 IClassFactory_AddRef(iface
);
97 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
101 static ULONG WINAPI
IDirectXFileImpl_AddRef(IDirectXFile
* iface
)
103 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
104 ULONG ref
= InterlockedIncrement(&This
->ref
);
106 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
111 static ULONG WINAPI
IDirectXFileImpl_Release(IDirectXFile
* iface
)
113 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
114 ULONG ref
= InterlockedDecrement(&This
->ref
);
116 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
119 HeapFree(GetProcessHeap(), 0, This
);
124 /*** IDirectXFile methods ***/
125 static HRESULT WINAPI
IDirectXFileImpl_CreateEnumObject(IDirectXFile
* iface
, LPVOID pvSource
, DXFILELOADOPTIONS dwLoadOptions
, LPDIRECTXFILEENUMOBJECT
* ppEnumObj
)
127 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
128 IDirectXFileEnumObjectImpl
* object
;
131 HANDLE hFile
= INVALID_HANDLE_VALUE
;
132 HANDLE file_mapping
= 0;
133 LPBYTE buffer
= NULL
;
134 HGLOBAL resource_data
= 0;
138 LPDXFILELOADMEMORY lpdxflm
= NULL
;
140 TRACE("(%p/%p)->(%p,%x,%p)\n", This
, iface
, pvSource
, dwLoadOptions
, ppEnumObj
);
143 return DXFILEERR_BADVALUE
;
145 /* Only lowest 4 bits are relevant in DXFILELOADOPTIONS */
146 dwLoadOptions
&= 0xF;
148 if (dwLoadOptions
== DXFILELOAD_FROMFILE
)
150 TRACE("Open source file '%s'\n", (char*)pvSource
);
152 hFile
= CreateFileA(pvSource
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
153 if (hFile
== INVALID_HANDLE_VALUE
)
155 TRACE("File '%s' not found\n", (char*)pvSource
);
156 return DXFILEERR_FILENOTFOUND
;
159 file_size
= GetFileSize(hFile
, NULL
);
161 file_mapping
= CreateFileMappingA(hFile
, NULL
, PAGE_READONLY
, 0, 0, NULL
);
164 hr
= DXFILEERR_BADFILETYPE
;
168 buffer
= MapViewOfFile(file_mapping
, FILE_MAP_READ
, 0, 0, 0);
171 hr
= DXFILEERR_BADFILETYPE
;
174 file_buffer
= buffer
;
176 else if (dwLoadOptions
== DXFILELOAD_FROMRESOURCE
)
179 LPDXFILELOADRESOURCE lpdxflr
= pvSource
;
181 TRACE("Source in resource (module = %p, name = %s, type = %s\n", lpdxflr
->hModule
, debugstr_a(lpdxflr
->lpName
), debugstr_a(lpdxflr
->lpType
));
183 resource_info
= FindResourceA(lpdxflr
->hModule
, lpdxflr
->lpName
, lpdxflr
->lpType
);
186 hr
= DXFILEERR_RESOURCENOTFOUND
;
190 file_size
= SizeofResource(lpdxflr
->hModule
, resource_info
);
192 resource_data
= LoadResource(lpdxflr
->hModule
, resource_info
);
195 hr
= DXFILEERR_BADRESOURCE
;
199 file_buffer
= LockResource(resource_data
);
202 hr
= DXFILEERR_BADRESOURCE
;
206 else if (dwLoadOptions
== DXFILELOAD_FROMMEMORY
)
210 TRACE("Source in memory at %p with size %d\n", lpdxflm
->lpMemory
, lpdxflm
->dSize
);
212 file_buffer
= lpdxflm
->lpMemory
;
213 file_size
= lpdxflm
->dSize
;
217 FIXME("Source type %d is not handled yet\n", dwLoadOptions
);
218 hr
= DXFILEERR_NOTDONEYET
;
222 header
= (DWORD
*)file_buffer
;
224 if (TRACE_ON(d3dxof
))
227 memcpy(string
, header
, 16);
229 TRACE("header = '%s'\n", string
);
234 hr
= DXFILEERR_BADFILETYPE
;
238 if (header
[0] != XOFFILE_FORMAT_MAGIC
)
240 hr
= DXFILEERR_BADFILETYPE
;
244 if ((header
[1] != XOFFILE_FORMAT_VERSION_302
) && (header
[1] != XOFFILE_FORMAT_VERSION_303
))
246 hr
= DXFILEERR_BADFILEVERSION
;
250 if ((header
[2] != XOFFILE_FORMAT_BINARY
) && (header
[2] != XOFFILE_FORMAT_TEXT
) && (header
[2] != XOFFILE_FORMAT_COMPRESSED
))
252 hr
= DXFILEERR_BADFILETYPE
;
256 if (header
[2] == XOFFILE_FORMAT_COMPRESSED
)
258 FIXME("Compressed formats not supported yet\n");
259 hr
= DXFILEERR_BADVALUE
;
263 if ((header
[3] != XOFFILE_FORMAT_FLOAT_BITS_32
) && (header
[3] != XOFFILE_FORMAT_FLOAT_BITS_64
))
265 hr
= DXFILEERR_BADFILEFLOATSIZE
;
269 TRACE("Header is correct\n");
271 hr
= IDirectXFileEnumObjectImpl_Create(&object
);
275 object
->source
= dwLoadOptions
;
276 object
->hFile
= hFile
;
277 object
->file_mapping
= file_mapping
;
278 object
->buffer
= buffer
;
279 object
->pDirectXFile
= This
;
280 object
->buf
.pdxf
= This
;
281 object
->buf
.txt
= (header
[2] == XOFFILE_FORMAT_TEXT
);
282 object
->buf
.token_present
= FALSE
;
283 object
->buf
.cur_subobject
= 0;
285 TRACE("File size is %d bytes\n", file_size
);
287 /* Go to data after header */
288 object
->buf
.buffer
= file_buffer
+ 16;
289 object
->buf
.rem_bytes
= file_size
- 16;
291 *ppEnumObj
= (LPDIRECTXFILEENUMOBJECT
)object
;
293 while (object
->buf
.rem_bytes
&& is_template_available(&object
->buf
))
295 if (!parse_template(&object
->buf
))
297 TRACE("Template is not correct\n");
298 hr
= DXFILEERR_BADVALUE
;
303 TRACE("Template successfully parsed:\n");
304 if (TRACE_ON(d3dxof
))
305 dump_template(This
->xtemplates
, &This
->xtemplates
[This
->nb_xtemplates
- 1]);
309 if (TRACE_ON(d3dxof
))
312 TRACE("Registered templates (%d):\n", This
->nb_xtemplates
);
313 for (i
= 0; i
< This
->nb_xtemplates
; i
++)
314 DPRINTF("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
321 UnmapViewOfFile(buffer
);
323 CloseHandle(file_mapping
);
324 if (hFile
!= INVALID_HANDLE_VALUE
)
327 FreeResource(resource_data
);
333 static HRESULT WINAPI
IDirectXFileImpl_CreateSaveObject(IDirectXFile
* iface
, LPCSTR szFileName
, DXFILEFORMAT dwFileFormat
, LPDIRECTXFILESAVEOBJECT
* ppSaveObj
)
335 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
337 FIXME("(%p/%p)->(%s,%x,%p) partial stub!\n", This
, iface
, szFileName
, dwFileFormat
, ppSaveObj
);
339 if (!szFileName
|| !ppSaveObj
)
342 return IDirectXFileSaveObjectImpl_Create((IDirectXFileSaveObjectImpl
**)ppSaveObj
);
345 static HRESULT WINAPI
IDirectXFileImpl_RegisterTemplates(IDirectXFile
* iface
, LPVOID pvData
, DWORD cbSize
)
347 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
352 buf
.rem_bytes
= cbSize
;
354 buf
.token_present
= FALSE
;
357 TRACE("(%p/%p)->(%p,%d)\n", This
, iface
, pvData
, cbSize
);
360 return DXFILEERR_BADVALUE
;
363 return DXFILEERR_BADFILETYPE
;
365 if (TRACE_ON(d3dxof
))
368 memcpy(string
, pvData
, 16);
370 TRACE("header = '%s'\n", string
);
373 read_bytes(&buf
, &token_header
, 4);
375 if (token_header
!= XOFFILE_FORMAT_MAGIC
)
376 return DXFILEERR_BADFILETYPE
;
378 read_bytes(&buf
, &token_header
, 4);
380 if ((token_header
!= XOFFILE_FORMAT_VERSION_302
) && (token_header
!= XOFFILE_FORMAT_VERSION_303
))
381 return DXFILEERR_BADFILEVERSION
;
383 read_bytes(&buf
, &token_header
, 4);
385 if ((token_header
!= XOFFILE_FORMAT_BINARY
) && (token_header
!= XOFFILE_FORMAT_TEXT
) && (token_header
!= XOFFILE_FORMAT_COMPRESSED
))
386 return DXFILEERR_BADFILETYPE
;
388 if (token_header
== XOFFILE_FORMAT_TEXT
)
393 if (token_header
== XOFFILE_FORMAT_COMPRESSED
)
395 FIXME("Compressed formats not supported yet\n");
396 return DXFILEERR_BADVALUE
;
399 read_bytes(&buf
, &token_header
, 4);
401 if ((token_header
!= XOFFILE_FORMAT_FLOAT_BITS_32
) && (token_header
!= XOFFILE_FORMAT_FLOAT_BITS_64
))
402 return DXFILEERR_BADFILEFLOATSIZE
;
404 TRACE("Header is correct\n");
406 while (buf
.rem_bytes
)
408 if (!parse_template(&buf
))
410 TRACE("Template is not correct\n");
411 return DXFILEERR_BADVALUE
;
415 TRACE("Template successfully parsed:\n");
416 if (TRACE_ON(d3dxof
))
417 dump_template(This
->xtemplates
, &This
->xtemplates
[This
->nb_xtemplates
- 1]);
421 if (TRACE_ON(d3dxof
))
424 TRACE("Registered templates (%d):\n", This
->nb_xtemplates
);
425 for (i
= 0; i
< This
->nb_xtemplates
; i
++)
426 DPRINTF("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
432 static const IDirectXFileVtbl IDirectXFile_Vtbl
=
434 IDirectXFileImpl_QueryInterface
,
435 IDirectXFileImpl_AddRef
,
436 IDirectXFileImpl_Release
,
437 IDirectXFileImpl_CreateEnumObject
,
438 IDirectXFileImpl_CreateSaveObject
,
439 IDirectXFileImpl_RegisterTemplates
442 static HRESULT
IDirectXFileBinaryImpl_Create(IDirectXFileBinaryImpl
** ppObj
)
444 IDirectXFileBinaryImpl
* object
;
446 TRACE("(%p)\n", ppObj
);
448 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileBinaryImpl
));
451 ERR("Out of memory\n");
452 return DXFILEERR_BADALLOC
;
455 object
->lpVtbl
.lpVtbl
= &IDirectXFileBinary_Vtbl
;
463 /*** IUnknown methods ***/
464 static HRESULT WINAPI
IDirectXFileBinaryImpl_QueryInterface(IDirectXFileBinary
* iface
, REFIID riid
, void** ppvObject
)
466 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
468 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
470 if (IsEqualGUID(riid
, &IID_IUnknown
)
471 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
472 || IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
474 IClassFactory_AddRef(iface
);
479 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
480 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
)
481 && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
482 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
484 return E_NOINTERFACE
;
487 static ULONG WINAPI
IDirectXFileBinaryImpl_AddRef(IDirectXFileBinary
* iface
)
489 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
490 ULONG ref
= InterlockedIncrement(&This
->ref
);
492 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
497 static ULONG WINAPI
IDirectXFileBinaryImpl_Release(IDirectXFileBinary
* iface
)
499 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
500 ULONG ref
= InterlockedDecrement(&This
->ref
);
502 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
505 HeapFree(GetProcessHeap(), 0, This
);
510 /*** IDirectXFileObject methods ***/
511 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetName(IDirectXFileBinary
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
514 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
516 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
518 return DXFILEERR_BADVALUE
;
521 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetId(IDirectXFileBinary
* iface
, LPGUID pGuid
)
523 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
525 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pGuid
);
527 return DXFILEERR_BADVALUE
;
530 /*** IDirectXFileBinary methods ***/
531 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetSize(IDirectXFileBinary
* iface
, DWORD
* pcbSize
)
533 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
535 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pcbSize
);
537 return DXFILEERR_BADVALUE
;
540 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetMimeType(IDirectXFileBinary
* iface
, LPCSTR
* pszMimeType
)
542 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
544 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pszMimeType
);
546 return DXFILEERR_BADVALUE
;
549 static HRESULT WINAPI
IDirectXFileBinaryImpl_Read(IDirectXFileBinary
* iface
, LPVOID pvData
, DWORD cbSize
, LPDWORD pcbRead
)
551 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
553 FIXME("(%p/%p)->(%p, %d, %p) stub!\n", This
, iface
, pvData
, cbSize
, pcbRead
);
555 return DXFILEERR_BADVALUE
;
558 static const IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl
=
560 IDirectXFileBinaryImpl_QueryInterface
,
561 IDirectXFileBinaryImpl_AddRef
,
562 IDirectXFileBinaryImpl_Release
,
563 IDirectXFileBinaryImpl_GetName
,
564 IDirectXFileBinaryImpl_GetId
,
565 IDirectXFileBinaryImpl_GetSize
,
566 IDirectXFileBinaryImpl_GetMimeType
,
567 IDirectXFileBinaryImpl_Read
570 static HRESULT
IDirectXFileDataImpl_Create(IDirectXFileDataImpl
** ppObj
)
572 IDirectXFileDataImpl
* object
;
574 TRACE("(%p)\n", ppObj
);
576 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataImpl
));
579 ERR("Out of memory\n");
580 return DXFILEERR_BADALLOC
;
583 object
->lpVtbl
.lpVtbl
= &IDirectXFileData_Vtbl
;
591 /*** IUnknown methods ***/
592 static HRESULT WINAPI
IDirectXFileDataImpl_QueryInterface(IDirectXFileData
* iface
, REFIID riid
, void** ppvObject
)
594 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
596 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
598 if (IsEqualGUID(riid
, &IID_IUnknown
)
599 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
600 || IsEqualGUID(riid
, &IID_IDirectXFileData
))
602 IClassFactory_AddRef(iface
);
607 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
608 if (!IsEqualGUID(riid
, &IID_IDirectXFileBinary
)
609 && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
610 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
612 return E_NOINTERFACE
;
615 static ULONG WINAPI
IDirectXFileDataImpl_AddRef(IDirectXFileData
* iface
)
617 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
618 ULONG ref
= InterlockedIncrement(&This
->ref
);
620 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
625 static ULONG WINAPI
IDirectXFileDataImpl_Release(IDirectXFileData
* iface
)
627 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
628 ULONG ref
= InterlockedDecrement(&This
->ref
);
630 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
634 if (!This
->level
&& !This
->from_ref
)
636 HeapFree(GetProcessHeap(), 0, This
->pstrings
);
637 HeapFree(GetProcessHeap(), 0, This
->pobj
->pdata
);
638 HeapFree(GetProcessHeap(), 0, This
->pobj
);
640 HeapFree(GetProcessHeap(), 0, This
);
646 /*** IDirectXFileObject methods ***/
647 static HRESULT WINAPI
IDirectXFileDataImpl_GetName(IDirectXFileData
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
650 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
652 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
655 return DXFILEERR_BADVALUE
;
657 strcpy(pstrNameBuf
, This
->pobj
->name
);
662 static HRESULT WINAPI
IDirectXFileDataImpl_GetId(IDirectXFileData
* iface
, LPGUID pGuid
)
664 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
666 TRACE("(%p/%p)->(%p)\n", This
, iface
, pGuid
);
669 return DXFILEERR_BADVALUE
;
671 memcpy(pGuid
, &This
->pobj
->class_id
, 16);
676 /*** IDirectXFileData methods ***/
677 static HRESULT WINAPI
IDirectXFileDataImpl_GetData(IDirectXFileData
* iface
, LPCSTR szMember
, DWORD
* pcbSize
, void** ppvData
)
679 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
681 TRACE("(%p/%p)->(%s,%p,%p)\n", This
, iface
, szMember
, pcbSize
, ppvData
);
683 if (!pcbSize
|| !ppvData
)
684 return DXFILEERR_BADVALUE
;
688 FIXME("Specifying a member is not supported yet!\n");
689 return DXFILEERR_BADVALUE
;
692 *pcbSize
= This
->pobj
->size
;
693 *ppvData
= This
->pobj
->root
->pdata
+ This
->pobj
->pos_data
;
698 static HRESULT WINAPI
IDirectXFileDataImpl_GetType(IDirectXFileData
* iface
, const GUID
** pguid
)
700 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
703 TRACE("(%p/%p)->(%p)\n", This
, iface
, pguid
);
706 return DXFILEERR_BADVALUE
;
708 memcpy(&guid
, &This
->pobj
->type
, 16);
714 static HRESULT WINAPI
IDirectXFileDataImpl_GetNextObject(IDirectXFileData
* iface
, LPDIRECTXFILEOBJECT
* ppChildObj
)
717 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
719 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppChildObj
);
721 if (This
->cur_enum_object
>= This
->pobj
->nb_childs
)
722 return DXFILEERR_NOMOREOBJECTS
;
724 if (This
->from_ref
&& (This
->level
>= 1))
726 /* Only 2 levels can enumerated if the object is obtained from a reference */
727 return DXFILEERR_NOMOREOBJECTS
;
730 if (This
->pobj
->childs
[This
->cur_enum_object
]->binary
)
732 IDirectXFileBinaryImpl
*object
;
734 hr
= IDirectXFileBinaryImpl_Create(&object
);
738 *ppChildObj
= (LPDIRECTXFILEOBJECT
)object
;
740 else if (This
->pobj
->childs
[This
->cur_enum_object
]->ptarget
)
742 IDirectXFileDataReferenceImpl
*object
;
744 hr
= IDirectXFileDataReferenceImpl_Create(&object
);
748 object
->ptarget
= This
->pobj
->childs
[This
->cur_enum_object
++]->ptarget
;
750 *ppChildObj
= (LPDIRECTXFILEOBJECT
)object
;
754 IDirectXFileDataImpl
*object
;
756 hr
= IDirectXFileDataImpl_Create(&object
);
760 object
->pobj
= This
->pobj
->childs
[This
->cur_enum_object
++];
761 object
->cur_enum_object
= 0;
762 object
->from_ref
= This
->from_ref
;
763 object
->level
= This
->level
+ 1;
765 *ppChildObj
= (LPDIRECTXFILEOBJECT
)object
;
771 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataObject(IDirectXFileData
* iface
, LPDIRECTXFILEDATA pDataObj
)
773 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
775 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pDataObj
);
777 return DXFILEERR_BADVALUE
;
780 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataReference(IDirectXFileData
* iface
, LPCSTR szRef
, const GUID
* pguidRef
)
782 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
784 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szRef
, pguidRef
);
786 return DXFILEERR_BADVALUE
;
789 static HRESULT WINAPI
IDirectXFileDataImpl_AddBinaryObject(IDirectXFileData
* iface
, LPCSTR szName
, const GUID
* pguid
, LPCSTR szMimeType
, LPVOID pvData
, DWORD cbSize
)
791 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
793 FIXME("(%p/%p)->(%s,%p,%s,%p,%d) stub!\n", This
, iface
, szName
, pguid
, szMimeType
, pvData
, cbSize
);
795 return DXFILEERR_BADVALUE
;
798 static const IDirectXFileDataVtbl IDirectXFileData_Vtbl
=
800 IDirectXFileDataImpl_QueryInterface
,
801 IDirectXFileDataImpl_AddRef
,
802 IDirectXFileDataImpl_Release
,
803 IDirectXFileDataImpl_GetName
,
804 IDirectXFileDataImpl_GetId
,
805 IDirectXFileDataImpl_GetData
,
806 IDirectXFileDataImpl_GetType
,
807 IDirectXFileDataImpl_GetNextObject
,
808 IDirectXFileDataImpl_AddDataObject
,
809 IDirectXFileDataImpl_AddDataReference
,
810 IDirectXFileDataImpl_AddBinaryObject
813 static HRESULT
IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl
** ppObj
)
815 IDirectXFileDataReferenceImpl
* object
;
817 TRACE("(%p)\n", ppObj
);
819 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataReferenceImpl
));
822 ERR("Out of memory\n");
823 return DXFILEERR_BADALLOC
;
826 object
->lpVtbl
.lpVtbl
= &IDirectXFileDataReference_Vtbl
;
834 /*** IUnknown methods ***/
835 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_QueryInterface(IDirectXFileDataReference
* iface
, REFIID riid
, void** ppvObject
)
837 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
839 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
841 if (IsEqualGUID(riid
, &IID_IUnknown
)
842 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
843 || IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
845 IClassFactory_AddRef(iface
);
850 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
851 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
)
852 && !IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
853 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
855 return E_NOINTERFACE
;
858 static ULONG WINAPI
IDirectXFileDataReferenceImpl_AddRef(IDirectXFileDataReference
* iface
)
860 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
861 ULONG ref
= InterlockedIncrement(&This
->ref
);
863 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
868 static ULONG WINAPI
IDirectXFileDataReferenceImpl_Release(IDirectXFileDataReference
* iface
)
870 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
871 ULONG ref
= InterlockedDecrement(&This
->ref
);
873 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
876 HeapFree(GetProcessHeap(), 0, This
);
881 /*** IDirectXFileObject methods ***/
882 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetName(IDirectXFileDataReference
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
884 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
886 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
889 return DXFILEERR_BADVALUE
;
891 strcpy(pstrNameBuf
, This
->ptarget
->name
);
893 return DXFILEERR_BADVALUE
;
896 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetId(IDirectXFileDataReference
* iface
, LPGUID pGuid
)
898 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
900 TRACE("(%p/%p)->(%p)\n", This
, iface
, pGuid
);
903 return DXFILEERR_BADVALUE
;
905 memcpy(pGuid
, &This
->ptarget
->class_id
, 16);
910 /*** IDirectXFileDataReference ***/
911 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
913 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
914 IDirectXFileDataImpl
*object
;
917 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
920 return DXFILEERR_BADVALUE
;
922 hr
= IDirectXFileDataImpl_Create(&object
);
926 object
->pobj
= This
->ptarget
;
927 object
->cur_enum_object
= 0;
929 object
->from_ref
= TRUE
;
931 *ppDataObj
= (LPDIRECTXFILEDATA
)object
;
936 static const IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl
=
938 IDirectXFileDataReferenceImpl_QueryInterface
,
939 IDirectXFileDataReferenceImpl_AddRef
,
940 IDirectXFileDataReferenceImpl_Release
,
941 IDirectXFileDataReferenceImpl_GetName
,
942 IDirectXFileDataReferenceImpl_GetId
,
943 IDirectXFileDataReferenceImpl_Resolve
946 static HRESULT
IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl
** ppObj
)
948 IDirectXFileEnumObjectImpl
* object
;
950 TRACE("(%p)\n", ppObj
);
952 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileEnumObjectImpl
));
955 ERR("Out of memory\n");
956 return DXFILEERR_BADALLOC
;
959 object
->lpVtbl
.lpVtbl
= &IDirectXFileEnumObject_Vtbl
;
967 /*** IUnknown methods ***/
968 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_QueryInterface(IDirectXFileEnumObject
* iface
, REFIID riid
, void** ppvObject
)
970 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
972 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
974 if (IsEqualGUID(riid
, &IID_IUnknown
)
975 || IsEqualGUID(riid
, &IID_IDirectXFileEnumObject
))
977 IClassFactory_AddRef(iface
);
982 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
983 return E_NOINTERFACE
;
986 static ULONG WINAPI
IDirectXFileEnumObjectImpl_AddRef(IDirectXFileEnumObject
* iface
)
988 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
989 ULONG ref
= InterlockedIncrement(&This
->ref
);
991 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
996 static ULONG WINAPI
IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject
* iface
)
998 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
999 ULONG ref
= InterlockedDecrement(&This
->ref
);
1001 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
1006 for (i
= 0; i
< This
->nb_xobjects
; i
++)
1007 IDirectXFileData_Release(This
->pRefObjects
[i
]);
1008 if (This
->source
== DXFILELOAD_FROMFILE
)
1010 UnmapViewOfFile(This
->buffer
);
1011 CloseHandle(This
->file_mapping
);
1012 CloseHandle(This
->hFile
);
1014 else if (This
->source
== DXFILELOAD_FROMRESOURCE
)
1015 FreeResource(This
->resource_data
);
1016 HeapFree(GetProcessHeap(), 0, This
);
1022 /*** IDirectXFileEnumObject methods ***/
1023 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
1025 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1026 IDirectXFileDataImpl
* object
;
1028 LPBYTE pstrings
= NULL
;
1030 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
1032 if (This
->nb_xobjects
>= MAX_OBJECTS
)
1034 ERR("Too many objects\n");
1035 return DXFILEERR_NOMOREOBJECTS
;
1038 if (!This
->buf
.rem_bytes
)
1039 return DXFILEERR_NOMOREOBJECTS
;
1041 hr
= IDirectXFileDataImpl_Create(&object
);
1045 This
->buf
.pxo_globals
= This
->xobjects
;
1046 This
->buf
.nb_pxo_globals
= This
->nb_xobjects
;
1047 This
->buf
.cur_subobject
= 1;
1048 This
->buf
.level
= 0;
1050 This
->buf
.pxo_tab
= HeapAlloc(GetProcessHeap(), 0, sizeof(xobject
)*MAX_SUBOBJECTS
);
1051 if (!This
->buf
.pxo_tab
)
1053 ERR("Out of memory\n");
1054 hr
= DXFILEERR_BADALLOC
;
1057 This
->buf
.pxo
= This
->xobjects
[This
->nb_xobjects
] = This
->buf
.pxo_tab
;
1059 This
->buf
.pxo
->pdata
= This
->buf
.pdata
= NULL
;
1060 This
->buf
.capacity
= 0;
1061 This
->buf
.cur_pos_data
= 0;
1063 pstrings
= HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER
);
1066 ERR("Out of memory\n");
1067 hr
= DXFILEERR_BADALLOC
;
1070 This
->buf
.cur_pstrings
= This
->buf
.pstrings
= object
->pstrings
= pstrings
;
1072 if (!parse_object(&This
->buf
))
1074 TRACE("Object is not correct\n");
1075 hr
= DXFILEERR_PARSEERROR
;
1079 This
->buf
.pxo
->nb_subobjects
= This
->buf
.cur_subobject
;
1080 if (This
->buf
.cur_subobject
> MAX_SUBOBJECTS
)
1082 FIXME("Too many suobjects %d\n", This
->buf
.cur_subobject
);
1083 hr
= DXFILEERR_BADALLOC
;
1087 object
->pstrings
= pstrings
;
1088 object
->pobj
= This
->buf
.pxo
;
1089 object
->cur_enum_object
= 0;
1091 object
->from_ref
= FALSE
;
1093 *ppDataObj
= (LPDIRECTXFILEDATA
)object
;
1095 /* Get a reference to created object */
1096 This
->pRefObjects
[This
->nb_xobjects
] = (LPDIRECTXFILEDATA
)object
;
1097 IDirectXFileData_AddRef(This
->pRefObjects
[This
->nb_xobjects
]);
1099 This
->nb_xobjects
++;
1105 HeapFree(GetProcessHeap(), 0, This
->buf
.pxo_tab
);
1106 HeapFree(GetProcessHeap(), 0, This
->buf
.pxo
->pdata
);
1107 HeapFree(GetProcessHeap(), 0, pstrings
);
1112 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectById(IDirectXFileEnumObject
* iface
, REFGUID rguid
, LPDIRECTXFILEDATA
* ppDataObj
)
1114 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1116 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, rguid
, ppDataObj
);
1118 return DXFILEERR_BADVALUE
;
1121 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectByName(IDirectXFileEnumObject
* iface
, LPCSTR szName
, LPDIRECTXFILEDATA
* ppDataObj
)
1123 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1125 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szName
, ppDataObj
);
1127 return DXFILEERR_BADVALUE
;
1130 static const IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl
=
1132 IDirectXFileEnumObjectImpl_QueryInterface
,
1133 IDirectXFileEnumObjectImpl_AddRef
,
1134 IDirectXFileEnumObjectImpl_Release
,
1135 IDirectXFileEnumObjectImpl_GetNextDataObject
,
1136 IDirectXFileEnumObjectImpl_GetDataObjectById
,
1137 IDirectXFileEnumObjectImpl_GetDataObjectByName
1140 static HRESULT
IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl
** ppObj
)
1142 IDirectXFileSaveObjectImpl
* object
;
1144 TRACE("(%p)\n", ppObj
);
1146 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileSaveObjectImpl
));
1149 ERR("Out of memory\n");
1150 return DXFILEERR_BADALLOC
;
1153 object
->lpVtbl
.lpVtbl
= &IDirectXFileSaveObject_Vtbl
;
1161 /*** IUnknown methods ***/
1162 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_QueryInterface(IDirectXFileSaveObject
* iface
, REFIID riid
, void** ppvObject
)
1164 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
1166 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1168 if (IsEqualGUID(riid
, &IID_IUnknown
)
1169 || IsEqualGUID(riid
, &IID_IDirectXFileSaveObject
))
1171 IClassFactory_AddRef(iface
);
1176 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1177 return E_NOINTERFACE
;
1180 static ULONG WINAPI
IDirectXFileSaveObjectImpl_AddRef(IDirectXFileSaveObject
* iface
)
1182 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
1183 ULONG ref
= InterlockedIncrement(&This
->ref
);
1185 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
1190 static ULONG WINAPI
IDirectXFileSaveObjectImpl_Release(IDirectXFileSaveObject
* iface
)
1192 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
1193 ULONG ref
= InterlockedDecrement(&This
->ref
);
1195 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
1198 HeapFree(GetProcessHeap(), 0, This
);
1203 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveTemplates(IDirectXFileSaveObject
* iface
, DWORD cTemplates
, const GUID
** ppguidTemplates
)
1205 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
1207 FIXME("(%p/%p)->(%d,%p) stub!\n", This
, iface
, cTemplates
, ppguidTemplates
);
1209 return DXFILEERR_BADVALUE
;
1212 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_CreateDataObject(IDirectXFileSaveObject
* iface
, REFGUID rguidTemplate
, LPCSTR szName
, const GUID
* pguid
, DWORD cbSize
, LPVOID pvData
, LPDIRECTXFILEDATA
* ppDataObj
)
1214 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
1216 FIXME("(%p/%p)->(%p,%s,%p,%d,%p,%p) stub!\n", This
, iface
, rguidTemplate
, szName
, pguid
, cbSize
, pvData
, ppDataObj
);
1218 return DXFILEERR_BADVALUE
;
1221 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveData(IDirectXFileSaveObject
* iface
, LPDIRECTXFILEDATA ppDataObj
)
1223 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
1225 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, ppDataObj
);
1227 return DXFILEERR_BADVALUE
;
1230 static const IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl
=
1232 IDirectXFileSaveObjectImpl_QueryInterface
,
1233 IDirectXFileSaveObjectImpl_AddRef
,
1234 IDirectXFileSaveObjectImpl_Release
,
1235 IDirectXFileSaveObjectImpl_SaveTemplates
,
1236 IDirectXFileSaveObjectImpl_CreateDataObject
,
1237 IDirectXFileSaveObjectImpl_SaveData