wined3d: Use a lookup table in select_card_ati_binary().
[wine] / dlls / d3dxof / tests / d3dxof.c
1 /*
2  * Some unit tests for d3dxof
3  *
4  * Copyright (C) 2008 Christian Costa
5  *
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.
10  *
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.
15  *
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
19  */
20 #define COBJMACROS
21
22 #include <assert.h>
23 #include <stdio.h>
24 #include "wine/test.h"
25 #include "initguid.h"
26 #include "dxfile.h"
27
28 static inline void debugstr_guid( char* buf, CONST GUID *id )
29 {
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] );
34 }
35
36 static HMODULE hd3dxof;
37 static HRESULT (WINAPI *pDirectXFileCreate)(LPDIRECTXFILE*);
38
39 static 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";
48
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";
58
59 static char object[] =
60 "xof 0302txt 0064\n"
61 "Header Object\n"
62 "{\n"
63 "1; 2; 3;\n"
64 "}\n";
65
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";
71
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";
85
86 static void init_function_pointers(void)
87 {
88     /* We have to use LoadLibrary as no d3dxof functions are referenced directly */
89     hd3dxof = LoadLibraryA("d3dxof.dll");
90
91     pDirectXFileCreate = (void *)GetProcAddress(hd3dxof, "DirectXFileCreate");
92 }
93
94 static ULONG getRefcount(IUnknown *iface)
95 {
96     IUnknown_AddRef(iface);
97     return IUnknown_Release(iface);
98 }
99
100 static void test_refcount(void)
101 {
102     HRESULT hr;
103     ULONG ref;
104     LPDIRECTXFILE lpDirectXFile = NULL;
105     LPDIRECTXFILEENUMOBJECT lpdxfeo;
106     LPDIRECTXFILEDATA lpdxfd;
107     DXFILELOADMEMORY dxflm;
108
109     if (!pDirectXFileCreate)
110     {
111         win_skip("DirectXFileCreate is not available\n");
112         return;
113     }
114
115     hr = pDirectXFileCreate(&lpDirectXFile);
116     ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
117     if(!lpDirectXFile)
118     {
119         skip("Couldn't create DirectXFile interface\n");
120         return;
121     }
122
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);
129
130     hr = IDirectXFile_RegisterTemplates(lpDirectXFile, template, sizeof(template) - 1);
131     ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
132
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);
141
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);
151
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);
159
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);
165
166     ref = IDirectXFileData_Release(lpdxfd);
167     ok(ref == 0, "Got refcount %d, expected 0\n", ref);
168 }
169
170 static void test_CreateEnumObject(void)
171 {
172     HRESULT hr;
173     ULONG ref;
174     LPDIRECTXFILE lpDirectXFile = NULL;
175     LPDIRECTXFILEENUMOBJECT lpdxfeo;
176     LPDIRECTXFILEDATA lpdxfd;
177     DXFILELOADMEMORY dxflm;
178     BYTE* pdata;
179     DWORD size;
180
181     if (!pDirectXFileCreate)
182     {
183         win_skip("DirectXFileCreate is not available\n");
184         return;
185     }
186
187     hr = pDirectXFileCreate(&lpDirectXFile);
188     ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
189     if(!lpDirectXFile)
190     {
191         skip("Couldn't create DirectXFile interface\n");
192         return;
193     }
194
195     hr = IDirectXFile_RegisterTemplates(lpDirectXFile, template, sizeof(template) - 1);
196     ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
197
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);
203
204     hr = IDirectXFileEnumObject_GetNextDataObject(lpdxfeo, &lpdxfd);
205     ok(hr == DXFILE_OK, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
206
207     hr = IDirectXFileData_GetData(lpdxfd, NULL, &size, (void**)&pdata);
208     ok(hr == DXFILE_OK, "IDirectXFileData_GetData: %x\n", hr);
209
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");
212
213     ref = IDirectXFileEnumObject_Release(lpdxfeo);
214     ok(ref == 0, "Got refcount %d, expected 0\n", ref);
215
216     ref = IDirectXFile_Release(lpDirectXFile);
217     ok(ref == 0, "Got refcount %d, expected 0\n", ref);
218
219     ref = IDirectXFileData_Release(lpdxfd);
220     ok(ref == 0, "Got refcount %d, expected 0\n", ref);
221 }
222
223 static void test_file_types(void)
224 {
225     HRESULT hr;
226     LPDIRECTXFILE dxfile = NULL;
227     LPDIRECTXFILEENUMOBJECT enum_object;
228     DXFILELOADMEMORY lminfo;
229
230     if (!pDirectXFileCreate)
231     {
232         win_skip("DirectXFileCreate is not available\n");
233         return;
234     }
235
236     hr = pDirectXFileCreate(&dxfile);
237     ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
238     if (!dxfile)
239     {
240         skip("Couldn't create DirectXFile interface\n");
241         return;
242     }
243
244     hr = IDirectXFile_RegisterTemplates(dxfile, empty_txt_file, sizeof(empty_txt_file) - 1);
245     ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
246
247     hr = IDirectXFile_RegisterTemplates(dxfile, empty_bin_file, sizeof(empty_bin_file) - 1);
248     ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
249
250     hr = IDirectXFile_RegisterTemplates(dxfile, empty_tzip_file, sizeof(empty_tzip_file) - 1);
251     ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
252
253     hr = IDirectXFile_RegisterTemplates(dxfile, empty_bzip_file, sizeof(empty_bzip_file) - 1);
254     ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
255
256     hr = IDirectXFile_RegisterTemplates(dxfile, empty_cmp_file, sizeof(empty_cmp_file) - 1);
257     ok(hr == DXFILEERR_BADFILETYPE, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
258
259     hr = IDirectXFile_RegisterTemplates(dxfile, empty_xxxx_file, sizeof(empty_xxxx_file) - 1);
260     ok(hr == DXFILEERR_BADFILETYPE, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
261
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);
267
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);
273
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);
279
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);
285
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);
290
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);
295
296     IDirectXFile_Release(dxfile);
297 }
298
299 static void test_compressed_files(void)
300 {
301     HRESULT hr;
302     LPDIRECTXFILE dxfile = NULL;
303     LPDIRECTXFILEENUMOBJECT enum_object;
304     LPDIRECTXFILEDATA file_data;
305     DXFILELOADMEMORY lminfo;
306     BYTE* data;
307     DWORD size;
308
309     if (!pDirectXFileCreate)
310     {
311         win_skip("DirectXFileCreate is not available\n");
312         return;
313     }
314
315     hr = pDirectXFileCreate(&dxfile);
316     ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
317     if (!dxfile)
318     {
319         skip("Couldn't create DirectXFile interface\n");
320         return;
321     }
322
323     hr = IDirectXFile_RegisterTemplates(dxfile, compressed_template, sizeof(compressed_template) - 1);
324     ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
325
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);
330
331     hr = IDirectXFileEnumObject_GetNextDataObject(enum_object, &file_data);
332     ok(hr == DXFILE_OK, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
333
334     hr = IDirectXFileData_GetData(file_data, NULL, &size, (void**)&data);
335     ok(hr == DXFILE_OK, "IDirectXFileData_GetData: %x\n", hr);
336
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");
339
340     IDirectXFileData_Release(file_data);
341     IDirectXFileEnumObject_Release(enum_object);
342     IDirectXFile_Release(dxfile);
343 }
344
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
348
349 static void process_data(LPDIRECTXFILEDATA lpDirectXFileData, int* plevel)
350 {
351     HRESULT hr;
352     char name[100];
353     GUID clsid;
354     CONST GUID* clsid_type = NULL;
355     char str_clsid[40];
356     char str_clsid_type[40];
357     DWORD len= 100;
358     LPDIRECTXFILEOBJECT pChildObj;
359     int i;
360     int j = 0;
361     LPBYTE pData;
362     DWORD k, size;
363
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++)
373         printf("  ");
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);
377
378     if (EXPAND_STRING && size == 4)
379     {
380         char * str = *(char**)pData;
381         printf("string %s\n", str);
382     }
383     else if (size)
384     {
385         for (k = 0; k < size; k++)
386         {
387             if (k && !(k%16))
388                 printf("\n");
389             printf("%02x ", pData[k]);
390         }
391         printf("\n");
392     }
393     (*plevel)++;
394     while (SUCCEEDED(hr = IDirectXFileData_GetNextObject(lpDirectXFileData, &pChildObj)))
395     {
396         LPDIRECTXFILEDATA p1;
397         LPDIRECTXFILEDATAREFERENCE p2;
398         LPDIRECTXFILEBINARY p3;
399         j++;
400
401         hr = IDirectXFileObject_QueryInterface(pChildObj, &IID_IDirectXFileData, (void **) &p1);
402         if (SUCCEEDED(hr))
403         {
404             for (i = 0; i < *plevel; i++)
405                 printf("  ");
406             printf("Found Data (%d)\n", j);
407             process_data(p1, plevel);
408             IDirectXFileData_Release(p1);
409         }
410         hr = IDirectXFileObject_QueryInterface(pChildObj, &IID_IDirectXFileDataReference, (void **) &p2);
411         if (SUCCEEDED(hr))
412         {
413             LPDIRECTXFILEDATA pfdo;
414             for (i = 0; i < *plevel; i++)
415                 printf("  ");
416             printf("Found Data Reference (%d)\n", j);
417 #if 0
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);
422 #endif
423             IDirectXFileDataReference_Resolve(p2, &pfdo);
424             process_data(pfdo, plevel);
425             IDirectXFileData_Release(pfdo);
426             IDirectXFileDataReference_Release(p2);
427         }
428         hr = IDirectXFileObject_QueryInterface(pChildObj, &IID_IDirectXFileBinary, (void **) &p3);
429         if (SUCCEEDED(hr))
430         {
431             for (i = 0; i < *plevel; i++)
432                 printf("  ");
433             printf("Found Binary (%d)\n", j);
434             IDirectXFileBinary_Release(p3);
435         }
436     }
437     (*plevel)--;
438     ok(hr == DXFILE_OK || hr == DXFILEERR_NOMOREOBJECTS, "IDirectXFileData_GetNextObject: %x\n", hr);
439 }
440
441 static void test_dump(void)
442 {
443     HRESULT hr;
444     ULONG ref;
445     LPDIRECTXFILE lpDirectXFile = NULL;
446     LPDIRECTXFILEENUMOBJECT lpDirectXFileEnumObject = NULL;
447     LPDIRECTXFILEDATA lpDirectXFileData = NULL;
448     HANDLE hFile;
449     LPVOID pvData = NULL;
450     DWORD cbSize;
451
452     if (!pDirectXFileCreate)
453     {
454         win_skip("DirectXFileCreate is not available\n");
455         goto exit;
456     }
457
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)
461       return;
462     CloseHandle(hFile);
463
464     hFile = CreateFileA("templates.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
465     if (hFile == INVALID_HANDLE_VALUE)
466       return;
467
468     pvData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 10000);
469
470     if (!ReadFile(hFile, pvData, 10000, &cbSize, NULL))
471     {
472       skip("Template file is too big\n");
473       goto exit;
474     }
475
476     printf("Load %d bytes\n", cbSize);
477
478     hr = pDirectXFileCreate(&lpDirectXFile);
479     ok(hr == DXFILE_OK, "DirectXFileCreate: %x\n", hr);
480     if(!lpDirectXFile)
481     {
482         skip("Couldn't create DirectXFile interface\n");
483         goto exit;
484     }
485
486     hr = IDirectXFile_RegisterTemplates(lpDirectXFile, pvData, cbSize);
487     ok(hr == DXFILE_OK, "IDirectXFileImpl_RegisterTemplates: %x\n", hr);
488
489     hr = IDirectXFile_CreateEnumObject(lpDirectXFile, (LPVOID)"objects.txt", DXFILELOAD_FROMFILE, &lpDirectXFileEnumObject);
490     ok(hr == DXFILE_OK, "IDirectXFile_CreateEnumObject: %x\n", hr);
491
492     while (SUCCEEDED(hr = IDirectXFileEnumObject_GetNextDataObject(lpDirectXFileEnumObject, &lpDirectXFileData)))
493     {
494         int level = 0;
495         printf("\n");
496         process_data(lpDirectXFileData, &level);
497         IDirectXFileData_Release(lpDirectXFileData);
498     }
499     ok(hr == DXFILE_OK || hr == DXFILEERR_NOMOREOBJECTS, "IDirectXFileEnumObject_GetNextDataObject: %x\n", hr);
500
501     ref = IDirectXFile_Release(lpDirectXFileEnumObject);
502     ok(ref == 0, "Got refcount %d, expected 0\n", ref);
503
504     ref = IDirectXFile_Release(lpDirectXFile);
505     ok(ref == 0, "Got refcount %d, expected 0\n", ref);
506
507     CloseHandle(hFile);
508
509 exit:
510     HeapFree(GetProcessHeap(), 0, pvData);
511 }
512
513 START_TEST(d3dxof)
514 {
515     init_function_pointers();
516
517     test_refcount();
518     test_CreateEnumObject();
519     test_file_types();
520     test_compressed_files();
521     test_dump();
522
523     FreeLibrary(hd3dxof);
524 }