pop b0283e26815279d45d201d5585820bb1d1997663
[wine/hacks.git] / dlls / d3dxof / tests / d3dxof.c
blobf1d020a24dcfea4f8d7457e7e6893342263d30d6
1 /*
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
20 #define COBJMACROS
22 #include <assert.h>
23 #include <stdio.h>
24 #include "wine/test.h"
25 #include "initguid.h"
26 #include "dxfile.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 char template[] =
40 "xof 0302txt 0064\n"
41 "template Header\n"
42 "{\n"
43 "<3D82AB43-62DA-11CF-AB39-0020AF71E433>\n"
44 "WORD major;\n"
45 "WORD minor;\n"
46 "DWORD flags;\n"
47 "}\n";
49 char object[] =
50 "xof 0302txt 0064\n"
51 "Header Object\n"
52 "{\n"
53 "1; 2; 3;\n"
54 "}\n";
56 char empty_txt_file[] = "xof 0302txt 0064";
57 char empty_bin_file[] = "xof 0302bin 0064";
58 /* MSZip data is generated with the command "MAKECAB.EXE /D Compress=ON /D CompressionType=MSZip file packed"
59 * Data in cab is after the filename (null terminated) and the 32-bit checksum:
60 * size (16-bit), packed_size (16-bit) and compressed data (with leading 16-bit CK signature)
61 * Data in x files is preceding by 2 16-bit words: size with xof header (16 bytes) and a 0 value
62 * It does not seem possible to generate a MSZip data with no byte, so put just 1 byte here */
63 /* "\n" packed with MSZip => not text */
64 char empty_tzip_file[] = "xof 0302tzip0064\x11\x00\x00\x00\x01\x00\x05\x00\x43\x4b\xe3\x02\x00";
65 /* "\n" packed with MSZip => not token (token are 16-bit and there is only 1 byte) */
66 char empty_bzip_file[] = "xof 0302bzip0064\x11\x00\x00\x00\x01\x00\x05\x00\x43\x4b\xe3\x02\x00";
67 char empty_cmp_file[] = "xof 0302cmp 0064";
68 char empty_xxxx_file[] = "xof 0302xxxx0064";
70 static void init_function_pointers(void)
72 /* We have to use LoadLibrary as no d3dxof functions are referenced directly */
73 hd3dxof = LoadLibraryA("d3dxof.dll");
75 pDirectXFileCreate = (void *)GetProcAddress(hd3dxof, "DirectXFileCreate");
78 static ULONG getRefcount(IUnknown *iface)
80 IUnknown_AddRef(iface);
81 return IUnknown_Release(iface);
84 static void test_refcount(void)
86 HRESULT hr;
87 ULONG ref;
88 LPDIRECTXFILE lpDirectXFile = NULL;
89 LPDIRECTXFILEENUMOBJECT lpdxfeo;
90 LPDIRECTXFILEDATA lpdxfd;
91 DXFILELOADMEMORY dxflm;
93 if (!pDirectXFileCreate)
95 win_skip("DirectXFileCreate is not available\n");
96 return;
99 hr = pDirectXFileCreate(&lpDirectXFile);
100 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
101 if(!lpDirectXFile)
103 skip("Couldn't create DirectXFile interface\n");
104 return;
107 ref = getRefcount( (IUnknown *) lpDirectXFile);
108 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
109 ref = IDirectXFile_AddRef(lpDirectXFile);
110 ok(ref == 2, "Got refcount %d, expected 1\n", ref);
111 ref = IDirectXFile_Release(lpDirectXFile);
112 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
114 hr = IDirectXFile_RegisterTemplates(lpDirectXFile, template, sizeof(template) - 1);
115 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
117 dxflm.lpMemory = &object;
118 dxflm.dSize = sizeof(object) - 1;
119 hr = IDirectXFile_CreateEnumObject(lpDirectXFile, &dxflm, DXFILELOAD_FROMMEMORY, &lpdxfeo);
120 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
121 ref = getRefcount( (IUnknown *) lpDirectXFile);
122 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
123 ref = getRefcount( (IUnknown *) lpdxfeo);
124 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
126 hr = IDirectXFileEnumObject_GetNextDataObject(lpdxfeo, &lpdxfd);
127 ok(hr == DXFILE_OK, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
128 ref = getRefcount( (IUnknown *) lpDirectXFile);
129 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
130 ref = getRefcount( (IUnknown *) lpdxfeo);
131 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
132 /* Enum object gets references to all top level objects */
133 ref = getRefcount( (IUnknown *) lpdxfd);
134 ok(ref == 2, "Got refcount %d, expected 2\n", ref);
136 ref = IDirectXFile_Release(lpDirectXFile);
137 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
138 /* Nothing changes for all other objects */
139 ref = getRefcount( (IUnknown *) lpdxfeo);
140 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
141 ref = getRefcount( (IUnknown *) lpdxfd);
142 ok(ref == 2, "Got refcount %d, expected 1\n", ref);
144 ref = IDirectXFileEnumObject_Release(lpdxfeo);
145 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
146 /* Enum object releases references to all top level objects */
147 ref = getRefcount( (IUnknown *) lpdxfd);
148 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
150 ref = IDirectXFileData_Release(lpdxfd);
151 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
154 static void test_CreateEnumObject(void)
156 HRESULT hr;
157 ULONG ref;
158 LPDIRECTXFILE lpDirectXFile = NULL;
159 LPDIRECTXFILEENUMOBJECT lpdxfeo;
160 LPDIRECTXFILEDATA lpdxfd;
161 DXFILELOADMEMORY dxflm;
162 BYTE* pdata;
163 DWORD size;
165 if (!pDirectXFileCreate)
167 win_skip("DirectXFileCreate is not available\n");
168 return;
171 hr = pDirectXFileCreate(&lpDirectXFile);
172 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
173 if(!lpDirectXFile)
175 skip("Couldn't create DirectXFile interface\n");
176 return;
179 hr = IDirectXFile_RegisterTemplates(lpDirectXFile, template, sizeof(template) - 1);
180 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
182 dxflm.lpMemory = &object;
183 dxflm.dSize = sizeof(object) - 1;
184 /* Check that only lowest 4 bits are relevant in DXFILELOADOPTIONS */
185 hr = IDirectXFile_CreateEnumObject(lpDirectXFile, &dxflm, 0xFFFFFFF0 + DXFILELOAD_FROMMEMORY, &lpdxfeo);
186 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
188 hr = IDirectXFileEnumObject_GetNextDataObject(lpdxfeo, &lpdxfd);
189 ok(hr == DXFILE_OK, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
191 hr = IDirectXFileData_GetData(lpdxfd, NULL, &size, (void**)&pdata);
192 ok(hr == DXFILE_OK, "IDirectXFileData_GetData: %x\n", hr);
194 ok(size == 8, "Retrieved data size is wrong\n");
195 ok((*((WORD*)pdata) == 1) && (*((WORD*)(pdata+2)) == 2) && (*((DWORD*)(pdata+4)) == 3), "Retrieved data is wrong\n");
197 ref = IDirectXFileEnumObject_Release(lpdxfeo);
198 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
200 ref = IDirectXFile_Release(lpDirectXFile);
201 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
203 ref = IDirectXFileData_Release(lpdxfd);
204 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
207 static void test_file_types(void)
209 HRESULT hr;
210 LPDIRECTXFILE dxfile = NULL;
211 LPDIRECTXFILEENUMOBJECT enum_object;
212 DXFILELOADMEMORY lminfo;
214 if (!pDirectXFileCreate)
216 win_skip("DirectXFileCreate is not available\n");
217 return;
220 hr = pDirectXFileCreate(&dxfile);
221 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
222 if (!dxfile)
224 skip("Couldn't create DirectXFile interface\n");
225 return;
228 hr = IDirectXFile_RegisterTemplates(dxfile, empty_txt_file, sizeof(empty_txt_file) - 1);
229 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
231 hr = IDirectXFile_RegisterTemplates(dxfile, empty_bin_file, sizeof(empty_bin_file) - 1);
232 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
234 hr = IDirectXFile_RegisterTemplates(dxfile, empty_tzip_file, sizeof(empty_tzip_file) - 1);
235 todo_wine ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
237 hr = IDirectXFile_RegisterTemplates(dxfile, empty_bzip_file, sizeof(empty_bzip_file) - 1);
238 todo_wine ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
240 hr = IDirectXFile_RegisterTemplates(dxfile, empty_cmp_file, sizeof(empty_cmp_file) - 1);
241 ok(hr == DXFILEERR_BADFILETYPE, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
243 hr = IDirectXFile_RegisterTemplates(dxfile, empty_xxxx_file, sizeof(empty_xxxx_file) - 1);
244 ok(hr == DXFILEERR_BADFILETYPE, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
246 lminfo.lpMemory = empty_txt_file;
247 lminfo.dSize = sizeof(empty_txt_file) - 1;
248 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
249 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
250 if (hr == DXFILE_OK) IDirectXFileEnumObject_Release(enum_object);
252 lminfo.lpMemory = empty_bin_file;
253 lminfo.dSize = sizeof(empty_bin_file) - 1;
254 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
255 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
256 if (hr == DXFILE_OK) IDirectXFileEnumObject_Release(enum_object);
258 lminfo.lpMemory = empty_tzip_file;
259 lminfo.dSize = sizeof(empty_tzip_file) - 1;
260 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
261 todo_wine ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
262 if (hr == DXFILE_OK) IDirectXFileEnumObject_Release(enum_object);
264 lminfo.lpMemory = empty_bzip_file;
265 lminfo.dSize = sizeof(empty_bzip_file) - 1;
266 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
267 todo_wine ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
268 if (hr == DXFILE_OK) IDirectXFileEnumObject_Release(enum_object);
270 lminfo.lpMemory = empty_cmp_file;
271 lminfo.dSize = sizeof(empty_cmp_file) - 1;
272 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
273 ok(hr == DXFILEERR_BADFILETYPE, "IDirectXFile_CreateEnumObject: %x\n", hr);
275 lminfo.lpMemory = empty_xxxx_file;
276 lminfo.dSize = sizeof(empty_xxxx_file) - 1;
277 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
278 ok(hr == DXFILEERR_BADFILETYPE, "IDirectXFile_CreateEnumObject: %x\n", hr);
280 IDirectXFile_Release(dxfile);
283 /* Set it to 1 to expand the string when dumping the object. This is useful when there is
284 * only one string in a sub-object (very common). Use with care, this may lead to a crash. */
285 #define EXPAND_STRING 0
287 static void process_data(LPDIRECTXFILEDATA lpDirectXFileData, int* plevel)
289 HRESULT hr;
290 char name[100];
291 GUID clsid;
292 CONST GUID* clsid_type = NULL;
293 char str_clsid[40];
294 char str_clsid_type[40];
295 DWORD len= 100;
296 LPDIRECTXFILEOBJECT pChildObj;
297 int i;
298 int j = 0;
299 LPBYTE pData;
300 DWORD k, size;
302 hr = IDirectXFileData_GetId(lpDirectXFileData, &clsid);
303 ok(hr == DXFILE_OK, "IDirectXFileData_GetId: %x\n", hr);
304 hr = IDirectXFileData_GetName(lpDirectXFileData, name, &len);
305 ok(hr == DXFILE_OK, "IDirectXFileData_GetName: %x\n", hr);
306 hr = IDirectXFileData_GetType(lpDirectXFileData, &clsid_type);
307 ok(hr == DXFILE_OK, "IDirectXFileData_GetType: %x\n", hr);
308 hr = IDirectXFileData_GetData(lpDirectXFileData, NULL, &size, (void**)&pData);
309 ok(hr == DXFILE_OK, "IDirectXFileData_GetData: %x\n", hr);
310 for (i = 0; i < *plevel; i++)
311 printf(" ");
312 debugstr_guid(str_clsid, &clsid);
313 debugstr_guid(str_clsid_type, clsid_type);
314 printf("Found object '%s' - %s - %s - %d\n", name, str_clsid, str_clsid_type, size);
316 if (EXPAND_STRING && size == 4)
318 char * str = *(char**)pData;
319 printf("string %s\n", str);
321 else if (size)
323 for (k = 0; k < size; k++)
325 if (k && !(k%16))
326 printf("\n");
327 printf("%02x ", pData[k]);
329 printf("\n");
331 (*plevel)++;
332 while (SUCCEEDED(hr = IDirectXFileData_GetNextObject(lpDirectXFileData, &pChildObj)))
334 LPDIRECTXFILEDATA p1;
335 LPDIRECTXFILEDATAREFERENCE p2;
336 LPDIRECTXFILEBINARY p3;
337 j++;
339 hr = IDirectXFileObject_QueryInterface(pChildObj, &IID_IDirectXFileData, (void **) &p1);
340 if (SUCCEEDED(hr))
342 for (i = 0; i < *plevel; i++)
343 printf(" ");
344 printf("Found Data (%d)\n", j);
345 process_data(p1, plevel);
346 IDirectXFileData_Release(p1);
348 hr = IDirectXFileObject_QueryInterface(pChildObj, &IID_IDirectXFileDataReference, (void **) &p2);
349 if (SUCCEEDED(hr))
351 LPDIRECTXFILEDATA pfdo;
352 for (i = 0; i < *plevel; i++)
353 printf(" ");
354 printf("Found Data Reference (%d)\n", j);
355 #if 0
356 hr = IDirectXFileDataReference_GetId(lpDirectXFileData, &clsid);
357 ok(hr == DXFILE_OK, "IDirectXFileData_GetId: %x\n", hr);
358 hr = IDirectXFileDataReference_GetName(lpDirectXFileData, name, &len);
359 ok(hr == DXFILE_OK, "IDirectXFileData_GetName: %x\n", hr);
360 #endif
361 IDirectXFileDataReference_Resolve(p2, &pfdo);
362 process_data(pfdo, plevel);
363 IDirectXFileData_Release(pfdo);
364 IDirectXFileDataReference_Release(p2);
366 hr = IDirectXFileObject_QueryInterface(pChildObj, &IID_IDirectXFileBinary, (void **) &p3);
367 if (SUCCEEDED(hr))
369 for (i = 0; i < *plevel; i++)
370 printf(" ");
371 printf("Found Binary (%d)\n", j);
372 IDirectXFileBinary_Release(p3);
375 (*plevel)--;
376 ok(hr == DXFILE_OK || hr == DXFILEERR_NOMOREOBJECTS, "IDirectXFileData_GetNextObject: %x\n", hr);
379 static void test_dump(void)
381 HRESULT hr;
382 ULONG ref;
383 LPDIRECTXFILE lpDirectXFile = NULL;
384 LPDIRECTXFILEENUMOBJECT lpDirectXFileEnumObject = NULL;
385 LPDIRECTXFILEDATA lpDirectXFileData = NULL;
386 HANDLE hFile;
387 LPVOID pvData = NULL;
388 DWORD cbSize;
390 if (!pDirectXFileCreate)
392 win_skip("DirectXFileCreate is not available\n");
393 goto exit;
396 /* Dump data only if there is an object and a template */
397 hFile = CreateFileA("objects.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
398 if (hFile == INVALID_HANDLE_VALUE)
399 return;
400 CloseHandle(hFile);
402 hFile = CreateFileA("templates.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
403 if (hFile == INVALID_HANDLE_VALUE)
404 return;
406 pvData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 10000);
408 if (!ReadFile(hFile, pvData, 10000, &cbSize, NULL))
410 skip("Template file is too big\n");
411 goto exit;
414 printf("Load %d bytes\n", cbSize);
416 hr = pDirectXFileCreate(&lpDirectXFile);
417 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
418 if(!lpDirectXFile)
420 skip("Couldn't create DirectXFile interface\n");
421 goto exit;
424 hr = IDirectXFile_RegisterTemplates(lpDirectXFile, pvData, cbSize);
425 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
427 hr = IDirectXFile_CreateEnumObject(lpDirectXFile, (LPVOID)"objects.txt", DXFILELOAD_FROMFILE, &lpDirectXFileEnumObject);
428 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
430 while (SUCCEEDED(hr = IDirectXFileEnumObject_GetNextDataObject(lpDirectXFileEnumObject, &lpDirectXFileData)))
432 int level = 0;
433 printf("\n");
434 process_data(lpDirectXFileData, &level);
435 IDirectXFileData_Release(lpDirectXFileData);
437 ok(hr == DXFILE_OK || hr == DXFILEERR_NOMOREOBJECTS, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
439 ref = IDirectXFile_Release(lpDirectXFileEnumObject);
440 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
442 ref = IDirectXFile_Release(lpDirectXFile);
443 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
445 CloseHandle(hFile);
447 exit:
448 HeapFree(GetProcessHeap(), 0, pvData);
451 START_TEST(d3dxof)
453 init_function_pointers();
455 test_refcount();
456 test_CreateEnumObject();
457 test_file_types();
458 test_dump();
460 FreeLibrary(hd3dxof);