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 1000000
84 #define MAX_DATA_SIZE 100000
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
);
100 static void dump_template(xtemplate
* templates_array
, xtemplate
* ptemplate
)
105 clsid
= &ptemplate
->class_id
;
107 DPRINTF("template %s\n", ptemplate
->name
);
109 DPRINTF(CLSIDFMT
"\n", clsid
->Data1
, clsid
->Data2
, clsid
->Data3
, clsid
->Data4
[0],
110 clsid
->Data4
[1], clsid
->Data4
[2], clsid
->Data4
[3], clsid
->Data4
[4], clsid
->Data4
[5], clsid
->Data4
[6], clsid
->Data4
[7]);
111 for (j
= 0; j
< ptemplate
->nb_members
; j
++)
113 if (ptemplate
->members
[j
].nb_dims
)
115 if (ptemplate
->members
[j
].type
== TOKEN_NAME
)
116 DPRINTF("%s ", templates_array
[ptemplate
->members
[j
].idx_template
].name
);
118 DPRINTF("%s ", get_primitive_string(ptemplate
->members
[j
].type
));
119 DPRINTF("%s", ptemplate
->members
[j
].name
);
120 for (k
= 0; k
< ptemplate
->members
[j
].nb_dims
; k
++)
122 if (ptemplate
->members
[j
].dim_fixed
[k
])
123 DPRINTF("[%d]", ptemplate
->members
[j
].dim_value
[k
]);
125 DPRINTF("[%s]", ptemplate
->members
[ptemplate
->members
[j
].dim_value
[k
]].name
);
131 else if (ptemplate
->nb_childs
)
133 DPRINTF("[%s", ptemplate
->childs
[0]);
134 for (j
= 1; j
< ptemplate
->nb_childs
; j
++)
135 DPRINTF(",%s", ptemplate
->childs
[j
]);
141 HRESULT
IDirectXFileImpl_Create(IUnknown
* pUnkOuter
, LPVOID
* ppObj
)
143 IDirectXFileImpl
* object
;
145 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
147 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileImpl
));
149 object
->lpVtbl
.lpVtbl
= &IDirectXFile_Vtbl
;
157 /*** IUnknown methods ***/
158 static HRESULT WINAPI
IDirectXFileImpl_QueryInterface(IDirectXFile
* iface
, REFIID riid
, void** ppvObject
)
160 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
162 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
164 if (IsEqualGUID(riid
, &IID_IUnknown
)
165 || IsEqualGUID(riid
, &IID_IDirectXFile
))
167 IClassFactory_AddRef(iface
);
172 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
173 return E_NOINTERFACE
;
176 static ULONG WINAPI
IDirectXFileImpl_AddRef(IDirectXFile
* iface
)
178 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
179 ULONG ref
= InterlockedIncrement(&This
->ref
);
181 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
186 static ULONG WINAPI
IDirectXFileImpl_Release(IDirectXFile
* iface
)
188 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
189 ULONG ref
= InterlockedDecrement(&This
->ref
);
191 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
194 HeapFree(GetProcessHeap(), 0, This
);
199 /*** IDirectXFile methods ***/
200 static HRESULT WINAPI
IDirectXFileImpl_CreateEnumObject(IDirectXFile
* iface
, LPVOID pvSource
, DXFILELOADOPTIONS dwLoadOptions
, LPDIRECTXFILEENUMOBJECT
* ppEnumObj
)
202 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
203 IDirectXFileEnumObjectImpl
* object
;
207 HANDLE hFile
= INVALID_HANDLE_VALUE
;
208 LPDXFILELOADMEMORY lpdxflm
= NULL
;
210 TRACE("(%p/%p)->(%p,%x,%p)\n", This
, iface
, pvSource
, dwLoadOptions
, ppEnumObj
);
213 return DXFILEERR_BADVALUE
;
215 if (dwLoadOptions
== DXFILELOAD_FROMFILE
)
217 TRACE("Open source file '%s'\n", (char*)pvSource
);
219 hFile
= CreateFileA((char*)pvSource
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
220 if (hFile
== INVALID_HANDLE_VALUE
)
222 TRACE("File '%s' not found\n", (char*)pvSource
);
223 return DXFILEERR_FILENOTFOUND
;
226 if (!ReadFile(hFile
, header
, 16, &size
, NULL
))
228 hr
= DXFILEERR_BADVALUE
;
234 hr
= DXFILEERR_BADFILETYPE
;
238 else if (dwLoadOptions
== DXFILELOAD_FROMMEMORY
)
240 lpdxflm
= (LPDXFILELOADMEMORY
)pvSource
;
242 FIXME("Source in memory at %p with size %d\n", lpdxflm
->lpMemory
, lpdxflm
->dSize
);
244 memcpy(header
, (char*)lpdxflm
->lpMemory
, 16);
248 FIXME("Source type %d is not handled yet\n", dwLoadOptions
);
249 hr
= DXFILEERR_NOTDONEYET
;
253 if (TRACE_ON(d3dxof
))
256 memcpy(string
, header
, 16);
258 TRACE("header = '%s'\n", string
);
261 if (header
[0] != XOFFILE_FORMAT_MAGIC
)
263 hr
= DXFILEERR_BADFILETYPE
;
267 if ((header
[1] != XOFFILE_FORMAT_VERSION_302
) && (header
[1] != XOFFILE_FORMAT_VERSION_303
))
269 hr
= DXFILEERR_BADFILEVERSION
;
273 if ((header
[2] != XOFFILE_FORMAT_BINARY
) && (header
[2] != XOFFILE_FORMAT_TEXT
) && (header
[2] != XOFFILE_FORMAT_COMPRESSED
))
275 hr
= DXFILEERR_BADFILETYPE
;
279 if (header
[2] == XOFFILE_FORMAT_BINARY
)
281 FIXME("Binary format not supported yet\n");
282 hr
= DXFILEERR_NOTDONEYET
;
286 if (header
[2] == XOFFILE_FORMAT_COMPRESSED
)
288 FIXME("Compressed formats not supported yet\n");
289 hr
= DXFILEERR_BADVALUE
;
293 if ((header
[3] != XOFFILE_FORMAT_FLOAT_BITS_32
) && (header
[3] != XOFFILE_FORMAT_FLOAT_BITS_64
))
295 hr
= DXFILEERR_BADFILEFLOATSIZE
;
299 TRACE("Header is correct\n");
301 hr
= IDirectXFileEnumObjectImpl_Create(&object
);
305 object
->source
= dwLoadOptions
;
306 object
->hFile
= hFile
;
307 object
->pDirectXFile
= This
;
308 object
->buf
.pdxf
= This
;
309 object
->buf
.txt
= (header
[2] == XOFFILE_FORMAT_TEXT
);
310 object
->buf
.token_present
= FALSE
;
311 object
->buf
.cur_subobject
= 0;
313 if (dwLoadOptions
== DXFILELOAD_FROMFILE
)
315 object
->buf
.buffer
= HeapAlloc(GetProcessHeap(), 0, MAX_INPUT_SIZE
+1);
316 if (!object
->buf
.buffer
)
318 WARN("Out of memory\n");
319 hr
= DXFILEERR_BADALLOC
;
323 ReadFile(hFile
, object
->buf
.buffer
, MAX_INPUT_SIZE
+1, &object
->buf
.rem_bytes
, NULL
);
324 if (object
->buf
.rem_bytes
> MAX_INPUT_SIZE
)
326 FIXME("File size > %d not supported yet\n", MAX_INPUT_SIZE
);
327 HeapFree(GetProcessHeap(), 0, object
->buf
.buffer
);
328 hr
= DXFILEERR_PARSEERROR
;
334 object
->buf
.buffer
= ((LPBYTE
)lpdxflm
->lpMemory
) + 16;
335 object
->buf
.rem_bytes
= lpdxflm
->dSize
;
338 TRACE("Read %d bytes\n", object
->buf
.rem_bytes
);
340 *ppEnumObj
= (LPDIRECTXFILEENUMOBJECT
)object
;
342 while (object
->buf
.rem_bytes
&& (check_TOKEN(&object
->buf
) == TOKEN_TEMPLATE
))
344 if (!parse_template(&object
->buf
))
346 TRACE("Template is not correct\n");
347 hr
= DXFILEERR_BADVALUE
;
352 TRACE("Template successfully parsed:\n");
353 if (TRACE_ON(d3dxof
))
354 dump_template(This
->xtemplates
, &This
->xtemplates
[This
->nb_xtemplates
- 1]);
358 if (TRACE_ON(d3dxof
))
361 TRACE("Registered templates (%d):\n", This
->nb_xtemplates
);
362 for (i
= 0; i
< This
->nb_xtemplates
; i
++)
363 DPRINTF("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
369 if (hFile
!= INVALID_HANDLE_VALUE
)
376 static HRESULT WINAPI
IDirectXFileImpl_CreateSaveObject(IDirectXFile
* iface
, LPCSTR szFileName
, DXFILEFORMAT dwFileFormat
, LPDIRECTXFILESAVEOBJECT
* ppSaveObj
)
378 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
380 FIXME("(%p/%p)->(%s,%x,%p) stub!\n", This
, iface
, szFileName
, dwFileFormat
, ppSaveObj
);
382 return DXFILEERR_BADVALUE
;
385 static BOOL
read_bytes(parse_buffer
* buf
, LPVOID data
, DWORD size
)
387 if (buf
->rem_bytes
< size
)
389 memcpy(data
, buf
->buffer
, size
);
391 buf
->rem_bytes
-= size
;
395 static void dump_TOKEN(WORD token
)
397 #define DUMP_TOKEN(t) case t: TRACE(#t "\n"); break
400 DUMP_TOKEN(TOKEN_NAME
);
401 DUMP_TOKEN(TOKEN_STRING
);
402 DUMP_TOKEN(TOKEN_INTEGER
);
403 DUMP_TOKEN(TOKEN_GUID
);
404 DUMP_TOKEN(TOKEN_INTEGER_LIST
);
405 DUMP_TOKEN(TOKEN_FLOAT_LIST
);
406 DUMP_TOKEN(TOKEN_OBRACE
);
407 DUMP_TOKEN(TOKEN_CBRACE
);
408 DUMP_TOKEN(TOKEN_OPAREN
);
409 DUMP_TOKEN(TOKEN_CPAREN
);
410 DUMP_TOKEN(TOKEN_OBRACKET
);
411 DUMP_TOKEN(TOKEN_CBRACKET
);
412 DUMP_TOKEN(TOKEN_OANGLE
);
413 DUMP_TOKEN(TOKEN_CANGLE
);
414 DUMP_TOKEN(TOKEN_DOT
);
415 DUMP_TOKEN(TOKEN_COMMA
);
416 DUMP_TOKEN(TOKEN_SEMICOLON
);
417 DUMP_TOKEN(TOKEN_TEMPLATE
);
418 DUMP_TOKEN(TOKEN_WORD
);
419 DUMP_TOKEN(TOKEN_DWORD
);
420 DUMP_TOKEN(TOKEN_FLOAT
);
421 DUMP_TOKEN(TOKEN_DOUBLE
);
422 DUMP_TOKEN(TOKEN_CHAR
);
423 DUMP_TOKEN(TOKEN_UCHAR
);
424 DUMP_TOKEN(TOKEN_SWORD
);
425 DUMP_TOKEN(TOKEN_SDWORD
);
426 DUMP_TOKEN(TOKEN_VOID
);
427 DUMP_TOKEN(TOKEN_LPSTR
);
428 DUMP_TOKEN(TOKEN_UNICODE
);
429 DUMP_TOKEN(TOKEN_CSTRING
);
430 DUMP_TOKEN(TOKEN_ARRAY
);
433 TRACE("Unknown token %d\n", token
);
439 static BOOL
is_space(char c
)
453 static BOOL
is_operator(char c
)
472 static inline BOOL
is_separator(char c
)
474 return is_space(c
) || is_operator(c
);
477 static WORD
get_operator_token(char c
)
486 return TOKEN_OBRACKET
;
488 return TOKEN_CBRACKET
;
500 return TOKEN_SEMICOLON
;
505 static BOOL
is_keyword(parse_buffer
* buf
, const char* keyword
)
507 DWORD len
= strlen(keyword
);
508 if (!strncmp((char*)buf
->buffer
, keyword
,len
) && is_separator(*(buf
->buffer
+len
)))
511 buf
->rem_bytes
-= len
;
517 static WORD
get_keyword_token(parse_buffer
* buf
)
519 if (is_keyword(buf
, "template"))
520 return TOKEN_TEMPLATE
;
521 if (is_keyword(buf
, "WORD"))
523 if (is_keyword(buf
, "DWORD"))
525 if (is_keyword(buf
, "FLOAT"))
527 if (is_keyword(buf
, "DOUBLE"))
529 if (is_keyword(buf
, "CHAR"))
531 if (is_keyword(buf
, "UCHAR"))
533 if (is_keyword(buf
, "SWORD"))
535 if (is_keyword(buf
, "SDWORD"))
537 if (is_keyword(buf
, "VOID"))
539 if (is_keyword(buf
, "STRING"))
541 if (is_keyword(buf
, "UNICODE"))
542 return TOKEN_UNICODE
;
543 if (is_keyword(buf
, "CSTRING"))
544 return TOKEN_CSTRING
;
545 if (is_keyword(buf
, "array"))
551 static BOOL
is_guid(parse_buffer
* buf
)
559 if (*buf
->buffer
!= '<')
562 while (*(buf
->buffer
+pos
) != '>')
564 tmp
[pos
] = *(buf
->buffer
+pos
);
569 if (pos
!= 38 /* <+36+> */)
571 TRACE("Wrong guid %s (%d)\n", tmp
, pos
);
575 buf
->rem_bytes
-= pos
;
577 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);
580 TRACE("Wrong guid %s (%d)\n", tmp
, pos
);
583 TRACE("Found guid %s (%d)\n", tmp
, pos
);
585 class_id
.Data2
= tab
[0];
586 class_id
.Data3
= tab
[1];
587 class_id
.Data4
[0] = tab
[2];
588 class_id
.Data4
[1] = tab
[3];
589 class_id
.Data4
[2] = tab
[4];
590 class_id
.Data4
[3] = tab
[5];
591 class_id
.Data4
[4] = tab
[6];
592 class_id
.Data4
[5] = tab
[7];
593 class_id
.Data4
[6] = tab
[8];
594 class_id
.Data4
[7] = tab
[9];
596 *(GUID
*)buf
->value
= class_id
;
601 static BOOL
is_name(parse_buffer
* buf
)
607 while (!is_separator(c
= *(buf
->buffer
+pos
)))
609 if (!(((c
>= 'a') && (c
<= 'z')) || ((c
>= 'A') && (c
<= 'Z')) || ((c
>= '0') && (c
<= '9')) || (c
== '_')))
617 TRACE("Wrong name %s\n", tmp
);
622 buf
->rem_bytes
-= pos
;
624 TRACE("Found name %s\n", tmp
);
625 strcpy((char*)buf
->value
, tmp
);
630 static BOOL
is_float(parse_buffer
* buf
)
638 while (!is_separator(c
= *(buf
->buffer
+pos
)))
640 if (!((!pos
&& (c
== '-')) || ((c
>= '0') && (c
<= '9')) || (!dot
&& (c
== '.'))))
649 buf
->rem_bytes
-= pos
;
651 sscanf(tmp
, "%f", &decimal
);
653 TRACE("Found float %s - %f\n", tmp
, decimal
);
655 *(float*)buf
->value
= decimal
;
660 static BOOL
is_integer(parse_buffer
* buf
)
667 while (!is_separator(c
= *(buf
->buffer
+pos
)))
669 if (!((c
>= '0') && (c
<= '9')))
676 buf
->rem_bytes
-= pos
;
678 sscanf(tmp
, "%d", &integer
);
680 TRACE("Found integer %s - %d\n", tmp
, integer
);
682 *(DWORD
*)buf
->value
= integer
;
687 static BOOL
is_string(parse_buffer
* buf
)
694 if (*buf
->buffer
!= '"')
697 while (!is_separator(c
= *(buf
->buffer
+pos
+1)) && (pos
< 31))
710 TRACE("Wrong string %s\n", tmp
);
714 buf
->buffer
+= pos
+ 2;
715 buf
->rem_bytes
-= pos
+ 2;
717 TRACE("Found string %s\n", tmp
);
718 strcpy((char*)buf
->value
, tmp
);
723 static WORD
parse_TOKEN(parse_buffer
* buf
)
732 if (!read_bytes(buf
, &c
, 1))
734 /*TRACE("char = '%c'\n", is_space(c) ? ' ' : c);*/
735 if ((c
== '#') || (c
== '/'))
737 /* Handle comment (# or //) */
740 if (!read_bytes(buf
, &c
, 1))
748 if (!read_bytes(buf
, &c
, 1))
755 if (is_operator(c
) && (c
!= '<'))
757 token
= get_operator_token(c
);
770 if ((token
= get_keyword_token(buf
)))
780 token
= TOKEN_INTEGER
;
799 FIXME("Unrecognize element\n");
806 if (!read_bytes(buf
, &token
, 2))
816 if (!read_bytes(buf
, &count
, 4))
818 if (!read_bytes(buf
, strname
, count
))
821 /*TRACE("name = %s\n", strname);*/
823 strcpy((char*)buf
->value
, strname
);
830 if (!read_bytes(buf
, &integer
, 4))
832 /*TRACE("integer = %ld\n", integer);*/
834 *(DWORD
*)buf
->value
= integer
;
842 if (!read_bytes(buf
, &class_id
, 16))
844 sprintf(strguid
, CLSIDFMT
, class_id
.Data1
, class_id
.Data2
, class_id
.Data3
, class_id
.Data4
[0],
845 class_id
.Data4
[1], class_id
.Data4
[2], class_id
.Data4
[3], class_id
.Data4
[4], class_id
.Data4
[5],
846 class_id
.Data4
[6], class_id
.Data4
[7]);
847 /*TRACE("guid = {%s}\n", strguid);*/
849 *(GUID
*)buf
->value
= class_id
;
853 case TOKEN_INTEGER_LIST
:
854 case TOKEN_FLOAT_LIST
:
865 case TOKEN_SEMICOLON
:
891 static const char* get_primitive_string(WORD token
)
925 static WORD
get_TOKEN(parse_buffer
* buf
)
927 if (buf
->token_present
)
929 buf
->token_present
= FALSE
;
930 return buf
->current_token
;
933 buf
->current_token
= parse_TOKEN(buf
);
935 return buf
->current_token
;
938 static WORD
check_TOKEN(parse_buffer
* buf
)
940 if (buf
->token_present
)
941 return buf
->current_token
;
943 buf
->current_token
= parse_TOKEN(buf
);
944 buf
->token_present
= TRUE
;
946 return buf
->current_token
;
949 static inline BOOL
is_primitive_type(WORD token
)
974 static BOOL
parse_template_option_info(parse_buffer
* buf
)
976 xtemplate
* cur_template
= &buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
];
978 if (check_TOKEN(buf
) == TOKEN_DOT
)
981 if (get_TOKEN(buf
) != TOKEN_DOT
)
983 if (get_TOKEN(buf
) != TOKEN_DOT
)
985 cur_template
->open
= TRUE
;
991 if (get_TOKEN(buf
) != TOKEN_NAME
)
993 strcpy(cur_template
->childs
[cur_template
->nb_childs
], (char*)buf
->value
);
994 if (check_TOKEN(buf
) == TOKEN_GUID
)
996 cur_template
->nb_childs
++;
997 if (check_TOKEN(buf
) != TOKEN_COMMA
)
1001 cur_template
->open
= FALSE
;
1007 static BOOL
parse_template_members_list(parse_buffer
* buf
)
1016 cur_member
= &buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].members
[idx_member
];
1018 if (check_TOKEN(buf
) == TOKEN_ARRAY
)
1024 if (check_TOKEN(buf
) == TOKEN_NAME
)
1026 cur_member
->type
= get_TOKEN(buf
);
1027 cur_member
->idx_template
= 0;
1028 while (cur_member
->idx_template
< buf
->pdxf
->nb_xtemplates
)
1030 if (!strcmp((char*)buf
->value
, buf
->pdxf
->xtemplates
[cur_member
->idx_template
].name
))
1032 cur_member
->idx_template
++;
1034 if (cur_member
->idx_template
== buf
->pdxf
->nb_xtemplates
)
1036 TRACE("Reference to a nonexistent template '%s'\n", (char*)buf
->value
);
1040 else if (is_primitive_type(check_TOKEN(buf
)))
1041 cur_member
->type
= get_TOKEN(buf
);
1045 if (get_TOKEN(buf
) != TOKEN_NAME
)
1047 strcpy(cur_member
->name
, (char*)buf
->value
);
1051 while (check_TOKEN(buf
) == TOKEN_OBRACKET
)
1055 FIXME("No support for multi-dimensional array yet\n");
1059 if (check_TOKEN(buf
) == TOKEN_INTEGER
)
1062 cur_member
->dim_fixed
[nb_dims
] = TRUE
;
1063 cur_member
->dim_value
[nb_dims
] = *(DWORD
*)buf
->value
;
1067 if (get_TOKEN(buf
) != TOKEN_NAME
)
1069 cur_member
->dim_fixed
[nb_dims
] = FALSE
;
1070 /* Hack: Assume array size is specified in previous member */
1071 cur_member
->dim_value
[nb_dims
] = idx_member
- 1;
1073 if (get_TOKEN(buf
) != TOKEN_CBRACKET
)
1079 cur_member
->nb_dims
= nb_dims
;
1081 if (get_TOKEN(buf
) != TOKEN_SEMICOLON
)
1087 buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].nb_members
= idx_member
;
1092 static BOOL
parse_template_parts(parse_buffer
* buf
)
1094 if (!parse_template_members_list(buf
))
1096 if (check_TOKEN(buf
) == TOKEN_OBRACKET
)
1099 if (!parse_template_option_info(buf
))
1101 if (get_TOKEN(buf
) != TOKEN_CBRACKET
)
1108 static BOOL
parse_template(parse_buffer
* buf
)
1110 if (get_TOKEN(buf
) != TOKEN_TEMPLATE
)
1112 if (get_TOKEN(buf
) != TOKEN_NAME
)
1114 strcpy(buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].name
, (char*)buf
->value
);
1115 if (get_TOKEN(buf
) != TOKEN_OBRACE
)
1117 if (get_TOKEN(buf
) != TOKEN_GUID
)
1119 buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].class_id
= *(GUID
*)buf
->value
;
1120 if (!parse_template_parts(buf
))
1122 if (get_TOKEN(buf
) != TOKEN_CBRACE
)
1126 /* Go to the next template */
1127 while (buf
->rem_bytes
&& is_space(*buf
->buffer
))
1134 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
));
1135 buf
->pdxf
->nb_xtemplates
++;
1140 static HRESULT WINAPI
IDirectXFileImpl_RegisterTemplates(IDirectXFile
* iface
, LPVOID pvData
, DWORD cbSize
)
1142 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
1146 buf
.buffer
= (LPBYTE
)pvData
;
1147 buf
.rem_bytes
= cbSize
;
1149 buf
.token_present
= FALSE
;
1152 TRACE("(%p/%p)->(%p,%d)\n", This
, iface
, pvData
, cbSize
);
1155 return DXFILEERR_BADVALUE
;
1158 return DXFILEERR_BADFILETYPE
;
1160 if (TRACE_ON(d3dxof
))
1163 memcpy(string
, pvData
, 16);
1165 TRACE("header = '%s'\n", string
);
1168 read_bytes(&buf
, &token_header
, 4);
1170 if (token_header
!= XOFFILE_FORMAT_MAGIC
)
1171 return DXFILEERR_BADFILETYPE
;
1173 read_bytes(&buf
, &token_header
, 4);
1175 if ((token_header
!= XOFFILE_FORMAT_VERSION_302
) && (token_header
!= XOFFILE_FORMAT_VERSION_303
))
1176 return DXFILEERR_BADFILEVERSION
;
1178 read_bytes(&buf
, &token_header
, 4);
1180 if ((token_header
!= XOFFILE_FORMAT_BINARY
) && (token_header
!= XOFFILE_FORMAT_TEXT
) && (token_header
!= XOFFILE_FORMAT_COMPRESSED
))
1181 return DXFILEERR_BADFILETYPE
;
1183 if (token_header
== XOFFILE_FORMAT_TEXT
)
1188 if (token_header
== XOFFILE_FORMAT_COMPRESSED
)
1190 FIXME("Compressed formats not supported yet\n");
1191 return DXFILEERR_BADVALUE
;
1194 read_bytes(&buf
, &token_header
, 4);
1196 if ((token_header
!= XOFFILE_FORMAT_FLOAT_BITS_32
) && (token_header
!= XOFFILE_FORMAT_FLOAT_BITS_64
))
1197 return DXFILEERR_BADFILEFLOATSIZE
;
1199 TRACE("Header is correct\n");
1201 while (buf
.rem_bytes
)
1203 if (!parse_template(&buf
))
1205 TRACE("Template is not correct\n");
1206 return DXFILEERR_BADVALUE
;
1210 TRACE("Template successfully parsed:\n");
1211 if (TRACE_ON(d3dxof
))
1212 dump_template(This
->xtemplates
, &This
->xtemplates
[This
->nb_xtemplates
- 1]);
1216 if (TRACE_ON(d3dxof
))
1219 TRACE("Registered templates (%d):\n", This
->nb_xtemplates
);
1220 for (i
= 0; i
< This
->nb_xtemplates
; i
++)
1221 DPRINTF("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
1227 static const IDirectXFileVtbl IDirectXFile_Vtbl
=
1229 IDirectXFileImpl_QueryInterface
,
1230 IDirectXFileImpl_AddRef
,
1231 IDirectXFileImpl_Release
,
1232 IDirectXFileImpl_CreateEnumObject
,
1233 IDirectXFileImpl_CreateSaveObject
,
1234 IDirectXFileImpl_RegisterTemplates
1237 HRESULT
IDirectXFileBinaryImpl_Create(IDirectXFileBinaryImpl
** ppObj
)
1239 IDirectXFileBinaryImpl
* object
;
1241 TRACE("(%p)\n", ppObj
);
1243 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileBinaryImpl
));
1245 object
->lpVtbl
.lpVtbl
= &IDirectXFileBinary_Vtbl
;
1253 /*** IUnknown methods ***/
1254 static HRESULT WINAPI
IDirectXFileBinaryImpl_QueryInterface(IDirectXFileBinary
* iface
, REFIID riid
, void** ppvObject
)
1256 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1258 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1260 if (IsEqualGUID(riid
, &IID_IUnknown
)
1261 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
1262 || IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
1264 IClassFactory_AddRef(iface
);
1269 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
1270 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
)
1271 && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
1272 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1274 return E_NOINTERFACE
;
1277 static ULONG WINAPI
IDirectXFileBinaryImpl_AddRef(IDirectXFileBinary
* iface
)
1279 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1280 ULONG ref
= InterlockedIncrement(&This
->ref
);
1282 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
1287 static ULONG WINAPI
IDirectXFileBinaryImpl_Release(IDirectXFileBinary
* iface
)
1289 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1290 ULONG ref
= InterlockedDecrement(&This
->ref
);
1292 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
1295 HeapFree(GetProcessHeap(), 0, This
);
1300 /*** IDirectXFileObject methods ***/
1301 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetName(IDirectXFileBinary
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
1304 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1306 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
1308 return DXFILEERR_BADVALUE
;
1311 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetId(IDirectXFileBinary
* iface
, LPGUID pGuid
)
1313 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1315 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pGuid
);
1317 return DXFILEERR_BADVALUE
;
1320 /*** IDirectXFileBinary methods ***/
1321 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetSize(IDirectXFileBinary
* iface
, DWORD
* pcbSize
)
1323 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1325 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pcbSize
);
1327 return DXFILEERR_BADVALUE
;
1330 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetMimeType(IDirectXFileBinary
* iface
, LPCSTR
* pszMimeType
)
1332 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1334 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pszMimeType
);
1336 return DXFILEERR_BADVALUE
;
1339 static HRESULT WINAPI
IDirectXFileBinaryImpl_Read(IDirectXFileBinary
* iface
, LPVOID pvData
, DWORD cbSize
, LPDWORD pcbRead
)
1341 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1343 FIXME("(%p/%p)->(%p, %d, %p) stub!\n", This
, iface
, pvData
, cbSize
, pcbRead
);
1345 return DXFILEERR_BADVALUE
;
1348 static const IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl
=
1350 IDirectXFileBinaryImpl_QueryInterface
,
1351 IDirectXFileBinaryImpl_AddRef
,
1352 IDirectXFileBinaryImpl_Release
,
1353 IDirectXFileBinaryImpl_GetName
,
1354 IDirectXFileBinaryImpl_GetId
,
1355 IDirectXFileBinaryImpl_GetSize
,
1356 IDirectXFileBinaryImpl_GetMimeType
,
1357 IDirectXFileBinaryImpl_Read
1360 HRESULT
IDirectXFileDataImpl_Create(IDirectXFileDataImpl
** ppObj
)
1362 IDirectXFileDataImpl
* object
;
1364 TRACE("(%p)\n", ppObj
);
1366 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataImpl
));
1368 object
->lpVtbl
.lpVtbl
= &IDirectXFileData_Vtbl
;
1376 /*** IUnknown methods ***/
1377 static HRESULT WINAPI
IDirectXFileDataImpl_QueryInterface(IDirectXFileData
* iface
, REFIID riid
, void** ppvObject
)
1379 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1381 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1383 if (IsEqualGUID(riid
, &IID_IUnknown
)
1384 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
1385 || IsEqualGUID(riid
, &IID_IDirectXFileData
))
1387 IClassFactory_AddRef(iface
);
1392 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
1393 if (!IsEqualGUID(riid
, &IID_IDirectXFileBinary
)
1394 && !IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
1395 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1397 return E_NOINTERFACE
;
1400 static ULONG WINAPI
IDirectXFileDataImpl_AddRef(IDirectXFileData
* iface
)
1402 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1403 ULONG ref
= InterlockedIncrement(&This
->ref
);
1405 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
1410 static ULONG WINAPI
IDirectXFileDataImpl_Release(IDirectXFileData
* iface
)
1412 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1413 ULONG ref
= InterlockedDecrement(&This
->ref
);
1415 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
1418 HeapFree(GetProcessHeap(), 0, This
);
1423 /*** IDirectXFileObject methods ***/
1424 static HRESULT WINAPI
IDirectXFileDataImpl_GetName(IDirectXFileData
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
1427 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1429 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
1432 return DXFILEERR_BADVALUE
;
1434 strcpy(pstrNameBuf
, This
->pobj
->name
);
1439 static HRESULT WINAPI
IDirectXFileDataImpl_GetId(IDirectXFileData
* iface
, LPGUID pGuid
)
1441 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1443 TRACE("(%p/%p)->(%p)\n", This
, iface
, pGuid
);
1446 return DXFILEERR_BADVALUE
;
1448 memcpy(pGuid
, &This
->pobj
->class_id
, 16);
1453 /*** IDirectXFileData methods ***/
1454 static HRESULT WINAPI
IDirectXFileDataImpl_GetData(IDirectXFileData
* iface
, LPCSTR szMember
, DWORD
* pcbSize
, void** ppvData
)
1456 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1458 TRACE("(%p/%p)->(%s,%p,%p)\n", This
, iface
, szMember
, pcbSize
, ppvData
);
1460 if (!pcbSize
|| !ppvData
)
1461 return DXFILEERR_BADVALUE
;
1465 FIXME("Specifying a member is not supported yet!\n");
1466 return DXFILEERR_BADVALUE
;
1469 *pcbSize
= This
->pobj
->size
;
1470 *ppvData
= This
->pobj
->pdata
;
1475 static HRESULT WINAPI
IDirectXFileDataImpl_GetType(IDirectXFileData
* iface
, const GUID
** pguid
)
1477 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1480 TRACE("(%p/%p)->(%p)\n", This
, iface
, pguid
);
1483 return DXFILEERR_BADVALUE
;
1485 memcpy(&guid
, &This
->pobj
->type
, 16);
1491 static HRESULT WINAPI
IDirectXFileDataImpl_GetNextObject(IDirectXFileData
* iface
, LPDIRECTXFILEOBJECT
* ppChildObj
)
1494 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1496 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppChildObj
);
1498 if (This
->cur_enum_object
>= This
->pobj
->nb_childs
)
1499 return DXFILEERR_NOMOREOBJECTS
;
1501 if (This
->from_ref
&& (This
->level
>= 1))
1503 /* Only 2 levels can enumerated if the object is obtained from a reference */
1504 return DXFILEERR_NOMOREOBJECTS
;
1507 if (This
->pobj
->childs
[This
->cur_enum_object
]->ptarget
)
1509 IDirectXFileDataReferenceImpl
*object
;
1511 hr
= IDirectXFileDataReferenceImpl_Create(&object
);
1513 return DXFILEERR_BADVALUE
;
1515 object
->ptarget
= This
->pobj
->childs
[This
->cur_enum_object
++]->ptarget
;
1517 *ppChildObj
= (LPDIRECTXFILEOBJECT
)object
;
1521 IDirectXFileDataImpl
*object
;
1523 hr
= IDirectXFileDataImpl_Create(&object
);
1525 return DXFILEERR_BADVALUE
;
1527 object
->pobj
= This
->pobj
->childs
[This
->cur_enum_object
++];
1528 object
->cur_enum_object
= 0;
1529 object
->from_ref
= This
->from_ref
;
1530 object
->level
= This
->level
+ 1;
1532 *ppChildObj
= (LPDIRECTXFILEOBJECT
)object
;
1538 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataObject(IDirectXFileData
* iface
, LPDIRECTXFILEDATA pDataObj
)
1540 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1542 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pDataObj
);
1544 return DXFILEERR_BADVALUE
;
1547 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataReference(IDirectXFileData
* iface
, LPCSTR szRef
, const GUID
* pguidRef
)
1549 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1551 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szRef
, pguidRef
);
1553 return DXFILEERR_BADVALUE
;
1556 static HRESULT WINAPI
IDirectXFileDataImpl_AddBinaryObject(IDirectXFileData
* iface
, LPCSTR szName
, const GUID
* pguid
, LPCSTR szMimeType
, LPVOID pvData
, DWORD cbSize
)
1558 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1560 FIXME("(%p/%p)->(%s,%p,%s,%p,%d) stub!\n", This
, iface
, szName
, pguid
, szMimeType
, pvData
, cbSize
);
1562 return DXFILEERR_BADVALUE
;
1565 static const IDirectXFileDataVtbl IDirectXFileData_Vtbl
=
1567 IDirectXFileDataImpl_QueryInterface
,
1568 IDirectXFileDataImpl_AddRef
,
1569 IDirectXFileDataImpl_Release
,
1570 IDirectXFileDataImpl_GetName
,
1571 IDirectXFileDataImpl_GetId
,
1572 IDirectXFileDataImpl_GetData
,
1573 IDirectXFileDataImpl_GetType
,
1574 IDirectXFileDataImpl_GetNextObject
,
1575 IDirectXFileDataImpl_AddDataObject
,
1576 IDirectXFileDataImpl_AddDataReference
,
1577 IDirectXFileDataImpl_AddBinaryObject
1580 HRESULT
IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl
** ppObj
)
1582 IDirectXFileDataReferenceImpl
* object
;
1584 TRACE("(%p)\n", ppObj
);
1586 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataReferenceImpl
));
1588 object
->lpVtbl
.lpVtbl
= &IDirectXFileDataReference_Vtbl
;
1596 /*** IUnknown methods ***/
1597 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_QueryInterface(IDirectXFileDataReference
* iface
, REFIID riid
, void** ppvObject
)
1599 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
1601 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1603 if (IsEqualGUID(riid
, &IID_IUnknown
)
1604 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
1605 || IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
1607 IClassFactory_AddRef(iface
);
1612 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
1613 if (!IsEqualGUID(riid
, &IID_IDirectXFileData
)
1614 && !IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
1615 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1617 return E_NOINTERFACE
;
1620 static ULONG WINAPI
IDirectXFileDataReferenceImpl_AddRef(IDirectXFileDataReference
* iface
)
1622 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
1623 ULONG ref
= InterlockedIncrement(&This
->ref
);
1625 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
1630 static ULONG WINAPI
IDirectXFileDataReferenceImpl_Release(IDirectXFileDataReference
* iface
)
1632 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
1633 ULONG ref
= InterlockedDecrement(&This
->ref
);
1635 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
1638 HeapFree(GetProcessHeap(), 0, This
);
1643 /*** IDirectXFileObject methods ***/
1644 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetName(IDirectXFileDataReference
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
1646 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
1648 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
1651 return DXFILEERR_BADVALUE
;
1653 strcpy(pstrNameBuf
, This
->ptarget
->name
);
1655 return DXFILEERR_BADVALUE
;
1658 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetId(IDirectXFileDataReference
* iface
, LPGUID pGuid
)
1660 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
1662 TRACE("(%p/%p)->(%p)\n", This
, iface
, pGuid
);
1665 return DXFILEERR_BADVALUE
;
1667 memcpy(pGuid
, &This
->ptarget
->class_id
, 16);
1672 /*** IDirectXFileDataReference ***/
1673 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
1675 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
1676 IDirectXFileDataImpl
*object
;
1679 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
1682 return DXFILEERR_BADVALUE
;
1684 hr
= IDirectXFileDataImpl_Create(&object
);
1686 return DXFILEERR_BADVALUE
;
1688 object
->pobj
= This
->ptarget
;
1689 object
->cur_enum_object
= 0;
1691 object
->from_ref
= TRUE
;
1693 *ppDataObj
= (LPDIRECTXFILEDATA
)object
;
1698 static const IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl
=
1700 IDirectXFileDataReferenceImpl_QueryInterface
,
1701 IDirectXFileDataReferenceImpl_AddRef
,
1702 IDirectXFileDataReferenceImpl_Release
,
1703 IDirectXFileDataReferenceImpl_GetName
,
1704 IDirectXFileDataReferenceImpl_GetId
,
1705 IDirectXFileDataReferenceImpl_Resolve
1708 HRESULT
IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl
** ppObj
)
1710 IDirectXFileEnumObjectImpl
* object
;
1712 TRACE("(%p)\n", ppObj
);
1714 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileEnumObjectImpl
));
1716 object
->lpVtbl
.lpVtbl
= &IDirectXFileEnumObject_Vtbl
;
1724 /*** IUnknown methods ***/
1725 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_QueryInterface(IDirectXFileEnumObject
* iface
, REFIID riid
, void** ppvObject
)
1727 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1729 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1731 if (IsEqualGUID(riid
, &IID_IUnknown
)
1732 || IsEqualGUID(riid
, &IID_IDirectXFileEnumObject
))
1734 IClassFactory_AddRef(iface
);
1739 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1740 return E_NOINTERFACE
;
1743 static ULONG WINAPI
IDirectXFileEnumObjectImpl_AddRef(IDirectXFileEnumObject
* iface
)
1745 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1746 ULONG ref
= InterlockedIncrement(&This
->ref
);
1748 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
1753 static ULONG WINAPI
IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject
* iface
)
1755 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1756 ULONG ref
= InterlockedDecrement(&This
->ref
);
1758 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
1762 CloseHandle(This
->hFile
);
1763 HeapFree(GetProcessHeap(), 0, This
);
1769 static BOOL
parse_object_members_list(parse_buffer
* buf
)
1773 xtemplate
* pt
= buf
->pxt
[buf
->level
];
1774 DWORD last_dword
= 0;
1776 for (i
= 0; i
< pt
->nb_members
; i
++)
1780 if (pt
->members
[i
].nb_dims
> 1)
1782 FIXME("Arrays with dimension > 1 not yet supported\n");
1785 else if (pt
->members
[i
].nb_dims
)
1787 if (!pt
->members
[i
].dim_fixed
[0])
1791 FIXME("Array with variable must be preceded by the size\n");
1794 nb_elems
= last_dword
;
1795 /*FIXME("Arrays with variable size not yet supported\n");
1799 nb_elems
= pt
->members
[i
].dim_value
[0];
1804 for (k
= 0; k
< nb_elems
; k
++)
1808 token
= check_TOKEN(buf
);
1809 if (token
== TOKEN_COMMA
)
1815 /* Allow comma omission */
1816 if (!((token
== TOKEN_FLOAT
)))
1821 if (pt
->members
[i
].type
== TOKEN_NAME
)
1825 TRACE("Found suboject %s\n", buf
->pdxf
->xtemplates
[pt
->members
[i
].idx_template
].name
);
1827 /* To do template lookup */
1828 for (j
= 0; j
< buf
->pdxf
->nb_xtemplates
; j
++)
1830 if (!strcmp(buf
->pdxf
->xtemplates
[pt
->members
[i
].idx_template
].name
, buf
->pdxf
->xtemplates
[j
].name
))
1832 buf
->pxt
[buf
->level
] = &buf
->pdxf
->xtemplates
[j
];
1836 if (j
== buf
->pdxf
->nb_xtemplates
)
1838 FIXME("Unknown template %s\n", (char*)buf
->value
);
1842 TRACE("Enter %s\n", buf
->pdxf
->xtemplates
[pt
->members
[i
].idx_template
].name
);
1843 if (!parse_object_parts(buf
, FALSE
))
1849 /*if (get_TOKEN(buf) != TOKEN_SEMICOLON)
1854 token
= check_TOKEN(buf
);
1855 if (token
== TOKEN_INTEGER
)
1858 last_dword
= *(DWORD
*)buf
->value
;
1859 TRACE("%s = %d\n", pt
->members
[i
].name
, *(DWORD
*)buf
->value
);
1860 /* Assume larger size */
1861 if ((buf
->cur_pdata
- buf
->pxo
->pdata
+ 4) > MAX_DATA_SIZE
)
1863 WARN("Buffer too small\n");
1866 if (pt
->members
[i
].type
== TOKEN_WORD
)
1868 *(((WORD
*)(buf
->cur_pdata
))) = (WORD
)(*(DWORD
*)buf
->value
);
1869 buf
->cur_pdata
+= 2;
1871 else if (pt
->members
[i
].type
== TOKEN_DWORD
)
1873 *(((DWORD
*)(buf
->cur_pdata
))) = (DWORD
)(*(DWORD
*)buf
->value
);
1874 buf
->cur_pdata
+= 4;
1878 FIXME("Token %d not supported\n", pt
->members
[i
].type
);
1882 else if (token
== TOKEN_FLOAT
)
1885 TRACE("%s = %f\n", pt
->members
[i
].name
, *(float*)buf
->value
);
1886 /* Assume larger size */
1887 if ((buf
->cur_pdata
- buf
->pxo
->pdata
+ 4) > MAX_DATA_SIZE
)
1889 WARN("Buffer too small\n");
1892 if (pt
->members
[i
].type
== TOKEN_FLOAT
)
1894 *(((float*)(buf
->cur_pdata
))) = (float)(*(float*)buf
->value
);
1895 buf
->cur_pdata
+= 4;
1899 FIXME("Token %d not supported\n", pt
->members
[i
].type
);
1903 else if (token
== TOKEN_LPSTR
)
1906 TRACE("%s = %s\n", pt
->members
[i
].name
, (char*)buf
->value
);
1907 /* Assume larger size */
1908 if ((buf
->cur_pdata
- buf
->pxo
->pdata
+ 4) > MAX_DATA_SIZE
)
1910 WARN("Buffer too small\n");
1913 if (pt
->members
[i
].type
== TOKEN_LPSTR
)
1915 int len
= strlen((char*)buf
->value
) + 1;
1916 if ((buf
->cur_pstrings
- buf
->pstrings
+ len
) > MAX_STRINGS_BUFFER
)
1918 WARN("Buffer too small %p %p %d\n", buf
->cur_pstrings
, buf
->pstrings
, len
);
1921 strcpy((char*)buf
->cur_pstrings
, (char*)buf
->value
);
1922 *(((LPCSTR
*)(buf
->cur_pdata
))) = (char*)buf
->cur_pstrings
;
1923 buf
->cur_pstrings
+= len
;
1924 buf
->cur_pdata
+= 4;
1928 FIXME("Token %d not supported\n", pt
->members
[i
].type
);
1934 FIXME("Unexpected token %d\n", token
);
1942 token
= get_TOKEN(buf
);
1943 if (token
!= TOKEN_SEMICOLON
)
1945 /* Allow comma instead of semicolon in some specific cases */
1946 if (!((token
== TOKEN_COMMA
) && ((i
+1) < pt
->nb_members
) && (pt
->members
[i
].type
== pt
->members
[i
+1].type
)
1947 && (!pt
->members
[i
].nb_dims
) && (!pt
->members
[i
+1].nb_dims
)))
1956 static BOOL
parse_object_parts(parse_buffer
* buf
, BOOL allow_optional
)
1958 if (!parse_object_members_list(buf
))
1963 buf
->pxo
->size
= buf
->cur_pdata
- buf
->pxo
->pdata
;
1965 /* Skip trailing semicolon */
1966 while (check_TOKEN(buf
) == TOKEN_SEMICOLON
)
1971 if (check_TOKEN(buf
) == TOKEN_OBRACE
)
1975 if (get_TOKEN(buf
) != TOKEN_NAME
)
1977 if (get_TOKEN(buf
) != TOKEN_CBRACE
)
1979 TRACE("Found optional reference %s\n", (char*)buf
->value
);
1980 for (i
= 0; i
< buf
->nb_pxo_globals
; i
++)
1982 for (j
= 0; j
< buf
->pxo_globals
[i
*MAX_SUBOBJECTS
].nb_subobjects
; j
++)
1984 if (!strcmp(buf
->pxo_globals
[i
*MAX_SUBOBJECTS
+j
].name
, (char*)buf
->value
))
1989 if (i
== buf
->nb_pxo_globals
)
1991 ERR("Reference to unknown object %s\n", (char*)buf
->value
);
1994 buf
->pxo
->childs
[buf
->pxo
->nb_childs
] = &buf
->pxo_tab
[buf
->cur_subobject
++];
1995 buf
->pxo
->childs
[buf
->pxo
->nb_childs
]->ptarget
= &buf
->pxo_globals
[i
*MAX_SUBOBJECTS
+j
];
1996 buf
->pxo
->nb_childs
++;
1998 else if (check_TOKEN(buf
) == TOKEN_NAME
)
2000 xobject
* pxo
= buf
->pxo
;
2001 buf
->pxo
= buf
->pxo
->childs
[buf
->pxo
->nb_childs
] = &buf
->pxo_tab
[buf
->cur_subobject
++];
2003 TRACE("Enter optional %s\n", (char*)buf
->value
);
2005 if (!parse_object(buf
))
2012 buf
->pxo
->nb_childs
++;
2019 if (buf
->pxo
->nb_childs
> MAX_CHILDS
)
2021 FIXME("Too many childs %d\n", buf
->pxo
->nb_childs
);
2028 static BOOL
parse_object(parse_buffer
* buf
)
2032 buf
->pxo
->pdata
= buf
->cur_pdata
;
2033 buf
->pxo
->ptarget
= NULL
;
2035 if (get_TOKEN(buf
) != TOKEN_NAME
)
2038 /* To do template lookup */
2039 for (i
= 0; i
< buf
->pdxf
->nb_xtemplates
; i
++)
2041 if (!strcmp((char*)buf
->value
, buf
->pdxf
->xtemplates
[i
].name
))
2043 buf
->pxt
[buf
->level
] = &buf
->pdxf
->xtemplates
[i
];
2044 memcpy(&buf
->pxo
->type
, &buf
->pdxf
->xtemplates
[i
].class_id
, 16);
2048 if (i
== buf
->pdxf
->nb_xtemplates
)
2050 FIXME("Unknown template %s\n", (char*)buf
->value
);
2054 if (check_TOKEN(buf
) == TOKEN_NAME
)
2057 strcpy(buf
->pxo
->name
, (char*)buf
->value
);
2060 buf
->pxo
->name
[0] = 0;
2062 if (get_TOKEN(buf
) != TOKEN_OBRACE
)
2064 if (check_TOKEN(buf
) == TOKEN_GUID
)
2067 memcpy(&buf
->pxo
->class_id
, buf
->value
, 16);
2070 memset(&buf
->pxo
->class_id
, 0, 16);
2072 if (!parse_object_parts(buf
, TRUE
))
2074 if (get_TOKEN(buf
) != TOKEN_CBRACE
)
2079 /* Go to the next object */
2080 while (buf
->rem_bytes
&& is_space(*buf
->buffer
))
2090 /*** IDirectXFileEnumObject methods ***/
2091 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
2093 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
2094 IDirectXFileDataImpl
* object
;
2099 TRACE("(%p/%p)->(%p)\n", This
, iface
, ppDataObj
);
2101 if (This
->nb_xobjects
>= MAX_OBJECTS
)
2103 ERR("Too many objects\n");
2104 return DXFILEERR_NOMOREOBJECTS
;
2107 if (!This
->buf
.rem_bytes
)
2108 return DXFILEERR_NOMOREOBJECTS
;
2110 hr
= IDirectXFileDataImpl_Create(&object
);
2114 This
->buf
.pxo_globals
= &This
->xobjects
[0][0];
2115 This
->buf
.nb_pxo_globals
= This
->nb_xobjects
;
2116 This
->buf
.pxo_tab
= &This
->xobjects
[This
->nb_xobjects
][0];
2117 This
->buf
.cur_subobject
= 0;
2118 This
->buf
.pxo
= &This
->buf
.pxo_tab
[This
->buf
.cur_subobject
++];
2119 This
->buf
.level
= 0;
2121 pdata
= HeapAlloc(GetProcessHeap(), 0, MAX_DATA_SIZE
);
2124 WARN("Out of memory\n");
2125 return DXFILEERR_BADALLOC
;
2127 This
->buf
.cur_pdata
= pdata
;
2129 pstrings
= HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER
);
2132 WARN("Out of memory\n");
2133 HeapFree(GetProcessHeap(), 0, This
->buf
.pxo
->pdata
);
2134 return DXFILEERR_BADALLOC
;
2136 This
->buf
.cur_pstrings
= This
->buf
.pstrings
= pstrings
;
2138 if (!parse_object(&This
->buf
))
2140 TRACE("Object is not correct\n");
2141 HeapFree(GetProcessHeap(), 0, This
->buf
.pxo
->pdata
);
2142 HeapFree(GetProcessHeap(), 0, This
->buf
.pstrings
);
2143 return DXFILEERR_PARSEERROR
;
2146 This
->buf
.pxo
->nb_subobjects
= This
->buf
.cur_subobject
;
2147 if (This
->buf
.cur_subobject
> MAX_SUBOBJECTS
)
2149 FIXME("Too many suobjects %d\n", This
->buf
.cur_subobject
);
2150 return DXFILEERR_BADALLOC
;
2153 object
->pstrings
= pstrings
;
2154 object
->pobj
= This
->buf
.pxo
;
2155 object
->cur_enum_object
= 0;
2157 object
->from_ref
= FALSE
;
2159 *ppDataObj
= (LPDIRECTXFILEDATA
)object
;
2161 This
->nb_xobjects
++;
2166 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectById(IDirectXFileEnumObject
* iface
, REFGUID rguid
, LPDIRECTXFILEDATA
* ppDataObj
)
2168 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
2170 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, rguid
, ppDataObj
);
2172 return DXFILEERR_BADVALUE
;
2175 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectByName(IDirectXFileEnumObject
* iface
, LPCSTR szName
, LPDIRECTXFILEDATA
* ppDataObj
)
2177 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
2179 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szName
, ppDataObj
);
2181 return DXFILEERR_BADVALUE
;
2184 static const IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl
=
2186 IDirectXFileEnumObjectImpl_QueryInterface
,
2187 IDirectXFileEnumObjectImpl_AddRef
,
2188 IDirectXFileEnumObjectImpl_Release
,
2189 IDirectXFileEnumObjectImpl_GetNextDataObject
,
2190 IDirectXFileEnumObjectImpl_GetDataObjectById
,
2191 IDirectXFileEnumObjectImpl_GetDataObjectByName
2194 HRESULT
IDirectXFileObjectImpl_Create(IDirectXFileObjectImpl
** ppObj
)
2196 IDirectXFileObjectImpl
* object
;
2198 TRACE("(%p)\n", ppObj
);
2200 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileObjectImpl
));
2202 object
->lpVtbl
.lpVtbl
= &IDirectXFileObject_Vtbl
;
2210 /*** IUnknown methods ***/
2211 static HRESULT WINAPI
IDirectXFileObjectImpl_QueryInterface(IDirectXFileObject
* iface
, REFIID riid
, void** ppvObject
)
2213 IDirectXFileObjectImpl
*This
= (IDirectXFileObjectImpl
*)iface
;
2215 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
2217 if (IsEqualGUID(riid
, &IID_IUnknown
)
2218 || IsEqualGUID(riid
, &IID_IDirectXFileObject
))
2220 IClassFactory_AddRef(iface
);
2225 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
2226 return E_NOINTERFACE
;
2229 static ULONG WINAPI
IDirectXFileObjectImpl_AddRef(IDirectXFileObject
* iface
)
2231 IDirectXFileObjectImpl
*This
= (IDirectXFileObjectImpl
*)iface
;
2232 ULONG ref
= InterlockedIncrement(&This
->ref
);
2234 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
2239 static ULONG WINAPI
IDirectXFileObjectImpl_Release(IDirectXFileObject
* iface
)
2241 IDirectXFileObjectImpl
*This
= (IDirectXFileObjectImpl
*)iface
;
2242 ULONG ref
= InterlockedDecrement(&This
->ref
);
2244 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
2247 HeapFree(GetProcessHeap(), 0, This
);
2252 /*** IDirectXFileObject methods ***/
2253 static HRESULT WINAPI
IDirectXFileObjectImpl_GetName(IDirectXFileObject
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
2255 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
2257 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
2259 return DXFILEERR_BADVALUE
;
2262 static HRESULT WINAPI
IDirectXFileObjectImpl_GetId(IDirectXFileObject
* iface
, LPGUID pGuid
)
2264 IDirectXFileObjectImpl
*This
= (IDirectXFileObjectImpl
*)iface
;
2266 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pGuid
);
2268 return DXFILEERR_BADVALUE
;
2271 static const IDirectXFileObjectVtbl IDirectXFileObject_Vtbl
=
2273 IDirectXFileObjectImpl_QueryInterface
,
2274 IDirectXFileObjectImpl_AddRef
,
2275 IDirectXFileObjectImpl_Release
,
2276 IDirectXFileObjectImpl_GetName
,
2277 IDirectXFileObjectImpl_GetId
2280 HRESULT
IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl
** ppObj
)
2282 IDirectXFileSaveObjectImpl
* object
;
2284 TRACE("(%p)\n", ppObj
);
2286 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileSaveObjectImpl
));
2288 object
->lpVtbl
.lpVtbl
= &IDirectXFileSaveObject_Vtbl
;
2296 /*** IUnknown methods ***/
2297 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_QueryInterface(IDirectXFileSaveObject
* iface
, REFIID riid
, void** ppvObject
)
2299 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
2301 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
2303 if (IsEqualGUID(riid
, &IID_IUnknown
)
2304 || IsEqualGUID(riid
, &IID_IDirectXFileSaveObject
))
2306 IClassFactory_AddRef(iface
);
2311 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
2312 return E_NOINTERFACE
;
2315 static ULONG WINAPI
IDirectXFileSaveObjectImpl_AddRef(IDirectXFileSaveObject
* iface
)
2317 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
2318 ULONG ref
= InterlockedIncrement(&This
->ref
);
2320 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
2325 static ULONG WINAPI
IDirectXFileSaveObjectImpl_Release(IDirectXFileSaveObject
* iface
)
2327 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
2328 ULONG ref
= InterlockedDecrement(&This
->ref
);
2330 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
2333 HeapFree(GetProcessHeap(), 0, This
);
2338 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveTemplates(IDirectXFileSaveObject
* iface
, DWORD cTemplates
, const GUID
** ppguidTemplates
)
2340 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
2342 FIXME("(%p/%p)->(%d,%p) stub!\n", This
, iface
, cTemplates
, ppguidTemplates
);
2344 return DXFILEERR_BADVALUE
;
2347 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_CreateDataObject(IDirectXFileSaveObject
* iface
, REFGUID rguidTemplate
, LPCSTR szName
, const GUID
* pguid
, DWORD cbSize
, LPVOID pvData
, LPDIRECTXFILEDATA
* ppDataObj
)
2349 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
2351 FIXME("(%p/%p)->(%p,%s,%p,%d,%p,%p) stub!\n", This
, iface
, rguidTemplate
, szName
, pguid
, cbSize
, pvData
, ppDataObj
);
2353 return DXFILEERR_BADVALUE
;
2356 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveData(IDirectXFileSaveObject
* iface
, LPDIRECTXFILEDATA ppDataObj
)
2358 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
2360 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, ppDataObj
);
2362 return DXFILEERR_BADVALUE
;
2365 static const IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl
=
2367 IDirectXFileSaveObjectImpl_QueryInterface
,
2368 IDirectXFileSaveObjectImpl_AddRef
,
2369 IDirectXFileSaveObjectImpl_Release
,
2370 IDirectXFileSaveObjectImpl_SaveTemplates
,
2371 IDirectXFileSaveObjectImpl_CreateDataObject
,
2372 IDirectXFileSaveObjectImpl_SaveData