2 * Some unit tests for d3dxof
4 * Copyright (C) 2008 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
24 #include "wine/test.h"
28 static inline void debugstr_guid( char* buf, CONST GUID *id )
30 sprintf(buf, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
31 id->Data1, id->Data2, id->Data3,
32 id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
33 id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] );
36 static HMODULE hd3dxof;
37 static HRESULT (WINAPI *pDirectXFileCreate)(LPDIRECTXFILE*);
39 static char template[] =
43 "<3D82AB43-62DA-11CF-AB39-0020AF71E433>\n"
49 /* Same version as above compressed with mszip */
50 static char compressed_template[] =
51 "xof 0302tzip0064\x71\x00\x00\x00\x61\x00\x5a\x00"
52 "\x43\x4B\x2B\x49\xCD\x2D\xC8\x49\x2C\x49\x55\xF0\x48\x4D\x4C\x49"
53 "\x2D\xE2\xAA\xE6\xB2\x31\x76\xB1\x30\x72\x74\x32\x31\xD6\x35\x33"
54 "\x72\x71\xD4\x35\x34\x74\x76\xD3\x75\x74\x32\xB6\xD4\x35\x30\x30"
55 "\x32\x70\x74\x33\x37\x74\x35\x31\x36\xB6\xE3\x0A\xF7\x0F\x72\x51"
56 "\xC8\x4D\xCC\xCA\x2F\xB2\x86\xB2\x33\xF3\x40\x6C\x17\x30\x27\x2D"
57 "\x27\x31\xBD\xD8\x9A\xAB\x96\x8B\x0B\x00";
59 static char object[] =
66 /* Same version as above compressed with mszip */
67 static char compressed_object[] =
68 "xof 0302tzip0064\x2c\x00\x00\x00\x1c\x00\x20\x00"
69 "\x43\x4b\xf3\x48\x4d\x4c\x49\x2d\x52\xf0\x4f\xca\x4a\x4d\x2e\xe1"
70 "\xaa\xe6\x32\xb4\x56\x30\xb2\x56\x30\xb6\xe6\xaa\xe5\xe2\x02\x00";
72 static char empty_txt_file[] = "xof 0302txt 0064";
73 static char empty_bin_file[] = "xof 0302bin 0064";
74 /* MSZip data is generated with the command "MAKECAB.EXE /D Compress=ON /D CompressionType=MSZip file packed"
75 * Data in cab is after the filename (null terminated) and the 32-bit checksum:
76 * size (16-bit), packed_size (16-bit) and compressed data (with leading 16-bit CK signature)
77 * Data in x files is preceding by 2 16-bit words: size with xof header (16 bytes) and a 0 value
78 * It does not seem possible to generate a MSZip data with no byte, so put just 1 byte here */
79 /* "\n" packed with MSZip => not text */
80 static char empty_tzip_file[] = "xof 0302tzip0064\x11\x00\x00\x00\x01\x00\x05\x00\x43\x4b\xe3\x02\x00";
81 /* "\n" packed with MSZip => not token (token are 16-bit and there is only 1 byte) */
82 static char empty_bzip_file[] = "xof 0302bzip0064\x11\x00\x00\x00\x01\x00\x05\x00\x43\x4b\xe3\x02\x00";
83 static char empty_cmp_file[] = "xof 0302cmp 0064";
84 static char empty_xxxx_file[] = "xof 0302xxxx0064";
86 static void init_function_pointers(void)
88 /* We have to use LoadLibrary as no d3dxof functions are referenced directly */
89 hd3dxof = LoadLibraryA("d3dxof.dll");
91 pDirectXFileCreate = (void *)GetProcAddress(hd3dxof, "DirectXFileCreate");
94 static ULONG getRefcount(IUnknown *iface)
96 IUnknown_AddRef(iface);
97 return IUnknown_Release(iface);
100 static void test_refcount(void)
104 LPDIRECTXFILE lpDirectXFile = NULL;
105 LPDIRECTXFILEENUMOBJECT lpdxfeo;
106 LPDIRECTXFILEDATA lpdxfd;
107 DXFILELOADMEMORY dxflm;
109 if (!pDirectXFileCreate)
111 win_skip("DirectXFileCreate is not available\n");
115 hr = pDirectXFileCreate(&lpDirectXFile);
116 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
119 skip("Couldn't create DirectXFile interface\n");
123 ref = getRefcount( (IUnknown *) lpDirectXFile);
124 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
125 ref = IDirectXFile_AddRef(lpDirectXFile);
126 ok(ref == 2, "Got refcount %d, expected 1\n", ref);
127 ref = IDirectXFile_Release(lpDirectXFile);
128 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
130 hr = IDirectXFile_RegisterTemplates(lpDirectXFile, template, sizeof(template) - 1);
131 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
133 dxflm.lpMemory = &object;
134 dxflm.dSize = sizeof(object) - 1;
135 hr = IDirectXFile_CreateEnumObject(lpDirectXFile, &dxflm, DXFILELOAD_FROMMEMORY, &lpdxfeo);
136 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
137 ref = getRefcount( (IUnknown *) lpDirectXFile);
138 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
139 ref = getRefcount( (IUnknown *) lpdxfeo);
140 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
142 hr = IDirectXFileEnumObject_GetNextDataObject(lpdxfeo, &lpdxfd);
143 ok(hr == DXFILE_OK, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
144 ref = getRefcount( (IUnknown *) lpDirectXFile);
145 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
146 ref = getRefcount( (IUnknown *) lpdxfeo);
147 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
148 /* Enum object gets references to all top level objects */
149 ref = getRefcount( (IUnknown *) lpdxfd);
150 ok(ref == 2, "Got refcount %d, expected 2\n", ref);
152 ref = IDirectXFile_Release(lpDirectXFile);
153 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
154 /* Nothing changes for all other objects */
155 ref = getRefcount( (IUnknown *) lpdxfeo);
156 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
157 ref = getRefcount( (IUnknown *) lpdxfd);
158 ok(ref == 2, "Got refcount %d, expected 1\n", ref);
160 ref = IDirectXFileEnumObject_Release(lpdxfeo);
161 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
162 /* Enum object releases references to all top level objects */
163 ref = getRefcount( (IUnknown *) lpdxfd);
164 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
166 ref = IDirectXFileData_Release(lpdxfd);
167 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
170 static void test_CreateEnumObject(void)
174 LPDIRECTXFILE lpDirectXFile = NULL;
175 LPDIRECTXFILEENUMOBJECT lpdxfeo;
176 LPDIRECTXFILEDATA lpdxfd;
177 DXFILELOADMEMORY dxflm;
181 if (!pDirectXFileCreate)
183 win_skip("DirectXFileCreate is not available\n");
187 hr = pDirectXFileCreate(&lpDirectXFile);
188 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
191 skip("Couldn't create DirectXFile interface\n");
195 hr = IDirectXFile_RegisterTemplates(lpDirectXFile, template, sizeof(template) - 1);
196 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
198 dxflm.lpMemory = &object;
199 dxflm.dSize = sizeof(object) - 1;
200 /* Check that only lowest 4 bits are relevant in DXFILELOADOPTIONS */
201 hr = IDirectXFile_CreateEnumObject(lpDirectXFile, &dxflm, 0xFFFFFFF0 + DXFILELOAD_FROMMEMORY, &lpdxfeo);
202 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
204 hr = IDirectXFileEnumObject_GetNextDataObject(lpdxfeo, &lpdxfd);
205 ok(hr == DXFILE_OK, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
207 hr = IDirectXFileData_GetData(lpdxfd, NULL, &size, (void**)&pdata);
208 ok(hr == DXFILE_OK, "IDirectXFileData_GetData: %x\n", hr);
210 ok(size == 8, "Retrieved data size is wrong\n");
211 ok((*((WORD*)pdata) == 1) && (*((WORD*)(pdata+2)) == 2) && (*((DWORD*)(pdata+4)) == 3), "Retrieved data is wrong\n");
213 ref = IDirectXFileEnumObject_Release(lpdxfeo);
214 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
216 ref = IDirectXFile_Release(lpDirectXFile);
217 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
219 ref = IDirectXFileData_Release(lpdxfd);
220 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
223 static void test_file_types(void)
226 LPDIRECTXFILE dxfile = NULL;
227 LPDIRECTXFILEENUMOBJECT enum_object;
228 DXFILELOADMEMORY lminfo;
230 if (!pDirectXFileCreate)
232 win_skip("DirectXFileCreate is not available\n");
236 hr = pDirectXFileCreate(&dxfile);
237 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
240 skip("Couldn't create DirectXFile interface\n");
244 hr = IDirectXFile_RegisterTemplates(dxfile, empty_txt_file, sizeof(empty_txt_file) - 1);
245 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
247 hr = IDirectXFile_RegisterTemplates(dxfile, empty_bin_file, sizeof(empty_bin_file) - 1);
248 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
250 hr = IDirectXFile_RegisterTemplates(dxfile, empty_tzip_file, sizeof(empty_tzip_file) - 1);
251 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
253 hr = IDirectXFile_RegisterTemplates(dxfile, empty_bzip_file, sizeof(empty_bzip_file) - 1);
254 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
256 hr = IDirectXFile_RegisterTemplates(dxfile, empty_cmp_file, sizeof(empty_cmp_file) - 1);
257 ok(hr == DXFILEERR_BADFILETYPE, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
259 hr = IDirectXFile_RegisterTemplates(dxfile, empty_xxxx_file, sizeof(empty_xxxx_file) - 1);
260 ok(hr == DXFILEERR_BADFILETYPE, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
262 lminfo.lpMemory = empty_txt_file;
263 lminfo.dSize = sizeof(empty_txt_file) - 1;
264 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
265 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
266 if (hr == DXFILE_OK) IDirectXFileEnumObject_Release(enum_object);
268 lminfo.lpMemory = empty_bin_file;
269 lminfo.dSize = sizeof(empty_bin_file) - 1;
270 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
271 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
272 if (hr == DXFILE_OK) IDirectXFileEnumObject_Release(enum_object);
274 lminfo.lpMemory = empty_tzip_file;
275 lminfo.dSize = sizeof(empty_tzip_file) - 1;
276 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
277 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
278 if (hr == DXFILE_OK) IDirectXFileEnumObject_Release(enum_object);
280 lminfo.lpMemory = empty_bzip_file;
281 lminfo.dSize = sizeof(empty_bzip_file) - 1;
282 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
283 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
284 if (hr == DXFILE_OK) IDirectXFileEnumObject_Release(enum_object);
286 lminfo.lpMemory = empty_cmp_file;
287 lminfo.dSize = sizeof(empty_cmp_file) - 1;
288 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
289 ok(hr == DXFILEERR_BADFILETYPE, "IDirectXFile_CreateEnumObject: %x\n", hr);
291 lminfo.lpMemory = empty_xxxx_file;
292 lminfo.dSize = sizeof(empty_xxxx_file) - 1;
293 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
294 ok(hr == DXFILEERR_BADFILETYPE, "IDirectXFile_CreateEnumObject: %x\n", hr);
296 IDirectXFile_Release(dxfile);
299 static void test_compressed_files(void)
302 LPDIRECTXFILE dxfile = NULL;
303 LPDIRECTXFILEENUMOBJECT enum_object;
304 LPDIRECTXFILEDATA file_data;
305 DXFILELOADMEMORY lminfo;
309 if (!pDirectXFileCreate)
311 win_skip("DirectXFileCreate is not available\n");
315 hr = pDirectXFileCreate(&dxfile);
316 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
319 skip("Couldn't create DirectXFile interface\n");
323 hr = IDirectXFile_RegisterTemplates(dxfile, compressed_template, sizeof(compressed_template) - 1);
324 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
326 lminfo.lpMemory = compressed_object;
327 lminfo.dSize = sizeof(compressed_object) - 1;
328 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
329 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
331 hr = IDirectXFileEnumObject_GetNextDataObject(enum_object, &file_data);
332 ok(hr == DXFILE_OK, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
334 hr = IDirectXFileData_GetData(file_data, NULL, &size, (void**)&data);
335 ok(hr == DXFILE_OK, "IDirectXFileData_GetData: %x\n", hr);
337 ok(size == 8, "Retrieved data size is wrong\n");
338 ok((*((WORD*)data) == 1) && (*((WORD*)(data+2)) == 2) && (*((DWORD*)(data+4)) == 3), "Retrieved data is wrong\n");
340 IDirectXFileData_Release(file_data);
341 IDirectXFileEnumObject_Release(enum_object);
342 IDirectXFile_Release(dxfile);
345 /* Set it to 1 to expand the string when dumping the object. This is useful when there is
346 * only one string in a sub-object (very common). Use with care, this may lead to a crash. */
347 #define EXPAND_STRING 0
349 static void process_data(LPDIRECTXFILEDATA lpDirectXFileData, int* plevel)
354 CONST GUID* clsid_type = NULL;
356 char str_clsid_type[40];
358 LPDIRECTXFILEOBJECT pChildObj;
364 hr = IDirectXFileData_GetId(lpDirectXFileData, &clsid);
365 ok(hr == DXFILE_OK, "IDirectXFileData_GetId: %x\n", hr);
366 hr = IDirectXFileData_GetName(lpDirectXFileData, name, &len);
367 ok(hr == DXFILE_OK, "IDirectXFileData_GetName: %x\n", hr);
368 hr = IDirectXFileData_GetType(lpDirectXFileData, &clsid_type);
369 ok(hr == DXFILE_OK, "IDirectXFileData_GetType: %x\n", hr);
370 hr = IDirectXFileData_GetData(lpDirectXFileData, NULL, &size, (void**)&pData);
371 ok(hr == DXFILE_OK, "IDirectXFileData_GetData: %x\n", hr);
372 for (i = 0; i < *plevel; i++)
374 debugstr_guid(str_clsid, &clsid);
375 debugstr_guid(str_clsid_type, clsid_type);
376 printf("Found object '%s' - %s - %s - %d\n", name, str_clsid, str_clsid_type, size);
378 if (EXPAND_STRING && size == 4)
380 char * str = *(char**)pData;
381 printf("string %s\n", str);
385 for (k = 0; k < size; k++)
389 printf("%02x ", pData[k]);
394 while (SUCCEEDED(hr = IDirectXFileData_GetNextObject(lpDirectXFileData, &pChildObj)))
396 LPDIRECTXFILEDATA p1;
397 LPDIRECTXFILEDATAREFERENCE p2;
398 LPDIRECTXFILEBINARY p3;
401 hr = IDirectXFileObject_QueryInterface(pChildObj, &IID_IDirectXFileData, (void **) &p1);
404 for (i = 0; i < *plevel; i++)
406 printf("Found Data (%d)\n", j);
407 process_data(p1, plevel);
408 IDirectXFileData_Release(p1);
410 hr = IDirectXFileObject_QueryInterface(pChildObj, &IID_IDirectXFileDataReference, (void **) &p2);
413 LPDIRECTXFILEDATA pfdo;
414 for (i = 0; i < *plevel; i++)
416 printf("Found Data Reference (%d)\n", j);
418 hr = IDirectXFileDataReference_GetId(lpDirectXFileData, &clsid);
419 ok(hr == DXFILE_OK, "IDirectXFileData_GetId: %x\n", hr);
420 hr = IDirectXFileDataReference_GetName(lpDirectXFileData, name, &len);
421 ok(hr == DXFILE_OK, "IDirectXFileData_GetName: %x\n", hr);
423 IDirectXFileDataReference_Resolve(p2, &pfdo);
424 process_data(pfdo, plevel);
425 IDirectXFileData_Release(pfdo);
426 IDirectXFileDataReference_Release(p2);
428 hr = IDirectXFileObject_QueryInterface(pChildObj, &IID_IDirectXFileBinary, (void **) &p3);
431 for (i = 0; i < *plevel; i++)
433 printf("Found Binary (%d)\n", j);
434 IDirectXFileBinary_Release(p3);
438 ok(hr == DXFILE_OK || hr == DXFILEERR_NOMOREOBJECTS, "IDirectXFileData_GetNextObject: %x\n", hr);
441 static void test_dump(void)
445 LPDIRECTXFILE lpDirectXFile = NULL;
446 LPDIRECTXFILEENUMOBJECT lpDirectXFileEnumObject = NULL;
447 LPDIRECTXFILEDATA lpDirectXFileData = NULL;
449 LPVOID pvData = NULL;
452 if (!pDirectXFileCreate)
454 win_skip("DirectXFileCreate is not available\n");
458 /* Dump data only if there is an object and a template */
459 hFile = CreateFileA("objects.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
460 if (hFile == INVALID_HANDLE_VALUE)
464 hFile = CreateFileA("templates.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
465 if (hFile == INVALID_HANDLE_VALUE)
468 pvData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 10000);
470 if (!ReadFile(hFile, pvData, 10000, &cbSize, NULL))
472 skip("Template file is too big\n");
476 printf("Load %d bytes\n", cbSize);
478 hr = pDirectXFileCreate(&lpDirectXFile);
479 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
482 skip("Couldn't create DirectXFile interface\n");
486 hr = IDirectXFile_RegisterTemplates(lpDirectXFile, pvData, cbSize);
487 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
489 hr = IDirectXFile_CreateEnumObject(lpDirectXFile, (LPVOID)"objects.txt", DXFILELOAD_FROMFILE, &lpDirectXFileEnumObject);
490 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
492 while (SUCCEEDED(hr = IDirectXFileEnumObject_GetNextDataObject(lpDirectXFileEnumObject, &lpDirectXFileData)))
496 process_data(lpDirectXFileData, &level);
497 IDirectXFileData_Release(lpDirectXFileData);
499 ok(hr == DXFILE_OK || hr == DXFILEERR_NOMOREOBJECTS, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
501 ref = IDirectXFile_Release(lpDirectXFileEnumObject);
502 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
504 ref = IDirectXFile_Release(lpDirectXFile);
505 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
510 HeapFree(GetProcessHeap(), 0, pvData);
515 init_function_pointers();
518 test_CreateEnumObject();
520 test_compressed_files();
523 FreeLibrary(hd3dxof);