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