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);
95 static const char* get_primitive_string(WORD token);
97 static void dump_template(xtemplate* templates_array, xtemplate* ptemplate)
102 clsid = &ptemplate->class_id;
104 DPRINTF("template %s\n", ptemplate->name);
106 DPRINTF(CLSIDFMT "\n", clsid->Data1, clsid->Data2, clsid->Data3, clsid->Data4[0],
107 clsid->Data4[1], clsid->Data4[2], clsid->Data4[3], clsid->Data4[4], clsid->Data4[5], clsid->Data4[6], clsid->Data4[7]);
108 for (j = 0; j < ptemplate->nb_members; j++)
110 if (ptemplate->members[j].nb_dims)
112 if (ptemplate->members[j].type == TOKEN_NAME)
113 DPRINTF("%s ", templates_array[ptemplate->members[j].idx_template].name);
115 DPRINTF("%s ", get_primitive_string(ptemplate->members[j].type));
116 DPRINTF("%s", ptemplate->members[j].name);
117 for (k = 0; k < ptemplate->members[j].nb_dims; k++)
119 if (ptemplate->members[j].dim_fixed[k])
120 DPRINTF("[%d]", ptemplate->members[j].dim_value[k]);
122 DPRINTF("[%s]", ptemplate->members[ptemplate->members[j].dim_value[k]].name);
128 else if (ptemplate->nb_childs)
130 DPRINTF("[%s", ptemplate->childs[0]);
131 for (j = 1; j < ptemplate->nb_childs; j++)
132 DPRINTF(",%s", ptemplate->childs[j]);
138 HRESULT IDirectXFileImpl_Create(IUnknown* pUnkOuter, LPVOID* ppObj)
140 IDirectXFileImpl* object;
142 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
144 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileImpl));
146 object->lpVtbl.lpVtbl = &IDirectXFile_Vtbl;
154 /*** IUnknown methods ***/
155 static HRESULT WINAPI IDirectXFileImpl_QueryInterface(IDirectXFile* iface, REFIID riid, void** ppvObject)
157 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
159 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
161 if (IsEqualGUID(riid, &IID_IUnknown)
162 || IsEqualGUID(riid, &IID_IDirectXFile))
164 IClassFactory_AddRef(iface);
169 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
170 return E_NOINTERFACE;
173 static ULONG WINAPI IDirectXFileImpl_AddRef(IDirectXFile* iface)
175 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
176 ULONG ref = InterlockedIncrement(&This->ref);
178 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
183 static ULONG WINAPI IDirectXFileImpl_Release(IDirectXFile* iface)
185 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
186 ULONG ref = InterlockedDecrement(&This->ref);
188 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
191 HeapFree(GetProcessHeap(), 0, This);
196 /*** IDirectXFile methods ***/
197 static HRESULT WINAPI IDirectXFileImpl_CreateEnumObject(IDirectXFile* iface, LPVOID pvSource, DXFILELOADOPTIONS dwLoadOptions, LPDIRECTXFILEENUMOBJECT* ppEnumObj)
199 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
200 IDirectXFileEnumObjectImpl* object;
204 HANDLE hFile = INVALID_HANDLE_VALUE;
206 TRACE("(%p/%p)->(%p,%x,%p)\n", This, iface, pvSource, dwLoadOptions, ppEnumObj);
209 return DXFILEERR_BADVALUE;
211 if (dwLoadOptions == DXFILELOAD_FROMFILE)
213 TRACE("Open source file '%s'\n", (char*)pvSource);
215 hFile = CreateFileA((char*)pvSource, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
216 if (hFile == INVALID_HANDLE_VALUE)
218 TRACE("File '%s' not found\n", (char*)pvSource);
219 return DXFILEERR_FILENOTFOUND;
222 if (!ReadFile(hFile, header, 16, &size, NULL))
224 hr = DXFILEERR_BADVALUE;
230 hr = DXFILEERR_BADFILETYPE;
234 if (TRACE_ON(d3dxof))
237 memcpy(string, header, 16);
239 TRACE("header = '%s'\n", string);
244 FIXME("Source type %d is not handled yet\n", dwLoadOptions);
245 hr = DXFILEERR_NOTDONEYET;
249 if (header[0] != XOFFILE_FORMAT_MAGIC)
251 hr = DXFILEERR_BADFILETYPE;
255 if (header[1] != XOFFILE_FORMAT_VERSION)
257 hr = DXFILEERR_BADFILEVERSION;
261 if ((header[2] != XOFFILE_FORMAT_BINARY) && (header[2] != XOFFILE_FORMAT_TEXT) && (header[2] != XOFFILE_FORMAT_COMPRESSED))
263 hr = DXFILEERR_BADFILETYPE;
267 if (header[2] == XOFFILE_FORMAT_BINARY)
269 FIXME("Binary format not supported yet\n");
270 hr = DXFILEERR_NOTDONEYET;
274 if (header[2] == XOFFILE_FORMAT_COMPRESSED)
276 FIXME("Compressed formats not supported yet\n");
277 hr = DXFILEERR_BADVALUE;
281 if ((header[3] != XOFFILE_FORMAT_FLOAT_BITS_32) && (header[3] != XOFFILE_FORMAT_FLOAT_BITS_64))
283 hr = DXFILEERR_BADFILEFLOATSIZE;
287 TRACE("Header is correct\n");
289 hr = IDirectXFileEnumObjectImpl_Create(&object);
293 object->source = dwLoadOptions;
294 object->hFile = hFile;
295 object->pDirectXFile = This;
296 object->buf.pdxf = This;
297 object->buf.txt = TRUE;
298 object->buf.token_present = FALSE;
299 object->buf.cur_subobject = 0;
301 object->buf.buffer = HeapAlloc(GetProcessHeap(), 0, MAX_INPUT_SIZE+1);
302 if (!object->buf.buffer)
304 WARN("Out of memory\n");
305 hr = DXFILEERR_BADALLOC;
309 ReadFile(hFile, object->buf.buffer, MAX_INPUT_SIZE+1, &object->buf.rem_bytes, NULL);
310 if (object->buf.rem_bytes > MAX_INPUT_SIZE)
312 FIXME("File size > %d not supported yet\n", MAX_INPUT_SIZE);
313 HeapFree(GetProcessHeap(), 0, object->buf.buffer);
314 hr = DXFILEERR_PARSEERROR;
317 TRACE("Read %d bytes\n", object->buf.rem_bytes);
319 *ppEnumObj = (LPDIRECTXFILEENUMOBJECT)object;
324 if (hFile != INVALID_HANDLE_VALUE)
331 static HRESULT WINAPI IDirectXFileImpl_CreateSaveObject(IDirectXFile* iface, LPCSTR szFileName, DXFILEFORMAT dwFileFormat, LPDIRECTXFILESAVEOBJECT* ppSaveObj)
333 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
335 FIXME("(%p/%p)->(%s,%x,%p) stub!\n", This, iface, szFileName, dwFileFormat, ppSaveObj);
337 return DXFILEERR_BADVALUE;
340 static BOOL read_bytes(parse_buffer * buf, LPVOID data, DWORD size)
342 if (buf->rem_bytes < size)
344 memcpy(data, buf->buffer, size);
346 buf->rem_bytes -= size;
350 static void dump_TOKEN(WORD token)
352 #define DUMP_TOKEN(t) case t: TRACE(#t "\n"); break
355 DUMP_TOKEN(TOKEN_NAME);
356 DUMP_TOKEN(TOKEN_STRING);
357 DUMP_TOKEN(TOKEN_INTEGER);
358 DUMP_TOKEN(TOKEN_GUID);
359 DUMP_TOKEN(TOKEN_INTEGER_LIST);
360 DUMP_TOKEN(TOKEN_FLOAT_LIST);
361 DUMP_TOKEN(TOKEN_OBRACE);
362 DUMP_TOKEN(TOKEN_CBRACE);
363 DUMP_TOKEN(TOKEN_OPAREN);
364 DUMP_TOKEN(TOKEN_CPAREN);
365 DUMP_TOKEN(TOKEN_OBRACKET);
366 DUMP_TOKEN(TOKEN_CBRACKET);
367 DUMP_TOKEN(TOKEN_OANGLE);
368 DUMP_TOKEN(TOKEN_CANGLE);
369 DUMP_TOKEN(TOKEN_DOT);
370 DUMP_TOKEN(TOKEN_COMMA);
371 DUMP_TOKEN(TOKEN_SEMICOLON);
372 DUMP_TOKEN(TOKEN_TEMPLATE);
373 DUMP_TOKEN(TOKEN_WORD);
374 DUMP_TOKEN(TOKEN_DWORD);
375 DUMP_TOKEN(TOKEN_FLOAT);
376 DUMP_TOKEN(TOKEN_DOUBLE);
377 DUMP_TOKEN(TOKEN_CHAR);
378 DUMP_TOKEN(TOKEN_UCHAR);
379 DUMP_TOKEN(TOKEN_SWORD);
380 DUMP_TOKEN(TOKEN_SDWORD);
381 DUMP_TOKEN(TOKEN_VOID);
382 DUMP_TOKEN(TOKEN_LPSTR);
383 DUMP_TOKEN(TOKEN_UNICODE);
384 DUMP_TOKEN(TOKEN_CSTRING);
385 DUMP_TOKEN(TOKEN_ARRAY);
388 TRACE("Unknown token %d\n", token);
394 static BOOL is_space(char c)
408 static BOOL is_operator(char c)
427 static inline BOOL is_separator(char c)
429 return is_space(c) || is_operator(c);
432 static WORD get_operator_token(char c)
441 return TOKEN_OBRACKET;
443 return TOKEN_CBRACKET;
455 return TOKEN_SEMICOLON;
460 static BOOL is_keyword(parse_buffer* buf, const char* keyword)
462 DWORD len = strlen(keyword);
463 if (!strncmp((char*)buf->buffer, keyword,len) && is_separator(*(buf->buffer+len)))
466 buf->rem_bytes -= len;
472 static WORD get_keyword_token(parse_buffer* buf)
474 if (is_keyword(buf, "template"))
475 return TOKEN_TEMPLATE;
476 if (is_keyword(buf, "WORD"))
478 if (is_keyword(buf, "DWORD"))
480 if (is_keyword(buf, "FLOAT"))
482 if (is_keyword(buf, "DOUBLE"))
484 if (is_keyword(buf, "CHAR"))
486 if (is_keyword(buf, "UCHAR"))
488 if (is_keyword(buf, "SWORD"))
490 if (is_keyword(buf, "SDWORD"))
492 if (is_keyword(buf, "VOID"))
494 if (is_keyword(buf, "STRING"))
496 if (is_keyword(buf, "UNICODE"))
497 return TOKEN_UNICODE;
498 if (is_keyword(buf, "CSTRING"))
499 return TOKEN_CSTRING;
500 if (is_keyword(buf, "array"))
506 static BOOL is_guid(parse_buffer* buf)
514 if (*buf->buffer != '<')
517 while (*(buf->buffer+pos) != '>')
519 tmp[pos] = *(buf->buffer+pos);
524 if (pos != 38 /* <+36+> */)
526 TRACE("Wrong guid %s (%d)\n", tmp, pos);
530 buf->rem_bytes -= pos;
532 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);
535 TRACE("Wrong guid %s (%d)\n", tmp, pos);
538 TRACE("Found guid %s (%d)\n", tmp, pos);
540 class_id.Data2 = tab[0];
541 class_id.Data3 = tab[1];
542 class_id.Data4[0] = tab[2];
543 class_id.Data4[1] = tab[3];
544 class_id.Data4[2] = tab[4];
545 class_id.Data4[3] = tab[5];
546 class_id.Data4[4] = tab[6];
547 class_id.Data4[5] = tab[7];
548 class_id.Data4[6] = tab[8];
549 class_id.Data4[7] = tab[9];
551 *(GUID*)buf->value = class_id;
556 static BOOL is_name(parse_buffer* buf)
562 while (!is_separator(c = *(buf->buffer+pos)))
564 if (!(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9')) || (c == '_')))
572 TRACE("Wrong name %s\n", tmp);
577 buf->rem_bytes -= pos;
579 TRACE("Found name %s\n", tmp);
580 strcpy((char*)buf->value, tmp);
585 static BOOL is_float(parse_buffer* buf)
593 while (!is_separator(c = *(buf->buffer+pos)))
595 if (!((!pos && (c == '-')) || ((c >= '0') && (c <= '9')) || (!dot && (c == '.'))))
604 buf->rem_bytes -= pos;
606 sscanf(tmp, "%f", &decimal);
608 TRACE("Found float %s - %f\n", tmp, decimal);
610 *(float*)buf->value = decimal;
615 static BOOL is_integer(parse_buffer* buf)
622 while (!is_separator(c = *(buf->buffer+pos)))
624 if (!((c >= '0') && (c <= '9')))
631 buf->rem_bytes -= pos;
633 sscanf(tmp, "%d", &integer);
635 TRACE("Found integer %s - %d\n", tmp, integer);
637 *(DWORD*)buf->value = integer;
642 static BOOL is_string(parse_buffer* buf)
649 if (*buf->buffer != '"')
653 while (!is_separator(c = *(buf->buffer+pos)) && (pos < 32))
666 TRACE("Wrong string %s\n", tmp);
671 buf->rem_bytes -= pos;
673 TRACE("Found string %s\n", tmp);
674 strcpy((char*)buf->value, tmp);
679 static WORD parse_TOKEN(parse_buffer * buf)
688 if (!read_bytes(buf, &c, 1))
690 /*TRACE("char = '%c'\n", is_space(c) ? ' ' : c);*/
691 if ((c == '#') || (c == '/'))
693 /* Handle comment (# or //) */
696 if (!read_bytes(buf, &c, 1))
704 if (!read_bytes(buf, &c, 1))
711 if (is_operator(c) && (c != '<'))
713 token = get_operator_token(c);
726 if ((token = get_keyword_token(buf)))
736 token = TOKEN_INTEGER;
755 FIXME("Unrecognize element\n");
762 if (!read_bytes(buf, &token, 2))
772 if (!read_bytes(buf, &count, 4))
774 if (!read_bytes(buf, strname, count))
777 /*TRACE("name = %s\n", strname);*/
779 strcpy((char*)buf->value, strname);
786 if (!read_bytes(buf, &integer, 4))
788 /*TRACE("integer = %ld\n", integer);*/
790 *(DWORD*)buf->value = integer;
798 if (!read_bytes(buf, &class_id, 16))
800 sprintf(strguid, CLSIDFMT, class_id.Data1, class_id.Data2, class_id.Data3, class_id.Data4[0],
801 class_id.Data4[1], class_id.Data4[2], class_id.Data4[3], class_id.Data4[4], class_id.Data4[5],
802 class_id.Data4[6], class_id.Data4[7]);
803 /*TRACE("guid = {%s}\n", strguid);*/
805 *(GUID*)buf->value = class_id;
809 case TOKEN_INTEGER_LIST:
810 case TOKEN_FLOAT_LIST:
821 case TOKEN_SEMICOLON:
847 static const char* get_primitive_string(WORD token)
881 static WORD get_TOKEN(parse_buffer * buf)
883 if (buf->token_present)
885 buf->token_present = FALSE;
886 return buf->current_token;
889 buf->current_token = parse_TOKEN(buf);
891 return buf->current_token;
894 static WORD check_TOKEN(parse_buffer * buf)
896 if (buf->token_present)
897 return buf->current_token;
899 buf->current_token = parse_TOKEN(buf);
900 buf->token_present = TRUE;
902 return buf->current_token;
905 static inline BOOL is_primitive_type(WORD token)
930 static BOOL parse_template_option_info(parse_buffer * buf)
932 xtemplate* cur_template = &buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates];
934 if (check_TOKEN(buf) == TOKEN_DOT)
937 if (get_TOKEN(buf) != TOKEN_DOT)
939 if (get_TOKEN(buf) != TOKEN_DOT)
941 cur_template->open = TRUE;
947 if (get_TOKEN(buf) != TOKEN_NAME)
949 strcpy(cur_template->childs[cur_template->nb_childs], (char*)buf->value);
950 if (check_TOKEN(buf) == TOKEN_GUID)
952 cur_template->nb_childs++;
953 if (check_TOKEN(buf) != TOKEN_COMMA)
957 cur_template->open = FALSE;
963 static BOOL parse_template_members_list(parse_buffer * buf)
972 cur_member = &buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].members[idx_member];
974 if (check_TOKEN(buf) == TOKEN_ARRAY)
980 if (check_TOKEN(buf) == TOKEN_NAME)
982 cur_member->type = get_TOKEN(buf);
983 cur_member->idx_template = 0;
984 while (cur_member->idx_template < buf->pdxf->nb_xtemplates)
986 if (!strcmp((char*)buf->value, buf->pdxf->xtemplates[cur_member->idx_template].name))
988 cur_member->idx_template++;
990 if (cur_member->idx_template == buf->pdxf->nb_xtemplates)
992 TRACE("Reference to a nonexistent template '%s'\n", (char*)buf->value);
996 else if (is_primitive_type(check_TOKEN(buf)))
997 cur_member->type = get_TOKEN(buf);
1001 if (get_TOKEN(buf) != TOKEN_NAME)
1003 strcpy(cur_member->name, (char*)buf->value);
1007 while (check_TOKEN(buf) == TOKEN_OBRACKET)
1011 FIXME("No support for multi-dimensional array yet\n");
1015 if (check_TOKEN(buf) == TOKEN_INTEGER)
1018 cur_member->dim_fixed[nb_dims] = TRUE;
1019 cur_member->dim_value[nb_dims] = *(DWORD*)buf->value;
1023 if (get_TOKEN(buf) != TOKEN_NAME)
1025 cur_member->dim_fixed[nb_dims] = FALSE;
1026 /* Hack: Assume array size is specified in previous member */
1027 cur_member->dim_value[nb_dims] = idx_member - 1;
1029 if (get_TOKEN(buf) != TOKEN_CBRACKET)
1035 cur_member->nb_dims = nb_dims;
1037 if (get_TOKEN(buf) != TOKEN_SEMICOLON)
1043 buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].nb_members = idx_member;
1048 static BOOL parse_template_parts(parse_buffer * buf)
1050 if (!parse_template_members_list(buf))
1052 if (check_TOKEN(buf) == TOKEN_OBRACKET)
1055 if (!parse_template_option_info(buf))
1057 if (get_TOKEN(buf) != TOKEN_CBRACKET)
1064 static BOOL parse_template(parse_buffer * buf)
1066 if (get_TOKEN(buf) != TOKEN_TEMPLATE)
1068 if (get_TOKEN(buf) != TOKEN_NAME)
1070 strcpy(buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].name, (char*)buf->value);
1071 if (get_TOKEN(buf) != TOKEN_OBRACE)
1073 if (get_TOKEN(buf) != TOKEN_GUID)
1075 buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].class_id = *(GUID*)buf->value;
1076 if (!parse_template_parts(buf))
1078 if (get_TOKEN(buf) != TOKEN_CBRACE)
1082 /* Go to the next template */
1083 while (buf->rem_bytes && is_space(*buf->buffer))
1090 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));
1091 buf->pdxf->nb_xtemplates++;
1096 static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LPVOID pvData, DWORD cbSize)
1098 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
1102 buf.buffer = (LPBYTE)pvData;
1103 buf.rem_bytes = cbSize;
1105 buf.token_present = FALSE;
1108 TRACE("(%p/%p)->(%p,%d)\n", This, iface, pvData, cbSize);
1111 return DXFILEERR_BADVALUE;
1114 return DXFILEERR_BADFILETYPE;
1116 if (TRACE_ON(d3dxof))
1119 memcpy(string, pvData, 16);
1121 TRACE("header = '%s'\n", string);
1124 read_bytes(&buf, &token_header, 4);
1126 if (token_header != XOFFILE_FORMAT_MAGIC)
1127 return DXFILEERR_BADFILETYPE;
1129 read_bytes(&buf, &token_header, 4);
1131 if (token_header != XOFFILE_FORMAT_VERSION)
1132 return DXFILEERR_BADFILEVERSION;
1134 read_bytes(&buf, &token_header, 4);
1136 if ((token_header != XOFFILE_FORMAT_BINARY) && (token_header != XOFFILE_FORMAT_TEXT) && (token_header != XOFFILE_FORMAT_COMPRESSED))
1137 return DXFILEERR_BADFILETYPE;
1139 if (token_header == XOFFILE_FORMAT_TEXT)
1144 if (token_header == XOFFILE_FORMAT_COMPRESSED)
1146 FIXME("Compressed formats not supported yet\n");
1147 return DXFILEERR_BADVALUE;
1150 read_bytes(&buf, &token_header, 4);
1152 if ((token_header != XOFFILE_FORMAT_FLOAT_BITS_32) && (token_header != XOFFILE_FORMAT_FLOAT_BITS_64))
1153 return DXFILEERR_BADFILEFLOATSIZE;
1155 TRACE("Header is correct\n");
1157 while (buf.rem_bytes)
1159 if (!parse_template(&buf))
1161 TRACE("Template is not correct\n");
1162 return DXFILEERR_BADVALUE;
1166 TRACE("Template successfully parsed:\n");
1167 if (TRACE_ON(d3dxof))
1168 dump_template(This->xtemplates, &This->xtemplates[This->nb_xtemplates - 1]);
1172 if (TRACE_ON(d3dxof))
1175 TRACE("Registered templates (%d):\n", This->nb_xtemplates);
1176 for (i = 0; i < This->nb_xtemplates; i++)
1177 DPRINTF("%s - %s\n", This->xtemplates[i].name, debugstr_guid(&This->xtemplates[i].class_id));
1183 static const IDirectXFileVtbl IDirectXFile_Vtbl =
1185 IDirectXFileImpl_QueryInterface,
1186 IDirectXFileImpl_AddRef,
1187 IDirectXFileImpl_Release,
1188 IDirectXFileImpl_CreateEnumObject,
1189 IDirectXFileImpl_CreateSaveObject,
1190 IDirectXFileImpl_RegisterTemplates
1193 HRESULT IDirectXFileBinaryImpl_Create(IDirectXFileBinaryImpl** ppObj)
1195 IDirectXFileBinaryImpl* object;
1197 TRACE("(%p)\n", ppObj);
1199 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileBinaryImpl));
1201 object->lpVtbl.lpVtbl = &IDirectXFileBinary_Vtbl;
1209 /*** IUnknown methods ***/
1210 static HRESULT WINAPI IDirectXFileBinaryImpl_QueryInterface(IDirectXFileBinary* iface, REFIID riid, void** ppvObject)
1212 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
1214 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
1216 if (IsEqualGUID(riid, &IID_IUnknown)
1217 || IsEqualGUID(riid, &IID_IDirectXFileObject)
1218 || IsEqualGUID(riid, &IID_IDirectXFileBinary))
1220 IClassFactory_AddRef(iface);
1225 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
1226 if (!IsEqualGUID(riid, &IID_IDirectXFileData)
1227 && !IsEqualGUID(riid, &IID_IDirectXFileDataReference))
1228 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
1230 return E_NOINTERFACE;
1233 static ULONG WINAPI IDirectXFileBinaryImpl_AddRef(IDirectXFileBinary* iface)
1235 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
1236 ULONG ref = InterlockedIncrement(&This->ref);
1238 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
1243 static ULONG WINAPI IDirectXFileBinaryImpl_Release(IDirectXFileBinary* iface)
1245 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
1246 ULONG ref = InterlockedDecrement(&This->ref);
1248 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
1251 HeapFree(GetProcessHeap(), 0, This);
1256 /*** IDirectXFileObject methods ***/
1257 static HRESULT WINAPI IDirectXFileBinaryImpl_GetName(IDirectXFileBinary* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen)
1260 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
1262 FIXME("(%p/%p)->(%p,%p) stub!\n", This, iface, pstrNameBuf, pdwBufLen);
1264 return DXFILEERR_BADVALUE;
1267 static HRESULT WINAPI IDirectXFileBinaryImpl_GetId(IDirectXFileBinary* iface, LPGUID pGuid)
1269 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
1271 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pGuid);
1273 return DXFILEERR_BADVALUE;
1276 /*** IDirectXFileBinary methods ***/
1277 static HRESULT WINAPI IDirectXFileBinaryImpl_GetSize(IDirectXFileBinary* iface, DWORD* pcbSize)
1279 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
1281 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pcbSize);
1283 return DXFILEERR_BADVALUE;
1286 static HRESULT WINAPI IDirectXFileBinaryImpl_GetMimeType(IDirectXFileBinary* iface, LPCSTR* pszMimeType)
1288 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
1290 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pszMimeType);
1292 return DXFILEERR_BADVALUE;
1295 static HRESULT WINAPI IDirectXFileBinaryImpl_Read(IDirectXFileBinary* iface, LPVOID pvData, DWORD cbSize, LPDWORD pcbRead)
1297 IDirectXFileBinaryImpl *This = (IDirectXFileBinaryImpl *)iface;
1299 FIXME("(%p/%p)->(%p, %d, %p) stub!\n", This, iface, pvData, cbSize, pcbRead);
1301 return DXFILEERR_BADVALUE;
1304 static const IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl =
1306 IDirectXFileBinaryImpl_QueryInterface,
1307 IDirectXFileBinaryImpl_AddRef,
1308 IDirectXFileBinaryImpl_Release,
1309 IDirectXFileBinaryImpl_GetName,
1310 IDirectXFileBinaryImpl_GetId,
1311 IDirectXFileBinaryImpl_GetSize,
1312 IDirectXFileBinaryImpl_GetMimeType,
1313 IDirectXFileBinaryImpl_Read
1316 HRESULT IDirectXFileDataImpl_Create(IDirectXFileDataImpl** ppObj)
1318 IDirectXFileDataImpl* object;
1320 TRACE("(%p)\n", ppObj);
1322 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileDataImpl));
1324 object->lpVtbl.lpVtbl = &IDirectXFileData_Vtbl;
1332 /*** IUnknown methods ***/
1333 static HRESULT WINAPI IDirectXFileDataImpl_QueryInterface(IDirectXFileData* iface, REFIID riid, void** ppvObject)
1335 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
1337 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
1339 if (IsEqualGUID(riid, &IID_IUnknown)
1340 || IsEqualGUID(riid, &IID_IDirectXFileObject)
1341 || IsEqualGUID(riid, &IID_IDirectXFileData))
1343 IClassFactory_AddRef(iface);
1348 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
1349 if (!IsEqualGUID(riid, &IID_IDirectXFileBinary)
1350 && !IsEqualGUID(riid, &IID_IDirectXFileDataReference))
1351 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
1353 return E_NOINTERFACE;
1356 static ULONG WINAPI IDirectXFileDataImpl_AddRef(IDirectXFileData* iface)
1358 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
1359 ULONG ref = InterlockedIncrement(&This->ref);
1361 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
1366 static ULONG WINAPI IDirectXFileDataImpl_Release(IDirectXFileData* iface)
1368 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
1369 ULONG ref = InterlockedDecrement(&This->ref);
1371 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
1374 HeapFree(GetProcessHeap(), 0, This);
1379 /*** IDirectXFileObject methods ***/
1380 static HRESULT WINAPI IDirectXFileDataImpl_GetName(IDirectXFileData* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen)
1383 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
1385 TRACE("(%p/%p)->(%p,%p)\n", This, iface, pstrNameBuf, pdwBufLen);
1388 return DXFILEERR_BADVALUE;
1390 strcpy(pstrNameBuf, This->pobj->name);
1395 static HRESULT WINAPI IDirectXFileDataImpl_GetId(IDirectXFileData* iface, LPGUID pGuid)
1397 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
1399 TRACE("(%p/%p)->(%p)\n", This, iface, pGuid);
1402 return DXFILEERR_BADVALUE;
1404 memcpy(pGuid, &This->pobj->class_id, 16);
1409 /*** IDirectXFileData methods ***/
1410 static HRESULT WINAPI IDirectXFileDataImpl_GetData(IDirectXFileData* iface, LPCSTR szMember, DWORD* pcbSize, void** ppvData)
1412 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
1414 TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, szMember, pcbSize, ppvData);
1416 if (!pcbSize || !ppvData)
1417 return DXFILEERR_BADVALUE;
1421 FIXME("Specifying a member is not supported yet!\n");
1422 return DXFILEERR_BADVALUE;
1425 *pcbSize = This->pobj->size;
1426 *ppvData = This->pobj->pdata;
1431 static HRESULT WINAPI IDirectXFileDataImpl_GetType(IDirectXFileData* iface, const GUID** pguid)
1433 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
1436 TRACE("(%p/%p)->(%p)\n", This, iface, pguid);
1439 return DXFILEERR_BADVALUE;
1441 memcpy(&guid, &This->pobj->type, 16);
1447 static HRESULT WINAPI IDirectXFileDataImpl_GetNextObject(IDirectXFileData* iface, LPDIRECTXFILEOBJECT* ppChildObj)
1450 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
1452 TRACE("(%p/%p)->(%p)\n", This, iface, ppChildObj);
1454 if (This->cur_enum_object >= This->pobj->nb_childs)
1455 return DXFILEERR_NOMOREOBJECTS;
1457 if (This->from_ref && (This->level >= 1))
1459 /* Only 2 levels can enumerated if the object is obtained from a reference */
1460 return DXFILEERR_NOMOREOBJECTS;
1463 if (This->pobj->childs[This->cur_enum_object]->ptarget)
1465 IDirectXFileDataReferenceImpl *object;
1467 hr = IDirectXFileDataReferenceImpl_Create(&object);
1469 return DXFILEERR_BADVALUE;
1471 object->ptarget = This->pobj->childs[This->cur_enum_object++]->ptarget;
1473 *ppChildObj = (LPDIRECTXFILEOBJECT)object;
1477 IDirectXFileDataImpl *object;
1479 hr = IDirectXFileDataImpl_Create(&object);
1481 return DXFILEERR_BADVALUE;
1483 object->pobj = This->pobj->childs[This->cur_enum_object++];
1484 object->cur_enum_object = 0;
1485 object->from_ref = This->from_ref;
1486 object->level = This->level + 1;
1488 *ppChildObj = (LPDIRECTXFILEOBJECT)object;
1494 static HRESULT WINAPI IDirectXFileDataImpl_AddDataObject(IDirectXFileData* iface, LPDIRECTXFILEDATA pDataObj)
1496 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
1498 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pDataObj);
1500 return DXFILEERR_BADVALUE;
1503 static HRESULT WINAPI IDirectXFileDataImpl_AddDataReference(IDirectXFileData* iface, LPCSTR szRef, const GUID* pguidRef)
1505 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
1507 FIXME("(%p/%p)->(%s,%p) stub!\n", This, iface, szRef, pguidRef);
1509 return DXFILEERR_BADVALUE;
1512 static HRESULT WINAPI IDirectXFileDataImpl_AddBinaryObject(IDirectXFileData* iface, LPCSTR szName, const GUID* pguid, LPCSTR szMimeType, LPVOID pvData, DWORD cbSize)
1514 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
1516 FIXME("(%p/%p)->(%s,%p,%s,%p,%d) stub!\n", This, iface, szName, pguid, szMimeType, pvData, cbSize);
1518 return DXFILEERR_BADVALUE;
1521 static const IDirectXFileDataVtbl IDirectXFileData_Vtbl =
1523 IDirectXFileDataImpl_QueryInterface,
1524 IDirectXFileDataImpl_AddRef,
1525 IDirectXFileDataImpl_Release,
1526 IDirectXFileDataImpl_GetName,
1527 IDirectXFileDataImpl_GetId,
1528 IDirectXFileDataImpl_GetData,
1529 IDirectXFileDataImpl_GetType,
1530 IDirectXFileDataImpl_GetNextObject,
1531 IDirectXFileDataImpl_AddDataObject,
1532 IDirectXFileDataImpl_AddDataReference,
1533 IDirectXFileDataImpl_AddBinaryObject
1536 HRESULT IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImpl** ppObj)
1538 IDirectXFileDataReferenceImpl* object;
1540 TRACE("(%p)\n", ppObj);
1542 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileDataReferenceImpl));
1544 object->lpVtbl.lpVtbl = &IDirectXFileDataReference_Vtbl;
1552 /*** IUnknown methods ***/
1553 static HRESULT WINAPI IDirectXFileDataReferenceImpl_QueryInterface(IDirectXFileDataReference* iface, REFIID riid, void** ppvObject)
1555 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
1557 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
1559 if (IsEqualGUID(riid, &IID_IUnknown)
1560 || IsEqualGUID(riid, &IID_IDirectXFileObject)
1561 || IsEqualGUID(riid, &IID_IDirectXFileDataReference))
1563 IClassFactory_AddRef(iface);
1568 /* Do not print an error for interfaces that can be queried to retrieve the type of the object */
1569 if (!IsEqualGUID(riid, &IID_IDirectXFileData)
1570 && !IsEqualGUID(riid, &IID_IDirectXFileBinary))
1571 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
1573 return E_NOINTERFACE;
1576 static ULONG WINAPI IDirectXFileDataReferenceImpl_AddRef(IDirectXFileDataReference* iface)
1578 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
1579 ULONG ref = InterlockedIncrement(&This->ref);
1581 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
1586 static ULONG WINAPI IDirectXFileDataReferenceImpl_Release(IDirectXFileDataReference* iface)
1588 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
1589 ULONG ref = InterlockedDecrement(&This->ref);
1591 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
1594 HeapFree(GetProcessHeap(), 0, This);
1599 /*** IDirectXFileObject methods ***/
1600 static HRESULT WINAPI IDirectXFileDataReferenceImpl_GetName(IDirectXFileDataReference* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen)
1602 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
1604 TRACE("(%p/%p)->(%p,%p)\n", This, iface, pstrNameBuf, pdwBufLen);
1607 return DXFILEERR_BADVALUE;
1609 strcpy(pstrNameBuf, This->ptarget->name);
1611 return DXFILEERR_BADVALUE;
1614 static HRESULT WINAPI IDirectXFileDataReferenceImpl_GetId(IDirectXFileDataReference* iface, LPGUID pGuid)
1616 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
1618 TRACE("(%p/%p)->(%p)\n", This, iface, pGuid);
1621 return DXFILEERR_BADVALUE;
1623 memcpy(pGuid, &This->ptarget->class_id, 16);
1628 /*** IDirectXFileDataReference ***/
1629 static HRESULT WINAPI IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference* iface, LPDIRECTXFILEDATA* ppDataObj)
1631 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
1632 IDirectXFileDataImpl *object;
1635 TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj);
1638 return DXFILEERR_BADVALUE;
1640 hr = IDirectXFileDataImpl_Create(&object);
1642 return DXFILEERR_BADVALUE;
1644 object->pobj = This->ptarget;
1645 object->cur_enum_object = 0;
1647 object->from_ref = TRUE;
1649 *ppDataObj = (LPDIRECTXFILEDATA)object;
1654 static const IDirectXFileDataReferenceVtbl IDirectXFileDataReference_Vtbl =
1656 IDirectXFileDataReferenceImpl_QueryInterface,
1657 IDirectXFileDataReferenceImpl_AddRef,
1658 IDirectXFileDataReferenceImpl_Release,
1659 IDirectXFileDataReferenceImpl_GetName,
1660 IDirectXFileDataReferenceImpl_GetId,
1661 IDirectXFileDataReferenceImpl_Resolve
1664 HRESULT IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl** ppObj)
1666 IDirectXFileEnumObjectImpl* object;
1668 TRACE("(%p)\n", ppObj);
1670 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileEnumObjectImpl));
1672 object->lpVtbl.lpVtbl = &IDirectXFileEnumObject_Vtbl;
1680 /*** IUnknown methods ***/
1681 static HRESULT WINAPI IDirectXFileEnumObjectImpl_QueryInterface(IDirectXFileEnumObject* iface, REFIID riid, void** ppvObject)
1683 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1685 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
1687 if (IsEqualGUID(riid, &IID_IUnknown)
1688 || IsEqualGUID(riid, &IID_IDirectXFileEnumObject))
1690 IClassFactory_AddRef(iface);
1695 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
1696 return E_NOINTERFACE;
1699 static ULONG WINAPI IDirectXFileEnumObjectImpl_AddRef(IDirectXFileEnumObject* iface)
1701 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1702 ULONG ref = InterlockedIncrement(&This->ref);
1704 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
1709 static ULONG WINAPI IDirectXFileEnumObjectImpl_Release(IDirectXFileEnumObject* iface)
1711 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
1712 ULONG ref = InterlockedDecrement(&This->ref);
1714 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
1717 HeapFree(GetProcessHeap(), 0, This);
1722 static BOOL parse_object_members_list(parse_buffer * buf)
1726 xtemplate* pt = buf->pxt[buf->level];
1727 DWORD last_dword = 0;
1729 for (i = 0; i < pt->nb_members; i++)
1733 if (pt->members[i].nb_dims > 1)
1735 FIXME("Arrays with dimension > 1 not yet supported\n");
1738 else if (pt->members[i].nb_dims)
1740 if (!pt->members[i].dim_fixed[0])
1744 FIXME("Array with variable must be preceded by the size\n");
1747 nb_elems = last_dword;
1748 /*FIXME("Arrays with variable size not yet supported\n");
1752 nb_elems = pt->members[i].dim_value[0];
1757 for (k = 0; k < nb_elems; k++)
1761 token = check_TOKEN(buf);
1762 if (token == TOKEN_COMMA)
1768 /* Allow comma omission */
1769 if (!((token == TOKEN_FLOAT)))
1774 if (pt->members[i].type == TOKEN_NAME)
1778 TRACE("Found suboject %s\n", buf->pdxf->xtemplates[pt->members[i].idx_template].name);
1780 /* To do template lookup */
1781 for (j = 0; j < buf->pdxf->nb_xtemplates; j++)
1783 if (!strcmp(buf->pdxf->xtemplates[pt->members[i].idx_template].name, buf->pdxf->xtemplates[j].name))
1785 buf->pxt[buf->level] = &buf->pdxf->xtemplates[j];
1789 if (j == buf->pdxf->nb_xtemplates)
1791 FIXME("Unknown template %s\n", (char*)buf->value);
1795 TRACE("Enter %s\n", buf->pdxf->xtemplates[pt->members[i].idx_template].name);
1796 if (!parse_object_parts(buf, FALSE))
1802 /*if (get_TOKEN(buf) != TOKEN_SEMICOLON)
1807 token = check_TOKEN(buf);
1808 if (token == TOKEN_INTEGER)
1811 last_dword = *(DWORD*)buf->value;
1812 TRACE("%s = %d\n", pt->members[i].name, *(DWORD*)buf->value);
1813 /* Assume larger size */
1814 if ((buf->cur_pdata - buf->pxo->pdata + 4) > MAX_DATA_SIZE)
1816 WARN("Buffer too small\n");
1819 if (pt->members[i].type == TOKEN_WORD)
1821 *(((WORD*)(buf->cur_pdata))) = (WORD)(*(DWORD*)buf->value);
1822 buf->cur_pdata += 2;
1824 else if (pt->members[i].type == TOKEN_DWORD)
1826 *(((DWORD*)(buf->cur_pdata))) = (DWORD)(*(DWORD*)buf->value);
1827 buf->cur_pdata += 4;
1831 FIXME("Token %d not supported\n", pt->members[i].type);
1835 else if (token == TOKEN_FLOAT)
1838 TRACE("%s = %f\n", pt->members[i].name, *(float*)buf->value);
1839 /* Assume larger size */
1840 if ((buf->cur_pdata - buf->pxo->pdata + 4) > MAX_DATA_SIZE)
1842 WARN("Buffer too small\n");
1845 if (pt->members[i].type == TOKEN_FLOAT)
1847 *(((float*)(buf->cur_pdata))) = (float)(*(float*)buf->value);
1848 buf->cur_pdata += 4;
1852 FIXME("Token %d not supported\n", pt->members[i].type);
1856 else if (token == TOKEN_LPSTR)
1858 static char fake_string[] = "Fake string";
1860 TRACE("%s = %s\n", pt->members[i].name, (char*)buf->value);
1861 /* Assume larger size */
1862 if ((buf->cur_pdata - buf->pxo->pdata + 4) > MAX_DATA_SIZE)
1864 WARN("Buffer too small\n");
1867 if (pt->members[i].type == TOKEN_LPSTR)
1869 /* Use a fake string for now */
1870 *(((LPCSTR*)(buf->cur_pdata))) = fake_string;
1871 buf->cur_pdata += 4;
1875 FIXME("Token %d not supported\n", pt->members[i].type);
1881 FIXME("Unexpected token %d\n", token);
1887 token = get_TOKEN(buf);
1888 if (token != TOKEN_SEMICOLON)
1890 /* Allow comma instead of semicolon in some specific cases */
1891 if (!((token == TOKEN_COMMA) && ((i+1) < pt->nb_members) && (pt->members[i].type == pt->members[i+1].type)
1892 && (!pt->members[i].nb_dims) && (!pt->members[i+1].nb_dims)))
1900 static BOOL parse_object_parts(parse_buffer * buf, BOOL allow_optional)
1902 if (!parse_object_members_list(buf))
1907 buf->pxo->size = buf->cur_pdata - buf->pxo->pdata;
1909 /* Skip trailing semicolon */
1910 while (check_TOKEN(buf) == TOKEN_SEMICOLON)
1915 if (check_TOKEN(buf) == TOKEN_OBRACE)
1919 if (get_TOKEN(buf) != TOKEN_NAME)
1921 if (get_TOKEN(buf) != TOKEN_CBRACE)
1923 TRACE("Found optional reference %s\n", (char*)buf->value);
1924 for (i = 0; i < buf->nb_pxo_globals; i++)
1926 for (j = 0; j < buf->pxo_globals[i*MAX_SUBOBJECTS].nb_subobjects; j++)
1928 if (!strcmp(buf->pxo_globals[i*MAX_SUBOBJECTS+j].name, (char*)buf->value))
1933 if (i == buf->nb_pxo_globals)
1935 ERR("Reference to unknown object %s\n", (char*)buf->value);
1938 buf->pxo->childs[buf->pxo->nb_childs] = &buf->pxo_tab[buf->cur_subobject++];
1939 buf->pxo->childs[buf->pxo->nb_childs]->ptarget = &buf->pxo_globals[i*MAX_SUBOBJECTS+j];
1940 buf->pxo->nb_childs++;
1942 else if (check_TOKEN(buf) == TOKEN_NAME)
1944 xobject* pxo = buf->pxo;
1945 buf->pxo = buf->pxo->childs[buf->pxo->nb_childs] = &buf->pxo_tab[buf->cur_subobject++];
1947 TRACE("Enter optional %s\n", (char*)buf->value);
1949 if (!parse_object(buf))
1956 buf->pxo->nb_childs++;
1966 static BOOL parse_object(parse_buffer * buf)
1970 buf->pxo->pdata = buf->cur_pdata;
1971 buf->pxo->ptarget = NULL;
1973 if (get_TOKEN(buf) != TOKEN_NAME)
1976 /* To do template lookup */
1977 for (i = 0; i < buf->pdxf->nb_xtemplates; i++)
1979 if (!strcmp((char*)buf->value, buf->pdxf->xtemplates[i].name))
1981 buf->pxt[buf->level] = &buf->pdxf->xtemplates[i];
1982 memcpy(&buf->pxo->type, &buf->pdxf->xtemplates[i].class_id, 16);
1986 if (i == buf->pdxf->nb_xtemplates)
1988 FIXME("Unknown template %s\n", (char*)buf->value);
1992 if (check_TOKEN(buf) == TOKEN_NAME)
1995 strcpy(buf->pxo->name, (char*)buf->value);
1998 buf->pxo->name[0] = 0;
2000 if (get_TOKEN(buf) != TOKEN_OBRACE)
2002 if (check_TOKEN(buf) == TOKEN_GUID)
2005 memcpy(&buf->pxo->class_id, buf->value, 16);
2008 memset(&buf->pxo->class_id, 0, 16);
2010 if (!parse_object_parts(buf, TRUE))
2012 if (get_TOKEN(buf) != TOKEN_CBRACE)
2017 /* Go to the next object */
2018 while (buf->rem_bytes && is_space(*buf->buffer))
2028 /*** IDirectXFileEnumObject methods ***/
2029 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject* iface, LPDIRECTXFILEDATA* ppDataObj)
2031 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
2032 IDirectXFileDataImpl* object;
2036 TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj);
2038 if (!This->buf.rem_bytes)
2039 return DXFILEERR_NOMOREOBJECTS;
2041 hr = IDirectXFileDataImpl_Create(&object);
2045 This->buf.pxo_globals = &This->xobjects[0][0];
2046 This->buf.nb_pxo_globals = This->nb_xobjects;
2047 This->buf.pxo_tab = &This->xobjects[This->nb_xobjects][0];
2048 This->buf.cur_subobject = 0;
2049 This->buf.pxo = &This->buf.pxo_tab[This->buf.cur_subobject++];
2051 pdata = HeapAlloc(GetProcessHeap(), 0, MAX_DATA_SIZE);
2054 WARN("Out of memory\n");
2055 return DXFILEERR_BADALLOC;
2057 This->buf.cur_pdata = pdata;
2058 This->buf.level = 0;
2060 if (!parse_object(&This->buf))
2062 TRACE("Object is not correct\n");
2063 HeapFree(GetProcessHeap(), 0, This->buf.pxo->pdata);
2064 return DXFILEERR_PARSEERROR;
2067 This->buf.pxo->nb_subobjects = This->buf.cur_subobject;
2069 object->pobj = This->buf.pxo;
2070 object->cur_enum_object = 0;
2072 object->from_ref = FALSE;
2074 *ppDataObj = (LPDIRECTXFILEDATA)object;
2076 This->nb_xobjects++;
2081 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetDataObjectById(IDirectXFileEnumObject* iface, REFGUID rguid, LPDIRECTXFILEDATA* ppDataObj)
2083 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
2085 FIXME("(%p/%p)->(%p,%p) stub!\n", This, iface, rguid, ppDataObj);
2087 return DXFILEERR_BADVALUE;
2090 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetDataObjectByName(IDirectXFileEnumObject* iface, LPCSTR szName, LPDIRECTXFILEDATA* ppDataObj)
2092 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
2094 FIXME("(%p/%p)->(%s,%p) stub!\n", This, iface, szName, ppDataObj);
2096 return DXFILEERR_BADVALUE;
2099 static const IDirectXFileEnumObjectVtbl IDirectXFileEnumObject_Vtbl =
2101 IDirectXFileEnumObjectImpl_QueryInterface,
2102 IDirectXFileEnumObjectImpl_AddRef,
2103 IDirectXFileEnumObjectImpl_Release,
2104 IDirectXFileEnumObjectImpl_GetNextDataObject,
2105 IDirectXFileEnumObjectImpl_GetDataObjectById,
2106 IDirectXFileEnumObjectImpl_GetDataObjectByName
2109 HRESULT IDirectXFileObjectImpl_Create(IDirectXFileObjectImpl** ppObj)
2111 IDirectXFileObjectImpl* object;
2113 TRACE("(%p)\n", ppObj);
2115 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileObjectImpl));
2117 object->lpVtbl.lpVtbl = &IDirectXFileObject_Vtbl;
2125 /*** IUnknown methods ***/
2126 static HRESULT WINAPI IDirectXFileObjectImpl_QueryInterface(IDirectXFileObject* iface, REFIID riid, void** ppvObject)
2128 IDirectXFileObjectImpl *This = (IDirectXFileObjectImpl *)iface;
2130 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
2132 if (IsEqualGUID(riid, &IID_IUnknown)
2133 || IsEqualGUID(riid, &IID_IDirectXFileObject))
2135 IClassFactory_AddRef(iface);
2140 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
2141 return E_NOINTERFACE;
2144 static ULONG WINAPI IDirectXFileObjectImpl_AddRef(IDirectXFileObject* iface)
2146 IDirectXFileObjectImpl *This = (IDirectXFileObjectImpl *)iface;
2147 ULONG ref = InterlockedIncrement(&This->ref);
2149 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
2154 static ULONG WINAPI IDirectXFileObjectImpl_Release(IDirectXFileObject* iface)
2156 IDirectXFileObjectImpl *This = (IDirectXFileObjectImpl *)iface;
2157 ULONG ref = InterlockedDecrement(&This->ref);
2159 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
2162 HeapFree(GetProcessHeap(), 0, This);
2167 /*** IDirectXFileObject methods ***/
2168 static HRESULT WINAPI IDirectXFileObjectImpl_GetName(IDirectXFileObject* iface, LPSTR pstrNameBuf, LPDWORD pdwBufLen)
2170 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
2172 FIXME("(%p/%p)->(%p,%p) stub!\n", This, iface, pstrNameBuf, pdwBufLen);
2174 return DXFILEERR_BADVALUE;
2177 static HRESULT WINAPI IDirectXFileObjectImpl_GetId(IDirectXFileObject* iface, LPGUID pGuid)
2179 IDirectXFileObjectImpl *This = (IDirectXFileObjectImpl *)iface;
2181 FIXME("(%p/%p)->(%p) stub!\n", This, iface, pGuid);
2183 return DXFILEERR_BADVALUE;
2186 static const IDirectXFileObjectVtbl IDirectXFileObject_Vtbl =
2188 IDirectXFileObjectImpl_QueryInterface,
2189 IDirectXFileObjectImpl_AddRef,
2190 IDirectXFileObjectImpl_Release,
2191 IDirectXFileObjectImpl_GetName,
2192 IDirectXFileObjectImpl_GetId
2195 HRESULT IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl** ppObj)
2197 IDirectXFileSaveObjectImpl* object;
2199 TRACE("(%p)\n", ppObj);
2201 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectXFileSaveObjectImpl));
2203 object->lpVtbl.lpVtbl = &IDirectXFileSaveObject_Vtbl;
2211 /*** IUnknown methods ***/
2212 static HRESULT WINAPI IDirectXFileSaveObjectImpl_QueryInterface(IDirectXFileSaveObject* iface, REFIID riid, void** ppvObject)
2214 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
2216 TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
2218 if (IsEqualGUID(riid, &IID_IUnknown)
2219 || IsEqualGUID(riid, &IID_IDirectXFileSaveObject))
2221 IClassFactory_AddRef(iface);
2226 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
2227 return E_NOINTERFACE;
2230 static ULONG WINAPI IDirectXFileSaveObjectImpl_AddRef(IDirectXFileSaveObject* iface)
2232 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
2233 ULONG ref = InterlockedIncrement(&This->ref);
2235 TRACE("(%p/%p): AddRef from %d\n", iface, This, ref - 1);
2240 static ULONG WINAPI IDirectXFileSaveObjectImpl_Release(IDirectXFileSaveObject* iface)
2242 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
2243 ULONG ref = InterlockedDecrement(&This->ref);
2245 TRACE("(%p/%p): ReleaseRef to %d\n", iface, This, ref);
2248 HeapFree(GetProcessHeap(), 0, This);
2253 static HRESULT WINAPI IDirectXFileSaveObjectImpl_SaveTemplates(IDirectXFileSaveObject* iface, DWORD cTemplates, const GUID** ppguidTemplates)
2255 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
2257 FIXME("(%p/%p)->(%d,%p) stub!\n", This, iface, cTemplates, ppguidTemplates);
2259 return DXFILEERR_BADVALUE;
2262 static HRESULT WINAPI IDirectXFileSaveObjectImpl_CreateDataObject(IDirectXFileSaveObject* iface, REFGUID rguidTemplate, LPCSTR szName, const GUID* pguid, DWORD cbSize, LPVOID pvData, LPDIRECTXFILEDATA* ppDataObj)
2264 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
2266 FIXME("(%p/%p)->(%p,%s,%p,%d,%p,%p) stub!\n", This, iface, rguidTemplate, szName, pguid, cbSize, pvData, ppDataObj);
2268 return DXFILEERR_BADVALUE;
2271 static HRESULT WINAPI IDirectXFileSaveObjectImpl_SaveData(IDirectXFileSaveObject* iface, LPDIRECTXFILEDATA ppDataObj)
2273 IDirectXFileSaveObjectImpl *This = (IDirectXFileSaveObjectImpl *)iface;
2275 FIXME("(%p/%p)->(%p) stub!\n", This, iface, ppDataObj);
2277 return DXFILEERR_BADVALUE;
2280 static const IDirectXFileSaveObjectVtbl IDirectXFileSaveObject_Vtbl =
2282 IDirectXFileSaveObjectImpl_QueryInterface,
2283 IDirectXFileSaveObjectImpl_AddRef,
2284 IDirectXFileSaveObjectImpl_Release,
2285 IDirectXFileSaveObjectImpl_SaveTemplates,
2286 IDirectXFileSaveObjectImpl_CreateDataObject,
2287 IDirectXFileSaveObjectImpl_SaveData