wined3d: Fix the num blend values -> type match.
[wine/multimedia.git] / dlls / d3dxof / d3dxof.c
blobca4eb73750b7b8dcc38ed3f26c1ff33bac29079b
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 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')
48 #define TOKEN_NAME 1
49 #define TOKEN_STRING 2
50 #define TOKEN_INTEGER 3
51 #define TOKEN_GUID 5
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
62 #define TOKEN_DOT 18
63 #define TOKEN_COMMA 19
64 #define TOKEN_SEMICOLON 20
65 #define TOKEN_TEMPLATE 31
66 #define TOKEN_WORD 40
67 #define TOKEN_DWORD 41
68 #define TOKEN_FLOAT 42
69 #define TOKEN_DOUBLE 43
70 #define TOKEN_CHAR 44
71 #define TOKEN_UCHAR 45
72 #define TOKEN_SWORD 46
73 #define TOKEN_SDWORD 47
74 #define TOKEN_VOID 48
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)
99 int j, k;
100 GUID* clsid;
102 clsid = &ptemplate->class_id;
104 DPRINTF("template %s\n", ptemplate->name);
105 DPRINTF("{\n");
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)
111 DPRINTF("array ");
112 if (ptemplate->members[j].type == TOKEN_NAME)
113 DPRINTF("%s ", templates_array[ptemplate->members[j].idx_template].name);
114 else
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]);
121 else
122 DPRINTF("[%s]", ptemplate->members[ptemplate->members[j].dim_value[k]].name);
124 DPRINTF(";\n");
126 if (ptemplate->open)
127 DPRINTF("[...]\n");
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]);
133 DPRINTF("]\n");
135 DPRINTF("}\n");
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;
147 object->ref = 1;
149 *ppObj = object;
151 return S_OK;
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);
165 *ppvObject = This;
166 return S_OK;
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);
180 return ref;
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);
190 if (!ref)
191 HeapFree(GetProcessHeap(), 0, This);
193 return ref;
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;
201 HRESULT hr;
202 DWORD header[4];
203 DWORD size;
204 HANDLE hFile = INVALID_HANDLE_VALUE;
206 TRACE("(%p/%p)->(%p,%x,%p)\n", This, iface, pvSource, dwLoadOptions, ppEnumObj);
208 if (!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;
225 goto error;
228 if (size < 16)
230 hr = DXFILEERR_BADFILETYPE;
231 goto error;
234 if (TRACE_ON(d3dxof))
236 char string[17];
237 memcpy(string, header, 16);
238 string[16] = 0;
239 TRACE("header = '%s'\n", string);
242 else
244 FIXME("Source type %d is not handled yet\n", dwLoadOptions);
245 hr = DXFILEERR_NOTDONEYET;
246 goto error;
249 if (header[0] != XOFFILE_FORMAT_MAGIC)
251 hr = DXFILEERR_BADFILETYPE;
252 goto error;
255 if (header[1] != XOFFILE_FORMAT_VERSION)
257 hr = DXFILEERR_BADFILEVERSION;
258 goto error;
261 if ((header[2] != XOFFILE_FORMAT_BINARY) && (header[2] != XOFFILE_FORMAT_TEXT) && (header[2] != XOFFILE_FORMAT_COMPRESSED))
263 hr = DXFILEERR_BADFILETYPE;
264 goto error;
267 if (header[2] == XOFFILE_FORMAT_BINARY)
269 FIXME("Binary format not supported yet\n");
270 hr = DXFILEERR_NOTDONEYET;
271 goto error;
274 if (header[2] == XOFFILE_FORMAT_COMPRESSED)
276 FIXME("Compressed formats not supported yet\n");
277 hr = DXFILEERR_BADVALUE;
278 goto error;
281 if ((header[3] != XOFFILE_FORMAT_FLOAT_BITS_32) && (header[3] != XOFFILE_FORMAT_FLOAT_BITS_64))
283 hr = DXFILEERR_BADFILEFLOATSIZE;
284 goto error;
287 TRACE("Header is correct\n");
289 hr = IDirectXFileEnumObjectImpl_Create(&object);
290 if (FAILED(hr))
291 goto error;
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;
306 goto error;
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;
315 goto error;
317 TRACE("Read %d bytes\n", object->buf.rem_bytes);
319 *ppEnumObj = (LPDIRECTXFILEENUMOBJECT)object;
321 return DXFILE_OK;
323 error:
324 if (hFile != INVALID_HANDLE_VALUE)
325 CloseHandle(hFile);
326 *ppEnumObj = NULL;
328 return hr;
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)
343 return FALSE;
344 memcpy(data, buf->buffer, size);
345 buf->buffer += size;
346 buf->rem_bytes -= size;
347 return TRUE;
350 static void dump_TOKEN(WORD token)
352 #define DUMP_TOKEN(t) case t: TRACE(#t "\n"); break
353 switch(token)
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);
386 default:
387 if (0)
388 TRACE("Unknown token %d\n", token);
389 break;
391 #undef DUMP_TOKEN
394 static BOOL is_space(char c)
396 switch (c)
398 case 0x00:
399 case 0x0D:
400 case 0x0A:
401 case ' ':
402 case '\t':
403 return TRUE;
405 return FALSE;
408 static BOOL is_operator(char c)
410 switch(c)
412 case '{':
413 case '}':
414 case '[':
415 case ']':
416 case '(':
417 case ')':
418 case '<':
419 case '>':
420 case ',':
421 case ';':
422 return TRUE;
424 return FALSE;
427 static inline BOOL is_separator(char c)
429 return is_space(c) || is_operator(c);
432 static WORD get_operator_token(char c)
434 switch(c)
436 case '{':
437 return TOKEN_OBRACE;
438 case '}':
439 return TOKEN_CBRACE;
440 case '[':
441 return TOKEN_OBRACKET;
442 case ']':
443 return TOKEN_CBRACKET;
444 case '(':
445 return TOKEN_OPAREN;
446 case ')':
447 return TOKEN_CPAREN;
448 case '<':
449 return TOKEN_OANGLE;
450 case '>':
451 return TOKEN_CANGLE;
452 case ',':
453 return TOKEN_COMMA;
454 case ';':
455 return TOKEN_SEMICOLON;
457 return 0;
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)))
465 buf->buffer += len;
466 buf->rem_bytes -= len;
467 return TRUE;
469 return FALSE;
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"))
477 return TOKEN_WORD;
478 if (is_keyword(buf, "DWORD"))
479 return TOKEN_DWORD;
480 if (is_keyword(buf, "FLOAT"))
481 return TOKEN_FLOAT;
482 if (is_keyword(buf, "DOUBLE"))
483 return TOKEN_DOUBLE;
484 if (is_keyword(buf, "CHAR"))
485 return TOKEN_CHAR;
486 if (is_keyword(buf, "UCHAR"))
487 return TOKEN_UCHAR;
488 if (is_keyword(buf, "SWORD"))
489 return TOKEN_SWORD;
490 if (is_keyword(buf, "SDWORD"))
491 return TOKEN_SDWORD;
492 if (is_keyword(buf, "VOID"))
493 return TOKEN_VOID;
494 if (is_keyword(buf, "STRING"))
495 return TOKEN_LPSTR;
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"))
501 return TOKEN_ARRAY;
503 return 0;
506 static BOOL is_guid(parse_buffer* buf)
508 char tmp[50];
509 DWORD pos = 1;
510 GUID class_id;
511 DWORD tab[10];
512 int ret;
514 if (*buf->buffer != '<')
515 return FALSE;
516 tmp[0] = '<';
517 while (*(buf->buffer+pos) != '>')
519 tmp[pos] = *(buf->buffer+pos);
520 pos++;
522 tmp[pos++] = '>';
523 tmp[pos] = 0;
524 if (pos != 38 /* <+36+> */)
526 TRACE("Wrong guid %s (%d)\n", tmp, pos);
527 return FALSE;
529 buf->buffer += 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);
533 if (ret != 11)
535 TRACE("Wrong guid %s (%d)\n", tmp, pos);
536 return FALSE;
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;
553 return TRUE;
556 static BOOL is_name(parse_buffer* buf)
558 char tmp[50];
559 DWORD pos = 0;
560 char c;
561 BOOL error = 0;
562 while (!is_separator(c = *(buf->buffer+pos)))
564 if (!(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9')) || (c == '_')))
565 error = 1;
566 tmp[pos++] = c;
568 tmp[pos] = 0;
570 if (error)
572 TRACE("Wrong name %s\n", tmp);
573 return FALSE;
576 buf->buffer += pos;
577 buf->rem_bytes -= pos;
579 TRACE("Found name %s\n", tmp);
580 strcpy((char*)buf->value, tmp);
582 return TRUE;
585 static BOOL is_float(parse_buffer* buf)
587 char tmp[50];
588 DWORD pos = 0;
589 char c;
590 float decimal;
591 BOOL dot = 0;
593 while (!is_separator(c = *(buf->buffer+pos)))
595 if (!((!pos && (c == '-')) || ((c >= '0') && (c <= '9')) || (!dot && (c == '.'))))
596 return FALSE;
597 if (c == '.')
598 dot = TRUE;
599 tmp[pos++] = c;
601 tmp[pos] = 0;
603 buf->buffer += pos;
604 buf->rem_bytes -= pos;
606 sscanf(tmp, "%f", &decimal);
608 TRACE("Found float %s - %f\n", tmp, decimal);
610 *(float*)buf->value = decimal;
612 return TRUE;
615 static BOOL is_integer(parse_buffer* buf)
617 char tmp[50];
618 DWORD pos = 0;
619 char c;
620 DWORD integer;
622 while (!is_separator(c = *(buf->buffer+pos)))
624 if (!((c >= '0') && (c <= '9')))
625 return FALSE;
626 tmp[pos++] = c;
628 tmp[pos] = 0;
630 buf->buffer += pos;
631 buf->rem_bytes -= pos;
633 sscanf(tmp, "%d", &integer);
635 TRACE("Found integer %s - %d\n", tmp, integer);
637 *(DWORD*)buf->value = integer;
639 return TRUE;
642 static BOOL is_string(parse_buffer* buf)
644 char tmp[32];
645 DWORD pos = 1;
646 char c;
647 BOOL ok = 0;
649 if (*buf->buffer != '"')
650 return FALSE;
651 tmp[0] = '"';
653 while (!is_separator(c = *(buf->buffer+pos)) && (pos < 32))
655 tmp[pos++] = c;
656 if (c == '"')
658 ok = 1;
659 break;
662 tmp[pos] = 0;
664 if (!ok)
666 TRACE("Wrong string %s\n", tmp);
667 return FALSE;
670 buf->buffer += pos;
671 buf->rem_bytes -= pos;
673 TRACE("Found string %s\n", tmp);
674 strcpy((char*)buf->value, tmp);
676 return TRUE;
679 static WORD parse_TOKEN(parse_buffer * buf)
681 WORD token;
683 if (buf->txt)
685 while(1)
687 char c;
688 if (!read_bytes(buf, &c, 1))
689 return 0;
690 /*TRACE("char = '%c'\n", is_space(c) ? ' ' : c);*/
691 if ((c == '#') || (c == '/'))
693 /* Handle comment (# or //) */
694 if (c == '/')
696 if (!read_bytes(buf, &c, 1))
697 return 0;
698 if (c != '/')
699 return 0;
701 c = 0;
702 while (c != 0x0A)
704 if (!read_bytes(buf, &c, 1))
705 return 0;
707 continue;
709 if (is_space(c))
710 continue;
711 if (is_operator(c) && (c != '<'))
713 token = get_operator_token(c);
714 break;
716 else if (c == '.')
718 token = TOKEN_DOT;
719 break;
721 else
723 buf->buffer -= 1;
724 buf->rem_bytes += 1;
726 if ((token = get_keyword_token(buf)))
727 break;
729 if (is_guid(buf))
731 token = TOKEN_GUID;
732 break;
734 if (is_integer(buf))
736 token = TOKEN_INTEGER;
737 break;
739 if (is_float(buf))
741 token = TOKEN_FLOAT;
742 break;
744 if (is_string(buf))
746 token = TOKEN_LPSTR;
747 break;
749 if (is_name(buf))
751 token = TOKEN_NAME;
752 break;
755 FIXME("Unrecognize element\n");
756 return 0;
760 else
762 if (!read_bytes(buf, &token, 2))
763 return 0;
765 switch(token)
767 case TOKEN_NAME:
769 DWORD count;
770 char strname[100];
772 if (!read_bytes(buf, &count, 4))
773 return 0;
774 if (!read_bytes(buf, strname, count))
775 return 0;
776 strname[count] = 0;
777 /*TRACE("name = %s\n", strname);*/
779 strcpy((char*)buf->value, strname);
781 break;
782 case TOKEN_INTEGER:
784 DWORD integer;
786 if (!read_bytes(buf, &integer, 4))
787 return 0;
788 /*TRACE("integer = %ld\n", integer);*/
790 *(DWORD*)buf->value = integer;
792 break;
793 case TOKEN_GUID:
795 char strguid[38];
796 GUID class_id;
798 if (!read_bytes(buf, &class_id, 16))
799 return 0;
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;
807 break;
808 case TOKEN_STRING:
809 case TOKEN_INTEGER_LIST:
810 case TOKEN_FLOAT_LIST:
811 case TOKEN_OBRACE:
812 case TOKEN_CBRACE:
813 case TOKEN_OPAREN:
814 case TOKEN_CPAREN:
815 case TOKEN_OBRACKET:
816 case TOKEN_CBRACKET:
817 case TOKEN_OANGLE:
818 case TOKEN_CANGLE:
819 case TOKEN_DOT:
820 case TOKEN_COMMA:
821 case TOKEN_SEMICOLON:
822 case TOKEN_TEMPLATE:
823 case TOKEN_WORD:
824 case TOKEN_DWORD:
825 case TOKEN_FLOAT:
826 case TOKEN_DOUBLE:
827 case TOKEN_CHAR:
828 case TOKEN_UCHAR:
829 case TOKEN_SWORD:
830 case TOKEN_SDWORD:
831 case TOKEN_VOID:
832 case TOKEN_LPSTR:
833 case TOKEN_UNICODE:
834 case TOKEN_CSTRING:
835 case TOKEN_ARRAY:
836 break;
837 default:
838 return 0;
842 dump_TOKEN(token);
844 return token;
847 static const char* get_primitive_string(WORD token)
849 switch(token)
851 case TOKEN_WORD:
852 return "WORD";
853 case TOKEN_DWORD:
854 return "DWORD";
855 case TOKEN_FLOAT:
856 return "FLOAT";
857 case TOKEN_DOUBLE:
858 return "DOUBLE";
859 case TOKEN_CHAR:
860 return "CHAR";
861 case TOKEN_UCHAR:
862 return "UCHAR";
863 case TOKEN_SWORD:
864 return "SWORD";
865 case TOKEN_SDWORD:
866 return "SDWORD";
867 case TOKEN_VOID:
868 return "VOID";
869 case TOKEN_LPSTR:
870 return "STRING";
871 case TOKEN_UNICODE:
872 return "UNICODE";
873 case TOKEN_CSTRING:
874 return "CSTRING ";
875 default:
876 break;
878 return NULL;
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)
907 BOOL ret;
908 switch(token)
910 case TOKEN_WORD:
911 case TOKEN_DWORD:
912 case TOKEN_FLOAT:
913 case TOKEN_DOUBLE:
914 case TOKEN_CHAR:
915 case TOKEN_UCHAR:
916 case TOKEN_SWORD:
917 case TOKEN_SDWORD:
918 case TOKEN_LPSTR:
919 case TOKEN_UNICODE:
920 case TOKEN_CSTRING:
921 ret = 1;
922 break;
923 default:
924 ret = 0;
925 break;
927 return ret;
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)
936 get_TOKEN(buf);
937 if (get_TOKEN(buf) != TOKEN_DOT)
938 return FALSE;
939 if (get_TOKEN(buf) != TOKEN_DOT)
940 return FALSE;
941 cur_template->open = TRUE;
943 else
945 while (1)
947 if (get_TOKEN(buf) != TOKEN_NAME)
948 return FALSE;
949 strcpy(cur_template->childs[cur_template->nb_childs], (char*)buf->value);
950 if (check_TOKEN(buf) == TOKEN_GUID)
951 get_TOKEN(buf);
952 cur_template->nb_childs++;
953 if (check_TOKEN(buf) != TOKEN_COMMA)
954 break;
955 get_TOKEN(buf);
957 cur_template->open = FALSE;
960 return TRUE;
963 static BOOL parse_template_members_list(parse_buffer * buf)
965 int idx_member = 0;
966 member* cur_member;
968 while (1)
970 BOOL array = 0;
971 int nb_dims = 0;
972 cur_member = &buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].members[idx_member];
974 if (check_TOKEN(buf) == TOKEN_ARRAY)
976 get_TOKEN(buf);
977 array = 1;
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))
987 break;
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);
993 return FALSE;
996 else if (is_primitive_type(check_TOKEN(buf)))
997 cur_member->type = get_TOKEN(buf);
998 else
999 break;
1001 if (get_TOKEN(buf) != TOKEN_NAME)
1002 return FALSE;
1003 strcpy(cur_member->name, (char*)buf->value);
1005 if (array)
1007 while (check_TOKEN(buf) == TOKEN_OBRACKET)
1009 if (nb_dims)
1011 FIXME("No support for multi-dimensional array yet\n");
1012 return FALSE;
1014 get_TOKEN(buf);
1015 if (check_TOKEN(buf) == TOKEN_INTEGER)
1017 get_TOKEN(buf);
1018 cur_member->dim_fixed[nb_dims] = TRUE;
1019 cur_member->dim_value[nb_dims] = *(DWORD*)buf->value;
1021 else
1023 if (get_TOKEN(buf) != TOKEN_NAME)
1024 return FALSE;
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)
1030 return FALSE;
1031 nb_dims++;
1033 if (!nb_dims)
1034 return FALSE;
1035 cur_member->nb_dims = nb_dims;
1037 if (get_TOKEN(buf) != TOKEN_SEMICOLON)
1038 return FALSE;
1040 idx_member++;
1043 buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].nb_members = idx_member;
1045 return TRUE;
1048 static BOOL parse_template_parts(parse_buffer * buf)
1050 if (!parse_template_members_list(buf))
1051 return FALSE;
1052 if (check_TOKEN(buf) == TOKEN_OBRACKET)
1054 get_TOKEN(buf);
1055 if (!parse_template_option_info(buf))
1056 return FALSE;
1057 if (get_TOKEN(buf) != TOKEN_CBRACKET)
1058 return FALSE;
1061 return TRUE;
1064 static BOOL parse_template(parse_buffer * buf)
1066 if (get_TOKEN(buf) != TOKEN_TEMPLATE)
1067 return FALSE;
1068 if (get_TOKEN(buf) != TOKEN_NAME)
1069 return FALSE;
1070 strcpy(buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].name, (char*)buf->value);
1071 if (get_TOKEN(buf) != TOKEN_OBRACE)
1072 return FALSE;
1073 if (get_TOKEN(buf) != TOKEN_GUID)
1074 return FALSE;
1075 buf->pdxf->xtemplates[buf->pdxf->nb_xtemplates].class_id = *(GUID*)buf->value;
1076 if (!parse_template_parts(buf))
1077 return FALSE;
1078 if (get_TOKEN(buf) != TOKEN_CBRACE)
1079 return FALSE;
1080 if (buf->txt)
1082 /* Go to the next template */
1083 while (buf->rem_bytes && is_space(*buf->buffer))
1085 buf->buffer++;
1086 buf->rem_bytes--;
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++;
1093 return TRUE;
1096 static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LPVOID pvData, DWORD cbSize)
1098 IDirectXFileImpl *This = (IDirectXFileImpl *)iface;
1099 DWORD token_header;
1100 parse_buffer buf;
1102 buf.buffer = (LPBYTE)pvData;
1103 buf.rem_bytes = cbSize;
1104 buf.txt = FALSE;
1105 buf.token_present = FALSE;
1106 buf.pdxf = This;
1108 TRACE("(%p/%p)->(%p,%d)\n", This, iface, pvData, cbSize);
1110 if (!pvData)
1111 return DXFILEERR_BADVALUE;
1113 if (cbSize < 16)
1114 return DXFILEERR_BADFILETYPE;
1116 if (TRACE_ON(d3dxof))
1118 char string[17];
1119 memcpy(string, pvData, 16);
1120 string[16] = 0;
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)
1141 buf.txt = TRUE;
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;
1164 else
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))
1174 int i;
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));
1180 return DXFILE_OK;
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;
1202 object->ref = 1;
1204 *ppObj = object;
1206 return DXFILE_OK;
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);
1221 *ppvObject = This;
1222 return S_OK;
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);
1240 return ref;
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);
1250 if (!ref)
1251 HeapFree(GetProcessHeap(), 0, This);
1253 return ref;
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;
1325 object->ref = 1;
1327 *ppObj = object;
1329 return S_OK;
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);
1344 *ppvObject = This;
1345 return S_OK;
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);
1363 return ref;
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);
1373 if (!ref)
1374 HeapFree(GetProcessHeap(), 0, This);
1376 return ref;
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);
1387 if (!pstrNameBuf)
1388 return DXFILEERR_BADVALUE;
1390 strcpy(pstrNameBuf, This->pobj->name);
1392 return DXFILE_OK;
1395 static HRESULT WINAPI IDirectXFileDataImpl_GetId(IDirectXFileData* iface, LPGUID pGuid)
1397 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
1399 TRACE("(%p/%p)->(%p)\n", This, iface, pGuid);
1401 if (!pGuid)
1402 return DXFILEERR_BADVALUE;
1404 memcpy(pGuid, &This->pobj->class_id, 16);
1406 return DXFILE_OK;
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;
1419 if (szMember)
1421 FIXME("Specifying a member is not supported yet!\n");
1422 return DXFILEERR_BADVALUE;
1425 *pcbSize = This->pobj->size;
1426 *ppvData = This->pobj->pdata;
1428 return DXFILE_OK;
1431 static HRESULT WINAPI IDirectXFileDataImpl_GetType(IDirectXFileData* iface, const GUID** pguid)
1433 IDirectXFileDataImpl *This = (IDirectXFileDataImpl *)iface;
1434 static GUID guid;
1436 TRACE("(%p/%p)->(%p)\n", This, iface, pguid);
1438 if (!pguid)
1439 return DXFILEERR_BADVALUE;
1441 memcpy(&guid, &This->pobj->type, 16);
1442 *pguid = &guid;
1444 return DXFILE_OK;
1447 static HRESULT WINAPI IDirectXFileDataImpl_GetNextObject(IDirectXFileData* iface, LPDIRECTXFILEOBJECT* ppChildObj)
1449 HRESULT hr;
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);
1468 if (hr != S_OK)
1469 return DXFILEERR_BADVALUE;
1471 object->ptarget = This->pobj->childs[This->cur_enum_object++]->ptarget;
1473 *ppChildObj = (LPDIRECTXFILEOBJECT)object;
1475 else
1477 IDirectXFileDataImpl *object;
1479 hr = IDirectXFileDataImpl_Create(&object);
1480 if (hr != S_OK)
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;
1491 return DXFILE_OK;
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;
1545 object->ref = 1;
1547 *ppObj = object;
1549 return S_OK;
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);
1564 *ppvObject = This;
1565 return S_OK;
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);
1583 return ref;
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);
1593 if (!ref)
1594 HeapFree(GetProcessHeap(), 0, This);
1596 return ref;
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);
1606 if (!pstrNameBuf)
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);
1620 if (!pGuid)
1621 return DXFILEERR_BADVALUE;
1623 memcpy(pGuid, &This->ptarget->class_id, 16);
1625 return DXFILE_OK;
1628 /*** IDirectXFileDataReference ***/
1629 static HRESULT WINAPI IDirectXFileDataReferenceImpl_Resolve(IDirectXFileDataReference* iface, LPDIRECTXFILEDATA* ppDataObj)
1631 IDirectXFileDataReferenceImpl *This = (IDirectXFileDataReferenceImpl *)iface;
1632 IDirectXFileDataImpl *object;
1633 HRESULT hr;
1635 TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj);
1637 if (!ppDataObj)
1638 return DXFILEERR_BADVALUE;
1640 hr = IDirectXFileDataImpl_Create(&object);
1641 if (hr != S_OK)
1642 return DXFILEERR_BADVALUE;
1644 object->pobj = This->ptarget;
1645 object->cur_enum_object = 0;
1646 object->level = 0;
1647 object->from_ref = TRUE;
1649 *ppDataObj = (LPDIRECTXFILEDATA)object;
1651 return DXFILE_OK;
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;
1673 object->ref = 1;
1675 *ppObj = object;
1677 return S_OK;
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);
1691 *ppvObject = This;
1692 return S_OK;
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);
1706 return ref;
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);
1716 if (!ref)
1717 HeapFree(GetProcessHeap(), 0, This);
1719 return ref;
1722 static BOOL parse_object_members_list(parse_buffer * buf)
1724 DWORD token;
1725 int i;
1726 xtemplate* pt = buf->pxt[buf->level];
1727 DWORD last_dword = 0;
1729 for (i = 0; i < pt->nb_members; i++)
1731 int nb_elems, k;
1733 if (pt->members[i].nb_dims > 1)
1735 FIXME("Arrays with dimension > 1 not yet supported\n");
1736 return FALSE;
1738 else if (pt->members[i].nb_dims)
1740 if (!pt->members[i].dim_fixed[0])
1742 if (!i)
1744 FIXME("Array with variable must be preceded by the size\n");
1745 return FALSE;
1747 nb_elems = last_dword;
1748 /*FIXME("Arrays with variable size not yet supported\n");
1749 return FALSE;*/
1751 else
1752 nb_elems = pt->members[i].dim_value[0];
1754 else
1755 nb_elems = 1;
1757 for (k = 0; k < nb_elems; k++)
1759 if (k)
1761 token = check_TOKEN(buf);
1762 if (token == TOKEN_COMMA)
1764 get_TOKEN(buf);
1766 else
1768 /* Allow comma omission */
1769 if (!((token == TOKEN_FLOAT)))
1770 return FALSE;
1774 if (pt->members[i].type == TOKEN_NAME)
1776 int j;
1778 TRACE("Found suboject %s\n", buf->pdxf->xtemplates[pt->members[i].idx_template].name);
1779 buf->level++;
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];
1786 break;
1789 if (j == buf->pdxf->nb_xtemplates)
1791 FIXME("Unknown template %s\n", (char*)buf->value);
1792 buf->level--;
1793 return FALSE;
1795 TRACE("Enter %s\n", buf->pdxf->xtemplates[pt->members[i].idx_template].name);
1796 if (!parse_object_parts(buf, FALSE))
1798 buf->level--;
1799 return FALSE;
1801 buf->level--;
1802 /*if (get_TOKEN(buf) != TOKEN_SEMICOLON)
1803 return FALSE;*/
1805 else
1807 token = check_TOKEN(buf);
1808 if (token == TOKEN_INTEGER)
1810 get_TOKEN(buf);
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");
1817 return FALSE;
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;
1829 else
1831 FIXME("Token %d not supported\n", pt->members[i].type);
1832 return FALSE;
1835 else if (token == TOKEN_FLOAT)
1837 get_TOKEN(buf);
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");
1843 return FALSE;
1845 if (pt->members[i].type == TOKEN_FLOAT)
1847 *(((float*)(buf->cur_pdata))) = (float)(*(float*)buf->value);
1848 buf->cur_pdata += 4;
1850 else
1852 FIXME("Token %d not supported\n", pt->members[i].type);
1853 return FALSE;
1856 else if (token == TOKEN_LPSTR)
1858 static char fake_string[] = "Fake string";
1859 get_TOKEN(buf);
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");
1865 return FALSE;
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;
1873 else
1875 FIXME("Token %d not supported\n", pt->members[i].type);
1876 return FALSE;
1879 else
1881 FIXME("Unexpected token %d\n", token);
1882 return FALSE;
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)))
1893 return FALSE;
1897 return TRUE;
1900 static BOOL parse_object_parts(parse_buffer * buf, BOOL allow_optional)
1902 if (!parse_object_members_list(buf))
1903 return FALSE;
1905 if (allow_optional)
1907 buf->pxo->size = buf->cur_pdata - buf->pxo->pdata;
1909 /* Skip trailing semicolon */
1910 while (check_TOKEN(buf) == TOKEN_SEMICOLON)
1911 get_TOKEN(buf);
1913 while (1)
1915 if (check_TOKEN(buf) == TOKEN_OBRACE)
1917 int i, j;
1918 get_TOKEN(buf);
1919 if (get_TOKEN(buf) != TOKEN_NAME)
1920 return FALSE;
1921 if (get_TOKEN(buf) != TOKEN_CBRACE)
1922 return FALSE;
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))
1929 goto _exit;
1932 _exit:
1933 if (i == buf->nb_pxo_globals)
1935 ERR("Reference to unknown object %s\n", (char*)buf->value);
1936 return FALSE;
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);
1948 buf->level++;
1949 if (!parse_object(buf))
1951 buf->level--;
1952 return FALSE;
1954 buf->level--;
1955 buf->pxo = pxo;
1956 buf->pxo->nb_childs++;
1958 else
1959 break;
1963 return TRUE;
1966 static BOOL parse_object(parse_buffer * buf)
1968 int i;
1970 buf->pxo->pdata = buf->cur_pdata;
1971 buf->pxo->ptarget = NULL;
1973 if (get_TOKEN(buf) != TOKEN_NAME)
1974 return FALSE;
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);
1983 break;
1986 if (i == buf->pdxf->nb_xtemplates)
1988 FIXME("Unknown template %s\n", (char*)buf->value);
1989 return FALSE;
1992 if (check_TOKEN(buf) == TOKEN_NAME)
1994 get_TOKEN(buf);
1995 strcpy(buf->pxo->name, (char*)buf->value);
1997 else
1998 buf->pxo->name[0] = 0;
2000 if (get_TOKEN(buf) != TOKEN_OBRACE)
2001 return FALSE;
2002 if (check_TOKEN(buf) == TOKEN_GUID)
2004 get_TOKEN(buf);
2005 memcpy(&buf->pxo->class_id, buf->value, 16);
2007 else
2008 memset(&buf->pxo->class_id, 0, 16);
2010 if (!parse_object_parts(buf, TRUE))
2011 return FALSE;
2012 if (get_TOKEN(buf) != TOKEN_CBRACE)
2013 return FALSE;
2015 if (buf->txt)
2017 /* Go to the next object */
2018 while (buf->rem_bytes && is_space(*buf->buffer))
2020 buf->buffer++;
2021 buf->rem_bytes--;
2025 return TRUE;
2028 /*** IDirectXFileEnumObject methods ***/
2029 static HRESULT WINAPI IDirectXFileEnumObjectImpl_GetNextDataObject(IDirectXFileEnumObject* iface, LPDIRECTXFILEDATA* ppDataObj)
2031 IDirectXFileEnumObjectImpl *This = (IDirectXFileEnumObjectImpl *)iface;
2032 IDirectXFileDataImpl* object;
2033 HRESULT hr;
2034 LPBYTE pdata;
2036 TRACE("(%p/%p)->(%p)\n", This, iface, ppDataObj);
2038 if (!This->buf.rem_bytes)
2039 return DXFILEERR_NOMOREOBJECTS;
2041 hr = IDirectXFileDataImpl_Create(&object);
2042 if (FAILED(hr))
2043 return hr;
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);
2052 if (!pdata)
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;
2071 object->level = 0;
2072 object->from_ref = FALSE;
2074 *ppDataObj = (LPDIRECTXFILEDATA)object;
2076 This->nb_xobjects++;
2078 return DXFILE_OK;
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;
2118 object->ref = 1;
2120 *ppObj = object;
2122 return S_OK;
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);
2136 *ppvObject = This;
2137 return S_OK;
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);
2151 return ref;
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);
2161 if (!ref)
2162 HeapFree(GetProcessHeap(), 0, This);
2164 return ref;
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;
2204 object->ref = 1;
2206 *ppObj = object;
2208 return S_OK;
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);
2222 *ppvObject = This;
2223 return S_OK;
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);
2237 return ref;
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);
2247 if (!ref)
2248 HeapFree(GetProcessHeap(), 0, This);
2250 return ref;
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