d3dxof: Fix file types checks + tests.
[wine.git] / dlls / d3dxof / tests / d3dxof.c
blob11982295adac407275135a54671b3628c3baf1e5
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 char empty_tzip_file[] = "xof 0302tzip0064";
59 char empty_bzip_file[] = "xof 0302bzip0064";
60 char empty_cmp_file[] = "xof 0302cmp 0064";
61 char empty_xxxx_file[] = "xof 0302xxxx0064";
63 static void init_function_pointers(void)
65 /* We have to use LoadLibrary as no d3dxof functions are referenced directly */
66 hd3dxof = LoadLibraryA("d3dxof.dll");
68 pDirectXFileCreate = (void *)GetProcAddress(hd3dxof, "DirectXFileCreate");
71 static ULONG getRefcount(IUnknown *iface)
73 IUnknown_AddRef(iface);
74 return IUnknown_Release(iface);
77 static void test_refcount(void)
79 HRESULT hr;
80 ULONG ref;
81 LPDIRECTXFILE lpDirectXFile = NULL;
82 LPDIRECTXFILEENUMOBJECT lpdxfeo;
83 LPDIRECTXFILEDATA lpdxfd;
84 DXFILELOADMEMORY dxflm;
86 if (!pDirectXFileCreate)
88 win_skip("DirectXFileCreate is not available\n");
89 return;
92 hr = pDirectXFileCreate(&lpDirectXFile);
93 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
94 if(!lpDirectXFile)
96 skip("Couldn't create DirectXFile interface\n");
97 return;
100 ref = getRefcount( (IUnknown *) lpDirectXFile);
101 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
102 ref = IDirectXFile_AddRef(lpDirectXFile);
103 ok(ref == 2, "Got refcount %d, expected 1\n", ref);
104 ref = IDirectXFile_Release(lpDirectXFile);
105 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
107 hr = IDirectXFile_RegisterTemplates(lpDirectXFile, template, strlen(template));
108 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
110 dxflm.lpMemory = &object;
111 dxflm.dSize = strlen(object);
112 hr = IDirectXFile_CreateEnumObject(lpDirectXFile, &dxflm, DXFILELOAD_FROMMEMORY, &lpdxfeo);
113 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
114 ref = getRefcount( (IUnknown *) lpDirectXFile);
115 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
116 ref = getRefcount( (IUnknown *) lpdxfeo);
117 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
119 hr = IDirectXFileEnumObject_GetNextDataObject(lpdxfeo, &lpdxfd);
120 ok(hr == DXFILE_OK, "IDirectXFileEnumObject_GetNextDataObject: %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);
125 /* Enum object gets references to all top level objects */
126 ref = getRefcount( (IUnknown *) lpdxfd);
127 ok(ref == 2, "Got refcount %d, expected 2\n", ref);
129 ref = IDirectXFile_Release(lpDirectXFile);
130 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
131 /* Nothing changes for all other objects */
132 ref = getRefcount( (IUnknown *) lpdxfeo);
133 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
134 ref = getRefcount( (IUnknown *) lpdxfd);
135 ok(ref == 2, "Got refcount %d, expected 1\n", ref);
137 ref = IDirectXFileEnumObject_Release(lpdxfeo);
138 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
139 /* Enum object releases references to all top level objects */
140 ref = getRefcount( (IUnknown *) lpdxfd);
141 ok(ref == 1, "Got refcount %d, expected 1\n", ref);
143 ref = IDirectXFileData_Release(lpdxfd);
144 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
147 static void test_CreateEnumObject(void)
149 HRESULT hr;
150 ULONG ref;
151 LPDIRECTXFILE lpDirectXFile = NULL;
152 LPDIRECTXFILEENUMOBJECT lpdxfeo;
153 LPDIRECTXFILEDATA lpdxfd;
154 DXFILELOADMEMORY dxflm;
155 BYTE* pdata;
156 DWORD size;
158 if (!pDirectXFileCreate)
160 win_skip("DirectXFileCreate is not available\n");
161 return;
164 hr = pDirectXFileCreate(&lpDirectXFile);
165 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
166 if(!lpDirectXFile)
168 skip("Couldn't create DirectXFile interface\n");
169 return;
172 hr = IDirectXFile_RegisterTemplates(lpDirectXFile, template, strlen(template));
173 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
175 dxflm.lpMemory = &object;
176 dxflm.dSize = strlen(object);
177 /* Check that only lowest 4 bits are relevant in DXFILELOADOPTIONS */
178 hr = IDirectXFile_CreateEnumObject(lpDirectXFile, &dxflm, 0xFFFFFFF0 + DXFILELOAD_FROMMEMORY, &lpdxfeo);
179 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
181 hr = IDirectXFileEnumObject_GetNextDataObject(lpdxfeo, &lpdxfd);
182 ok(hr == DXFILE_OK, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
184 hr = IDirectXFileData_GetData(lpdxfd, NULL, &size, (void**)&pdata);
185 ok(hr == DXFILE_OK, "IDirectXFileData_GetData: %x\n", hr);
187 ok(size == 8, "Retrieved data size is wrong\n");
188 ok((*((WORD*)pdata) == 1) && (*((WORD*)(pdata+2)) == 2) && (*((DWORD*)(pdata+4)) == 3), "Retrieved data is wrong\n");
190 ref = IDirectXFileEnumObject_Release(lpdxfeo);
191 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
193 ref = IDirectXFile_Release(lpDirectXFile);
194 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
196 ref = IDirectXFileData_Release(lpdxfd);
197 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
200 static void test_file_types(void)
202 HRESULT hr;
203 LPDIRECTXFILE dxfile = NULL;
204 LPDIRECTXFILEENUMOBJECT enum_object;
205 DXFILELOADMEMORY lminfo;
207 if (!pDirectXFileCreate)
209 win_skip("DirectXFileCreate is not available\n");
210 return;
213 hr = pDirectXFileCreate(&dxfile);
214 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
215 if (!dxfile)
217 skip("Couldn't create DirectXFile interface\n");
218 return;
221 hr = IDirectXFile_RegisterTemplates(dxfile, empty_txt_file, strlen(empty_txt_file));
222 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
224 hr = IDirectXFile_RegisterTemplates(dxfile, empty_bin_file, strlen(empty_bin_file));
225 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
227 hr = IDirectXFile_RegisterTemplates(dxfile, empty_tzip_file, strlen(empty_tzip_file));
228 ok(hr == DXFILEERR_BADALLOC, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
230 hr = IDirectXFile_RegisterTemplates(dxfile, empty_bzip_file, strlen(empty_bzip_file));
231 ok(hr == DXFILEERR_BADALLOC, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
233 hr = IDirectXFile_RegisterTemplates(dxfile, empty_cmp_file, strlen(empty_cmp_file));
234 ok(hr == DXFILEERR_BADFILETYPE, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
236 hr = IDirectXFile_RegisterTemplates(dxfile, empty_xxxx_file, strlen(empty_xxxx_file));
237 ok(hr == DXFILEERR_BADFILETYPE, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
239 lminfo.lpMemory = empty_txt_file;
240 lminfo.dSize = strlen(empty_txt_file);
241 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
242 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
243 if (hr == DXFILE_OK) IDirectXFileEnumObject_Release(enum_object);
245 lminfo.lpMemory = empty_bin_file;
246 lminfo.dSize = strlen(empty_bin_file);
247 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
248 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
249 if (hr == DXFILE_OK) IDirectXFileEnumObject_Release(enum_object);
251 lminfo.lpMemory = empty_tzip_file;
252 lminfo.dSize = strlen(empty_tzip_file);
253 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
254 ok(hr == DXFILEERR_BADALLOC, "IDirectXFile_CreateEnumObject: %x\n", hr);
256 lminfo.lpMemory = empty_bzip_file;
257 lminfo.dSize = strlen(empty_bzip_file);
258 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
259 ok(hr == DXFILEERR_BADALLOC, "IDirectXFile_CreateEnumObject: %x\n", hr);
261 lminfo.lpMemory = empty_cmp_file;
262 lminfo.dSize = strlen(empty_cmp_file);
263 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
264 ok(hr == DXFILEERR_BADFILETYPE, "IDirectXFile_CreateEnumObject: %x\n", hr);
266 lminfo.lpMemory = empty_xxxx_file;
267 lminfo.dSize = strlen(empty_xxxx_file);
268 hr = IDirectXFile_CreateEnumObject(dxfile, &lminfo, DXFILELOAD_FROMMEMORY, &enum_object);
269 ok(hr == DXFILEERR_BADFILETYPE, "IDirectXFile_CreateEnumObject: %x\n", hr);
271 IDirectXFile_Release(dxfile);
274 /* Set it to 1 to expand the string when dumping the object. This is useful when there is
275 * only one string in a sub-object (very common). Use with care, this may lead to a crash. */
276 #define EXPAND_STRING 0
278 static void process_data(LPDIRECTXFILEDATA lpDirectXFileData, int* plevel)
280 HRESULT hr;
281 char name[100];
282 GUID clsid;
283 CONST GUID* clsid_type = NULL;
284 char str_clsid[40];
285 char str_clsid_type[40];
286 DWORD len= 100;
287 LPDIRECTXFILEOBJECT pChildObj;
288 int i;
289 int j = 0;
290 LPBYTE pData;
291 DWORD k, size;
293 hr = IDirectXFileData_GetId(lpDirectXFileData, &clsid);
294 ok(hr == DXFILE_OK, "IDirectXFileData_GetId: %x\n", hr);
295 hr = IDirectXFileData_GetName(lpDirectXFileData, name, &len);
296 ok(hr == DXFILE_OK, "IDirectXFileData_GetName: %x\n", hr);
297 hr = IDirectXFileData_GetType(lpDirectXFileData, &clsid_type);
298 ok(hr == DXFILE_OK, "IDirectXFileData_GetType: %x\n", hr);
299 hr = IDirectXFileData_GetData(lpDirectXFileData, NULL, &size, (void**)&pData);
300 ok(hr == DXFILE_OK, "IDirectXFileData_GetData: %x\n", hr);
301 for (i = 0; i < *plevel; i++)
302 printf(" ");
303 debugstr_guid(str_clsid, &clsid);
304 debugstr_guid(str_clsid_type, clsid_type);
305 printf("Found object '%s' - %s - %s - %d\n", name, str_clsid, str_clsid_type, size);
307 if (EXPAND_STRING && size == 4)
309 char * str = *(char**)pData;
310 printf("string %s\n", str);
312 else if (size)
314 for (k = 0; k < size; k++)
316 if (k && !(k%16))
317 printf("\n");
318 printf("%02x ", pData[k]);
320 printf("\n");
322 (*plevel)++;
323 while (SUCCEEDED(hr = IDirectXFileData_GetNextObject(lpDirectXFileData, &pChildObj)))
325 LPDIRECTXFILEDATA p1;
326 LPDIRECTXFILEDATAREFERENCE p2;
327 LPDIRECTXFILEBINARY p3;
328 j++;
330 hr = IDirectXFileObject_QueryInterface(pChildObj, &IID_IDirectXFileData, (void **) &p1);
331 if (SUCCEEDED(hr))
333 for (i = 0; i < *plevel; i++)
334 printf(" ");
335 printf("Found Data (%d)\n", j);
336 process_data(p1, plevel);
337 IDirectXFileData_Release(p1);
339 hr = IDirectXFileObject_QueryInterface(pChildObj, &IID_IDirectXFileDataReference, (void **) &p2);
340 if (SUCCEEDED(hr))
342 LPDIRECTXFILEDATA pfdo;
343 for (i = 0; i < *plevel; i++)
344 printf(" ");
345 printf("Found Data Reference (%d)\n", j);
346 #if 0
347 hr = IDirectXFileDataReference_GetId(lpDirectXFileData, &clsid);
348 ok(hr == DXFILE_OK, "IDirectXFileData_GetId: %x\n", hr);
349 hr = IDirectXFileDataReference_GetName(lpDirectXFileData, name, &len);
350 ok(hr == DXFILE_OK, "IDirectXFileData_GetName: %x\n", hr);
351 #endif
352 IDirectXFileDataReference_Resolve(p2, &pfdo);
353 process_data(pfdo, plevel);
354 IDirectXFileData_Release(pfdo);
355 IDirectXFileDataReference_Release(p2);
357 hr = IDirectXFileObject_QueryInterface(pChildObj, &IID_IDirectXFileBinary, (void **) &p3);
358 if (SUCCEEDED(hr))
360 for (i = 0; i < *plevel; i++)
361 printf(" ");
362 printf("Found Binary (%d)\n", j);
363 IDirectXFileBinary_Release(p3);
366 (*plevel)--;
367 ok(hr == DXFILE_OK || hr == DXFILEERR_NOMOREOBJECTS, "IDirectXFileData_GetNextObject: %x\n", hr);
370 static void test_dump(void)
372 HRESULT hr;
373 ULONG ref;
374 LPDIRECTXFILE lpDirectXFile = NULL;
375 LPDIRECTXFILEENUMOBJECT lpDirectXFileEnumObject = NULL;
376 LPDIRECTXFILEDATA lpDirectXFileData = NULL;
377 HANDLE hFile;
378 LPVOID pvData = NULL;
379 DWORD cbSize;
381 if (!pDirectXFileCreate)
383 win_skip("DirectXFileCreate is not available\n");
384 goto exit;
387 /* Dump data only if there is an object and a template */
388 hFile = CreateFileA("objects.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
389 if (hFile == INVALID_HANDLE_VALUE)
390 return;
391 CloseHandle(hFile);
393 hFile = CreateFileA("templates.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
394 if (hFile == INVALID_HANDLE_VALUE)
395 return;
397 pvData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 10000);
399 if (!ReadFile(hFile, pvData, 10000, &cbSize, NULL))
401 skip("Template file is too big\n");
402 goto exit;
405 printf("Load %d bytes\n", cbSize);
407 hr = pDirectXFileCreate(&lpDirectXFile);
408 ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
409 if(!lpDirectXFile)
411 skip("Couldn't create DirectXFile interface\n");
412 goto exit;
415 hr = IDirectXFile_RegisterTemplates(lpDirectXFile, pvData, strlen(pvData));
416 ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
418 hr = IDirectXFile_CreateEnumObject(lpDirectXFile, (LPVOID)"objects.txt", DXFILELOAD_FROMFILE, &lpDirectXFileEnumObject);
419 ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
421 while (SUCCEEDED(hr = IDirectXFileEnumObject_GetNextDataObject(lpDirectXFileEnumObject, &lpDirectXFileData)))
423 int level = 0;
424 printf("\n");
425 process_data(lpDirectXFileData, &level);
426 IDirectXFileData_Release(lpDirectXFileData);
428 ok(hr == DXFILE_OK || hr == DXFILEERR_NOMOREOBJECTS, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
430 ref = IDirectXFile_Release(lpDirectXFileEnumObject);
431 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
433 ref = IDirectXFile_Release(lpDirectXFile);
434 ok(ref == 0, "Got refcount %d, expected 0\n", ref);
436 CloseHandle(hFile);
438 exit:
439 HeapFree(GetProcessHeap(), 0, pvData);
442 START_TEST(d3dxof)
444 init_function_pointers();
446 test_refcount();
447 test_CreateEnumObject();
448 test_file_types();
449 test_dump();
451 FreeLibrary(hd3dxof);