wshom.ocx: Implement get_Item() for IWshEnvironment.
[wine.git] / dlls / d3dxof / tests / d3dxof.c
blob0573e4a87c7bcc9b74372ffdd29bf06a679b28cc
1 /*
2 * Some unit tests for d3dxof
4 * Copyright (C) 2008, 2013 Christian Costa
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #define COBJMACROS
22 #include <stdio.h>
24 #include "wine/test.h"
25 #include "initguid.h"
26 #include "dxfile.h"
27 #include "rmxftmpl.h"
29 #define I2(x) x,0
30 #define I4(x) x,0,0,0
32 #define TOKEN_NAME I2(1)
33 #define TOKEN_STRING I2(2)
34 #define TOKEN_INTEGER I2(3)
35 #define TOKEN_INTEGER_LIST I2(6)
36 #define TOKEN_OBRACE I2(10)
37 #define TOKEN_CBRACE I2(11)
38 #define TOKEN_COMMA I2(19)
39 #define TOKEN_SEMICOLON I2(20)
41 #define SEMICOLON_5X TOKEN_SEMICOLON, TOKEN_SEMICOLON, TOKEN_SEMICOLON, TOKEN_SEMICOLON, TOKEN_SEMICOLON
43 static HMODULE hd3dxof;
44 static HRESULT (WINAPI *pDirectXFileCreate)(LPDIRECTXFILE*);
46 static char template[] =
47 "xof 0302txt 0064\n"
48 "template Header\n"
49 "{\n"
50 "<3D82AB43-62DA-11CF-AB39-0020AF71E433>\n"
51 "WORD major;\n"
52 "WORD minor;\n"
53 "DWORD flags;\n"
54 "}\n";
56 /* Same version as above compressed with mszip */
57 static char compressed_template[] =
58 "xof 0302tzip0064\x71\x00\x00\x00\x61\x00\x5a\x00"
59 "\x43\x4B\x2B\x49\xCD\x2D\xC8\x49\x2C\x49\x55\xF0\x48\x4D\x4C\x49"
60 "\x2D\xE2\xAA\xE6\xB2\x31\x76\xB1\x30\x72\x74\x32\x31\xD6\x35\x33"
61 "\x72\x71\xD4\x35\x34\x74\x76\xD3\x75\x74\x32\xB6\xD4\x35\x30\x30"
62 "\x32\x70\x74\x33\x37\x74\x35\x31\x36\xB6\xE3\x0A\xF7\x0F\x72\x51"
63 "\xC8\x4D\xCC\xCA\x2F\xB2\x86\xB2\x33\xF3\x40\x6C\x17\x30\x27\x2D"
64 "\x27\x31\xBD\xD8\x9A\xAB\x96\x8B\x0B\x00";
66 static char object[] =
67 "xof 0302txt 0064\n"
68 "Header Object\n"
69 "{\n"
70 "1; 2; 3;\n"
71 "}\n";
73 /* Same version as above compressed with mszip */
74 static char compressed_object[] =
75 "xof 0302tzip0064\x2c\x00\x00\x00\x1c\x00\x20\x00"
76 "\x43\x4b\xf3\x48\x4d\x4c\x49\x2d\x52\xf0\x4f\xca\x4a\x4d\x2e\xe1"
77 "\xaa\xe6\x32\xb4\x56\x30\xb2\x56\x30\xb6\xe6\xaa\xe5\xe2\x02\x00";
79 static char empty_txt_file[] = "xof 0302txt 0064";
80 static char empty_bin_file[] = "xof 0302bin 0064";
81 /* MSZip data is generated with the command "MAKECAB.EXE /D Compress=ON /D CompressionType=MSZip file packed"
82 * Data in cab is after the filename (null terminated) and the 32-bit checksum:
83 * size (16-bit), packed_size (16-bit) and compressed data (with leading 16-bit CK signature)
84 * for each MSZIP chunk whose decompressed size cannot exceed 32768 bytes
85 * Data in x files is preceded by the size (32-bit) of the decompressed file including the xof header (16 bytes)
86 * It does not seem possible to generate an MSZip data chunk with no byte, so put just 1 byte here */
87 /* "\n" packed with MSZip => no text */
88 static char empty_tzip_file[] = "xof 0302tzip0064\x11\x00\x00\x00\x01\x00\x05\x00\x43\x4b\xe3\x02\x00";
89 /* "\n" packed with MSZip => no token (token are 16-bit and there is only 1 byte) */
90 static char empty_bzip_file[] = "xof 0302bzip0064\x11\x00\x00\x00\x01\x00\x05\x00\x43\x4b\xe3\x02\x00";
91 static char empty_cmp_file[] = "xof 0302cmp 0064";
92 static char empty_xxxx_file[] = "xof 0302xxxx0064";
94 static char templates_bad_file_type1[] = "xOf 0302txt 0064\n";
95 static char templates_bad_file_version[] = "xof 0102txt 0064\n";
96 static char templates_bad_file_type2[] = "xof 0302foo 0064\n";
97 static char templates_bad_file_float_size[] = "xof 0302txt 0050\n";
99 static char templates_parse_error[] =
100 "xof 0302txt 0064"
101 "foobar;\n";
103 static char object_noname[] =
104 "xof 0302txt 0064\n"
105 "Header\n"
106 "{\n"
107 "1; 2; 3;\n"
108 "}\n";
110 static char template_syntax_array_mixed[] =
111 "xof 0302txt 0064\n"
112 "template Buffer\n"
113 "{\n"
114 "<3D82AB43-62DA-11CF-AB39-0020AF71E433>\n"
115 "DWORD num_elem;\n"
116 "array DWORD value[num_elem];\n"
117 "DWORD dummy;\n"
118 "}\n";
120 static char object_syntax_empty_array[] =
121 "xof 0302txt 0064\n"
122 "Buffer\n"
123 "{\n"
124 "0;\n"
125 "1234;\n"
126 "}\n";
128 static char object_syntax_semicolon_txt[] =
129 "xof 0302txt 0064\n"
130 "Buffer\n"
131 "{\n"
132 "3;\n"
133 "0; 1; 2;\n"
134 "5;\n"
135 "}\n";
137 static char object_syntax_semicolon_bin[] = {
138 'x','o','f',' ','0','3','0','2','b','i','n',' ','0','0','6','4',
139 TOKEN_NAME, /* size */ I4(6), /* name */ 'B','u','f','f','e','r', TOKEN_OBRACE,
140 TOKEN_INTEGER, I4(3), TOKEN_SEMICOLON,
141 TOKEN_INTEGER, I4(0), TOKEN_SEMICOLON, TOKEN_INTEGER, I4(1), TOKEN_SEMICOLON, TOKEN_INTEGER, I4(2), TOKEN_SEMICOLON,
142 TOKEN_INTEGER, I4(5), TOKEN_SEMICOLON,
143 TOKEN_CBRACE
146 static char object_syntax_comma_txt[] =
147 "xof 0302txt 0064\n"
148 "Buffer\n"
149 "{\n"
150 "3,\n"
151 "0, 1, 2,\n"
152 "5,\n"
153 "}\n";
155 static char object_syntax_comma_bin[] = {
156 'x','o','f',' ','0','3','0','2','b','i','n',' ','0','0','6','4',
157 TOKEN_NAME, /* size */ I4(6), /* name */ 'B','u','f','f','e','r', TOKEN_OBRACE,
158 TOKEN_INTEGER, I4(3), TOKEN_COMMA,
159 TOKEN_INTEGER, I4(0), TOKEN_COMMA, TOKEN_INTEGER, I4(1), TOKEN_COMMA, TOKEN_INTEGER, I4(2), TOKEN_COMMA,
160 TOKEN_INTEGER, I4(5), TOKEN_COMMA,
161 TOKEN_CBRACE
164 static char object_syntax_multi_semicolons_txt[] =
165 "xof 0302txt 0064\n"
166 "Buffer\n"
167 "{\n"
168 "3;;;;;\n"
169 "0;;;;; 1;;;;; 2;;;;;\n"
170 "5;;;;;\n"
171 "}\n";
173 static char object_syntax_multi_semicolons_bin[] = {
174 'x','o','f',' ','0','3','0','2','b','i','n',' ','0','0','6','4',
175 TOKEN_NAME, /* size */ I4(6), /* name */ 'B','u','f','f','e','r', TOKEN_OBRACE,
176 TOKEN_INTEGER, I4(3), SEMICOLON_5X,
177 TOKEN_INTEGER, I4(0), SEMICOLON_5X, TOKEN_INTEGER, I4(1), SEMICOLON_5X, TOKEN_INTEGER, I4(2), SEMICOLON_5X,
178 TOKEN_INTEGER, I4(5), SEMICOLON_5X,
179 TOKEN_CBRACE
182 static char object_syntax_multi_commas_txt[] =
183 "xof 0302txt 0064\n"
184 "Buffer\n"
185 "{\n"
186 "3;\n"
187 "0, 1,, 2;\n"
188 "5;\n"
189 "}\n";
191 static char object_syntax_multi_commas_bin[] = {
192 'x','o','f',' ','0','3','0','2','b','i','n',' ','0','0','6','4',
193 TOKEN_NAME, /* size */ I4(6), /* name */ 'B','u','f','f','e','r', TOKEN_OBRACE,
194 TOKEN_INTEGER, I4(3), TOKEN_SEMICOLON,
195 TOKEN_INTEGER, I4(0), TOKEN_COMMA, TOKEN_INTEGER, I4(1), TOKEN_COMMA, TOKEN_COMMA, TOKEN_INTEGER, I4(2), TOKEN_SEMICOLON,
196 TOKEN_INTEGER, I4(5), TOKEN_SEMICOLON,
197 TOKEN_CBRACE
200 static char object_syntax_multi_semicolons_and_comma_txt[] =
201 "xof 0302txt 0064\n"
202 "Buffer\n"
203 "{\n"
204 "3;;;;;,\n"
205 "0;;;;;, 1;;;;;, 2;;;;;,\n"
206 "5;;;;;,\n"
207 "}\n";
209 static char object_syntax_multi_semicolons_and_comma_bin[] = {
210 'x','o','f',' ','0','3','0','2','b','i','n',' ','0','0','6','4',
211 TOKEN_NAME, /* size */ I4(6), /* name */ 'B','u','f','f','e','r', TOKEN_OBRACE,
212 TOKEN_INTEGER, I4(3), SEMICOLON_5X, TOKEN_COMMA,
213 TOKEN_INTEGER, I4(0), SEMICOLON_5X, TOKEN_COMMA, TOKEN_INTEGER, I4(1), SEMICOLON_5X, TOKEN_COMMA, TOKEN_INTEGER, I4(2), SEMICOLON_5X, TOKEN_COMMA,
214 TOKEN_INTEGER, I4(5), SEMICOLON_5X, TOKEN_COMMA,
215 TOKEN_CBRACE
218 static char object_syntax_comma_and_semicolon_txt[] =
219 "xof 0302txt 0064\n"
220 "Buffer\n"
221 "{\n"
222 "3;\n"
223 "0, 1,; 2;\n"
224 "5;\n"
225 "}\n";
227 static char object_syntax_comma_and_semicolon_bin[] = {
228 'x','o','f',' ','0','3','0','2','b','i','n',' ','0','0','6','4',
229 TOKEN_NAME, /* size */ I4(6), /* name */ 'B','u','f','f','e','r', TOKEN_OBRACE,
230 TOKEN_INTEGER, I4(3), TOKEN_SEMICOLON,
231 TOKEN_INTEGER, I4(0), TOKEN_COMMA, TOKEN_INTEGER, I4(1), TOKEN_COMMA, TOKEN_SEMICOLON, TOKEN_INTEGER, I4(2), TOKEN_SEMICOLON,
232 TOKEN_INTEGER, I4(5), TOKEN_SEMICOLON,
233 TOKEN_CBRACE
236 static char object_syntax_no_ending_separator_txt[] =
237 "xof 0302txt 0064\n"
238 "Buffer\n"
239 "{\n"
240 "3;\n"
241 "0, 1, 2;\n"
242 "5\n"
243 "}\n";
245 static char object_syntax_no_ending_separator_bin[] = {
246 'x','o','f',' ','0','3','0','2','b','i','n',' ','0','0','6','4',
247 TOKEN_NAME, /* size */ I4(6), /* name */ 'B','u','f','f','e','r', TOKEN_OBRACE,
248 TOKEN_INTEGER, I4(3), TOKEN_SEMICOLON,
249 TOKEN_INTEGER, I4(0), TOKEN_COMMA, TOKEN_INTEGER, I4(1), TOKEN_COMMA, TOKEN_INTEGER, I4(2), TOKEN_SEMICOLON,
250 TOKEN_INTEGER, I4(5),
251 TOKEN_CBRACE
254 static char object_syntax_array_no_separator_txt[] =
255 "xof 0302txt 0064\n"
256 "Buffer\n"
257 "{\n"
258 "3;\n"
259 "0 1 2;\n"
260 "5;\n"
261 "}\n";
263 static char object_syntax_array_no_separator_bin[] = {
264 'x','o','f',' ','0','3','0','2','b','i','n',' ','0','0','6','4',
265 TOKEN_NAME, /* size */ I4(6), /* name */ 'B','u','f','f','e','r', TOKEN_OBRACE,
266 TOKEN_INTEGER, I4(3), TOKEN_SEMICOLON,
267 TOKEN_INTEGER, I4(0), TOKEN_INTEGER, I4(1), TOKEN_INTEGER, I4(2), TOKEN_SEMICOLON,
268 TOKEN_INTEGER, I4(5), TOKEN_SEMICOLON,
269 TOKEN_CBRACE
272 static char object_syntax_full_integer_list_bin[] = {
273 'x','o','f',' ','0','3','0','2','b','i','n',' ','0','0','6','4',
274 TOKEN_NAME, /* size */ I4(6), /* name */ 'B','u','f','f','e','r', TOKEN_OBRACE,
275 TOKEN_INTEGER, I4(3), TOKEN_SEMICOLON,
276 TOKEN_INTEGER_LIST, I4(3), I4(0), I4(1), I4(2),
277 TOKEN_INTEGER, I4(5), TOKEN_SEMICOLON,
278 TOKEN_CBRACE
281 static char object_syntax_mixed_integer_list_bin[] = {
282 'x','o','f',' ','0','3','0','2','b','i','n',' ','0','0','6','4',
283 TOKEN_NAME, /* size */ I4(6), /* name */ 'B','u','f','f','e','r', TOKEN_OBRACE,
284 TOKEN_INTEGER_LIST, I4(5), I4(3), I4(0), I4(1), I4(2), I4(5),
285 TOKEN_CBRACE
288 static char object_syntax_integer_list_semicolon_bin[] = {
289 'x','o','f',' ','0','3','0','2','b','i','n',' ','0','0','6','4',
290 TOKEN_NAME, /* size */ I4(6), /* name */ 'B','u','f','f','e','r', TOKEN_OBRACE,
291 TOKEN_INTEGER_LIST, I4(5), I4(3), I4(0), I4(1), I4(2), I4(5), TOKEN_SEMICOLON,
292 TOKEN_CBRACE
295 static char object_syntax_integer_list_comma_bin[] = {
296 'x','o','f',' ','0','3','0','2','b','i','n',' ','0','0','6','4',
297 TOKEN_NAME, /* size */ I4(6), /* name */ 'B','u','f','f','e','r', TOKEN_OBRACE,
298 TOKEN_INTEGER_LIST, I4(5), I4(3), I4(0), I4(1), I4(2), I4(5), TOKEN_COMMA,
299 TOKEN_CBRACE
302 static char template_syntax_string[] =
303 "xof 0302txt 0064\n"
304 "template Filename\n"
305 "{\n"
306 "<3D82AB43-62DA-11CF-AB39-0020AF71E433>\n"
307 "STRING filename;\n"
308 "}\n";
310 static char object_syntax_string_normal[] =
311 "xof 0302txt 0064\n"
312 "Filename\n"
313 "{\n"
314 "\"foobar\";\n"
315 "}\n";
317 static char object_syntax_string_with_separator[] =
318 "xof 0302txt 0064\n"
319 "Filename\n"
320 "{\n"
321 "\"foo;bar\";\n"
322 "}\n";
324 static char object_syntax_string_bin[] = {
325 'x','o','f',' ','0','3','0','2','b','i','n',' ','0','0','6','4',
326 TOKEN_NAME, /* size */ I4(8), /* name */ 'F','i','l','e','n','a','m','e', TOKEN_OBRACE,
327 TOKEN_STRING, /* size */ I4(6), /* string */ 'f','o','o','b','a','r', TOKEN_SEMICOLON,
328 TOKEN_CBRACE
331 static char templates_complex_object[] =
332 "xof 0302txt 0064\n"
333 "template Vector\n"
334 "{\n"
335 "<3D82AB5E-62DA-11CF-AB39-0020AF71E433>\n"
336 "FLOAT x;\n"
337 "FLOAT y;\n"
338 "FLOAT z;\n"
339 "}\n"
340 "template MeshFace\n"
341 "{\n"
342 "<3D82AB5F-62DA-11CF-AB39-0020AF71E433>\n"
343 "DWORD nFaceVertexIndices;\n"
344 "array DWORD faceVertexIndices[nFaceVertexIndices];\n"
345 "}\n"
346 "template Mesh\n"
347 "{\n"
348 "<3D82AB44-62DA-11CF-AB39-0020AF71E433>\n"
349 "DWORD nVertices;\n"
350 "array Vector vertices[nVertices];\n"
351 "DWORD nFaces;\n"
352 "array MeshFace faces[nFaces];\n"
353 "[...]\n"
354 "}\n";
356 static char object_complex[] =
357 "xof 0302txt 0064\n"
358 "Mesh Object\n"
359 "{\n"
360 "4;;;,\n"
361 "1.0;;;, 0.0;;;, 0.0;;;,\n"
362 "0.0;;;, 1.0;;;, 0.0;;;,\n"
363 "0.0;;;, 0.0;;;, 1.0;;;,\n"
364 "1.0;;;, 1.0;;;, 1.0;;;,\n"
365 "3;;;,\n"
366 "3;;;, 0;;;, 1;;;, 2;;;,\n"
367 "3;;;, 1;;;, 2;;;, 3;;;,\n"
368 "3;;;, 3;;;, 1;;;, 2;;;,\n"
369 "}\n";
371 static char template_using_index_color_lower[] =
372 "xof 0302txt 0064\n"
373 "template MeshVertexColors\n"
374 "{\n"
375 "<1630B821-7842-11cf-8F52-0040333594A3>\n"
376 "DWORD nVertexColors;\n"
377 "array indexColor vertexColors[nVertexColors];\n"
378 "}\n";
380 static char template_using_index_color_upper[] =
381 "xof 0302txt 0064\n"
382 "template MeshVertexColors\n"
383 "{\n"
384 "<1630B821-7842-11cf-8F52-0040333594A3>\n"
385 "DWORD nVertexColors;\n"
386 "array IndexColor vertexColors[nVertexColors];\n"
387 "}\n";
389 static void init_function_pointers(void)
391 /* We have to use LoadLibrary as no d3dxof functions are referenced directly */
392 hd3dxof = LoadLibraryA("d3dxof.dll");
394 pDirectXFileCreate = (void *)GetProcAddress(hd3dxof, "DirectXFileCreate");
397 static ULONG getRefcount(IUnknown *iface)
399 IUnknown_AddRef(iface);
400 return IUnknown_Release(iface);
403 static void test_refcount(void)
405 HRESULT hr;
406 ULONG ref;
407 LPDIRECTXFILE lpDirectXFile = NULL;
408 LPDIRECTXFILEENUMOBJECT lpdxfeo;
409 LPDIRECTXFILEDATA lpdxfd;
410 DXFILELOADMEMORY dxflm;
412 if (!pDirectXFileCreate)
414 win_skip("DirectXFileCreate is not available\n");
415 return;
418 hr = pDirectXFileCreate(&lpDirectXFile);
419 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
420 if (!lpDirectXFile)
422 skip("Couldn't create DirectXFile interface\n");
423 return;
426 ref = getRefcount( (IUnknown *) lpDirectXFile);
427 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
428 ref = IDirectXFile_AddRef(lpDirectXFile);
429 ok(ref == 2, "Got refcount %d, expected 2\n", ref);
430 ref = IDirectXFile_Release(lpDirectXFile);
431 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
433 hr = IDirectXFile_RegisterTemplates(lpDirectXFile, template, sizeof(template) - 1);
434 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
436 dxflm.lpMemory = &object;
437 dxflm.dSize = sizeof(object) - 1;
438 hr = IDirectXFile_CreateEnumObject(lpDirectXFile, &dxflm, DXFILELOAD_FROMMEMORY, &lpdxfeo);
439 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
440 ref = getRefcount( (IUnknown *) lpDirectXFile);
441 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
442 ref = getRefcount( (IUnknown *) lpdxfeo);
443 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
445 hr = IDirectXFileEnumObject_GetNextDataObject(lpdxfeo, &lpdxfd);
446 ok(hr == DXFILE_OK, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
447 ref = getRefcount( (IUnknown *) lpDirectXFile);
448 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
449 ref = getRefcount( (IUnknown *) lpdxfeo);
450 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
451 /* Enum object gets references to all top level objects */
452 ref = getRefcount( (IUnknown *) lpdxfd);
453 ok(ref == 2, "Got refcount %d, expected 2\n", ref);
455 ref = IDirectXFile_Release(lpDirectXFile);
456 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
457 /* Nothing changes for all other objects */
458 ref = getRefcount( (IUnknown *) lpdxfeo);
459 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
460 ref = getRefcount( (IUnknown *) lpdxfd);
461 ok(ref == 2, "Got refcount %d, expected 2\n", ref);
463 ref = IDirectXFileEnumObject_Release(lpdxfeo);
464 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
465 /* Enum object releases references to all top level objects */
466 ref = getRefcount( (IUnknown *) lpdxfd);
467 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
469 ref = IDirectXFileData_Release(lpdxfd);
470 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
473 static void test_CreateEnumObject(void)
475 HRESULT hr;
476 ULONG ref;
477 LPDIRECTXFILE lpDirectXFile = NULL;
478 LPDIRECTXFILEENUMOBJECT lpdxfeo;
479 LPDIRECTXFILEDATA lpdxfd;
480 DXFILELOADMEMORY dxflm;
481 BYTE* pdata;
482 DWORD size;
484 if (!pDirectXFileCreate)
486 win_skip("DirectXFileCreate is not available\n");
487 return;
490 hr = pDirectXFileCreate(&lpDirectXFile);
491 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
492 if (!lpDirectXFile)
494 skip("Couldn't create DirectXFile interface\n");
495 return;
498 hr = IDirectXFile_RegisterTemplates(lpDirectXFile, template, sizeof(template) - 1);
499 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
501 dxflm.lpMemory = &object;
502 dxflm.dSize = sizeof(object) - 1;
503 /* Check that only lowest 4 bits are relevant in DXFILELOADOPTIONS */
504 hr = IDirectXFile_CreateEnumObject(lpDirectXFile, &dxflm, 0xFFFFFFF0 + DXFILELOAD_FROMMEMORY, &lpdxfeo);
505 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
507 hr = IDirectXFileEnumObject_GetNextDataObject(lpdxfeo, &lpdxfd);
508 ok(hr == DXFILE_OK, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
510 /* Get all data (szMember == NULL) */
511 hr = IDirectXFileData_GetData(lpdxfd, NULL, &size, (void**)&pdata);
512 ok(hr == DXFILE_OK, "IDirectXFileData_GetData: %x\n", hr);
514 ok(size == 8, "Retrieved data size is wrong (%u instead of 8)\n", size);
515 ok((*((WORD*)pdata) == 1) && (*((WORD*)(pdata+2)) == 2) && (*((DWORD*)(pdata+4)) == 3), "Retrieved data is wrong\n");
517 /* Get only "major" member (szMember == "major") */
518 hr = IDirectXFileData_GetData(lpdxfd, "major", &size, (void**)&pdata);
519 ok(hr == DXFILE_OK, "IDirectXFileData_GetData: %x\n", hr);
521 ok(size == 2, "Retrieved data size is wrong (%u instead of 2)\n", size);
522 ok(*((WORD*)pdata) == 1, "Retrieved data is wrong (%u instead of 1)\n", *((WORD*)pdata));
524 /* Get only "minor" member (szMember == "minor") */
525 hr = IDirectXFileData_GetData(lpdxfd, "minor", &size, (void**)&pdata);
526 ok(hr == DXFILE_OK, "IDirectXFileData_GetData: %x\n", hr);
528 ok(size == 2, "Retrieved data size is wrong (%u instead of 2)\n", size);
529 ok(*((WORD*)pdata) == 2, "Retrieved data is wrong (%u instead of 2)\n", *((WORD*)pdata));
531 /* Get only "flags" member (szMember == "flags") */
532 hr = IDirectXFileData_GetData(lpdxfd, "flags", &size, (void**)&pdata);
533 ok(hr == DXFILE_OK, "IDirectXFileData_GetData: %x\n", hr);
535 ok(size == 4, "Retrieved data size is wrong (%u instead of 4)\n", size);
536 ok(*((WORD*)pdata) == 3, "Retrieved data is wrong (%u instead of 3)\n", *((WORD*)pdata));
538 /* Try to get not existing member (szMember == "unknown") */
539 hr = IDirectXFileData_GetData(lpdxfd, "unknow", &size, (void**)&pdata);
540 ok(hr == DXFILEERR_BADDATAREFERENCE, "IDirectXFileData_GetData: %x\n", hr);
542 ref = IDirectXFileEnumObject_Release(lpdxfeo);
543 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
545 ref = IDirectXFile_Release(lpDirectXFile);
546 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
548 ref = IDirectXFileData_Release(lpdxfd);
549 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
552 static void test_file_types(void)
554 HRESULT hr;
555 LPDIRECTXFILE dxfile = NULL;
556 LPDIRECTXFILEENUMOBJECT enum_object;
557 DXFILELOADMEMORY lminfo;
559 if (!pDirectXFileCreate)
561 win_skip("DirectXFileCreate is not available\n");
562 return;
565 hr = pDirectXFileCreate(&dxfile);
566 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
567 if (!dxfile)
569 skip("Couldn't create DirectXFile interface\n");
570 return;
573 hr = IDirectXFile_RegisterTemplates(dxfile, empty_txt_file, sizeof(empty_txt_file) - 1);
574 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
576 hr = IDirectXFile_RegisterTemplates(dxfile, empty_bin_file, sizeof(empty_bin_file) - 1);
577 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
579 hr = IDirectXFile_RegisterTemplates(dxfile, empty_tzip_file, sizeof(empty_tzip_file) - 1);
580 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
582 hr = IDirectXFile_RegisterTemplates(dxfile, empty_bzip_file, sizeof(empty_bzip_file) - 1);
583 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
585 hr = IDirectXFile_RegisterTemplates(dxfile, empty_cmp_file, sizeof(empty_cmp_file) - 1);
586 ok(hr == DXFILEERR_BADFILETYPE, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
588 hr = IDirectXFile_RegisterTemplates(dxfile, empty_xxxx_file, sizeof(empty_xxxx_file) - 1);
589 ok(hr == DXFILEERR_BADFILETYPE, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
591 lminfo.lpMemory = empty_txt_file;
592 lminfo.dSize = sizeof(empty_txt_file) - 1;
593 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
594 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
595 if (hr == DXFILE_OK) IDirectXFileEnumObject_Release(enum_object);
597 lminfo.lpMemory = empty_bin_file;
598 lminfo.dSize = sizeof(empty_bin_file) - 1;
599 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
600 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
601 if (hr == DXFILE_OK) IDirectXFileEnumObject_Release(enum_object);
603 lminfo.lpMemory = empty_tzip_file;
604 lminfo.dSize = sizeof(empty_tzip_file) - 1;
605 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
606 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
607 if (hr == DXFILE_OK) IDirectXFileEnumObject_Release(enum_object);
609 lminfo.lpMemory = empty_bzip_file;
610 lminfo.dSize = sizeof(empty_bzip_file) - 1;
611 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
612 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
613 if (hr == DXFILE_OK) IDirectXFileEnumObject_Release(enum_object);
615 lminfo.lpMemory = empty_cmp_file;
616 lminfo.dSize = sizeof(empty_cmp_file) - 1;
617 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
618 ok(hr == DXFILEERR_BADFILETYPE, "IDirectXFile_CreateEnumObject: %x\n", hr);
620 lminfo.lpMemory = empty_xxxx_file;
621 lminfo.dSize = sizeof(empty_xxxx_file) - 1;
622 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
623 ok(hr == DXFILEERR_BADFILETYPE, "IDirectXFile_CreateEnumObject: %x\n", hr);
625 IDirectXFile_Release(dxfile);
628 static void test_templates(void)
630 HRESULT ret;
631 IDirectXFile *dxfile = NULL;
633 if (!pDirectXFileCreate)
635 win_skip("DirectXFileCreate is not available\n");
636 return;
639 ret = pDirectXFileCreate(&dxfile);
640 ok(ret == DXFILE_OK, "DirectXFileCreate: %x\n", ret);
641 if (!dxfile)
643 skip("Couldn't create DirectXFile interface\n");
644 return;
647 ret = IDirectXFile_RegisterTemplates(dxfile, templates_bad_file_type1, sizeof(templates_bad_file_type1) - 1);
648 ok(ret == DXFILEERR_BADFILETYPE, "RegisterTemplates returned %#x, expected %#x\n", ret, DXFILEERR_BADFILETYPE);
650 ret = IDirectXFile_RegisterTemplates(dxfile, templates_bad_file_version, sizeof(templates_bad_file_version) - 1);
651 ok(ret == DXFILEERR_BADFILEVERSION, "RegisterTemplates returned %#x, expected %#x\n", ret, DXFILEERR_BADFILEVERSION);
653 ret = IDirectXFile_RegisterTemplates(dxfile, templates_bad_file_type2, sizeof(templates_bad_file_type2) - 1);
654 ok(ret == DXFILEERR_BADFILETYPE, "RegisterTemplates returned %#x, expected %#x\n", ret, DXFILEERR_BADFILETYPE);
656 ret = IDirectXFile_RegisterTemplates(dxfile, templates_bad_file_float_size, sizeof(templates_bad_file_float_size) - 1);
657 ok(ret == DXFILEERR_BADFILEFLOATSIZE, "RegisterTemplates returned %#x, expected %#x\n", ret, DXFILEERR_BADFILEFLOATSIZE);
659 ret = IDirectXFile_RegisterTemplates(dxfile, templates_parse_error, sizeof(templates_parse_error) - 1);
660 ok(ret == DXFILEERR_PARSEERROR, "RegisterTemplates returned %#x, expected %#x\n", ret, DXFILEERR_PARSEERROR);
662 IDirectXFile_Release(dxfile);
665 static void test_compressed_files(void)
667 HRESULT hr;
668 LPDIRECTXFILE dxfile = NULL;
669 LPDIRECTXFILEENUMOBJECT enum_object;
670 LPDIRECTXFILEDATA file_data;
671 DXFILELOADMEMORY lminfo;
672 BYTE* data;
673 DWORD size;
675 if (!pDirectXFileCreate)
677 win_skip("DirectXFileCreate is not available\n");
678 return;
681 hr = pDirectXFileCreate(&dxfile);
682 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
683 if (!dxfile)
685 skip("Couldn't create DirectXFile interface\n");
686 return;
689 hr = IDirectXFile_RegisterTemplates(dxfile, compressed_template, sizeof(compressed_template) - 1);
690 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
692 lminfo.lpMemory = compressed_object;
693 lminfo.dSize = sizeof(compressed_object) - 1;
694 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
695 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
697 hr = IDirectXFileEnumObject_GetNextDataObject(enum_object, &file_data);
698 ok(hr == DXFILE_OK, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
700 hr = IDirectXFileData_GetData(file_data, NULL, &size, (void**)&data);
701 ok(hr == DXFILE_OK, "IDirectXFileData_GetData: %x\n", hr);
703 ok(size == 8, "Retrieved data size is wrong\n");
704 ok((*((WORD*)data) == 1) && (*((WORD*)(data+2)) == 2) && (*((DWORD*)(data+4)) == 3), "Retrieved data is wrong\n");
706 IDirectXFileData_Release(file_data);
707 IDirectXFileEnumObject_Release(enum_object);
708 IDirectXFile_Release(dxfile);
711 static void test_getname(void)
713 HRESULT hr;
714 ULONG ref;
715 LPDIRECTXFILE lpDirectXFile = NULL;
716 LPDIRECTXFILEENUMOBJECT lpdxfeo;
717 LPDIRECTXFILEDATA lpdxfd;
718 DXFILELOADMEMORY dxflm;
719 char name[100];
720 DWORD length;
722 if (!pDirectXFileCreate)
724 win_skip("DirectXFileCreate is not available\n");
725 return;
728 hr = pDirectXFileCreate(&lpDirectXFile);
729 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
730 if (!lpDirectXFile)
732 skip("Couldn't create DirectXFile interface\n");
733 return;
736 hr = IDirectXFile_RegisterTemplates(lpDirectXFile, template, sizeof(template) - 1);
737 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
739 /* Check object with name */
740 dxflm.lpMemory = &object;
741 dxflm.dSize = sizeof(object) - 1;
742 hr = IDirectXFile_CreateEnumObject(lpDirectXFile, &dxflm, DXFILELOAD_FROMMEMORY, &lpdxfeo);
743 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
744 hr = IDirectXFileEnumObject_GetNextDataObject(lpdxfeo, &lpdxfd);
745 ok(hr == DXFILE_OK, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
747 hr = IDirectXFileData_GetName(lpdxfd, NULL, NULL);
748 ok(hr == DXFILEERR_BADVALUE, "IDirectXFileData_GetName: %x\n", hr);
749 hr = IDirectXFileData_GetName(lpdxfd, name, NULL);
750 ok(hr == DXFILEERR_BADVALUE, "IDirectXFileData_GetName: %x\n", hr);
751 hr = IDirectXFileData_GetName(lpdxfd, NULL, &length);
752 ok(hr == DXFILE_OK, "IDirectXFileData_GetName: %x\n", hr);
753 ok(length == 7, "Returned length should be 7 instead of %u\n", length);
754 length = sizeof(name);
755 hr = IDirectXFileData_GetName(lpdxfd, name, &length);
756 ok(hr == DXFILE_OK, "IDirectXFileData_GetName: %x\n", hr);
757 ok(length == 7, "Returned length should be 7 instead of %u\n", length);
758 ok(!strcmp(name, "Object"), "Returned string should be 'Object' intead of '%s'\n", name);
759 length = 3;
760 hr = IDirectXFileData_GetName(lpdxfd, name, &length);
761 ok(hr == DXFILEERR_BADVALUE, "IDirectXFileData_GetName: %x\n", hr);
763 ref = IDirectXFileEnumObject_Release(lpdxfeo);
764 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
765 ref = IDirectXFileData_Release(lpdxfd);
766 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
768 /* Check object without name */
769 dxflm.lpMemory = &object_noname;
770 dxflm.dSize = sizeof(object_noname) - 1;
771 hr = IDirectXFile_CreateEnumObject(lpDirectXFile, &dxflm, DXFILELOAD_FROMMEMORY, &lpdxfeo);
772 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
773 hr = IDirectXFileEnumObject_GetNextDataObject(lpdxfeo, &lpdxfd);
774 ok(hr == DXFILE_OK, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
776 hr = IDirectXFileData_GetName(lpdxfd, NULL, &length);
777 ok(hr == DXFILE_OK, "IDirectXFileData_GetName: %x\n", hr);
778 ok(length == 0, "Returned length should be 0 instead of %u\n", length);
779 length = 0;
780 name[0] = 0x7f;
781 hr = IDirectXFileData_GetName(lpdxfd, name, &length);
782 ok(hr == DXFILE_OK, "IDirectXFileData_GetName: %x\n", hr);
783 ok(length == 0, "Returned length should be 0 instead of %u\n", length);
784 ok(name[0] == 0x7f, "First character is %#x instead of 0x7f\n", name[0]);
785 length = sizeof(name);
786 name[0] = 0x7f;
787 hr = IDirectXFileData_GetName(lpdxfd, name, &length);
788 ok(hr == DXFILE_OK, "IDirectXFileData_GetName: %x\n", hr);
789 ok(length == 0, "Returned length should be 0 instead of %u\n", length);
790 ok(name[0] == 0, "First character is %#x instead of 0x00\n", name[0]);
792 ref = IDirectXFileEnumObject_Release(lpdxfeo);
793 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
794 ref = IDirectXFileData_Release(lpdxfd);
795 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
796 ref = IDirectXFile_Release(lpDirectXFile);
797 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
800 static void test_syntax(void)
802 HRESULT hr;
803 LPDIRECTXFILE lpDirectXFile = NULL;
804 LPDIRECTXFILEENUMOBJECT lpdxfeo;
805 LPDIRECTXFILEDATA lpdxfd;
806 DXFILELOADMEMORY dxflm;
807 DWORD size;
808 char** string;
810 if (!pDirectXFileCreate)
812 win_skip("DirectXFileCreate is not available\n");
813 return;
816 hr = pDirectXFileCreate(&lpDirectXFile);
817 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
818 if (!lpDirectXFile)
820 skip("Couldn't create DirectXFile interface\n");
821 return;
824 hr = IDirectXFile_RegisterTemplates(lpDirectXFile, template_syntax_array_mixed, sizeof(template_syntax_array_mixed) - 1);
825 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
827 /* Test empty array */
828 dxflm.lpMemory = &object_syntax_empty_array;
829 dxflm.dSize = sizeof(object_syntax_empty_array) - 1;
830 hr = IDirectXFile_CreateEnumObject(lpDirectXFile, &dxflm, DXFILELOAD_FROMMEMORY, &lpdxfeo);
831 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
832 hr = IDirectXFileEnumObject_GetNextDataObject(lpdxfeo, &lpdxfd);
833 ok(hr == DXFILE_OK, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
834 if (hr == DXFILE_OK)
835 IDirectXFileData_Release(lpdxfd);
836 IDirectXFileEnumObject_Release(lpdxfeo);
838 hr = IDirectXFile_RegisterTemplates(lpDirectXFile, template_syntax_string, sizeof(template_syntax_string) - 1);
839 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
841 /* Test normal string */
842 dxflm.lpMemory = &object_syntax_string_normal;
843 dxflm.dSize = sizeof(object_syntax_string_normal) - 1;
844 hr = IDirectXFile_CreateEnumObject(lpDirectXFile, &dxflm, DXFILELOAD_FROMMEMORY, &lpdxfeo);
845 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
846 hr = IDirectXFileEnumObject_GetNextDataObject(lpdxfeo, &lpdxfd);
847 ok(hr == DXFILE_OK, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
848 hr = IDirectXFileData_GetData(lpdxfd, NULL, &size, (void**)&string);
849 ok(hr == DXFILE_OK, "IDirectXFileData_GetData: %x\n", hr);
850 ok(size == sizeof(char*), "Got wrong data size %d\n", size);
851 ok(!strcmp(*string, "foobar"), "Got string %s, expected foobar\n", *string);
852 if (hr == DXFILE_OK)
853 IDirectXFileData_Release(lpdxfd);
854 IDirectXFileEnumObject_Release(lpdxfeo);
856 /* Test string containing separator character */
857 dxflm.lpMemory = &object_syntax_string_with_separator;
858 dxflm.dSize = sizeof(object_syntax_string_with_separator) - 1;
859 hr = IDirectXFile_CreateEnumObject(lpDirectXFile, &dxflm, DXFILELOAD_FROMMEMORY, &lpdxfeo);
860 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
861 hr = IDirectXFileEnumObject_GetNextDataObject(lpdxfeo, &lpdxfd);
862 ok(hr == DXFILE_OK, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
863 hr = IDirectXFileData_GetData(lpdxfd, NULL, &size, (void**)&string);
864 ok(hr == DXFILE_OK, "IDirectXFileData_GetData: %x\n", hr);
865 ok(size == sizeof(char*), "Got wrong data size %d\n", size);
866 ok(!strcmp(*string, "foo;bar"), "Got string %s, expected foo;bar\n", *string);
867 if (hr == DXFILE_OK)
868 IDirectXFileData_Release(lpdxfd);
869 IDirectXFileEnumObject_Release(lpdxfeo);
871 /* Test string in binary mode */
872 dxflm.lpMemory = &object_syntax_string_bin;
873 dxflm.dSize = sizeof(object_syntax_string_bin);
874 hr = IDirectXFile_CreateEnumObject(lpDirectXFile, &dxflm, DXFILELOAD_FROMMEMORY, &lpdxfeo);
875 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
876 hr = IDirectXFileEnumObject_GetNextDataObject(lpdxfeo, &lpdxfd);
877 ok(hr == DXFILE_OK, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
878 hr = IDirectXFileData_GetData(lpdxfd, NULL, &size, (void**)&string);
879 ok(hr == DXFILE_OK, "IDirectXFileData_GetData: %x\n", hr);
880 ok(size == sizeof(char*), "Got wrong data size %d\n", size);
881 ok(!strcmp(*string, "foobar"), "Got string %s, expected foobar\n", *string);
882 if (hr == DXFILE_OK)
883 IDirectXFileData_Release(lpdxfd);
884 IDirectXFileEnumObject_Release(lpdxfeo);
886 IDirectXFile_Release(lpDirectXFile);
889 static HRESULT test_buffer_object(IDirectXFile *dxfile, char* object_data, DWORD object_size)
891 HRESULT hr, ret;
892 IDirectXFileEnumObject *enum_object;
893 IDirectXFileData *file_data;
894 DXFILELOADMEMORY load_info;
895 DWORD size;
896 const DWORD values[] = { 3, 0, 1, 2, 5 };
897 DWORD* array;
899 load_info.lpMemory = object_data;
900 load_info.dSize = object_size;
901 hr = IDirectXFile_CreateEnumObject(dxfile, &load_info, DXFILELOAD_FROMMEMORY, &enum_object);
902 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
903 ret = IDirectXFileEnumObject_GetNextDataObject(enum_object, &file_data);
904 if (ret == DXFILE_OK)
906 hr = IDirectXFileData_GetData(file_data, NULL, &size, (void**)&array);
907 ok(hr == DXFILE_OK, "IDirectXFileData_GetData: %x\n", hr);
908 ok(size == sizeof(values), "Got wrong data size %d\n", size);
909 ok(!memcmp(array, values, sizeof(values)), "Got values [%u, %u, %u, %u, %u], expected [%u, %u, %u, %u, %u]\n",
910 array[0], array[1], array[2], array[3], array[4], values[0], values[1], values[2], values[3], values[4]);
911 IDirectXFileData_Release(file_data);
913 IDirectXFileEnumObject_Release(enum_object);
915 return ret;
918 static void test_syntax_semicolon_comma(void)
920 HRESULT ret;
921 IDirectXFile *dxfile = NULL;
923 if (!pDirectXFileCreate)
925 win_skip("DirectXFileCreate is not available\n");
926 return;
929 ret = pDirectXFileCreate(&dxfile);
930 ok(ret == DXFILE_OK, "DirectXFileCreate failed with %#x\n", ret);
931 if (!dxfile)
933 skip("Couldn't create DirectXFile interface\n");
934 return;
937 ret = IDirectXFile_RegisterTemplates(dxfile, template_syntax_array_mixed, sizeof(template_syntax_array_mixed) - 1);
938 ok(ret == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates failed with %#x\n", ret);
940 /* Test semicolon separators in text mode */
941 ret = test_buffer_object(dxfile, object_syntax_semicolon_txt, sizeof(object_syntax_semicolon_txt) - 1);
942 ok(ret == DXFILE_OK, "test_buffer_object failed with %#x\n", ret);
943 /* Test semicolon separators in binary mode */
944 ret = test_buffer_object(dxfile, object_syntax_semicolon_bin, sizeof(object_syntax_semicolon_bin));
945 ok(ret == DXFILE_OK, "test_buffer_object failed with %#x\n", ret);
947 /* Test comma separators in text mode */
948 ret = test_buffer_object(dxfile, object_syntax_comma_txt, sizeof(object_syntax_comma_txt) - 1);
949 ok(ret == DXFILE_OK, "test_buffer_object failed with %#x\n", ret);
950 /* Test comma separators in binary mode */
951 ret = test_buffer_object(dxfile, object_syntax_comma_bin, sizeof(object_syntax_comma_bin));
952 ok(ret == DXFILE_OK, "test_buffer_object failed with %#x\n", ret);
954 /* Test multi-semicolons separators in text mode */
955 ret = test_buffer_object(dxfile, object_syntax_multi_semicolons_txt, sizeof(object_syntax_multi_semicolons_txt) - 1);
956 ok(ret == DXFILE_OK, "test_buffer_object failed with %#x\n", ret);
957 /* Test multi-semicolons separators in binary mode */
958 ret = test_buffer_object(dxfile, object_syntax_multi_semicolons_bin, sizeof(object_syntax_multi_semicolons_bin));
959 ok(ret == DXFILE_OK, "test_buffer_object failed with %#x\n", ret);
961 /* Test multi-commas separators in text mode */
962 ret = test_buffer_object(dxfile, object_syntax_multi_commas_txt, sizeof(object_syntax_multi_semicolons_txt) - 1);
963 ok(ret == DXFILEERR_PARSEERROR, "test_buffer_object returned %#x, expected %#x\n", ret, DXFILEERR_PARSEERROR);
964 /* Test multi-commas separators in binary mode */
965 ret = test_buffer_object(dxfile, object_syntax_multi_commas_bin, sizeof(object_syntax_multi_semicolons_bin));
966 ok(ret == DXFILEERR_PARSEERROR, "test_buffer_object returned %#x, expected %#x\n", ret, DXFILEERR_PARSEERROR);
968 /* Test multi-semicolons + single comma separators in text mode */
969 ret = test_buffer_object(dxfile, object_syntax_multi_semicolons_and_comma_txt, sizeof(object_syntax_multi_semicolons_and_comma_txt) - 1);
970 ok(ret == DXFILE_OK, "test_buffer_object failed with %#x\n", ret);
971 /* Test multi-semicolons + single comma separators in binary mode */
972 ret = test_buffer_object(dxfile, object_syntax_multi_semicolons_and_comma_bin, sizeof(object_syntax_multi_semicolons_and_comma_bin));
973 ok(ret == DXFILE_OK, "test_buffer_object failed with %#x\n", ret);
975 /* Test comma + semicolon separators in text mode */
976 ret = test_buffer_object(dxfile, object_syntax_comma_and_semicolon_txt, sizeof(object_syntax_comma_and_semicolon_txt) - 1);
977 ok(ret == DXFILEERR_PARSEERROR, "test_buffer_object returned %#x, expected %#x\n", ret, DXFILEERR_PARSEERROR);
978 /* Test comma + semicolon separators in binary mode */
979 ret = test_buffer_object(dxfile, object_syntax_comma_and_semicolon_bin, sizeof(object_syntax_comma_and_semicolon_bin));
980 ok(ret == DXFILEERR_PARSEERROR, "test_buffer_object returned %#x, expected %#x\n", ret, DXFILEERR_PARSEERROR);
982 /* Test no ending separator in text mode */
983 ret = test_buffer_object(dxfile, object_syntax_no_ending_separator_txt, sizeof(object_syntax_no_ending_separator_txt) - 1);
984 ok(ret == DXFILEERR_PARSEERROR, "test_buffer_object returned %#x, expected %#x\n", ret, DXFILEERR_PARSEERROR);
985 /* Test no ending separator in binary mode */
986 ret = test_buffer_object(dxfile, object_syntax_no_ending_separator_bin, sizeof(object_syntax_no_ending_separator_bin));
987 ok(ret == DXFILEERR_PARSEERROR, "test_buffer_object returned %#x, expected %#x\n", ret, DXFILEERR_PARSEERROR);
989 /* Test no array separator in text mode */
990 ret = test_buffer_object(dxfile, object_syntax_array_no_separator_txt, sizeof(object_syntax_array_no_separator_txt) - 1);
991 ok(ret == DXFILEERR_PARSEERROR, "test_buffer_object returned %#x, expected %#x\n", ret, DXFILEERR_PARSEERROR);
992 /* Test no array separator in binary mode */
993 ret = test_buffer_object(dxfile, object_syntax_array_no_separator_bin, sizeof(object_syntax_array_no_separator_bin));
994 ok(ret == DXFILEERR_PARSEERROR, "test_buffer_object returned %#x, expected %#x\n", ret, DXFILEERR_PARSEERROR);
996 /* Test object with a single integer list in binary mode */
997 ret = test_buffer_object(dxfile, object_syntax_full_integer_list_bin, sizeof(object_syntax_full_integer_list_bin));
998 ok(ret == DXFILE_OK, "test_buffer_object failed with %#x\n", ret);
1000 /* Test object with mixed integer list and integers + single comma separators in binary mode */
1001 ret = test_buffer_object(dxfile, object_syntax_mixed_integer_list_bin, sizeof(object_syntax_mixed_integer_list_bin));
1002 ok(ret == DXFILE_OK, "test_buffer_object failed with %#x\n", ret);
1004 /* Test integer list followed by a semicolon in binary mode */
1005 ret = test_buffer_object(dxfile, object_syntax_integer_list_semicolon_bin, sizeof(object_syntax_integer_list_semicolon_bin));
1006 ok(ret == DXFILEERR_PARSEERROR, "test_buffer_object returned %#x, expected %#x\n", ret, DXFILEERR_PARSEERROR);
1008 /* Test integer list followed by a comma in binary mode */
1009 ret = test_buffer_object(dxfile, object_syntax_integer_list_comma_bin, sizeof(object_syntax_integer_list_comma_bin));
1010 ok(ret == DXFILEERR_PARSEERROR, "test_buffer_object returned %#x, expected %#x\n", ret, DXFILEERR_PARSEERROR);
1012 IDirectXFile_Release(dxfile);
1015 static void test_complex_object(void)
1017 HRESULT ret;
1018 IDirectXFile *dxfile = NULL;
1019 IDirectXFileEnumObject *enum_object;
1020 IDirectXFileData *file_data;
1021 DXFILELOADMEMORY load_info;
1023 if (!pDirectXFileCreate)
1025 win_skip("DirectXFileCreate is not available\n");
1026 return;
1029 ret = pDirectXFileCreate(&dxfile);
1030 ok(ret == DXFILE_OK, "DirectXFileCreate failed with %#x\n", ret);
1031 if (!dxfile)
1033 skip("Couldn't create DirectXFile interface\n");
1034 return;
1037 ret = IDirectXFile_RegisterTemplates(dxfile, templates_complex_object, sizeof(templates_complex_object) - 1);
1038 ok(ret == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates failed with %#x\n", ret);
1040 load_info.lpMemory = object_complex;
1041 load_info.dSize = sizeof(object_complex) - 1;
1042 ret = IDirectXFile_CreateEnumObject(dxfile, &load_info, DXFILELOAD_FROMMEMORY, &enum_object);
1043 ok(ret == DXFILE_OK, "IDirectXFile_CreateEnumObject failed with %#x\n", ret);
1044 ret = IDirectXFileEnumObject_GetNextDataObject(enum_object, &file_data);
1045 ok(ret == DXFILE_OK, "IDirectXFileEnumObject_GetNextDataObject failed with %#x\n", ret);
1047 IDirectXFileData_Release(file_data);
1048 IDirectXFileEnumObject_Release(enum_object);
1049 IDirectXFile_Release(dxfile);
1052 static void test_standard_templates(void)
1054 HRESULT ret;
1055 IDirectXFile *dxfile = NULL;
1057 if (!pDirectXFileCreate)
1059 win_skip("DirectXFileCreate is not available\n");
1060 return;
1063 ret = pDirectXFileCreate(&dxfile);
1064 ok(ret == DXFILE_OK, "DirectXFileCreate failed with %#x\n", ret);
1065 if (!dxfile)
1067 skip("Couldn't create DirectXFile interface\n");
1068 return;
1071 ret = IDirectXFile_RegisterTemplates(dxfile, D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES);
1072 ok(ret == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates failed with %#x\n", ret);
1074 IDirectXFile_Release(dxfile);
1077 static void test_type_index_color(void)
1079 HRESULT ret;
1080 IDirectXFile *dxfile = NULL;
1082 if (!pDirectXFileCreate)
1084 win_skip("DirectXFileCreate is not available\n");
1085 return;
1088 ret = pDirectXFileCreate(&dxfile);
1089 ok(ret == DXFILE_OK, "DirectXFileCreate failed with %#x\n", ret);
1090 if (!dxfile)
1092 skip("Couldn't create DirectXFile interface\n");
1093 return;
1096 /* Test that 'indexColor' can be used (same as IndexedColor in standard templates) and is case sensitive */
1097 ret = IDirectXFile_RegisterTemplates(dxfile, template_using_index_color_lower, sizeof(template_using_index_color_lower) - 1);
1098 ok(ret == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates failed with %#x\n", ret);
1099 ret = IDirectXFile_RegisterTemplates(dxfile, template_using_index_color_upper, sizeof(template_using_index_color_upper) - 1);
1100 ok(ret == DXFILEERR_PARSEERROR, "IDirectXFileImpl_RegisterTemplates returned %#x instead of %#x\n", ret, DXFILEERR_PARSEERROR);
1102 IDirectXFile_Release(dxfile);
1105 /* Set it to 1 to expand the string when dumping the object. This is useful when there is
1106 * only one string in a sub-object (very common). Use with care, this may lead to a crash. */
1107 #define EXPAND_STRING 0
1109 static void process_data(LPDIRECTXFILEDATA lpDirectXFileData, int level)
1111 HRESULT hr;
1112 char name[100];
1113 GUID clsid;
1114 const GUID *clsid_type = NULL;
1115 DWORD len = 100;
1116 LPDIRECTXFILEOBJECT pChildObj;
1117 int i;
1118 int j = 0;
1119 LPBYTE pData;
1120 DWORD k, size;
1122 hr = IDirectXFileData_GetId(lpDirectXFileData, &clsid);
1123 ok(hr == DXFILE_OK, "IDirectXFileData_GetId: %x\n", hr);
1124 hr = IDirectXFileData_GetName(lpDirectXFileData, name, &len);
1125 ok(hr == DXFILE_OK, "IDirectXFileData_GetName: %x\n", hr);
1126 hr = IDirectXFileData_GetType(lpDirectXFileData, &clsid_type);
1127 ok(hr == DXFILE_OK, "IDirectXFileData_GetType: %x\n", hr);
1128 hr = IDirectXFileData_GetData(lpDirectXFileData, NULL, &size, (void**)&pData);
1129 ok(hr == DXFILE_OK, "IDirectXFileData_GetData: %x\n", hr);
1130 for (i = 0; i < level; i++)
1131 printf(" ");
1132 printf("Found object '%s' - %s - %s - %d\n",
1133 len ? name : "", wine_dbgstr_guid(&clsid), wine_dbgstr_guid(clsid_type), size);
1135 if (EXPAND_STRING && size == 4)
1137 char * str = *(char**)pData;
1138 printf("string %s\n", str);
1140 else if (size)
1142 for (k = 0; k < size; k++)
1144 if (k && !(k%16))
1145 printf("\n");
1146 printf("%02x ", pData[k]);
1148 printf("\n");
1151 level++;
1153 while (SUCCEEDED(hr = IDirectXFileData_GetNextObject(lpDirectXFileData, &pChildObj)))
1155 LPDIRECTXFILEDATA p1;
1156 LPDIRECTXFILEDATAREFERENCE p2;
1157 LPDIRECTXFILEBINARY p3;
1158 j++;
1160 hr = IDirectXFileObject_QueryInterface(pChildObj, &IID_IDirectXFileData, (void **) &p1);
1161 if (SUCCEEDED(hr))
1163 for (i = 0; i < level; i++)
1164 printf(" ");
1165 printf("Found Data (%d)\n", j);
1166 process_data(p1, level);
1167 IDirectXFileData_Release(p1);
1169 hr = IDirectXFileObject_QueryInterface(pChildObj, &IID_IDirectXFileDataReference, (void **) &p2);
1170 if (SUCCEEDED(hr))
1172 LPDIRECTXFILEDATA pfdo;
1173 for (i = 0; i < level; i++)
1174 printf(" ");
1175 printf("Found Data Reference (%d)\n", j);
1176 if (0)
1178 hr = IDirectXFileDataReference_GetId(lpDirectXFileData, &clsid);
1179 ok(hr == DXFILE_OK, "IDirectXFileData_GetId: %x\n", hr);
1180 hr = IDirectXFileDataReference_GetName(lpDirectXFileData, name, &len);
1181 ok(hr == DXFILE_OK, "IDirectXFileData_GetName: %x\n", hr);
1183 IDirectXFileDataReference_Resolve(p2, &pfdo);
1184 process_data(pfdo, level);
1185 IDirectXFileData_Release(pfdo);
1186 IDirectXFileDataReference_Release(p2);
1188 hr = IDirectXFileObject_QueryInterface(pChildObj, &IID_IDirectXFileBinary, (void **) &p3);
1189 if (SUCCEEDED(hr))
1191 for (i = 0; i < level; i++)
1192 printf(" ");
1193 printf("Found Binary (%d)\n", j);
1194 IDirectXFileBinary_Release(p3);
1196 IDirectXFileObject_Release(pChildObj);
1199 ok(hr == DXFILE_OK || hr == DXFILEERR_NOMOREOBJECTS, "IDirectXFileData_GetNextObject: %x\n", hr);
1202 /* Dump an X file 'objects.x' and its related templates file 'templates.x' if they are both presents
1203 * Useful for debug by comparing outputs from native and builtin dlls */
1204 static void test_dump(void)
1206 HRESULT hr;
1207 ULONG ref;
1208 LPDIRECTXFILE lpDirectXFile = NULL;
1209 LPDIRECTXFILEENUMOBJECT lpDirectXFileEnumObject = NULL;
1210 LPDIRECTXFILEDATA lpDirectXFileData = NULL;
1211 HANDLE hFile;
1212 LPVOID pvData = NULL;
1213 DWORD cbSize;
1215 if (!pDirectXFileCreate)
1217 win_skip("DirectXFileCreate is not available\n");
1218 goto exit;
1221 /* Dump data only if there is an object and a template */
1222 hFile = CreateFileA("objects.x", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
1223 if (hFile == INVALID_HANDLE_VALUE)
1224 return;
1225 CloseHandle(hFile);
1227 hFile = CreateFileA("templates.x", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
1228 if (hFile == INVALID_HANDLE_VALUE)
1229 return;
1231 pvData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 10000);
1233 if (!ReadFile(hFile, pvData, 10000, &cbSize, NULL))
1235 skip("Templates file is too big\n");
1236 goto exit;
1239 printf("Load templates file (%d bytes)\n", cbSize);
1241 hr = pDirectXFileCreate(&lpDirectXFile);
1242 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
1243 if(!lpDirectXFile)
1245 skip("Couldn't create DirectXFile interface\n");
1246 goto exit;
1249 hr = IDirectXFile_RegisterTemplates(lpDirectXFile, pvData, cbSize);
1250 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
1252 hr = IDirectXFile_CreateEnumObject(lpDirectXFile, (LPVOID)"objects.x", DXFILELOAD_FROMFILE, &lpDirectXFileEnumObject);
1253 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
1255 while (SUCCEEDED(hr = IDirectXFileEnumObject_GetNextDataObject(lpDirectXFileEnumObject, &lpDirectXFileData)))
1257 printf("\n");
1258 process_data(lpDirectXFileData, 0);
1259 IDirectXFileData_Release(lpDirectXFileData);
1261 ok(hr == DXFILE_OK || hr == DXFILEERR_NOMOREOBJECTS, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
1263 ref = IDirectXFile_Release(lpDirectXFileEnumObject);
1264 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
1266 ref = IDirectXFile_Release(lpDirectXFile);
1267 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
1269 CloseHandle(hFile);
1271 exit:
1272 HeapFree(GetProcessHeap(), 0, pvData);
1275 START_TEST(d3dxof)
1277 init_function_pointers();
1279 test_refcount();
1280 test_CreateEnumObject();
1281 test_file_types();
1282 test_templates();
1283 test_compressed_files();
1284 test_getname();
1285 test_syntax();
1286 test_syntax_semicolon_comma();
1287 test_complex_object();
1288 test_standard_templates();
1289 test_type_index_color();
1290 test_dump();
1292 FreeLibrary(hd3dxof);