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