2 * Copyright 2012 Christian Costa
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/test.h"
25 static const char templates_bad_file_type1
[] =
28 static const char templates_bad_file_version
[] =
31 static const char templates_bad_file_type2
[] =
34 static const char templates_bad_file_float_size
[] =
37 static const char templates_parse_error
[] =
41 static const char templates
[] =
45 "<3D82AB43-62DA-11CF-AB39-0020AF71E433>"
51 static char objects
[] =
58 static char object_noname
[] =
65 static char template_using_index_color_lower
[] =
67 "template MeshVertexColors\n"
69 "<1630B821-7842-11cf-8F52-0040333594A3>\n"
70 "DWORD nVertexColors;\n"
71 "array indexColor vertexColors[nVertexColors];\n"
74 static char template_using_index_color_upper
[] =
76 "template MeshVertexColors\n"
78 "<1630B821-7842-11cf-8F52-0040333594A3>\n"
79 "DWORD nVertexColors;\n"
80 "array IndexColor vertexColors[nVertexColors];\n"
83 static void test_templates(void)
88 ret
= D3DXFileCreate(NULL
);
89 ok(ret
== E_POINTER
, "D3DXCreateFile returned %#x, expected %#x\n", ret
, E_POINTER
);
91 ret
= D3DXFileCreate(&d3dxfile
);
92 ok(ret
== S_OK
, "D3DXCreateFile failed with %#x\n", ret
);
94 ret
= d3dxfile
->lpVtbl
->RegisterTemplates(d3dxfile
, templates_bad_file_type1
, sizeof(templates_bad_file_type1
) - 1);
95 ok(ret
== D3DXFERR_BADFILETYPE
, "RegisterTemplates returned %#x, expected %#x\n", ret
, D3DXFERR_BADFILETYPE
);
97 ret
= d3dxfile
->lpVtbl
->RegisterTemplates(d3dxfile
, templates_bad_file_version
, sizeof(templates_bad_file_version
) - 1);
98 ok(ret
== D3DXFERR_BADFILEVERSION
, "RegisterTemplates returned %#x, expected %#x\n", ret
, D3DXFERR_BADFILEVERSION
);
100 ret
= d3dxfile
->lpVtbl
->RegisterTemplates(d3dxfile
, templates_bad_file_type2
, sizeof(templates_bad_file_type2
) - 1);
101 ok(ret
== D3DXFERR_BADFILETYPE
, "RegisterTemplates returned %#x, expected %#x\n", ret
, D3DXFERR_BADFILETYPE
);
103 ret
= d3dxfile
->lpVtbl
->RegisterTemplates(d3dxfile
, templates_bad_file_float_size
, sizeof(templates_bad_file_float_size
) - 1);
104 ok(ret
== D3DXFERR_BADFILEFLOATSIZE
, "RegisterTemplates returned %#x, expected %#x\n", ret
, D3DXFERR_BADFILEFLOATSIZE
);
106 ret
= d3dxfile
->lpVtbl
->RegisterTemplates(d3dxfile
, templates_parse_error
, sizeof(templates_parse_error
) - 1);
107 ok(ret
== D3DXFERR_PARSEERROR
, "RegisterTemplates returned %#x, expected %#x\n", ret
, D3DXFERR_PARSEERROR
);
109 ret
= d3dxfile
->lpVtbl
->RegisterTemplates(d3dxfile
, templates
, sizeof(templates
) - 1);
110 ok(ret
== S_OK
, "RegisterTemplates failed with %#x\n", ret
);
112 d3dxfile
->lpVtbl
->Release(d3dxfile
);
115 static void test_lock_unlock(void)
118 D3DXF_FILELOADMEMORY memory
;
119 ID3DXFileEnumObject
*enum_object
;
120 ID3DXFileData
*data_object
;
125 ret
= D3DXFileCreate(&d3dxfile
);
126 ok(ret
== S_OK
, "D3DXCreateFile failed with %#x\n", ret
);
128 ret
= d3dxfile
->lpVtbl
->RegisterTemplates(d3dxfile
, templates
, sizeof(templates
) - 1);
129 ok(ret
== S_OK
, "RegisterTemplates failed with %#x\n", ret
);
131 memory
.lpMemory
= objects
;
132 memory
.dSize
= sizeof(objects
) - 1;
134 ret
= d3dxfile
->lpVtbl
->CreateEnumObject(d3dxfile
, &memory
, D3DXF_FILELOAD_FROMMEMORY
, &enum_object
);
135 ok(ret
== S_OK
, "CreateEnumObject failed with %#x\n", ret
);
137 ret
= enum_object
->lpVtbl
->GetChild(enum_object
, 0, &data_object
);
138 ok(ret
== S_OK
, "GetChild failed with %#x\n", ret
);
140 ret
= data_object
->lpVtbl
->Unlock(data_object
);
141 ok(ret
== S_OK
, "Unlock failed with %#x\n", ret
);
142 ret
= data_object
->lpVtbl
->Lock(data_object
, &size
, &data
);
143 ok(ret
== S_OK
, "Lock failed with %#x\n", ret
);
144 ret
= data_object
->lpVtbl
->Lock(data_object
, &size
, &data
);
145 ok(ret
== S_OK
, "Lock failed with %#x\n", ret
);
146 ret
= data_object
->lpVtbl
->Unlock(data_object
);
147 ok(ret
== S_OK
, "Unlock failed with %#x\n", ret
);
148 ret
= data_object
->lpVtbl
->Unlock(data_object
);
149 ok(ret
== S_OK
, "Unlock failed with %#x\n", ret
);
151 data_object
->lpVtbl
->Release(data_object
);
152 enum_object
->lpVtbl
->Release(enum_object
);
153 d3dxfile
->lpVtbl
->Release(d3dxfile
);
156 static void test_getname(void)
159 D3DXF_FILELOADMEMORY memory
;
160 ID3DXFileEnumObject
*enum_object
;
161 ID3DXFileData
*data_object
;
166 ret
= D3DXFileCreate(&d3dxfile
);
167 ok(ret
== S_OK
, "D3DXCreateFile failed with %#x\n", ret
);
169 ret
= d3dxfile
->lpVtbl
->RegisterTemplates(d3dxfile
, templates
, sizeof(templates
) - 1);
170 ok(ret
== S_OK
, "RegisterTemplates failed with %#x\n", ret
);
172 /* Check object with name */
173 memory
.lpMemory
= objects
;
174 memory
.dSize
= sizeof(objects
) - 1;
175 ret
= d3dxfile
->lpVtbl
->CreateEnumObject(d3dxfile
, &memory
, D3DXF_FILELOAD_FROMMEMORY
, &enum_object
);
176 ok(ret
== S_OK
, "CreateEnumObject failed with %#x\n", ret
);
177 ret
= enum_object
->lpVtbl
->GetChild(enum_object
, 0, &data_object
);
178 ok(ret
== S_OK
, "GetChild failed with %#x\n", ret
);
180 ret
= data_object
->lpVtbl
->GetName(data_object
, NULL
, NULL
);
181 ok(ret
== D3DXFERR_BADVALUE
, "GetName returned %#x, expected %#x\n", ret
, D3DXFERR_BADVALUE
);
182 ret
= data_object
->lpVtbl
->GetName(data_object
, name
, NULL
);
183 ok(ret
== D3DXFERR_BADVALUE
, "GetName returned %#x, expected %#x\n", ret
, D3DXFERR_BADVALUE
);
184 ret
= data_object
->lpVtbl
->GetName(data_object
, NULL
, &length
);
185 ok(ret
== S_OK
, "GetName failed with %#x\n", ret
);
186 ok(length
== 7, "Returned length should be 7 instead of %ld\n", length
);
187 length
= sizeof(name
);
188 ret
= data_object
->lpVtbl
->GetName(data_object
, name
, &length
);
189 ok(ret
== S_OK
, "GetName failed with %#x\n", ret
);
190 ok(length
== 7, "Returned length should be 7 instead of %ld\n", length
);
191 ok(!strcmp(name
, "Object"), "Returned string should be 'Object' instead of '%s'\n", name
);
193 ret
= data_object
->lpVtbl
->GetName(data_object
, name
, &length
);
194 ok(ret
== D3DXFERR_BADVALUE
, "GetName returned %#x, expected %#x\n", ret
, D3DXFERR_BADVALUE
);
196 data_object
->lpVtbl
->Release(data_object
);
197 enum_object
->lpVtbl
->Release(enum_object
);
199 /* Check object without name */
200 memory
.lpMemory
= object_noname
;
201 memory
.dSize
= sizeof(object_noname
) - 1;
202 ret
= d3dxfile
->lpVtbl
->CreateEnumObject(d3dxfile
, &memory
, D3DXF_FILELOAD_FROMMEMORY
, &enum_object
);
203 ok(ret
== S_OK
, "CreateEnumObject failed with %#x\n", ret
);
204 ret
= enum_object
->lpVtbl
->GetChild(enum_object
, 0, &data_object
);
205 ok(ret
== S_OK
, "GetChild failed with %#x\n", ret
);
207 /* Contrary to d3dxof, d3dx9_36 returns an empty string with a null byte when no name is available.
208 * If the input size is 0, it returns a length of 1 without touching the buffer */
209 ret
= data_object
->lpVtbl
->GetName(data_object
, NULL
, &length
);
210 ok(ret
== S_OK
, "GetName failed with %#x\n", ret
);
211 ok(length
== 1, "Returned length should be 1 instead of %ld\n", length
);
214 ret
= data_object
->lpVtbl
->GetName(data_object
, name
, &length
);
215 ok(ret
== S_OK
, "GetName failed with %#x\n", ret
);
216 ok(length
== 1, "Returned length should be 1 instead of %ld\n", length
);
217 ok(name
[0] == 0x7f, "First character is %#x instead of 0x7f\n", name
[0]);
218 length
= sizeof(name
);
220 ret
= data_object
->lpVtbl
->GetName(data_object
, name
, &length
);
221 ok(ret
== S_OK
, "GetName failed with %#x\n", ret
);
222 ok(length
== 1, "Returned length should be 1 instead of %ld\n", length
);
223 ok(name
[0] == 0, "First character is %#x instead of 0x00\n", name
[0]);
225 data_object
->lpVtbl
->Release(data_object
);
226 enum_object
->lpVtbl
->Release(enum_object
);
227 d3dxfile
->lpVtbl
->Release(d3dxfile
);
230 static void test_type_index_color(void)
235 ret
= D3DXFileCreate(&d3dxfile
);
236 ok(ret
== S_OK
, "D3DXCreateFile failed with %#x\n", ret
);
238 /* Test that 'indexColor' can be used (same as IndexedColor in standard templates) and is case sensitive */
239 ret
= d3dxfile
->lpVtbl
->RegisterTemplates(d3dxfile
, template_using_index_color_lower
, sizeof(template_using_index_color_lower
) - 1);
240 ok(ret
== S_OK
, "RegisterTemplates failed with %#x\n", ret
);
241 ret
= d3dxfile
->lpVtbl
->RegisterTemplates(d3dxfile
, template_using_index_color_upper
, sizeof(template_using_index_color_upper
) - 1);
242 ok(ret
== D3DXFERR_PARSEERROR
, "RegisterTemplates returned %#x instead of %#x\n", ret
, D3DXFERR_PARSEERROR
);
244 d3dxfile
->lpVtbl
->Release(d3dxfile
);
247 static void process_data(ID3DXFileData
*xfile_data
, int level
)
253 SIZE_T len
= sizeof(name
);
259 ret
= xfile_data
->lpVtbl
->GetId(xfile_data
, &clsid
);
260 ok(ret
== S_OK
, "ID3DXFileData_GetId failed with %#x\n", ret
);
261 ret
= xfile_data
->lpVtbl
->GetName(xfile_data
, name
, &len
);
262 ok(ret
== S_OK
, "ID3DXFileData_GetName failed with %#x\n", ret
);
263 ret
= xfile_data
->lpVtbl
->GetType(xfile_data
, &clsid_type
);
264 ok(ret
== S_OK
, "IDirectXFileData_GetType failed with %#x\n", ret
);
265 ret
= xfile_data
->lpVtbl
->Lock(xfile_data
, &size
, (const void**)&data
);
266 ok(ret
== S_OK
, "IDirectXFileData_Lock failed with %#x\n", ret
);
268 for (i
= 0; i
< level
; i
++)
271 printf("Found object '%s' - %s - %s - %lu\n",
272 len
? name
: "", wine_dbgstr_guid(&clsid
), wine_dbgstr_guid(&clsid_type
), size
);
277 for (j
= 0; j
< size
; j
++)
281 printf("%02x ", data
[j
]);
286 ret
= xfile_data
->lpVtbl
->Unlock(xfile_data
);
287 ok(ret
== S_OK
, "ID3DXFileData_Unlock failed with %#x\n", ret
);
289 ret
= xfile_data
->lpVtbl
->GetChildren(xfile_data
, &children
);
290 ok(ret
== S_OK
, "ID3DXFileData_GetChildren failed with %#x\n", ret
);
294 for (i
= 0; i
< children
; i
++)
296 ID3DXFileData
*child
;
299 ret
= xfile_data
->lpVtbl
->GetChild(xfile_data
, i
, &child
);
300 ok(ret
== S_OK
, "ID3DXFileData_GetChild failed with %#x\n", ret
);
301 for (j
= 0; j
< level
; j
++)
303 if (child
->lpVtbl
->IsReference(child
))
304 printf("Found Data Reference (%d)\n", i
+ 1);
306 printf("Found Data (%d)\n", i
+ 1);
308 process_data(child
, level
);
310 child
->lpVtbl
->Release(child
);
314 /* Dump an X file 'objects.x' and its related templates file 'templates.x' if they are both presents
315 * Useful for debug by comparing outputs from native and builtin dlls */
316 static void test_dump(void)
320 ID3DXFile
*xfile
= NULL
;
321 ID3DXFileEnumObject
*xfile_enum_object
= NULL
;
328 /* Dump data only if there is an object and a template */
329 file
= CreateFileA("objects.x", GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
330 if (file
== INVALID_HANDLE_VALUE
)
334 file
= CreateFileA("templates.x", GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
335 if (file
== INVALID_HANDLE_VALUE
)
338 data
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 10000);
340 if (!ReadFile(file
, data
, 10000, &size
, NULL
))
342 skip("Templates file is too big\n");
346 printf("Load templates file (%u bytes)\n", size
);
348 ret
= D3DXFileCreate(&xfile
);
349 ok(ret
== S_OK
, "D3DXCreateFile failed with %#x\n", ret
);
351 ret
= xfile
->lpVtbl
->RegisterTemplates(xfile
, data
, size
);
352 ok(ret
== S_OK
, "ID3DXFileImpl_RegisterTemplates failed with %#x\n", ret
);
354 ret
= xfile
->lpVtbl
->CreateEnumObject(xfile
, (void*)"objects.x", D3DXF_FILELOAD_FROMFILE
, &xfile_enum_object
);
355 ok(ret
== S_OK
, "ID3DXFile_CreateEnumObject failed with %#x\n", ret
);
357 ret
= xfile_enum_object
->lpVtbl
->GetChildren(xfile_enum_object
, &children
);
358 ok(ret
== S_OK
, "ID3DXFileEnumObject_GetChildren failed with %#x\n", ret
);
360 for (i
= 0; i
< children
; i
++)
362 ID3DXFileData
*child
;
363 ret
= xfile_enum_object
->lpVtbl
->GetChild(xfile_enum_object
, i
, &child
);
364 ok(ret
== S_OK
, "ID3DXFileEnumObject_GetChild failed with %#x\n", ret
);
366 process_data(child
, 0);
367 child
->lpVtbl
->Release(child
);
370 ref
= xfile_enum_object
->lpVtbl
->Release(xfile_enum_object
);
371 ok(ref
== 0, "Got refcount %u, expected 0\n", ref
);
373 ref
= xfile
->lpVtbl
->Release(xfile
);
374 ok(ref
== 0, "Got refcount %u, expected 0\n", ref
);
379 HeapFree(GetProcessHeap(), 0, data
);
387 test_type_index_color();