lz32: Fix several failing tests in win95.
[wine] / dlls / lz32 / tests / lzexpand_main.c
1 /*
2  * Unit test suite for lz32 functions
3  *
4  * Copyright 2004 Evan Parry, Daniel Kegel
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 <stdarg.h>
22 #include <windef.h>
23 #include <winbase.h>
24 #include <stdlib.h>
25 #include <winerror.h>
26 #include <lzexpand.h>
27
28 #include "wine/test.h"
29
30 /* Compressed file names end with underscore. */
31 static char filename [] = "testfile.xxx";
32 static char filename_[] = "testfile.xx_";
33 static WCHAR filenameW [] = {'t','e','s','t','f','i','l','e','.','x','x','x',0};
34 static WCHAR filenameW_[] = {'t','e','s','t','f','i','l','e','.','x','x','_',0};
35
36 static char dotless [] = "dotless";
37 static char dotless_[] = "dotless._";
38 static WCHAR dotlessW [] = {'d','o','t','l','e','s','s', 0};
39 static WCHAR dotlessW_[] = {'d','o','t','l','e','s','s','.','_', 0};
40
41 static char extless [] = "extless.";
42 static char extless_[] = "extless._";
43 static WCHAR extlessW [] = {'e','x','t','l','e','s','s','.', 0};
44 static WCHAR extlessW_[] = {'e','x','t','l','e','s','s','.','_', 0};
45
46 static char _terminated [] = "_terminated.xxxx_";
47 static char _terminated_[] = "_terminated.xxxx_";
48 static WCHAR _terminatedW [] = {'_','t','e','r','m','i','n','a','t','e','d','.','x','x','x','x','_', 0};
49 static WCHAR _terminatedW_[] = {'_','t','e','r','m','i','n','a','t','e','d','.','x','x','x','x','_', 0};
50
51 static char filename2[] = "testfile.yyy";
52
53 /* This is the hex string representation of the file created by compressing
54    a simple text file with the contents "This is a test file."
55  
56    The file was created using COMPRESS.EXE from the Windows Server 2003
57    Resource Kit from Microsoft.
58  */
59 static const unsigned char compressed_file[] = 
60   {0x53,0x5A,0x44,0x44,0x88,0xF0,0x27,0x33,0x41,
61    0x74,0x75,0x14,0x00,0x00,0xDF,0x54,0x68,0x69,
62    0x73,0x20,0xF2,0xF0,0x61,0x20,0xFF,0x74,0x65,
63    0x73,0x74,0x20,0x66,0x69,0x6C,0x03,0x65,0x2E};
64 static const DWORD compressed_file_size = sizeof(compressed_file);
65
66 static const char uncompressed_data[] = "This is a test file.";
67 static const DWORD uncompressed_data_size = sizeof(uncompressed_data) - 1;
68
69 static char *buf;
70
71 static void full_file_path_name_in_a_CWD(const char *src, char *dst, BOOL expect_short)
72 {
73   DWORD retval;
74   char shortname[MAX_PATH];
75
76   retval = GetCurrentDirectoryA(MAX_PATH, dst);
77   ok(retval > 0, "GetCurrentDirectoryA returned %d, GLE=%d\n",
78      retval, GetLastError());
79   if(dst[retval-1] != '\\')
80     /* Append backslash only when it's missing */
81       lstrcatA(dst, "\\");
82   lstrcatA(dst, src);
83   if(expect_short) 
84   {
85     memcpy(shortname, dst, MAX_PATH);
86     retval = GetShortPathName(shortname, dst, MAX_PATH-1);
87     ok(retval > 0, "GetShortPathName returned %d for '%s', GLE=%d\n",
88        retval, dst, GetLastError());
89   }
90 }
91
92 static void create_file(char *fname)
93 {
94   INT file;
95   OFSTRUCT ofs;
96   DWORD retval;
97
98   file = LZOpenFileA(fname, &ofs, OF_CREATE);
99   ok(file >= 0, "LZOpenFileA failed to create '%s'\n", fname);
100   LZClose(file);
101   retval = GetFileAttributesA(fname);
102   ok(retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA('%s'): error %d\n", ofs.szPathName, GetLastError());
103 }
104
105 static void delete_file(char *fname)
106 {
107   INT file;
108   OFSTRUCT ofs;
109   DWORD retval;
110
111   file = LZOpenFileA(fname, &ofs, OF_DELETE);
112   ok(file >= 0, "LZOpenFileA failed to delete '%s'\n", fname);
113   LZClose(file);
114   retval = GetFileAttributesA(fname);
115   ok(retval == INVALID_FILE_ATTRIBUTES, "GetFileAttributesA succeeded on deleted file ('%s')\n", ofs.szPathName);
116 }
117
118 static void test_LZOpenFileA_existing_compressed(void)
119 {
120   OFSTRUCT test;
121   INT file;
122   char expected[MAX_PATH];
123   char short_expected[MAX_PATH];
124   char filled_0xA5[OFS_MAXPATHNAME];
125
126   /* Try to open existing compressed files: */
127   create_file(filename_);
128   create_file(dotless_);
129   create_file(extless_);
130   create_file(_terminated_);
131
132   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
133   memset(&test, 0xA5, sizeof(test));
134   full_file_path_name_in_a_CWD(filename_, expected, FALSE);
135   SetLastError(0xfaceabee);
136
137   /* a, using 8.3-conformant file name. */
138   file = LZOpenFileA(filename, &test, OF_EXIST);
139   /* If the file "foo.xxx" does not exist, LZOpenFileA should then
140      check for the file "foo.xx_" and open that -- at least on some
141      operating systems.  Doesn't seem to on my copy of Win98.   
142    */
143   if(file != LZERROR_BADINHANDLE) {
144     ok(file >= 0, "LZOpenFileA returns negative file descriptor for '%s'\n", filename);
145     ok(test.cBytes == sizeof(OFSTRUCT), 
146        "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
147     ok(test.nErrCode == 0, "LZOpenFileA set test.nErrCode to %d\n", 
148        test.nErrCode);
149     ok(lstrcmpA(test.szPathName, expected) == 0, 
150        "LZOpenFileA returned '%s', but was expected to return '%s'\n", 
151        test.szPathName, expected);
152     LZClose(file);
153   } else { /* Win9x */
154     ok(GetLastError() == ERROR_FILE_NOT_FOUND,
155        "GetLastError() returns %d\n", GetLastError());
156     ok(test.cBytes == 0xA5, 
157        "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
158     ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
159        "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
160     ok(strncmp(test.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, 
161        "LZOpenFileA returned '%s', but was expected to return '%s'\n", 
162        test.szPathName, filled_0xA5);
163   }
164
165   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
166   memset(&test, 0xA5, sizeof(test));
167   full_file_path_name_in_a_CWD(dotless_, expected, FALSE);
168   SetLastError(0xfaceabee);
169
170   /* b, using dotless file name. */
171   file = LZOpenFileA(dotless, &test, OF_EXIST);
172   if(file != LZERROR_BADINHANDLE) {
173     ok(file >= 0, "LZOpenFileA returns negative file descriptor for '%s'\n", dotless);
174     ok(test.cBytes == sizeof(OFSTRUCT), 
175        "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
176     ok(test.nErrCode == 0, "LZOpenFileA set test.nErrCode to %d\n", 
177        test.nErrCode);
178     ok(lstrcmpA(test.szPathName, expected) == 0, 
179        "LZOpenFileA returned '%s', but was expected to return '%s'\n", 
180        test.szPathName, expected);
181     LZClose(file);
182   } else { /* Win9x */
183     ok(GetLastError() == ERROR_FILE_NOT_FOUND,
184        "GetLastError() returns %d\n", GetLastError());
185     todo_wine
186     ok(test.cBytes == 0xA5, 
187        "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
188     ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
189        "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
190     todo_wine
191     ok(strncmp(test.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, 
192        "LZOpenFileA returned '%s', but was expected to return '%s'\n", 
193        test.szPathName, filled_0xA5);
194   }
195
196   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
197   memset(&test, 0xA5, sizeof(test));
198   full_file_path_name_in_a_CWD(extless_, expected, FALSE);
199   SetLastError(0xfaceabee);
200
201   /* c, using extensionless file name. */
202   file = LZOpenFileA(extless, &test, OF_EXIST);
203   if(file != LZERROR_BADINHANDLE) {
204     ok(file >= 0, "LZOpenFileA returns negative file descriptor for '%s'\n", extless);
205     ok(test.cBytes == sizeof(OFSTRUCT), 
206        "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
207     ok(test.nErrCode == 0, "LZOpenFileA set test.nErrCode to %d\n", 
208        test.nErrCode);
209     ok(lstrcmpA(test.szPathName, expected) == 0, 
210        "LZOpenFileA returned '%s', but was expected to return '%s'\n", 
211        test.szPathName, expected);
212     LZClose(file);
213   } else { /* Win9x */
214     ok(GetLastError() == ERROR_FILE_NOT_FOUND,
215        "GetLastError() returns %d\n", GetLastError());
216     ok(test.cBytes == 0xA5, 
217        "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
218     ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
219        "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
220     ok(strncmp(test.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, 
221        "LZOpenFileA returned '%s', but was expected to return '%s'\n", 
222        test.szPathName, filled_0xA5);
223   }
224
225   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
226   memset(&test, 0xA5, sizeof(test));
227   full_file_path_name_in_a_CWD(_terminated_, expected, FALSE);
228   full_file_path_name_in_a_CWD(_terminated_, short_expected, TRUE);
229
230   /* d, using underscore-terminated file name. */
231   file = LZOpenFileA(_terminated, &test, OF_EXIST);
232   ok(file >= 0, "LZOpenFileA failed on switching to a compressed file name\n");
233   ok(test.cBytes == sizeof(OFSTRUCT) ||
234      broken(test.cBytes == 40), /* win95 */
235      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
236   ok(test.nErrCode == 0, "LZOpenFileA set test.nErrCode to %d\n", 
237      test.nErrCode);
238   ok(lstrcmpA(test.szPathName, expected) == 0 ||
239      lstrcmpA(test.szPathName, short_expected) == 0, /* Win9x */
240      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n", 
241      test.szPathName, expected, short_expected);
242   LZClose(file);
243
244   delete_file(filename_);
245   delete_file(dotless_);
246   delete_file(extless_);
247   delete_file(_terminated_);
248 }
249
250 static void test_LZOpenFileA_nonexisting_compressed(void)
251 {
252   OFSTRUCT test;
253   INT file;
254   char expected[MAX_PATH];
255   char filled_0xA5[OFS_MAXPATHNAME];
256
257   /* Try to open nonexisting compressed files: */
258   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
259   memset(&test, 0xA5, sizeof(test));
260   full_file_path_name_in_a_CWD(filename_, expected, FALSE);
261   SetLastError(0xfaceabee);
262
263   /* a, using 8.3-conformant file name. */
264   file = LZOpenFileA(filename, &test, OF_EXIST);
265   /* If the file "foo.xxx" does not exist, LZOpenFileA should then
266      check for the file "foo.xx_" and open that -- at least on some
267      operating systems.  Doesn't seem to on my copy of Win98.   
268    */
269   ok(file == LZERROR_BADINHANDLE, 
270      "LZOpenFileA succeeded on nonexistent file\n");
271   ok(GetLastError() == ERROR_FILE_NOT_FOUND,
272      "GetLastError() returns %d\n", GetLastError());
273   todo_wine
274   ok(test.cBytes == 0xA5, 
275      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
276   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
277      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
278   ok(lstrcmpA(test.szPathName, expected) == 0 ||
279      strncmp(test.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, /* Win9x */
280      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n", 
281      test.szPathName, expected, filled_0xA5);
282
283   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
284   memset(&test, 0xA5, sizeof(test));
285   full_file_path_name_in_a_CWD(dotless_, expected, FALSE);
286   SetLastError(0xfaceabee);
287
288   /* b, using dotless file name. */
289   file = LZOpenFileA(dotless, &test, OF_EXIST);
290   ok(file == LZERROR_BADINHANDLE, 
291      "LZOpenFileA succeeded on nonexistent file\n");
292   ok(GetLastError() == ERROR_FILE_NOT_FOUND,
293      "GetLastError() returns %d\n", GetLastError());
294   todo_wine
295   ok(test.cBytes == 0xA5, 
296      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
297   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
298      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
299   ok(lstrcmpA(test.szPathName, expected) == 0 ||
300      strncmp(test.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, /* Win9x */
301      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n", 
302      test.szPathName, expected, filled_0xA5);
303
304   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
305   memset(&test, 0xA5, sizeof(test));
306   full_file_path_name_in_a_CWD(extless_, expected, FALSE);
307   SetLastError(0xfaceabee);
308
309   /* c, using extensionless file name. */
310   file = LZOpenFileA(extless, &test, OF_EXIST);
311   ok(file == LZERROR_BADINHANDLE, 
312      "LZOpenFileA succeeded on nonexistent file\n");
313   ok(GetLastError() == ERROR_FILE_NOT_FOUND,
314      "GetLastError() returns %d\n", GetLastError());
315   todo_wine
316   ok(test.cBytes == 0xA5, 
317      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
318   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
319      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
320   ok(lstrcmpA(test.szPathName, expected) == 0 ||
321      strncmp(test.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, /* Win9x */
322      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n", 
323      test.szPathName, expected, filled_0xA5);
324
325   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
326   memset(&test, 0xA5, sizeof(test));
327   full_file_path_name_in_a_CWD(_terminated_, expected, FALSE);
328   SetLastError(0xfaceabee);
329
330   /* d, using underscore-terminated file name. */
331   file = LZOpenFileA(_terminated, &test, OF_EXIST);
332   ok(file == LZERROR_BADINHANDLE, 
333      "LZOpenFileA succeeded on nonexistent file\n");
334   ok(GetLastError() == ERROR_FILE_NOT_FOUND,
335      "GetLastError() returns %d\n", GetLastError());
336   todo_wine
337   ok(test.cBytes == 0xA5, 
338      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
339   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
340      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
341   ok(lstrcmpA(test.szPathName, expected) == 0 ||
342      strncmp(test.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, /* Win9x */
343      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n", 
344      test.szPathName, expected, filled_0xA5);
345 }
346
347 static void test_LZOpenFileA(void)
348 {
349   OFSTRUCT test;
350   DWORD retval;
351   INT file;
352   static char badfilename_[] = "badfilename_";
353   char expected[MAX_PATH];
354   char short_expected[MAX_PATH];
355
356   SetLastError(0xfaceabee);
357   /* Check for nonexistent file. */
358   file = LZOpenFileA(badfilename_, &test, OF_READ);
359   ok(file == LZERROR_BADINHANDLE, 
360      "LZOpenFileA succeeded on nonexistent file\n");
361   ok(GetLastError() == ERROR_FILE_NOT_FOUND, 
362      "GetLastError() returns %d\n", GetLastError());
363   LZClose(file);
364
365   memset(&test, 0xA5, sizeof(test));
366   full_file_path_name_in_a_CWD(filename_, expected, FALSE);
367
368   /* Create an empty file. */
369   file = LZOpenFileA(filename_, &test, OF_CREATE);
370   ok(file >= 0, "LZOpenFileA failed on creation\n");
371   ok(test.cBytes == sizeof(OFSTRUCT),
372      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
373   ok(test.nErrCode == ERROR_SUCCESS ||
374      test.nErrCode == ERROR_FILE_NOT_FOUND, /* win9x */
375      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
376   ok(lstrcmpA(test.szPathName, expected) == 0,
377      "LZOpenFileA returned '%s', but was expected to return '%s'\n",
378      test.szPathName, expected);
379   LZClose(file);
380
381   retval = GetFileAttributesA(filename_);
382   ok(retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %d\n", 
383      GetLastError());
384
385   /* Check various opening options: */
386   memset(&test, 0xA5, sizeof(test));
387   full_file_path_name_in_a_CWD(filename_, short_expected, TRUE);
388
389   /* a, for reading. */
390   file = LZOpenFileA(filename_, &test, OF_READ);
391   ok(file >= 0, "LZOpenFileA failed on read\n");
392   ok(test.cBytes == sizeof(OFSTRUCT) ||
393      broken(test.cBytes == 40), /* win95 */
394      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
395   ok(test.nErrCode == ERROR_SUCCESS,
396      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
397   ok(lstrcmpA(test.szPathName, expected) == 0 ||
398      lstrcmpA(test.szPathName, short_expected) == 0, /* Win9x */
399      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n",
400      test.szPathName, expected, short_expected);
401   LZClose(file);
402
403   memset(&test, 0xA5, sizeof(test));
404
405   /* b, for writing. */
406   file = LZOpenFileA(filename_, &test, OF_WRITE);
407   ok(file >= 0, "LZOpenFileA failed on write\n");
408   ok(test.cBytes == sizeof(OFSTRUCT) ||
409      broken(test.cBytes == 40), /* win95 */
410      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
411   ok(test.nErrCode == ERROR_SUCCESS,
412      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
413   ok(lstrcmpA(test.szPathName, expected) == 0 ||
414      lstrcmpA(test.szPathName, short_expected) == 0, /* Win9x */
415      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n",
416      test.szPathName, expected, short_expected);
417   LZClose(file);
418
419   memset(&test, 0xA5, sizeof(test));
420
421   /* c, for reading and writing. */
422   file = LZOpenFileA(filename_, &test, OF_READWRITE);
423   ok(file >= 0, "LZOpenFileA failed on read/write\n");
424   ok(test.cBytes == sizeof(OFSTRUCT) ||
425      broken(test.cBytes == 40), /* win95 */
426      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
427   ok(test.nErrCode == ERROR_SUCCESS,
428      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
429   ok(lstrcmpA(test.szPathName, expected) == 0 ||
430      lstrcmpA(test.szPathName, short_expected) == 0, /* Win9x */
431      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n",
432      test.szPathName, expected, short_expected);
433   LZClose(file);
434
435   memset(&test, 0xA5, sizeof(test));
436
437   /* d, for checking file existence. */
438   file = LZOpenFileA(filename_, &test, OF_EXIST);
439   ok(file >= 0, "LZOpenFileA failed on read/write\n");
440   ok(test.cBytes == sizeof(OFSTRUCT) ||
441      broken(test.cBytes == 40), /* win95 */
442      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
443   ok(test.nErrCode == ERROR_SUCCESS,
444      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
445   ok(lstrcmpA(test.szPathName, expected) == 0 ||
446      lstrcmpA(test.szPathName, short_expected) == 0, /* Win9x */
447      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n",
448      test.szPathName, expected, short_expected);
449   LZClose(file);
450
451   memset(&test, 0xA5, sizeof(test));
452
453   /* Delete the file then make sure it doesn't exist anymore. */
454   file = LZOpenFileA(filename_, &test, OF_DELETE);
455   ok(file >= 0, "LZOpenFileA failed on delete\n");
456   ok(test.cBytes == sizeof(OFSTRUCT) ||
457      broken(test.cBytes == 40), /* win95 */
458      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
459   ok(test.nErrCode == ERROR_SUCCESS,
460      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
461   ok(lstrcmpA(test.szPathName, expected) == 0 ||
462      lstrcmpA(test.szPathName, short_expected) == 0, /* Win9x */
463      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n",
464      test.szPathName, expected, short_expected);
465   LZClose(file);
466
467   retval = GetFileAttributesA(filename_);
468   ok(retval == INVALID_FILE_ATTRIBUTES, 
469      "GetFileAttributesA succeeded on deleted file\n");
470
471   test_LZOpenFileA_existing_compressed();
472   test_LZOpenFileA_nonexisting_compressed();
473 }
474
475 static void test_LZRead(void)
476 {
477   HANDLE file;
478   DWORD ret;
479   int cfile;
480   OFSTRUCT test;
481   BOOL retok;
482
483   /* Create the compressed file. */
484   file = CreateFileA(filename_, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0);
485   ok(file != INVALID_HANDLE_VALUE, "Could not create test file\n");
486   retok = WriteFile(file, compressed_file, compressed_file_size, &ret, 0);
487   ok( retok, "WriteFile: error %d\n", GetLastError());
488   ok(ret == compressed_file_size, "Wrote wrong number of bytes with WriteFile?\n");
489   CloseHandle(file);
490
491   cfile = LZOpenFileA(filename_, &test, OF_READ);
492   ok(cfile > 0, "LZOpenFileA failed\n");
493
494   ret = LZRead(cfile, buf, uncompressed_data_size);
495   ok(ret == uncompressed_data_size, "Read wrong number of bytes\n");
496
497   /* Compare what we read with what we think we should read. */
498   ok(memcmp(buf, uncompressed_data, uncompressed_data_size) == 0,
499      "buffer contents mismatch\n");
500
501   todo_wine {
502      /* Wine returns the number of bytes actually read instead of an error */
503      ret = LZRead(cfile, buf, uncompressed_data_size);
504      ok(ret == LZERROR_READ, "Expected read-past-EOF to return LZERROR_READ\n");
505   }
506
507   LZClose(cfile);
508
509   ret = DeleteFileA(filename_);
510   ok(ret, "DeleteFileA: error %d\n", GetLastError());
511 }
512
513 static void test_LZCopy(void)
514 {
515   HANDLE file;
516   DWORD ret;
517   int source, dest;
518   OFSTRUCT stest, dtest;
519   BOOL retok;
520
521   /* Create the compressed file. */
522   file = CreateFileA(filename_, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0);
523   ok(file != INVALID_HANDLE_VALUE, 
524      "CreateFileA: error %d\n", GetLastError());
525   retok = WriteFile(file, compressed_file, compressed_file_size, &ret, 0);
526   ok( retok, "WriteFile error %d\n", GetLastError());
527   ok(ret == compressed_file_size, "Wrote wrong number of bytes\n");
528   CloseHandle(file);
529
530   source = LZOpenFileA(filename_, &stest, OF_READ);
531   ok(source >= 0, "LZOpenFileA failed on compressed file\n");
532   dest = LZOpenFileA(filename2, &dtest, OF_CREATE);
533   ok(dest >= 0, "LZOpenFileA failed on creating new file %d\n", dest);
534
535   ret = LZCopy(source, dest);
536   ok(ret > 0, "LZCopy error\n");
537
538   LZClose(source);
539   LZClose(dest);
540
541   file = CreateFileA(filename2, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
542   ok(file != INVALID_HANDLE_VALUE,
543      "CreateFileA: error %d\n", GetLastError());
544
545   retok = ReadFile(file, buf, uncompressed_data_size*2, &ret, 0);
546   ok( retok && ret == uncompressed_data_size, "ReadFile: error %d\n", GetLastError());
547   /* Compare what we read with what we think we should read. */
548   ok(!memcmp(buf, uncompressed_data, uncompressed_data_size),
549      "buffer contents mismatch\n");
550   CloseHandle(file);
551
552   ret = DeleteFileA(filename_);
553   ok(ret, "DeleteFileA: error %d\n", GetLastError());
554   ret = DeleteFileA(filename2);
555   ok(ret, "DeleteFileA: error %d\n", GetLastError());
556 }
557
558 static void create_fileW(WCHAR *fnameW)
559 {
560   INT file;
561   OFSTRUCT ofs;
562   DWORD retval;
563
564   file = LZOpenFileW(fnameW, &ofs, OF_CREATE);
565   ok(file >= 0, "LZOpenFileW failed on creation\n");
566   LZClose(file);
567   retval = GetFileAttributesW(fnameW);
568   ok(retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributesW('%s'): error %d\n", ofs.szPathName, GetLastError());
569 }
570
571 static void delete_fileW(WCHAR *fnameW)
572 {
573   INT file;
574   OFSTRUCT ofs;
575   DWORD retval;
576
577   file = LZOpenFileW(fnameW, &ofs, OF_DELETE);
578   ok(file >= 0, "LZOpenFileW failed on delete\n");
579   LZClose(file);
580   retval = GetFileAttributesW(fnameW);
581   ok(retval == INVALID_FILE_ATTRIBUTES, "GetFileAttributesW succeeded on deleted file ('%s')\n", ofs.szPathName);
582 }
583
584 static void test_LZOpenFileW_existing_compressed(void)
585 {
586   OFSTRUCT test;
587   INT file;
588   char expected[MAX_PATH];
589
590   /* Try to open existing compressed files: */
591   create_fileW(filenameW_);
592   create_fileW(dotlessW_);
593   create_fileW(extlessW_);
594   create_fileW(_terminatedW_);
595
596   full_file_path_name_in_a_CWD(filename_, expected, FALSE);
597   memset(&test, 0xA5, sizeof(test));
598
599   /* a, using 8.3-conformant file name. */
600   file = LZOpenFileW(filenameW, &test, OF_EXIST);
601   /* If the file "foo.xxx" does not exist, LZOpenFileW should then
602      check for the file "foo.xx_" and open that.
603    */
604   ok(file >= 0, "LZOpenFileW failed on switching to a compressed file name\n");
605   ok(test.cBytes == sizeof(OFSTRUCT), 
606      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
607   ok(test.nErrCode == ERROR_SUCCESS, "LZOpenFileW set test.nErrCode to %d\n", 
608      test.nErrCode);
609   /* Note that W-function returns A-string by a OFSTRUCT.szPathName: */
610   ok(lstrcmpA(test.szPathName, expected) == 0, 
611      "LZOpenFileW returned '%s', but was expected to return '%s'\n", 
612      test.szPathName, expected);
613   LZClose(file);
614
615   memset(&test, 0xA5, sizeof(test));
616   full_file_path_name_in_a_CWD(dotless_, expected, FALSE);
617
618   /* b, using dotless file name. */
619   file = LZOpenFileW(dotlessW, &test, OF_EXIST);
620   ok(file >= 0, "LZOpenFileW failed on switching to a compressed file name\n");
621   ok(test.cBytes == sizeof(OFSTRUCT), 
622      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
623   ok(test.nErrCode == ERROR_SUCCESS, "LZOpenFileW set test.nErrCode to %d\n", 
624      test.nErrCode);
625   /* Note that W-function returns A-string by a OFSTRUCT.szPathName: */
626   ok(lstrcmpA(test.szPathName, expected) == 0, 
627      "LZOpenFileW returned '%s', but was expected to return '%s'\n", 
628      test.szPathName, expected);
629   LZClose(file);
630
631   memset(&test, 0xA5, sizeof(test));
632   full_file_path_name_in_a_CWD(extless_, expected, FALSE);
633
634   /* c, using extensionless file name. */
635   file = LZOpenFileW(extlessW, &test, OF_EXIST);
636   ok(file >= 0, "LZOpenFileW failed on switching to a compressed file name\n");
637   ok(test.cBytes == sizeof(OFSTRUCT), 
638      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
639   ok(test.nErrCode == ERROR_SUCCESS, "LZOpenFileW set test.nErrCode to %d\n", 
640      test.nErrCode);
641   /* Note that W-function returns A-string by a OFSTRUCT.szPathName: */
642   ok(lstrcmpA(test.szPathName, expected) == 0, 
643      "LZOpenFileW returned '%s', but was expected to return '%s'\n", 
644      test.szPathName, expected);
645   LZClose(file);
646
647   memset(&test, 0xA5, sizeof(test));
648   full_file_path_name_in_a_CWD(_terminated_, expected, FALSE);
649
650   /* d, using underscore-terminated file name. */
651   file = LZOpenFileW(_terminatedW, &test, OF_EXIST);
652   ok(file >= 0, "LZOpenFileW failed on switching to a compressed file name\n");
653   ok(test.cBytes == sizeof(OFSTRUCT), 
654      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
655   ok(test.nErrCode == ERROR_SUCCESS, "LZOpenFileW set test.nErrCode to %d\n", 
656      test.nErrCode);
657   /* Note that W-function returns A-string by a OFSTRUCT.szPathName: */
658   ok(lstrcmpA(test.szPathName, expected) == 0, 
659      "LZOpenFileW returned '%s', but was expected to return '%s'\n", 
660      test.szPathName, expected);
661   LZClose(file);
662
663   delete_fileW(filenameW_);
664   delete_fileW(dotlessW_);
665   delete_fileW(extlessW_);
666   delete_fileW(_terminatedW_);
667 }
668
669 static void test_LZOpenFileW_nonexisting_compressed(void)
670 {
671   OFSTRUCT test;
672   INT file;
673   char expected[MAX_PATH];
674   char filled_0xA5[OFS_MAXPATHNAME];
675
676   /* Try to open nonexisting compressed files: */
677   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
678   memset(&test, 0xA5, sizeof(test));
679   full_file_path_name_in_a_CWD(filename_, expected, FALSE);
680   SetLastError(0xfaceabee);
681
682   /* a, using 8.3-conformant file name. */
683   file = LZOpenFileW(filenameW, &test, OF_EXIST);
684   /* If the file "foo.xxx" does not exist, LZOpenFileA should then
685      check for the file "foo.xx_" and open that -- at least on some
686      operating systems.  Doesn't seem to on my copy of Win98.   
687    */
688   ok(file == LZERROR_BADINHANDLE, 
689      "LZOpenFileW succeeded on nonexistent file\n");
690   ok(GetLastError() == ERROR_FILE_NOT_FOUND,
691      "GetLastError() returns %d\n", GetLastError());
692   todo_wine
693   ok(test.cBytes == 0xA5, 
694      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
695   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
696      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
697   ok(lstrcmpA(test.szPathName, expected) == 0,
698      "LZOpenFileW returned '%s', but was expected to return '%s' or '%s'\n", 
699      test.szPathName, expected, filled_0xA5);
700
701   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
702   memset(&test, 0xA5, sizeof(test));
703   full_file_path_name_in_a_CWD(dotless_, expected, FALSE);
704   SetLastError(0xfaceabee);
705
706   /* b, using dotless file name. */
707   file = LZOpenFileW(dotlessW, &test, OF_EXIST);
708   ok(file == LZERROR_BADINHANDLE, 
709      "LZOpenFileW succeeded on nonexistent file\n");
710   ok(GetLastError() == ERROR_FILE_NOT_FOUND,
711      "GetLastError() returns %d\n", GetLastError());
712   todo_wine
713   ok(test.cBytes == 0xA5, 
714      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
715   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
716      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
717   ok(lstrcmpA(test.szPathName, expected) == 0,
718      "LZOpenFileW returned '%s', but was expected to return '%s' or '%s'\n", 
719      test.szPathName, expected, filled_0xA5);
720
721   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
722   memset(&test, 0xA5, sizeof(test));
723   full_file_path_name_in_a_CWD(extless_, expected, FALSE);
724   SetLastError(0xfaceabee);
725
726   /* c, using extensionless file name. */
727   file = LZOpenFileW(extlessW, &test, OF_EXIST);
728   ok(file == LZERROR_BADINHANDLE, 
729      "LZOpenFileW succeeded on nonexistent file\n");
730   ok(GetLastError() == ERROR_FILE_NOT_FOUND,
731      "GetLastError() returns %d\n", GetLastError());
732   todo_wine
733   ok(test.cBytes == 0xA5, 
734      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
735   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
736      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
737   ok(lstrcmpA(test.szPathName, expected) == 0,
738      "LZOpenFileW returned '%s', but was expected to return '%s' or '%s'\n", 
739      test.szPathName, expected, filled_0xA5);
740
741   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
742   memset(&test, 0xA5, sizeof(test));
743   full_file_path_name_in_a_CWD(_terminated_, expected, FALSE);
744   SetLastError(0xfaceabee);
745
746   /* d, using underscore-terminated file name. */
747   file = LZOpenFileW(_terminatedW, &test, OF_EXIST);
748   ok(file == LZERROR_BADINHANDLE, 
749      "LZOpenFileW succeeded on nonexistent file\n");
750   ok(GetLastError() == ERROR_FILE_NOT_FOUND,
751      "GetLastError() returns %d\n", GetLastError());
752   todo_wine
753   ok(test.cBytes == 0xA5, 
754      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
755   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
756      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
757   ok(lstrcmpA(test.szPathName, expected) == 0,
758      "LZOpenFileW returned '%s', but was expected to return '%s' or '%s'\n",
759      test.szPathName, expected, filled_0xA5);
760 }
761
762 static void test_LZOpenFileW(void)
763 {
764   OFSTRUCT test;
765   DWORD retval;
766   INT file;
767   static WCHAR badfilenameW[] = {'b','a','d','f','i','l','e','n','a','m','e','.','x','t','n',0};
768   char expected[MAX_PATH];
769
770   SetLastError(0xfaceabee);
771   /* Check for nonexistent file. */
772   file = LZOpenFileW(badfilenameW, &test, OF_READ);
773   ok(GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_CALL_NOT_IMPLEMENTED,
774      "GetLastError() returns %d\n", GetLastError());
775   if(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
776   {
777     trace("LZOpenFileW call not implemented, skipping rest of the test\n");
778     return;
779   }
780   ok(file == LZERROR_BADINHANDLE, "LZOpenFileW succeeded on nonexistent file\n");
781   LZClose(file);
782
783   memset(&test, 0xA5, sizeof(test));
784   full_file_path_name_in_a_CWD(filename_, expected, FALSE);
785
786   /* Create an empty file. */
787   file = LZOpenFileW(filenameW_, &test, OF_CREATE);
788   ok(file >= 0, "LZOpenFile failed on creation\n");
789   ok(test.cBytes == sizeof(OFSTRUCT),
790      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
791   ok(test.nErrCode == ERROR_SUCCESS,
792      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
793   ok(lstrcmpA(test.szPathName, expected) == 0,
794      "LZOpenFileW returned '%s', but was expected to return '%s'\n",
795      test.szPathName, expected);
796   LZClose(file);
797
798   retval = GetFileAttributesW(filenameW_);
799   ok(retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributes: error %d\n", 
800     GetLastError());
801
802   /* Check various opening options: */
803   memset(&test, 0xA5, sizeof(test));
804
805   /* a, for reading. */
806   file = LZOpenFileW(filenameW_, &test, OF_READ);
807   ok(file >= 0, "LZOpenFileW failed on read\n");
808   ok(test.cBytes == sizeof(OFSTRUCT),
809      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
810   ok(test.nErrCode == ERROR_SUCCESS,
811      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
812   ok(lstrcmpA(test.szPathName, expected) == 0,
813      "LZOpenFileW returned '%s', but was expected to return '%s'\n",
814      test.szPathName, expected);
815   LZClose(file);
816
817   memset(&test, 0xA5, sizeof(test));
818
819   /* b, for writing. */
820   file = LZOpenFileW(filenameW_, &test, OF_WRITE);
821   ok(file >= 0, "LZOpenFileW failed on write\n");
822   ok(test.cBytes == sizeof(OFSTRUCT),
823      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
824   ok(test.nErrCode == ERROR_SUCCESS,
825      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
826   ok(lstrcmpA(test.szPathName, expected) == 0,
827      "LZOpenFileW returned '%s', but was expected to return '%s'\n",
828      test.szPathName, expected);
829   LZClose(file);
830
831   memset(&test, 0xA5, sizeof(test));
832
833   /* c, for reading and writing. */
834   file = LZOpenFileW(filenameW_, &test, OF_READWRITE);
835   ok(file >= 0, "LZOpenFileW failed on read/write\n");
836   ok(test.cBytes == sizeof(OFSTRUCT),
837      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
838   ok(test.nErrCode == ERROR_SUCCESS,
839      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
840   ok(lstrcmpA(test.szPathName, expected) == 0,
841      "LZOpenFileW returned '%s', but was expected to return '%s'\n",
842      test.szPathName, expected);
843   LZClose(file);
844
845   memset(&test, 0xA5, sizeof(test));
846
847   /* d, for checking file existence. */
848   file = LZOpenFileW(filenameW_, &test, OF_EXIST);
849   ok(file >= 0, "LZOpenFileW failed on read/write\n");
850   ok(test.cBytes == sizeof(OFSTRUCT),
851      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
852   ok(test.nErrCode == ERROR_SUCCESS,
853      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
854   ok(lstrcmpA(test.szPathName, expected) == 0,
855      "LZOpenFileW returned '%s', but was expected to return '%s'\n",
856      test.szPathName, expected);
857   LZClose(file);
858
859   memset(&test, 0xA5, sizeof(test));
860
861   /* Delete the file then make sure it doesn't exist anymore. */
862   file = LZOpenFileW(filenameW_, &test, OF_DELETE);
863   ok(file >= 0, "LZOpenFileW failed on delete\n");
864   ok(test.cBytes == sizeof(OFSTRUCT),
865      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
866   ok(test.nErrCode == ERROR_SUCCESS,
867      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
868   ok(lstrcmpA(test.szPathName, expected) == 0,
869      "LZOpenFileW returned '%s', but was expected to return '%s'\n",
870      test.szPathName, expected);
871   LZClose(file);
872
873   retval = GetFileAttributesW(filenameW_);
874   ok(retval == INVALID_FILE_ATTRIBUTES, 
875      "GetFileAttributesW succeeded on deleted file\n");
876
877   test_LZOpenFileW_existing_compressed();
878   test_LZOpenFileW_nonexisting_compressed();
879 }
880
881
882 START_TEST(lzexpand_main)
883 {
884   buf = malloc(uncompressed_data_size * 2);
885   test_LZOpenFileA();
886   test_LZOpenFileW();
887   test_LZRead();
888   test_LZCopy();
889   free(buf);
890 }