janitorial: Remove remaining NULL checks before free() (found by Smatch).
[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.  The resource kit was retrieved from the
58    following URL:  
59
60    http://www.microsoft.com/downloads/details.aspx?FamilyID=9d467a69-57ff-4ae7-96ee-b18c4790cffd&displaylang=en
61  */
62 static const unsigned char compressed_file[] = 
63   {0x53,0x5A,0x44,0x44,0x88,0xF0,0x27,0x33,0x41,
64    0x74,0x75,0x14,0x00,0x00,0xDF,0x54,0x68,0x69,
65    0x73,0x20,0xF2,0xF0,0x61,0x20,0xFF,0x74,0x65,
66    0x73,0x74,0x20,0x66,0x69,0x6C,0x03,0x65,0x2E};
67 static const DWORD compressed_file_size = sizeof(compressed_file);
68
69 static const char uncompressed_data[] = "This is a test file.";
70 static const DWORD uncompressed_data_size = sizeof(uncompressed_data) - 1;
71
72 static char *buf;
73
74 static void full_file_path_name_in_a_CWD(const char *src, char *dst, BOOL expect_short)
75 {
76   DWORD retval;
77   char shortname[MAX_PATH];
78
79   retval = GetCurrentDirectoryA(MAX_PATH, dst);
80   ok(retval > 0, "GetCurrentDirectoryA returned %ld, GLE=0x%lx\n", 
81      retval, GetLastError());
82   lstrcatA(dst, "\\");
83   lstrcatA(dst, src);
84   if(expect_short) 
85   {
86     memcpy(shortname, dst, MAX_PATH);
87     GetShortPathName(shortname, dst, MAX_PATH-1);
88   }
89 }
90
91 static void create_file(char *fname)
92 {
93   INT file;
94   OFSTRUCT ofs;
95   DWORD retval;
96
97   file = LZOpenFileA(fname, &ofs, OF_CREATE);
98   ok(file >= 0, "LZOpenFileA failed on creation\n");
99   LZClose(file);
100   retval = GetFileAttributesA(fname);
101   ok(retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA('%s'): error %ld\n", ofs.szPathName, GetLastError());
102 }
103
104 static void delete_file(char *fname)
105 {
106   INT file;
107   OFSTRUCT ofs;
108   DWORD retval;
109
110   file = LZOpenFileA(fname, &ofs, OF_DELETE);
111   ok(file >= 0, "LZOpenFileA failed on delete\n");
112   LZClose(file);
113   retval = GetFileAttributesA(fname);
114   ok(retval == INVALID_FILE_ATTRIBUTES, "GetFileAttributesA succeeded on deleted file ('%s')\n", ofs.szPathName);
115 }
116
117 static void test_LZOpenFileA_existing_compressed(void)
118 {
119   OFSTRUCT test;
120   INT file;
121   char expected[MAX_PATH];
122   char short_expected[MAX_PATH];
123   char filled_0xA5[OFS_MAXPATHNAME];
124
125   /* Try to open existing compressed files: */
126   create_file(filename_);
127   create_file(dotless_);
128   create_file(extless_);
129   create_file(_terminated_);
130
131   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
132   memset(&test, 0xA5, sizeof(test));
133   full_file_path_name_in_a_CWD(filename_, expected, FALSE);
134
135   /* a, using 8.3-conformant file name. */
136   file = LZOpenFileA(filename, &test, OF_EXIST);
137   /* If the file "foo.xxx" does not exist, LZOpenFileA should then
138      check for the file "foo.xx_" and open that -- at least on some
139      operating systems.  Doesn't seem to on my copy of Win98.   
140    */
141   if(file != LZERROR_BADINHANDLE) {
142     ok(test.cBytes == sizeof(OFSTRUCT), 
143        "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
144     ok(test.nErrCode == 0, "LZOpenFileA set test.nErrCode to %d\n", 
145        test.nErrCode);
146     ok(lstrcmpA(test.szPathName, expected) == 0, 
147        "LZOpenFileA returned '%s', but was expected to return '%s'\n", 
148        test.szPathName, expected);
149     LZClose(file);
150   } else { /* Win9x */
151     ok(test.cBytes == 0xA5, 
152        "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
153     ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
154        "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
155     ok(strncmp(test.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, 
156        "LZOpenFileA returned '%s', but was expected to return '%s'\n", 
157        test.szPathName, filled_0xA5);
158   }
159
160   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
161   memset(&test, 0xA5, sizeof(test));
162   full_file_path_name_in_a_CWD(dotless_, expected, FALSE);
163
164   /* b, using dotless file name. */
165   file = LZOpenFileA(dotless, &test, OF_EXIST);
166   if(file != LZERROR_BADINHANDLE) {
167     ok(test.cBytes == sizeof(OFSTRUCT), 
168        "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
169     ok(test.nErrCode == 0, "LZOpenFileA set test.nErrCode to %d\n", 
170        test.nErrCode);
171     ok(lstrcmpA(test.szPathName, expected) == 0, 
172        "LZOpenFileA returned '%s', but was expected to return '%s'\n", 
173        test.szPathName, expected);
174     LZClose(file);
175   } else { /* Win9x */
176     todo_wine
177     ok(test.cBytes == 0xA5, 
178        "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
179     ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
180        "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
181     todo_wine
182     ok(strncmp(test.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, 
183        "LZOpenFileA returned '%s', but was expected to return '%s'\n", 
184        test.szPathName, filled_0xA5);
185   }
186
187   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
188   memset(&test, 0xA5, sizeof(test));
189   full_file_path_name_in_a_CWD(extless_, expected, FALSE);
190
191   /* c, using extensionless file name. */
192   file = LZOpenFileA(extless, &test, OF_EXIST);
193   if(file != LZERROR_BADINHANDLE) {
194     ok(test.cBytes == sizeof(OFSTRUCT), 
195        "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
196     ok(test.nErrCode == 0, "LZOpenFileA set test.nErrCode to %d\n", 
197        test.nErrCode);
198     ok(lstrcmpA(test.szPathName, expected) == 0, 
199        "LZOpenFileA returned '%s', but was expected to return '%s'\n", 
200        test.szPathName, expected);
201     LZClose(file);
202   } else { /* Win9x */
203     ok(test.cBytes == 0xA5, 
204        "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
205     ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
206        "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
207     ok(strncmp(test.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, 
208        "LZOpenFileA returned '%s', but was expected to return '%s'\n", 
209        test.szPathName, filled_0xA5);
210   }
211
212   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
213   memset(&test, 0xA5, sizeof(test));
214   full_file_path_name_in_a_CWD(_terminated_, expected, FALSE);
215   full_file_path_name_in_a_CWD(_terminated_, short_expected, TRUE);
216
217   /* d, using underscore-terminated file name. */
218   file = LZOpenFileA(_terminated, &test, OF_EXIST);
219   ok(file >= 0, "LZOpenFileA failed on switching to a compressed file name\n");
220   ok(test.cBytes == sizeof(OFSTRUCT), 
221      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
222   ok(test.nErrCode == 0, "LZOpenFileA set test.nErrCode to %d\n", 
223      test.nErrCode);
224   ok(lstrcmpA(test.szPathName, expected) == 0 ||
225      lstrcmpA(test.szPathName, short_expected) == 0, /* Win9x */
226      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n", 
227      test.szPathName, expected, short_expected);
228   LZClose(file);
229
230   delete_file(filename_);
231   delete_file(dotless_);
232   delete_file(extless_);
233   delete_file(_terminated_);
234 }
235
236 static void test_LZOpenFileA_nonexisting_compressed(void)
237 {
238   OFSTRUCT test;
239   INT file;
240   char expected[MAX_PATH];
241   char filled_0xA5[OFS_MAXPATHNAME];
242
243   /* Try to open nonexisting compressed files: */
244   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
245   memset(&test, 0xA5, sizeof(test));
246   full_file_path_name_in_a_CWD(filename_, expected, FALSE);
247
248   /* a, using 8.3-conformant file name. */
249   file = LZOpenFileA(filename, &test, OF_EXIST);
250   /* If the file "foo.xxx" does not exist, LZOpenFileA should then
251      check for the file "foo.xx_" and open that -- at least on some
252      operating systems.  Doesn't seem to on my copy of Win98.   
253    */
254   ok(file == LZERROR_BADINHANDLE, 
255      "LZOpenFileA succeeded on nonexistent file\n");
256   todo_wine
257   ok(test.cBytes == 0xA5, 
258      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
259   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
260      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
261   ok(lstrcmpA(test.szPathName, expected) == 0 ||
262      strncmp(test.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, /* Win9x */
263      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n", 
264      test.szPathName, expected, filled_0xA5);
265
266   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
267   memset(&test, 0xA5, sizeof(test));
268   full_file_path_name_in_a_CWD(dotless_, expected, FALSE);
269
270   /* b, using dotless file name. */
271   file = LZOpenFileA(dotless, &test, OF_EXIST);
272   ok(file == LZERROR_BADINHANDLE, 
273      "LZOpenFileA succeeded on nonexistent file\n");
274   todo_wine
275   ok(test.cBytes == 0xA5, 
276      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
277   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
278      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
279   ok(lstrcmpA(test.szPathName, expected) == 0 ||
280      strncmp(test.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, /* Win9x */
281      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n", 
282      test.szPathName, expected, filled_0xA5);
283
284   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
285   memset(&test, 0xA5, sizeof(test));
286   full_file_path_name_in_a_CWD(extless_, expected, FALSE);
287
288   /* c, using extensionless file name. */
289   file = LZOpenFileA(extless, &test, OF_EXIST);
290   ok(file == LZERROR_BADINHANDLE, 
291      "LZOpenFileA succeeded on nonexistent file\n");
292   todo_wine
293   ok(test.cBytes == 0xA5, 
294      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
295   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
296      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
297   ok(lstrcmpA(test.szPathName, expected) == 0 ||
298      strncmp(test.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, /* Win9x */
299      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n", 
300      test.szPathName, expected, filled_0xA5);
301
302   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
303   memset(&test, 0xA5, sizeof(test));
304   full_file_path_name_in_a_CWD(_terminated_, expected, FALSE);
305
306   /* d, using underscore-terminated file name. */
307   file = LZOpenFileA(_terminated, &test, OF_EXIST);
308   ok(file == LZERROR_BADINHANDLE, 
309      "LZOpenFileA succeeded on nonexistent file\n");
310   todo_wine
311   ok(test.cBytes == 0xA5, 
312      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
313   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
314      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
315   ok(lstrcmpA(test.szPathName, expected) == 0 ||
316      strncmp(test.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, /* Win9x */
317      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n", 
318      test.szPathName, expected, filled_0xA5);
319 }
320
321 static void test_LZOpenFileA(void)
322 {
323   OFSTRUCT test;
324   DWORD retval;
325   INT file;
326   static char badfilename_[] = "badfilename_";
327
328   SetLastError(0xfaceabee);
329   /* Check for nonexistent file. */
330   file = LZOpenFileA(badfilename_, &test, OF_READ);
331   ok(file == LZERROR_BADINHANDLE, 
332      "LZOpenFileA succeeded on nonexistent file\n");
333   ok(GetLastError() == ERROR_FILE_NOT_FOUND, 
334      "GetLastError() returns %ld\n", GetLastError());
335   LZClose(file);
336
337   /* Create an empty file. */
338   file = LZOpenFileA(filename_, &test, OF_CREATE);
339   ok(file >= 0, "LZOpenFileA failed on creation\n");
340   LZClose(file);
341   retval = GetFileAttributesA(filename_);
342   ok(retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %ld\n", 
343      GetLastError());
344
345   /* Check various opening options. */
346   file = LZOpenFileA(filename_, &test, OF_READ);
347   ok(file >= 0, "LZOpenFileA failed on read\n");
348   LZClose(file);
349   file = LZOpenFileA(filename_, &test, OF_WRITE);
350   ok(file >= 0, "LZOpenFileA failed on write\n");
351   LZClose(file);
352   file = LZOpenFileA(filename_, &test, OF_READWRITE);
353   ok(file >= 0, "LZOpenFileA failed on read/write\n");
354   LZClose(file);
355   file = LZOpenFileA(filename_, &test, OF_EXIST);
356   ok(file >= 0, "LZOpenFileA failed on read/write\n");
357   LZClose(file);
358
359   /* Delete the file then make sure it doesn't exist anymore. */
360   file = LZOpenFileA(filename_, &test, OF_DELETE);
361   ok(file >= 0, "LZOpenFileA failed on delete\n");
362   LZClose(file);
363
364   retval = GetFileAttributesA(filename_);
365   ok(retval == INVALID_FILE_ATTRIBUTES, 
366      "GetFileAttributesA succeeded on deleted file\n");
367
368   test_LZOpenFileA_existing_compressed();
369   test_LZOpenFileA_nonexisting_compressed();
370 }
371
372 static void test_LZRead(void)
373 {
374   HANDLE file;
375   DWORD ret;
376   int cfile;
377   OFSTRUCT test;
378   BOOL retok;
379
380   /* Create the compressed file. */
381   file = CreateFileA(filename_, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0);
382   ok(file != INVALID_HANDLE_VALUE, "Could not create test file\n");
383   retok = WriteFile(file, compressed_file, compressed_file_size, &ret, 0);
384   ok( retok, "WriteFile: error %ld\n", GetLastError());
385   ok(ret == compressed_file_size, "Wrote wrong number of bytes with WriteFile?\n");
386   CloseHandle(file);
387
388   cfile = LZOpenFileA(filename_, &test, OF_READ);
389   ok(cfile > 0, "LZOpenFileA failed\n");
390
391   ret = LZRead(cfile, buf, uncompressed_data_size);
392   ok(ret == uncompressed_data_size, "Read wrong number of bytes\n");
393
394   /* Compare what we read with what we think we should read. */
395   ok(memcmp(buf, uncompressed_data, uncompressed_data_size) == 0,
396      "buffer contents mismatch\n");
397
398   todo_wine {
399      /* Wine returns the number of bytes actually read instead of an error */
400      ret = LZRead(cfile, buf, uncompressed_data_size);
401      ok(ret == LZERROR_READ, "Expected read-past-EOF to return LZERROR_READ\n");
402   }
403
404   LZClose(cfile);
405
406   ret = DeleteFileA(filename_);
407   ok(ret, "DeleteFileA: error %ld\n", GetLastError());
408 }
409
410 static void test_LZCopy(void)
411 {
412   HANDLE file;
413   DWORD ret;
414   int source, dest;
415   OFSTRUCT stest, dtest;
416   BOOL retok;
417
418   /* Create the compressed file. */
419   file = CreateFileA(filename_, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0);
420   ok(file != INVALID_HANDLE_VALUE, 
421      "CreateFileA: error %ld\n", GetLastError());
422   retok = WriteFile(file, compressed_file, compressed_file_size, &ret, 0);
423   ok( retok, "WriteFile error %ld\n", GetLastError());
424   ok(ret == compressed_file_size, "Wrote wrong number of bytes\n");
425   CloseHandle(file);
426
427   source = LZOpenFileA(filename_, &stest, OF_READ);
428   ok(source >= 0, "LZOpenFileA failed on compressed file\n");
429   dest = LZOpenFileA(filename2, &dtest, OF_CREATE);
430   ok(dest >= 0, "LZOpenFileA failed on creating new file %d\n", dest);
431
432   ret = LZCopy(source, dest);
433   ok(ret > 0, "LZCopy error\n");
434
435   LZClose(source);
436   LZClose(dest);
437
438   file = CreateFileA(filename2, GENERIC_READ, 0, NULL, OPEN_EXISTING,
439                     0, 0);
440   ok(file != INVALID_HANDLE_VALUE,
441      "CreateFileA: error %ld\n", GetLastError());
442
443   retok = ReadFile(file, buf, uncompressed_data_size*2, &ret, 0);
444   ok( retok && ret == uncompressed_data_size, "ReadFile: error %ld\n", GetLastError());
445   /* Compare what we read with what we think we should read. */
446   ok(!memcmp(buf, uncompressed_data, uncompressed_data_size),
447      "buffer contents mismatch\n");
448   CloseHandle(file);
449
450   ret = DeleteFileA(filename_);
451   ok(ret, "DeleteFileA: error %ld\n", GetLastError());
452   ret = DeleteFileA(filename2);
453   ok(ret, "DeleteFileA: error %ld\n", GetLastError());
454 }
455
456 static void create_fileW(WCHAR *fnameW)
457 {
458   INT file;
459   OFSTRUCT ofs;
460   DWORD retval;
461
462   file = LZOpenFileW(fnameW, &ofs, OF_CREATE);
463   ok(file >= 0, "LZOpenFileW failed on creation\n");
464   LZClose(file);
465   retval = GetFileAttributesW(fnameW);
466   ok(retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributesW('%s'): error %ld\n", ofs.szPathName, GetLastError());
467 }
468
469 static void delete_fileW(WCHAR *fnameW)
470 {
471   INT file;
472   OFSTRUCT ofs;
473   DWORD retval;
474
475   file = LZOpenFileW(fnameW, &ofs, OF_DELETE);
476   ok(file >= 0, "LZOpenFileW failed on delete\n");
477   LZClose(file);
478   retval = GetFileAttributesW(fnameW);
479   ok(retval == INVALID_FILE_ATTRIBUTES, "GetFileAttributesW succeeded on deleted file ('%s')\n", ofs.szPathName);
480 }
481
482 static void test_LZOpenFileW_existing_compressed(void)
483 {
484   OFSTRUCT test;
485   INT file;
486   char expected[MAX_PATH];
487
488   /* Try to open existing compressed files: */
489   create_fileW(filenameW_);
490   create_fileW(dotlessW_);
491   create_fileW(extlessW_);
492   create_fileW(_terminatedW_);
493
494   full_file_path_name_in_a_CWD(filename_, expected, FALSE);
495   memset(&test, 0xA5, sizeof(test));
496
497   /* a, using 8.3-conformant file name. */
498   file = LZOpenFileW(filenameW, &test, OF_EXIST);
499   /* If the file "foo.xxx" does not exist, LZOpenFileW should then
500      check for the file "foo.xx_" and open that.
501    */
502   ok(file >= 0, "LZOpenFileW failed on switching to a compressed file name\n");
503   ok(test.cBytes == sizeof(OFSTRUCT), 
504      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
505   ok(test.nErrCode == ERROR_SUCCESS, "LZOpenFileW set test.nErrCode to %d\n", 
506      test.nErrCode);
507   /* Note that W-function returns A-string by a OFSTRUCT.szPathName: */
508   ok(lstrcmpA(test.szPathName, expected) == 0, 
509      "LZOpenFileW returned '%s', but was expected to return '%s'\n", 
510      test.szPathName, expected);
511   LZClose(file);
512
513   memset(&test, 0xA5, sizeof(test));
514   full_file_path_name_in_a_CWD(dotless_, expected, FALSE);
515
516   /* b, using dotless file name. */
517   file = LZOpenFileW(dotlessW, &test, OF_EXIST);
518   ok(file >= 0, "LZOpenFileW failed on switching to a compressed file name\n");
519   ok(test.cBytes == sizeof(OFSTRUCT), 
520      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
521   ok(test.nErrCode == ERROR_SUCCESS, "LZOpenFileW set test.nErrCode to %d\n", 
522      test.nErrCode);
523   /* Note that W-function returns A-string by a OFSTRUCT.szPathName: */
524   ok(lstrcmpA(test.szPathName, expected) == 0, 
525      "LZOpenFileW returned '%s', but was expected to return '%s'\n", 
526      test.szPathName, expected);
527   LZClose(file);
528
529   memset(&test, 0xA5, sizeof(test));
530   full_file_path_name_in_a_CWD(extless_, expected, FALSE);
531
532   /* c, using extensionless file name. */
533   file = LZOpenFileW(extlessW, &test, OF_EXIST);
534   ok(file >= 0, "LZOpenFileW failed on switching to a compressed file name\n");
535   ok(test.cBytes == sizeof(OFSTRUCT), 
536      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
537   ok(test.nErrCode == ERROR_SUCCESS, "LZOpenFileW set test.nErrCode to %d\n", 
538      test.nErrCode);
539   /* Note that W-function returns A-string by a OFSTRUCT.szPathName: */
540   ok(lstrcmpA(test.szPathName, expected) == 0, 
541      "LZOpenFileW returned '%s', but was expected to return '%s'\n", 
542      test.szPathName, expected);
543   LZClose(file);
544
545   memset(&test, 0xA5, sizeof(test));
546   full_file_path_name_in_a_CWD(_terminated_, expected, FALSE);
547
548   /* d, using underscore-terminated file name. */
549   file = LZOpenFileW(_terminatedW, &test, OF_EXIST);
550   ok(file >= 0, "LZOpenFileW failed on switching to a compressed file name\n");
551   ok(test.cBytes == sizeof(OFSTRUCT), 
552      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
553   ok(test.nErrCode == ERROR_SUCCESS, "LZOpenFileW set test.nErrCode to %d\n", 
554      test.nErrCode);
555   /* Note that W-function returns A-string by a OFSTRUCT.szPathName: */
556   ok(lstrcmpA(test.szPathName, expected) == 0, 
557      "LZOpenFileW returned '%s', but was expected to return '%s'\n", 
558      test.szPathName, expected);
559   LZClose(file);
560
561   delete_fileW(filenameW_);
562   delete_fileW(dotlessW_);
563   delete_fileW(extlessW_);
564   delete_fileW(_terminatedW_);
565 }
566
567 static void test_LZOpenFileW_nonexisting_compressed(void)
568 {
569   OFSTRUCT test;
570   INT file;
571   char expected[MAX_PATH];
572   char filled_0xA5[OFS_MAXPATHNAME];
573
574   /* Try to open nonexisting compressed files: */
575   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
576   memset(&test, 0xA5, sizeof(test));
577   full_file_path_name_in_a_CWD(filename_, expected, FALSE);
578
579   /* a, using 8.3-conformant file name. */
580   file = LZOpenFileW(filenameW, &test, OF_EXIST);
581   /* If the file "foo.xxx" does not exist, LZOpenFileA should then
582      check for the file "foo.xx_" and open that -- at least on some
583      operating systems.  Doesn't seem to on my copy of Win98.   
584    */
585   ok(file == LZERROR_BADINHANDLE, 
586      "LZOpenFileW succeeded on nonexistent file\n");
587   todo_wine
588   ok(test.cBytes == 0xA5, 
589      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
590   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
591      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
592   ok(lstrcmpA(test.szPathName, expected) == 0,
593      "LZOpenFileW returned '%s', but was expected to return '%s' or '%s'\n", 
594      test.szPathName, expected, filled_0xA5);
595
596   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
597   memset(&test, 0xA5, sizeof(test));
598   full_file_path_name_in_a_CWD(dotless_, expected, FALSE);
599
600   /* b, using dotless file name. */
601   file = LZOpenFileW(dotlessW, &test, OF_EXIST);
602   ok(file == LZERROR_BADINHANDLE, 
603      "LZOpenFileW succeeded on nonexistent file\n");
604   todo_wine
605   ok(test.cBytes == 0xA5, 
606      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
607   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
608      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
609   ok(lstrcmpA(test.szPathName, expected) == 0,
610      "LZOpenFileW returned '%s', but was expected to return '%s' or '%s'\n", 
611      test.szPathName, expected, filled_0xA5);
612
613   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
614   memset(&test, 0xA5, sizeof(test));
615   full_file_path_name_in_a_CWD(extless_, expected, FALSE);
616
617   /* c, using extensionless file name. */
618   file = LZOpenFileW(extlessW, &test, OF_EXIST);
619   ok(file == LZERROR_BADINHANDLE, 
620      "LZOpenFileW succeeded on nonexistent file\n");
621   todo_wine
622   ok(test.cBytes == 0xA5, 
623      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
624   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
625      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
626   ok(lstrcmpA(test.szPathName, expected) == 0,
627      "LZOpenFileW returned '%s', but was expected to return '%s' or '%s'\n", 
628      test.szPathName, expected, filled_0xA5);
629
630   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
631   memset(&test, 0xA5, sizeof(test));
632   full_file_path_name_in_a_CWD(_terminated_, expected, FALSE);
633
634   /* d, using underscore-terminated file name. */
635   file = LZOpenFileW(_terminatedW, &test, OF_EXIST);
636   ok(file == LZERROR_BADINHANDLE, 
637      "LZOpenFileW succeeded on nonexistent file\n");
638   todo_wine
639   ok(test.cBytes == 0xA5, 
640      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
641   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
642      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
643   ok(lstrcmpA(test.szPathName, expected) == 0,
644      "LZOpenFileW returned '%s', but was expected to return '%s' or '%s'\n",
645      test.szPathName, expected, filled_0xA5);
646 }
647
648 static void test_LZOpenFileW(void)
649 {
650   OFSTRUCT test;
651   DWORD retval;
652   INT file;
653   static WCHAR badfilenameW[] = {'b','a','d','f','i','l','e','n','a','m','e','.','x','t','n',0};
654
655   SetLastError(0xfaceabee);
656   /* Check for nonexistent file. */
657   file = LZOpenFileW(badfilenameW, &test, OF_READ);
658   if(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
659   {
660     trace("LZOpenFileW call not implemented, skipping rest of the test\n");
661     return;
662   }
663   ok(file == LZERROR_BADINHANDLE, 
664      "LZOpenFileW succeeded on nonexistent file\n");
665   LZClose(file);
666
667   /* Create an empty file. */
668   file = LZOpenFileW(filenameW_, &test, OF_CREATE);
669   ok(file >= 0, "LZOpenFile failed on creation\n");
670   LZClose(file);
671   retval = GetFileAttributesW(filenameW_);
672   ok(retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributes: error %ld\n", 
673     GetLastError());
674
675   /* Check various opening options. */
676   file = LZOpenFileW(filenameW_, &test, OF_READ);
677   ok(file >= 0, "LZOpenFileW failed on read\n");
678   LZClose(file);
679   file = LZOpenFileW(filenameW_, &test, OF_WRITE);
680   ok(file >= 0, "LZOpenFileW failed on write\n");
681   LZClose(file);
682   file = LZOpenFileW(filenameW_, &test, OF_READWRITE);
683   ok(file >= 0, "LZOpenFileW failed on read/write\n");
684   LZClose(file);
685   file = LZOpenFileW(filenameW_, &test, OF_EXIST);
686   ok(file >= 0, "LZOpenFileW failed on read/write\n");
687   LZClose(file);
688
689   /* Delete the file then make sure it doesn't exist anymore. */
690   file = LZOpenFileW(filenameW_, &test, OF_DELETE);
691   ok(file >= 0, "LZOpenFileW failed on delete\n");
692   LZClose(file);
693
694   retval = GetFileAttributesW(filenameW_);
695   ok(retval == INVALID_FILE_ATTRIBUTES, 
696      "GetFileAttributesW succeeded on deleted file\n");
697
698   test_LZOpenFileW_existing_compressed();
699   test_LZOpenFileW_nonexisting_compressed();
700 }
701
702
703 START_TEST(lzexpand_main)
704 {
705   buf = malloc(uncompressed_data_size * 2);
706   test_LZOpenFileA();
707   test_LZOpenFileW();
708   test_LZRead();
709   test_LZCopy();
710   free(buf);
711 }