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')
50 #define TOKEN_STRING 2
51 #define TOKEN_INTEGER 3
53 #define TOKEN_INTEGER_LIST 6
54 #define TOKEN_FLOAT_LIST 7
55 #define TOKEN_OBRACE 10
56 #define TOKEN_CBRACE 11
57 #define TOKEN_OPAREN 12
58 #define TOKEN_CPAREN 13
59 #define TOKEN_OBRACKET 14
60 #define TOKEN_CBRACKET 15
61 #define TOKEN_OANGLE 16
62 #define TOKEN_CANGLE 17
64 #define TOKEN_COMMA 19
65 #define TOKEN_SEMICOLON 20
66 #define TOKEN_TEMPLATE 31
68 #define TOKEN_DWORD 41
69 #define TOKEN_FLOAT 42
70 #define TOKEN_DOUBLE 43
72 #define TOKEN_UCHAR 45
73 #define TOKEN_SWORD 46
74 #define TOKEN_SDWORD 47
76 #define TOKEN_LPSTR 49
77 #define TOKEN_UNICODE 50
78 #define TOKEN_CSTRING 51
79 #define TOKEN_ARRAY 52
81 #define CLSIDFMT "<%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X>"
83 #define MAX_INPUT_SIZE 2000000
84 #define MAX_DATA_SIZE 400000
86 static const struct IDirectXFileVtbl IDirectXFile_Vtbl
;
87 static const struct IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl
;
88 static const struct IDirectXFileDataVtbl IDirectXFileData_Vtbl
;
89 static const struct IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl
;
90 static const struct IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl
;
91 static const struct IDirectXFileObjectVtbl IDirectXFileObject_Vtbl
;
92 static const struct IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl
;
94 static BOOL
parse_object_parts(parse_buffer
* buf
, BOOL allow_optional
);
95 static BOOL
parse_object(parse_buffer
* buf
);
96 static const char* get_primitive_string(WORD token
);
97 static WORD
check_TOKEN(parse_buffer
* buf
);
98 static BOOL
parse_template(parse_buffer
* buf
);
99 static HRESULT
IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl
** ppObj
);
100 static HRESULT
IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl
** ppObj
);
101 static HRESULT
IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl
** ppObj
);
103 static void dump_template(xtemplate
* templates_array
, xtemplate
* ptemplate
)
108 clsid
= &ptemplate
->class_id
;
110 DPRINTF("template %s\n", ptemplate
->name
);
112 DPRINTF(CLSIDFMT
"\n", clsid
->Data1
, clsid
->Data2
, clsid
->Data3
, clsid
->Data4
[0],
113 clsid
->Data4
[1], clsid
->Data4
[2], clsid
->Data4
[3], clsid
->Data4
[4], clsid
->Data4
[5], clsid
->Data4
[6], clsid
->Data4
[7]);
114 for (j
= 0; j
< ptemplate
->nb_members
; j
++)
116 if (ptemplate
->members
[j
].nb_dims
)
118 if (ptemplate
->members
[j
].type
== TOKEN_NAME
)
119 DPRINTF("%s ", templates_array
[ptemplate
->members
[j
].idx_template
].name
);
121 DPRINTF("%s ", get_primitive_string(ptemplate
->members
[j
].type
));
122 DPRINTF("%s", ptemplate
->members
[j
].name
);
123 for (k
= 0; k
< ptemplate
->members
[j
].nb_dims
; k
++)
125 if (ptemplate
->members
[j
].dim_fixed
[k
])
126 DPRINTF("[%d]", ptemplate
->members
[j
].dim_value
[k
]);
128 DPRINTF("[%s]", ptemplate
->members
[ptemplate
->members
[j
].dim_value
[k
]].name
);
134 else if (ptemplate
->nb_childs
)
136 DPRINTF("[%s", ptemplate
->childs
[0]);
137 for (j
= 1; j
< ptemplate
->nb_childs
; j
++)
138 DPRINTF(",%s", ptemplate
->childs
[j
]);
144 HRESULT
IDirectXFileImpl_Create(IUnknown
* pUnkOuter
, LPVOID
* ppObj
)
146 IDirectXFileImpl
* object
;
148 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
150 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileImpl
));
153 ERR("Out of memory\n");
154 return DXFILEERR_BADALLOC
;
157 object
->lpVtbl
.lpVtbl
= &IDirectXFile_Vtbl
;
165 /*** IUnknown methods ***/
166 static HRESULT WINAPI
IDirectXFileImpl_QueryInterface(IDirectXFile
* iface
, REFIID riid
, void** ppvObject
)
168 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
170 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
172 if (IsEqualGUID(riid
, &IID_IUnknown
)
173 || IsEqualGUID(riid
, &IID_IDirectXFile
))
175 IClassFactory_AddRef(iface
);
180 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
181 return E_NOINTERFACE
;
184 static ULONG WINAPI
IDirectXFileImpl_AddRef(IDirectXFile
* iface
)
186 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
187 ULONG ref
= InterlockedIncrement(&This
->ref
);
189 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
194 static ULONG WINAPI
IDirectXFileImpl_Release(IDirectXFile
* iface
)
196 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
197 ULONG ref
= InterlockedDecrement(&This
->ref
);
199 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
202 HeapFree(GetProcessHeap(), 0, This
);
207 /*** IDirectXFile methods ***/
208 static HRESULT WINAPI
IDirectXFileImpl_CreateEnumObject(IDirectXFile
* iface
, LPVOID pvSource
, DXFILELOADOPTIONS dwLoadOptions
, LPDIRECTXFILEENUMOBJECT
* ppEnumObj
)
210 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
211 IDirectXFileEnumObjectImpl
* object
;
215 HANDLE hFile
= INVALID_HANDLE_VALUE
;
216 LPDXFILELOADMEMORY lpdxflm
= NULL
;
218 TRACE("(%p/%p)->(%p,%x,%p)\n", This
, iface
, pvSource
, dwLoadOptions
, ppEnumObj
);
221 return DXFILEERR_BADVALUE
;
223 if (dwLoadOptions
== DXFILELOAD_FROMFILE
)
225 TRACE("Open source file '%s'\n", (char*)pvSource
);
227 hFile
= CreateFileA((char*)pvSource
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
228 if (hFile
== INVALID_HANDLE_VALUE
)
230 TRACE("File '%s' not found\n", (char*)pvSource
);
231 return DXFILEERR_FILENOTFOUND
;
234 if (!ReadFile(hFile
, header
, 16, &size
, NULL
))
236 hr
= DXFILEERR_BADVALUE
;
242 hr
= DXFILEERR_BADFILETYPE
;
246 else if (dwLoadOptions
== DXFILELOAD_FROMMEMORY
)
248 lpdxflm
= (LPDXFILELOADMEMORY
)pvSource
;
250 TRACE("Source in memory at %p with size %d\n", lpdxflm
->lpMemory
, lpdxflm
->dSize
);
252 memcpy(header
, (char*)lpdxflm
->lpMemory
, 16);
256 FIXME("Source type %d is not handled yet\n", dwLoadOptions
);
257 hr
= DXFILEERR_NOTDONEYET
;
261 if (TRACE_ON(d3dxof
))
264 memcpy(string
, header
, 16);
266 TRACE("header = '%s'\n", string
);
269 if (header
[0] != XOFFILE_FORMAT_MAGIC
)
271 hr
= DXFILEERR_BADFILETYPE
;
275 if ((header
[1] != XOFFILE_FORMAT_VERSION_302
) && (header
[1] != XOFFILE_FORMAT_VERSION_303
))
277 hr
= DXFILEERR_BADFILEVERSION
;
281 if ((header
[2] != XOFFILE_FORMAT_BINARY
) && (header
[2] != XOFFILE_FORMAT_TEXT
) && (header
[2] != XOFFILE_FORMAT_COMPRESSED
))
283 hr
= DXFILEERR_BADFILETYPE
;
287 if (header
[2] == XOFFILE_FORMAT_COMPRESSED
)
289 FIXME("Compressed formats not supported yet\n");
290 hr
= DXFILEERR_BADVALUE
;
294 if ((header
[3] != XOFFILE_FORMAT_FLOAT_BITS_32
) && (header
[3] != XOFFILE_FORMAT_FLOAT_BITS_64
))
296 hr
= DXFILEERR_BADFILEFLOATSIZE
;
300 TRACE("Header is correct\n");
302 hr
= IDirectXFileEnumObjectImpl_Create(&object
);
306 object
->source
= dwLoadOptions
;
307 object
->hFile
= hFile
;
308 object
->pDirectXFile
= This
;
309 object
->buf
.pdxf
= This
;
310 object
->buf
.txt
= (header
[2] == XOFFILE_FORMAT_TEXT
);
311 object
->buf
.token_present
= FALSE
;
312 object
->buf
.cur_subobject
= 0;
314 if (dwLoadOptions
== DXFILELOAD_FROMFILE
)
316 object
->buf
.buffer
= HeapAlloc(GetProcessHeap(), 0, MAX_INPUT_SIZE
+1);
317 if (!object
->buf
.buffer
)
319 ERR("Out of memory\n");
320 hr
= DXFILEERR_BADALLOC
;
324 ReadFile(hFile
, object
->buf
.buffer
, MAX_INPUT_SIZE
+1, &object
->buf
.rem_bytes
, NULL
);
325 if (object
->buf
.rem_bytes
> MAX_INPUT_SIZE
)
327 FIXME("File size > %d not supported yet\n", MAX_INPUT_SIZE
);
328 HeapFree(GetProcessHeap(), 0, object
->buf
.buffer
);
329 hr
= DXFILEERR_PARSEERROR
;
335 object
->buf
.buffer
= ((LPBYTE
)lpdxflm
->lpMemory
) + 16;
336 object
->buf
.rem_bytes
= lpdxflm
->dSize
;
339 TRACE("Read %d bytes\n", object
->buf
.rem_bytes
);
341 *ppEnumObj
= (LPDIRECTXFILEENUMOBJECT
)object
;
343 while (object
->buf
.rem_bytes
&& (check_TOKEN(&object
->buf
) == TOKEN_TEMPLATE
))
345 if (!parse_template(&object
->buf
))
347 TRACE("Template is not correct\n");
348 hr
= DXFILEERR_BADVALUE
;
353 TRACE("Template successfully parsed:\n");
354 if (TRACE_ON(d3dxof
))
355 dump_template(This
->xtemplates
, &This
->xtemplates
[This
->nb_xtemplates
- 1]);
359 if (TRACE_ON(d3dxof
))
362 TRACE("Registered templates (%d):\n", This
->nb_xtemplates
);
363 for (i
= 0; i
< This
->nb_xtemplates
; i
++)
364 DPRINTF("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
370 if (hFile
!= INVALID_HANDLE_VALUE
)
377 static HRESULT WINAPI
IDirectXFileImpl_CreateSaveObject(IDirectXFile
* iface
, LPCSTR szFileName
, DXFILEFORMAT dwFileFormat
, LPDIRECTXFILESAVEOBJECT
* ppSaveObj
)
379 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
381 FIXME("(%p/%p)->(%s,%x,%p) partial stub!\n", This
, iface
, szFileName
, dwFileFormat
, ppSaveObj
);
383 if (!szFileName
|| !ppSaveObj
)
386 return IDirectXFileSaveObjectImpl_Create((IDirectXFileSaveObjectImpl
**)ppSaveObj
);
389 static BOOL
read_bytes(parse_buffer
* buf
, LPVOID data
, DWORD size
)
391 if (buf
->rem_bytes
< size
)
393 memcpy(data
, buf
->buffer
, size
);
395 buf
->rem_bytes
-= size
;
399 static void dump_TOKEN(WORD token
)
401 #define DUMP_TOKEN(t) case t: TRACE(#t "\n"); break
404 DUMP_TOKEN(TOKEN_NAME
);
405 DUMP_TOKEN(TOKEN_STRING
);
406 DUMP_TOKEN(TOKEN_INTEGER
);
407 DUMP_TOKEN(TOKEN_GUID
);
408 DUMP_TOKEN(TOKEN_INTEGER_LIST
);
409 DUMP_TOKEN(TOKEN_FLOAT_LIST
);
410 DUMP_TOKEN(TOKEN_OBRACE
);
411 DUMP_TOKEN(TOKEN_CBRACE
);
412 DUMP_TOKEN(TOKEN_OPAREN
);
413 DUMP_TOKEN(TOKEN_CPAREN
);
414 DUMP_TOKEN(TOKEN_OBRACKET
);
415 DUMP_TOKEN(TOKEN_CBRACKET
);
416 DUMP_TOKEN(TOKEN_OANGLE
);
417 DUMP_TOKEN(TOKEN_CANGLE
);
418 DUMP_TOKEN(TOKEN_DOT
);
419 DUMP_TOKEN(TOKEN_COMMA
);
420 DUMP_TOKEN(TOKEN_SEMICOLON
);
421 DUMP_TOKEN(TOKEN_TEMPLATE
);
422 DUMP_TOKEN(TOKEN_WORD
);
423 DUMP_TOKEN(TOKEN_DWORD
);
424 DUMP_TOKEN(TOKEN_FLOAT
);
425 DUMP_TOKEN(TOKEN_DOUBLE
);
426 DUMP_TOKEN(TOKEN_CHAR
);
427 DUMP_TOKEN(TOKEN_UCHAR
);
428 DUMP_TOKEN(TOKEN_SWORD
);
429 DUMP_TOKEN(TOKEN_SDWORD
);
430 DUMP_TOKEN(TOKEN_VOID
);
431 DUMP_TOKEN(TOKEN_LPSTR
);
432 DUMP_TOKEN(TOKEN_UNICODE
);
433 DUMP_TOKEN(TOKEN_CSTRING
);
434 DUMP_TOKEN(TOKEN_ARRAY
);
437 TRACE("Unknown token %d\n", token
);
443 static BOOL
is_space(char c
)
457 static BOOL
is_operator(char c
)
476 static inline BOOL
is_separator(char c
)
478 return is_space(c
) || is_operator(c
);
481 static WORD
get_operator_token(char c
)
490 return TOKEN_OBRACKET
;
492 return TOKEN_CBRACKET
;
504 return TOKEN_SEMICOLON
;
509 static BOOL
is_keyword(parse_buffer
* buf
, const char* keyword
)
511 DWORD len
= strlen(keyword
);
512 if (!strncasecmp((char*)buf
->buffer
, keyword
,len
) && is_separator(*(buf
->buffer
+len
)))
515 buf
->rem_bytes
-= len
;
521 static WORD
get_keyword_token(parse_buffer
* buf
)
523 if (is_keyword(buf
, "template"))
524 return TOKEN_TEMPLATE
;
525 if (is_keyword(buf
, "WORD"))
527 if (is_keyword(buf
, "DWORD"))
529 if (is_keyword(buf
, "FLOAT"))
531 if (is_keyword(buf
, "DOUBLE"))
533 if (is_keyword(buf
, "CHAR"))
535 if (is_keyword(buf
, "UCHAR"))
537 if (is_keyword(buf
, "SWORD"))
539 if (is_keyword(buf
, "SDWORD"))
541 if (is_keyword(buf
, "VOID"))
543 if (is_keyword(buf
, "STRING"))
545 if (is_keyword(buf
, "UNICODE"))
546 return TOKEN_UNICODE
;
547 if (is_keyword(buf
, "CSTRING"))
548 return TOKEN_CSTRING
;
549 if (is_keyword(buf
, "array"))
555 static BOOL
is_guid(parse_buffer
* buf
)
563 if (*buf
->buffer
!= '<')
566 while (*(buf
->buffer
+pos
) != '>')
568 tmp
[pos
] = *(buf
->buffer
+pos
);
573 if (pos
!= 38 /* <+36+> */)
575 TRACE("Wrong guid %s (%d)\n", tmp
, pos
);
579 buf
->rem_bytes
-= pos
;
581 ret
= sscanf(tmp
, CLSIDFMT
, &class_id
.Data1
, tab
, tab
+1, tab
+2, tab
+3, tab
+4, tab
+5, tab
+6, tab
+7, tab
+8, tab
+9);
584 TRACE("Wrong guid %s (%d)\n", tmp
, pos
);
587 TRACE("Found guid %s (%d)\n", tmp
, pos
);
589 class_id
.Data2
= tab
[0];
590 class_id
.Data3
= tab
[1];
591 class_id
.Data4
[0] = tab
[2];
592 class_id
.Data4
[1] = tab
[3];
593 class_id
.Data4
[2] = tab
[4];
594 class_id
.Data4
[3] = tab
[5];
595 class_id
.Data4
[4] = tab
[6];
596 class_id
.Data4
[5] = tab
[7];
597 class_id
.Data4
[6] = tab
[8];
598 class_id
.Data4
[7] = tab
[9];
600 *(GUID
*)buf
->value
= class_id
;
605 static BOOL
is_name(parse_buffer
* buf
)
611 while (!is_separator(c
= *(buf
->buffer
+pos
)))
613 if (!(((c
>= 'a') && (c
<= 'z')) || ((c
>= 'A') && (c
<= 'Z')) || ((c
>= '0') && (c
<= '9')) || (c
== '_') || (c
== '-')))
621 TRACE("Wrong name %s\n", tmp
);
626 buf
->rem_bytes
-= pos
;
628 TRACE("Found name %s\n", tmp
);
629 strcpy((char*)buf
->value
, tmp
);
634 static BOOL
is_float(parse_buffer
* buf
)
642 while (!is_separator(c
= *(buf
->buffer
+pos
)))
644 if (!((!pos
&& (c
== '-')) || ((c
>= '0') && (c
<= '9')) || (!dot
&& (c
== '.'))))
653 buf
->rem_bytes
-= pos
;
655 sscanf(tmp
, "%f", &decimal
);
657 TRACE("Found float %s - %f\n", tmp
, decimal
);
659 *(float*)buf
->value
= decimal
;
664 static BOOL
is_integer(parse_buffer
* buf
)
671 while (!is_separator(c
= *(buf
->buffer
+pos
)))
673 if (!((c
>= '0') && (c
<= '9')))
680 buf
->rem_bytes
-= pos
;
682 sscanf(tmp
, "%d", &integer
);
684 TRACE("Found integer %s - %d\n", tmp
, integer
);
686 *(DWORD
*)buf
->value
= integer
;
691 static BOOL
is_string(parse_buffer
* buf
)
698 if (*buf
->buffer
!= '"')
701 while (!is_separator(c
= *(buf
->buffer
+pos
+1)) && (pos
< 31))
714 TRACE("Wrong string %s\n", tmp
);
718 buf
->buffer
+= pos
+ 2;
719 buf
->rem_bytes
-= pos
+ 2;
721 TRACE("Found string %s\n", tmp
);
722 strcpy((char*)buf
->value
, tmp
);
727 static WORD
parse_TOKEN(parse_buffer
* buf
)
736 if (!read_bytes(buf
, &c
, 1))
738 /*TRACE("char = '%c'\n", is_space(c) ? ' ' : c);*/
739 if ((c
== '#') || (c
== '/'))
741 /* Handle comment (# or //) */
744 if (!read_bytes(buf
, &c
, 1))
752 if (!read_bytes(buf
, &c
, 1))
759 if (is_operator(c
) && (c
!= '<'))
761 token
= get_operator_token(c
);
774 if ((token
= get_keyword_token(buf
)))
784 token
= TOKEN_INTEGER
;
803 FIXME("Unrecognize element\n");
815 if (!read_bytes(buf
, &token
, 2))
818 /* Convert integer and float list into separate elements */
819 if (token
== TOKEN_INTEGER_LIST
)
821 if (!read_bytes(buf
, &nb_elem
, 4))
823 token
= TOKEN_INTEGER
;
825 TRACE("Integer list (TOKEN_INTEGER_LIST) of size %d\n", nb_elem
);
827 else if (token
== TOKEN_FLOAT_LIST
)
829 if (!read_bytes(buf
, &nb_elem
, 4))
833 TRACE("Float list (TOKEN_FLOAT_LIST) of size %d\n", nb_elem
);
839 token
= is_float
? TOKEN_FLOAT
: TOKEN_INTEGER
;
844 if (!read_bytes(buf
, &integer
, 4))
847 *(DWORD
*)buf
->value
= integer
;
860 if (!read_bytes(buf
, &count
, 4))
862 if (!read_bytes(buf
, strname
, count
))
865 /*TRACE("name = %s\n", strname);*/
867 strcpy((char*)buf
->value
, strname
);
874 if (!read_bytes(buf
, &integer
, 4))
876 /*TRACE("integer = %ld\n", integer);*/
878 *(DWORD
*)buf
->value
= integer
;
886 if (!read_bytes(buf
, &class_id
, 16))
888 sprintf(strguid
, CLSIDFMT
, class_id
.Data1
, class_id
.Data2
, class_id
.Data3
, class_id
.Data4
[0],
889 class_id
.Data4
[1], class_id
.Data4
[2], class_id
.Data4
[3], class_id
.Data4
[4], class_id
.Data4
[5],
890 class_id
.Data4
[6], class_id
.Data4
[7]);
891 /*TRACE("guid = {%s}\n", strguid);*/
893 *(GUID
*)buf
->value
= class_id
;
901 if (!read_bytes(buf
, &count
, 4))
903 if (!read_bytes(buf
, strname
, count
))
906 if (!read_bytes(buf
, &tmp_token
, 2))
908 if ((tmp_token
!= TOKEN_COMMA
) && (tmp_token
!= TOKEN_SEMICOLON
))
909 ERR("No comma or semicolon (got %d)\n", tmp_token
);
910 /*TRACE("name = %s\n", strname);*/
912 strcpy((char*)buf
->value
, strname
);
926 case TOKEN_SEMICOLON
:
952 static const char* get_primitive_string(WORD token
)
986 static WORD
get_TOKEN(parse_buffer
* buf
)
988 if (buf
->token_present
)
990 buf
->token_present
= FALSE
;
991 return buf
->current_token
;
994 buf
->current_token
= parse_TOKEN(buf
);
996 return buf
->current_token
;
999 static WORD
check_TOKEN(parse_buffer
* buf
)
1001 if (buf
->token_present
)
1002 return buf
->current_token
;
1004 buf
->current_token
= parse_TOKEN(buf
);
1005 buf
->token_present
= TRUE
;
1007 return buf
->current_token
;
1010 static inline BOOL
is_primitive_type(WORD token
)
1035 static BOOL
parse_template_option_info(parse_buffer
* buf
)
1037 xtemplate
* cur_template
= &buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
];
1039 if (check_TOKEN(buf
) == TOKEN_DOT
)
1042 if (get_TOKEN(buf
) != TOKEN_DOT
)
1044 if (get_TOKEN(buf
) != TOKEN_DOT
)
1046 cur_template
->open
= TRUE
;
1052 if (get_TOKEN(buf
) != TOKEN_NAME
)
1054 strcpy(cur_template
->childs
[cur_template
->nb_childs
], (char*)buf
->value
);
1055 if (check_TOKEN(buf
) == TOKEN_GUID
)
1057 cur_template
->nb_childs
++;
1058 if (check_TOKEN(buf
) != TOKEN_COMMA
)
1062 cur_template
->open
= FALSE
;
1068 static BOOL
parse_template_members_list(parse_buffer
* buf
)
1077 cur_member
= &buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].members
[idx_member
];
1079 if (check_TOKEN(buf
) == TOKEN_ARRAY
)
1085 if (check_TOKEN(buf
) == TOKEN_NAME
)
1087 cur_member
->type
= get_TOKEN(buf
);
1088 cur_member
->idx_template
= 0;
1089 while (cur_member
->idx_template
< buf
->pdxf
->nb_xtemplates
)
1091 if (!strcmp((char*)buf
->value
, buf
->pdxf
->xtemplates
[cur_member
->idx_template
].name
))
1093 cur_member
->idx_template
++;
1095 if (cur_member
->idx_template
== buf
->pdxf
->nb_xtemplates
)
1097 TRACE("Reference to a nonexistent template '%s'\n", (char*)buf
->value
);
1101 else if (is_primitive_type(check_TOKEN(buf
)))
1102 cur_member
->type
= get_TOKEN(buf
);
1106 if (get_TOKEN(buf
) != TOKEN_NAME
)
1108 strcpy(cur_member
->name
, (char*)buf
->value
);
1112 while (check_TOKEN(buf
) == TOKEN_OBRACKET
)
1114 if (nb_dims
>= MAX_ARRAY_DIM
)
1116 FIXME("Too many dimensions (%d) for multi-dimensional array\n", nb_dims
+ 1);
1120 if (check_TOKEN(buf
) == TOKEN_INTEGER
)
1123 cur_member
->dim_fixed
[nb_dims
] = TRUE
;
1124 cur_member
->dim_value
[nb_dims
] = *(DWORD
*)buf
->value
;
1129 if (get_TOKEN(buf
) != TOKEN_NAME
)
1131 for (i
= 0; i
< idx_member
; i
++)
1133 if (!strcmp((char*)buf
->value
, buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].members
[i
].name
))
1135 if (buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].members
[i
].nb_dims
)
1137 ERR("Array cannot be used to specify variable array size\n");
1140 if (buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].members
[i
].type
!= TOKEN_DWORD
)
1142 FIXME("Only DWORD supported to specify variable array size\n");
1148 if (i
== idx_member
)
1150 ERR("Reference to unknown member %s\n", (char*)buf
->value
);
1153 cur_member
->dim_fixed
[nb_dims
] = FALSE
;
1154 cur_member
->dim_value
[nb_dims
] = i
;
1156 if (get_TOKEN(buf
) != TOKEN_CBRACKET
)
1162 cur_member
->nb_dims
= nb_dims
;
1164 if (get_TOKEN(buf
) != TOKEN_SEMICOLON
)
1170 buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].nb_members
= idx_member
;
1175 static BOOL
parse_template_parts(parse_buffer
* buf
)
1177 if (!parse_template_members_list(buf
))
1179 if (check_TOKEN(buf
) == TOKEN_OBRACKET
)
1182 if (!parse_template_option_info(buf
))
1184 if (get_TOKEN(buf
) != TOKEN_CBRACKET
)
1191 static void go_to_next_definition(parse_buffer
* buf
)
1193 while (buf
->rem_bytes
)
1195 char c
= *buf
->buffer
;
1196 if ((c
== '#') || (c
== '/'))
1198 read_bytes(buf
, &c
, 1);
1199 /* Handle comment (# or //) */
1202 if (!read_bytes(buf
, &c
, 1))
1210 if (!read_bytes(buf
, &c
, 1))
1215 else if (is_space(*buf
->buffer
))
1225 static BOOL
parse_template(parse_buffer
* buf
)
1227 if (get_TOKEN(buf
) != TOKEN_TEMPLATE
)
1229 if (get_TOKEN(buf
) != TOKEN_NAME
)
1231 strcpy(buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].name
, (char*)buf
->value
);
1232 if (get_TOKEN(buf
) != TOKEN_OBRACE
)
1234 if (get_TOKEN(buf
) != TOKEN_GUID
)
1236 buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].class_id
= *(GUID
*)buf
->value
;
1237 if (!parse_template_parts(buf
))
1239 if (get_TOKEN(buf
) != TOKEN_CBRACE
)
1243 /* Go to the next template */
1244 go_to_next_definition(buf
);
1247 TRACE("%d - %s - %s\n", buf
->pdxf
->nb_xtemplates
, buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].name
, debugstr_guid(&buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].class_id
));
1248 buf
->pdxf
->nb_xtemplates
++;
1253 static HRESULT WINAPI
IDirectXFileImpl_RegisterTemplates(IDirectXFile
* iface
, LPVOID pvData
, DWORD cbSize
)
1255 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
1259 buf
.buffer
= (LPBYTE
)pvData
;
1260 buf
.rem_bytes
= cbSize
;
1262 buf
.token_present
= FALSE
;
1265 TRACE("(%p/%p)->(%p,%d)\n", This
, iface
, pvData
, cbSize
);
1268 return DXFILEERR_BADVALUE
;
1271 return DXFILEERR_BADFILETYPE
;
1273 if (TRACE_ON(d3dxof
))
1276 memcpy(string
, pvData
, 16);
1278 TRACE("header = '%s'\n", string
);
1281 read_bytes(&buf
, &token_header
, 4);
1283 if (token_header
!= XOFFILE_FORMAT_MAGIC
)
1284 return DXFILEERR_BADFILETYPE
;
1286 read_bytes(&buf
, &token_header
, 4);
1288 if ((token_header
!= XOFFILE_FORMAT_VERSION_302
) && (token_header
!= XOFFILE_FORMAT_VERSION_303
))
1289 return DXFILEERR_BADFILEVERSION
;
1291 read_bytes(&buf
, &token_header
, 4);
1293 if ((token_header
!= XOFFILE_FORMAT_BINARY
) && (token_header
!= XOFFILE_FORMAT_TEXT
) && (token_header
!= XOFFILE_FORMAT_COMPRESSED
))
1294 return DXFILEERR_BADFILETYPE
;
1296 if (token_header
== XOFFILE_FORMAT_TEXT
)
1301 if (token_header
== XOFFILE_FORMAT_COMPRESSED
)
1303 FIXME("Compressed formats not supported yet\n");
1304 return DXFILEERR_BADVALUE
;
1307 read_bytes(&buf
, &token_header
, 4);
1309 if ((token_header
!= XOFFILE_FORMAT_FLOAT_BITS_32
) && (token_header
!= XOFFILE_FORMAT_FLOAT_BITS_64
))
1310 return DXFILEERR_BADFILEFLOATSIZE
;
1312 TRACE("Header is correct\n");
1314 while (buf
.rem_bytes
)
1316 if (!parse_template(&buf
))
1318 TRACE("Template is not correct\n");
1319 return DXFILEERR_BADVALUE
;
1323 TRACE("Template successfully parsed:\n");
1324 if (TRACE_ON(d3dxof
))
1325 dump_template(This
->xtemplates
, &This
->xtemplates
[This
->nb_xtemplates
- 1]);
1329 if (TRACE_ON(d3dxof
))
1332 TRACE("Registered templates (%d):\n", This
->nb_xtemplates
);
1333 for (i
= 0; i
< This
->nb_xtemplates
; i
++)
1334 DPRINTF("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
1340 static const IDirectXFileVtbl IDirectXFile_Vtbl
=
1342 IDirectXFileImpl_QueryInterface
,
1343 IDirectXFileImpl_AddRef
,
1344 IDirectXFileImpl_Release
,
1345 IDirectXFileImpl_CreateEnumObject
,
1346 IDirectXFileImpl_CreateSaveObject
,
1347 IDirectXFileImpl_RegisterTemplates
1350 static HRESULT
IDirectXFileBinaryImpl_Create(IDirectXFileBinaryImpl
** ppObj
)
1352 IDirectXFileBinaryImpl
* object
;
1354 TRACE("(%p)\n", ppObj
);
1356 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileBinaryImpl
));
1359 ERR("Out of memory\n");
1360 return DXFILEERR_BADALLOC
;
1363 object
->lpVtbl
.lpVtbl
= &IDirectXFileBinary_Vtbl
;
1371 /*** IUnknown methods ***/
1372 static HRESULT WINAPI
IDirectXFileBinaryImpl_QueryInterface(IDirectXFileBinary
* iface
, REFIID riid
, void** ppvObject
)
1374 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1376 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1378 if (IsEqualGUID(riid
, &IID_IUnknown
)
1379 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
1380 || IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
1382 IClassFactory_AddRef(iface
);
1387 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
1388 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
)
1389 && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
1390 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1392 return E_NOINTERFACE
;
1395 static ULONG WINAPI
IDirectXFileBinaryImpl_AddRef(IDirectXFileBinary
* iface
)
1397 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1398 ULONG ref
= InterlockedIncrement(&This
->ref
);
1400 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
1405 static ULONG WINAPI
IDirectXFileBinaryImpl_Release(IDirectXFileBinary
* iface
)
1407 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1408 ULONG ref
= InterlockedDecrement(&This
->ref
);
1410 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
1413 HeapFree(GetProcessHeap(), 0, This
);
1418 /*** IDirectXFileObject methods ***/
1419 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetName(IDirectXFileBinary
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
1422 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1424 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
1426 return DXFILEERR_BADVALUE
;
1429 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetId(IDirectXFileBinary
* iface
, LPGUID pGuid
)
1431 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1433 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pGuid
);
1435 return DXFILEERR_BADVALUE
;
1438 /*** IDirectXFileBinary methods ***/
1439 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetSize(IDirectXFileBinary
* iface
, DWORD
* pcbSize
)
1441 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1443 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pcbSize
);
1445 return DXFILEERR_BADVALUE
;
1448 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetMimeType(IDirectXFileBinary
* iface
, LPCSTR
* pszMimeType
)
1450 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1452 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pszMimeType
);
1454 return DXFILEERR_BADVALUE
;
1457 static HRESULT WINAPI
IDirectXFileBinaryImpl_Read(IDirectXFileBinary
* iface
, LPVOID pvData
, DWORD cbSize
, LPDWORD pcbRead
)
1459 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1461 FIXME("(%p/%p)->(%p, %d, %p) stub!\n", This
, iface
, pvData
, cbSize
, pcbRead
);
1463 return DXFILEERR_BADVALUE
;
1466 static const IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl
=
1468 IDirectXFileBinaryImpl_QueryInterface
,
1469 IDirectXFileBinaryImpl_AddRef
,
1470 IDirectXFileBinaryImpl_Release
,
1471 IDirectXFileBinaryImpl_GetName
,
1472 IDirectXFileBinaryImpl_GetId
,
1473 IDirectXFileBinaryImpl_GetSize
,
1474 IDirectXFileBinaryImpl_GetMimeType
,
1475 IDirectXFileBinaryImpl_Read
1478 static HRESULT
IDirectXFileDataImpl_Create(IDirectXFileDataImpl
** ppObj
)
1480 IDirectXFileDataImpl
* object
;
1482 TRACE("(%p)\n", ppObj
);
1484 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataImpl
));
1487 ERR("Out of memory\n");
1488 return DXFILEERR_BADALLOC
;
1491 object
->lpVtbl
.lpVtbl
= &IDirectXFileData_Vtbl
;
1499 /*** IUnknown methods ***/
1500 static HRESULT WINAPI
IDirectXFileDataImpl_QueryInterface(IDirectXFileData
* iface
, REFIID riid
, void** ppvObject
)
1502 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1504 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1506 if (IsEqualGUID(riid
, &IID_IUnknown
)
1507 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
1508 || IsEqualGUID(riid
, &IID_IDirectXFileData
))
1510 IClassFactory_AddRef(iface
);
1515 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
1516 if (!IsEqualGUID(riid
, &IID_IDirectXFileBinary
)
1517 && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
1518 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1520 return E_NOINTERFACE
;
1523 static ULONG WINAPI
IDirectXFileDataImpl_AddRef(IDirectXFileData
* iface
)
1525 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1526 ULONG ref
= InterlockedIncrement(&This
->ref
);
1528 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
1533 static ULONG WINAPI
IDirectXFileDataImpl_Release(IDirectXFileData
* iface
)
1535 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1536 ULONG ref
= InterlockedDecrement(&This
->ref
);
1538 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
1544 HeapFree(GetProcessHeap(), 0, This
->pdata
);
1545 HeapFree(GetProcessHeap(), 0, This
->pstrings
);
1547 HeapFree(GetProcessHeap(), 0, This
);
1553 /*** IDirectXFileObject methods ***/
1554 static HRESULT WINAPI
IDirectXFileDataImpl_GetName(IDirectXFileData
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
1557 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1559 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
1562 return DXFILEERR_BADVALUE
;
1564 strcpy(pstrNameBuf
, This
->pobj
->name
);
1569 static HRESULT WINAPI
IDirectXFileDataImpl_GetId(IDirectXFileData
* iface
, LPGUID pGuid
)
1571 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1573 TRACE("(%p/%p)->(%p)\n", This
, iface
, pGuid
);
1576 return DXFILEERR_BADVALUE
;
1578 memcpy(pGuid
, &This
->pobj
->class_id
, 16);
1583 /*** IDirectXFileData methods ***/
1584 static HRESULT WINAPI
IDirectXFileDataImpl_GetData(IDirectXFileData
* iface
, LPCSTR szMember
, DWORD
* pcbSize
, void** ppvData
)
1586 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1588 TRACE("(%p/%p)->(%s,%p,%p)\n", This
, iface
, szMember
, pcbSize
, ppvData
);
1590 if (!pcbSize
|| !ppvData
)
1591 return DXFILEERR_BADVALUE
;
1595 FIXME("Specifying a member is not supported yet!\n");
1596 return DXFILEERR_BADVALUE
;
1599 *pcbSize
= This
->pobj
->size
;
1600 *ppvData
= This
->pobj
->pdata
;
1605 static HRESULT WINAPI
IDirectXFileDataImpl_GetType(IDirectXFileData
* iface
, const GUID
** pguid
)
1607 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1610 TRACE("(%p/%p)->(%p)\n", This
, iface
, pguid
);
1613 return DXFILEERR_BADVALUE
;
1615 memcpy(&guid
, &This
->pobj
->type
, 16);
1621 static HRESULT WINAPI
IDirectXFileDataImpl_GetNextObject(IDirectXFileData
* iface
, LPDIRECTXFILEOBJECT
* ppChildObj
)
1624 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1626 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppChildObj
);
1628 if (This
->cur_enum_object
>= This
->pobj
->nb_childs
)
1629 return DXFILEERR_NOMOREOBJECTS
;
1631 if (This
->from_ref
&& (This
->level
>= 1))
1633 /* Only 2 levels can enumerated if the object is obtained from a reference */
1634 return DXFILEERR_NOMOREOBJECTS
;
1637 if (This
->pobj
->childs
[This
->cur_enum_object
]->binary
)
1639 IDirectXFileBinaryImpl
*object
;
1641 hr
= IDirectXFileBinaryImpl_Create(&object
);
1645 *ppChildObj
= (LPDIRECTXFILEOBJECT
)object
;
1647 else if (This
->pobj
->childs
[This
->cur_enum_object
]->ptarget
)
1649 IDirectXFileDataReferenceImpl
*object
;
1651 hr
= IDirectXFileDataReferenceImpl_Create(&object
);
1655 object
->ptarget
= This
->pobj
->childs
[This
->cur_enum_object
++]->ptarget
;
1657 *ppChildObj
= (LPDIRECTXFILEOBJECT
)object
;
1661 IDirectXFileDataImpl
*object
;
1663 hr
= IDirectXFileDataImpl_Create(&object
);
1667 object
->pobj
= This
->pobj
->childs
[This
->cur_enum_object
++];
1668 object
->cur_enum_object
= 0;
1669 object
->from_ref
= This
->from_ref
;
1670 object
->level
= This
->level
+ 1;
1672 *ppChildObj
= (LPDIRECTXFILEOBJECT
)object
;
1678 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataObject(IDirectXFileData
* iface
, LPDIRECTXFILEDATA pDataObj
)
1680 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1682 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pDataObj
);
1684 return DXFILEERR_BADVALUE
;
1687 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataReference(IDirectXFileData
* iface
, LPCSTR szRef
, const GUID
* pguidRef
)
1689 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1691 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szRef
, pguidRef
);
1693 return DXFILEERR_BADVALUE
;
1696 static HRESULT WINAPI
IDirectXFileDataImpl_AddBinaryObject(IDirectXFileData
* iface
, LPCSTR szName
, const GUID
* pguid
, LPCSTR szMimeType
, LPVOID pvData
, DWORD cbSize
)
1698 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1700 FIXME("(%p/%p)->(%s,%p,%s,%p,%d) stub!\n", This
, iface
, szName
, pguid
, szMimeType
, pvData
, cbSize
);
1702 return DXFILEERR_BADVALUE
;
1705 static const IDirectXFileDataVtbl IDirectXFileData_Vtbl
=
1707 IDirectXFileDataImpl_QueryInterface
,
1708 IDirectXFileDataImpl_AddRef
,
1709 IDirectXFileDataImpl_Release
,
1710 IDirectXFileDataImpl_GetName
,
1711 IDirectXFileDataImpl_GetId
,
1712 IDirectXFileDataImpl_GetData
,
1713 IDirectXFileDataImpl_GetType
,
1714 IDirectXFileDataImpl_GetNextObject
,
1715 IDirectXFileDataImpl_AddDataObject
,
1716 IDirectXFileDataImpl_AddDataReference
,
1717 IDirectXFileDataImpl_AddBinaryObject
1720 static HRESULT
IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl
** ppObj
)
1722 IDirectXFileDataReferenceImpl
* object
;
1724 TRACE("(%p)\n", ppObj
);
1726 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataReferenceImpl
));
1729 ERR("Out of memory\n");
1730 return DXFILEERR_BADALLOC
;
1733 object
->lpVtbl
.lpVtbl
= &IDirectXFileDataReference_Vtbl
;
1741 /*** IUnknown methods ***/
1742 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_QueryInterface(IDirectXFileDataReference
* iface
, REFIID riid
, void** ppvObject
)
1744 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
1746 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1748 if (IsEqualGUID(riid
, &IID_IUnknown
)
1749 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
1750 || IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
1752 IClassFactory_AddRef(iface
);
1757 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
1758 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
)
1759 && !IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
1760 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1762 return E_NOINTERFACE
;
1765 static ULONG WINAPI
IDirectXFileDataReferenceImpl_AddRef(IDirectXFileDataReference
* iface
)
1767 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
1768 ULONG ref
= InterlockedIncrement(&This
->ref
);
1770 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
1775 static ULONG WINAPI
IDirectXFileDataReferenceImpl_Release(IDirectXFileDataReference
* iface
)
1777 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
1778 ULONG ref
= InterlockedDecrement(&This
->ref
);
1780 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
1783 HeapFree(GetProcessHeap(), 0, This
);
1788 /*** IDirectXFileObject methods ***/
1789 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetName(IDirectXFileDataReference
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
1791 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
1793 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
1796 return DXFILEERR_BADVALUE
;
1798 strcpy(pstrNameBuf
, This
->ptarget
->name
);
1800 return DXFILEERR_BADVALUE
;
1803 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetId(IDirectXFileDataReference
* iface
, LPGUID pGuid
)
1805 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
1807 TRACE("(%p/%p)->(%p)\n", This
, iface
, pGuid
);
1810 return DXFILEERR_BADVALUE
;
1812 memcpy(pGuid
, &This
->ptarget
->class_id
, 16);
1817 /*** IDirectXFileDataReference ***/
1818 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
1820 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
1821 IDirectXFileDataImpl
*object
;
1824 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
1827 return DXFILEERR_BADVALUE
;
1829 hr
= IDirectXFileDataImpl_Create(&object
);
1833 object
->pobj
= This
->ptarget
;
1834 object
->cur_enum_object
= 0;
1836 object
->from_ref
= TRUE
;
1838 *ppDataObj
= (LPDIRECTXFILEDATA
)object
;
1843 static const IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl
=
1845 IDirectXFileDataReferenceImpl_QueryInterface
,
1846 IDirectXFileDataReferenceImpl_AddRef
,
1847 IDirectXFileDataReferenceImpl_Release
,
1848 IDirectXFileDataReferenceImpl_GetName
,
1849 IDirectXFileDataReferenceImpl_GetId
,
1850 IDirectXFileDataReferenceImpl_Resolve
1853 static HRESULT
IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl
** ppObj
)
1855 IDirectXFileEnumObjectImpl
* object
;
1857 TRACE("(%p)\n", ppObj
);
1859 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileEnumObjectImpl
));
1862 ERR("Out of memory\n");
1863 return DXFILEERR_BADALLOC
;
1866 object
->lpVtbl
.lpVtbl
= &IDirectXFileEnumObject_Vtbl
;
1874 /*** IUnknown methods ***/
1875 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_QueryInterface(IDirectXFileEnumObject
* iface
, REFIID riid
, void** ppvObject
)
1877 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1879 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1881 if (IsEqualGUID(riid
, &IID_IUnknown
)
1882 || IsEqualGUID(riid
, &IID_IDirectXFileEnumObject
))
1884 IClassFactory_AddRef(iface
);
1889 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1890 return E_NOINTERFACE
;
1893 static ULONG WINAPI
IDirectXFileEnumObjectImpl_AddRef(IDirectXFileEnumObject
* iface
)
1895 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1896 ULONG ref
= InterlockedIncrement(&This
->ref
);
1898 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
1903 static ULONG WINAPI
IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject
* iface
)
1905 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1906 ULONG ref
= InterlockedDecrement(&This
->ref
);
1908 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
1913 for (i
= 0; i
< This
->nb_xobjects
; i
++)
1914 IDirectXFileData_Release(This
->pRefObjects
[i
]);
1915 if (This
->source
== DXFILELOAD_FROMFILE
)
1916 HeapFree(GetProcessHeap(), 0, This
->buf
.buffer
);
1917 if (This
->hFile
!= INVALID_HANDLE_VALUE
)
1918 CloseHandle(This
->hFile
);
1919 HeapFree(GetProcessHeap(), 0, This
);
1925 static BOOL
parse_object_members_list(parse_buffer
* buf
)
1929 xtemplate
* pt
= buf
->pxt
[buf
->level
];
1930 DWORD last_dword
= 0;
1932 for (i
= 0; i
< pt
->nb_members
; i
++)
1937 buf
->pxo
->members
[i
].start
= buf
->cur_pdata
;
1939 for (k
= 0; k
< pt
->members
[i
].nb_dims
; k
++)
1941 if (pt
->members
[i
].dim_fixed
[k
])
1942 nb_elems
*= pt
->members
[i
].dim_value
[k
];
1944 nb_elems
*= *(DWORD
*)buf
->pxo
->members
[pt
->members
[i
].dim_value
[k
]].start
;
1947 TRACE("Elements to consider: %d\n", nb_elems
);
1949 for (k
= 0; k
< nb_elems
; k
++)
1953 token
= check_TOKEN(buf
);
1954 if (token
== TOKEN_COMMA
)
1960 /* Allow comma omission */
1961 if (!((token
== TOKEN_FLOAT
) || (token
== TOKEN_INTEGER
)))
1966 if (pt
->members
[i
].type
== TOKEN_NAME
)
1970 TRACE("Found sub-object %s\n", buf
->pdxf
->xtemplates
[pt
->members
[i
].idx_template
].name
);
1972 /* To do template lookup */
1973 for (j
= 0; j
< buf
->pdxf
->nb_xtemplates
; j
++)
1975 if (!strcmp(buf
->pdxf
->xtemplates
[pt
->members
[i
].idx_template
].name
, buf
->pdxf
->xtemplates
[j
].name
))
1977 buf
->pxt
[buf
->level
] = &buf
->pdxf
->xtemplates
[j
];
1981 if (j
== buf
->pdxf
->nb_xtemplates
)
1983 FIXME("Unknown template %s\n", (char*)buf
->value
);
1987 TRACE("Enter %s\n", buf
->pdxf
->xtemplates
[pt
->members
[i
].idx_template
].name
);
1988 if (!parse_object_parts(buf
, FALSE
))
1997 token
= check_TOKEN(buf
);
1998 if (token
== TOKEN_INTEGER
)
2001 last_dword
= *(DWORD
*)buf
->value
;
2002 TRACE("%s = %d\n", pt
->members
[i
].name
, *(DWORD
*)buf
->value
);
2003 /* Assume larger size */
2004 if ((buf
->cur_pdata
- buf
->pdata
+ 4) > MAX_DATA_SIZE
)
2006 FIXME("Buffer too small\n");
2009 if (pt
->members
[i
].type
== TOKEN_WORD
)
2011 *(((WORD
*)(buf
->cur_pdata
))) = (WORD
)(*(DWORD
*)buf
->value
);
2012 buf
->cur_pdata
+= 2;
2014 else if (pt
->members
[i
].type
== TOKEN_DWORD
)
2016 *(((DWORD
*)(buf
->cur_pdata
))) = (DWORD
)(*(DWORD
*)buf
->value
);
2017 buf
->cur_pdata
+= 4;
2021 FIXME("Token %d not supported\n", pt
->members
[i
].type
);
2025 else if (token
== TOKEN_FLOAT
)
2028 TRACE("%s = %f\n", pt
->members
[i
].name
, *(float*)buf
->value
);
2029 /* Assume larger size */
2030 if ((buf
->cur_pdata
- buf
->pdata
+ 4) > MAX_DATA_SIZE
)
2032 FIXME("Buffer too small\n");
2035 if (pt
->members
[i
].type
== TOKEN_FLOAT
)
2037 *(((float*)(buf
->cur_pdata
))) = (float)(*(float*)buf
->value
);
2038 buf
->cur_pdata
+= 4;
2042 FIXME("Token %d not supported\n", pt
->members
[i
].type
);
2046 else if (token
== TOKEN_LPSTR
)
2049 TRACE("%s = %s\n", pt
->members
[i
].name
, (char*)buf
->value
);
2050 /* Assume larger size */
2051 if ((buf
->cur_pdata
- buf
->pdata
+ 4) > MAX_DATA_SIZE
)
2053 FIXME("Buffer too small\n");
2056 if (pt
->members
[i
].type
== TOKEN_LPSTR
)
2058 int len
= strlen((char*)buf
->value
) + 1;
2059 if ((buf
->cur_pstrings
- buf
->pstrings
+ len
) > MAX_STRINGS_BUFFER
)
2061 FIXME("Buffer too small %p %p %d\n", buf
->cur_pstrings
, buf
->pstrings
, len
);
2064 strcpy((char*)buf
->cur_pstrings
, (char*)buf
->value
);
2065 *(((LPCSTR
*)(buf
->cur_pdata
))) = (char*)buf
->cur_pstrings
;
2066 buf
->cur_pstrings
+= len
;
2067 buf
->cur_pdata
+= 4;
2071 FIXME("Token %d not supported\n", pt
->members
[i
].type
);
2077 FIXME("Unexpected token %d\n", token
);
2083 if (buf
->txt
&& (check_TOKEN(buf
) != TOKEN_CBRACE
))
2085 token
= get_TOKEN(buf
);
2086 if ((token
!= TOKEN_SEMICOLON
) && (token
!= TOKEN_COMMA
))
2088 /* Allow comma instead of semicolon in some specific cases */
2089 if (!((token
== TOKEN_COMMA
) && ((i
+1) < pt
->nb_members
) && (pt
->members
[i
].type
== pt
->members
[i
+1].type
)
2090 && (!pt
->members
[i
].nb_dims
) && (!pt
->members
[i
+1].nb_dims
)))
2099 static BOOL
parse_object_parts(parse_buffer
* buf
, BOOL allow_optional
)
2101 if (!parse_object_members_list(buf
))
2106 buf
->pxo
->size
= buf
->cur_pdata
- buf
->pxo
->pdata
;
2108 /* Skip trailing semicolon */
2109 while (check_TOKEN(buf
) == TOKEN_SEMICOLON
)
2114 if (check_TOKEN(buf
) == TOKEN_OBRACE
)
2118 if (get_TOKEN(buf
) != TOKEN_NAME
)
2120 if (get_TOKEN(buf
) != TOKEN_CBRACE
)
2122 TRACE("Found optional reference %s\n", (char*)buf
->value
);
2123 for (i
= 0; i
< buf
->nb_pxo_globals
; i
++)
2125 for (j
= 0; j
< (buf
->pxo_globals
[i
])[0].nb_subobjects
; j
++)
2127 if (!strcmp((buf
->pxo_globals
[i
])[j
].name
, (char*)buf
->value
))
2132 if (i
== buf
->nb_pxo_globals
)
2134 ERR("Reference to unknown object %s\n", (char*)buf
->value
);
2137 buf
->pxo
->childs
[buf
->pxo
->nb_childs
] = &buf
->pxo_tab
[buf
->cur_subobject
++];
2138 buf
->pxo
->childs
[buf
->pxo
->nb_childs
]->ptarget
= &(buf
->pxo_globals
[i
])[j
];
2139 buf
->pxo
->nb_childs
++;
2141 else if (check_TOKEN(buf
) == TOKEN_NAME
)
2143 xobject
* pxo
= buf
->pxo
;
2144 buf
->pxo
= buf
->pxo
->childs
[buf
->pxo
->nb_childs
] = &buf
->pxo_tab
[buf
->cur_subobject
++];
2146 TRACE("Enter optional %s\n", (char*)buf
->value
);
2148 if (!parse_object(buf
))
2155 buf
->pxo
->nb_childs
++;
2162 if (buf
->pxo
->nb_childs
> MAX_CHILDS
)
2164 FIXME("Too many childs %d\n", buf
->pxo
->nb_childs
);
2171 static BOOL
parse_object(parse_buffer
* buf
)
2175 buf
->pxo
->pdata
= buf
->cur_pdata
;
2176 buf
->pxo
->ptarget
= NULL
;
2178 if (get_TOKEN(buf
) != TOKEN_NAME
)
2181 /* To do template lookup */
2182 for (i
= 0; i
< buf
->pdxf
->nb_xtemplates
; i
++)
2184 if (!strcmp((char*)buf
->value
, buf
->pdxf
->xtemplates
[i
].name
))
2186 buf
->pxt
[buf
->level
] = &buf
->pdxf
->xtemplates
[i
];
2187 memcpy(&buf
->pxo
->type
, &buf
->pdxf
->xtemplates
[i
].class_id
, 16);
2191 if (i
== buf
->pdxf
->nb_xtemplates
)
2193 FIXME("Unknown template %s\n", (char*)buf
->value
);
2197 if (check_TOKEN(buf
) == TOKEN_NAME
)
2200 strcpy(buf
->pxo
->name
, (char*)buf
->value
);
2203 buf
->pxo
->name
[0] = 0;
2205 if (get_TOKEN(buf
) != TOKEN_OBRACE
)
2207 if (check_TOKEN(buf
) == TOKEN_GUID
)
2210 memcpy(&buf
->pxo
->class_id
, buf
->value
, 16);
2213 memset(&buf
->pxo
->class_id
, 0, 16);
2215 if (!parse_object_parts(buf
, TRUE
))
2217 if (get_TOKEN(buf
) != TOKEN_CBRACE
)
2222 /* Go to the next object */
2223 go_to_next_definition(buf
);
2229 /*** IDirectXFileEnumObject methods ***/
2230 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
2232 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
2233 IDirectXFileDataImpl
* object
;
2235 LPBYTE pdata
= NULL
;
2236 LPBYTE pstrings
= NULL
;
2238 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
2240 if (This
->nb_xobjects
>= MAX_OBJECTS
)
2242 ERR("Too many objects\n");
2243 return DXFILEERR_NOMOREOBJECTS
;
2246 if (!This
->buf
.rem_bytes
)
2247 return DXFILEERR_NOMOREOBJECTS
;
2249 hr
= IDirectXFileDataImpl_Create(&object
);
2253 This
->buf
.pxo_globals
= This
->xobjects
;
2254 This
->buf
.nb_pxo_globals
= This
->nb_xobjects
;
2255 This
->buf
.cur_subobject
= 1;
2256 This
->buf
.level
= 0;
2258 This
->buf
.pxo_tab
= HeapAlloc(GetProcessHeap(), 0, sizeof(xobject
)*MAX_SUBOBJECTS
);
2259 if (!This
->buf
.pxo_tab
)
2261 ERR("Out of memory\n");
2262 hr
= DXFILEERR_BADALLOC
;
2265 This
->buf
.pxo
= This
->xobjects
[This
->nb_xobjects
] = This
->buf
.pxo_tab
;
2267 pdata
= HeapAlloc(GetProcessHeap(), 0, MAX_DATA_SIZE
);
2270 ERR("Out of memory\n");
2271 hr
= DXFILEERR_BADALLOC
;
2274 This
->buf
.cur_pdata
= This
->buf
.pdata
= object
->pdata
= pdata
;
2276 pstrings
= HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER
);
2279 ERR("Out of memory\n");
2280 hr
= DXFILEERR_BADALLOC
;
2283 This
->buf
.cur_pstrings
= This
->buf
.pstrings
= object
->pstrings
= pstrings
;
2285 if (!parse_object(&This
->buf
))
2287 TRACE("Object is not correct\n");
2288 hr
= DXFILEERR_PARSEERROR
;
2292 This
->buf
.pxo
->nb_subobjects
= This
->buf
.cur_subobject
;
2293 if (This
->buf
.cur_subobject
> MAX_SUBOBJECTS
)
2295 FIXME("Too many suobjects %d\n", This
->buf
.cur_subobject
);
2296 hr
= DXFILEERR_BADALLOC
;
2300 object
->pstrings
= pstrings
;
2301 object
->pobj
= This
->buf
.pxo
;
2302 object
->cur_enum_object
= 0;
2304 object
->from_ref
= FALSE
;
2306 *ppDataObj
= (LPDIRECTXFILEDATA
)object
;
2308 /* Get a reference to created object */
2309 This
->pRefObjects
[This
->nb_xobjects
] = (LPDIRECTXFILEDATA
)object
;
2310 IDirectXFileData_AddRef(This
->pRefObjects
[This
->nb_xobjects
]);
2312 This
->nb_xobjects
++;
2318 HeapFree(GetProcessHeap(), 0, This
->buf
.pxo_tab
);
2319 HeapFree(GetProcessHeap(), 0, pdata
);
2320 HeapFree(GetProcessHeap(), 0, pstrings
);
2325 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectById(IDirectXFileEnumObject
* iface
, REFGUID rguid
, LPDIRECTXFILEDATA
* ppDataObj
)
2327 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
2329 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, rguid
, ppDataObj
);
2331 return DXFILEERR_BADVALUE
;
2334 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectByName(IDirectXFileEnumObject
* iface
, LPCSTR szName
, LPDIRECTXFILEDATA
* ppDataObj
)
2336 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
2338 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szName
, ppDataObj
);
2340 return DXFILEERR_BADVALUE
;
2343 static const IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl
=
2345 IDirectXFileEnumObjectImpl_QueryInterface
,
2346 IDirectXFileEnumObjectImpl_AddRef
,
2347 IDirectXFileEnumObjectImpl_Release
,
2348 IDirectXFileEnumObjectImpl_GetNextDataObject
,
2349 IDirectXFileEnumObjectImpl_GetDataObjectById
,
2350 IDirectXFileEnumObjectImpl_GetDataObjectByName
2353 static HRESULT
IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl
** ppObj
)
2355 IDirectXFileSaveObjectImpl
* object
;
2357 TRACE("(%p)\n", ppObj
);
2359 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileSaveObjectImpl
));
2362 ERR("Out of memory\n");
2363 return DXFILEERR_BADALLOC
;
2366 object
->lpVtbl
.lpVtbl
= &IDirectXFileSaveObject_Vtbl
;
2374 /*** IUnknown methods ***/
2375 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_QueryInterface(IDirectXFileSaveObject
* iface
, REFIID riid
, void** ppvObject
)
2377 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
2379 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
2381 if (IsEqualGUID(riid
, &IID_IUnknown
)
2382 || IsEqualGUID(riid
, &IID_IDirectXFileSaveObject
))
2384 IClassFactory_AddRef(iface
);
2389 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
2390 return E_NOINTERFACE
;
2393 static ULONG WINAPI
IDirectXFileSaveObjectImpl_AddRef(IDirectXFileSaveObject
* iface
)
2395 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
2396 ULONG ref
= InterlockedIncrement(&This
->ref
);
2398 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
2403 static ULONG WINAPI
IDirectXFileSaveObjectImpl_Release(IDirectXFileSaveObject
* iface
)
2405 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
2406 ULONG ref
= InterlockedDecrement(&This
->ref
);
2408 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
2411 HeapFree(GetProcessHeap(), 0, This
);
2416 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveTemplates(IDirectXFileSaveObject
* iface
, DWORD cTemplates
, const GUID
** ppguidTemplates
)
2418 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
2420 FIXME("(%p/%p)->(%d,%p) stub!\n", This
, iface
, cTemplates
, ppguidTemplates
);
2422 return DXFILEERR_BADVALUE
;
2425 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_CreateDataObject(IDirectXFileSaveObject
* iface
, REFGUID rguidTemplate
, LPCSTR szName
, const GUID
* pguid
, DWORD cbSize
, LPVOID pvData
, LPDIRECTXFILEDATA
* ppDataObj
)
2427 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
2429 FIXME("(%p/%p)->(%p,%s,%p,%d,%p,%p) stub!\n", This
, iface
, rguidTemplate
, szName
, pguid
, cbSize
, pvData
, ppDataObj
);
2431 return DXFILEERR_BADVALUE
;
2434 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveData(IDirectXFileSaveObject
* iface
, LPDIRECTXFILEDATA ppDataObj
)
2436 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
2438 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, ppDataObj
);
2440 return DXFILEERR_BADVALUE
;
2443 static const IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl
=
2445 IDirectXFileSaveObjectImpl_QueryInterface
,
2446 IDirectXFileSaveObjectImpl_AddRef
,
2447 IDirectXFileSaveObjectImpl_Release
,
2448 IDirectXFileSaveObjectImpl_SaveTemplates
,
2449 IDirectXFileSaveObjectImpl_CreateDataObject
,
2450 IDirectXFileSaveObjectImpl_SaveData