push 9eb9af089d68d39110a91889d3a673043db63c4b
[wine/hacks.git] / dlls / d3dxof / d3dxof.c
blob25d4834ea615c24cee5c6a891540c417aa9a3f6b
1 /*
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
24 #include "config.h"
25 #include "wine/debug.h"
27 #define COBJMACROS
29 #include "winbase.h"
30 #include "wingdi.h"
32 #include "d3dxof_private.h"
33 #include "dxfile.h"
35 #include <stdio.h>
37 WINE_DEFAULT_DEBUG_CHANNEL(d3dxof);
39 #define MAKEFOUR(a,b,c,d) ((DWORD)a + ((DWORD)b << 8) + ((DWORD)c << 16) + ((DWORD)d << 24))
40 #define XOFFILE_FORMAT_MAGIC MAKEFOUR('x','o','f',' ')
41 #define XOFFILE_FORMAT_VERSION_302 MAKEFOUR('0','3','0','2')
42 #define XOFFILE_FORMAT_VERSION_303 MAKEFOUR('0','3','0','3')
43 #define XOFFILE_FORMAT_BINARY MAKEFOUR('b','i','n',' ')
44 #define XOFFILE_FORMAT_TEXT MAKEFOUR('t','x','t',' ')
45 #define XOFFILE_FORMAT_COMPRESSED MAKEFOUR('c','m','p',' ')
46 #define XOFFILE_FORMAT_FLOAT_BITS_32 MAKEFOUR('0','0','3','2')
47 #define XOFFILE_FORMAT_FLOAT_BITS_64 MAKEFOUR('0','0','6','4')
49 #define TOKEN_NAME 1
50 #define TOKEN_STRING 2
51 #define TOKEN_INTEGER 3
52 #define TOKEN_GUID 5
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
63 #define TOKEN_DOT 18
64 #define TOKEN_COMMA 19
65 #define TOKEN_SEMICOLON 20
66 #define TOKEN_TEMPLATE 31
67 #define TOKEN_WORD 40
68 #define TOKEN_DWORD 41
69 #define TOKEN_FLOAT 42
70 #define TOKEN_DOUBLE 43
71 #define TOKEN_CHAR 44
72 #define TOKEN_UCHAR 45
73 #define TOKEN_SWORD 46
74 #define TOKEN_SDWORD 47
75 #define TOKEN_VOID 48
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)
102 int j, k;
103 GUID* clsid;
105 clsid = &ptemplate->class_id;
107 DPRINTF("template %s\n", ptemplate->name);
108 DPRINTF("{\n");
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)
114 DPRINTF("array ");
115 if (ptemplate->members[j].type == TOKEN_NAME)
116 DPRINTF("%s ", templates_array[ptemplate->members[j].idx_template].name);
117 else
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]);
124 else
125 DPRINTF("[%s]", ptemplate->members[ptemplate->members[j].dim_value[k]].name);
127 DPRINTF(";\n");
129 if (ptemplate->open)
130 DPRINTF("[...]\n");
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]);
136 DPRINTF("]\n");
138 DPRINTF("}\n");
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;
150 object->ref = 1;
152 *ppObj = object;
154 return S_OK;
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);
168 *ppvObject = This;
169 return S_OK;
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);
183 return ref;
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);
193 if (!ref)
194 HeapFree(GetProcessHeap(), 0, This);
196 return ref;
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;
204 HRESULT hr;
205 DWORD header[4];
206 DWORD size;
207 HANDLE hFile = INVALID_HANDLE_VALUE;
208 LPDXFILELOADMEMORY lpdxflm = NULL;
210 TRACE("(%p/%p)->(%p,%x,%p)\n", This, iface, pvSource, dwLoadOptions, ppEnumObj);
212 if (!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;
229 goto error;
232 if (size < 16)
234 hr = DXFILEERR_BADFILETYPE;
235 goto error;
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);
246 else
248 FIXME("Source type %d is not handled yet\n", dwLoadOptions);
249 hr = DXFILEERR_NOTDONEYET;
250 goto error;
253 if (TRACE_ON(d3dxof))
255 char string[17];
256 memcpy(string, header, 16);
257 string[16] = 0;
258 TRACE("header = '%s'\n", string);
261 if (header[0] != XOFFILE_FORMAT_MAGIC)
263 hr = DXFILEERR_BADFILETYPE;
264 goto error;
267 if ((header[1] != XOFFILE_FORMAT_VERSION_302) && (header[1] != XOFFILE_FORMAT_VERSION_303))
269 hr = DXFILEERR_BADFILEVERSION;
270 goto error;
273 if ((header[2] != XOFFILE_FORMAT_BINARY) && (header[2] != XOFFILE_FORMAT_TEXT) && (header[2] != XOFFILE_FORMAT_COMPRESSED))
275 hr = DXFILEERR_BADFILETYPE;
276 goto error;
279 if (header[2] == XOFFILE_FORMAT_BINARY)
281 FIXME("Binary format not supported yet\n");
282 hr = DXFILEERR_NOTDONEYET;
283 goto error;
286 if (header[2] == XOFFILE_FORMAT_COMPRESSED)
288 FIXME("Compressed formats not supported yet\n");
289 hr = DXFILEERR_BADVALUE;
290 goto error;
293 if ((header[3] != XOFFILE_FORMAT_FLOAT_BITS_32) && (header[3] != XOFFILE_FORMAT_FLOAT_BITS_64))
295 hr = DXFILEERR_BADFILEFLOATSIZE;
296 goto error;
299 TRACE("Header is correct\n");
301 hr = IDirectXFileEnumObjectImpl_Create(&object);
302 if (FAILED(hr))
303 goto error;
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;
320 goto error;
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;
329 goto error;
332 else
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;
348 goto error;
350 else
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))
360 int i;
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));
366 return DXFILE_OK;
368 error:
369 if (hFile != INVALID_HANDLE_VALUE)
370 CloseHandle(hFile);
371 *ppEnumObj = NULL;
373 return hr;
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)
388 return FALSE;
389 memcpy(data, buf->buffer, size);
390 buf->buffer += size;
391 buf->rem_bytes -= size;
392 return TRUE;
395 static void dump_TOKEN(WORD token)
397 #define DUMP_TOKEN(t) case t: TRACE(#t "\n"); break
398 switch(token)
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);
431 default:
432 if (0)
433 TRACE("Unknown token %d\n", token);
434 break;
436 #undef DUMP_TOKEN
439 static BOOL is_space(char c)
441 switch (c)
443 case 0x00:
444 case 0x0D:
445 case 0x0A:
446 case ' ':
447 case '\t':
448 return TRUE;
450 return FALSE;
453 static BOOL is_operator(char c)
455 switch(c)
457 case '{':
458 case '}':
459 case '[':
460 case ']':
461 case '(':
462 case ')':
463 case '<':
464 case '>':
465 case ',':
466 case ';':
467 return TRUE;
469 return FALSE;
472 static inline BOOL is_separator(char c)
474 return is_space(c) || is_operator(c);
477 static WORD get_operator_token(char c)
479 switch(c)
481 case '{':
482 return TOKEN_OBRACE;
483 case '}':
484 return TOKEN_CBRACE;
485 case '[':
486 return TOKEN_OBRACKET;
487 case ']':
488 return TOKEN_CBRACKET;
489 case '(':
490 return TOKEN_OPAREN;
491 case ')':
492 return TOKEN_CPAREN;
493 case '<':
494 return TOKEN_OANGLE;
495 case '>':
496 return TOKEN_CANGLE;
497 case ',':
498 return TOKEN_COMMA;
499 case ';':
500 return TOKEN_SEMICOLON;
502 return 0;
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)))
510 buf->buffer += len;
511 buf->rem_bytes -= len;
512 return TRUE;
514 return FALSE;
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"))
522 return TOKEN_WORD;
523 if (is_keyword(buf, "DWORD"))
524 return TOKEN_DWORD;
525 if (is_keyword(buf, "FLOAT"))
526 return TOKEN_FLOAT;
527 if (is_keyword(buf, "DOUBLE"))
528 return TOKEN_DOUBLE;
529 if (is_keyword(buf, "CHAR"))
530 return TOKEN_CHAR;
531 if (is_keyword(buf, "UCHAR"))
532 return TOKEN_UCHAR;
533 if (is_keyword(buf, "SWORD"))
534 return TOKEN_SWORD;
535 if (is_keyword(buf, "SDWORD"))
536 return TOKEN_SDWORD;
537 if (is_keyword(buf, "VOID"))
538 return TOKEN_VOID;
539 if (is_keyword(buf, "STRING"))
540 return TOKEN_LPSTR;
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"))
546 return TOKEN_ARRAY;
548 return 0;
551 static BOOL is_guid(parse_buffer* buf)
553 char tmp[50];
554 DWORD pos = 1;
555 GUID class_id;
556 DWORD tab[10];
557 int ret;
559 if (*buf->buffer != '<')
560 return FALSE;
561 tmp[0] = '<';
562 while (*(buf->buffer+pos) != '>')
564 tmp[pos] = *(buf->buffer+pos);
565 pos++;
567 tmp[pos++] = '>';
568 tmp[pos] = 0;
569 if (pos != 38 /* <+36+> */)
571 TRACE("Wrong guid %s (%d)\n", tmp, pos);
572 return FALSE;
574 buf->buffer += 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);
578 if (ret != 11)
580 TRACE("Wrong guid %s (%d)\n", tmp, pos);
581 return FALSE;
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;
598 return TRUE;
601 static BOOL is_name(parse_buffer* buf)
603 char tmp[50];
604 DWORD pos = 0;
605 char c;
606 BOOL error = 0;
607 while (!is_separator(c = *(buf->buffer+pos)))
609 if (!(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9')) || (c == '_')))
610 error = 1;
611 tmp[pos++] = c;
613 tmp[pos] = 0;
615 if (error)
617 TRACE("Wrong name %s\n", tmp);
618 return FALSE;
621 buf->buffer += pos;
622 buf->rem_bytes -= pos;
624 TRACE("Found name %s\n", tmp);
625 strcpy((char*)buf->value, tmp);
627 return TRUE;
630 static BOOL is_float(parse_buffer* buf)
632 char tmp[50];
633 DWORD pos = 0;
634 char c;
635 float decimal;
636 BOOL dot = 0;
638 while (!is_separator(c = *(buf->buffer+pos)))
640 if (!((!pos && (c == '-')) || ((c >= '0') && (c <= '9')) || (!dot && (c == '.'))))
641 return FALSE;
642 if (c == '.')
643 dot = TRUE;
644 tmp[pos++] = c;
646 tmp[pos] = 0;
648 buf->buffer += pos;
649 buf->rem_bytes -= pos;
651 sscanf(tmp, "%f", &decimal);
653 TRACE("Found float %s - %f\n", tmp, decimal);
655 *(float*)buf->value = decimal;
657 return TRUE;
660 static BOOL is_integer(parse_buffer* buf)
662 char tmp[50];
663 DWORD pos = 0;
664 char c;
665 DWORD integer;
667 while (!is_separator(c = *(buf->buffer+pos)))
669 if (!((c >= '0') && (c <= '9')))
670 return FALSE;
671 tmp[pos++] = c;
673 tmp[pos] = 0;
675 buf->buffer += pos;
676 buf->rem_bytes -= pos;
678 sscanf(tmp, "%d", &integer);
680 TRACE("Found integer %s - %d\n", tmp, integer);
682 *(DWORD*)buf->value = integer;
684 return TRUE;
687 static BOOL is_string(parse_buffer* buf)
689 char tmp[32];
690 DWORD pos = 0;
691 char c;
692 BOOL ok = 0;
694 if (*buf->buffer != '"')
695 return FALSE;
697 while (!is_separator(c = *(buf->buffer+pos+1)) && (pos < 31))
699 if (c == '"')
701 ok = 1;
702 break;
704 tmp[pos++] = c;
706 tmp[pos] = 0;
708 if (!ok)
710 TRACE("Wrong string %s\n", tmp);
711 return FALSE;
714 buf->buffer += pos + 2;
715 buf->rem_bytes -= pos + 2;
717 TRACE("Found string %s\n", tmp);
718 strcpy((char*)buf->value, tmp);
720 return TRUE;
723 static WORD parse_TOKEN(parse_buffer * buf)
725 WORD token;
727 if (buf->txt)
729 while(1)
731 char c;
732 if (!read_bytes(buf, &c, 1))
733 return 0;
734 /*TRACE("char = '%c'\n", is_space(c) ? ' ' : c);*/
735 if ((c == '#') || (c == '/'))
737 /* Handle comment (# or //) */
738 if (c == '/')
740 if (!read_bytes(buf, &c, 1))
741 return 0;
742 if (c != '/')
743 return 0;
745 c = 0;
746 while (c != 0x0A)
748 if (!read_bytes(buf, &c, 1))
749 return 0;
751 continue;
753 if (is_space(c))
754 continue;
755 if (is_operator(c) && (c != '<'))
757 token = get_operator_token(c);
758 break;
760 else if (c == '.')
762 token = TOKEN_DOT;
763 break;
765 else
767 buf->buffer -= 1;
768 buf->rem_bytes += 1;
770 if ((token = get_keyword_token(buf)))
771 break;
773 if (is_guid(buf))
775 token = TOKEN_GUID;
776 break;
778 if (is_integer(buf))
780 token = TOKEN_INTEGER;
781 break;
783 if (is_float(buf))
785 token = TOKEN_FLOAT;
786 break;
788 if (is_string(buf))
790 token = TOKEN_LPSTR;
791 break;
793 if (is_name(buf))
795 token = TOKEN_NAME;
796 break;
799 FIXME("Unrecognize element\n");
800 return 0;
804 else
806 if (!read_bytes(buf, &token, 2))
807 return 0;
809 switch(token)
811 case TOKEN_NAME:
813 DWORD count;
814 char strname[100];
816 if (!read_bytes(buf, &count, 4))
817 return 0;
818 if (!read_bytes(buf, strname, count))
819 return 0;
820 strname[count] = 0;
821 /*TRACE("name = %s\n", strname);*/
823 strcpy((char*)buf->value, strname);
825 break;
826 case TOKEN_INTEGER:
828 DWORD integer;
830 if (!read_bytes(buf, &integer, 4))
831 return 0;
832 /*TRACE("integer = %ld\n", integer);*/
834 *(DWORD*)buf->value = integer;
836 break;
837 case TOKEN_GUID:
839 char strguid[39];
840 GUID class_id;
842 if (!read_bytes(buf, &class_id, 16))
843 return 0;
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;
851 break;
852 case TOKEN_STRING:
853 case TOKEN_INTEGER_LIST:
854 case TOKEN_FLOAT_LIST:
855 case TOKEN_OBRACE:
856 case TOKEN_CBRACE:
857 case TOKEN_OPAREN:
858 case TOKEN_CPAREN:
859 case TOKEN_OBRACKET:
860 case TOKEN_CBRACKET:
861 case TOKEN_OANGLE:
862 case TOKEN_CANGLE:
863 case TOKEN_DOT:
864 case TOKEN_COMMA:
865 case TOKEN_SEMICOLON:
866 case TOKEN_TEMPLATE:
867 case TOKEN_WORD:
868 case TOKEN_DWORD:
869 case TOKEN_FLOAT:
870 case TOKEN_DOUBLE:
871 case TOKEN_CHAR:
872 case TOKEN_UCHAR:
873 case TOKEN_SWORD:
874 case TOKEN_SDWORD:
875 case TOKEN_VOID:
876 case TOKEN_LPSTR:
877 case TOKEN_UNICODE:
878 case TOKEN_CSTRING:
879 case TOKEN_ARRAY:
880 break;
881 default:
882 return 0;
886 dump_TOKEN(token);
888 return token;
891 static const char* get_primitive_string(WORD token)
893 switch(token)
895 case TOKEN_WORD:
896 return "WORD";
897 case TOKEN_DWORD:
898 return "DWORD";
899 case TOKEN_FLOAT:
900 return "FLOAT";
901 case TOKEN_DOUBLE:
902 return "DOUBLE";
903 case TOKEN_CHAR:
904 return "CHAR";
905 case TOKEN_UCHAR:
906 return "UCHAR";
907 case TOKEN_SWORD:
908 return "SWORD";
909 case TOKEN_SDWORD:
910 return "SDWORD";
911 case TOKEN_VOID:
912 return "VOID";
913 case TOKEN_LPSTR:
914 return "STRING";
915 case TOKEN_UNICODE:
916 return "UNICODE";
917 case TOKEN_CSTRING:
918 return "CSTRING ";
919 default:
920 break;
922 return NULL;
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)
951 BOOL ret;
952 switch(token)
954 case TOKEN_WORD:
955 case TOKEN_DWORD:
956 case TOKEN_FLOAT:
957 case TOKEN_DOUBLE:
958 case TOKEN_CHAR:
959 case TOKEN_UCHAR:
960 case TOKEN_SWORD:
961 case TOKEN_SDWORD:
962 case TOKEN_LPSTR:
963 case TOKEN_UNICODE:
964 case TOKEN_CSTRING:
965 ret = 1;
966 break;
967 default:
968 ret = 0;
969 break;
971 return ret;
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)
980 get_TOKEN(buf);
981 if (get_TOKEN(buf) != TOKEN_DOT)
982 return FALSE;
983 if (get_TOKEN(buf) != TOKEN_DOT)
984 return FALSE;
985 cur_template->open = TRUE;
987 else
989 while (1)
991 if (get_TOKEN(buf) != TOKEN_NAME)
992 return FALSE;
993 strcpy(cur_template->childs[cur_template->nb_childs], (char*)buf->value);
994 if (check_TOKEN(buf) == TOKEN_GUID)
995 get_TOKEN(buf);
996 cur_template->nb_childs++;
997 if (check_TOKEN(buf) != TOKEN_COMMA)
998 break;
999 get_TOKEN(buf);
1001 cur_template->open = FALSE;
1004 return TRUE;
1007 static BOOL parse_template_members_list(parse_buffer * buf)
1009 int idx_member = 0;
1010 member* cur_member;
1012 while (1)
1014 BOOL array = 0;
1015 int nb_dims = 0;
1016 cur_member = &buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].members[idx_member];
1018 if (check_TOKEN(buf) == TOKEN_ARRAY)
1020 get_TOKEN(buf);
1021 array = 1;
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))
1031 break;
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);
1037 return FALSE;
1040 else if (is_primitive_type(check_TOKEN(buf)))
1041 cur_member->type = get_TOKEN(buf);
1042 else
1043 break;
1045 if (get_TOKEN(buf) != TOKEN_NAME)
1046 return FALSE;
1047 strcpy(cur_member->name, (char*)buf->value);
1049 if (array)
1051 while (check_TOKEN(buf) == TOKEN_OBRACKET)
1053 if (nb_dims)
1055 FIXME("No support for multi-dimensional array yet\n");
1056 return FALSE;
1058 get_TOKEN(buf);
1059 if (check_TOKEN(buf) == TOKEN_INTEGER)
1061 get_TOKEN(buf);
1062 cur_member->dim_fixed[nb_dims] = TRUE;
1063 cur_member->dim_value[nb_dims] = *(DWORD*)buf->value;
1065 else
1067 if (get_TOKEN(buf) != TOKEN_NAME)
1068 return FALSE;
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)
1074 return FALSE;
1075 nb_dims++;
1077 if (!nb_dims)
1078 return FALSE;
1079 cur_member->nb_dims = nb_dims;
1081 if (get_TOKEN(buf) != TOKEN_SEMICOLON)
1082 return FALSE;
1084 idx_member++;
1087 buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].nb_members = idx_member;
1089 return TRUE;
1092 static BOOL parse_template_parts(parse_buffer * buf)
1094 if (!parse_template_members_list(buf))
1095 return FALSE;
1096 if (check_TOKEN(buf) == TOKEN_OBRACKET)
1098 get_TOKEN(buf);
1099 if (!parse_template_option_info(buf))
1100 return FALSE;
1101 if (get_TOKEN(buf) != TOKEN_CBRACKET)
1102 return FALSE;
1105 return TRUE;
1108 static BOOL parse_template(parse_buffer * buf)
1110 if (get_TOKEN(buf) != TOKEN_TEMPLATE)
1111 return FALSE;
1112 if (get_TOKEN(buf) != TOKEN_NAME)
1113 return FALSE;
1114 strcpy(buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].name, (char*)buf->value);
1115 if (get_TOKEN(buf) != TOKEN_OBRACE)
1116 return FALSE;
1117 if (get_TOKEN(buf) != TOKEN_GUID)
1118 return FALSE;
1119 buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].class_id = *(GUID*)buf->value;
1120 if (!parse_template_parts(buf))
1121 return FALSE;
1122 if (get_TOKEN(buf) != TOKEN_CBRACE)
1123 return FALSE;
1124 if (buf->txt)
1126 /* Go to the next template */
1127 while (buf->rem_bytes && is_space(*buf->buffer))
1129 buf->buffer++;
1130 buf->rem_bytes--;
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++;
1137 return TRUE;
1140 static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LPVOID pvData, DWORD cbSize)
1142 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
1143 DWORD token_header;
1144 parse_buffer buf;
1146 buf.buffer = (LPBYTE)pvData;
1147 buf.rem_bytes = cbSize;
1148 buf.txt = FALSE;
1149 buf.token_present = FALSE;
1150 buf.pdxf = This;
1152 TRACE("(%p/%p)->(%p,%d)\n", This, iface, pvData, cbSize);
1154 if (!pvData)
1155 return DXFILEERR_BADVALUE;
1157 if (cbSize < 16)
1158 return DXFILEERR_BADFILETYPE;
1160 if (TRACE_ON(d3dxof))
1162 char string[17];
1163 memcpy(string, pvData, 16);
1164 string[16] = 0;
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)
1185 buf.txt = TRUE;
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;
1208 else
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))
1218 int i;
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));
1224 return DXFILE_OK;
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;
1246 object->ref = 1;
1248 *ppObj = object;
1250 return DXFILE_OK;
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);
1265 *ppvObject = This;
1266 return S_OK;
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);
1284 return ref;
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);
1294 if (!ref)
1295 HeapFree(GetProcessHeap(), 0, This);
1297 return ref;
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;
1369 object->ref = 1;
1371 *ppObj = object;
1373 return S_OK;
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);
1388 *ppvObject = This;
1389 return S_OK;
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);
1407 return ref;
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);
1417 if (!ref)
1418 HeapFree(GetProcessHeap(), 0, This);
1420 return ref;
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);
1431 if (!pstrNameBuf)
1432 return DXFILEERR_BADVALUE;
1434 strcpy(pstrNameBuf, This->pobj->name);
1436 return DXFILE_OK;
1439 static HRESULT WINAPI IDirectXFileDataImpl_GetId(IDirectXFileData* iface, LPGUID pGuid)
1441 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
1443 TRACE("(%p/%p)->(%p)\n", This, iface, pGuid);
1445 if (!pGuid)
1446 return DXFILEERR_BADVALUE;
1448 memcpy(pGuid, &This->pobj->class_id, 16);
1450 return DXFILE_OK;
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;
1463 if (szMember)
1465 FIXME("Specifying a member is not supported yet!\n");
1466 return DXFILEERR_BADVALUE;
1469 *pcbSize = This->pobj->size;
1470 *ppvData = This->pobj->pdata;
1472 return DXFILE_OK;
1475 static HRESULT WINAPI IDirectXFileDataImpl_GetType(IDirectXFileData* iface, const GUID** pguid)
1477 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
1478 static GUID guid;
1480 TRACE("(%p/%p)->(%p)\n", This, iface, pguid);
1482 if (!pguid)
1483 return DXFILEERR_BADVALUE;
1485 memcpy(&guid, &This->pobj->type, 16);
1486 *pguid = &guid;
1488 return DXFILE_OK;
1491 static HRESULT WINAPI IDirectXFileDataImpl_GetNextObject(IDirectXFileData* iface, LPDIRECTXFILEOBJECT* ppChildObj)
1493 HRESULT hr;
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);
1512 if (hr != S_OK)
1513 return DXFILEERR_BADVALUE;
1515 object->ptarget = This->pobj->childs[This->cur_enum_object++]->ptarget;
1517 *ppChildObj = (LPDIRECTXFILEOBJECT)object;
1519 else
1521 IDirectXFileDataImpl *object;
1523 hr = IDirectXFileDataImpl_Create(&object);
1524 if (hr != S_OK)
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;
1535 return DXFILE_OK;
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;
1589 object->ref = 1;
1591 *ppObj = object;
1593 return S_OK;
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);
1608 *ppvObject = This;
1609 return S_OK;
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);
1627 return ref;
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);
1637 if (!ref)
1638 HeapFree(GetProcessHeap(), 0, This);
1640 return ref;
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);
1650 if (!pstrNameBuf)
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);
1664 if (!pGuid)
1665 return DXFILEERR_BADVALUE;
1667 memcpy(pGuid, &This->ptarget->class_id, 16);
1669 return DXFILE_OK;
1672 /*** IDirectXFileDataReference ***/
1673 static HRESULT WINAPI IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference* iface, LPDIRECTXFILEDATA* ppDataObj)
1675 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
1676 IDirectXFileDataImpl *object;
1677 HRESULT hr;
1679 TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj);
1681 if (!ppDataObj)
1682 return DXFILEERR_BADVALUE;
1684 hr = IDirectXFileDataImpl_Create(&object);
1685 if (hr != S_OK)
1686 return DXFILEERR_BADVALUE;
1688 object->pobj = This->ptarget;
1689 object->cur_enum_object = 0;
1690 object->level = 0;
1691 object->from_ref = TRUE;
1693 *ppDataObj = (LPDIRECTXFILEDATA)object;
1695 return DXFILE_OK;
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;
1717 object->ref = 1;
1719 *ppObj = object;
1721 return S_OK;
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);
1735 *ppvObject = This;
1736 return S_OK;
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);
1750 return ref;
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);
1760 if (!ref)
1762 CloseHandle(This->hFile);
1763 HeapFree(GetProcessHeap(), 0, This);
1766 return ref;
1769 static BOOL parse_object_members_list(parse_buffer * buf)
1771 DWORD token;
1772 int i;
1773 xtemplate* pt = buf->pxt[buf->level];
1774 DWORD last_dword = 0;
1776 for (i = 0; i < pt->nb_members; i++)
1778 int nb_elems, k;
1780 if (pt->members[i].nb_dims > 1)
1782 FIXME("Arrays with dimension > 1 not yet supported\n");
1783 return FALSE;
1785 else if (pt->members[i].nb_dims)
1787 if (!pt->members[i].dim_fixed[0])
1789 if (!i)
1791 FIXME("Array with variable must be preceded by the size\n");
1792 return FALSE;
1794 nb_elems = last_dword;
1795 /*FIXME("Arrays with variable size not yet supported\n");
1796 return FALSE;*/
1798 else
1799 nb_elems = pt->members[i].dim_value[0];
1801 else
1802 nb_elems = 1;
1804 for (k = 0; k < nb_elems; k++)
1806 if (buf->txt && k)
1808 token = check_TOKEN(buf);
1809 if (token == TOKEN_COMMA)
1811 get_TOKEN(buf);
1813 else
1815 /* Allow comma omission */
1816 if (!((token == TOKEN_FLOAT)))
1817 return FALSE;
1821 if (pt->members[i].type == TOKEN_NAME)
1823 int j;
1825 TRACE("Found suboject %s\n", buf->pdxf->xtemplates[pt->members[i].idx_template].name);
1826 buf->level++;
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];
1833 break;
1836 if (j == buf->pdxf->nb_xtemplates)
1838 FIXME("Unknown template %s\n", (char*)buf->value);
1839 buf->level--;
1840 return FALSE;
1842 TRACE("Enter %s\n", buf->pdxf->xtemplates[pt->members[i].idx_template].name);
1843 if (!parse_object_parts(buf, FALSE))
1845 buf->level--;
1846 return FALSE;
1848 buf->level--;
1849 /*if (get_TOKEN(buf) != TOKEN_SEMICOLON)
1850 return FALSE;*/
1852 else
1854 token = check_TOKEN(buf);
1855 if (token == TOKEN_INTEGER)
1857 get_TOKEN(buf);
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");
1864 return FALSE;
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;
1876 else
1878 FIXME("Token %d not supported\n", pt->members[i].type);
1879 return FALSE;
1882 else if (token == TOKEN_FLOAT)
1884 get_TOKEN(buf);
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");
1890 return FALSE;
1892 if (pt->members[i].type == TOKEN_FLOAT)
1894 *(((float*)(buf->cur_pdata))) = (float)(*(float*)buf->value);
1895 buf->cur_pdata += 4;
1897 else
1899 FIXME("Token %d not supported\n", pt->members[i].type);
1900 return FALSE;
1903 else if (token == TOKEN_LPSTR)
1905 get_TOKEN(buf);
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");
1911 return FALSE;
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);
1919 return FALSE;
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;
1926 else
1928 FIXME("Token %d not supported\n", pt->members[i].type);
1929 return FALSE;
1932 else
1934 FIXME("Unexpected token %d\n", token);
1935 return FALSE;
1940 if (buf->txt)
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)))
1948 return FALSE;
1953 return TRUE;
1956 static BOOL parse_object_parts(parse_buffer * buf, BOOL allow_optional)
1958 if (!parse_object_members_list(buf))
1959 return FALSE;
1961 if (allow_optional)
1963 buf->pxo->size = buf->cur_pdata - buf->pxo->pdata;
1965 /* Skip trailing semicolon */
1966 while (check_TOKEN(buf) == TOKEN_SEMICOLON)
1967 get_TOKEN(buf);
1969 while (1)
1971 if (check_TOKEN(buf) == TOKEN_OBRACE)
1973 int i, j;
1974 get_TOKEN(buf);
1975 if (get_TOKEN(buf) != TOKEN_NAME)
1976 return FALSE;
1977 if (get_TOKEN(buf) != TOKEN_CBRACE)
1978 return FALSE;
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))
1985 goto _exit;
1988 _exit:
1989 if (i == buf->nb_pxo_globals)
1991 ERR("Reference to unknown object %s\n", (char*)buf->value);
1992 return FALSE;
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);
2004 buf->level++;
2005 if (!parse_object(buf))
2007 buf->level--;
2008 return FALSE;
2010 buf->level--;
2011 buf->pxo = pxo;
2012 buf->pxo->nb_childs++;
2014 else
2015 break;
2019 if (buf->pxo->nb_childs > MAX_CHILDS)
2021 FIXME("Too many childs %d\n", buf->pxo->nb_childs);
2022 return FALSE;
2025 return TRUE;
2028 static BOOL parse_object(parse_buffer * buf)
2030 int i;
2032 buf->pxo->pdata = buf->cur_pdata;
2033 buf->pxo->ptarget = NULL;
2035 if (get_TOKEN(buf) != TOKEN_NAME)
2036 return FALSE;
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);
2045 break;
2048 if (i == buf->pdxf->nb_xtemplates)
2050 FIXME("Unknown template %s\n", (char*)buf->value);
2051 return FALSE;
2054 if (check_TOKEN(buf) == TOKEN_NAME)
2056 get_TOKEN(buf);
2057 strcpy(buf->pxo->name, (char*)buf->value);
2059 else
2060 buf->pxo->name[0] = 0;
2062 if (get_TOKEN(buf) != TOKEN_OBRACE)
2063 return FALSE;
2064 if (check_TOKEN(buf) == TOKEN_GUID)
2066 get_TOKEN(buf);
2067 memcpy(&buf->pxo->class_id, buf->value, 16);
2069 else
2070 memset(&buf->pxo->class_id, 0, 16);
2072 if (!parse_object_parts(buf, TRUE))
2073 return FALSE;
2074 if (get_TOKEN(buf) != TOKEN_CBRACE)
2075 return FALSE;
2077 if (buf->txt)
2079 /* Go to the next object */
2080 while (buf->rem_bytes && is_space(*buf->buffer))
2082 buf->buffer++;
2083 buf->rem_bytes--;
2087 return TRUE;
2090 /*** IDirectXFileEnumObject methods ***/
2091 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject* iface, LPDIRECTXFILEDATA* ppDataObj)
2093 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
2094 IDirectXFileDataImpl* object;
2095 HRESULT hr;
2096 LPBYTE pdata;
2097 LPBYTE pstrings;
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);
2111 if (FAILED(hr))
2112 return hr;
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);
2122 if (!pdata)
2124 WARN("Out of memory\n");
2125 return DXFILEERR_BADALLOC;
2127 This->buf.cur_pdata = pdata;
2129 pstrings = HeapAlloc(GetProcessHeap(), 0, MAX_STRINGS_BUFFER);
2130 if (!pstrings)
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;
2156 object->level = 0;
2157 object->from_ref = FALSE;
2159 *ppDataObj = (LPDIRECTXFILEDATA)object;
2161 This->nb_xobjects++;
2163 return DXFILE_OK;
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;
2203 object->ref = 1;
2205 *ppObj = object;
2207 return S_OK;
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);
2221 *ppvObject = This;
2222 return S_OK;
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);
2236 return ref;
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);
2246 if (!ref)
2247 HeapFree(GetProcessHeap(), 0, This);
2249 return ref;
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;
2289 object->ref = 1;
2291 *ppObj = object;
2293 return S_OK;
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);
2307 *ppvObject = This;
2308 return S_OK;
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);
2322 return ref;
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);
2332 if (!ref)
2333 HeapFree(GetProcessHeap(), 0, This);
2335 return ref;
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