msi: Set all folders' source paths to the root directory if the source type is compre...
[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      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
235   ok(test.nErrCode == 0, "LZOpenFileA set test.nErrCode to %d\n", 
236      test.nErrCode);
237   ok(lstrcmpA(test.szPathName, expected) == 0 ||
238      lstrcmpA(test.szPathName, short_expected) == 0, /* Win9x */
239      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n", 
240      test.szPathName, expected, short_expected);
241   LZClose(file);
242
243   delete_file(filename_);
244   delete_file(dotless_);
245   delete_file(extless_);
246   delete_file(_terminated_);
247 }
248
249 static void test_LZOpenFileA_nonexisting_compressed(void)
250 {
251   OFSTRUCT test;
252   INT file;
253   char expected[MAX_PATH];
254   char filled_0xA5[OFS_MAXPATHNAME];
255
256   /* Try to open nonexisting compressed files: */
257   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
258   memset(&test, 0xA5, sizeof(test));
259   full_file_path_name_in_a_CWD(filename_, expected, FALSE);
260   SetLastError(0xfaceabee);
261
262   /* a, using 8.3-conformant file name. */
263   file = LZOpenFileA(filename, &test, OF_EXIST);
264   /* If the file "foo.xxx" does not exist, LZOpenFileA should then
265      check for the file "foo.xx_" and open that -- at least on some
266      operating systems.  Doesn't seem to on my copy of Win98.   
267    */
268   ok(file == LZERROR_BADINHANDLE, 
269      "LZOpenFileA succeeded on nonexistent file\n");
270   ok(GetLastError() == ERROR_FILE_NOT_FOUND,
271      "GetLastError() returns %d\n", GetLastError());
272   todo_wine
273   ok(test.cBytes == 0xA5, 
274      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
275   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
276      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
277   ok(lstrcmpA(test.szPathName, expected) == 0 ||
278      strncmp(test.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, /* Win9x */
279      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n", 
280      test.szPathName, expected, filled_0xA5);
281
282   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
283   memset(&test, 0xA5, sizeof(test));
284   full_file_path_name_in_a_CWD(dotless_, expected, FALSE);
285   SetLastError(0xfaceabee);
286
287   /* b, using dotless file name. */
288   file = LZOpenFileA(dotless, &test, OF_EXIST);
289   ok(file == LZERROR_BADINHANDLE, 
290      "LZOpenFileA succeeded on nonexistent file\n");
291   ok(GetLastError() == ERROR_FILE_NOT_FOUND,
292      "GetLastError() returns %d\n", GetLastError());
293   todo_wine
294   ok(test.cBytes == 0xA5, 
295      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
296   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
297      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
298   ok(lstrcmpA(test.szPathName, expected) == 0 ||
299      strncmp(test.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, /* Win9x */
300      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n", 
301      test.szPathName, expected, filled_0xA5);
302
303   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
304   memset(&test, 0xA5, sizeof(test));
305   full_file_path_name_in_a_CWD(extless_, expected, FALSE);
306   SetLastError(0xfaceabee);
307
308   /* c, using extensionless file name. */
309   file = LZOpenFileA(extless, &test, OF_EXIST);
310   ok(file == LZERROR_BADINHANDLE, 
311      "LZOpenFileA succeeded on nonexistent file\n");
312   ok(GetLastError() == ERROR_FILE_NOT_FOUND,
313      "GetLastError() returns %d\n", GetLastError());
314   todo_wine
315   ok(test.cBytes == 0xA5, 
316      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
317   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
318      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
319   ok(lstrcmpA(test.szPathName, expected) == 0 ||
320      strncmp(test.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, /* Win9x */
321      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n", 
322      test.szPathName, expected, filled_0xA5);
323
324   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
325   memset(&test, 0xA5, sizeof(test));
326   full_file_path_name_in_a_CWD(_terminated_, expected, FALSE);
327   SetLastError(0xfaceabee);
328
329   /* d, using underscore-terminated file name. */
330   file = LZOpenFileA(_terminated, &test, OF_EXIST);
331   ok(file == LZERROR_BADINHANDLE, 
332      "LZOpenFileA succeeded on nonexistent file\n");
333   ok(GetLastError() == ERROR_FILE_NOT_FOUND,
334      "GetLastError() returns %d\n", GetLastError());
335   todo_wine
336   ok(test.cBytes == 0xA5, 
337      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
338   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
339      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
340   ok(lstrcmpA(test.szPathName, expected) == 0 ||
341      strncmp(test.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, /* Win9x */
342      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n", 
343      test.szPathName, expected, filled_0xA5);
344 }
345
346 static void test_LZOpenFileA(void)
347 {
348   OFSTRUCT test;
349   DWORD retval;
350   INT file;
351   static char badfilename_[] = "badfilename_";
352   char expected[MAX_PATH];
353   char short_expected[MAX_PATH];
354
355   SetLastError(0xfaceabee);
356   /* Check for nonexistent file. */
357   file = LZOpenFileA(badfilename_, &test, OF_READ);
358   ok(file == LZERROR_BADINHANDLE, 
359      "LZOpenFileA succeeded on nonexistent file\n");
360   ok(GetLastError() == ERROR_FILE_NOT_FOUND, 
361      "GetLastError() returns %d\n", GetLastError());
362   LZClose(file);
363
364   memset(&test, 0xA5, sizeof(test));
365   full_file_path_name_in_a_CWD(filename_, expected, FALSE);
366
367   /* Create an empty file. */
368   file = LZOpenFileA(filename_, &test, OF_CREATE);
369   ok(file >= 0, "LZOpenFileA failed on creation\n");
370   ok(test.cBytes == sizeof(OFSTRUCT),
371      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
372   ok(test.nErrCode == ERROR_SUCCESS ||
373      test.nErrCode == ERROR_FILE_NOT_FOUND, /* win9x */
374      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
375   ok(lstrcmpA(test.szPathName, expected) == 0,
376      "LZOpenFileA returned '%s', but was expected to return '%s'\n",
377      test.szPathName, expected);
378   LZClose(file);
379
380   retval = GetFileAttributesA(filename_);
381   ok(retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %d\n", 
382      GetLastError());
383
384   /* Check various opening options: */
385   memset(&test, 0xA5, sizeof(test));
386   full_file_path_name_in_a_CWD(filename_, short_expected, TRUE);
387
388   /* a, for reading. */
389   file = LZOpenFileA(filename_, &test, OF_READ);
390   ok(file >= 0, "LZOpenFileA failed on read\n");
391   ok(test.cBytes == sizeof(OFSTRUCT),
392      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
393   ok(test.nErrCode == ERROR_SUCCESS,
394      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
395   ok(lstrcmpA(test.szPathName, expected) == 0 ||
396      lstrcmpA(test.szPathName, short_expected) == 0, /* Win9x */
397      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n",
398      test.szPathName, expected, short_expected);
399   LZClose(file);
400
401   memset(&test, 0xA5, sizeof(test));
402
403   /* b, for writing. */
404   file = LZOpenFileA(filename_, &test, OF_WRITE);
405   ok(file >= 0, "LZOpenFileA failed on write\n");
406   ok(test.cBytes == sizeof(OFSTRUCT),
407      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
408   ok(test.nErrCode == ERROR_SUCCESS,
409      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
410   ok(lstrcmpA(test.szPathName, expected) == 0 ||
411      lstrcmpA(test.szPathName, short_expected) == 0, /* Win9x */
412      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n",
413      test.szPathName, expected, short_expected);
414   LZClose(file);
415
416   memset(&test, 0xA5, sizeof(test));
417
418   /* c, for reading and writing. */
419   file = LZOpenFileA(filename_, &test, OF_READWRITE);
420   ok(file >= 0, "LZOpenFileA failed on read/write\n");
421   ok(test.cBytes == sizeof(OFSTRUCT),
422      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
423   ok(test.nErrCode == ERROR_SUCCESS,
424      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
425   ok(lstrcmpA(test.szPathName, expected) == 0 ||
426      lstrcmpA(test.szPathName, short_expected) == 0, /* Win9x */
427      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n",
428      test.szPathName, expected, short_expected);
429   LZClose(file);
430
431   memset(&test, 0xA5, sizeof(test));
432
433   /* d, for checking file existence. */
434   file = LZOpenFileA(filename_, &test, OF_EXIST);
435   ok(file >= 0, "LZOpenFileA failed on read/write\n");
436   ok(test.cBytes == sizeof(OFSTRUCT),
437      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
438   ok(test.nErrCode == ERROR_SUCCESS,
439      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
440   ok(lstrcmpA(test.szPathName, expected) == 0 ||
441      lstrcmpA(test.szPathName, short_expected) == 0, /* Win9x */
442      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n",
443      test.szPathName, expected, short_expected);
444   LZClose(file);
445
446   memset(&test, 0xA5, sizeof(test));
447
448   /* Delete the file then make sure it doesn't exist anymore. */
449   file = LZOpenFileA(filename_, &test, OF_DELETE);
450   ok(file >= 0, "LZOpenFileA failed on delete\n");
451   ok(test.cBytes == sizeof(OFSTRUCT),
452      "LZOpenFileA set test.cBytes to %d\n", test.cBytes);
453   ok(test.nErrCode == ERROR_SUCCESS,
454      "LZOpenFileA set test.nErrCode to %d\n", test.nErrCode);
455   ok(lstrcmpA(test.szPathName, expected) == 0 ||
456      lstrcmpA(test.szPathName, short_expected) == 0, /* Win9x */
457      "LZOpenFileA returned '%s', but was expected to return '%s' or '%s'\n",
458      test.szPathName, expected, short_expected);
459   LZClose(file);
460
461   retval = GetFileAttributesA(filename_);
462   ok(retval == INVALID_FILE_ATTRIBUTES, 
463      "GetFileAttributesA succeeded on deleted file\n");
464
465   test_LZOpenFileA_existing_compressed();
466   test_LZOpenFileA_nonexisting_compressed();
467 }
468
469 static void test_LZRead(void)
470 {
471   HANDLE file;
472   DWORD ret;
473   int cfile;
474   OFSTRUCT test;
475   BOOL retok;
476
477   /* Create the compressed file. */
478   file = CreateFileA(filename_, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0);
479   ok(file != INVALID_HANDLE_VALUE, "Could not create test file\n");
480   retok = WriteFile(file, compressed_file, compressed_file_size, &ret, 0);
481   ok( retok, "WriteFile: error %d\n", GetLastError());
482   ok(ret == compressed_file_size, "Wrote wrong number of bytes with WriteFile?\n");
483   CloseHandle(file);
484
485   cfile = LZOpenFileA(filename_, &test, OF_READ);
486   ok(cfile > 0, "LZOpenFileA failed\n");
487
488   ret = LZRead(cfile, buf, uncompressed_data_size);
489   ok(ret == uncompressed_data_size, "Read wrong number of bytes\n");
490
491   /* Compare what we read with what we think we should read. */
492   ok(memcmp(buf, uncompressed_data, uncompressed_data_size) == 0,
493      "buffer contents mismatch\n");
494
495   todo_wine {
496      /* Wine returns the number of bytes actually read instead of an error */
497      ret = LZRead(cfile, buf, uncompressed_data_size);
498      ok(ret == LZERROR_READ, "Expected read-past-EOF to return LZERROR_READ\n");
499   }
500
501   LZClose(cfile);
502
503   ret = DeleteFileA(filename_);
504   ok(ret, "DeleteFileA: error %d\n", GetLastError());
505 }
506
507 static void test_LZCopy(void)
508 {
509   HANDLE file;
510   DWORD ret;
511   int source, dest;
512   OFSTRUCT stest, dtest;
513   BOOL retok;
514
515   /* Create the compressed file. */
516   file = CreateFileA(filename_, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, 0);
517   ok(file != INVALID_HANDLE_VALUE, 
518      "CreateFileA: error %d\n", GetLastError());
519   retok = WriteFile(file, compressed_file, compressed_file_size, &ret, 0);
520   ok( retok, "WriteFile error %d\n", GetLastError());
521   ok(ret == compressed_file_size, "Wrote wrong number of bytes\n");
522   CloseHandle(file);
523
524   source = LZOpenFileA(filename_, &stest, OF_READ);
525   ok(source >= 0, "LZOpenFileA failed on compressed file\n");
526   dest = LZOpenFileA(filename2, &dtest, OF_CREATE);
527   ok(dest >= 0, "LZOpenFileA failed on creating new file %d\n", dest);
528
529   ret = LZCopy(source, dest);
530   ok(ret > 0, "LZCopy error\n");
531
532   LZClose(source);
533   LZClose(dest);
534
535   file = CreateFileA(filename2, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
536   ok(file != INVALID_HANDLE_VALUE,
537      "CreateFileA: error %d\n", GetLastError());
538
539   retok = ReadFile(file, buf, uncompressed_data_size*2, &ret, 0);
540   ok( retok && ret == uncompressed_data_size, "ReadFile: error %d\n", GetLastError());
541   /* Compare what we read with what we think we should read. */
542   ok(!memcmp(buf, uncompressed_data, uncompressed_data_size),
543      "buffer contents mismatch\n");
544   CloseHandle(file);
545
546   ret = DeleteFileA(filename_);
547   ok(ret, "DeleteFileA: error %d\n", GetLastError());
548   ret = DeleteFileA(filename2);
549   ok(ret, "DeleteFileA: error %d\n", GetLastError());
550 }
551
552 static void create_fileW(WCHAR *fnameW)
553 {
554   INT file;
555   OFSTRUCT ofs;
556   DWORD retval;
557
558   file = LZOpenFileW(fnameW, &ofs, OF_CREATE);
559   ok(file >= 0, "LZOpenFileW failed on creation\n");
560   LZClose(file);
561   retval = GetFileAttributesW(fnameW);
562   ok(retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributesW('%s'): error %d\n", ofs.szPathName, GetLastError());
563 }
564
565 static void delete_fileW(WCHAR *fnameW)
566 {
567   INT file;
568   OFSTRUCT ofs;
569   DWORD retval;
570
571   file = LZOpenFileW(fnameW, &ofs, OF_DELETE);
572   ok(file >= 0, "LZOpenFileW failed on delete\n");
573   LZClose(file);
574   retval = GetFileAttributesW(fnameW);
575   ok(retval == INVALID_FILE_ATTRIBUTES, "GetFileAttributesW succeeded on deleted file ('%s')\n", ofs.szPathName);
576 }
577
578 static void test_LZOpenFileW_existing_compressed(void)
579 {
580   OFSTRUCT test;
581   INT file;
582   char expected[MAX_PATH];
583
584   /* Try to open existing compressed files: */
585   create_fileW(filenameW_);
586   create_fileW(dotlessW_);
587   create_fileW(extlessW_);
588   create_fileW(_terminatedW_);
589
590   full_file_path_name_in_a_CWD(filename_, expected, FALSE);
591   memset(&test, 0xA5, sizeof(test));
592
593   /* a, using 8.3-conformant file name. */
594   file = LZOpenFileW(filenameW, &test, OF_EXIST);
595   /* If the file "foo.xxx" does not exist, LZOpenFileW should then
596      check for the file "foo.xx_" and open that.
597    */
598   ok(file >= 0, "LZOpenFileW failed on switching to a compressed file name\n");
599   ok(test.cBytes == sizeof(OFSTRUCT), 
600      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
601   ok(test.nErrCode == ERROR_SUCCESS, "LZOpenFileW set test.nErrCode to %d\n", 
602      test.nErrCode);
603   /* Note that W-function returns A-string by a OFSTRUCT.szPathName: */
604   ok(lstrcmpA(test.szPathName, expected) == 0, 
605      "LZOpenFileW returned '%s', but was expected to return '%s'\n", 
606      test.szPathName, expected);
607   LZClose(file);
608
609   memset(&test, 0xA5, sizeof(test));
610   full_file_path_name_in_a_CWD(dotless_, expected, FALSE);
611
612   /* b, using dotless file name. */
613   file = LZOpenFileW(dotlessW, &test, OF_EXIST);
614   ok(file >= 0, "LZOpenFileW failed on switching to a compressed file name\n");
615   ok(test.cBytes == sizeof(OFSTRUCT), 
616      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
617   ok(test.nErrCode == ERROR_SUCCESS, "LZOpenFileW set test.nErrCode to %d\n", 
618      test.nErrCode);
619   /* Note that W-function returns A-string by a OFSTRUCT.szPathName: */
620   ok(lstrcmpA(test.szPathName, expected) == 0, 
621      "LZOpenFileW returned '%s', but was expected to return '%s'\n", 
622      test.szPathName, expected);
623   LZClose(file);
624
625   memset(&test, 0xA5, sizeof(test));
626   full_file_path_name_in_a_CWD(extless_, expected, FALSE);
627
628   /* c, using extensionless file name. */
629   file = LZOpenFileW(extlessW, &test, OF_EXIST);
630   ok(file >= 0, "LZOpenFileW failed on switching to a compressed file name\n");
631   ok(test.cBytes == sizeof(OFSTRUCT), 
632      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
633   ok(test.nErrCode == ERROR_SUCCESS, "LZOpenFileW set test.nErrCode to %d\n", 
634      test.nErrCode);
635   /* Note that W-function returns A-string by a OFSTRUCT.szPathName: */
636   ok(lstrcmpA(test.szPathName, expected) == 0, 
637      "LZOpenFileW returned '%s', but was expected to return '%s'\n", 
638      test.szPathName, expected);
639   LZClose(file);
640
641   memset(&test, 0xA5, sizeof(test));
642   full_file_path_name_in_a_CWD(_terminated_, expected, FALSE);
643
644   /* d, using underscore-terminated file name. */
645   file = LZOpenFileW(_terminatedW, &test, OF_EXIST);
646   ok(file >= 0, "LZOpenFileW failed on switching to a compressed file name\n");
647   ok(test.cBytes == sizeof(OFSTRUCT), 
648      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
649   ok(test.nErrCode == ERROR_SUCCESS, "LZOpenFileW set test.nErrCode to %d\n", 
650      test.nErrCode);
651   /* Note that W-function returns A-string by a OFSTRUCT.szPathName: */
652   ok(lstrcmpA(test.szPathName, expected) == 0, 
653      "LZOpenFileW returned '%s', but was expected to return '%s'\n", 
654      test.szPathName, expected);
655   LZClose(file);
656
657   delete_fileW(filenameW_);
658   delete_fileW(dotlessW_);
659   delete_fileW(extlessW_);
660   delete_fileW(_terminatedW_);
661 }
662
663 static void test_LZOpenFileW_nonexisting_compressed(void)
664 {
665   OFSTRUCT test;
666   INT file;
667   char expected[MAX_PATH];
668   char filled_0xA5[OFS_MAXPATHNAME];
669
670   /* Try to open nonexisting compressed files: */
671   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
672   memset(&test, 0xA5, sizeof(test));
673   full_file_path_name_in_a_CWD(filename_, expected, FALSE);
674   SetLastError(0xfaceabee);
675
676   /* a, using 8.3-conformant file name. */
677   file = LZOpenFileW(filenameW, &test, OF_EXIST);
678   /* If the file "foo.xxx" does not exist, LZOpenFileA should then
679      check for the file "foo.xx_" and open that -- at least on some
680      operating systems.  Doesn't seem to on my copy of Win98.   
681    */
682   ok(file == LZERROR_BADINHANDLE, 
683      "LZOpenFileW succeeded on nonexistent file\n");
684   ok(GetLastError() == ERROR_FILE_NOT_FOUND,
685      "GetLastError() returns %d\n", GetLastError());
686   todo_wine
687   ok(test.cBytes == 0xA5, 
688      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
689   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
690      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
691   ok(lstrcmpA(test.szPathName, expected) == 0,
692      "LZOpenFileW returned '%s', but was expected to return '%s' or '%s'\n", 
693      test.szPathName, expected, filled_0xA5);
694
695   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
696   memset(&test, 0xA5, sizeof(test));
697   full_file_path_name_in_a_CWD(dotless_, expected, FALSE);
698   SetLastError(0xfaceabee);
699
700   /* b, using dotless file name. */
701   file = LZOpenFileW(dotlessW, &test, OF_EXIST);
702   ok(file == LZERROR_BADINHANDLE, 
703      "LZOpenFileW succeeded on nonexistent file\n");
704   ok(GetLastError() == ERROR_FILE_NOT_FOUND,
705      "GetLastError() returns %d\n", GetLastError());
706   todo_wine
707   ok(test.cBytes == 0xA5, 
708      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
709   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
710      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
711   ok(lstrcmpA(test.szPathName, expected) == 0,
712      "LZOpenFileW returned '%s', but was expected to return '%s' or '%s'\n", 
713      test.szPathName, expected, filled_0xA5);
714
715   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
716   memset(&test, 0xA5, sizeof(test));
717   full_file_path_name_in_a_CWD(extless_, expected, FALSE);
718   SetLastError(0xfaceabee);
719
720   /* c, using extensionless file name. */
721   file = LZOpenFileW(extlessW, &test, OF_EXIST);
722   ok(file == LZERROR_BADINHANDLE, 
723      "LZOpenFileW succeeded on nonexistent file\n");
724   ok(GetLastError() == ERROR_FILE_NOT_FOUND,
725      "GetLastError() returns %d\n", GetLastError());
726   todo_wine
727   ok(test.cBytes == 0xA5, 
728      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
729   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
730      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
731   ok(lstrcmpA(test.szPathName, expected) == 0,
732      "LZOpenFileW returned '%s', but was expected to return '%s' or '%s'\n", 
733      test.szPathName, expected, filled_0xA5);
734
735   memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
736   memset(&test, 0xA5, sizeof(test));
737   full_file_path_name_in_a_CWD(_terminated_, expected, FALSE);
738   SetLastError(0xfaceabee);
739
740   /* d, using underscore-terminated file name. */
741   file = LZOpenFileW(_terminatedW, &test, OF_EXIST);
742   ok(file == LZERROR_BADINHANDLE, 
743      "LZOpenFileW succeeded on nonexistent file\n");
744   ok(GetLastError() == ERROR_FILE_NOT_FOUND,
745      "GetLastError() returns %d\n", GetLastError());
746   todo_wine
747   ok(test.cBytes == 0xA5, 
748      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
749   ok(test.nErrCode == ERROR_FILE_NOT_FOUND, 
750      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
751   ok(lstrcmpA(test.szPathName, expected) == 0,
752      "LZOpenFileW returned '%s', but was expected to return '%s' or '%s'\n",
753      test.szPathName, expected, filled_0xA5);
754 }
755
756 static void test_LZOpenFileW(void)
757 {
758   OFSTRUCT test;
759   DWORD retval;
760   INT file;
761   static WCHAR badfilenameW[] = {'b','a','d','f','i','l','e','n','a','m','e','.','x','t','n',0};
762   char expected[MAX_PATH];
763
764   SetLastError(0xfaceabee);
765   /* Check for nonexistent file. */
766   file = LZOpenFileW(badfilenameW, &test, OF_READ);
767   ok(GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_CALL_NOT_IMPLEMENTED,
768      "GetLastError() returns %d\n", GetLastError());
769   if(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
770   {
771     trace("LZOpenFileW call not implemented, skipping rest of the test\n");
772     return;
773   }
774   ok(file == LZERROR_BADINHANDLE, "LZOpenFileW succeeded on nonexistent file\n");
775   LZClose(file);
776
777   memset(&test, 0xA5, sizeof(test));
778   full_file_path_name_in_a_CWD(filename_, expected, FALSE);
779
780   /* Create an empty file. */
781   file = LZOpenFileW(filenameW_, &test, OF_CREATE);
782   ok(file >= 0, "LZOpenFile failed on creation\n");
783   ok(test.cBytes == sizeof(OFSTRUCT),
784      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
785   ok(test.nErrCode == ERROR_SUCCESS,
786      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
787   ok(lstrcmpA(test.szPathName, expected) == 0,
788      "LZOpenFileW returned '%s', but was expected to return '%s'\n",
789      test.szPathName, expected);
790   LZClose(file);
791
792   retval = GetFileAttributesW(filenameW_);
793   ok(retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributes: error %d\n", 
794     GetLastError());
795
796   /* Check various opening options: */
797   memset(&test, 0xA5, sizeof(test));
798
799   /* a, for reading. */
800   file = LZOpenFileW(filenameW_, &test, OF_READ);
801   ok(file >= 0, "LZOpenFileW failed on read\n");
802   ok(test.cBytes == sizeof(OFSTRUCT),
803      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
804   ok(test.nErrCode == ERROR_SUCCESS,
805      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
806   ok(lstrcmpA(test.szPathName, expected) == 0,
807      "LZOpenFileW returned '%s', but was expected to return '%s'\n",
808      test.szPathName, expected);
809   LZClose(file);
810
811   memset(&test, 0xA5, sizeof(test));
812
813   /* b, for writing. */
814   file = LZOpenFileW(filenameW_, &test, OF_WRITE);
815   ok(file >= 0, "LZOpenFileW failed on write\n");
816   ok(test.cBytes == sizeof(OFSTRUCT),
817      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
818   ok(test.nErrCode == ERROR_SUCCESS,
819      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
820   ok(lstrcmpA(test.szPathName, expected) == 0,
821      "LZOpenFileW returned '%s', but was expected to return '%s'\n",
822      test.szPathName, expected);
823   LZClose(file);
824
825   memset(&test, 0xA5, sizeof(test));
826
827   /* c, for reading and writing. */
828   file = LZOpenFileW(filenameW_, &test, OF_READWRITE);
829   ok(file >= 0, "LZOpenFileW failed on read/write\n");
830   ok(test.cBytes == sizeof(OFSTRUCT),
831      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
832   ok(test.nErrCode == ERROR_SUCCESS,
833      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
834   ok(lstrcmpA(test.szPathName, expected) == 0,
835      "LZOpenFileW returned '%s', but was expected to return '%s'\n",
836      test.szPathName, expected);
837   LZClose(file);
838
839   memset(&test, 0xA5, sizeof(test));
840
841   /* d, for checking file existence. */
842   file = LZOpenFileW(filenameW_, &test, OF_EXIST);
843   ok(file >= 0, "LZOpenFileW failed on read/write\n");
844   ok(test.cBytes == sizeof(OFSTRUCT),
845      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
846   ok(test.nErrCode == ERROR_SUCCESS,
847      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
848   ok(lstrcmpA(test.szPathName, expected) == 0,
849      "LZOpenFileW returned '%s', but was expected to return '%s'\n",
850      test.szPathName, expected);
851   LZClose(file);
852
853   memset(&test, 0xA5, sizeof(test));
854
855   /* Delete the file then make sure it doesn't exist anymore. */
856   file = LZOpenFileW(filenameW_, &test, OF_DELETE);
857   ok(file >= 0, "LZOpenFileW failed on delete\n");
858   ok(test.cBytes == sizeof(OFSTRUCT),
859      "LZOpenFileW set test.cBytes to %d\n", test.cBytes);
860   ok(test.nErrCode == ERROR_SUCCESS,
861      "LZOpenFileW set test.nErrCode to %d\n", test.nErrCode);
862   ok(lstrcmpA(test.szPathName, expected) == 0,
863      "LZOpenFileW returned '%s', but was expected to return '%s'\n",
864      test.szPathName, expected);
865   LZClose(file);
866
867   retval = GetFileAttributesW(filenameW_);
868   ok(retval == INVALID_FILE_ATTRIBUTES, 
869      "GetFileAttributesW succeeded on deleted file\n");
870
871   test_LZOpenFileW_existing_compressed();
872   test_LZOpenFileW_nonexisting_compressed();
873 }
874
875
876 START_TEST(lzexpand_main)
877 {
878   buf = malloc(uncompressed_data_size * 2);
879   test_LZOpenFileA();
880   test_LZOpenFileW();
881   test_LZRead();
882   test_LZCopy();
883   free(buf);
884 }