mshtml: Added IHTMLStyleSheet::get_rules implementation.
[wine] / dlls / cabinet / tests / fdi.c
1 /*
2  * Unit tests for the File Decompression Interface
3  *
4  * Copyright (C) 2006 James Hawkins
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
21 #include <stdio.h>
22 #include <windows.h>
23 #include "fci.h"
24 #include "fdi.h"
25 #include "wine/test.h"
26
27 /* make the max size large so there is only one cab file */
28 #define MEDIA_SIZE          999999999
29 #define FOLDER_THRESHOLD    900000
30
31 CHAR CURR_DIR[MAX_PATH];
32
33 /* FDI callbacks */
34
35 static void *fdi_alloc(ULONG cb)
36 {
37     return HeapAlloc(GetProcessHeap(), 0, cb);
38 }
39
40 static void *fdi_alloc_bad(ULONG cb)
41 {
42     return NULL;
43 }
44
45 static void fdi_free(void *pv)
46 {
47     HeapFree(GetProcessHeap(), 0, pv);
48 }
49
50 static INT_PTR fdi_open(char *pszFile, int oflag, int pmode)
51 {
52     HANDLE handle;
53     handle = CreateFileA(pszFile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
54                           OPEN_EXISTING, 0, NULL );
55     if (handle == INVALID_HANDLE_VALUE)
56         return 0;
57     return (INT_PTR) handle;
58 }
59
60 static UINT fdi_read(INT_PTR hf, void *pv, UINT cb)
61 {
62     HANDLE handle = (HANDLE) hf;
63     DWORD dwRead;
64     if (ReadFile(handle, pv, cb, &dwRead, NULL))
65         return dwRead;
66     return 0;
67 }
68
69 static UINT fdi_write(INT_PTR hf, void *pv, UINT cb)
70 {
71     HANDLE handle = (HANDLE) hf;
72     DWORD dwWritten;
73     if (WriteFile(handle, pv, cb, &dwWritten, NULL))
74         return dwWritten;
75     return 0;
76 }
77
78 static int fdi_close(INT_PTR hf)
79 {
80     HANDLE handle = (HANDLE) hf;
81     return CloseHandle(handle) ? 0 : -1;
82 }
83
84 static long fdi_seek(INT_PTR hf, long dist, int seektype)
85 {
86     HANDLE handle = (HANDLE) hf;
87     return SetFilePointer(handle, dist, NULL, seektype);
88 }
89
90 static void test_FDICreate(void)
91 {
92     HFDI hfdi;
93     ERF erf;
94
95     erf.erfOper = 0xcafefeed;
96     erf.erfType = 0xdeadbabe;
97     erf.fError = 0xdecaface;
98
99     /* native crashes if pfnalloc is NULL */
100
101     /* FDICreate does not crash with a NULL pfnfree,
102      * but FDIDestroy will crash when it tries to access it.
103      */
104     if (0)
105     {
106         SetLastError(0xdeadbeef);
107         hfdi = FDICreate(fdi_alloc, NULL, fdi_open, fdi_read,
108                          fdi_write, fdi_close, fdi_seek,
109                          cpuUNKNOWN, &erf);
110         ok(hfdi != NULL, "Expected non-NULL context\n");
111         ok(GetLastError() == 0xdeadbeef,
112            "Expected 0xdeadbeef, got %d\n", GetLastError());
113         ok(erf.erfOper == 0xcafefeed, "Expected 0xcafefeed, got %d\n", erf.erfOper);
114         ok(erf.erfType == 0xdeadbabe, "Expected 0xdeadbabe, got %d\n", erf.erfType);
115         ok(erf.fError == 0xdecaface, "Expected 0xdecaface, got %d\n", erf.fError);
116
117         FDIDestroy(hfdi);
118     }
119
120     SetLastError(0xdeadbeef);
121     hfdi = FDICreate(fdi_alloc, fdi_free, NULL, fdi_read,
122                      fdi_write, fdi_close, fdi_seek,
123                      cpuUNKNOWN, &erf);
124     ok(hfdi != NULL, "Expected non-NULL context\n");
125     ok(GetLastError() == 0xdeadbeef,
126        "Expected 0xdeadbeef, got %d\n", GetLastError());
127     ok(erf.erfOper == 0xcafefeed, "Expected 0xcafefeed, got %d\n", erf.erfOper);
128     ok(erf.erfType == 0xdeadbabe, "Expected 0xdeadbabe, got %d\n", erf.erfType);
129     ok(erf.fError == 0xdecaface, "Expected 0xdecaface, got %d\n", erf.fError);
130
131     FDIDestroy(hfdi);
132
133     SetLastError(0xdeadbeef);
134     hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, NULL,
135                      fdi_write, fdi_close, fdi_seek,
136                      cpuUNKNOWN, &erf);
137     ok(hfdi != NULL, "Expected non-NULL context\n");
138     ok(GetLastError() == 0xdeadbeef,
139        "Expected 0xdeadbeef, got %d\n", GetLastError());
140     ok(erf.erfOper == 0xcafefeed, "Expected 0xcafefeed, got %d\n", erf.erfOper);
141     ok(erf.erfType == 0xdeadbabe, "Expected 0xdeadbabe, got %d\n", erf.erfType);
142     ok(erf.fError == 0xdecaface, "Expected 0xdecaface, got %d\n", erf.fError);
143
144     FDIDestroy(hfdi);
145
146     SetLastError(0xdeadbeef);
147     hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read,
148                      NULL, fdi_close, fdi_seek,
149                      cpuUNKNOWN, &erf);
150     ok(hfdi != NULL, "Expected non-NULL context\n");
151     ok(GetLastError() == 0xdeadbeef,
152        "Expected 0xdeadbeef, got %d\n", GetLastError());
153     ok(erf.erfOper == 0xcafefeed, "Expected 0xcafefeed, got %d\n", erf.erfOper);
154     ok(erf.erfType == 0xdeadbabe, "Expected 0xdeadbabe, got %d\n", erf.erfType);
155     ok(erf.fError == 0xdecaface, "Expected 0xdecaface, got %d\n", erf.fError);
156
157     FDIDestroy(hfdi);
158
159     SetLastError(0xdeadbeef);
160     hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read,
161                      fdi_write, NULL, fdi_seek,
162                      cpuUNKNOWN, &erf);
163     ok(hfdi != NULL, "Expected non-NULL context\n");
164     ok(GetLastError() == 0xdeadbeef,
165        "Expected 0xdeadbeef, got %d\n", GetLastError());
166     ok(erf.erfOper == 0xcafefeed, "Expected 0xcafefeed, got %d\n", erf.erfOper);
167     ok(erf.erfType == 0xdeadbabe, "Expected 0xdeadbabe, got %d\n", erf.erfType);
168     ok(erf.fError == 0xdecaface, "Expected 0xdecaface, got %d\n", erf.fError);
169
170     FDIDestroy(hfdi);
171
172     SetLastError(0xdeadbeef);
173     hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read,
174                      fdi_write, fdi_close, NULL,
175                      cpuUNKNOWN, &erf);
176     ok(hfdi != NULL, "Expected non-NULL context\n");
177     ok(GetLastError() == 0xdeadbeef,
178        "Expected 0xdeadbeef, got %d\n", GetLastError());
179     ok(erf.erfOper == 0xcafefeed, "Expected 0xcafefeed, got %d\n", erf.erfOper);
180     ok(erf.erfType == 0xdeadbabe, "Expected 0xdeadbabe, got %d\n", erf.erfType);
181     ok(erf.fError == 0xdecaface, "Expected 0xdecaface, got %d\n", erf.fError);
182
183     FDIDestroy(hfdi);
184
185     SetLastError(0xdeadbeef);
186     hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read,
187                      fdi_write, fdi_close, fdi_seek,
188                      cpuUNKNOWN, NULL);
189     ok(hfdi != NULL, "Expected non-NULL context\n");
190     ok(GetLastError() == 0xdeadbeef,
191        "Expected 0xdeadbeef, got %d\n", GetLastError());
192     ok(erf.erfOper == 0xcafefeed, "Expected 0xcafefeed, got %d\n", erf.erfOper);
193     ok(erf.erfType == 0xdeadbabe, "Expected 0xdeadbabe, got %d\n", erf.erfType);
194     ok(erf.fError == 0xdecaface, "Expected 0xdecaface, got %d\n", erf.fError);
195
196     FDIDestroy(hfdi);
197
198     /* bad cpu type */
199     SetLastError(0xdeadbeef);
200     hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read,
201                      fdi_write, fdi_close, fdi_seek,
202                      0xcafebabe, &erf);
203     ok(hfdi != NULL, "Expected non-NULL context\n");
204     ok(GetLastError() == 0xdeadbeef,
205        "Expected 0xdeadbeef, got %d\n", GetLastError());
206     ok(erf.erfOper == 0xcafefeed, "Expected 0xcafefeed, got %d\n", erf.erfOper);
207     ok(erf.erfType == 0xdeadbabe, "Expected 0xdeadbabe, got %d\n", erf.erfType);
208     ok(erf.fError == 0xdecaface, "Expected 0xdecaface, got %d\n", erf.fError);
209
210     FDIDestroy(hfdi);
211
212     /* pfnalloc fails */
213     SetLastError(0xdeadbeef);
214     hfdi = FDICreate(fdi_alloc_bad, fdi_free, fdi_open, fdi_read,
215                      fdi_write, fdi_close, fdi_seek,
216                      cpuUNKNOWN, &erf);
217     ok(hfdi == NULL, "Expected NULL context, got %p\n", hfdi);
218     ok(erf.erfOper == FDIERROR_ALLOC_FAIL,
219        "Expected FDIERROR_ALLOC_FAIL, got %d\n", erf.erfOper);
220     ok(erf.fError == TRUE, "Expected TRUE, got %d\n", erf.fError);
221     todo_wine
222     {
223         ok(GetLastError() == 0xdeadbeef,
224            "Expected 0xdeadbeef, got %d\n", GetLastError());
225         ok(erf.erfType == 0, "Expected 0, got %d\n", erf.erfType);
226     }
227 }
228
229 static void test_FDIDestroy(void)
230 {
231     HFDI hfdi;
232     ERF erf;
233     BOOL ret;
234
235     /* native crashes if hfdi is NULL or invalid */
236
237     hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read,
238                      fdi_write, fdi_close, fdi_seek,
239                      cpuUNKNOWN, &erf);
240     ok(hfdi != NULL, "Expected non-NULL context\n");
241
242     /* successfully destroy hfdi */
243     ret = FDIDestroy(hfdi);
244     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
245
246     /* native crashes if you try to destroy hfdi twice */
247     if (0)
248     {
249         /* try to destroy hfdi again */
250         ret = FDIDestroy(hfdi);
251         ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
252     }
253 }
254
255 static void createTestFile(const CHAR *name)
256 {
257     HANDLE file;
258     DWORD written;
259
260     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
261     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
262     WriteFile(file, name, strlen(name), &written, NULL);
263     WriteFile(file, "\n", strlen("\n"), &written, NULL);
264     CloseHandle(file);
265 }
266
267 static void create_test_files(void)
268 {
269     int len;
270
271     GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
272     len = lstrlenA(CURR_DIR);
273
274     if(len && (CURR_DIR[len-1] == '\\'))
275         CURR_DIR[len-1] = 0;
276
277     createTestFile("a.txt");
278     createTestFile("b.txt");
279     CreateDirectoryA("testdir", NULL);
280     createTestFile("testdir\\c.txt");
281     createTestFile("testdir\\d.txt");
282 }
283
284 static void delete_test_files(void)
285 {
286     DeleteFileA("a.txt");
287     DeleteFileA("b.txt");
288     DeleteFileA("testdir\\c.txt");
289     DeleteFileA("testdir\\d.txt");
290     RemoveDirectoryA("testdir");
291
292     DeleteFileA("extract.cab");
293 }
294
295 /* FCI callbacks */
296
297 static void *mem_alloc(ULONG cb)
298 {
299     return HeapAlloc(GetProcessHeap(), 0, cb);
300 }
301
302 static void mem_free(void *memory)
303 {
304     HeapFree(GetProcessHeap(), 0, memory);
305 }
306
307 static BOOL get_next_cabinet(PCCAB pccab, ULONG  cbPrevCab, void *pv)
308 {
309     return TRUE;
310 }
311
312 static long progress(UINT typeStatus, ULONG cb1, ULONG cb2, void *pv)
313 {
314     return 0;
315 }
316
317 static int file_placed(PCCAB pccab, char *pszFile, long cbFile,
318                        BOOL fContinuation, void *pv)
319 {
320     return 0;
321 }
322
323 static INT_PTR fci_open(char *pszFile, int oflag, int pmode, int *err, void *pv)
324 {
325     HANDLE handle;
326     DWORD dwAccess = 0;
327     DWORD dwShareMode = 0;
328     DWORD dwCreateDisposition = OPEN_EXISTING;
329
330     dwAccess = GENERIC_READ | GENERIC_WRITE;
331     /* FILE_SHARE_DELETE is not supported by Windows Me/98/95 */
332     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
333
334     if (GetFileAttributesA(pszFile) != INVALID_FILE_ATTRIBUTES)
335         dwCreateDisposition = OPEN_EXISTING;
336     else
337         dwCreateDisposition = CREATE_NEW;
338
339     handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
340                          dwCreateDisposition, 0, NULL);
341
342     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszFile);
343
344     return (INT_PTR)handle;
345 }
346
347 static UINT fci_read(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
348 {
349     HANDLE handle = (HANDLE)hf;
350     DWORD dwRead;
351     BOOL res;
352
353     res = ReadFile(handle, memory, cb, &dwRead, NULL);
354     ok(res, "Failed to ReadFile\n");
355
356     return dwRead;
357 }
358
359 static UINT fci_write(INT_PTR hf, void *memory, UINT cb, int *err, void *pv)
360 {
361     HANDLE handle = (HANDLE)hf;
362     DWORD dwWritten;
363     BOOL res;
364
365     res = WriteFile(handle, memory, cb, &dwWritten, NULL);
366     ok(res, "Failed to WriteFile\n");
367
368     return dwWritten;
369 }
370
371 static int fci_close(INT_PTR hf, int *err, void *pv)
372 {
373     HANDLE handle = (HANDLE)hf;
374     ok(CloseHandle(handle), "Failed to CloseHandle\n");
375
376     return 0;
377 }
378
379 static long fci_seek(INT_PTR hf, long dist, int seektype, int *err, void *pv)
380 {
381     HANDLE handle = (HANDLE)hf;
382     DWORD ret;
383
384     ret = SetFilePointer(handle, dist, NULL, seektype);
385     ok(ret != INVALID_SET_FILE_POINTER, "Failed to SetFilePointer\n");
386
387     return ret;
388 }
389
390 static int fci_delete(char *pszFile, int *err, void *pv)
391 {
392     BOOL ret = DeleteFileA(pszFile);
393     ok(ret, "Failed to DeleteFile %s\n", pszFile);
394
395     return 0;
396 }
397
398 static BOOL get_temp_file(char *pszTempName, int cbTempName, void *pv)
399 {
400     LPSTR tempname;
401
402     tempname = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
403     GetTempFileNameA(".", "xx", 0, tempname);
404
405     if (tempname && (strlen(tempname) < (unsigned)cbTempName))
406     {
407         lstrcpyA(pszTempName, tempname);
408         HeapFree(GetProcessHeap(), 0, tempname);
409         return TRUE;
410     }
411
412     HeapFree(GetProcessHeap(), 0, tempname);
413
414     return FALSE;
415 }
416
417 static INT_PTR get_open_info(char *pszName, USHORT *pdate, USHORT *ptime,
418                              USHORT *pattribs, int *err, void *pv)
419 {
420     BY_HANDLE_FILE_INFORMATION finfo;
421     FILETIME filetime;
422     HANDLE handle;
423     DWORD attrs;
424     BOOL res;
425
426     handle = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL,
427                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
428
429     ok(handle != INVALID_HANDLE_VALUE, "Failed to CreateFile %s\n", pszName);
430
431     res = GetFileInformationByHandle(handle, &finfo);
432     ok(res, "Expected GetFileInformationByHandle to succeed\n");
433
434     FileTimeToLocalFileTime(&finfo.ftLastWriteTime, &filetime);
435     FileTimeToDosDateTime(&filetime, pdate, ptime);
436
437     attrs = GetFileAttributes(pszName);
438     ok(attrs != INVALID_FILE_ATTRIBUTES, "Failed to GetFileAttributes\n");
439     /* fixme: should convert attrs to *pattribs, make sure
440      * have a test that catches the fact that we don't?
441      */
442
443     return (INT_PTR)handle;
444 }
445
446 static void add_file(HFCI hfci, char *file)
447 {
448     char path[MAX_PATH];
449     BOOL res;
450
451     lstrcpyA(path, CURR_DIR);
452     lstrcatA(path, "\\");
453     lstrcatA(path, file);
454
455     res = FCIAddFile(hfci, path, file, FALSE, get_next_cabinet, progress,
456                      get_open_info, tcompTYPE_MSZIP);
457     ok(res, "Expected FCIAddFile to succeed\n");
458 }
459
460 static void set_cab_parameters(PCCAB pCabParams)
461 {
462     ZeroMemory(pCabParams, sizeof(CCAB));
463
464     pCabParams->cb = MEDIA_SIZE;
465     pCabParams->cbFolderThresh = FOLDER_THRESHOLD;
466     pCabParams->setID = 0xbeef;
467     lstrcpyA(pCabParams->szCabPath, CURR_DIR);
468     lstrcatA(pCabParams->szCabPath, "\\");
469     lstrcpyA(pCabParams->szCab, "extract.cab");
470 }
471
472 static void create_cab_file(void)
473 {
474     CCAB cabParams;
475     HFCI hfci;
476     ERF erf;
477     static CHAR a_txt[]         = "a.txt",
478                 b_txt[]         = "b.txt",
479                 testdir_c_txt[] = "testdir\\c.txt",
480                 testdir_d_txt[] = "testdir\\d.txt";
481     BOOL res;
482
483     set_cab_parameters(&cabParams);
484
485     hfci = FCICreate(&erf, file_placed, mem_alloc, mem_free, fci_open,
486                       fci_read, fci_write, fci_close, fci_seek, fci_delete,
487                       get_temp_file, &cabParams, NULL);
488
489     ok(hfci != NULL, "Failed to create an FCI context\n");
490
491     add_file(hfci, a_txt);
492     add_file(hfci, b_txt);
493     add_file(hfci, testdir_c_txt);
494     add_file(hfci, testdir_d_txt);
495
496     res = FCIFlushCabinet(hfci, FALSE, get_next_cabinet, progress);
497     ok(res, "Failed to flush the cabinet\n");
498
499     res = FCIDestroy(hfci);
500     ok(res, "Failed to destroy the cabinet\n");
501 }
502
503 static void test_FDIIsCabinet(void)
504 {
505     ERF erf;
506     BOOL ret;
507     HFDI hfdi;
508     INT_PTR fd;
509     FDICABINETINFO cabinfo;
510     char temp[] = "temp.txt";
511     char extract[] = "extract.cab";
512
513     create_test_files();
514     create_cab_file();
515
516     hfdi = FDICreate(fdi_alloc, fdi_free, fdi_open, fdi_read,
517                      fdi_write, fdi_close, fdi_seek,
518                      cpuUNKNOWN, &erf);
519     ok(hfdi != NULL, "Expected non-NULL context\n");
520
521     /* native crashes if hfdi or cabinfo are NULL or invalid */
522
523     /* invalid file handle */
524     ZeroMemory(&cabinfo, sizeof(FDICABINETINFO));
525     SetLastError(0xdeadbeef);
526     ret = FDIIsCabinet(hfdi, (int)INVALID_HANDLE_VALUE, &cabinfo);
527     ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
528     ok(GetLastError() == ERROR_INVALID_HANDLE,
529        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
530     ok(cabinfo.cbCabinet == 0, "Expected 0, got %ld\n", cabinfo.cbCabinet);
531     ok(cabinfo.cFiles == 0, "Expected 0, got %d\n", cabinfo.cFiles);
532     ok(cabinfo.cFolders == 0, "Expected 0, got %d\n", cabinfo.cFolders);
533     ok(cabinfo.iCabinet == 0, "Expected 0, got %d\n", cabinfo.iCabinet);
534     ok(cabinfo.setID == 0, "Expected 0, got %d\n", cabinfo.setID);
535
536     createTestFile("temp.txt");
537     fd = fdi_open(temp, 0, 0);
538
539     /* file handle doesn't point to a cabinet */
540     ZeroMemory(&cabinfo, sizeof(FDICABINETINFO));
541     SetLastError(0xdeadbeef);
542     ret = FDIIsCabinet(hfdi, fd, &cabinfo);
543     ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
544     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
545     ok(cabinfo.cbCabinet == 0, "Expected 0, got %ld\n", cabinfo.cbCabinet);
546     ok(cabinfo.cFiles == 0, "Expected 0, got %d\n", cabinfo.cFiles);
547     ok(cabinfo.cFolders == 0, "Expected 0, got %d\n", cabinfo.cFolders);
548     ok(cabinfo.iCabinet == 0, "Expected 0, got %d\n", cabinfo.iCabinet);
549     ok(cabinfo.setID == 0, "Expected 0, got %d\n", cabinfo.setID);
550
551     fdi_close(fd);
552     DeleteFileA("temp.txt");
553
554     /* try a real cab */
555     fd = fdi_open(extract, 0, 0);
556     ZeroMemory(&cabinfo, sizeof(FDICABINETINFO));
557     SetLastError(0xdeadbeef);
558     ret = FDIIsCabinet(hfdi, fd, &cabinfo);
559     ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
560     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
561     ok(cabinfo.cFiles == 4, "Expected 4, got %d\n", cabinfo.cFiles);
562     ok(cabinfo.cFolders == 1, "Expected 1, got %d\n", cabinfo.cFolders);
563     ok(cabinfo.setID == 0xbeef, "Expected 0xbeef, got %d\n", cabinfo.setID);
564     todo_wine
565     {
566         ok(cabinfo.cbCabinet == 182, "Expected 182, got %ld\n", cabinfo.cbCabinet);
567         ok(cabinfo.iCabinet == 0, "Expected 0, got %d\n", cabinfo.iCabinet);
568     }
569
570     fdi_close(fd);
571     FDIDestroy(hfdi);
572     delete_test_files();
573 }
574
575 START_TEST(fdi)
576 {
577     test_FDICreate();
578     test_FDIDestroy();
579     test_FDIIsCabinet();
580 }