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 MAKEFOUR('0','3','0','2')
42 #define XOFFILE_FORMAT_BINARY MAKEFOUR('b','i','n',' ')
43 #define XOFFILE_FORMAT_TEXT MAKEFOUR('t','x','t',' ')
44 #define XOFFILE_FORMAT_COMPRESSED MAKEFOUR('c','m','p',' ')
45 #define XOFFILE_FORMAT_FLOAT_BITS_32 MAKEFOUR('0','0','3','2')
46 #define XOFFILE_FORMAT_FLOAT_BITS_64 MAKEFOUR('0','0','6','4')
49 #define TOKEN_STRING 2
50 #define TOKEN_INTEGER 3
52 #define TOKEN_INTEGER_LIST 6
53 #define TOKEN_FLOAT_LIST 7
54 #define TOKEN_OBRACE 10
55 #define TOKEN_CBRACE 11
56 #define TOKEN_OPAREN 12
57 #define TOKEN_CPAREN 13
58 #define TOKEN_OBRACKET 14
59 #define TOKEN_CBRACKET 15
60 #define TOKEN_OANGLE 16
61 #define TOKEN_CANGLE 17
63 #define TOKEN_COMMA 19
64 #define TOKEN_SEMICOLON 20
65 #define TOKEN_TEMPLATE 31
67 #define TOKEN_DWORD 41
68 #define TOKEN_FLOAT 42
69 #define TOKEN_DOUBLE 43
71 #define TOKEN_UCHAR 45
72 #define TOKEN_SWORD 46
73 #define TOKEN_SDWORD 47
75 #define TOKEN_LPSTR 49
76 #define TOKEN_UNICODE 50
77 #define TOKEN_CSTRING 51
78 #define TOKEN_ARRAY 52
80 #define CLSIDFMT "<%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X>"
82 #define MAX_INPUT_SIZE 1000000
83 #define MAX_DATA_SIZE 100000
85 static const struct IDirectXFileVtbl IDirectXFile_Vtbl
;
86 static const struct IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl
;
87 static const struct IDirectXFileDataVtbl IDirectXFileData_Vtbl
;
88 static const struct IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl
;
89 static const struct IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl
;
90 static const struct IDirectXFileObjectVtbl IDirectXFileObject_Vtbl
;
91 static const struct IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl
;
93 static BOOL
parse_object_parts(parse_buffer
* buf
, BOOL allow_optional
);
94 static BOOL
parse_object(parse_buffer
* buf
);
96 HRESULT
IDirectXFileImpl_Create(IUnknown
* pUnkOuter
, LPVOID
* ppObj
)
98 IDirectXFileImpl
* object
;
100 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
102 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileImpl
));
104 object
->lpVtbl
.lpVtbl
= &IDirectXFile_Vtbl
;
112 /*** IUnknown methods ***/
113 static HRESULT WINAPI
IDirectXFileImpl_QueryInterface(IDirectXFile
* iface
, REFIID riid
, void** ppvObject
)
115 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
117 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
119 if (IsEqualGUID(riid
, &IID_IUnknown
)
120 || IsEqualGUID(riid
, &IID_IDirectXFile
))
122 IClassFactory_AddRef(iface
);
127 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
128 return E_NOINTERFACE
;
131 static ULONG WINAPI
IDirectXFileImpl_AddRef(IDirectXFile
* iface
)
133 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
134 ULONG ref
= InterlockedIncrement(&This
->ref
);
136 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
141 static ULONG WINAPI
IDirectXFileImpl_Release(IDirectXFile
* iface
)
143 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
144 ULONG ref
= InterlockedDecrement(&This
->ref
);
146 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
149 HeapFree(GetProcessHeap(), 0, This
);
154 /*** IDirectXFile methods ***/
155 static HRESULT WINAPI
IDirectXFileImpl_CreateEnumObject(IDirectXFile
* iface
, LPVOID pvSource
, DXFILELOADOPTIONS dwLoadOptions
, LPDIRECTXFILEENUMOBJECT
* ppEnumObj
)
157 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
158 IDirectXFileEnumObjectImpl
* object
;
162 HANDLE hFile
= INVALID_HANDLE_VALUE
;
164 FIXME("(%p/%p)->(%p,%x,%p) partial stub!\n", This
, iface
, pvSource
, dwLoadOptions
, ppEnumObj
);
167 return DXFILEERR_BADVALUE
;
169 if (dwLoadOptions
== DXFILELOAD_FROMFILE
)
171 TRACE("Open source file '%s'\n", (char*)pvSource
);
173 hFile
= CreateFileA((char*)pvSource
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
174 if (hFile
== INVALID_HANDLE_VALUE
)
176 TRACE("File '%s' not found\n", (char*)pvSource
);
177 return DXFILEERR_FILENOTFOUND
;
180 if (!ReadFile(hFile
, header
, 16, &size
, NULL
))
182 hr
= DXFILEERR_BADVALUE
;
188 hr
= DXFILEERR_BADFILETYPE
;
192 if (TRACE_ON(d3dxof
))
195 memcpy(string
, header
, 16);
197 TRACE("header = '%s'\n", string
);
202 FIXME("Source type %d is not handled yet\n", dwLoadOptions
);
203 hr
= DXFILEERR_NOTDONEYET
;
207 if (header
[0] != XOFFILE_FORMAT_MAGIC
)
209 hr
= DXFILEERR_BADFILETYPE
;
213 if (header
[1] != XOFFILE_FORMAT_VERSION
)
215 hr
= DXFILEERR_BADFILEVERSION
;
219 if ((header
[2] != XOFFILE_FORMAT_BINARY
) && (header
[2] != XOFFILE_FORMAT_TEXT
) && (header
[2] != XOFFILE_FORMAT_COMPRESSED
))
221 hr
= DXFILEERR_BADFILETYPE
;
225 if (header
[2] == XOFFILE_FORMAT_BINARY
)
227 FIXME("Binary format not supported yet\n");
228 hr
= DXFILEERR_NOTDONEYET
;
232 if (header
[2] == XOFFILE_FORMAT_COMPRESSED
)
234 FIXME("Compressed formats not supported yet\n");
235 hr
= DXFILEERR_BADVALUE
;
239 if ((header
[3] != XOFFILE_FORMAT_FLOAT_BITS_32
) && (header
[3] != XOFFILE_FORMAT_FLOAT_BITS_64
))
241 hr
= DXFILEERR_BADFILEFLOATSIZE
;
245 TRACE("Header is correct\n");
247 hr
= IDirectXFileEnumObjectImpl_Create(&object
);
251 object
->source
= dwLoadOptions
;
252 object
->hFile
= hFile
;
253 object
->pDirectXFile
= This
;
254 object
->buf
.pdxf
= This
;
255 object
->buf
.txt
= TRUE
;
256 object
->buf
.cur_subobject
= 0;
258 object
->buf
.buffer
= HeapAlloc(GetProcessHeap(), 0, MAX_INPUT_SIZE
+1);
259 if (!object
->buf
.buffer
)
261 WARN("Out of memory\n");
262 hr
= DXFILEERR_BADALLOC
;
266 ReadFile(hFile
, object
->buf
.buffer
, MAX_INPUT_SIZE
+1, &object
->buf
.rem_bytes
, NULL
);
267 if (object
->buf
.rem_bytes
> MAX_INPUT_SIZE
)
269 FIXME("File size > %d not supported yet\n", MAX_INPUT_SIZE
);
270 HeapFree(GetProcessHeap(), 0, object
->buf
.buffer
);
271 hr
= DXFILEERR_PARSEERROR
;
274 TRACE("Read %d bytes\n", object
->buf
.rem_bytes
);
276 *ppEnumObj
= (LPDIRECTXFILEENUMOBJECT
)object
;
281 if (hFile
!= INVALID_HANDLE_VALUE
)
288 static HRESULT WINAPI
IDirectXFileImpl_CreateSaveObject(IDirectXFile
* iface
, LPCSTR szFileName
, DXFILEFORMAT dwFileFormat
, LPDIRECTXFILESAVEOBJECT
* ppSaveObj
)
290 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
292 FIXME("(%p/%p)->(%s,%x,%p) stub!\n", This
, iface
, szFileName
, dwFileFormat
, ppSaveObj
);
294 return DXFILEERR_BADVALUE
;
297 static BOOL
read_bytes(parse_buffer
* buf
, LPVOID data
, DWORD size
)
299 if (buf
->rem_bytes
< size
)
301 memcpy(data
, buf
->buffer
, size
);
303 buf
->rem_bytes
-= size
;
307 static void dump_TOKEN(WORD token
)
309 #define DUMP_TOKEN(t) case t: TRACE(#t "\n"); break
312 DUMP_TOKEN(TOKEN_NAME
);
313 DUMP_TOKEN(TOKEN_STRING
);
314 DUMP_TOKEN(TOKEN_INTEGER
);
315 DUMP_TOKEN(TOKEN_GUID
);
316 DUMP_TOKEN(TOKEN_INTEGER_LIST
);
317 DUMP_TOKEN(TOKEN_FLOAT_LIST
);
318 DUMP_TOKEN(TOKEN_OBRACE
);
319 DUMP_TOKEN(TOKEN_CBRACE
);
320 DUMP_TOKEN(TOKEN_OPAREN
);
321 DUMP_TOKEN(TOKEN_CPAREN
);
322 DUMP_TOKEN(TOKEN_OBRACKET
);
323 DUMP_TOKEN(TOKEN_CBRACKET
);
324 DUMP_TOKEN(TOKEN_OANGLE
);
325 DUMP_TOKEN(TOKEN_CANGLE
);
326 DUMP_TOKEN(TOKEN_DOT
);
327 DUMP_TOKEN(TOKEN_COMMA
);
328 DUMP_TOKEN(TOKEN_SEMICOLON
);
329 DUMP_TOKEN(TOKEN_TEMPLATE
);
330 DUMP_TOKEN(TOKEN_WORD
);
331 DUMP_TOKEN(TOKEN_DWORD
);
332 DUMP_TOKEN(TOKEN_FLOAT
);
333 DUMP_TOKEN(TOKEN_DOUBLE
);
334 DUMP_TOKEN(TOKEN_CHAR
);
335 DUMP_TOKEN(TOKEN_UCHAR
);
336 DUMP_TOKEN(TOKEN_SWORD
);
337 DUMP_TOKEN(TOKEN_SDWORD
);
338 DUMP_TOKEN(TOKEN_VOID
);
339 DUMP_TOKEN(TOKEN_LPSTR
);
340 DUMP_TOKEN(TOKEN_UNICODE
);
341 DUMP_TOKEN(TOKEN_CSTRING
);
342 DUMP_TOKEN(TOKEN_ARRAY
);
345 TRACE("Unknown token %d\n", token
);
351 static BOOL
is_space(char c
)
365 static BOOL
is_operator(char c
)
384 static inline BOOL
is_separator(char c
)
386 return is_space(c
) || is_operator(c
);
389 static WORD
get_operator_token(char c
)
398 return TOKEN_OBRACKET
;
400 return TOKEN_CBRACKET
;
412 return TOKEN_SEMICOLON
;
417 static BOOL
is_keyword(parse_buffer
* buf
, const char* keyword
)
419 DWORD len
= strlen(keyword
);
420 if (!strncmp((char*)buf
->buffer
, keyword
,len
) && is_separator(*(buf
->buffer
+len
)))
423 buf
->rem_bytes
-= len
;
429 static WORD
get_keyword_token(parse_buffer
* buf
)
431 if (is_keyword(buf
, "template"))
432 return TOKEN_TEMPLATE
;
433 if (is_keyword(buf
, "WORD"))
435 if (is_keyword(buf
, "DWORD"))
437 if (is_keyword(buf
, "FLOAT"))
439 if (is_keyword(buf
, "DOUBLE"))
441 if (is_keyword(buf
, "CHAR"))
443 if (is_keyword(buf
, "UCHAR"))
445 if (is_keyword(buf
, "SWORD"))
447 if (is_keyword(buf
, "SDWORD"))
449 if (is_keyword(buf
, "VOID"))
451 if (is_keyword(buf
, "STRING"))
453 if (is_keyword(buf
, "UNICODE"))
454 return TOKEN_UNICODE
;
455 if (is_keyword(buf
, "CSTRING"))
456 return TOKEN_CSTRING
;
457 if (is_keyword(buf
, "array"))
463 static BOOL
is_guid(parse_buffer
* buf
)
471 if (*buf
->buffer
!= '<')
474 while (*(buf
->buffer
+pos
) != '>')
476 tmp
[pos
] = *(buf
->buffer
+pos
);
481 if (pos
!= 38 /* <+36+> */)
483 TRACE("Wrong guid %s (%d)\n", tmp
, pos
);
487 buf
->rem_bytes
-= pos
;
489 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);
492 TRACE("Wrong guid %s (%d)\n", tmp
, pos
);
495 TRACE("Found guid %s (%d)\n", tmp
, pos
);
497 class_id
.Data2
= tab
[0];
498 class_id
.Data3
= tab
[1];
499 class_id
.Data4
[0] = tab
[2];
500 class_id
.Data4
[1] = tab
[3];
501 class_id
.Data4
[2] = tab
[4];
502 class_id
.Data4
[3] = tab
[5];
503 class_id
.Data4
[4] = tab
[6];
504 class_id
.Data4
[5] = tab
[7];
505 class_id
.Data4
[6] = tab
[8];
506 class_id
.Data4
[7] = tab
[9];
508 *(GUID
*)buf
->value
= class_id
;
513 static BOOL
is_name(parse_buffer
* buf
)
519 while (!is_separator(c
= *(buf
->buffer
+pos
)))
521 if (!(((c
>= 'a') && (c
<= 'z')) || ((c
>= 'A') && (c
<= 'Z')) || ((c
>= '0') && (c
<= '9')) || (c
== '_')))
529 TRACE("Wrong name %s\n", tmp
);
534 buf
->rem_bytes
-= pos
;
536 TRACE("Found name %s\n", tmp
);
537 strcpy((char*)buf
->value
, tmp
);
542 static BOOL
is_float(parse_buffer
* buf
)
550 while (!is_separator(c
= *(buf
->buffer
+pos
)))
552 if (!((!pos
&& (c
== '-')) || ((c
>= '0') && (c
<= '9')) || (!dot
&& (c
== '.'))))
561 buf
->rem_bytes
-= pos
;
563 sscanf(tmp
, "%f", &decimal
);
565 TRACE("Found float %s - %f\n", tmp
, decimal
);
567 *(float*)buf
->value
= decimal
;
572 static BOOL
is_integer(parse_buffer
* buf
)
579 while (!is_separator(c
= *(buf
->buffer
+pos
)))
581 if (!((c
>= '0') && (c
<= '9')))
588 buf
->rem_bytes
-= pos
;
590 sscanf(tmp
, "%d", &integer
);
592 TRACE("Found integer %s - %d\n", tmp
, integer
);
594 *(DWORD
*)buf
->value
= integer
;
599 static WORD
parse_TOKEN_dbg_opt(parse_buffer
* buf
, BOOL show_token
)
608 if (!read_bytes(buf
, &c
, 1))
610 /*TRACE("char = '%c'\n", is_space(c) ? ' ' : c);*/
611 if ((c
== '#') || (c
== '/'))
613 /* Handle comment (# or //) */
616 if (!read_bytes(buf
, &c
, 1))
624 if (!read_bytes(buf
, &c
, 1))
631 if (is_operator(c
) && (c
!= '<'))
633 token
= get_operator_token(c
);
646 if ((token
= get_keyword_token(buf
)))
656 token
= TOKEN_INTEGER
;
670 FIXME("Unrecognize element\n");
677 if (!read_bytes(buf
, &token
, 2))
687 if (!read_bytes(buf
, &count
, 4))
689 if (!read_bytes(buf
, strname
, count
))
692 /*TRACE("name = %s\n", strname);*/
694 strcpy((char*)buf
->value
, strname
);
701 if (!read_bytes(buf
, &integer
, 4))
703 /*TRACE("integer = %ld\n", integer);*/
705 *(DWORD
*)buf
->value
= integer
;
713 if (!read_bytes(buf
, &class_id
, 16))
715 sprintf(strguid
, CLSIDFMT
, class_id
.Data1
, class_id
.Data2
, class_id
.Data3
, class_id
.Data4
[0],
716 class_id
.Data4
[1], class_id
.Data4
[2], class_id
.Data4
[3], class_id
.Data4
[4], class_id
.Data4
[5],
717 class_id
.Data4
[6], class_id
.Data4
[7]);
718 /*TRACE("guid = {%s}\n", strguid);*/
720 *(GUID
*)buf
->value
= class_id
;
724 case TOKEN_INTEGER_LIST
:
725 case TOKEN_FLOAT_LIST
:
736 case TOKEN_SEMICOLON
:
763 static const char* get_primitive_string(WORD token
)
797 static inline WORD
parse_TOKEN(parse_buffer
* buf
)
799 return parse_TOKEN_dbg_opt(buf
, TRUE
);
802 static WORD
check_TOKEN(parse_buffer
* buf
)
808 parse_buffer save
= *buf
;
809 /*TRACE("check: ");*/
810 token
= parse_TOKEN_dbg_opt(buf
, FALSE
);
815 if (!read_bytes(buf
, &token
, 2))
827 static inline BOOL
is_primitive_type(WORD token
)
852 static BOOL
parse_template_option_info(parse_buffer
* buf
)
854 xtemplate
* cur_template
= &buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
];
856 if (check_TOKEN(buf
) == TOKEN_DOT
)
859 if (parse_TOKEN(buf
) != TOKEN_DOT
)
861 if (parse_TOKEN(buf
) != TOKEN_DOT
)
863 cur_template
->open
= TRUE
;
869 if (parse_TOKEN(buf
) != TOKEN_NAME
)
871 strcpy(cur_template
->childs
[cur_template
->nb_childs
], (char*)buf
->value
);
872 if (check_TOKEN(buf
) == TOKEN_GUID
)
874 cur_template
->nb_childs
++;
875 if (check_TOKEN(buf
) != TOKEN_COMMA
)
879 cur_template
->open
= FALSE
;
885 static BOOL
parse_template_members_list(parse_buffer
* buf
)
894 cur_member
= &buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].members
[idx_member
];
896 if (check_TOKEN(buf
) == TOKEN_ARRAY
)
902 if (check_TOKEN(buf
) == TOKEN_NAME
)
904 cur_member
->type
= parse_TOKEN(buf
);
905 cur_member
->idx_template
= 0;
906 while (cur_member
->idx_template
< buf
->pdxf
->nb_xtemplates
)
908 if (!strcmp((char*)buf
->value
, buf
->pdxf
->xtemplates
[cur_member
->idx_template
].name
))
910 cur_member
->idx_template
++;
912 if (cur_member
->idx_template
== buf
->pdxf
->nb_xtemplates
)
914 TRACE("Reference to a nonexistent template '%s'\n", (char*)buf
->value
);
918 else if (is_primitive_type(check_TOKEN(buf
)))
919 cur_member
->type
= parse_TOKEN(buf
);
923 if (parse_TOKEN(buf
) != TOKEN_NAME
)
925 strcpy(cur_member
->name
, (char*)buf
->value
);
929 while (check_TOKEN(buf
) == TOKEN_OBRACKET
)
933 FIXME("No support for multi-dimensional array yet\n");
937 if (check_TOKEN(buf
) == TOKEN_INTEGER
)
940 cur_member
->dim_fixed
[nb_dims
] = TRUE
;
941 cur_member
->dim_value
[nb_dims
] = *(DWORD
*)buf
->value
;
945 if (parse_TOKEN(buf
) != TOKEN_NAME
)
947 cur_member
->dim_fixed
[nb_dims
] = FALSE
;
948 /* Hack: Assume array size is specified in previous member */
949 cur_member
->dim_value
[nb_dims
] = idx_member
- 1;
951 if (parse_TOKEN(buf
) != TOKEN_CBRACKET
)
957 cur_member
->nb_dims
= nb_dims
;
959 if (parse_TOKEN(buf
) != TOKEN_SEMICOLON
)
965 buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].nb_members
= idx_member
;
970 static BOOL
parse_template_parts(parse_buffer
* buf
)
972 if (!parse_template_members_list(buf
))
974 if (check_TOKEN(buf
) == TOKEN_OBRACKET
)
977 if (!parse_template_option_info(buf
))
979 if (parse_TOKEN(buf
) != TOKEN_CBRACKET
)
986 static BOOL
parse_template(parse_buffer
* buf
)
988 if (parse_TOKEN(buf
) != TOKEN_TEMPLATE
)
990 if (parse_TOKEN(buf
) != TOKEN_NAME
)
992 strcpy(buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].name
, (char*)buf
->value
);
993 if (parse_TOKEN(buf
) != TOKEN_OBRACE
)
995 if (parse_TOKEN(buf
) != TOKEN_GUID
)
997 buf
->pdxf
->xtemplates
[buf
->pdxf
->nb_xtemplates
].class_id
= *(GUID
*)buf
->value
;
998 if (!parse_template_parts(buf
))
1000 if (parse_TOKEN(buf
) != TOKEN_CBRACE
)
1004 /* Go to the next template */
1005 while (buf
->rem_bytes
&& is_space(*buf
->buffer
))
1012 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
));
1013 buf
->pdxf
->nb_xtemplates
++;
1018 static HRESULT WINAPI
IDirectXFileImpl_RegisterTemplates(IDirectXFile
* iface
, LPVOID pvData
, DWORD cbSize
)
1020 IDirectXFileImpl
*This
= (IDirectXFileImpl
*)iface
;
1024 buf
.buffer
= (LPBYTE
)pvData
;
1025 buf
.rem_bytes
= cbSize
;
1029 TRACE("(%p/%p)->(%p,%d)\n", This
, iface
, pvData
, cbSize
);
1032 return DXFILEERR_BADVALUE
;
1035 return DXFILEERR_BADFILETYPE
;
1037 if (TRACE_ON(d3dxof
))
1040 memcpy(string
, pvData
, 16);
1042 TRACE("header = '%s'\n", string
);
1045 read_bytes(&buf
, &token_header
, 4);
1047 if (token_header
!= XOFFILE_FORMAT_MAGIC
)
1048 return DXFILEERR_BADFILETYPE
;
1050 read_bytes(&buf
, &token_header
, 4);
1052 if (token_header
!= XOFFILE_FORMAT_VERSION
)
1053 return DXFILEERR_BADFILEVERSION
;
1055 read_bytes(&buf
, &token_header
, 4);
1057 if ((token_header
!= XOFFILE_FORMAT_BINARY
) && (token_header
!= XOFFILE_FORMAT_TEXT
) && (token_header
!= XOFFILE_FORMAT_COMPRESSED
))
1058 return DXFILEERR_BADFILETYPE
;
1060 if (token_header
== XOFFILE_FORMAT_TEXT
)
1065 if (token_header
== XOFFILE_FORMAT_COMPRESSED
)
1067 FIXME("Compressed formats not supported yet\n");
1068 return DXFILEERR_BADVALUE
;
1071 read_bytes(&buf
, &token_header
, 4);
1073 if ((token_header
!= XOFFILE_FORMAT_FLOAT_BITS_32
) && (token_header
!= XOFFILE_FORMAT_FLOAT_BITS_64
))
1074 return DXFILEERR_BADFILEFLOATSIZE
;
1076 TRACE("Header is correct\n");
1078 while (buf
.rem_bytes
)
1080 if (!parse_template(&buf
))
1082 TRACE("Template is not correct\n");
1083 return DXFILEERR_BADVALUE
;
1087 TRACE("Template successfully parsed:\n");
1088 if (TRACE_ON(d3dxof
))
1093 i
= This
->nb_xtemplates
- 1;
1094 clsid
= &This
->xtemplates
[i
].class_id
;
1096 DPRINTF("template %s\n", This
->xtemplates
[i
].name
);
1098 DPRINTF(CLSIDFMT
"\n", clsid
->Data1
, clsid
->Data2
, clsid
->Data3
, clsid
->Data4
[0],
1099 clsid
->Data4
[1], clsid
->Data4
[2], clsid
->Data4
[3], clsid
->Data4
[4], clsid
->Data4
[5], clsid
->Data4
[6], clsid
->Data4
[7]);
1100 for (j
= 0; j
< This
->xtemplates
[i
].nb_members
; j
++)
1102 if (This
->xtemplates
[i
].members
[j
].nb_dims
)
1104 if (This
->xtemplates
[i
].members
[j
].type
== TOKEN_NAME
)
1105 DPRINTF("%s ", This
->xtemplates
[This
->xtemplates
[i
].members
[j
].idx_template
].name
);
1107 DPRINTF("%s ", get_primitive_string(This
->xtemplates
[i
].members
[j
].type
));
1108 DPRINTF("%s", This
->xtemplates
[i
].members
[j
].name
);
1109 for (k
= 0; k
< This
->xtemplates
[i
].members
[j
].nb_dims
; k
++)
1111 if (This
->xtemplates
[i
].members
[j
].dim_fixed
[k
])
1112 DPRINTF("[%d]", This
->xtemplates
[i
].members
[j
].dim_value
[k
]);
1114 DPRINTF("[%s]", This
->xtemplates
[i
].members
[This
->xtemplates
[i
].members
[j
].dim_value
[k
]].name
);
1118 if (This
->xtemplates
[i
].open
)
1120 else if (This
->xtemplates
[i
].nb_childs
)
1122 DPRINTF("[%s", This
->xtemplates
[i
].childs
[0]);
1123 for (j
= 1; j
< This
->xtemplates
[i
].nb_childs
; j
++)
1124 DPRINTF(",%s", This
->xtemplates
[i
].childs
[j
]);
1132 if (TRACE_ON(d3dxof
))
1135 TRACE("Registered templates (%d):\n", This
->nb_xtemplates
);
1136 for (i
= 0; i
< This
->nb_xtemplates
; i
++)
1137 DPRINTF("%s - %s\n", This
->xtemplates
[i
].name
, debugstr_guid(&This
->xtemplates
[i
].class_id
));
1143 static const IDirectXFileVtbl IDirectXFile_Vtbl
=
1145 IDirectXFileImpl_QueryInterface
,
1146 IDirectXFileImpl_AddRef
,
1147 IDirectXFileImpl_Release
,
1148 IDirectXFileImpl_CreateEnumObject
,
1149 IDirectXFileImpl_CreateSaveObject
,
1150 IDirectXFileImpl_RegisterTemplates
1153 HRESULT
IDirectXFileBinaryImpl_Create(IDirectXFileBinaryImpl
** ppObj
)
1155 IDirectXFileBinaryImpl
* object
;
1157 TRACE("(%p)\n", ppObj
);
1159 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileBinaryImpl
));
1161 object
->lpVtbl
.lpVtbl
= &IDirectXFileBinary_Vtbl
;
1169 /*** IUnknown methods ***/
1170 static HRESULT WINAPI
IDirectXFileBinaryImpl_QueryInterface(IDirectXFileBinary
* iface
, REFIID riid
, void** ppvObject
)
1172 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1174 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1176 if (IsEqualGUID(riid
, &IID_IUnknown
)
1177 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
1178 || IsEqualGUID(riid
, &IID_IDirectXFileBinary
))
1180 IClassFactory_AddRef(iface
);
1185 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1186 return E_NOINTERFACE
;
1189 static ULONG WINAPI
IDirectXFileBinaryImpl_AddRef(IDirectXFileBinary
* iface
)
1191 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1192 ULONG ref
= InterlockedIncrement(&This
->ref
);
1194 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
1199 static ULONG WINAPI
IDirectXFileBinaryImpl_Release(IDirectXFileBinary
* iface
)
1201 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1202 ULONG ref
= InterlockedDecrement(&This
->ref
);
1204 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
1207 HeapFree(GetProcessHeap(), 0, This
);
1212 /*** IDirectXFileObject methods ***/
1213 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetName(IDirectXFileBinary
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
1216 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1218 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
1220 return DXFILEERR_BADVALUE
;
1223 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetId(IDirectXFileBinary
* iface
, LPGUID pGuid
)
1225 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1227 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pGuid
);
1229 return DXFILEERR_BADVALUE
;
1232 /*** IDirectXFileBinary methods ***/
1233 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetSize(IDirectXFileBinary
* iface
, DWORD
* pcbSize
)
1235 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1237 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pcbSize
);
1239 return DXFILEERR_BADVALUE
;
1242 static HRESULT WINAPI
IDirectXFileBinaryImpl_GetMimeType(IDirectXFileBinary
* iface
, LPCSTR
* pszMimeType
)
1244 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1246 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pszMimeType
);
1248 return DXFILEERR_BADVALUE
;
1251 static HRESULT WINAPI
IDirectXFileBinaryImpl_Read(IDirectXFileBinary
* iface
, LPVOID pvData
, DWORD cbSize
, LPDWORD pcbRead
)
1253 IDirectXFileBinaryImpl
*This
= (IDirectXFileBinaryImpl
*)iface
;
1255 FIXME("(%p/%p)->(%p, %d, %p) stub!\n", This
, iface
, pvData
, cbSize
, pcbRead
);
1257 return DXFILEERR_BADVALUE
;
1260 static const IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl
=
1262 IDirectXFileBinaryImpl_QueryInterface
,
1263 IDirectXFileBinaryImpl_AddRef
,
1264 IDirectXFileBinaryImpl_Release
,
1265 IDirectXFileBinaryImpl_GetName
,
1266 IDirectXFileBinaryImpl_GetId
,
1267 IDirectXFileBinaryImpl_GetSize
,
1268 IDirectXFileBinaryImpl_GetMimeType
,
1269 IDirectXFileBinaryImpl_Read
1272 HRESULT
IDirectXFileDataImpl_Create(IDirectXFileDataImpl
** ppObj
)
1274 IDirectXFileDataImpl
* object
;
1276 TRACE("(%p)\n", ppObj
);
1278 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataImpl
));
1280 object
->lpVtbl
.lpVtbl
= &IDirectXFileData_Vtbl
;
1288 /*** IUnknown methods ***/
1289 static HRESULT WINAPI
IDirectXFileDataImpl_QueryInterface(IDirectXFileData
* iface
, REFIID riid
, void** ppvObject
)
1291 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1293 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1295 if (IsEqualGUID(riid
, &IID_IUnknown
)
1296 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
1297 || IsEqualGUID(riid
, &IID_IDirectXFileData
))
1299 IClassFactory_AddRef(iface
);
1304 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1305 return E_NOINTERFACE
;
1308 static ULONG WINAPI
IDirectXFileDataImpl_AddRef(IDirectXFileData
* iface
)
1310 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1311 ULONG ref
= InterlockedIncrement(&This
->ref
);
1313 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
1318 static ULONG WINAPI
IDirectXFileDataImpl_Release(IDirectXFileData
* iface
)
1320 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1321 ULONG ref
= InterlockedDecrement(&This
->ref
);
1323 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
1326 HeapFree(GetProcessHeap(), 0, This
);
1331 /*** IDirectXFileObject methods ***/
1332 static HRESULT WINAPI
IDirectXFileDataImpl_GetName(IDirectXFileData
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
1335 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1337 TRACE("(%p/%p)->(%p,%p)\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
1340 return DXFILEERR_BADVALUE
;
1342 strcpy(pstrNameBuf
, This
->pobj
->name
);
1347 static HRESULT WINAPI
IDirectXFileDataImpl_GetId(IDirectXFileData
* iface
, LPGUID pGuid
)
1349 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1351 TRACE("(%p/%p)->(%p)\n", This
, iface
, pGuid
);
1354 return DXFILEERR_BADVALUE
;
1356 memcpy(pGuid
, &This
->pobj
->class_id
, 16);
1361 /*** IDirectXFileData methods ***/
1362 static HRESULT WINAPI
IDirectXFileDataImpl_GetData(IDirectXFileData
* iface
, LPCSTR szMember
, DWORD
* pcbSize
, void** ppvData
)
1364 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1366 TRACE("(%p/%p)->(%s,%p,%p)\n", This
, iface
, szMember
, pcbSize
, ppvData
);
1368 if (!pcbSize
|| !ppvData
)
1369 return DXFILEERR_BADVALUE
;
1373 FIXME("Specifying a member is not supported yet!\n");
1374 return DXFILEERR_BADVALUE
;
1377 *pcbSize
= This
->pobj
->size
;
1378 *ppvData
= This
->pobj
->pdata
;
1383 static HRESULT WINAPI
IDirectXFileDataImpl_GetType(IDirectXFileData
* iface
, const GUID
** pguid
)
1385 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1388 TRACE("(%p/%p)->(%p)\n", This
, iface
, pguid
);
1391 return DXFILEERR_BADVALUE
;
1393 memcpy(&guid
, &This
->pobj
->type
, 16);
1399 static HRESULT WINAPI
IDirectXFileDataImpl_GetNextObject(IDirectXFileData
* iface
, LPDIRECTXFILEOBJECT
* ppChildObj
)
1401 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1403 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, ppChildObj
);
1405 if (This
->cur_enum_object
>= This
->pobj
->nb_childs
)
1406 return DXFILEERR_NOMOREOBJECTS
;
1408 return DXFILEERR_BADVALUE
;
1411 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataObject(IDirectXFileData
* iface
, LPDIRECTXFILEDATA pDataObj
)
1413 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1415 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pDataObj
);
1417 return DXFILEERR_BADVALUE
;
1420 static HRESULT WINAPI
IDirectXFileDataImpl_AddDataReference(IDirectXFileData
* iface
, LPCSTR szRef
, const GUID
* pguidRef
)
1422 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1424 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szRef
, pguidRef
);
1426 return DXFILEERR_BADVALUE
;
1429 static HRESULT WINAPI
IDirectXFileDataImpl_AddBinaryObject(IDirectXFileData
* iface
, LPCSTR szName
, const GUID
* pguid
, LPCSTR szMimeType
, LPVOID pvData
, DWORD cbSize
)
1431 IDirectXFileDataImpl
*This
= (IDirectXFileDataImpl
*)iface
;
1433 FIXME("(%p/%p)->(%s,%p,%s,%p,%d) stub!\n", This
, iface
, szName
, pguid
, szMimeType
, pvData
, cbSize
);
1435 return DXFILEERR_BADVALUE
;
1438 static const IDirectXFileDataVtbl IDirectXFileData_Vtbl
=
1440 IDirectXFileDataImpl_QueryInterface
,
1441 IDirectXFileDataImpl_AddRef
,
1442 IDirectXFileDataImpl_Release
,
1443 IDirectXFileDataImpl_GetName
,
1444 IDirectXFileDataImpl_GetId
,
1445 IDirectXFileDataImpl_GetData
,
1446 IDirectXFileDataImpl_GetType
,
1447 IDirectXFileDataImpl_GetNextObject
,
1448 IDirectXFileDataImpl_AddDataObject
,
1449 IDirectXFileDataImpl_AddDataReference
,
1450 IDirectXFileDataImpl_AddBinaryObject
1453 HRESULT
IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl
** ppObj
)
1455 IDirectXFileDataReferenceImpl
* object
;
1457 TRACE("(%p)\n", ppObj
);
1459 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileDataReferenceImpl
));
1461 object
->lpVtbl
.lpVtbl
= &IDirectXFileDataReference_Vtbl
;
1469 /*** IUnknown methods ***/
1470 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_QueryInterface(IDirectXFileDataReference
* iface
, REFIID riid
, void** ppvObject
)
1472 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
1474 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1476 if (IsEqualGUID(riid
, &IID_IUnknown
)
1477 || IsEqualGUID(riid
, &IID_IDirectXFileObject
)
1478 || IsEqualGUID(riid
, &IID_IDirectXFileDataReference
))
1480 IClassFactory_AddRef(iface
);
1485 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1486 return E_NOINTERFACE
;
1489 static ULONG WINAPI
IDirectXFileDataReferenceImpl_AddRef(IDirectXFileDataReference
* iface
)
1491 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
1492 ULONG ref
= InterlockedIncrement(&This
->ref
);
1494 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
1499 static ULONG WINAPI
IDirectXFileDataReferenceImpl_Release(IDirectXFileDataReference
* iface
)
1501 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
1502 ULONG ref
= InterlockedDecrement(&This
->ref
);
1504 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
1507 HeapFree(GetProcessHeap(), 0, This
);
1512 /*** IDirectXFileObject methods ***/
1513 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetName(IDirectXFileDataReference
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
1515 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
1517 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
1519 return DXFILEERR_BADVALUE
;
1522 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_GetId(IDirectXFileDataReference
* iface
, LPGUID pGuid
)
1524 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
1526 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pGuid
);
1528 return DXFILEERR_BADVALUE
;
1531 /*** IDirectXFileDataReference ***/
1532 static HRESULT WINAPI
IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
1534 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
1536 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, ppDataObj
);
1538 return DXFILEERR_BADVALUE
;
1541 static const IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl
=
1543 IDirectXFileDataReferenceImpl_QueryInterface
,
1544 IDirectXFileDataReferenceImpl_AddRef
,
1545 IDirectXFileDataReferenceImpl_Release
,
1546 IDirectXFileDataReferenceImpl_GetName
,
1547 IDirectXFileDataReferenceImpl_GetId
,
1548 IDirectXFileDataReferenceImpl_Resolve
1551 HRESULT
IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl
** ppObj
)
1553 IDirectXFileEnumObjectImpl
* object
;
1555 TRACE("(%p)\n", ppObj
);
1557 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileEnumObjectImpl
));
1559 object
->lpVtbl
.lpVtbl
= &IDirectXFileEnumObject_Vtbl
;
1567 /*** IUnknown methods ***/
1568 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_QueryInterface(IDirectXFileEnumObject
* iface
, REFIID riid
, void** ppvObject
)
1570 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1572 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1574 if (IsEqualGUID(riid
, &IID_IUnknown
)
1575 || IsEqualGUID(riid
, &IID_IDirectXFileEnumObject
))
1577 IClassFactory_AddRef(iface
);
1582 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1583 return E_NOINTERFACE
;
1586 static ULONG WINAPI
IDirectXFileEnumObjectImpl_AddRef(IDirectXFileEnumObject
* iface
)
1588 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1589 ULONG ref
= InterlockedIncrement(&This
->ref
);
1591 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
1596 static ULONG WINAPI
IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject
* iface
)
1598 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1599 ULONG ref
= InterlockedDecrement(&This
->ref
);
1601 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
1604 HeapFree(GetProcessHeap(), 0, This
);
1609 static BOOL
parse_object_members_list(parse_buffer
* buf
)
1613 xtemplate
* pt
= buf
->pxt
[buf
->level
];
1614 DWORD last_dword
= 0;
1616 for (i
= 0; i
< pt
->nb_members
; i
++)
1620 if (pt
->members
[i
].nb_dims
> 1)
1622 FIXME("Arrays with dimension > 1 not yet supported\n");
1625 else if (pt
->members
[i
].nb_dims
)
1627 if (!pt
->members
[i
].dim_fixed
[0])
1631 FIXME("Array with variable must be preceded by the size\n");
1634 nb_elems
= last_dword
;
1635 /*FIXME("Arrays with variable size not yet supported\n");
1639 nb_elems
= pt
->members
[i
].dim_value
[0];
1644 for (k
= 0; k
< nb_elems
; k
++)
1648 if (parse_TOKEN(buf
) != TOKEN_COMMA
)
1652 if (pt
->members
[i
].type
== TOKEN_NAME
)
1656 TRACE("Found suboject %s\n", buf
->pdxf
->xtemplates
[pt
->members
[i
].idx_template
].name
);
1658 /* To do template lookup */
1659 for (j
= 0; j
< buf
->pdxf
->nb_xtemplates
; j
++)
1661 if (!strcmp(buf
->pdxf
->xtemplates
[pt
->members
[i
].idx_template
].name
, buf
->pdxf
->xtemplates
[j
].name
))
1663 buf
->pxt
[buf
->level
] = &buf
->pdxf
->xtemplates
[j
];
1667 if (j
== buf
->pdxf
->nb_xtemplates
)
1669 FIXME("Unknown template %s\n", (char*)buf
->value
);
1673 TRACE("Enter %s\n", buf
->pdxf
->xtemplates
[pt
->members
[i
].idx_template
].name
);
1674 if (!parse_object_parts(buf
, FALSE
))
1680 /*if (parse_TOKEN(buf) != TOKEN_SEMICOLON)
1685 token
= check_TOKEN(buf
);
1686 if (token
== TOKEN_INTEGER
)
1689 last_dword
= *(DWORD
*)buf
->value
;
1690 TRACE("%s = %d\n", pt
->members
[i
].name
, *(DWORD
*)buf
->value
);
1691 /* Assume larger size */
1692 if ((buf
->cur_pdata
- buf
->pxo
->pdata
+ 4) > MAX_DATA_SIZE
)
1694 WARN("Buffer too small\n");
1697 if (pt
->members
[i
].type
== TOKEN_WORD
)
1699 *(((WORD
*)(buf
->cur_pdata
))) = (WORD
)(*(DWORD
*)buf
->value
);
1700 buf
->cur_pdata
+= 2;
1702 else if (pt
->members
[i
].type
== TOKEN_DWORD
)
1704 *(((DWORD
*)(buf
->cur_pdata
))) = (DWORD
)(*(DWORD
*)buf
->value
);
1705 buf
->cur_pdata
+= 4;
1709 FIXME("Token %d not supported\n", pt
->members
[i
].type
);
1713 else if (token
== TOKEN_FLOAT
)
1716 TRACE("%s = %f\n", pt
->members
[i
].name
, *(float*)buf
->value
);
1717 /* Assume larger size */
1718 if ((buf
->cur_pdata
- buf
->pxo
->pdata
+ 4) > MAX_DATA_SIZE
)
1720 WARN("Buffer too small\n");
1723 if (pt
->members
[i
].type
== TOKEN_FLOAT
)
1725 *(((float*)(buf
->cur_pdata
))) = (float)(*(float*)buf
->value
);
1726 buf
->cur_pdata
+= 4;
1730 FIXME("Token %d not supported\n", pt
->members
[i
].type
);
1739 token
= parse_TOKEN(buf
);
1740 if (token
!= TOKEN_SEMICOLON
)
1742 /* Allow comma instead of semicolon in some specific cases */
1743 if (!((token
== TOKEN_COMMA
) && ((i
+1) < pt
->nb_members
) && (pt
->members
[i
].type
== pt
->members
[i
+1].type
)
1744 && (!pt
->members
[i
].nb_dims
) && (!pt
->members
[i
+1].nb_dims
)))
1752 static BOOL
parse_object_parts(parse_buffer
* buf
, BOOL allow_optional
)
1754 if (!parse_object_members_list(buf
))
1759 /* Skip trailing semicolon */
1760 while (check_TOKEN(buf
) == TOKEN_SEMICOLON
)
1765 if (check_TOKEN(buf
) == TOKEN_OBRACE
)
1768 if (parse_TOKEN(buf
) != TOKEN_NAME
)
1770 if (parse_TOKEN(buf
) != TOKEN_CBRACE
)
1773 else if (check_TOKEN(buf
) == TOKEN_NAME
)
1775 TRACE("Enter optional %s\n", (char*)buf
->value
);
1777 if (!parse_object(buf
))
1792 static BOOL
parse_object(parse_buffer
* buf
)
1796 if (parse_TOKEN(buf
) != TOKEN_NAME
)
1799 /* To do template lookup */
1800 for (i
= 0; i
< buf
->pdxf
->nb_xtemplates
; i
++)
1802 if (!strcmp((char*)buf
->value
, buf
->pdxf
->xtemplates
[i
].name
))
1804 buf
->pxt
[buf
->level
] = &buf
->pdxf
->xtemplates
[i
];
1805 memcpy(&buf
->pxo
->type
, &buf
->pdxf
->xtemplates
[i
].class_id
, 16);
1809 if (i
== buf
->pdxf
->nb_xtemplates
)
1811 FIXME("Unknown template %s\n", (char*)buf
->value
);
1815 if (check_TOKEN(buf
) == TOKEN_NAME
)
1818 strcpy(buf
->pxo
->name
, (char*)buf
->value
);
1821 buf
->pxo
->name
[0] = 0;
1823 if (parse_TOKEN(buf
) != TOKEN_OBRACE
)
1825 if (check_TOKEN(buf
) == TOKEN_GUID
)
1828 memcpy(&buf
->pxo
->class_id
, buf
->value
, 16);
1831 memset(&buf
->pxo
->class_id
, 0, 16);
1833 if (!parse_object_parts(buf
, TRUE
))
1835 if (parse_TOKEN(buf
) != TOKEN_CBRACE
)
1840 /* Go to the next object */
1841 while (buf
->rem_bytes
&& is_space(*buf
->buffer
))
1851 /*** IDirectXFileEnumObject methods ***/
1852 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject
* iface
, LPDIRECTXFILEDATA
* ppDataObj
)
1854 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1855 IDirectXFileDataImpl
* object
;
1858 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, ppDataObj
);
1860 /*printf("%d\n", This->buf.rem_bytes);*/
1862 if (!This
->buf
.rem_bytes
)
1863 return DXFILEERR_NOMOREOBJECTS
;
1865 hr
= IDirectXFileDataImpl_Create(&object
);
1869 This
->buf
.pxo
= &This
->xobjects
[This
->nb_xobjects
][This
->buf
.cur_subobject
];
1870 TRACE("Start %d %d\n", This
->nb_xobjects
, This
->buf
.cur_subobject
);
1872 This
->buf
.pxo
->pdata
= HeapAlloc(GetProcessHeap(), 0, MAX_DATA_SIZE
);
1873 if (!This
->buf
.pxo
->pdata
)
1875 WARN("Out of memory\n");
1876 return DXFILEERR_BADALLOC
;
1878 This
->buf
.cur_pdata
= This
->buf
.pxo
->pdata
;
1879 This
->buf
.level
= 0;
1881 This
->buf
.pxo
->pdata
= This
->buf
.cur_pdata
;
1883 if (!parse_object(&This
->buf
))
1885 TRACE("Object is not correct\n");
1886 HeapFree(GetProcessHeap(), 0, This
->buf
.pxo
->pdata
);
1887 return DXFILEERR_PARSEERROR
;
1890 This
->buf
.pxo
->size
= This
->buf
.cur_pdata
- This
->buf
.pxo
->pdata
;
1892 object
->pobj
= This
->buf
.pxo
;
1894 *ppDataObj
= (LPDIRECTXFILEDATA
)object
;
1899 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectById(IDirectXFileEnumObject
* iface
, REFGUID rguid
, LPDIRECTXFILEDATA
* ppDataObj
)
1901 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1903 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, rguid
, ppDataObj
);
1905 return DXFILEERR_BADVALUE
;
1908 static HRESULT WINAPI
IDirectXFileEnumObjectImpl_GetDataObjectByName(IDirectXFileEnumObject
* iface
, LPCSTR szName
, LPDIRECTXFILEDATA
* ppDataObj
)
1910 IDirectXFileEnumObjectImpl
*This
= (IDirectXFileEnumObjectImpl
*)iface
;
1912 FIXME("(%p/%p)->(%s,%p) stub!\n", This
, iface
, szName
, ppDataObj
);
1914 return DXFILEERR_BADVALUE
;
1917 static const IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl
=
1919 IDirectXFileEnumObjectImpl_QueryInterface
,
1920 IDirectXFileEnumObjectImpl_AddRef
,
1921 IDirectXFileEnumObjectImpl_Release
,
1922 IDirectXFileEnumObjectImpl_GetNextDataObject
,
1923 IDirectXFileEnumObjectImpl_GetDataObjectById
,
1924 IDirectXFileEnumObjectImpl_GetDataObjectByName
1927 HRESULT
IDirectXFileObjectImpl_Create(IDirectXFileObjectImpl
** ppObj
)
1929 IDirectXFileObjectImpl
* object
;
1931 TRACE("(%p)\n", ppObj
);
1933 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileObjectImpl
));
1935 object
->lpVtbl
.lpVtbl
= &IDirectXFileObject_Vtbl
;
1943 /*** IUnknown methods ***/
1944 static HRESULT WINAPI
IDirectXFileObjectImpl_QueryInterface(IDirectXFileObject
* iface
, REFIID riid
, void** ppvObject
)
1946 IDirectXFileObjectImpl
*This
= (IDirectXFileObjectImpl
*)iface
;
1948 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
1950 if (IsEqualGUID(riid
, &IID_IUnknown
)
1951 || IsEqualGUID(riid
, &IID_IDirectXFileObject
))
1953 IClassFactory_AddRef(iface
);
1958 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
1959 return E_NOINTERFACE
;
1962 static ULONG WINAPI
IDirectXFileObjectImpl_AddRef(IDirectXFileObject
* iface
)
1964 IDirectXFileObjectImpl
*This
= (IDirectXFileObjectImpl
*)iface
;
1965 ULONG ref
= InterlockedIncrement(&This
->ref
);
1967 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
1972 static ULONG WINAPI
IDirectXFileObjectImpl_Release(IDirectXFileObject
* iface
)
1974 IDirectXFileObjectImpl
*This
= (IDirectXFileObjectImpl
*)iface
;
1975 ULONG ref
= InterlockedDecrement(&This
->ref
);
1977 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
1980 HeapFree(GetProcessHeap(), 0, This
);
1985 /*** IDirectXFileObject methods ***/
1986 static HRESULT WINAPI
IDirectXFileObjectImpl_GetName(IDirectXFileObject
* iface
, LPSTR pstrNameBuf
, LPDWORD pdwBufLen
)
1988 IDirectXFileDataReferenceImpl
*This
= (IDirectXFileDataReferenceImpl
*)iface
;
1990 FIXME("(%p/%p)->(%p,%p) stub!\n", This
, iface
, pstrNameBuf
, pdwBufLen
);
1992 return DXFILEERR_BADVALUE
;
1995 static HRESULT WINAPI
IDirectXFileObjectImpl_GetId(IDirectXFileObject
* iface
, LPGUID pGuid
)
1997 IDirectXFileObjectImpl
*This
= (IDirectXFileObjectImpl
*)iface
;
1999 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, pGuid
);
2001 return DXFILEERR_BADVALUE
;
2004 static const IDirectXFileObjectVtbl IDirectXFileObject_Vtbl
=
2006 IDirectXFileObjectImpl_QueryInterface
,
2007 IDirectXFileObjectImpl_AddRef
,
2008 IDirectXFileObjectImpl_Release
,
2009 IDirectXFileObjectImpl_GetName
,
2010 IDirectXFileObjectImpl_GetId
2013 HRESULT
IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl
** ppObj
)
2015 IDirectXFileSaveObjectImpl
* object
;
2017 TRACE("(%p)\n", ppObj
);
2019 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectXFileSaveObjectImpl
));
2021 object
->lpVtbl
.lpVtbl
= &IDirectXFileSaveObject_Vtbl
;
2029 /*** IUnknown methods ***/
2030 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_QueryInterface(IDirectXFileSaveObject
* iface
, REFIID riid
, void** ppvObject
)
2032 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
2034 TRACE("(%p/%p)->(%s,%p)\n", iface
, This
, debugstr_guid(riid
), ppvObject
);
2036 if (IsEqualGUID(riid
, &IID_IUnknown
)
2037 || IsEqualGUID(riid
, &IID_IDirectXFileSaveObject
))
2039 IClassFactory_AddRef(iface
);
2044 ERR("(%p)->(%s,%p),not found\n",This
,debugstr_guid(riid
),ppvObject
);
2045 return E_NOINTERFACE
;
2048 static ULONG WINAPI
IDirectXFileSaveObjectImpl_AddRef(IDirectXFileSaveObject
* iface
)
2050 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
2051 ULONG ref
= InterlockedIncrement(&This
->ref
);
2053 TRACE("(%p/%p): AddRef from %d\n", iface
, This
, ref
- 1);
2058 static ULONG WINAPI
IDirectXFileSaveObjectImpl_Release(IDirectXFileSaveObject
* iface
)
2060 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
2061 ULONG ref
= InterlockedDecrement(&This
->ref
);
2063 TRACE("(%p/%p): ReleaseRef to %d\n", iface
, This
, ref
);
2066 HeapFree(GetProcessHeap(), 0, This
);
2071 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveTemplates(IDirectXFileSaveObject
* iface
, DWORD cTemplates
, const GUID
** ppguidTemplates
)
2073 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
2075 FIXME("(%p/%p)->(%d,%p) stub!\n", This
, iface
, cTemplates
, ppguidTemplates
);
2077 return DXFILEERR_BADVALUE
;
2080 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_CreateDataObject(IDirectXFileSaveObject
* iface
, REFGUID rguidTemplate
, LPCSTR szName
, const GUID
* pguid
, DWORD cbSize
, LPVOID pvData
, LPDIRECTXFILEDATA
* ppDataObj
)
2082 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
2084 FIXME("(%p/%p)->(%p,%s,%p,%d,%p,%p) stub!\n", This
, iface
, rguidTemplate
, szName
, pguid
, cbSize
, pvData
, ppDataObj
);
2086 return DXFILEERR_BADVALUE
;
2089 static HRESULT WINAPI
IDirectXFileSaveObjectImpl_SaveData(IDirectXFileSaveObject
* iface
, LPDIRECTXFILEDATA ppDataObj
)
2091 IDirectXFileSaveObjectImpl
*This
= (IDirectXFileSaveObjectImpl
*)iface
;
2093 FIXME("(%p/%p)->(%p) stub!\n", This
, iface
, ppDataObj
);
2095 return DXFILEERR_BADVALUE
;
2098 static const IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl
=
2100 IDirectXFileSaveObjectImpl_QueryInterface
,
2101 IDirectXFileSaveObjectImpl_AddRef
,
2102 IDirectXFileSaveObjectImpl_Release
,
2103 IDirectXFileSaveObjectImpl_SaveTemplates
,
2104 IDirectXFileSaveObjectImpl_CreateDataObject
,
2105 IDirectXFileSaveObjectImpl_SaveData