kernel32/tests: Don't compare the result of llseek or hwrite against HFILE_ERROR.
[wine] / dlls / kernel32 / tests / file.c
1 /*
2  * Unit tests for file functions in Wine
3  *
4  * Copyright (c) 2002, 2004 Jakob Eriksson
5  * Copyright (c) 2008 Jeff Zaroyko
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  *
21  */
22
23 /* ReplaceFile requires Windows 2000 or newer */
24 #define _WIN32_WINNT 0x0500
25
26 #include <stdarg.h>
27 #include <stdlib.h>
28 #include <time.h>
29
30 #include "wine/test.h"
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winerror.h"
34
35 static HANDLE (WINAPI *pFindFirstFileExA)(LPCSTR,FINDEX_INFO_LEVELS,LPVOID,FINDEX_SEARCH_OPS,LPVOID,DWORD);
36 static BOOL (WINAPI *pReplaceFileA)(LPCSTR, LPCSTR, LPCSTR, DWORD, LPVOID, LPVOID);
37 static BOOL (WINAPI *pReplaceFileW)(LPCWSTR, LPCWSTR, LPCWSTR, DWORD, LPVOID, LPVOID);
38 static UINT (WINAPI *pGetSystemWindowsDirectoryA)(LPSTR, UINT);
39
40 /* keep filename and filenameW the same */
41 static const char filename[] = "testfile.xxx";
42 static const WCHAR filenameW[] = { 't','e','s','t','f','i','l','e','.','x','x','x',0 };
43 static const char sillytext[] =
44 "en larvig liten text dx \033 gx hej 84 hej 4484 ! \001\033 bla bl\na.. bla bla."
45 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
46 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
47 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
48 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
49 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
50 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
51 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
52 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
53 "sdlkfjasdlkfj a dslkj adsklf  \n  \nasdklf askldfa sdlkf \nsadklf asdklf asdf ";
54
55 static void InitFunctionPointers(void)
56 {
57     HMODULE hkernel32 = GetModuleHandleA("kernel32");
58
59     pFindFirstFileExA=(void*)GetProcAddress(hkernel32, "FindFirstFileExA");
60     pReplaceFileA=(void*)GetProcAddress(hkernel32, "ReplaceFileA");
61     pReplaceFileW=(void*)GetProcAddress(hkernel32, "ReplaceFileW");
62     pGetSystemWindowsDirectoryA=(void*)GetProcAddress(hkernel32, "GetSystemWindowsDirectoryA");
63 }
64
65 static void test__hread( void )
66 {
67     HFILE filehandle;
68     char buffer[10000];
69     long bytes_read;
70     long bytes_wanted;
71     long i;
72     BOOL ret;
73
74     SetFileAttributesA(filename,FILE_ATTRIBUTE_NORMAL); /* be sure to remove stale files */
75     DeleteFileA( filename );
76     filehandle = _lcreat( filename, 0 );
77     if (filehandle == HFILE_ERROR)
78     {
79         ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
80         return;
81     }
82
83     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
84
85     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
86
87     filehandle = _lopen( filename, OF_READ );
88
89     ok( HFILE_ERROR != filehandle, "couldn't open file \"%s\" again (err=%d)\n", filename, GetLastError(  ) );
90
91     bytes_read = _hread( filehandle, buffer, 2 * strlen( sillytext ) );
92
93     ok( lstrlenA( sillytext ) == bytes_read, "file read size error\n" );
94
95     for (bytes_wanted = 0; bytes_wanted < lstrlenA( sillytext ); bytes_wanted++)
96     {
97         ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
98         ok( _hread( filehandle, buffer, bytes_wanted ) == bytes_wanted, "erratic _hread return value\n" );
99         for (i = 0; i < bytes_wanted; i++)
100         {
101             ok( buffer[i] == sillytext[i], "that's not what's written\n" );
102         }
103     }
104
105     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
106
107     ret = DeleteFileA( filename );
108     ok( ret != 0, "DeleteFile failed (%d)\n", GetLastError(  ) );
109 }
110
111
112 static void test__hwrite( void )
113 {
114     HFILE filehandle;
115     char buffer[10000];
116     long bytes_read;
117     long bytes_written;
118     long blocks;
119     long i;
120     char *contents;
121     HLOCAL memory_object;
122     char checksum[1];
123     BOOL ret;
124
125     filehandle = _lcreat( filename, 0 );
126     if (filehandle == HFILE_ERROR)
127     {
128         ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
129         return;
130     }
131
132     ok( HFILE_ERROR != _hwrite( filehandle, "", 0 ), "_hwrite complains\n" );
133
134     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
135
136     filehandle = _lopen( filename, OF_READ );
137
138     bytes_read = _hread( filehandle, buffer, 1);
139
140     ok( 0 == bytes_read, "file read size error\n" );
141
142     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
143
144     filehandle = _lopen( filename, OF_READWRITE );
145
146     bytes_written = 0;
147     checksum[0] = '\0';
148     srand( (unsigned)time( NULL ) );
149     for (blocks = 0; blocks < 100; blocks++)
150     {
151         for (i = 0; i < (long)sizeof( buffer ); i++)
152         {
153             buffer[i] = rand(  );
154             checksum[0] = checksum[0] + buffer[i];
155         }
156         ok( HFILE_ERROR != _hwrite( filehandle, buffer, sizeof( buffer ) ), "_hwrite complains\n" );
157         bytes_written = bytes_written + sizeof( buffer );
158     }
159
160     ok( HFILE_ERROR != _hwrite( filehandle, checksum, 1 ), "_hwrite complains\n" );
161     bytes_written++;
162
163     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
164
165     memory_object = LocalAlloc( LPTR, bytes_written );
166
167     ok( 0 != memory_object, "LocalAlloc fails. (Could be out of memory.)\n" );
168
169     contents = LocalLock( memory_object );
170
171     filehandle = _lopen( filename, OF_READ );
172
173     contents = LocalLock( memory_object );
174
175     ok( NULL != contents, "LocalLock whines\n" );
176
177     ok( bytes_written == _hread( filehandle, contents, bytes_written), "read length differ from write length\n" );
178
179     checksum[0] = '\0';
180     i = 0;
181     do
182     {
183         checksum[0] = checksum[0] + contents[i];
184         i++;
185     }
186     while (i < bytes_written - 1);
187
188     ok( checksum[0] == contents[i], "stored checksum differ from computed checksum\n" );
189
190     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
191
192     ret = DeleteFileA( filename );
193     ok( ret != 0, "DeleteFile failed (%d)\n", GetLastError(  ) );
194 }
195
196
197 static void test__lclose( void )
198 {
199     HFILE filehandle;
200     BOOL ret;
201
202     filehandle = _lcreat( filename, 0 );
203     if (filehandle == HFILE_ERROR)
204     {
205         ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
206         return;
207     }
208
209     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
210
211     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
212
213     ret = DeleteFileA( filename );
214     ok( ret != 0, "DeleteFile failed (%d)\n", GetLastError(  ) );
215 }
216
217
218 static void test__lcreat( void )
219 {
220     HFILE filehandle;
221     char buffer[10000];
222     WIN32_FIND_DATAA search_results;
223     char slashname[] = "testfi/";
224     int err;
225     HANDLE find;
226     BOOL ret;
227
228     filehandle = _lcreat( filename, 0 );
229     if (filehandle == HFILE_ERROR)
230     {
231         ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
232         return;
233     }
234
235     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
236
237     ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
238
239     ok( _hread( filehandle, buffer, strlen( sillytext ) ) ==  lstrlenA( sillytext ), "erratic _hread return value\n" );
240
241     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
242
243     ok( INVALID_HANDLE_VALUE != FindFirstFileA( filename, &search_results ), "should be able to find file\n" );
244
245     ret = DeleteFileA(filename);
246     ok( ret != 0, "DeleteFile failed (%d)\n", GetLastError());
247
248     filehandle = _lcreat( filename, 1 ); /* readonly */
249     ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%d)\n", filename, GetLastError(  ) );
250
251     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite shouldn't be able to write never the less\n" );
252
253     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
254
255     ok( INVALID_HANDLE_VALUE != FindFirstFileA( filename, &search_results ), "should be able to find file\n" );
256
257     ok( 0 == DeleteFileA( filename ), "shouldn't be able to delete a readonly file\n" );
258
259     ok( SetFileAttributesA(filename, FILE_ATTRIBUTE_NORMAL ) != 0, "couldn't change attributes on file\n" );
260
261     ok( DeleteFileA( filename ) != 0, "now it should be possible to delete the file!\n" );
262
263     filehandle = _lcreat( filename, 2 );
264     ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%d)\n", filename, GetLastError(  ) );
265
266     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
267
268     ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
269
270     ok( _hread( filehandle, buffer, strlen( sillytext ) ) ==  lstrlenA( sillytext ), "erratic _hread return value\n" );
271
272     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
273
274     ok( INVALID_HANDLE_VALUE != FindFirstFileA( filename, &search_results ), "should STILL be able to find file\n" );
275
276     ret = DeleteFileA( filename );
277     ok( ret, "DeleteFile failed (%d)\n", GetLastError(  ) );
278
279     filehandle = _lcreat( filename, 4 ); /* SYSTEM file */
280     ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%d)\n", filename, GetLastError(  ) );
281
282     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
283
284     ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
285
286     ok( _hread( filehandle, buffer, strlen( sillytext ) ) ==  lstrlenA( sillytext ), "erratic _hread return value\n" );
287
288     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
289
290     ok( INVALID_HANDLE_VALUE != FindFirstFileA( filename, &search_results ), "should STILL be able to find file\n" );
291
292     ret = DeleteFileA( filename );
293     ok( ret, "DeleteFile failed (%d)\n", GetLastError(  ) );
294
295     filehandle=_lcreat (slashname, 0); /* illegal name */
296     if (HFILE_ERROR==filehandle) {
297       err=GetLastError ();
298       ok (err==ERROR_INVALID_NAME || err==ERROR_PATH_NOT_FOUND,
299           "creating file \"%s\" failed with error %d\n", slashname, err);
300     } else { /* only NT succeeds */
301       _lclose(filehandle);
302       find=FindFirstFileA (slashname, &search_results);
303       if (INVALID_HANDLE_VALUE!=find)
304       {
305         ret = FindClose (find);
306         ok (0 != ret, "FindClose complains (%d)\n", GetLastError ());
307         slashname[strlen(slashname)-1]=0;
308         ok (!strcmp (slashname, search_results.cFileName),
309             "found unexpected name \"%s\"\n", search_results.cFileName);
310         ok (FILE_ATTRIBUTE_ARCHIVE==search_results.dwFileAttributes,
311             "attributes of file \"%s\" are 0x%04x\n", search_results.cFileName,
312             search_results.dwFileAttributes);
313       }
314     ret = DeleteFileA( slashname );
315     ok( ret, "DeleteFile failed (%d)\n", GetLastError(  ) );
316     }
317
318     filehandle=_lcreat (filename, 8); /* illegal attribute */
319     if (HFILE_ERROR==filehandle)
320       ok (0, "couldn't create volume label \"%s\"\n", filename);
321     else {
322       _lclose(filehandle);
323       find=FindFirstFileA (filename, &search_results);
324       if (INVALID_HANDLE_VALUE==find)
325         ok (0, "file \"%s\" not found\n", filename);
326       else {
327         ret = FindClose(find);
328         ok ( 0 != ret, "FindClose complains (%d)\n", GetLastError ());
329         ok (!strcmp (filename, search_results.cFileName),
330             "found unexpected name \"%s\"\n", search_results.cFileName);
331         search_results.dwFileAttributes &= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
332         ok (FILE_ATTRIBUTE_ARCHIVE==search_results.dwFileAttributes,
333             "attributes of file \"%s\" are 0x%04x\n", search_results.cFileName,
334             search_results.dwFileAttributes);
335       }
336     ret = DeleteFileA( filename );
337     ok( ret, "DeleteFile failed (%d)\n", GetLastError(  ) );
338     }
339 }
340
341
342 static void test__llseek( void )
343 {
344     INT i;
345     HFILE filehandle;
346     char buffer[1];
347     long bytes_read;
348     BOOL ret;
349
350     filehandle = _lcreat( filename, 0 );
351     if (filehandle == HFILE_ERROR)
352     {
353         ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
354         return;
355     }
356
357     for (i = 0; i < 400; i++)
358     {
359         ok( _hwrite( filehandle, sillytext, strlen( sillytext ) ) != -1, "_hwrite complains\n" );
360     }
361     ok( _llseek( filehandle, 400 * strlen( sillytext ), FILE_CURRENT ) != -1, "should be able to seek\n" );
362     ok( _llseek( filehandle, 27 + 35 * strlen( sillytext ), FILE_BEGIN ) != -1, "should be able to seek\n" );
363
364     bytes_read = _hread( filehandle, buffer, 1);
365     ok( 1 == bytes_read, "file read size error\n" );
366     ok( buffer[0] == sillytext[27], "_llseek error, it got lost seeking\n" );
367     ok( _llseek( filehandle, -400 * strlen( sillytext ), FILE_END ) != -1, "should be able to seek\n" );
368
369     bytes_read = _hread( filehandle, buffer, 1);
370     ok( 1 == bytes_read, "file read size error\n" );
371     ok( buffer[0] == sillytext[0], "_llseek error, it got lost seeking\n" );
372     ok( _llseek( filehandle, 1000000, FILE_END ) != -1, "should be able to seek past file; poor, poor Windows programmers\n" );
373     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
374
375     ret = DeleteFileA( filename );
376     ok( ret, "DeleteFile failed (%d)\n", GetLastError(  ) );
377 }
378
379
380 static void test__llopen( void )
381 {
382     HFILE filehandle;
383     UINT bytes_read;
384     char buffer[10000];
385     BOOL ret;
386
387     filehandle = _lcreat( filename, 0 );
388     if (filehandle == HFILE_ERROR)
389     {
390         ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
391         return;
392     }
393
394     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
395     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
396
397     filehandle = _lopen( filename, OF_READ );
398     ok( HFILE_ERROR == _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite shouldn't be able to write!\n" );
399     bytes_read = _hread( filehandle, buffer, strlen( sillytext ) );
400     ok( strlen( sillytext )  == bytes_read, "file read size error\n" );
401     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
402
403     filehandle = _lopen( filename, OF_READWRITE );
404     bytes_read = _hread( filehandle, buffer, 2 * strlen( sillytext ) );
405     ok( strlen( sillytext )  == bytes_read, "file read size error\n" );
406     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite should write just fine\n" );
407     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
408
409     filehandle = _lopen( filename, OF_WRITE );
410     ok( HFILE_ERROR == _hread( filehandle, buffer, 1 ), "you should only be able to write this file\n" );
411     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite should write just fine\n" );
412     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
413
414     ret = DeleteFileA( filename );
415     ok( ret, "DeleteFile failed (%d)\n", GetLastError(  ) );
416     /* TODO - add tests for the SHARE modes  -  use two processes to pull this one off */
417 }
418
419
420 static void test__lread( void )
421 {
422     HFILE filehandle;
423     char buffer[10000];
424     long bytes_read;
425     UINT bytes_wanted;
426     UINT i;
427     BOOL ret;
428
429     filehandle = _lcreat( filename, 0 );
430     if (filehandle == HFILE_ERROR)
431     {
432         ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
433         return;
434     }
435
436     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
437
438     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
439
440     filehandle = _lopen( filename, OF_READ );
441
442     ok( HFILE_ERROR != filehandle, "couldn't open file \"%s\" again (err=%d)\n", filename, GetLastError());
443
444     bytes_read = _lread( filehandle, buffer, 2 * strlen( sillytext ) );
445
446     ok( lstrlenA( sillytext ) == bytes_read, "file read size error\n" );
447
448     for (bytes_wanted = 0; bytes_wanted < strlen( sillytext ); bytes_wanted++)
449     {
450         ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
451         ok( _lread( filehandle, buffer, bytes_wanted ) == bytes_wanted, "erratic _hread return value\n" );
452         for (i = 0; i < bytes_wanted; i++)
453         {
454             ok( buffer[i] == sillytext[i], "that's not what's written\n" );
455         }
456     }
457
458     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
459
460     ret = DeleteFileA( filename );
461     ok( ret, "DeleteFile failed (%d)\n", GetLastError(  ) );
462 }
463
464
465 static void test__lwrite( void )
466 {
467     HFILE filehandle;
468     char buffer[10000];
469     long bytes_read;
470     long bytes_written;
471     long blocks;
472     long i;
473     char *contents;
474     HLOCAL memory_object;
475     char checksum[1];
476     BOOL ret;
477
478     filehandle = _lcreat( filename, 0 );
479     if (filehandle == HFILE_ERROR)
480     {
481         ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
482         return;
483     }
484
485     ok( HFILE_ERROR != _lwrite( filehandle, "", 0 ), "_hwrite complains\n" );
486
487     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
488
489     filehandle = _lopen( filename, OF_READ );
490
491     bytes_read = _hread( filehandle, buffer, 1);
492
493     ok( 0 == bytes_read, "file read size error\n" );
494
495     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
496
497     filehandle = _lopen( filename, OF_READWRITE );
498
499     bytes_written = 0;
500     checksum[0] = '\0';
501     srand( (unsigned)time( NULL ) );
502     for (blocks = 0; blocks < 100; blocks++)
503     {
504         for (i = 0; i < (long)sizeof( buffer ); i++)
505         {
506             buffer[i] = rand(  );
507             checksum[0] = checksum[0] + buffer[i];
508         }
509         ok( HFILE_ERROR != _lwrite( filehandle, buffer, sizeof( buffer ) ), "_hwrite complains\n" );
510         bytes_written = bytes_written + sizeof( buffer );
511     }
512
513     ok( HFILE_ERROR != _lwrite( filehandle, checksum, 1 ), "_hwrite complains\n" );
514     bytes_written++;
515
516     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
517
518     memory_object = LocalAlloc( LPTR, bytes_written );
519
520     ok( 0 != memory_object, "LocalAlloc fails, could be out of memory\n" );
521
522     contents = LocalLock( memory_object );
523
524     filehandle = _lopen( filename, OF_READ );
525
526     contents = LocalLock( memory_object );
527
528     ok( NULL != contents, "LocalLock whines\n" );
529
530     ok( bytes_written == _hread( filehandle, contents, bytes_written), "read length differ from write length\n" );
531
532     checksum[0] = '\0';
533     i = 0;
534     do
535     {
536         checksum[0] += contents[i];
537         i++;
538     }
539     while (i < bytes_written - 1);
540
541     ok( checksum[0] == contents[i], "stored checksum differ from computed checksum\n" );
542
543     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
544
545     ret = DeleteFileA( filename );
546     ok( ret, "DeleteFile failed (%d)\n", GetLastError(  ) );
547 }
548
549 static void test_CopyFileA(void)
550 {
551     char temp_path[MAX_PATH];
552     char source[MAX_PATH], dest[MAX_PATH];
553     static const char prefix[] = "pfx";
554     HANDLE hfile;
555     FILETIME ft1, ft2;
556     char buf[10];
557     DWORD ret;
558     BOOL retok;
559
560     ret = GetTempPathA(MAX_PATH, temp_path);
561     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
562     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
563
564     ret = GetTempFileNameA(temp_path, prefix, 0, source);
565     ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
566
567     /* make the source have not zero size */
568     hfile = CreateFileA(source, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
569     ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
570     retok = WriteFile(hfile, prefix, sizeof(prefix), &ret, NULL );
571     ok( retok && ret == sizeof(prefix),
572        "WriteFile error %d\n", GetLastError());
573     ok(GetFileSize(hfile, NULL) == sizeof(prefix), "source file has wrong size\n");
574     /* get the file time and change it to prove the difference */
575     ret = GetFileTime(hfile, NULL, NULL, &ft1);
576     ok( ret, "GetFileTime error %d\n", GetLastError());
577     ft1.dwLowDateTime -= 600000000; /* 60 second */
578     ret = SetFileTime(hfile, NULL, NULL, &ft1);
579     ok( ret, "SetFileTime error %d\n", GetLastError());
580     GetFileTime(hfile, NULL, NULL, &ft1);  /* get the actual time back */
581     CloseHandle(hfile);
582
583     ret = GetTempFileNameA(temp_path, prefix, 0, dest);
584     ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
585
586     SetLastError(0xdeadbeef);
587     ret = CopyFileA(source, dest, TRUE);
588     ok(!ret && GetLastError() == ERROR_FILE_EXISTS,
589        "CopyFileA: unexpected error %d\n", GetLastError());
590
591     ret = CopyFileA(source, dest, FALSE);
592     ok(ret, "CopyFileA: error %d\n", GetLastError());
593
594     /* make sure that destination has correct size */
595     hfile = CreateFileA(dest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
596     ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n");
597     ret = GetFileSize(hfile, NULL);
598     ok(ret == sizeof(prefix), "destination file has wrong size %d\n", ret);
599
600     /* make sure that destination has the same filetime */
601     ret = GetFileTime(hfile, NULL, NULL, &ft2);
602     ok( ret, "GetFileTime error %d\n", GetLastError());
603     ok(CompareFileTime(&ft1, &ft2) == 0, "destination file has wrong filetime\n");
604
605     SetLastError(0xdeadbeef);
606     ret = CopyFileA(source, dest, FALSE);
607     ok(!ret && GetLastError() == ERROR_SHARING_VIOLATION,
608        "CopyFileA: ret = %d, unexpected error %d\n", ret, GetLastError());
609
610     /* make sure that destination still has correct size */
611     ret = GetFileSize(hfile, NULL);
612     ok(ret == sizeof(prefix), "destination file has wrong size %d\n", ret);
613     retok = ReadFile(hfile, buf, sizeof(buf), &ret, NULL);
614     ok( retok && ret == sizeof(prefix),
615        "ReadFile: error %d\n", GetLastError());
616     ok(!memcmp(prefix, buf, sizeof(prefix)), "buffer contents mismatch\n");
617     CloseHandle(hfile);
618
619     ret = DeleteFileA(source);
620     ok(ret, "DeleteFileA: error %d\n", GetLastError());
621     ret = DeleteFileA(dest);
622     ok(ret, "DeleteFileA: error %d\n", GetLastError());
623 }
624
625 static void test_CopyFileW(void)
626 {
627     WCHAR temp_path[MAX_PATH];
628     WCHAR source[MAX_PATH], dest[MAX_PATH];
629     static const WCHAR prefix[] = {'p','f','x',0};
630     DWORD ret;
631
632     ret = GetTempPathW(MAX_PATH, temp_path);
633     if (ret==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
634         return;
635     ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
636     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
637
638     ret = GetTempFileNameW(temp_path, prefix, 0, source);
639     ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
640
641     ret = GetTempFileNameW(temp_path, prefix, 0, dest);
642     ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
643
644     ret = CopyFileW(source, dest, TRUE);
645     ok(!ret && GetLastError() == ERROR_FILE_EXISTS,
646        "CopyFileW: unexpected error %d\n", GetLastError());
647
648     ret = CopyFileW(source, dest, FALSE);
649     ok(ret, "CopyFileW: error %d\n", GetLastError());
650
651     ret = DeleteFileW(source);
652     ok(ret, "DeleteFileW: error %d\n", GetLastError());
653     ret = DeleteFileW(dest);
654     ok(ret, "DeleteFileW: error %d\n", GetLastError());
655 }
656
657 static void test_CreateFileA(void)
658 {
659     HANDLE hFile;
660     char temp_path[MAX_PATH];
661     char filename[MAX_PATH];
662     static const char prefix[] = "pfx";
663     DWORD ret;
664
665     ret = GetTempPathA(MAX_PATH, temp_path);
666     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
667     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
668
669     ret = GetTempFileNameA(temp_path, prefix, 0, filename);
670     ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
671
672     SetLastError(0xdeadbeef);
673     hFile = CreateFileA(filename, GENERIC_READ, 0, NULL,
674                         CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
675     ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS,
676         "CREATE_NEW should fail if file exists and last error value should be ERROR_FILE_EXISTS\n");
677
678     SetLastError(0xdeadbeef);
679     hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
680                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
681     ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
682        "hFile %p, last error %u\n", hFile, GetLastError());
683
684     CloseHandle(hFile);
685
686     SetLastError(0xdeadbeef);
687     hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
688                         OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
689     ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
690        "hFile %p, last error %u\n", hFile, GetLastError());
691
692     CloseHandle(hFile);
693
694     ret = DeleteFileA(filename);
695     ok(ret, "DeleteFileA: error %d\n", GetLastError());
696
697     SetLastError(0xdeadbeef);
698     hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
699                         OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
700     ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == 0,
701        "hFile %p, last error %u\n", hFile, GetLastError());
702
703     CloseHandle(hFile);
704
705     ret = DeleteFileA(filename);
706     ok(ret, "DeleteFileA: error %d\n", GetLastError());
707 }
708
709 static void test_CreateFileW(void)
710 {
711     HANDLE hFile;
712     WCHAR temp_path[MAX_PATH];
713     WCHAR filename[MAX_PATH];
714     static const WCHAR emptyW[]={'\0'};
715     static const WCHAR prefix[] = {'p','f','x',0};
716     static const WCHAR bogus[] = { '\\', '\\', '.', '\\', 'B', 'O', 'G', 'U', 'S', 0 };
717     DWORD ret;
718
719     ret = GetTempPathW(MAX_PATH, temp_path);
720     if (ret==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
721         return;
722     ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
723     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
724
725     ret = GetTempFileNameW(temp_path, prefix, 0, filename);
726     ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
727
728     SetLastError(0xdeadbeef);
729     hFile = CreateFileW(filename, GENERIC_READ, 0, NULL,
730                         CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
731     ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS,
732         "CREATE_NEW should fail if file exists and last error value should be ERROR_FILE_EXISTS\n");
733
734     SetLastError(0xdeadbeef);
735     hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
736                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
737     ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
738        "hFile %p, last error %u\n", hFile, GetLastError());
739
740     CloseHandle(hFile);
741
742     SetLastError(0xdeadbeef);
743     hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
744                         OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
745     ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
746        "hFile %p, last error %u\n", hFile, GetLastError());
747
748     CloseHandle(hFile);
749
750     ret = DeleteFileW(filename);
751     ok(ret, "DeleteFileW: error %d\n", GetLastError());
752
753     SetLastError(0xdeadbeef);
754     hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
755                         OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
756     ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == 0,
757        "hFile %p, last error %u\n", hFile, GetLastError());
758
759     CloseHandle(hFile);
760
761     ret = DeleteFileW(filename);
762     ok(ret, "DeleteFileW: error %d\n", GetLastError());
763
764     if (0)
765     {
766         /* this crashes on NT4.0 */
767         hFile = CreateFileW(NULL, GENERIC_READ, 0, NULL,
768                             CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
769         ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
770            "CreateFileW(NULL) returned ret=%p error=%u\n",hFile,GetLastError());
771     }
772
773     hFile = CreateFileW(emptyW, GENERIC_READ, 0, NULL,
774                         CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
775     ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
776        "CreateFileW(\"\") returned ret=%p error=%d\n",hFile,GetLastError());
777
778     /* test the result of opening a nonexistent driver name */
779     hFile = CreateFileW(bogus, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
780                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
781     ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND,
782        "CreateFileW on invalid VxD name returned ret=%p error=%d\n",hFile,GetLastError());
783
784     ret = CreateDirectoryW(filename, NULL);
785     ok(ret == TRUE, "couldn't create temporary directory\n");
786     hFile = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
787                         OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL);
788     ok(hFile != INVALID_HANDLE_VALUE,
789        "expected CreateFile to succeed on existing directory, error: %d\n", GetLastError());
790     CloseHandle(hFile);
791     ret = RemoveDirectoryW(filename);
792     ok(ret, "DeleteFileW: error %d\n", GetLastError());
793 }
794
795 static void test_GetTempFileNameA(void)
796 {
797     UINT result;
798     char out[MAX_PATH];
799     char expected[MAX_PATH + 10];
800     char windowsdir[MAX_PATH + 10];
801     char windowsdrive[3];
802
803     result = GetWindowsDirectory(windowsdir, sizeof(windowsdir));
804     ok(result < sizeof(windowsdir), "windowsdir is abnormally long!\n");
805     ok(result != 0, "GetWindowsDirectory: error %d\n", GetLastError());
806
807     /* If the Windows directory is the root directory, it ends in backslash, not else. */
808     if (strlen(windowsdir) != 3) /* As in  "C:\"  or  "F:\"  */
809     {
810         strcat(windowsdir, "\\");
811     }
812
813     windowsdrive[0] = windowsdir[0];
814     windowsdrive[1] = windowsdir[1];
815     windowsdrive[2] = '\0';
816
817     result = GetTempFileNameA(windowsdrive, "abc", 1, out);
818     ok(result != 0, "GetTempFileNameA: error %d\n", GetLastError());
819     ok(((out[0] == windowsdrive[0]) && (out[1] == ':')) && (out[2] == '\\'),
820        "GetTempFileNameA: first three characters should be %c:\\, string was actually %s\n",
821        windowsdrive[0], out);
822
823     result = GetTempFileNameA(windowsdir, "abc", 2, out);
824     ok(result != 0, "GetTempFileNameA: error %d\n", GetLastError());
825     expected[0] = '\0';
826     strcat(expected, windowsdir);
827     strcat(expected, "abc2.tmp");
828     ok(lstrcmpiA(out, expected) == 0, "GetTempFileNameA: Unexpected output \"%s\" vs \"%s\"\n",
829        out, expected);
830 }
831
832 static void test_DeleteFileA( void )
833 {
834     BOOL ret;
835
836     ret = DeleteFileA(NULL);
837     ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER ||
838                 GetLastError() == ERROR_PATH_NOT_FOUND),
839        "DeleteFileA(NULL) returned ret=%d error=%d\n",ret,GetLastError());
840
841     ret = DeleteFileA("");
842     ok(!ret && (GetLastError() == ERROR_PATH_NOT_FOUND ||
843                 GetLastError() == ERROR_BAD_PATHNAME),
844        "DeleteFileA(\"\") returned ret=%d error=%d\n",ret,GetLastError());
845
846     ret = DeleteFileA("nul");
847     ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
848                 GetLastError() == ERROR_INVALID_PARAMETER ||
849                 GetLastError() == ERROR_ACCESS_DENIED ||
850                 GetLastError() == ERROR_INVALID_FUNCTION),
851        "DeleteFileA(\"nul\") returned ret=%d error=%d\n",ret,GetLastError());
852 }
853
854 static void test_DeleteFileW( void )
855 {
856     BOOL ret;
857     WCHAR pathW[MAX_PATH];
858     WCHAR pathsubW[MAX_PATH];
859     static const WCHAR dirW[] = {'d','e','l','e','t','e','f','i','l','e',0};
860     static const WCHAR subdirW[] = {'\\','s','u','b',0};
861     static const WCHAR emptyW[]={'\0'};
862
863     ret = DeleteFileW(NULL);
864     if (ret==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
865         return;
866     ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND,
867        "DeleteFileW(NULL) returned ret=%d error=%d\n",ret,GetLastError());
868
869     ret = DeleteFileW(emptyW);
870     ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND,
871        "DeleteFileW(\"\") returned ret=%d error=%d\n",ret,GetLastError());
872
873     /* test DeleteFile on empty directory */
874     ret = GetTempPathW(MAX_PATH, pathW);
875     if (ret + sizeof(dirW)/sizeof(WCHAR)-1 + sizeof(subdirW)/sizeof(WCHAR)-1 >= MAX_PATH)
876     {
877         ok(0, "MAX_PATH exceeded in constructing paths\n");
878         return;
879     }
880     lstrcatW(pathW, dirW);
881     lstrcpyW(pathsubW, pathW);
882     lstrcatW(pathsubW, subdirW);
883     ret = CreateDirectoryW(pathW, NULL);
884     ok(ret == TRUE, "couldn't create directory deletefile\n");
885     ret = DeleteFileW(pathW);
886     ok(ret == FALSE, "DeleteFile should fail for empty directories\n");
887     ret = RemoveDirectoryW(pathW);
888     ok(ret == TRUE, "expected to remove directory deletefile\n");
889
890     /* test DeleteFile on non-empty directory */
891     ret = CreateDirectoryW(pathW, NULL);
892     ok(ret == TRUE, "couldn't create directory deletefile\n");
893     ret = CreateDirectoryW(pathsubW, NULL);
894     ok(ret == TRUE, "couldn't create directory deletefile\\sub\n");
895     ret = DeleteFileW(pathW);
896     ok(ret == FALSE, "DeleteFile should fail for non-empty directories\n");
897     ret = RemoveDirectoryW(pathsubW);
898     ok(ret == TRUE, "expected to remove directory deletefile\\sub\n");
899     ret = RemoveDirectoryW(pathW);
900     ok(ret == TRUE, "expected to remove directory deletefile\n");
901 }
902
903 #define IsDotDir(x)     ((x[0] == '.') && ((x[1] == 0) || ((x[1] == '.') && (x[2] == 0))))
904
905 static void test_MoveFileA(void)
906 {
907     char tempdir[MAX_PATH];
908     char source[MAX_PATH], dest[MAX_PATH];
909     static const char prefix[] = "pfx";
910     DWORD ret;
911
912     ret = GetTempPathA(MAX_PATH, tempdir);
913     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
914     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
915
916     ret = GetTempFileNameA(tempdir, prefix, 0, source);
917     ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
918
919     ret = GetTempFileNameA(tempdir, prefix, 0, dest);
920     ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
921
922     ret = MoveFileA(source, dest);
923     ok(!ret && GetLastError() == ERROR_ALREADY_EXISTS,
924        "MoveFileA: unexpected error %d\n", GetLastError());
925
926     ret = DeleteFileA(dest);
927     ok(ret, "DeleteFileA: error %d\n", GetLastError());
928
929     ret = MoveFileA(source, dest);
930     ok(ret, "MoveFileA: failed, error %d\n", GetLastError());
931
932     lstrcatA(tempdir, "Remove Me");
933     ret = CreateDirectoryA(tempdir, NULL);
934     ok(ret == TRUE, "CreateDirectoryA failed\n");
935
936     lstrcpyA(source, dest);
937     lstrcpyA(dest, tempdir);
938     lstrcatA(dest, "\\wild?.*");
939     /* FIXME: if we create a file with wildcards we can't delete it now that DeleteFile works correctly */
940     ret = MoveFileA(source, dest);
941     ok(!ret, "MoveFileA: shouldn't move to wildcard file\n");
942     ok(GetLastError() == ERROR_INVALID_NAME || /* NT */
943        GetLastError() == ERROR_FILE_NOT_FOUND, /* Win9x */
944        "MoveFileA: with wildcards, unexpected error %d\n", GetLastError());
945     if (ret || (GetLastError() != ERROR_INVALID_NAME))
946     {
947         WIN32_FIND_DATAA fd;
948         char temppath[MAX_PATH];
949         HANDLE hFind;
950
951         lstrcpyA(temppath, tempdir);
952         lstrcatA(temppath, "\\*.*");
953         hFind = FindFirstFileA(temppath, &fd);
954         if (INVALID_HANDLE_VALUE != hFind)
955         {
956           LPSTR lpName;
957           do
958           {
959             lpName = fd.cAlternateFileName;
960             if (!lpName[0])
961               lpName = fd.cFileName;
962             ok(IsDotDir(lpName), "MoveFileA: wildcards file created!\n");
963           }
964           while (FindNextFileA(hFind, &fd));
965           FindClose(hFind);
966         }
967     }
968     ret = DeleteFileA(source);
969     ok(ret, "DeleteFileA: error %d\n", GetLastError());
970     ret = DeleteFileA(dest);
971     ok(!ret, "DeleteFileA: error %d\n", GetLastError());
972     ret = RemoveDirectoryA(tempdir);
973     ok(ret, "DeleteDirectoryA: error %d\n", GetLastError());
974 }
975
976 static void test_MoveFileW(void)
977 {
978     WCHAR temp_path[MAX_PATH];
979     WCHAR source[MAX_PATH], dest[MAX_PATH];
980     static const WCHAR prefix[] = {'p','f','x',0};
981     DWORD ret;
982
983     ret = GetTempPathW(MAX_PATH, temp_path);
984     if (ret==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
985         return;
986     ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
987     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
988
989     ret = GetTempFileNameW(temp_path, prefix, 0, source);
990     ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
991
992     ret = GetTempFileNameW(temp_path, prefix, 0, dest);
993     ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
994
995     ret = MoveFileW(source, dest);
996     ok(!ret && GetLastError() == ERROR_ALREADY_EXISTS,
997        "CopyFileW: unexpected error %d\n", GetLastError());
998
999     ret = DeleteFileW(source);
1000     ok(ret, "DeleteFileW: error %d\n", GetLastError());
1001     ret = DeleteFileW(dest);
1002     ok(ret, "DeleteFileW: error %d\n", GetLastError());
1003 }
1004
1005 #define PATTERN_OFFSET 0x10
1006
1007 static void test_offset_in_overlapped_structure(void)
1008 {
1009     HANDLE hFile;
1010     OVERLAPPED ov;
1011     DWORD done, offset;
1012     BOOL rc;
1013     BYTE buf[256], pattern[] = "TeSt";
1014     UINT i;
1015     char temp_path[MAX_PATH], temp_fname[MAX_PATH];
1016     BOOL ret;
1017
1018     ret =GetTempPathA(MAX_PATH, temp_path);
1019     ok( ret, "GetTempPathA error %d\n", GetLastError());
1020     ret =GetTempFileNameA(temp_path, "pfx", 0, temp_fname);
1021     ok( ret, "GetTempFileNameA error %d\n", GetLastError());
1022
1023     /*** Write File *****************************************************/
1024
1025     hFile = CreateFileA(temp_fname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
1026     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError());
1027
1028     for(i = 0; i < sizeof(buf); i++) buf[i] = i;
1029     ret = WriteFile(hFile, buf, sizeof(buf), &done, NULL);
1030     ok( ret, "WriteFile error %d\n", GetLastError());
1031     ok(done == sizeof(buf), "expected number of bytes written %u\n", done);
1032
1033     memset(&ov, 0, sizeof(ov));
1034     S(U(ov)).Offset = PATTERN_OFFSET;
1035     S(U(ov)).OffsetHigh = 0;
1036     rc=WriteFile(hFile, pattern, sizeof(pattern), &done, &ov);
1037     /* Win 9x does not support the overlapped I/O on files */
1038     if (rc || GetLastError()!=ERROR_INVALID_PARAMETER) {
1039         ok(rc, "WriteFile error %d\n", GetLastError());
1040         ok(done == sizeof(pattern), "expected number of bytes written %u\n", done);
1041         offset = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
1042         ok(offset == PATTERN_OFFSET + sizeof(pattern), "wrong file offset %d\n", offset);
1043
1044         S(U(ov)).Offset = sizeof(buf) * 2;
1045         S(U(ov)).OffsetHigh = 0;
1046         ret = WriteFile(hFile, pattern, sizeof(pattern), &done, &ov);
1047         ok( ret, "WriteFile error %d\n", GetLastError());
1048         ok(done == sizeof(pattern), "expected number of bytes written %u\n", done);
1049         offset = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
1050         ok(offset == sizeof(buf) * 2 + sizeof(pattern), "wrong file offset %d\n", offset);
1051     }
1052
1053     CloseHandle(hFile);
1054
1055     /*** Read File *****************************************************/
1056
1057     hFile = CreateFileA(temp_fname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
1058     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError());
1059
1060     memset(buf, 0, sizeof(buf));
1061     memset(&ov, 0, sizeof(ov));
1062     S(U(ov)).Offset = PATTERN_OFFSET;
1063     S(U(ov)).OffsetHigh = 0;
1064     rc=ReadFile(hFile, buf, sizeof(pattern), &done, &ov);
1065     /* Win 9x does not support the overlapped I/O on files */
1066     if (rc || GetLastError()!=ERROR_INVALID_PARAMETER) {
1067         ok(rc, "ReadFile error %d\n", GetLastError());
1068         ok(done == sizeof(pattern), "expected number of bytes read %u\n", done);
1069         offset = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
1070         ok(offset == PATTERN_OFFSET + sizeof(pattern), "wrong file offset %d\n", offset);
1071         ok(!memcmp(buf, pattern, sizeof(pattern)), "pattern match failed\n");
1072     }
1073
1074     CloseHandle(hFile);
1075
1076     ret = DeleteFileA(temp_fname);
1077     ok( ret, "DeleteFileA error %d\n", GetLastError());
1078 }
1079
1080 static void test_LockFile(void)
1081 {
1082     HANDLE handle;
1083     DWORD written;
1084     OVERLAPPED overlapped;
1085     int limited_LockFile;
1086     int limited_UnLockFile;
1087     BOOL ret;
1088
1089     handle = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1090                           FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1091                           CREATE_ALWAYS, 0, 0 );
1092     if (handle == INVALID_HANDLE_VALUE)
1093     {
1094         ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
1095         return;
1096     }
1097     ok( WriteFile( handle, sillytext, strlen(sillytext), &written, NULL ), "write failed\n" );
1098
1099     ok( LockFile( handle, 0, 0, 0, 0 ), "LockFile failed\n" );
1100     ok( UnlockFile( handle, 0, 0, 0, 0 ), "UnlockFile failed\n" );
1101
1102     limited_UnLockFile = 0;
1103     if (UnlockFile( handle, 0, 0, 0, 0 ))
1104     {
1105         limited_UnLockFile = 1;
1106     }
1107
1108     ok( LockFile( handle, 10, 0, 20, 0 ), "LockFile 10,20 failed\n" );
1109     /* overlapping locks must fail */
1110     ok( !LockFile( handle, 12, 0, 10, 0 ), "LockFile 12,10 succeeded\n" );
1111     ok( !LockFile( handle, 5, 0, 6, 0 ), "LockFile 5,6 succeeded\n" );
1112     /* non-overlapping locks must succeed */
1113     ok( LockFile( handle, 5, 0, 5, 0 ), "LockFile 5,5 failed\n" );
1114
1115     ok( !UnlockFile( handle, 10, 0, 10, 0 ), "UnlockFile 10,10 succeeded\n" );
1116     ok( UnlockFile( handle, 10, 0, 20, 0 ), "UnlockFile 10,20 failed\n" );
1117     ok( !UnlockFile( handle, 10, 0, 20, 0 ), "UnlockFile 10,20 again succeeded\n" );
1118     ok( UnlockFile( handle, 5, 0, 5, 0 ), "UnlockFile 5,5 failed\n" );
1119
1120     S(U(overlapped)).Offset = 100;
1121     S(U(overlapped)).OffsetHigh = 0;
1122     overlapped.hEvent = 0;
1123
1124     /* Test for broken LockFileEx a la Windows 95 OSR2. */
1125     if (LockFileEx( handle, 0, 0, 100, 0, &overlapped ))
1126     {
1127         /* LockFileEx is probably OK, test it more. */
1128         ok( LockFileEx( handle, 0, 0, 100, 0, &overlapped ),
1129             "LockFileEx 100,100 failed\n" );
1130     }
1131
1132     /* overlapping shared locks are OK */
1133     S(U(overlapped)).Offset = 150;
1134     limited_UnLockFile || ok( LockFileEx( handle, 0, 0, 100, 0, &overlapped ), "LockFileEx 150,100 failed\n" );
1135
1136     /* but exclusive is not */
1137     ok( !LockFileEx( handle, LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,
1138                      0, 50, 0, &overlapped ),
1139         "LockFileEx exclusive 150,50 succeeded\n" );
1140     if (!UnlockFileEx( handle, 0, 100, 0, &overlapped ))
1141     { /* UnLockFile is capable. */
1142         S(U(overlapped)).Offset = 100;
1143         ok( !UnlockFileEx( handle, 0, 100, 0, &overlapped ),
1144             "UnlockFileEx 150,100 again succeeded\n" );
1145     }
1146
1147     ret = LockFile( handle, 0, 0x10000000, 0, 0xf0000000 );
1148     if (ret)
1149     {
1150         ok( !LockFile( handle, ~0, ~0, 1, 0 ), "LockFile ~0,1 succeeded\n" );
1151         ok( !LockFile( handle, 0, 0x20000000, 20, 0 ), "LockFile 0x20000000,20 succeeded\n" );
1152         ok( UnlockFile( handle, 0, 0x10000000, 0, 0xf0000000 ), "UnlockFile failed\n" );
1153     }
1154     else  /* win9x */
1155         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong LockFile error %u\n", GetLastError() );
1156
1157     /* wrap-around lock should not do anything */
1158     /* (but still succeeds on NT4 so we don't check result) */
1159     LockFile( handle, 0, 0x10000000, 0, 0xf0000001 );
1160
1161     limited_LockFile = 0;
1162     if (!LockFile( handle, ~0, ~0, 1, 0 ))
1163     {
1164         limited_LockFile = 1;
1165     }
1166
1167     limited_UnLockFile || ok( UnlockFile( handle, ~0, ~0, 1, 0 ), "Unlockfile ~0,1 failed\n" );
1168
1169     /* zero-byte lock */
1170     ok( LockFile( handle, 100, 0, 0, 0 ), "LockFile 100,0 failed\n" );
1171     limited_LockFile || ok( !LockFile( handle, 98, 0, 4, 0 ), "LockFile 98,4 succeeded\n" );
1172     ok( LockFile( handle, 90, 0, 10, 0 ), "LockFile 90,10 failed\n" );
1173     limited_LockFile || ok( !LockFile( handle, 100, 0, 10, 0 ), "LockFile 100,10 failed\n" );
1174
1175     ok( UnlockFile( handle, 90, 0, 10, 0 ), "UnlockFile 90,10 failed\n" );
1176     !ok( UnlockFile( handle, 100, 0, 10, 0 ), "UnlockFile 100,10 failed\n" );
1177
1178     ok( UnlockFile( handle, 100, 0, 0, 0 ), "UnlockFile 100,0 failed\n" );
1179
1180     CloseHandle( handle );
1181     DeleteFileA( filename );
1182 }
1183
1184 static inline int is_sharing_compatible( DWORD access1, DWORD sharing1, DWORD access2, DWORD sharing2, BOOL is_win9x )
1185 {
1186     if (!is_win9x)
1187     {
1188         if (!access1) sharing1 = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
1189         if (!access2) sharing2 = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
1190     }
1191     else
1192     {
1193         access1 &= ~DELETE;
1194         if (!access1) access1 = GENERIC_READ;
1195
1196         access2 &= ~DELETE;
1197         if (!access2) access2 = GENERIC_READ;
1198     }
1199
1200     if ((access1 & GENERIC_READ) && !(sharing2 & FILE_SHARE_READ)) return 0;
1201     if ((access1 & GENERIC_WRITE) && !(sharing2 & FILE_SHARE_WRITE)) return 0;
1202     if ((access1 & DELETE) && !(sharing2 & FILE_SHARE_DELETE)) return 0;
1203     if ((access2 & GENERIC_READ) && !(sharing1 & FILE_SHARE_READ)) return 0;
1204     if ((access2 & GENERIC_WRITE) && !(sharing1 & FILE_SHARE_WRITE)) return 0;
1205     if ((access2 & DELETE) && !(sharing1 & FILE_SHARE_DELETE)) return 0;
1206     return 1;
1207 }
1208
1209 static void test_file_sharing(void)
1210 {
1211     static const DWORD access_modes[] =
1212         { 0, GENERIC_READ, GENERIC_WRITE, GENERIC_READ|GENERIC_WRITE,
1213           DELETE, GENERIC_READ|DELETE, GENERIC_WRITE|DELETE, GENERIC_READ|GENERIC_WRITE|DELETE };
1214     static const DWORD sharing_modes[] =
1215         { 0, FILE_SHARE_READ,
1216           FILE_SHARE_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
1217           FILE_SHARE_DELETE, FILE_SHARE_READ|FILE_SHARE_DELETE,
1218           FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE };
1219     int a1, s1, a2, s2;
1220     int ret;
1221     HANDLE h, h2;
1222     BOOL is_win9x = FALSE;
1223
1224     /* make sure the file exists */
1225     h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1226     if (h == INVALID_HANDLE_VALUE)
1227     {
1228         ok(0, "couldn't create file \"%s\" (err=%d)\n", filename, GetLastError());
1229         return;
1230     }
1231     is_win9x = GetFileAttributesW(filenameW) == INVALID_FILE_ATTRIBUTES;
1232     CloseHandle( h );
1233
1234     for (a1 = 0; a1 < sizeof(access_modes)/sizeof(access_modes[0]); a1++)
1235     {
1236         for (s1 = 0; s1 < sizeof(sharing_modes)/sizeof(sharing_modes[0]); s1++)
1237         {
1238             /* Win9x doesn't support FILE_SHARE_DELETE */
1239             if (is_win9x && (sharing_modes[s1] & FILE_SHARE_DELETE))
1240                 continue;
1241
1242             SetLastError(0xdeadbeef);
1243             h = CreateFileA( filename, access_modes[a1], sharing_modes[s1],
1244                              NULL, OPEN_EXISTING, 0, 0 );
1245             if (h == INVALID_HANDLE_VALUE)
1246             {
1247                 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
1248                 return;
1249             }
1250             for (a2 = 0; a2 < sizeof(access_modes)/sizeof(access_modes[0]); a2++)
1251             {
1252                 for (s2 = 0; s2 < sizeof(sharing_modes)/sizeof(sharing_modes[0]); s2++)
1253                 {
1254                     /* Win9x doesn't support FILE_SHARE_DELETE */
1255                     if (is_win9x && (sharing_modes[s2] & FILE_SHARE_DELETE))
1256                         continue;
1257
1258                     SetLastError(0xdeadbeef);
1259                     h2 = CreateFileA( filename, access_modes[a2], sharing_modes[s2],
1260                                       NULL, OPEN_EXISTING, 0, 0 );
1261
1262                     if (is_sharing_compatible( access_modes[a1], sharing_modes[s1],
1263                                                access_modes[a2], sharing_modes[s2], is_win9x ))
1264                     {
1265                         ret = GetLastError();
1266
1267                         ok( h2 != INVALID_HANDLE_VALUE,
1268                             "open failed for modes %x/%x/%x/%x\n",
1269                             access_modes[a1], sharing_modes[s1],
1270                             access_modes[a2], sharing_modes[s2] );
1271                         ok( ret == 0xdeadbeef /* Win9x */ ||
1272                             ret == 0, /* XP */
1273                              "wrong error code %d\n", ret );
1274
1275                         CloseHandle( h2 );
1276                     }
1277                     else
1278                     {
1279                         ret = GetLastError();
1280
1281                         ok( h2 == INVALID_HANDLE_VALUE,
1282                             "open succeeded for modes %x/%x/%x/%x\n",
1283                             access_modes[a1], sharing_modes[s1],
1284                             access_modes[a2], sharing_modes[s2] );
1285                          ok( ret == ERROR_SHARING_VIOLATION,
1286                              "wrong error code %d\n", ret );
1287                     }
1288                 }
1289             }
1290             CloseHandle( h );
1291         }
1292     }
1293
1294     SetLastError(0xdeadbeef);
1295     h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, 0 );
1296     ok( h != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError() );
1297
1298     SetLastError(0xdeadbeef);
1299     h2 = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
1300     ok( h2 == INVALID_HANDLE_VALUE, "CreateFileA should fail\n");
1301     ok( GetLastError() == ERROR_SHARING_VIOLATION, "wrong error code %d\n", GetLastError() );
1302
1303     h2 = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
1304     ok( h2 != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError() );
1305
1306     CloseHandle(h);
1307     CloseHandle(h2);
1308
1309     DeleteFileA( filename );
1310 }
1311
1312 static char get_windows_drive(void)
1313 {
1314     char windowsdir[MAX_PATH];
1315     GetWindowsDirectory(windowsdir, sizeof(windowsdir));
1316     return windowsdir[0];
1317 }
1318
1319 static void test_FindFirstFileA(void)
1320 {
1321     HANDLE handle;
1322     WIN32_FIND_DATAA data;
1323     int err;
1324     char buffer[5] = "C:\\";
1325     char buffer2[100];
1326
1327     /* try FindFirstFileA on "C:\" */
1328     buffer[0] = get_windows_drive();
1329     
1330     SetLastError( 0xdeadbeaf );
1331     handle = FindFirstFileA(buffer, &data);
1332     err = GetLastError();
1333     ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on root directory should fail\n" );
1334     ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err );
1335
1336     /* try FindFirstFileA on "C:\*" */
1337     strcpy(buffer2, buffer);
1338     strcat(buffer2, "*");
1339     handle = FindFirstFileA(buffer2, &data);
1340     ok ( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s should succeed\n", buffer2 );
1341     ok ( strcmp( data.cFileName, "." ) && strcmp( data.cFileName, ".." ),
1342          "FindFirstFile shouldn't return '%s' in drive root\n", data.cFileName );
1343     if (FindNextFileA( handle, &data ))
1344         ok ( strcmp( data.cFileName, "." ) && strcmp( data.cFileName, ".." ),
1345              "FindNextFile shouldn't return '%s' in drive root\n", data.cFileName );
1346     ok ( FindClose(handle) == TRUE, "Failed to close handle %s\n", buffer2 );
1347
1348     /* try FindFirstFileA on windows dir */
1349     GetWindowsDirectory( buffer2, sizeof(buffer2) );
1350     strcat(buffer2, "\\*");
1351     handle = FindFirstFileA(buffer2, &data);
1352     ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s should succeed\n", buffer2 );
1353     ok( !strcmp( data.cFileName, "." ), "FindFirstFile should return '.' first\n" );
1354     ok( FindNextFileA( handle, &data ), "FindNextFile failed\n" );
1355     ok( !strcmp( data.cFileName, ".." ), "FindNextFile should return '..' as second entry\n" );
1356     while (FindNextFileA( handle, &data ))
1357         ok ( strcmp( data.cFileName, "." ) && strcmp( data.cFileName, ".." ),
1358              "FindNextFile shouldn't return '%s'\n", data.cFileName );
1359     ok ( FindClose(handle) == TRUE, "Failed to close handle %s\n", buffer2 );
1360
1361     /* try FindFirstFileA on "C:\foo\" */
1362     SetLastError( 0xdeadbeaf );
1363     strcpy(buffer2, buffer);
1364     strcat(buffer2, "foo\\");
1365     handle = FindFirstFileA(buffer2, &data);
1366     err = GetLastError();
1367     ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
1368     todo_wine {
1369         ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
1370     }
1371
1372     /* try FindFirstFileA on "C:\foo\bar.txt" */
1373     SetLastError( 0xdeadbeaf );
1374     strcpy(buffer2, buffer);
1375     strcat(buffer2, "foo\\bar.txt");
1376     handle = FindFirstFileA(buffer2, &data);
1377     err = GetLastError();
1378     ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
1379     ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
1380
1381     /* try FindFirstFileA on "C:\foo\*.*" */
1382     SetLastError( 0xdeadbeaf );
1383     strcpy(buffer2, buffer);
1384     strcat(buffer2, "foo\\*.*");
1385     handle = FindFirstFileA(buffer2, &data);
1386     err = GetLastError();
1387     ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
1388     ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
1389
1390     /* try FindFirstFileA on "foo\bar.txt" */
1391     SetLastError( 0xdeadbeaf );
1392     strcpy(buffer2, "foo\\bar.txt");
1393     handle = FindFirstFileA(buffer2, &data);
1394     err = GetLastError();
1395     ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
1396     ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
1397
1398     /* try FindFirstFileA on "c:\nul" */
1399     SetLastError( 0xdeadbeaf );
1400     strcpy(buffer2, buffer);
1401     strcat(buffer2, "nul");
1402     handle = FindFirstFileA(buffer2, &data);
1403     err = GetLastError();
1404     ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s failed\n", buffer2 );
1405     ok( 0 == lstrcmpiA(data.cFileName, "nul"), "wrong name %s\n", data.cFileName );
1406     ok( FILE_ATTRIBUTE_ARCHIVE == data.dwFileAttributes ||
1407         FILE_ATTRIBUTE_DEVICE == data.dwFileAttributes /* Win9x */,
1408         "wrong attributes %x\n", data.dwFileAttributes );
1409     if (data.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE)
1410     {
1411         ok( 0 == data.nFileSizeHigh, "wrong size %d\n", data.nFileSizeHigh );
1412         ok( 0 == data.nFileSizeLow, "wrong size %d\n", data.nFileSizeLow );
1413     }
1414     SetLastError( 0xdeadbeaf );
1415     ok( !FindNextFileA( handle, &data ), "FindNextFileA succeeded\n" );
1416     ok( GetLastError() == ERROR_NO_MORE_FILES, "bad error %d\n", GetLastError() );
1417     ok( FindClose( handle ), "failed to close handle\n" );
1418
1419     /* try FindFirstFileA on "lpt1" */
1420     SetLastError( 0xdeadbeaf );
1421     strcpy(buffer2, "lpt1");
1422     handle = FindFirstFileA(buffer2, &data);
1423     err = GetLastError();
1424     ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s failed\n", buffer2 );
1425     ok( 0 == lstrcmpiA(data.cFileName, "lpt1"), "wrong name %s\n", data.cFileName );
1426     ok( FILE_ATTRIBUTE_ARCHIVE == data.dwFileAttributes ||
1427         FILE_ATTRIBUTE_DEVICE == data.dwFileAttributes /* Win9x */,
1428         "wrong attributes %x\n", data.dwFileAttributes );
1429     if (data.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE)
1430     {
1431         ok( 0 == data.nFileSizeHigh, "wrong size %d\n", data.nFileSizeHigh );
1432         ok( 0 == data.nFileSizeLow, "wrong size %d\n", data.nFileSizeLow );
1433     }
1434     SetLastError( 0xdeadbeaf );
1435     ok( !FindNextFileA( handle, &data ), "FindNextFileA succeeded\n" );
1436     ok( GetLastError() == ERROR_NO_MORE_FILES, "bad error %d\n", GetLastError() );
1437     ok( FindClose( handle ), "failed to close handle\n" );
1438
1439     /* try FindFirstFileA on "c:\nul\*" */
1440     SetLastError( 0xdeadbeaf );
1441     strcpy(buffer2, buffer);
1442     strcat(buffer2, "nul\\*");
1443     handle = FindFirstFileA(buffer2, &data);
1444     err = GetLastError();
1445     ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
1446     ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
1447
1448     /* try FindFirstFileA on "c:\nul*" */
1449     SetLastError( 0xdeadbeaf );
1450     strcpy(buffer2, buffer);
1451     strcat(buffer2, "nul*");
1452     handle = FindFirstFileA(buffer2, &data);
1453     err = GetLastError();
1454     ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
1455     ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err );
1456
1457     /* try FindFirstFileA on "c:\foo\bar\nul" */
1458     SetLastError( 0xdeadbeaf );
1459     strcpy(buffer2, buffer);
1460     strcat(buffer2, "foo\\bar\\nul");
1461     handle = FindFirstFileA(buffer2, &data);
1462     err = GetLastError();
1463     ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
1464     ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
1465
1466     /* try FindFirstFileA on "c:\foo\nul\bar" */
1467     SetLastError( 0xdeadbeaf );
1468     strcpy(buffer2, buffer);
1469     strcat(buffer2, "foo\\nul\\bar");
1470     handle = FindFirstFileA(buffer2, &data);
1471     err = GetLastError();
1472     ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
1473     ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
1474 }
1475
1476 static void test_FindNextFileA(void)
1477 {
1478     HANDLE handle;
1479     WIN32_FIND_DATAA search_results;
1480     int err;
1481     char buffer[5] = "C:\\*";
1482
1483     buffer[0] = get_windows_drive();
1484     handle = FindFirstFileA(buffer,&search_results);
1485     ok ( handle != INVALID_HANDLE_VALUE, "FindFirstFile on C:\\* should succeed\n" );
1486     while (FindNextFile(handle, &search_results))
1487     {
1488         /* get to the end of the files */
1489     }
1490     ok ( FindClose(handle) == TRUE, "Failed to close handle\n");
1491     err = GetLastError();
1492     ok ( err == ERROR_NO_MORE_FILES, "GetLastError should return ERROR_NO_MORE_FILES\n");
1493 }
1494
1495 static void test_FindFirstFileExA(void)
1496 {
1497     WIN32_FIND_DATAA search_results;
1498     HANDLE handle;
1499
1500     if (!pFindFirstFileExA)
1501     {
1502         skip("FindFirstFileExA() is missing\n");
1503         return;
1504     }
1505
1506     CreateDirectoryA("test-dir", NULL);
1507     _lclose(_lcreat("test-dir\\file1", 0));
1508     _lclose(_lcreat("test-dir\\file2", 0));
1509     CreateDirectoryA("test-dir\\dir1", NULL);
1510     /* FindExLimitToDirectories is ignored */
1511     SetLastError(0xdeadbeef);
1512     handle = pFindFirstFileExA("test-dir\\*", FindExInfoStandard, &search_results, FindExSearchLimitToDirectories, NULL, 0);
1513     if (handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1514     {
1515         skip("FindFirstFileExA is not implemented\n");
1516         goto cleanup;
1517     }
1518     ok(handle != INVALID_HANDLE_VALUE, "FindFirstFile failed (err=%u)\n", GetLastError());
1519     ok(strcmp(search_results.cFileName, ".") == 0, "First entry should be '.', is %s\n", search_results.cFileName);
1520
1521 #define CHECK_NAME(fn) (strcmp((fn), "file1") == 0 || strcmp((fn), "file2") == 0 || strcmp((fn), "dir1") == 0)
1522
1523     ok(FindNextFile(handle, &search_results), "Fetching second file failed\n");
1524     ok(strcmp(search_results.cFileName, "..") == 0, "Second entry should be '..' is %s\n", search_results.cFileName);
1525
1526     ok(FindNextFile(handle, &search_results), "Fetching third file failed\n");
1527     ok(CHECK_NAME(search_results.cFileName), "Invalid third entry - %s\n", search_results.cFileName);
1528
1529     ok(FindNextFile(handle, &search_results), "Fetching fourth file failed\n");
1530     ok(CHECK_NAME(search_results.cFileName), "Invalid fourth entry - %s\n", search_results.cFileName);
1531
1532     ok(FindNextFile(handle, &search_results), "Fetching fifth file failed\n");
1533     ok(CHECK_NAME(search_results.cFileName), "Invalid fifth entry - %s\n", search_results.cFileName);
1534
1535 #undef CHECK_NAME
1536
1537     ok(FindNextFile(handle, &search_results) == FALSE, "Fetching sixth file should failed\n");
1538
1539     FindClose( handle );
1540
1541 cleanup:
1542     DeleteFileA("test-dir\\file1");
1543     DeleteFileA("test-dir\\file2");
1544     RemoveDirectoryA("test-dir\\dir1");
1545     RemoveDirectoryA("test-dir");
1546 }
1547
1548 static int test_Mapfile_createtemp(HANDLE *handle)
1549 {
1550     SetFileAttributesA(filename,FILE_ATTRIBUTE_NORMAL);
1551     DeleteFile(filename);
1552     *handle = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, 0,
1553                          CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1554     if (*handle != INVALID_HANDLE_VALUE) {
1555
1556         return 1;
1557     }
1558
1559     return 0;
1560 }
1561
1562 static void test_MapFile(void)
1563 {
1564     HANDLE handle;
1565     HANDLE hmap;
1566
1567     ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
1568
1569     hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0x1000, "named_file_map" );
1570     ok( hmap != NULL, "mapping should work, I named it!\n" );
1571
1572     ok( CloseHandle( hmap ), "can't close mapping handle\n");
1573
1574     /* We have to close file before we try new stuff with mapping again.
1575        Else we would always succeed on XP or block descriptors on 95. */
1576     hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
1577     ok( hmap != NULL, "We should still be able to map!\n" );
1578     ok( CloseHandle( hmap ), "can't close mapping handle\n");
1579     ok( CloseHandle( handle ), "can't close file handle\n");
1580     handle = NULL;
1581
1582     ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
1583
1584     hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
1585     ok( hmap == NULL, "mapped zero size file\n");
1586     ok( GetLastError() == ERROR_FILE_INVALID, "not ERROR_FILE_INVALID\n");
1587
1588     hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0x80000000, 0, NULL );
1589     ok( hmap == NULL || broken(hmap != NULL) /* NT4 */, "mapping should fail\n");
1590     /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */
1591     if ( hmap )
1592         CloseHandle( hmap );
1593
1594     hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0x80000000, 0x10000, NULL );
1595     ok( hmap == NULL || broken(hmap != NULL) /* NT4 */, "mapping should fail\n");
1596     /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */
1597     if ( hmap )
1598         CloseHandle( hmap );
1599
1600     /* On XP you can now map again, on Win 95 you cannot. */
1601
1602     ok( CloseHandle( handle ), "can't close file handle\n");
1603     ok( DeleteFileA( filename ), "DeleteFile failed after map\n" );
1604 }
1605
1606 static void test_GetFileType(void)
1607 {
1608     DWORD type;
1609     HANDLE h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1610     ok( h != INVALID_HANDLE_VALUE, "open %s failed\n", filename );
1611     type = GetFileType(h);
1612     ok( type == FILE_TYPE_DISK, "expected type disk got %d\n", type );
1613     CloseHandle( h );
1614     h = CreateFileA( "nul", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
1615     ok( h != INVALID_HANDLE_VALUE, "open nul failed\n" );
1616     type = GetFileType(h);
1617     ok( type == FILE_TYPE_CHAR, "expected type char for nul got %d\n", type );
1618     CloseHandle( h );
1619     DeleteFileA( filename );
1620 }
1621
1622 static int completion_count;
1623
1624 static void CALLBACK FileIOComplete(DWORD dwError, DWORD dwBytes, LPOVERLAPPED ovl)
1625 {
1626 /*      printf("(%ld, %ld, %p { %ld, %ld, %ld, %ld, %p })\n", dwError, dwBytes, ovl, ovl->Internal, ovl->InternalHigh, ovl->Offset, ovl->OffsetHigh, ovl->hEvent);*/
1627         ReleaseSemaphore(ovl->hEvent, 1, NULL);
1628         completion_count++;
1629 }
1630
1631 static void test_async_file_errors(void)
1632 {
1633     char szFile[MAX_PATH];
1634     HANDLE hSem = CreateSemaphoreW(NULL, 1, 1, NULL);
1635     HANDLE hFile;
1636     LPVOID lpBuffer = HeapAlloc(GetProcessHeap(), 0, 4096);
1637     OVERLAPPED ovl;
1638     S(U(ovl)).Offset = 0;
1639     S(U(ovl)).OffsetHigh = 0;
1640     ovl.hEvent = hSem;
1641     completion_count = 0;
1642     szFile[0] = '\0';
1643     GetWindowsDirectoryA(szFile, sizeof(szFile)/sizeof(szFile[0])-1-strlen("\\win.ini"));
1644     strcat(szFile, "\\win.ini");
1645     hFile = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
1646                         NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
1647     if (hFile == INVALID_HANDLE_VALUE)  /* win9x doesn't like FILE_SHARE_DELETE */
1648         hFile = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1649                             NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
1650     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA(%s ...) failed\n", szFile);
1651     while (TRUE)
1652     {
1653         BOOL res;
1654         DWORD count;
1655         while (WaitForSingleObjectEx(hSem, INFINITE, TRUE) == WAIT_IO_COMPLETION)
1656             ;
1657         res = ReadFileEx(hFile, lpBuffer, 4096, &ovl, FileIOComplete);
1658         /*printf("Offset = %ld, result = %s\n", ovl.Offset, res ? "TRUE" : "FALSE");*/
1659         if (!res)
1660             break;
1661         if (!GetOverlappedResult(hFile, &ovl, &count, FALSE))
1662             break;
1663         S(U(ovl)).Offset += count;
1664         /* i/o completion routine only called if ReadFileEx returned success.
1665          * we only care about violations of this rule so undo what should have
1666          * been done */
1667         completion_count--;
1668     }
1669     ok(completion_count == 0, "completion routine should only be called when ReadFileEx succeeds (this rule was violated %d times)\n", completion_count);
1670     /*printf("Error = %ld\n", GetLastError());*/
1671     HeapFree(GetProcessHeap(), 0, lpBuffer);
1672 }
1673
1674 static void test_read_write(void)
1675 {
1676     DWORD bytes, ret;
1677     HANDLE hFile;
1678     char temp_path[MAX_PATH];
1679     char filename[MAX_PATH];
1680     static const char prefix[] = "pfx";
1681
1682     ret = GetTempPathA(MAX_PATH, temp_path);
1683     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
1684     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
1685
1686     ret = GetTempFileNameA(temp_path, prefix, 0, filename);
1687     ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
1688
1689     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
1690                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
1691     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
1692
1693     SetLastError(12345678);
1694     bytes = 12345678;
1695     ret = WriteFile(hFile, NULL, 0, &bytes, NULL);
1696     ok(ret && GetLastError() == 12345678,
1697         "ret = %d, error %d\n", ret, GetLastError());
1698     ok(!bytes, "bytes = %d\n", bytes);
1699
1700     SetLastError(12345678);
1701     bytes = 12345678;
1702     ret = WriteFile(hFile, NULL, 10, &bytes, NULL);
1703     ok((!ret && GetLastError() == ERROR_INVALID_USER_BUFFER) || /* Win2k */
1704         (ret && GetLastError() == 12345678), /* Win9x */
1705         "ret = %d, error %d\n", ret, GetLastError());
1706     ok(!bytes || /* Win2k */
1707         bytes == 10, /* Win9x */
1708         "bytes = %d\n", bytes);
1709
1710     /* make sure the file contains data */
1711     WriteFile(hFile, "this is the test data", 21, &bytes, NULL);
1712     SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
1713
1714     SetLastError(12345678);
1715     bytes = 12345678;
1716     ret = ReadFile(hFile, NULL, 0, &bytes, NULL);
1717     ok(ret && GetLastError() == 12345678,
1718         "ret = %d, error %d\n", ret, GetLastError());
1719     ok(!bytes, "bytes = %d\n", bytes);
1720
1721     SetLastError(12345678);
1722     bytes = 12345678;
1723     ret = ReadFile(hFile, NULL, 10, &bytes, NULL);
1724     ok(!ret && (GetLastError() == ERROR_NOACCESS || /* Win2k */
1725                 GetLastError() == ERROR_INVALID_PARAMETER), /* Win9x */
1726         "ret = %d, error %d\n", ret, GetLastError());
1727     ok(!bytes, "bytes = %d\n", bytes);
1728
1729     ret = CloseHandle(hFile);
1730     ok( ret, "CloseHandle: error %d\n", GetLastError());
1731     ret = DeleteFileA(filename);
1732     ok( ret, "DeleteFileA: error %d\n", GetLastError());
1733 }
1734
1735 static void test_OpenFile(void)
1736 {
1737     HFILE hFile;
1738     OFSTRUCT ofs;
1739     BOOL ret;
1740     DWORD retval;
1741     
1742     static const char file[] = "regedit.exe";
1743     static const char foo[] = ".\\foo-bar-foo.baz";
1744     static const char *foo_too_long = ".\\foo-bar-foo.baz+++++++++++++++"
1745         "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
1746         "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
1747         "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
1748         "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
1749         "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
1750     char buff[MAX_PATH];
1751     char buff_long[4*MAX_PATH];
1752     char filled_0xA5[OFS_MAXPATHNAME];
1753     char *p;
1754     UINT length;
1755     
1756     /* Check for existing file */
1757     if (!pGetSystemWindowsDirectoryA)
1758         length = GetWindowsDirectoryA(buff, MAX_PATH);
1759     else
1760         length = pGetSystemWindowsDirectoryA(buff, MAX_PATH);
1761
1762     if (length + sizeof(file) < MAX_PATH)
1763     {
1764         p = buff + strlen(buff);
1765         if (p > buff && p[-1] != '\\') *p++ = '\\';
1766         strcpy( p, file );
1767         memset(&ofs, 0xA5, sizeof(ofs));
1768         SetLastError(0xfaceabee);
1769
1770         hFile = OpenFile(buff, &ofs, OF_EXIST);
1771         ok( hFile == TRUE, "%s not found : %d\n", buff, GetLastError() );
1772         ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 
1773             "GetLastError() returns %d\n", GetLastError() );
1774         ok( ofs.cBytes == sizeof(ofs), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
1775         ok( ofs.nErrCode == ERROR_SUCCESS, "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
1776         ok( lstrcmpiA(ofs.szPathName, buff) == 0,
1777             "OpenFile returned '%s', but was expected to return '%s' or string filled with 0xA5\n",
1778             ofs.szPathName, buff );
1779     }
1780
1781     memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
1782     length = GetCurrentDirectoryA(MAX_PATH, buff);
1783
1784     /* Check for nonexistent file */
1785     if (length + sizeof(foo) < MAX_PATH)
1786     {
1787         p = buff + strlen(buff);
1788         if (p > buff && p[-1] != '\\') *p++ = '\\';
1789         strcpy( p, foo + 2 );
1790         memset(&ofs, 0xA5, sizeof(ofs));
1791         SetLastError(0xfaceabee);
1792
1793         hFile = OpenFile(foo, &ofs, OF_EXIST);
1794         ok( hFile == HFILE_ERROR, "hFile != HFILE_ERROR : %d\n", GetLastError());
1795         ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError() returns %d\n", GetLastError() );
1796         todo_wine
1797         ok( ofs.cBytes == 0xA5, "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
1798         ok( ofs.nErrCode == ERROR_FILE_NOT_FOUND, "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
1799         ok( lstrcmpiA(ofs.szPathName, buff) == 0 || strncmp(ofs.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0,
1800             "OpenFile returned '%s', but was expected to return '%s' or string filled with 0xA5\n", 
1801             ofs.szPathName, buff );
1802     }
1803
1804     length = GetCurrentDirectoryA(MAX_PATH, buff_long);
1805     length += lstrlenA(foo_too_long + 1);
1806
1807     /* Check for nonexistent file with too long filename */ 
1808     if (length >= OFS_MAXPATHNAME && length < sizeof(buff_long)) 
1809     {
1810         lstrcatA(buff_long, foo_too_long + 1); /* Avoid '.' during concatenation */
1811         memset(&ofs, 0xA5, sizeof(ofs));
1812         SetLastError(0xfaceabee);
1813
1814         hFile = OpenFile(foo_too_long, &ofs, OF_EXIST);
1815         ok( hFile == HFILE_ERROR, "hFile != HFILE_ERROR : %d\n", GetLastError());
1816         ok( GetLastError() == ERROR_INVALID_DATA || GetLastError() == ERROR_FILENAME_EXCED_RANGE, 
1817             "GetLastError() returns %d\n", GetLastError() );
1818         todo_wine
1819         ok( ofs.cBytes == 0xA5, "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
1820         ok( ofs.nErrCode == ERROR_INVALID_DATA || ofs.nErrCode == ERROR_FILENAME_EXCED_RANGE,
1821             "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
1822         ok( strncmp(ofs.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, 
1823             "OpenFile returned '%s', but was expected to return string filled with 0xA5\n", 
1824             ofs.szPathName );
1825     }
1826
1827     length = GetCurrentDirectoryA(MAX_PATH, buff) + sizeof(filename);
1828
1829     if (length >= MAX_PATH) 
1830     {
1831         trace("Buffer too small, requested length = %d, but MAX_PATH = %d.  Skipping test.\n", length, MAX_PATH);
1832         return;
1833     }
1834     p = buff + strlen(buff);
1835     if (p > buff && p[-1] != '\\') *p++ = '\\';
1836     strcpy( p, filename );
1837
1838     memset(&ofs, 0xA5, sizeof(ofs));
1839     SetLastError(0xfaceabee);
1840     /* Create an empty file */
1841     hFile = OpenFile(filename, &ofs, OF_CREATE);
1842     ok( hFile != HFILE_ERROR, "OpenFile failed to create nonexistent file\n" );
1843     ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 
1844         "GetLastError() returns %d\n", GetLastError() );
1845     ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
1846     ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
1847         "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
1848     ret = CloseHandle((HANDLE)hFile);
1849     ok( ret == TRUE, "CloseHandle() returns %d\n", ret );
1850     retval = GetFileAttributesA(filename);
1851     ok( retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %d\n", GetLastError() );
1852
1853     memset(&ofs, 0xA5, sizeof(ofs));
1854     SetLastError(0xfaceabee);
1855     /* Check various opening options: */
1856     /* for reading only, */
1857     hFile = OpenFile(filename, &ofs, OF_READ);
1858     ok( hFile != HFILE_ERROR, "OpenFile failed on read\n" );
1859     ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 
1860         "GetLastError() returns %d\n", GetLastError() );
1861     ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
1862     ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
1863         "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
1864     ok( lstrcmpiA(ofs.szPathName, buff) == 0,
1865         "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
1866     ret = CloseHandle((HANDLE)hFile);
1867     ok( ret == TRUE, "CloseHandle() returns %d\n", ret );
1868
1869     memset(&ofs, 0xA5, sizeof(ofs));
1870     SetLastError(0xfaceabee);
1871     /* for writing only, */
1872     hFile = OpenFile(filename, &ofs, OF_WRITE);
1873     ok( hFile != HFILE_ERROR, "OpenFile failed on write\n" );
1874     ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 
1875         "GetLastError() returns %d\n", GetLastError() );
1876     ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
1877     ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
1878         "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
1879     ok( lstrcmpiA(ofs.szPathName, buff) == 0,
1880         "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
1881     ret = CloseHandle((HANDLE)hFile);
1882     ok( ret == TRUE, "CloseHandle() returns %d\n", ret );
1883
1884     memset(&ofs, 0xA5, sizeof(ofs));
1885     SetLastError(0xfaceabee);
1886     /* for reading and writing, */
1887     hFile = OpenFile(filename, &ofs, OF_READWRITE);
1888     ok( hFile != HFILE_ERROR, "OpenFile failed on read/write\n" );
1889     ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 
1890         "GetLastError() returns %d\n", GetLastError() );
1891     ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
1892     ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
1893         "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
1894     ok( lstrcmpiA(ofs.szPathName, buff) == 0,
1895         "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
1896     ret = CloseHandle((HANDLE)hFile);
1897     ok( ret == TRUE, "CloseHandle() returns %d\n", ret );
1898
1899     memset(&ofs, 0xA5, sizeof(ofs));
1900     SetLastError(0xfaceabee);
1901     /* for checking file presence. */
1902     hFile = OpenFile(filename, &ofs, OF_EXIST);
1903     ok( hFile == 1, "OpenFile failed on finding our created file\n" );
1904     ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 
1905         "GetLastError() returns %d\n", GetLastError() );
1906     ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
1907     ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
1908         "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
1909     ok( lstrcmpiA(ofs.szPathName, buff) == 0,
1910         "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
1911
1912     memset(&ofs, 0xA5, sizeof(ofs));
1913     SetLastError(0xfaceabee);
1914     /* Delete the file and make sure it doesn't exist anymore */
1915     hFile = OpenFile(filename, &ofs, OF_DELETE);
1916     ok( hFile == 1, "OpenFile failed on delete (%d)\n", hFile );
1917     ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 
1918         "GetLastError() returns %d\n", GetLastError() );
1919     ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
1920     ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
1921         "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
1922     ok( lstrcmpiA(ofs.szPathName, buff) == 0,
1923         "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
1924
1925     retval = GetFileAttributesA(filename);
1926     ok( retval == INVALID_FILE_ATTRIBUTES, "GetFileAttributesA succeeded on deleted file\n" );
1927 }
1928
1929 static void test_overlapped(void)
1930 {
1931     OVERLAPPED ov;
1932     DWORD r, result;
1933
1934     /* GetOverlappedResult crashes if the 2nd or 3rd param are NULL */
1935
1936     memset( &ov, 0,  sizeof ov );
1937     result = 1;
1938     r = GetOverlappedResult(0, &ov, &result, 0);
1939     if (r)
1940         ok( result == 0, "wrong result %u\n", result );
1941     else  /* win9x */
1942         ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
1943
1944     result = 0;
1945     ov.Internal = 0;
1946     ov.InternalHigh = 0xabcd;
1947     r = GetOverlappedResult(0, &ov, &result, 0);
1948     if (r)
1949         ok( result == 0xabcd, "wrong result %u\n", result );
1950     else  /* win9x */
1951         ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
1952
1953     SetLastError( 0xb00 );
1954     result = 0;
1955     ov.Internal = STATUS_INVALID_HANDLE;
1956     ov.InternalHigh = 0xabcd;
1957     r = GetOverlappedResult(0, &ov, &result, 0);
1958     ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
1959     ok( r == FALSE, "should return false\n");
1960     ok( result == 0xabcd || result == 0 /* win9x */, "wrong result %u\n", result );
1961
1962     SetLastError( 0xb00 );
1963     result = 0;
1964     ov.Internal = STATUS_PENDING;
1965     ov.InternalHigh = 0xabcd;
1966     r = GetOverlappedResult(0, &ov, &result, 0);
1967     ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
1968         "wrong error %u\n", GetLastError() );
1969     ok( r == FALSE, "should return false\n");
1970     ok( result == 0, "wrong result %u\n", result );
1971
1972     SetLastError( 0xb00 );
1973     ov.hEvent = CreateEvent( NULL, 1, 1, NULL );
1974     ov.Internal = STATUS_PENDING;
1975     ov.InternalHigh = 0xabcd;
1976     r = GetOverlappedResult(0, &ov, &result, 0);
1977     ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
1978         "wrong error %u\n", GetLastError() );
1979     ok( r == FALSE, "should return false\n");
1980
1981     ResetEvent( ov.hEvent );
1982
1983     SetLastError( 0xb00 );
1984     ov.Internal = STATUS_PENDING;
1985     ov.InternalHigh = 0;
1986     r = GetOverlappedResult(0, &ov, &result, 0);
1987     ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
1988         "wrong error %u\n", GetLastError() );
1989     ok( r == FALSE, "should return false\n");
1990
1991     r = CloseHandle( ov.hEvent );
1992     ok( r == TRUE, "close handle failed\n");
1993 }
1994
1995 static void test_RemoveDirectory(void)
1996 {
1997     int rc;
1998     char directory[] = "removeme";
1999
2000     rc = CreateDirectory(directory, NULL);
2001     ok( rc, "Createdirectory failed, gle=%d\n", GetLastError() );
2002
2003     rc = SetCurrentDirectory(directory);
2004     ok( rc, "SetCurrentDirectory failed, gle=%d\n", GetLastError() );
2005
2006     rc = RemoveDirectory(".");
2007     if (!rc)
2008     {
2009         rc = SetCurrentDirectory("..");
2010         ok( rc, "SetCurrentDirectory failed, gle=%d\n", GetLastError() );
2011
2012         rc = RemoveDirectory(directory);
2013         ok( rc, "RemoveDirectory failed, gle=%d\n", GetLastError() );
2014     }
2015 }
2016
2017 static BOOL check_file_time( const FILETIME *ft1, const FILETIME *ft2, UINT tolerance )
2018 {
2019     ULONGLONG t1 = ((ULONGLONG)ft1->dwHighDateTime << 32) | ft1->dwLowDateTime;
2020     ULONGLONG t2 = ((ULONGLONG)ft2->dwHighDateTime << 32) | ft2->dwLowDateTime;
2021     return abs(t1 - t2) <= tolerance;
2022 }
2023
2024 static void test_ReplaceFileA(void)
2025 {
2026     char replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH];
2027     HANDLE hReplacedFile, hReplacementFile, hBackupFile;
2028     static const char replacedData[] = "file-to-replace";
2029     static const char replacementData[] = "new-file";
2030     static const char backupData[] = "backup-file";
2031     FILETIME ftReplaced, ftReplacement, ftBackup;
2032     static const char prefix[] = "pfx";
2033     char temp_path[MAX_PATH];
2034     DWORD ret;
2035     BOOL retok;
2036
2037     if (!pReplaceFileA)
2038     {
2039         skip("ReplaceFileA() is missing\n");
2040         return;
2041     }
2042
2043     ret = GetTempPathA(MAX_PATH, temp_path);
2044     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
2045     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
2046
2047     ret = GetTempFileNameA(temp_path, prefix, 0, replaced);
2048     ok(ret != 0, "GetTempFileNameA error (replaced) %d\n", GetLastError());
2049
2050     ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
2051     ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
2052
2053     ret = GetTempFileNameA(temp_path, prefix, 0, backup);
2054     ok(ret != 0, "GetTempFileNameA error (backup) %d\n", GetLastError());
2055
2056     /* place predictable data in the file to be replaced */
2057     hReplacedFile = CreateFileA(replaced, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2058     ok(hReplacedFile != INVALID_HANDLE_VALUE,
2059         "failed to open replaced file\n");
2060     retok = WriteFile(hReplacedFile, replacedData, sizeof(replacedData), &ret, NULL );
2061     ok( retok && ret == sizeof(replacedData),
2062        "WriteFile error (replaced) %d\n", GetLastError());
2063     ok(GetFileSize(hReplacedFile, NULL) == sizeof(replacedData),
2064         "replaced file has wrong size\n");
2065     /* place predictable data in the file to be the replacement */
2066     hReplacementFile = CreateFileA(replacement, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2067     ok(hReplacementFile != INVALID_HANDLE_VALUE,
2068         "failed to open replacement file\n");
2069     retok = WriteFile(hReplacementFile, replacementData, sizeof(replacementData), &ret, NULL );
2070     ok( retok && ret == sizeof(replacementData),
2071        "WriteFile error (replacement) %d\n", GetLastError());
2072     ok(GetFileSize(hReplacementFile, NULL) == sizeof(replacementData),
2073         "replacement file has wrong size\n");
2074     /* place predictable data in the backup file (to be over-written) */
2075     hBackupFile = CreateFileA(backup, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2076     ok(hBackupFile != INVALID_HANDLE_VALUE,
2077         "failed to open backup file\n");
2078     retok = WriteFile(hBackupFile, backupData, sizeof(backupData), &ret, NULL );
2079     ok( retok && ret == sizeof(backupData),
2080        "WriteFile error (replacement) %d\n", GetLastError());
2081     ok(GetFileSize(hBackupFile, NULL) == sizeof(backupData),
2082         "backup file has wrong size\n");
2083     /* change the filetime on the "replaced" file to ensure that it changes */
2084     ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
2085     ok( ret, "GetFileTime error (replaced) %d\n", GetLastError());
2086     ftReplaced.dwLowDateTime -= 600000000; /* 60 second */
2087     ret = SetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
2088     ok( ret, "SetFileTime error (replaced) %d\n", GetLastError());
2089     GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);  /* get the actual time back */
2090     CloseHandle(hReplacedFile);
2091     /* change the filetime on the backup to ensure that it changes */
2092     ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
2093     ok( ret, "GetFileTime error (backup) %d\n", GetLastError());
2094     ftBackup.dwLowDateTime -= 1200000000; /* 120 second */
2095     ret = SetFileTime(hBackupFile, NULL, NULL, &ftBackup);
2096     ok( ret, "SetFileTime error (backup) %d\n", GetLastError());
2097     GetFileTime(hBackupFile, NULL, NULL, &ftBackup);  /* get the actual time back */
2098     CloseHandle(hBackupFile);
2099     /* get the filetime on the replacement file to perform checks */
2100     ret = GetFileTime(hReplacementFile, NULL, NULL, &ftReplacement);
2101     ok( ret, "GetFileTime error (replacement) %d\n", GetLastError());
2102     CloseHandle(hReplacementFile);
2103
2104     /* perform replacement w/ backup
2105      * TODO: flags are not implemented
2106      */
2107     SetLastError(0xdeadbeef);
2108     ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
2109     ok(ret, "ReplaceFileA: unexpected error %d\n", GetLastError());
2110     /* make sure that the backup has the size of the old "replaced" file */
2111     hBackupFile = CreateFileA(backup, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
2112     ok(hBackupFile != INVALID_HANDLE_VALUE,
2113         "failed to open backup file\n");
2114     ret = GetFileSize(hBackupFile, NULL);
2115     ok(ret == sizeof(replacedData),
2116         "backup file has wrong size %d\n", ret);
2117     /* make sure that the "replaced" file has the size of the replacement file */
2118     hReplacedFile = CreateFileA(replaced, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
2119     ok(hReplacedFile != INVALID_HANDLE_VALUE,
2120         "failed to open replaced file\n");
2121     ret = GetFileSize(hReplacedFile, NULL);
2122     ok(ret == sizeof(replacementData),
2123         "replaced file has wrong size %d\n", ret);
2124     /* make sure that the replacement file no-longer exists */
2125     hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
2126     ok(hReplacementFile == INVALID_HANDLE_VALUE,
2127        "unexpected error, replacement file should not exist %d\n", GetLastError());
2128     /* make sure that the backup has the old "replaced" filetime */
2129     ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
2130     ok( ret, "GetFileTime error (backup %d\n", GetLastError());
2131     ok(check_file_time(&ftBackup, &ftReplaced, 20000000), "backup file has wrong filetime\n");
2132     CloseHandle(hBackupFile);
2133     /* make sure that the "replaced" has the old replacement filetime */
2134     ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
2135     ok( ret, "GetFileTime error (backup %d\n", GetLastError());
2136     ok(check_file_time(&ftReplaced, &ftReplacement, 20000000),
2137        "replaced file has wrong filetime %x%08x / %x%08x\n",
2138        ftReplaced.dwHighDateTime, ftReplaced.dwLowDateTime,
2139        ftReplacement.dwHighDateTime, ftReplacement.dwLowDateTime );
2140     CloseHandle(hReplacedFile);
2141
2142     /* re-create replacement file for pass w/o backup (blank) */
2143     ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
2144     ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
2145     /* perform replacement w/o backup
2146      * TODO: flags are not implemented
2147      */
2148     SetLastError(0xdeadbeef);
2149     ret = pReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
2150     ok(ret, "ReplaceFileA: unexpected error %d\n", GetLastError());
2151
2152     /* re-create replacement file for pass w/ backup (backup-file not existing) */
2153     ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
2154     ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
2155     ret = DeleteFileA(backup);
2156     ok(ret, "DeleteFileA: error (backup) %d\n", GetLastError());
2157     /* perform replacement w/ backup (no pre-existing backup)
2158      * TODO: flags are not implemented
2159      */
2160     SetLastError(0xdeadbeef);
2161     ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
2162     ok(ret, "ReplaceFileA: unexpected error %d\n", GetLastError());
2163
2164     /* re-create replacement file for pass w/ no permissions to "replaced" */
2165     ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
2166     ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
2167     ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_READONLY);
2168     ok(ret, "SetFileAttributesA: error setting to read only %d\n", GetLastError());
2169     /* perform replacement w/ backup (no permission to "replaced")
2170      * TODO: flags are not implemented
2171      */
2172     SetLastError(0xdeadbeef);
2173     ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
2174     ok(ret != ERROR_UNABLE_TO_REMOVE_REPLACED, "ReplaceFileA: unexpected error %d\n", GetLastError());
2175     /* make sure that the replacement file still exists */
2176     hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
2177     ok(hReplacementFile != INVALID_HANDLE_VALUE ||
2178        broken(GetLastError() == ERROR_FILE_NOT_FOUND), /* win2k */
2179        "unexpected error, replacement file should still exist %d\n", GetLastError());
2180     CloseHandle(hReplacementFile);
2181     ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_NORMAL);
2182     ok(ret, "SetFileAttributesA: error setting to normal %d\n", GetLastError());
2183
2184     /* replacement file still exists, make pass w/o "replaced" */
2185     ret = DeleteFileA(replaced);
2186     ok(ret, "DeleteFileA: error (replaced) %d\n", GetLastError());
2187     /* perform replacement w/ backup (no pre-existing backup or "replaced")
2188      * TODO: flags are not implemented
2189      */
2190     SetLastError(0xdeadbeef);
2191     ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
2192     ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2193                         "ReplaceFileA: unexpected error %d\n", GetLastError());
2194
2195     /* perform replacement w/o existing "replacement" file
2196      * TODO: flags are not implemented
2197      */
2198     SetLastError(0xdeadbeef);
2199     ret = pReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
2200     ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2201         "ReplaceFileA: unexpected error %d\n", GetLastError());
2202
2203     /*
2204      * if the first round (w/ backup) worked then as long as there is no
2205      * failure then there is no need to check this round (w/ backup is the
2206      * more complete case)
2207      */
2208
2209     /* delete temporary files, replacement and replaced are already deleted */
2210     ret = DeleteFileA(backup);
2211     ok(ret ||
2212        broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */
2213        "DeleteFileA: error (backup) %d\n", GetLastError());
2214 }
2215
2216 /*
2217  * ReplaceFileW is a simpler case of ReplaceFileA, there is no
2218  * need to be as thorough.
2219  */
2220 static void test_ReplaceFileW(void)
2221 {
2222     WCHAR replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH];
2223     static const WCHAR prefix[] = {'p','f','x',0};
2224     WCHAR temp_path[MAX_PATH];
2225     DWORD ret;
2226
2227     if (!pReplaceFileW)
2228     {
2229         skip("ReplaceFileW() is missing\n");
2230         return;
2231     }
2232
2233     ret = GetTempPathW(MAX_PATH, temp_path);
2234     if (ret==0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
2235         return;
2236     ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
2237     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
2238
2239     ret = GetTempFileNameW(temp_path, prefix, 0, replaced);
2240     ok(ret != 0, "GetTempFileNameW error (replaced) %d\n", GetLastError());
2241
2242     ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
2243     ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
2244
2245     ret = GetTempFileNameW(temp_path, prefix, 0, backup);
2246     ok(ret != 0, "GetTempFileNameW error (backup) %d\n", GetLastError());
2247
2248     ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
2249     ok(ret, "ReplaceFileW: error %d\n", GetLastError());
2250
2251     ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
2252     ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
2253     ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0);
2254     ok(ret, "ReplaceFileW: error %d\n", GetLastError());
2255
2256     ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
2257     ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
2258     ret = DeleteFileW(backup);
2259     ok(ret, "DeleteFileW: error (backup) %d\n", GetLastError());
2260     ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
2261     ok(ret, "ReplaceFileW: error %d\n", GetLastError());
2262
2263     ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
2264     ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
2265     ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_READONLY);
2266     ok(ret, "SetFileAttributesW: error setting to read only %d\n", GetLastError());
2267
2268     ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
2269     ok(ret != ERROR_UNABLE_TO_REMOVE_REPLACED,
2270         "ReplaceFileW: unexpected error %d\n", GetLastError());
2271     ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_NORMAL);
2272     ok(ret, "SetFileAttributesW: error setting to normal %d\n", GetLastError());
2273
2274     ret = DeleteFileW(replaced);
2275     ok(ret, "DeleteFileW: error (replaced) %d\n", GetLastError());
2276     ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
2277     ok(!ret, "ReplaceFileW: error %d\n", GetLastError());
2278
2279     ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0);
2280     ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2281         "ReplaceFileW: unexpected error %d\n", GetLastError());
2282
2283     ret = DeleteFileW(backup);
2284     ok(ret ||
2285        broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */
2286        "DeleteFileW: error (backup) %d\n", GetLastError());
2287 }
2288
2289 START_TEST(file)
2290 {
2291     InitFunctionPointers();
2292
2293     test__hread(  );
2294     test__hwrite(  );
2295     test__lclose(  );
2296     test__lcreat(  );
2297     test__llseek(  );
2298     test__llopen(  );
2299     test__lread(  );
2300     test__lwrite(  );
2301     test_GetTempFileNameA();
2302     test_CopyFileA();
2303     test_CopyFileW();
2304     test_CreateFileA();
2305     test_CreateFileW();
2306     test_DeleteFileA();
2307     test_DeleteFileW();
2308     test_MoveFileA();
2309     test_MoveFileW();
2310     test_FindFirstFileA();
2311     test_FindNextFileA();
2312     test_FindFirstFileExA();
2313     test_LockFile();
2314     test_file_sharing();
2315     test_offset_in_overlapped_structure();
2316     test_MapFile();
2317     test_GetFileType();
2318     test_async_file_errors();
2319     test_read_write();
2320     test_OpenFile();
2321     test_overlapped();
2322     test_RemoveDirectory();
2323     test_ReplaceFileA();
2324     test_ReplaceFileW();
2325 }