winapi: Generate the 64-bit variant of structure size/alignment tests.
[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 #include <stdio.h>
30
31 #include "wine/test.h"
32 #include "windef.h"
33 #include "winbase.h"
34 #include "winerror.h"
35
36 static HANDLE (WINAPI *pFindFirstFileExA)(LPCSTR,FINDEX_INFO_LEVELS,LPVOID,FINDEX_SEARCH_OPS,LPVOID,DWORD);
37 static BOOL (WINAPI *pReplaceFileA)(LPCSTR, LPCSTR, LPCSTR, DWORD, LPVOID, LPVOID);
38 static BOOL (WINAPI *pReplaceFileW)(LPCWSTR, LPCWSTR, LPCWSTR, DWORD, LPVOID, LPVOID);
39 static UINT (WINAPI *pGetSystemWindowsDirectoryA)(LPSTR, UINT);
40 static BOOL (WINAPI *pGetVolumeNameForVolumeMountPointA)(LPCSTR, LPSTR, DWORD);
41
42 /* keep filename and filenameW the same */
43 static const char filename[] = "testfile.xxx";
44 static const WCHAR filenameW[] = { 't','e','s','t','f','i','l','e','.','x','x','x',0 };
45 static const char sillytext[] =
46 "en larvig liten text dx \033 gx hej 84 hej 4484 ! \001\033 bla bl\na.. bla bla."
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 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
54 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
55 "sdlkfjasdlkfj a dslkj adsklf  \n  \nasdklf askldfa sdlkf \nsadklf asdklf asdf ";
56
57 struct test_list {
58     const char *file;           /* file string to test */
59     const DWORD err;            /* Win NT and further error code */
60     const LONG err2;            /* Win 9x & ME error code  or -1 */
61     const DWORD options;        /* option flag to use for open */
62     const BOOL todo_flag;       /* todo_wine indicator */
63 } ;
64
65 static void InitFunctionPointers(void)
66 {
67     HMODULE hkernel32 = GetModuleHandleA("kernel32");
68
69     pFindFirstFileExA=(void*)GetProcAddress(hkernel32, "FindFirstFileExA");
70     pReplaceFileA=(void*)GetProcAddress(hkernel32, "ReplaceFileA");
71     pReplaceFileW=(void*)GetProcAddress(hkernel32, "ReplaceFileW");
72     pGetSystemWindowsDirectoryA=(void*)GetProcAddress(hkernel32, "GetSystemWindowsDirectoryA");
73     pGetVolumeNameForVolumeMountPointA = (void *) GetProcAddress(hkernel32, "GetVolumeNameForVolumeMountPointA");
74 }
75
76 static void test__hread( void )
77 {
78     HFILE filehandle;
79     char buffer[10000];
80     LONG bytes_read;
81     LONG bytes_wanted;
82     LONG i;
83     BOOL ret;
84
85     SetFileAttributesA(filename,FILE_ATTRIBUTE_NORMAL); /* be sure to remove stale files */
86     DeleteFileA( filename );
87     filehandle = _lcreat( filename, 0 );
88     if (filehandle == HFILE_ERROR)
89     {
90         ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
91         return;
92     }
93
94     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
95
96     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
97
98     filehandle = _lopen( filename, OF_READ );
99
100     ok( HFILE_ERROR != filehandle, "couldn't open file \"%s\" again (err=%d)\n", filename, GetLastError(  ) );
101
102     bytes_read = _hread( filehandle, buffer, 2 * strlen( sillytext ) );
103
104     ok( lstrlenA( sillytext ) == bytes_read, "file read size error\n" );
105
106     for (bytes_wanted = 0; bytes_wanted < lstrlenA( sillytext ); bytes_wanted++)
107     {
108         ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
109         ok( _hread( filehandle, buffer, bytes_wanted ) == bytes_wanted, "erratic _hread return value\n" );
110         for (i = 0; i < bytes_wanted; i++)
111         {
112             ok( buffer[i] == sillytext[i], "that's not what's written\n" );
113         }
114     }
115
116     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
117
118     ret = DeleteFileA( filename );
119     ok( ret != 0, "DeleteFile failed (%d)\n", GetLastError(  ) );
120 }
121
122
123 static void test__hwrite( void )
124 {
125     HFILE filehandle;
126     char buffer[10000];
127     LONG bytes_read;
128     LONG bytes_written;
129     ULONG blocks;
130     LONG i;
131     char *contents;
132     HLOCAL memory_object;
133     char checksum[1];
134     BOOL ret;
135
136     filehandle = _lcreat( filename, 0 );
137     if (filehandle == HFILE_ERROR)
138     {
139         ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
140         return;
141     }
142
143     ok( HFILE_ERROR != _hwrite( filehandle, "", 0 ), "_hwrite complains\n" );
144
145     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
146
147     filehandle = _lopen( filename, OF_READ );
148
149     bytes_read = _hread( filehandle, buffer, 1);
150
151     ok( 0 == bytes_read, "file read size error\n" );
152
153     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
154
155     filehandle = _lopen( filename, OF_READWRITE );
156
157     bytes_written = 0;
158     checksum[0] = '\0';
159     srand( (unsigned)time( NULL ) );
160     for (blocks = 0; blocks < 100; blocks++)
161     {
162         for (i = 0; i < (LONG)sizeof( buffer ); i++)
163         {
164             buffer[i] = rand(  );
165             checksum[0] = checksum[0] + buffer[i];
166         }
167         ok( HFILE_ERROR != _hwrite( filehandle, buffer, sizeof( buffer ) ), "_hwrite complains\n" );
168         bytes_written = bytes_written + sizeof( buffer );
169     }
170
171     ok( HFILE_ERROR != _hwrite( filehandle, checksum, 1 ), "_hwrite complains\n" );
172     bytes_written++;
173
174     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
175
176     memory_object = LocalAlloc( LPTR, bytes_written );
177
178     ok( 0 != memory_object, "LocalAlloc fails. (Could be out of memory.)\n" );
179
180     contents = LocalLock( memory_object );
181
182     filehandle = _lopen( filename, OF_READ );
183
184     contents = LocalLock( memory_object );
185
186     ok( NULL != contents, "LocalLock whines\n" );
187
188     ok( bytes_written == _hread( filehandle, contents, bytes_written), "read length differ from write length\n" );
189
190     checksum[0] = '\0';
191     i = 0;
192     do
193     {
194         checksum[0] = checksum[0] + contents[i];
195         i++;
196     }
197     while (i < bytes_written - 1);
198
199     ok( checksum[0] == contents[i], "stored checksum differ from computed checksum\n" );
200
201     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
202
203     ret = DeleteFileA( filename );
204     ok( ret != 0, "DeleteFile failed (%d)\n", GetLastError(  ) );
205
206     LocalFree( contents );
207 }
208
209
210 static void test__lclose( void )
211 {
212     HFILE filehandle;
213     BOOL ret;
214
215     filehandle = _lcreat( filename, 0 );
216     if (filehandle == HFILE_ERROR)
217     {
218         ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
219         return;
220     }
221
222     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
223
224     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
225
226     ret = DeleteFileA( filename );
227     ok( ret != 0, "DeleteFile failed (%d)\n", GetLastError(  ) );
228 }
229
230
231 static void test__lcreat( void )
232 {
233     HFILE filehandle;
234     char buffer[10000];
235     WIN32_FIND_DATAA search_results;
236     char slashname[] = "testfi/";
237     int err;
238     HANDLE find;
239     BOOL ret;
240
241     filehandle = _lcreat( filename, 0 );
242     if (filehandle == HFILE_ERROR)
243     {
244         ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
245         return;
246     }
247
248     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
249
250     ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
251
252     ok( _hread( filehandle, buffer, strlen( sillytext ) ) ==  lstrlenA( sillytext ), "erratic _hread return value\n" );
253
254     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
255
256     find = FindFirstFileA( filename, &search_results );
257     ok( INVALID_HANDLE_VALUE != find, "should be able to find file\n" );
258     FindClose( find );
259
260     ret = DeleteFileA(filename);
261     ok( ret != 0, "DeleteFile failed (%d)\n", GetLastError());
262
263     filehandle = _lcreat( filename, 1 ); /* readonly */
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 shouldn't be able to write never the less\n" );
267
268     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
269
270     find = FindFirstFileA( filename, &search_results );
271     ok( INVALID_HANDLE_VALUE != find, "should be able to find file\n" );
272     FindClose( find );
273
274     ok( 0 == DeleteFileA( filename ), "shouldn't be able to delete a readonly file\n" );
275
276     ok( SetFileAttributesA(filename, FILE_ATTRIBUTE_NORMAL ) != 0, "couldn't change attributes on file\n" );
277
278     ok( DeleteFileA( filename ) != 0, "now it should be possible to delete the file!\n" );
279
280     filehandle = _lcreat( filename, 2 );
281     ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%d)\n", filename, GetLastError(  ) );
282
283     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
284
285     ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
286
287     ok( _hread( filehandle, buffer, strlen( sillytext ) ) ==  lstrlenA( sillytext ), "erratic _hread return value\n" );
288
289     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
290
291     find = FindFirstFileA( filename, &search_results );
292     ok( INVALID_HANDLE_VALUE != find, "should STILL be able to find file\n" );
293     FindClose( find );
294
295     ret = DeleteFileA( filename );
296     ok( ret, "DeleteFile failed (%d)\n", GetLastError(  ) );
297
298     filehandle = _lcreat( filename, 4 ); /* SYSTEM file */
299     ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%d)\n", filename, GetLastError(  ) );
300
301     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
302
303     ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
304
305     ok( _hread( filehandle, buffer, strlen( sillytext ) ) ==  lstrlenA( sillytext ), "erratic _hread return value\n" );
306
307     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
308
309     find = FindFirstFileA( filename, &search_results );
310     ok( INVALID_HANDLE_VALUE != find, "should STILL be able to find file\n" );
311     FindClose( find );
312
313     ret = DeleteFileA( filename );
314     ok( ret, "DeleteFile failed (%d)\n", GetLastError(  ) );
315
316     filehandle=_lcreat (slashname, 0); /* illegal name */
317     if (HFILE_ERROR==filehandle) {
318       err=GetLastError ();
319       ok (err==ERROR_INVALID_NAME || err==ERROR_PATH_NOT_FOUND,
320           "creating file \"%s\" failed with error %d\n", slashname, err);
321     } else { /* only NT succeeds */
322       _lclose(filehandle);
323       find=FindFirstFileA (slashname, &search_results);
324       if (INVALID_HANDLE_VALUE!=find)
325       {
326         ret = FindClose (find);
327         ok (0 != ret, "FindClose complains (%d)\n", GetLastError ());
328         slashname[strlen(slashname)-1]=0;
329         ok (!strcmp (slashname, search_results.cFileName),
330             "found unexpected name \"%s\"\n", search_results.cFileName);
331         ok (FILE_ATTRIBUTE_ARCHIVE==search_results.dwFileAttributes,
332             "attributes of file \"%s\" are 0x%04x\n", search_results.cFileName,
333             search_results.dwFileAttributes);
334       }
335     ret = DeleteFileA( slashname );
336     ok( ret, "DeleteFile failed (%d)\n", GetLastError(  ) );
337     }
338
339     filehandle=_lcreat (filename, 8); /* illegal attribute */
340     if (HFILE_ERROR==filehandle)
341       ok (0, "couldn't create volume label \"%s\"\n", filename);
342     else {
343       _lclose(filehandle);
344       find=FindFirstFileA (filename, &search_results);
345       if (INVALID_HANDLE_VALUE==find)
346         ok (0, "file \"%s\" not found\n", filename);
347       else {
348         ret = FindClose(find);
349         ok ( 0 != ret, "FindClose complains (%d)\n", GetLastError ());
350         ok (!strcmp (filename, search_results.cFileName),
351             "found unexpected name \"%s\"\n", search_results.cFileName);
352         search_results.dwFileAttributes &= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
353         ok (FILE_ATTRIBUTE_ARCHIVE==search_results.dwFileAttributes,
354             "attributes of file \"%s\" are 0x%04x\n", search_results.cFileName,
355             search_results.dwFileAttributes);
356       }
357     ret = DeleteFileA( filename );
358     ok( ret, "DeleteFile failed (%d)\n", GetLastError(  ) );
359     }
360 }
361
362
363 static void test__llseek( void )
364 {
365     INT i;
366     HFILE filehandle;
367     char buffer[1];
368     LONG bytes_read;
369     BOOL ret;
370
371     filehandle = _lcreat( filename, 0 );
372     if (filehandle == HFILE_ERROR)
373     {
374         ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
375         return;
376     }
377
378     for (i = 0; i < 400; i++)
379     {
380         ok( _hwrite( filehandle, sillytext, strlen( sillytext ) ) != -1, "_hwrite complains\n" );
381     }
382     ok( _llseek( filehandle, 400 * strlen( sillytext ), FILE_CURRENT ) != -1, "should be able to seek\n" );
383     ok( _llseek( filehandle, 27 + 35 * strlen( sillytext ), FILE_BEGIN ) != -1, "should be able to seek\n" );
384
385     bytes_read = _hread( filehandle, buffer, 1);
386     ok( 1 == bytes_read, "file read size error\n" );
387     ok( buffer[0] == sillytext[27], "_llseek error, it got lost seeking\n" );
388     ok( _llseek( filehandle, -400 * (LONG)strlen( sillytext ), FILE_END ) != -1, "should be able to seek\n" );
389
390     bytes_read = _hread( filehandle, buffer, 1);
391     ok( 1 == bytes_read, "file read size error\n" );
392     ok( buffer[0] == sillytext[0], "_llseek error, it got lost seeking\n" );
393     ok( _llseek( filehandle, 1000000, FILE_END ) != -1, "should be able to seek past file; poor, poor Windows programmers\n" );
394     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
395
396     ret = DeleteFileA( filename );
397     ok( ret, "DeleteFile failed (%d)\n", GetLastError(  ) );
398 }
399
400
401 static void test__llopen( void )
402 {
403     HFILE filehandle;
404     UINT bytes_read;
405     char buffer[10000];
406     BOOL ret;
407
408     filehandle = _lcreat( filename, 0 );
409     if (filehandle == HFILE_ERROR)
410     {
411         ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
412         return;
413     }
414
415     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
416     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
417
418     filehandle = _lopen( filename, OF_READ );
419     ok( HFILE_ERROR == _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite shouldn't be able to write!\n" );
420     bytes_read = _hread( filehandle, buffer, strlen( sillytext ) );
421     ok( strlen( sillytext )  == bytes_read, "file read size error\n" );
422     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
423
424     filehandle = _lopen( filename, OF_READWRITE );
425     bytes_read = _hread( filehandle, buffer, 2 * strlen( sillytext ) );
426     ok( strlen( sillytext )  == bytes_read, "file read size error\n" );
427     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite should write just fine\n" );
428     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
429
430     filehandle = _lopen( filename, OF_WRITE );
431     ok( HFILE_ERROR == _hread( filehandle, buffer, 1 ), "you should only be able to write this file\n" );
432     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite should write just fine\n" );
433     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
434
435     ret = DeleteFileA( filename );
436     ok( ret, "DeleteFile failed (%d)\n", GetLastError(  ) );
437     /* TODO - add tests for the SHARE modes  -  use two processes to pull this one off */
438 }
439
440
441 static void test__lread( void )
442 {
443     HFILE filehandle;
444     char buffer[10000];
445     UINT bytes_read;
446     UINT bytes_wanted;
447     UINT i;
448     BOOL ret;
449
450     filehandle = _lcreat( filename, 0 );
451     if (filehandle == HFILE_ERROR)
452     {
453         ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
454         return;
455     }
456
457     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
458
459     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
460
461     filehandle = _lopen( filename, OF_READ );
462
463     ok( HFILE_ERROR != filehandle, "couldn't open file \"%s\" again (err=%d)\n", filename, GetLastError());
464
465     bytes_read = _lread( filehandle, buffer, 2 * strlen( sillytext ) );
466
467     ok( lstrlenA( sillytext ) == bytes_read, "file read size error\n" );
468
469     for (bytes_wanted = 0; bytes_wanted < strlen( sillytext ); bytes_wanted++)
470     {
471         ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
472         ok( _lread( filehandle, buffer, bytes_wanted ) == bytes_wanted, "erratic _hread return value\n" );
473         for (i = 0; i < bytes_wanted; i++)
474         {
475             ok( buffer[i] == sillytext[i], "that's not what's written\n" );
476         }
477     }
478
479     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
480
481     ret = DeleteFileA( filename );
482     ok( ret, "DeleteFile failed (%d)\n", GetLastError(  ) );
483 }
484
485
486 static void test__lwrite( void )
487 {
488     HFILE filehandle;
489     char buffer[10000];
490     UINT bytes_read;
491     UINT bytes_written;
492     UINT blocks;
493     INT i;
494     char *contents;
495     HLOCAL memory_object;
496     char checksum[1];
497     BOOL ret;
498
499     filehandle = _lcreat( filename, 0 );
500     if (filehandle == HFILE_ERROR)
501     {
502         ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
503         return;
504     }
505
506     ok( HFILE_ERROR != _lwrite( filehandle, "", 0 ), "_hwrite complains\n" );
507
508     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
509
510     filehandle = _lopen( filename, OF_READ );
511
512     bytes_read = _hread( filehandle, buffer, 1);
513
514     ok( 0 == bytes_read, "file read size error\n" );
515
516     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
517
518     filehandle = _lopen( filename, OF_READWRITE );
519
520     bytes_written = 0;
521     checksum[0] = '\0';
522     srand( (unsigned)time( NULL ) );
523     for (blocks = 0; blocks < 100; blocks++)
524     {
525         for (i = 0; i < (INT)sizeof( buffer ); i++)
526         {
527             buffer[i] = rand(  );
528             checksum[0] = checksum[0] + buffer[i];
529         }
530         ok( HFILE_ERROR != _lwrite( filehandle, buffer, sizeof( buffer ) ), "_hwrite complains\n" );
531         bytes_written = bytes_written + sizeof( buffer );
532     }
533
534     ok( HFILE_ERROR != _lwrite( filehandle, checksum, 1 ), "_hwrite complains\n" );
535     bytes_written++;
536
537     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
538
539     memory_object = LocalAlloc( LPTR, bytes_written );
540
541     ok( 0 != memory_object, "LocalAlloc fails, could be out of memory\n" );
542
543     contents = LocalLock( memory_object );
544
545     filehandle = _lopen( filename, OF_READ );
546
547     contents = LocalLock( memory_object );
548
549     ok( NULL != contents, "LocalLock whines\n" );
550
551     ok( bytes_written == _hread( filehandle, contents, bytes_written), "read length differ from write length\n" );
552
553     checksum[0] = '\0';
554     i = 0;
555     do
556     {
557         checksum[0] += contents[i];
558         i++;
559     }
560     while (i < bytes_written - 1);
561
562     ok( checksum[0] == contents[i], "stored checksum differ from computed checksum\n" );
563
564     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
565
566     ret = DeleteFileA( filename );
567     ok( ret, "DeleteFile failed (%d)\n", GetLastError(  ) );
568
569     LocalFree( contents );
570 }
571
572 static void test_CopyFileA(void)
573 {
574     char temp_path[MAX_PATH];
575     char source[MAX_PATH], dest[MAX_PATH];
576     static const char prefix[] = "pfx";
577     HANDLE hfile;
578     HANDLE hmapfile;
579     FILETIME ft1, ft2;
580     char buf[10];
581     DWORD ret;
582     BOOL retok;
583
584     ret = GetTempPathA(MAX_PATH, temp_path);
585     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
586     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
587
588     ret = GetTempFileNameA(temp_path, prefix, 0, source);
589     ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
590
591     ret = MoveFileA(source, source);
592     todo_wine ok(ret, "MoveFileA: failed, error %d\n", GetLastError());
593
594     /* make the source have not zero size */
595     hfile = CreateFileA(source, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
596     ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
597     retok = WriteFile(hfile, prefix, sizeof(prefix), &ret, NULL );
598     ok( retok && ret == sizeof(prefix),
599        "WriteFile error %d\n", GetLastError());
600     ok(GetFileSize(hfile, NULL) == sizeof(prefix), "source file has wrong size\n");
601     /* get the file time and change it to prove the difference */
602     ret = GetFileTime(hfile, NULL, NULL, &ft1);
603     ok( ret, "GetFileTime error %d\n", GetLastError());
604     ft1.dwLowDateTime -= 600000000; /* 60 second */
605     ret = SetFileTime(hfile, NULL, NULL, &ft1);
606     ok( ret, "SetFileTime error %d\n", GetLastError());
607     GetFileTime(hfile, NULL, NULL, &ft1);  /* get the actual time back */
608     CloseHandle(hfile);
609
610     ret = GetTempFileNameA(temp_path, prefix, 0, dest);
611     ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
612
613     SetLastError(0xdeadbeef);
614     ret = CopyFileA(source, dest, TRUE);
615     ok(!ret && GetLastError() == ERROR_FILE_EXISTS,
616        "CopyFileA: unexpected error %d\n", GetLastError());
617
618     ret = CopyFileA(source, dest, FALSE);
619     ok(ret, "CopyFileA: error %d\n", GetLastError());
620
621     /* make sure that destination has correct size */
622     hfile = CreateFileA(dest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
623     ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n");
624     ret = GetFileSize(hfile, NULL);
625     ok(ret == sizeof(prefix), "destination file has wrong size %d\n", ret);
626
627     /* make sure that destination has the same filetime */
628     ret = GetFileTime(hfile, NULL, NULL, &ft2);
629     ok( ret, "GetFileTime error %d\n", GetLastError());
630     ok(CompareFileTime(&ft1, &ft2) == 0, "destination file has wrong filetime\n");
631
632     SetLastError(0xdeadbeef);
633     ret = CopyFileA(source, dest, FALSE);
634     ok(!ret && GetLastError() == ERROR_SHARING_VIOLATION,
635        "CopyFileA: ret = %d, unexpected error %d\n", ret, GetLastError());
636
637     /* make sure that destination still has correct size */
638     ret = GetFileSize(hfile, NULL);
639     ok(ret == sizeof(prefix), "destination file has wrong size %d\n", ret);
640     retok = ReadFile(hfile, buf, sizeof(buf), &ret, NULL);
641     ok( retok && ret == sizeof(prefix),
642        "ReadFile: error %d\n", GetLastError());
643     ok(!memcmp(prefix, buf, sizeof(prefix)), "buffer contents mismatch\n");
644
645     /* check error on copying over a mapped file that was opened with FILE_SHARE_READ */
646     hmapfile = CreateFileMapping(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
647     ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError());
648
649     ret = CopyFileA(source, dest, FALSE);
650     ok(!ret && GetLastError() == ERROR_SHARING_VIOLATION,
651        "CopyFileA with mapped dest file: expected ERROR_SHARING_VIOLATION, got %d\n", GetLastError());
652
653     CloseHandle(hmapfile);
654     CloseHandle(hfile);
655
656     hfile = CreateFileA(dest, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
657     ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n");
658
659     /* check error on copying over a mapped file that was opened with FILE_SHARE_WRITE */
660     hmapfile = CreateFileMapping(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
661     ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError());
662
663     ret = CopyFileA(source, dest, FALSE);
664     ok(!ret, "CopyFileA: expected failure\n");
665     ok(GetLastError() == ERROR_USER_MAPPED_FILE ||
666        broken(GetLastError() == ERROR_SHARING_VIOLATION), /* Win9x */
667        "CopyFileA with mapped dest file: expected ERROR_USER_MAPPED_FILE, got %d\n", GetLastError());
668
669     CloseHandle(hmapfile);
670     CloseHandle(hfile);
671
672     ret = DeleteFileA(source);
673     ok(ret, "DeleteFileA: error %d\n", GetLastError());
674     ret = DeleteFileA(dest);
675     ok(ret, "DeleteFileA: error %d\n", GetLastError());
676 }
677
678 static void test_CopyFileW(void)
679 {
680     WCHAR temp_path[MAX_PATH];
681     WCHAR source[MAX_PATH], dest[MAX_PATH];
682     static const WCHAR prefix[] = {'p','f','x',0};
683     DWORD ret;
684
685     ret = GetTempPathW(MAX_PATH, temp_path);
686     if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
687     {
688         win_skip("GetTempPathW is not available\n");
689         return;
690     }
691     ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
692     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
693
694     ret = GetTempFileNameW(temp_path, prefix, 0, source);
695     ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
696
697     ret = GetTempFileNameW(temp_path, prefix, 0, dest);
698     ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
699
700     ret = CopyFileW(source, dest, TRUE);
701     ok(!ret && GetLastError() == ERROR_FILE_EXISTS,
702        "CopyFileW: unexpected error %d\n", GetLastError());
703
704     ret = CopyFileW(source, dest, FALSE);
705     ok(ret, "CopyFileW: error %d\n", GetLastError());
706
707     ret = DeleteFileW(source);
708     ok(ret, "DeleteFileW: error %d\n", GetLastError());
709     ret = DeleteFileW(dest);
710     ok(ret, "DeleteFileW: error %d\n", GetLastError());
711 }
712
713
714 /*
715  *   Debugging routine to dump a buffer in a hexdump-like fashion.
716  */
717 static void dumpmem(unsigned char *mem, int len)
718 {
719     int x = 0;
720     char hex[49], *p;
721     char txt[17], *c;
722
723     while (x < len)
724     {
725         p = hex;
726         c = txt;
727         do {
728             p += sprintf(p, "%02hhx ", mem[x]);
729             *c++ = (mem[x] >= 32 && mem[x] <= 127) ? mem[x] : '.';
730         } while (++x % 16 && x < len);
731         *c = '\0';
732         trace("%04x: %-48s- %s\n", x, hex, txt);
733     }
734 }
735
736 static void test_CreateFileA(void)
737 {
738     HANDLE hFile;
739     char temp_path[MAX_PATH], dirname[MAX_PATH];
740     char filename[MAX_PATH];
741     static const char prefix[] = "pfx";
742     char windowsdir[MAX_PATH];
743     char Volume_1[MAX_PATH];
744     unsigned char buffer[512];
745     char directory[] = "removeme";
746     static const char nt_drive[] = "\\\\?\\A:";
747     DWORD i, ret, len;
748     struct test_list p[] = {
749     {"", ERROR_PATH_NOT_FOUND, -1, FILE_ATTRIBUTE_NORMAL, TRUE }, /* dir as file w \ */
750     {"", ERROR_SUCCESS, ERROR_PATH_NOT_FOUND, FILE_FLAG_BACKUP_SEMANTICS, FALSE }, /* dir as dir w \ */
751     {"a", ERROR_FILE_NOT_FOUND, -1, FILE_ATTRIBUTE_NORMAL, FALSE }, /* non-exist file */
752     {"a\\", ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND, FILE_ATTRIBUTE_NORMAL, FALSE }, /* non-exist dir */
753     {"removeme", ERROR_ACCESS_DENIED, -1, FILE_ATTRIBUTE_NORMAL, FALSE }, /* exist dir w/o \ */
754     {"removeme\\", ERROR_PATH_NOT_FOUND, -1, FILE_ATTRIBUTE_NORMAL, TRUE }, /* exst dir w \ */
755     {"c:", ERROR_ACCESS_DENIED, ERROR_PATH_NOT_FOUND, FILE_ATTRIBUTE_NORMAL, FALSE }, /* device in file namespace */
756     {"c:", ERROR_SUCCESS, ERROR_PATH_NOT_FOUND, FILE_FLAG_BACKUP_SEMANTICS, FALSE }, /* device in file namespace as dir */
757     {"c:\\", ERROR_PATH_NOT_FOUND, ERROR_ACCESS_DENIED, FILE_ATTRIBUTE_NORMAL, TRUE }, /* root dir w \ */
758     {"c:\\", ERROR_SUCCESS, ERROR_ACCESS_DENIED, FILE_FLAG_BACKUP_SEMANTICS, FALSE }, /* root dir w \ as dir */
759     {"\\\\?\\c:", ERROR_SUCCESS, ERROR_BAD_NETPATH, FILE_ATTRIBUTE_NORMAL,FALSE }, /* dev namespace drive */
760     {"\\\\?\\c:\\", ERROR_PATH_NOT_FOUND, ERROR_BAD_NETPATH, FILE_ATTRIBUTE_NORMAL, TRUE }, /* dev namespace drive w \ */
761     {NULL, 0, -1, 0, FALSE}
762     };
763     BY_HANDLE_FILE_INFORMATION  Finfo;
764
765     ret = GetTempPathA(MAX_PATH, temp_path);
766     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
767     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
768
769     ret = GetTempFileNameA(temp_path, prefix, 0, filename);
770     ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
771
772     SetLastError(0xdeadbeef);
773     hFile = CreateFileA(filename, GENERIC_READ, 0, NULL,
774                         CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
775     ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS,
776         "CREATE_NEW should fail if file exists and last error value should be ERROR_FILE_EXISTS\n");
777
778     SetLastError(0xdeadbeef);
779     hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
780                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
781     ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
782        "hFile %p, last error %u\n", hFile, GetLastError());
783
784     CloseHandle(hFile);
785
786     SetLastError(0xdeadbeef);
787     hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
788                         OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
789     ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
790        "hFile %p, last error %u\n", hFile, GetLastError());
791
792     CloseHandle(hFile);
793
794     ret = DeleteFileA(filename);
795     ok(ret, "DeleteFileA: error %d\n", GetLastError());
796
797     SetLastError(0xdeadbeef);
798     hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
799                         OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
800     ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == 0,
801        "hFile %p, last error %u\n", hFile, GetLastError());
802
803     CloseHandle(hFile);
804
805     ret = DeleteFileA(filename);
806     ok(ret, "DeleteFileA: error %d\n", GetLastError());
807
808     /* get windows drive letter */
809     ret = GetWindowsDirectory(windowsdir, sizeof(windowsdir));
810     ok(ret < sizeof(windowsdir), "windowsdir is abnormally long!\n");
811     ok(ret != 0, "GetWindowsDirectory: error %d\n", GetLastError());
812
813     /* test error return codes from CreateFile for some cases */
814     ret = GetTempPathA(MAX_PATH, temp_path);
815     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
816     strcpy(dirname, temp_path);
817     strcat(dirname, directory);
818     ret = CreateDirectory(dirname, NULL);
819     ok( ret, "Createdirectory failed, gle=%d\n", GetLastError() );
820     /* set current drive & directory to known location */
821     SetCurrentDirectoryA( temp_path );
822     i = 0;
823     while (p[i].file)
824     {
825         filename[0] = 0;
826         /* update the drive id in the table entry with the current one */
827         if (p[i].file[1] == ':')
828         {
829             strcpy(filename, p[i].file);
830             filename[0] = windowsdir[0];
831         }
832         else if (p[i].file[0] == '\\' && p[i].file[5] == ':')
833         {
834             strcpy(filename, p[i].file);
835             filename[4] = windowsdir[0];
836         }
837         else
838         {
839             /* prefix the table entry with the current temp directory */
840             strcpy(filename, temp_path);
841             strcat(filename, p[i].file);
842         }
843         hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
844                         FILE_SHARE_READ | FILE_SHARE_WRITE,
845                         NULL, OPEN_EXISTING,
846                         p[i].options, NULL );
847         /* if we get ACCESS_DENIED when we do not expect it, assume
848          * no access to the volume
849          */
850         if (hFile == INVALID_HANDLE_VALUE &&
851             GetLastError() == ERROR_ACCESS_DENIED &&
852             p[i].err != ERROR_ACCESS_DENIED)
853         {
854             if (p[i].todo_flag)
855                 skip("Either no authority to volume, or is todo_wine for %s err=%d should be %d\n", filename, GetLastError(), p[i].err);
856             else
857                 skip("Do not have authority to access volumes. Test for %s skipped\n", filename);
858         }
859         /* otherwise validate results with expectations */
860         else if (p[i].todo_flag)
861             todo_wine ok(
862                 (hFile == INVALID_HANDLE_VALUE &&
863                   (p[i].err == GetLastError() || p[i].err2 == GetLastError())) ||
864                 (hFile != INVALID_HANDLE_VALUE && p[i].err == ERROR_SUCCESS),
865                 "CreateFileA failed on %s, hFile %p, err=%u, should be %u\n",
866                 filename, hFile, GetLastError(), p[i].err);
867         else
868             ok(
869                 (hFile == INVALID_HANDLE_VALUE &&
870                  (p[i].err == GetLastError() || p[i].err2 == GetLastError())) ||
871                 (hFile != INVALID_HANDLE_VALUE && p[i].err == ERROR_SUCCESS),
872                 "CreateFileA failed on %s, hFile %p, err=%u, should be %u\n",
873                 filename, hFile, GetLastError(), p[i].err);
874         if (hFile != INVALID_HANDLE_VALUE)
875             CloseHandle( hFile );
876         i++;
877     }
878     ret = RemoveDirectoryA(dirname);
879     ok(ret, "RemoveDirectoryA: error %d\n", GetLastError());
880
881
882     /* test opening directory as a directory */
883     hFile = CreateFileA( temp_path, GENERIC_READ,
884                         FILE_SHARE_READ,
885                         NULL,
886                         OPEN_EXISTING,
887                         FILE_FLAG_BACKUP_SEMANTICS, NULL );
888     if (hFile != INVALID_HANDLE_VALUE && GetLastError() != ERROR_PATH_NOT_FOUND)
889     {
890         ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_SUCCESS,
891             "CreateFileA did not work, last error %u on volume <%s>\n",
892              GetLastError(), temp_path );
893
894         if (hFile != INVALID_HANDLE_VALUE)
895         {
896             ret = GetFileInformationByHandle( hFile, &Finfo );
897             if (ret)
898             {
899                 ok(Finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY,
900                     "CreateFileA probably did not open temp directory %s correctly\n   file information does not include FILE_ATTRIBUTE_DIRECTORY, actual=0x%08x\n",
901                 temp_path, Finfo.dwFileAttributes);
902             }
903             CloseHandle( hFile );
904         }
905     }
906     else
907         skip("Probable Win9x, got ERROR_PATH_NOT_FOUND w/ FILE_FLAG_BACKUP_SEMANTICS or %s\n", temp_path);
908
909
910     /* ***  Test opening volumes/devices using drive letter  ***         */
911
912     /* test using drive letter in non-rewrite format without trailing \  */
913     /* this should work                                                  */
914     strcpy(filename, nt_drive);
915     filename[4] = windowsdir[0];
916     hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
917                         FILE_SHARE_READ | FILE_SHARE_WRITE,
918                         NULL, OPEN_EXISTING,
919                         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
920     if (hFile != INVALID_HANDLE_VALUE ||
921         (GetLastError() != ERROR_ACCESS_DENIED && GetLastError() != ERROR_BAD_NETPATH))
922     {
923         /* if we have adm rights to volume, then try rest of tests */
924         ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA did not open %s, last error=%u\n",
925             filename, GetLastError());
926         if (hFile != INVALID_HANDLE_VALUE)
927         {
928             /* if we opened the volume/device, try to read it. Since it  */
929             /* opened, we should be able to read it.  We don't care about*/
930             /* what the data is at this time.                            */
931             len = 512;
932             ret = ReadFile( hFile, buffer, len, &len, NULL );
933             todo_wine ok(ret, "Failed to read volume, last error %u, %u, for %s\n",
934                 GetLastError(), ret, filename);
935             if (ret)
936             {
937                 trace("buffer is\n");
938                 dumpmem(buffer, 64);
939             }
940             CloseHandle( hFile );
941         }
942
943         /* test using drive letter with trailing \ and in non-rewrite   */
944         /* this should not work                                         */
945         strcpy(filename, nt_drive);
946         filename[4] = windowsdir[0];
947         strcat( filename, "\\" );
948         hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
949                         FILE_SHARE_READ | FILE_SHARE_WRITE,
950                         NULL, OPEN_EXISTING,
951                         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
952         todo_wine
953         ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
954             "CreateFileA should have returned ERROR_PATH_NOT_FOUND on %s, but got %u\n",
955             filename, GetLastError());
956         if (hFile != INVALID_HANDLE_VALUE)
957             CloseHandle( hFile );
958
959         /* test using temp path with trailing \ and in non-rewrite as dir */
960         /* this should work                                               */
961         strcpy(filename, nt_drive);
962         filename[4] = 0;
963         strcat( filename, temp_path );
964         hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
965                         FILE_SHARE_READ | FILE_SHARE_WRITE,
966                         NULL, OPEN_EXISTING,
967                         FILE_FLAG_BACKUP_SEMANTICS, NULL );
968         ok(hFile != INVALID_HANDLE_VALUE,
969             "CreateFileA should have worked on %s, but got %u\n",
970             filename, GetLastError());
971         if (hFile != INVALID_HANDLE_VALUE)
972             CloseHandle( hFile );
973
974         /* test using drive letter without trailing \ and in device ns  */
975         /* this should work                                             */
976         strcpy(filename, nt_drive);
977         filename[4] = windowsdir[0];
978         filename[2] = '.';
979         hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
980                         FILE_SHARE_READ | FILE_SHARE_WRITE,
981                         NULL, OPEN_EXISTING,
982                         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
983         ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA did not open %s, last error=%u\n",
984             filename, GetLastError());
985         if (hFile != INVALID_HANDLE_VALUE)
986             CloseHandle( hFile );
987     }
988     /* If we see ERROR_BAD_NETPATH then on Win9x or WinME, so skip */
989     else if (GetLastError() == ERROR_BAD_NETPATH)
990         skip("Probable Win9x, got ERROR_BAD_NETPATH (53)\n");
991     else
992         skip("Do not have authority to access volumes. Tests skipped\n");
993
994
995     /* ***  Test opening volumes/devices using GUID  ***           */
996
997     if (pGetVolumeNameForVolumeMountPointA)
998     {
999         strcpy(filename, "c:\\");
1000         filename[0] = windowsdir[0];
1001         ret = pGetVolumeNameForVolumeMountPointA( filename, Volume_1, MAX_PATH );
1002         ok(ret, "GetVolumeNameForVolumeMountPointA failed, for %s, last error=%d\n", filename, GetLastError());
1003         if (ret)
1004         {
1005             ok(strlen(Volume_1) == 49, "GetVolumeNameForVolumeMountPointA returned wrong length name <%s>\n", Volume_1);
1006
1007             /* test the result of opening a unique volume name (GUID)
1008              *  with the trailing \
1009              *  this should error out
1010              */
1011             strcpy(filename, Volume_1);
1012             hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1013                         FILE_SHARE_READ | FILE_SHARE_WRITE,
1014                         NULL, OPEN_EXISTING,
1015                         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
1016             todo_wine
1017             ok(hFile == INVALID_HANDLE_VALUE,
1018                 "CreateFileA should not have opened %s, hFile %p\n",
1019                 filename, hFile);
1020             todo_wine
1021             ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
1022                 "CreateFileA should have returned ERROR_PATH_NOT_FOUND on %s, but got %u\n",
1023                 filename, GetLastError());
1024             if (hFile != INVALID_HANDLE_VALUE)
1025                 CloseHandle( hFile );
1026
1027             /* test the result of opening a unique volume name (GUID)
1028              * with the temp path string as dir
1029              * this should work
1030              */
1031             strcpy(filename, Volume_1);
1032             strcat(filename, temp_path+3);
1033             hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1034                         FILE_SHARE_READ | FILE_SHARE_WRITE,
1035                         NULL, OPEN_EXISTING,
1036                         FILE_FLAG_BACKUP_SEMANTICS, NULL );
1037             todo_wine
1038             ok(hFile != INVALID_HANDLE_VALUE,
1039                 "CreateFileA should have opened %s, but got %u\n",
1040                 filename, GetLastError());
1041             if (hFile != INVALID_HANDLE_VALUE)
1042                 CloseHandle( hFile );
1043
1044             /* test the result of opening a unique volume name (GUID)
1045              * without the trailing \ and in device namespace
1046              * this should work
1047              */
1048             strcpy(filename, Volume_1);
1049             filename[2] = '.';
1050             filename[48] = 0;
1051             hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1052                         FILE_SHARE_READ | FILE_SHARE_WRITE,
1053                         NULL, OPEN_EXISTING,
1054                         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
1055             if (hFile != INVALID_HANDLE_VALUE || GetLastError() != ERROR_ACCESS_DENIED)
1056             {
1057                 /* if we have adm rights to volume, then try rest of tests */
1058                 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA did not open %s, last error=%u\n",
1059                     filename, GetLastError());
1060                 if (hFile != INVALID_HANDLE_VALUE)
1061                 {
1062                     /* if we opened the volume/device, try to read it. Since it  */
1063                     /* opened, we should be able to read it.  We don't care about*/
1064                     /* what the data is at this time.                            */
1065                     len = 512;
1066                     ret = ReadFile( hFile, buffer, len, &len, NULL );
1067                     todo_wine ok(ret, "Failed to read volume, last error %u, %u, for %s\n",
1068                         GetLastError(), ret, filename);
1069                     if (ret)
1070                     {
1071                         trace("buffer is\n");
1072                         dumpmem(buffer, 64);
1073                     }
1074                     CloseHandle( hFile );
1075                 }
1076             }
1077             else
1078                 skip("Do not have authority to access volumes. Tests skipped\n");
1079         }
1080         else
1081             win_skip("GetVolumeNameForVolumeMountPointA not functioning\n");
1082     }
1083     else
1084         win_skip("GetVolumeNameForVolumeMountPointA not found\n");
1085 }
1086
1087 static void test_CreateFileW(void)
1088 {
1089     HANDLE hFile;
1090     WCHAR temp_path[MAX_PATH];
1091     WCHAR filename[MAX_PATH];
1092     static const WCHAR emptyW[]={'\0'};
1093     static const WCHAR prefix[] = {'p','f','x',0};
1094     static const WCHAR bogus[] = { '\\', '\\', '.', '\\', 'B', 'O', 'G', 'U', 'S', 0 };
1095     DWORD ret;
1096
1097     ret = GetTempPathW(MAX_PATH, temp_path);
1098     if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1099     {
1100         win_skip("GetTempPathW is not available\n");
1101         return;
1102     }
1103     ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
1104     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
1105
1106     ret = GetTempFileNameW(temp_path, prefix, 0, filename);
1107     ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
1108
1109     SetLastError(0xdeadbeef);
1110     hFile = CreateFileW(filename, GENERIC_READ, 0, NULL,
1111                         CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
1112     ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS,
1113         "CREATE_NEW should fail if file exists and last error value should be ERROR_FILE_EXISTS\n");
1114
1115     SetLastError(0xdeadbeef);
1116     hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
1117                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
1118     ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
1119        "hFile %p, last error %u\n", hFile, GetLastError());
1120
1121     CloseHandle(hFile);
1122
1123     SetLastError(0xdeadbeef);
1124     hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
1125                         OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
1126     ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
1127        "hFile %p, last error %u\n", hFile, GetLastError());
1128
1129     CloseHandle(hFile);
1130
1131     ret = DeleteFileW(filename);
1132     ok(ret, "DeleteFileW: error %d\n", GetLastError());
1133
1134     SetLastError(0xdeadbeef);
1135     hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
1136                         OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
1137     ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == 0,
1138        "hFile %p, last error %u\n", hFile, GetLastError());
1139
1140     CloseHandle(hFile);
1141
1142     ret = DeleteFileW(filename);
1143     ok(ret, "DeleteFileW: error %d\n", GetLastError());
1144
1145     if (0)
1146     {
1147         /* this crashes on NT4.0 */
1148         hFile = CreateFileW(NULL, GENERIC_READ, 0, NULL,
1149                             CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
1150         ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
1151            "CreateFileW(NULL) returned ret=%p error=%u\n",hFile,GetLastError());
1152     }
1153
1154     hFile = CreateFileW(emptyW, GENERIC_READ, 0, NULL,
1155                         CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
1156     ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
1157        "CreateFileW(\"\") returned ret=%p error=%d\n",hFile,GetLastError());
1158
1159     /* test the result of opening a nonexistent driver name */
1160     hFile = CreateFileW(bogus, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1161                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1162     ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND,
1163        "CreateFileW on invalid VxD name returned ret=%p error=%d\n",hFile,GetLastError());
1164
1165     ret = CreateDirectoryW(filename, NULL);
1166     ok(ret == TRUE, "couldn't create temporary directory\n");
1167     hFile = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
1168                         OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL);
1169     ok(hFile != INVALID_HANDLE_VALUE,
1170        "expected CreateFile to succeed on existing directory, error: %d\n", GetLastError());
1171     CloseHandle(hFile);
1172     ret = RemoveDirectoryW(filename);
1173     ok(ret, "DeleteFileW: error %d\n", GetLastError());
1174 }
1175
1176 static void test_GetTempFileNameA(void)
1177 {
1178     UINT result;
1179     char out[MAX_PATH];
1180     char expected[MAX_PATH + 10];
1181     char windowsdir[MAX_PATH + 10];
1182     char windowsdrive[3];
1183
1184     result = GetWindowsDirectory(windowsdir, sizeof(windowsdir));
1185     ok(result < sizeof(windowsdir), "windowsdir is abnormally long!\n");
1186     ok(result != 0, "GetWindowsDirectory: error %d\n", GetLastError());
1187
1188     /* If the Windows directory is the root directory, it ends in backslash, not else. */
1189     if (strlen(windowsdir) != 3) /* As in  "C:\"  or  "F:\"  */
1190     {
1191         strcat(windowsdir, "\\");
1192     }
1193
1194     windowsdrive[0] = windowsdir[0];
1195     windowsdrive[1] = windowsdir[1];
1196     windowsdrive[2] = '\0';
1197
1198     result = GetTempFileNameA(windowsdrive, "abc", 1, out);
1199     ok(result != 0, "GetTempFileNameA: error %d\n", GetLastError());
1200     ok(((out[0] == windowsdrive[0]) && (out[1] == ':')) && (out[2] == '\\'),
1201        "GetTempFileNameA: first three characters should be %c:\\, string was actually %s\n",
1202        windowsdrive[0], out);
1203
1204     result = GetTempFileNameA(windowsdir, "abc", 2, out);
1205     ok(result != 0, "GetTempFileNameA: error %d\n", GetLastError());
1206     expected[0] = '\0';
1207     strcat(expected, windowsdir);
1208     strcat(expected, "abc2.tmp");
1209     ok(lstrcmpiA(out, expected) == 0, "GetTempFileNameA: Unexpected output \"%s\" vs \"%s\"\n",
1210        out, expected);
1211 }
1212
1213 static void test_DeleteFileA( void )
1214 {
1215     BOOL ret;
1216
1217     ret = DeleteFileA(NULL);
1218     ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER ||
1219                 GetLastError() == ERROR_PATH_NOT_FOUND),
1220        "DeleteFileA(NULL) returned ret=%d error=%d\n",ret,GetLastError());
1221
1222     ret = DeleteFileA("");
1223     ok(!ret && (GetLastError() == ERROR_PATH_NOT_FOUND ||
1224                 GetLastError() == ERROR_BAD_PATHNAME),
1225        "DeleteFileA(\"\") returned ret=%d error=%d\n",ret,GetLastError());
1226
1227     ret = DeleteFileA("nul");
1228     ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
1229                 GetLastError() == ERROR_INVALID_PARAMETER ||
1230                 GetLastError() == ERROR_ACCESS_DENIED ||
1231                 GetLastError() == ERROR_INVALID_FUNCTION),
1232        "DeleteFileA(\"nul\") returned ret=%d error=%d\n",ret,GetLastError());
1233 }
1234
1235 static void test_DeleteFileW( void )
1236 {
1237     BOOL ret;
1238     WCHAR pathW[MAX_PATH];
1239     WCHAR pathsubW[MAX_PATH];
1240     static const WCHAR dirW[] = {'d','e','l','e','t','e','f','i','l','e',0};
1241     static const WCHAR subdirW[] = {'\\','s','u','b',0};
1242     static const WCHAR emptyW[]={'\0'};
1243
1244     ret = DeleteFileW(NULL);
1245     if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1246     {
1247         win_skip("DeleteFileW is not available\n");
1248         return;
1249     }
1250     ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND,
1251        "DeleteFileW(NULL) returned ret=%d error=%d\n",ret,GetLastError());
1252
1253     ret = DeleteFileW(emptyW);
1254     ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND,
1255        "DeleteFileW(\"\") returned ret=%d error=%d\n",ret,GetLastError());
1256
1257     /* test DeleteFile on empty directory */
1258     ret = GetTempPathW(MAX_PATH, pathW);
1259     if (ret + sizeof(dirW)/sizeof(WCHAR)-1 + sizeof(subdirW)/sizeof(WCHAR)-1 >= MAX_PATH)
1260     {
1261         ok(0, "MAX_PATH exceeded in constructing paths\n");
1262         return;
1263     }
1264     lstrcatW(pathW, dirW);
1265     lstrcpyW(pathsubW, pathW);
1266     lstrcatW(pathsubW, subdirW);
1267     ret = CreateDirectoryW(pathW, NULL);
1268     ok(ret == TRUE, "couldn't create directory deletefile\n");
1269     ret = DeleteFileW(pathW);
1270     ok(ret == FALSE, "DeleteFile should fail for empty directories\n");
1271     ret = RemoveDirectoryW(pathW);
1272     ok(ret == TRUE, "expected to remove directory deletefile\n");
1273
1274     /* test DeleteFile on non-empty directory */
1275     ret = CreateDirectoryW(pathW, NULL);
1276     ok(ret == TRUE, "couldn't create directory deletefile\n");
1277     ret = CreateDirectoryW(pathsubW, NULL);
1278     ok(ret == TRUE, "couldn't create directory deletefile\\sub\n");
1279     ret = DeleteFileW(pathW);
1280     ok(ret == FALSE, "DeleteFile should fail for non-empty directories\n");
1281     ret = RemoveDirectoryW(pathsubW);
1282     ok(ret == TRUE, "expected to remove directory deletefile\\sub\n");
1283     ret = RemoveDirectoryW(pathW);
1284     ok(ret == TRUE, "expected to remove directory deletefile\n");
1285 }
1286
1287 #define IsDotDir(x)     ((x[0] == '.') && ((x[1] == 0) || ((x[1] == '.') && (x[2] == 0))))
1288
1289 static void test_MoveFileA(void)
1290 {
1291     char tempdir[MAX_PATH];
1292     char source[MAX_PATH], dest[MAX_PATH];
1293     static const char prefix[] = "pfx";
1294     HANDLE hfile;
1295     HANDLE hmapfile;
1296     DWORD ret;
1297     BOOL retok;
1298
1299     ret = GetTempPathA(MAX_PATH, tempdir);
1300     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
1301     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
1302
1303     ret = GetTempFileNameA(tempdir, prefix, 0, source);
1304     ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
1305
1306     ret = GetTempFileNameA(tempdir, prefix, 0, dest);
1307     ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
1308
1309     ret = MoveFileA(source, dest);
1310     ok(!ret && GetLastError() == ERROR_ALREADY_EXISTS,
1311        "MoveFileA: unexpected error %d\n", GetLastError());
1312
1313     ret = DeleteFileA(dest);
1314     ok(ret, "DeleteFileA: error %d\n", GetLastError());
1315
1316     hfile = CreateFileA(source, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
1317     ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
1318
1319     retok = WriteFile(hfile, prefix, sizeof(prefix), &ret, NULL );
1320     ok( retok && ret == sizeof(prefix),
1321        "WriteFile error %d\n", GetLastError());
1322
1323     hmapfile = CreateFileMapping(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
1324     ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError());
1325
1326     ret = MoveFileA(source, dest);
1327     todo_wine {
1328         ok(!ret, "MoveFileA: expected failure\n");
1329         ok(GetLastError() == ERROR_SHARING_VIOLATION ||
1330            broken(GetLastError() == ERROR_ACCESS_DENIED), /* Win9x and WinMe */
1331            "MoveFileA: expected ERROR_SHARING_VIOLATION, got %d\n", GetLastError());
1332     }
1333
1334     CloseHandle(hmapfile);
1335     CloseHandle(hfile);
1336
1337     /* if MoveFile succeeded, move back to dest */
1338     if (ret) MoveFile(dest, source);
1339
1340     hfile = CreateFileA(source, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
1341     ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
1342
1343     hmapfile = CreateFileMapping(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
1344     ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError());
1345
1346     ret = MoveFileA(source, dest);
1347     todo_wine {
1348         ok(!ret, "MoveFileA: expected failure\n");
1349         ok(GetLastError() == ERROR_SHARING_VIOLATION ||
1350            broken(GetLastError() == ERROR_ACCESS_DENIED), /* Win9x and WinMe */
1351            "MoveFileA: expected ERROR_SHARING_VIOLATION, got %d\n", GetLastError());
1352     }
1353
1354     CloseHandle(hmapfile);
1355     CloseHandle(hfile);
1356
1357     /* if MoveFile succeeded, move back to dest */
1358     if (ret) MoveFile(dest, source);
1359
1360     ret = MoveFileA(source, dest);
1361     ok(ret, "MoveFileA: failed, error %d\n", GetLastError());
1362
1363     lstrcatA(tempdir, "Remove Me");
1364     ret = CreateDirectoryA(tempdir, NULL);
1365     ok(ret == TRUE, "CreateDirectoryA failed\n");
1366
1367     lstrcpyA(source, dest);
1368     lstrcpyA(dest, tempdir);
1369     lstrcatA(dest, "\\wild?.*");
1370     /* FIXME: if we create a file with wildcards we can't delete it now that DeleteFile works correctly */
1371     ret = MoveFileA(source, dest);
1372     ok(!ret, "MoveFileA: shouldn't move to wildcard file\n");
1373     ok(GetLastError() == ERROR_INVALID_NAME || /* NT */
1374        GetLastError() == ERROR_FILE_NOT_FOUND, /* Win9x */
1375        "MoveFileA: with wildcards, unexpected error %d\n", GetLastError());
1376     if (ret || (GetLastError() != ERROR_INVALID_NAME))
1377     {
1378         WIN32_FIND_DATAA fd;
1379         char temppath[MAX_PATH];
1380         HANDLE hFind;
1381
1382         lstrcpyA(temppath, tempdir);
1383         lstrcatA(temppath, "\\*.*");
1384         hFind = FindFirstFileA(temppath, &fd);
1385         if (INVALID_HANDLE_VALUE != hFind)
1386         {
1387           LPSTR lpName;
1388           do
1389           {
1390             lpName = fd.cAlternateFileName;
1391             if (!lpName[0])
1392               lpName = fd.cFileName;
1393             ok(IsDotDir(lpName), "MoveFileA: wildcards file created!\n");
1394           }
1395           while (FindNextFileA(hFind, &fd));
1396           FindClose(hFind);
1397         }
1398     }
1399     ret = DeleteFileA(source);
1400     ok(ret, "DeleteFileA: error %d\n", GetLastError());
1401     ret = DeleteFileA(dest);
1402     ok(!ret, "DeleteFileA: error %d\n", GetLastError());
1403     ret = RemoveDirectoryA(tempdir);
1404     ok(ret, "DeleteDirectoryA: error %d\n", GetLastError());
1405 }
1406
1407 static void test_MoveFileW(void)
1408 {
1409     WCHAR temp_path[MAX_PATH];
1410     WCHAR source[MAX_PATH], dest[MAX_PATH];
1411     static const WCHAR prefix[] = {'p','f','x',0};
1412     DWORD ret;
1413
1414     ret = GetTempPathW(MAX_PATH, temp_path);
1415     if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1416     {
1417         win_skip("GetTempPathW is not available\n");
1418         return;
1419     }
1420     ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
1421     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
1422
1423     ret = GetTempFileNameW(temp_path, prefix, 0, source);
1424     ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
1425
1426     ret = GetTempFileNameW(temp_path, prefix, 0, dest);
1427     ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
1428
1429     ret = MoveFileW(source, dest);
1430     ok(!ret && GetLastError() == ERROR_ALREADY_EXISTS,
1431        "CopyFileW: unexpected error %d\n", GetLastError());
1432
1433     ret = DeleteFileW(source);
1434     ok(ret, "DeleteFileW: error %d\n", GetLastError());
1435     ret = DeleteFileW(dest);
1436     ok(ret, "DeleteFileW: error %d\n", GetLastError());
1437 }
1438
1439 #define PATTERN_OFFSET 0x10
1440
1441 static void test_offset_in_overlapped_structure(void)
1442 {
1443     HANDLE hFile;
1444     OVERLAPPED ov;
1445     DWORD done, offset;
1446     BOOL rc;
1447     BYTE buf[256], pattern[] = "TeSt";
1448     UINT i;
1449     char temp_path[MAX_PATH], temp_fname[MAX_PATH];
1450     BOOL ret;
1451
1452     ret =GetTempPathA(MAX_PATH, temp_path);
1453     ok( ret, "GetTempPathA error %d\n", GetLastError());
1454     ret =GetTempFileNameA(temp_path, "pfx", 0, temp_fname);
1455     ok( ret, "GetTempFileNameA error %d\n", GetLastError());
1456
1457     /*** Write File *****************************************************/
1458
1459     hFile = CreateFileA(temp_fname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
1460     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError());
1461
1462     for(i = 0; i < sizeof(buf); i++) buf[i] = i;
1463     ret = WriteFile(hFile, buf, sizeof(buf), &done, NULL);
1464     ok( ret, "WriteFile error %d\n", GetLastError());
1465     ok(done == sizeof(buf), "expected number of bytes written %u\n", done);
1466
1467     memset(&ov, 0, sizeof(ov));
1468     S(U(ov)).Offset = PATTERN_OFFSET;
1469     S(U(ov)).OffsetHigh = 0;
1470     rc=WriteFile(hFile, pattern, sizeof(pattern), &done, &ov);
1471     /* Win 9x does not support the overlapped I/O on files */
1472     if (rc || GetLastError()!=ERROR_INVALID_PARAMETER) {
1473         ok(rc, "WriteFile error %d\n", GetLastError());
1474         ok(done == sizeof(pattern), "expected number of bytes written %u\n", done);
1475         offset = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
1476         ok(offset == PATTERN_OFFSET + sizeof(pattern), "wrong file offset %d\n", offset);
1477
1478         S(U(ov)).Offset = sizeof(buf) * 2;
1479         S(U(ov)).OffsetHigh = 0;
1480         ret = WriteFile(hFile, pattern, sizeof(pattern), &done, &ov);
1481         ok( ret, "WriteFile error %d\n", GetLastError());
1482         ok(done == sizeof(pattern), "expected number of bytes written %u\n", done);
1483         offset = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
1484         ok(offset == sizeof(buf) * 2 + sizeof(pattern), "wrong file offset %d\n", offset);
1485     }
1486
1487     CloseHandle(hFile);
1488
1489     /*** Read File *****************************************************/
1490
1491     hFile = CreateFileA(temp_fname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
1492     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError());
1493
1494     memset(buf, 0, sizeof(buf));
1495     memset(&ov, 0, sizeof(ov));
1496     S(U(ov)).Offset = PATTERN_OFFSET;
1497     S(U(ov)).OffsetHigh = 0;
1498     rc=ReadFile(hFile, buf, sizeof(pattern), &done, &ov);
1499     /* Win 9x does not support the overlapped I/O on files */
1500     if (rc || GetLastError()!=ERROR_INVALID_PARAMETER) {
1501         ok(rc, "ReadFile error %d\n", GetLastError());
1502         ok(done == sizeof(pattern), "expected number of bytes read %u\n", done);
1503         offset = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
1504         ok(offset == PATTERN_OFFSET + sizeof(pattern), "wrong file offset %d\n", offset);
1505         ok(!memcmp(buf, pattern, sizeof(pattern)), "pattern match failed\n");
1506     }
1507
1508     CloseHandle(hFile);
1509
1510     ret = DeleteFileA(temp_fname);
1511     ok( ret, "DeleteFileA error %d\n", GetLastError());
1512 }
1513
1514 static void test_LockFile(void)
1515 {
1516     HANDLE handle;
1517     DWORD written;
1518     OVERLAPPED overlapped;
1519     int limited_LockFile;
1520     int limited_UnLockFile;
1521     BOOL ret;
1522
1523     handle = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1524                           FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1525                           CREATE_ALWAYS, 0, 0 );
1526     if (handle == INVALID_HANDLE_VALUE)
1527     {
1528         ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
1529         return;
1530     }
1531     ok( WriteFile( handle, sillytext, strlen(sillytext), &written, NULL ), "write failed\n" );
1532
1533     ok( LockFile( handle, 0, 0, 0, 0 ), "LockFile failed\n" );
1534     ok( UnlockFile( handle, 0, 0, 0, 0 ), "UnlockFile failed\n" );
1535
1536     limited_UnLockFile = 0;
1537     if (UnlockFile( handle, 0, 0, 0, 0 ))
1538     {
1539         limited_UnLockFile = 1;
1540     }
1541
1542     ok( LockFile( handle, 10, 0, 20, 0 ), "LockFile 10,20 failed\n" );
1543     /* overlapping locks must fail */
1544     ok( !LockFile( handle, 12, 0, 10, 0 ), "LockFile 12,10 succeeded\n" );
1545     ok( !LockFile( handle, 5, 0, 6, 0 ), "LockFile 5,6 succeeded\n" );
1546     /* non-overlapping locks must succeed */
1547     ok( LockFile( handle, 5, 0, 5, 0 ), "LockFile 5,5 failed\n" );
1548
1549     ok( !UnlockFile( handle, 10, 0, 10, 0 ), "UnlockFile 10,10 succeeded\n" );
1550     ok( UnlockFile( handle, 10, 0, 20, 0 ), "UnlockFile 10,20 failed\n" );
1551     ok( !UnlockFile( handle, 10, 0, 20, 0 ), "UnlockFile 10,20 again succeeded\n" );
1552     ok( UnlockFile( handle, 5, 0, 5, 0 ), "UnlockFile 5,5 failed\n" );
1553
1554     S(U(overlapped)).Offset = 100;
1555     S(U(overlapped)).OffsetHigh = 0;
1556     overlapped.hEvent = 0;
1557
1558     /* Test for broken LockFileEx a la Windows 95 OSR2. */
1559     if (LockFileEx( handle, 0, 0, 100, 0, &overlapped ))
1560     {
1561         /* LockFileEx is probably OK, test it more. */
1562         ok( LockFileEx( handle, 0, 0, 100, 0, &overlapped ),
1563             "LockFileEx 100,100 failed\n" );
1564     }
1565
1566     /* overlapping shared locks are OK */
1567     S(U(overlapped)).Offset = 150;
1568     limited_UnLockFile || ok( LockFileEx( handle, 0, 0, 100, 0, &overlapped ), "LockFileEx 150,100 failed\n" );
1569
1570     /* but exclusive is not */
1571     ok( !LockFileEx( handle, LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,
1572                      0, 50, 0, &overlapped ),
1573         "LockFileEx exclusive 150,50 succeeded\n" );
1574     if (!UnlockFileEx( handle, 0, 100, 0, &overlapped ))
1575     { /* UnLockFile is capable. */
1576         S(U(overlapped)).Offset = 100;
1577         ok( !UnlockFileEx( handle, 0, 100, 0, &overlapped ),
1578             "UnlockFileEx 150,100 again succeeded\n" );
1579     }
1580
1581     ret = LockFile( handle, 0, 0x10000000, 0, 0xf0000000 );
1582     if (ret)
1583     {
1584         ok( !LockFile( handle, ~0, ~0, 1, 0 ), "LockFile ~0,1 succeeded\n" );
1585         ok( !LockFile( handle, 0, 0x20000000, 20, 0 ), "LockFile 0x20000000,20 succeeded\n" );
1586         ok( UnlockFile( handle, 0, 0x10000000, 0, 0xf0000000 ), "UnlockFile failed\n" );
1587     }
1588     else  /* win9x */
1589         ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong LockFile error %u\n", GetLastError() );
1590
1591     /* wrap-around lock should not do anything */
1592     /* (but still succeeds on NT4 so we don't check result) */
1593     LockFile( handle, 0, 0x10000000, 0, 0xf0000001 );
1594
1595     limited_LockFile = 0;
1596     if (!LockFile( handle, ~0, ~0, 1, 0 ))
1597     {
1598         limited_LockFile = 1;
1599     }
1600
1601     limited_UnLockFile || ok( UnlockFile( handle, ~0, ~0, 1, 0 ), "Unlockfile ~0,1 failed\n" );
1602
1603     /* zero-byte lock */
1604     ok( LockFile( handle, 100, 0, 0, 0 ), "LockFile 100,0 failed\n" );
1605     if (!limited_LockFile) ok( !LockFile( handle, 98, 0, 4, 0 ), "LockFile 98,4 succeeded\n" );
1606     ok( LockFile( handle, 90, 0, 10, 0 ), "LockFile 90,10 failed\n" );
1607     if (!limited_LockFile) ok( !LockFile( handle, 100, 0, 10, 0 ), "LockFile 100,10 failed\n" );
1608
1609     ok( UnlockFile( handle, 90, 0, 10, 0 ), "UnlockFile 90,10 failed\n" );
1610     ok( !UnlockFile( handle, 100, 0, 10, 0 ), "UnlockFile 100,10 succeeded\n" );
1611
1612     ok( UnlockFile( handle, 100, 0, 0, 0 ), "UnlockFile 100,0 failed\n" );
1613
1614     CloseHandle( handle );
1615     DeleteFileA( filename );
1616 }
1617
1618 static BOOL create_fake_dll( LPCSTR filename )
1619 {
1620     IMAGE_DOS_HEADER *dos;
1621     IMAGE_NT_HEADERS *nt;
1622     IMAGE_SECTION_HEADER *sec;
1623     BYTE *buffer;
1624     DWORD lfanew = sizeof(*dos);
1625     DWORD size = lfanew + sizeof(*nt) + sizeof(*sec);
1626     DWORD written;
1627     BOOL ret;
1628
1629     HANDLE file = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1630     if (file == INVALID_HANDLE_VALUE) return FALSE;
1631
1632     buffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size );
1633
1634     dos = (IMAGE_DOS_HEADER *)buffer;
1635     dos->e_magic    = IMAGE_DOS_SIGNATURE;
1636     dos->e_cblp     = sizeof(*dos);
1637     dos->e_cp       = 1;
1638     dos->e_cparhdr  = lfanew / 16;
1639     dos->e_minalloc = 0;
1640     dos->e_maxalloc = 0xffff;
1641     dos->e_ss       = 0x0000;
1642     dos->e_sp       = 0x00b8;
1643     dos->e_lfarlc   = lfanew;
1644     dos->e_lfanew   = lfanew;
1645
1646     nt = (IMAGE_NT_HEADERS *)(buffer + lfanew);
1647     nt->Signature = IMAGE_NT_SIGNATURE;
1648 #if defined __i386__
1649     nt->FileHeader.Machine = IMAGE_FILE_MACHINE_I386;
1650 #elif defined __x86_64__
1651     nt->FileHeader.Machine = IMAGE_FILE_MACHINE_AMD64;
1652 #elif defined __powerpc__
1653     nt->FileHeader.Machine = IMAGE_FILE_MACHINE_POWERPC;
1654 #else
1655 # error You must specify the machine type
1656 #endif
1657     nt->FileHeader.NumberOfSections = 1;
1658     nt->FileHeader.SizeOfOptionalHeader = IMAGE_SIZEOF_NT_OPTIONAL_HEADER;
1659     nt->FileHeader.Characteristics = IMAGE_FILE_DLL | IMAGE_FILE_EXECUTABLE_IMAGE;
1660     nt->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
1661     nt->OptionalHeader.MajorLinkerVersion = 1;
1662     nt->OptionalHeader.MinorLinkerVersion = 0;
1663     nt->OptionalHeader.ImageBase = 0x10000000;
1664     nt->OptionalHeader.SectionAlignment = 0x1000;
1665     nt->OptionalHeader.FileAlignment = 0x1000;
1666     nt->OptionalHeader.MajorOperatingSystemVersion = 1;
1667     nt->OptionalHeader.MinorOperatingSystemVersion = 0;
1668     nt->OptionalHeader.MajorImageVersion = 1;
1669     nt->OptionalHeader.MinorImageVersion = 0;
1670     nt->OptionalHeader.MajorSubsystemVersion = 4;
1671     nt->OptionalHeader.MinorSubsystemVersion = 0;
1672     nt->OptionalHeader.SizeOfImage = 0x2000;
1673     nt->OptionalHeader.SizeOfHeaders = size;
1674     nt->OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
1675     nt->OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
1676
1677     sec = (IMAGE_SECTION_HEADER *)(nt + 1);
1678     memcpy( sec->Name, ".rodata", sizeof(".rodata") );
1679     sec->Misc.VirtualSize = 0x1000;
1680     sec->VirtualAddress   = 0x1000;
1681     sec->SizeOfRawData    = 0;
1682     sec->PointerToRawData = 0;
1683     sec->Characteristics  = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
1684
1685     ret = WriteFile( file, buffer, size, &written, NULL ) && written == size;
1686     HeapFree( GetProcessHeap(), 0, buffer );
1687     CloseHandle( file );
1688     return ret;
1689 }
1690
1691 static int is_sharing_compatible( DWORD access1, DWORD sharing1, DWORD access2, DWORD sharing2, BOOL is_win9x )
1692 {
1693     if (!is_win9x)
1694     {
1695         if (!access1) sharing1 = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
1696         if (!access2) sharing2 = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
1697     }
1698     else
1699     {
1700         access1 &= ~DELETE;
1701         if (!access1) access1 = GENERIC_READ;
1702
1703         access2 &= ~DELETE;
1704         if (!access2) access2 = GENERIC_READ;
1705     }
1706
1707     if ((access1 & GENERIC_READ) && !(sharing2 & FILE_SHARE_READ)) return 0;
1708     if ((access1 & GENERIC_WRITE) && !(sharing2 & FILE_SHARE_WRITE)) return 0;
1709     if ((access1 & DELETE) && !(sharing2 & FILE_SHARE_DELETE)) return 0;
1710     if ((access2 & GENERIC_READ) && !(sharing1 & FILE_SHARE_READ)) return 0;
1711     if ((access2 & GENERIC_WRITE) && !(sharing1 & FILE_SHARE_WRITE)) return 0;
1712     if ((access2 & DELETE) && !(sharing1 & FILE_SHARE_DELETE)) return 0;
1713     return 1;
1714 }
1715
1716 static int is_sharing_map_compatible( DWORD map_access, DWORD access2, DWORD sharing2 )
1717 {
1718     if ((map_access == PAGE_READWRITE || map_access == PAGE_EXECUTE_READWRITE) &&
1719         !(sharing2 & FILE_SHARE_WRITE)) return 0;
1720     if ((map_access & SEC_IMAGE) && (access2 & GENERIC_WRITE)) return 0;
1721     return 1;
1722 }
1723
1724 static void test_file_sharing(void)
1725 {
1726     static const DWORD access_modes[] =
1727         { 0, GENERIC_READ, GENERIC_WRITE, GENERIC_READ|GENERIC_WRITE,
1728           DELETE, GENERIC_READ|DELETE, GENERIC_WRITE|DELETE, GENERIC_READ|GENERIC_WRITE|DELETE };
1729     static const DWORD sharing_modes[] =
1730         { 0, FILE_SHARE_READ,
1731           FILE_SHARE_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
1732           FILE_SHARE_DELETE, FILE_SHARE_READ|FILE_SHARE_DELETE,
1733           FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE };
1734     static const DWORD mapping_modes[] =
1735         { PAGE_READONLY, PAGE_WRITECOPY, PAGE_READWRITE, SEC_IMAGE | PAGE_WRITECOPY };
1736     int a1, s1, a2, s2;
1737     int ret;
1738     HANDLE h, h2;
1739     BOOL is_win9x = FALSE;
1740
1741     /* make sure the file exists */
1742     if (!create_fake_dll( filename ))
1743     {
1744         ok(0, "couldn't create file \"%s\" (err=%d)\n", filename, GetLastError());
1745         return;
1746     }
1747     is_win9x = GetFileAttributesW(filenameW) == INVALID_FILE_ATTRIBUTES;
1748
1749     for (a1 = 0; a1 < sizeof(access_modes)/sizeof(access_modes[0]); a1++)
1750     {
1751         for (s1 = 0; s1 < sizeof(sharing_modes)/sizeof(sharing_modes[0]); s1++)
1752         {
1753             /* Win9x doesn't support FILE_SHARE_DELETE */
1754             if (is_win9x && (sharing_modes[s1] & FILE_SHARE_DELETE))
1755                 continue;
1756
1757             SetLastError(0xdeadbeef);
1758             h = CreateFileA( filename, access_modes[a1], sharing_modes[s1],
1759                              NULL, OPEN_EXISTING, 0, 0 );
1760             if (h == INVALID_HANDLE_VALUE)
1761             {
1762                 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
1763                 return;
1764             }
1765             for (a2 = 0; a2 < sizeof(access_modes)/sizeof(access_modes[0]); a2++)
1766             {
1767                 for (s2 = 0; s2 < sizeof(sharing_modes)/sizeof(sharing_modes[0]); s2++)
1768                 {
1769                     /* Win9x doesn't support FILE_SHARE_DELETE */
1770                     if (is_win9x && (sharing_modes[s2] & FILE_SHARE_DELETE))
1771                         continue;
1772
1773                     SetLastError(0xdeadbeef);
1774                     h2 = CreateFileA( filename, access_modes[a2], sharing_modes[s2],
1775                                       NULL, OPEN_EXISTING, 0, 0 );
1776                     ret = GetLastError();
1777                     if (is_sharing_compatible( access_modes[a1], sharing_modes[s1],
1778                                                access_modes[a2], sharing_modes[s2], is_win9x ))
1779                     {
1780                         ok( h2 != INVALID_HANDLE_VALUE,
1781                             "open failed for modes %x/%x/%x/%x\n",
1782                             access_modes[a1], sharing_modes[s1],
1783                             access_modes[a2], sharing_modes[s2] );
1784                         ok( ret == 0xdeadbeef /* Win9x */ ||
1785                             ret == 0, /* XP */
1786                              "wrong error code %d\n", ret );
1787                     }
1788                     else
1789                     {
1790                         ok( h2 == INVALID_HANDLE_VALUE,
1791                             "open succeeded for modes %x/%x/%x/%x\n",
1792                             access_modes[a1], sharing_modes[s1],
1793                             access_modes[a2], sharing_modes[s2] );
1794                          ok( ret == ERROR_SHARING_VIOLATION,
1795                              "wrong error code %d\n", ret );
1796                     }
1797                     if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 );
1798                 }
1799             }
1800             CloseHandle( h );
1801         }
1802     }
1803
1804     for (a1 = 0; a1 < sizeof(mapping_modes)/sizeof(mapping_modes[0]); a1++)
1805     {
1806         HANDLE m;
1807
1808         create_fake_dll( filename );
1809         SetLastError(0xdeadbeef);
1810         h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
1811         if (h == INVALID_HANDLE_VALUE)
1812         {
1813             ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
1814             return;
1815         }
1816         m = CreateFileMappingA( h, NULL, mapping_modes[a1], 0, 0, NULL );
1817         ok( m != 0, "failed to create mapping %x err %u\n", mapping_modes[a1], GetLastError() );
1818         CloseHandle( h );
1819         if (!m) continue;
1820
1821         for (a2 = 0; a2 < sizeof(access_modes)/sizeof(access_modes[0]); a2++)
1822         {
1823             for (s2 = 0; s2 < sizeof(sharing_modes)/sizeof(sharing_modes[0]); s2++)
1824             {
1825                 /* Win9x doesn't support FILE_SHARE_DELETE */
1826                 if (is_win9x && (sharing_modes[s2] & FILE_SHARE_DELETE))
1827                     continue;
1828
1829                 SetLastError(0xdeadbeef);
1830                 h2 = CreateFileA( filename, access_modes[a2], sharing_modes[s2],
1831                                   NULL, OPEN_EXISTING, 0, 0 );
1832
1833                 ret = GetLastError();
1834                 if (h2 == INVALID_HANDLE_VALUE)
1835                 {
1836                     if (is_sharing_map_compatible(mapping_modes[a1], access_modes[a2], sharing_modes[s2]))
1837                         ok( is_win9x, /* there's no sharing at all with a mapping on win9x */
1838                             "open failed for modes map %x/%x/%x\n",
1839                             mapping_modes[a1], access_modes[a2], sharing_modes[s2] );
1840                     ok( ret == ERROR_SHARING_VIOLATION,
1841                         "wrong error code %d\n", ret );
1842                 }
1843                 else
1844                 {
1845                     if (!is_sharing_map_compatible(mapping_modes[a1], access_modes[a2], sharing_modes[s2]))
1846                         ok( broken(1),  /* no checking on nt4 */
1847                             "open succeeded for modes map %x/%x/%x\n",
1848                             mapping_modes[a1], access_modes[a2], sharing_modes[s2] );
1849                     ok( ret == 0xdeadbeef /* Win9x */ ||
1850                         ret == 0, /* XP */
1851                         "wrong error code %d\n", ret );
1852                     CloseHandle( h2 );
1853                 }
1854             }
1855         }
1856
1857         /* try CREATE_ALWAYS over an existing mapping */
1858         SetLastError(0xdeadbeef);
1859         h2 = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
1860                           NULL, CREATE_ALWAYS, 0, 0 );
1861         ret = GetLastError();
1862         if ((mapping_modes[a1] & SEC_IMAGE) || is_win9x)
1863         {
1864             ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] );
1865             ok( ret == ERROR_SHARING_VIOLATION, "wrong error code %d for %x\n", ret, mapping_modes[a1] );
1866         }
1867         else
1868         {
1869             ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] );
1870             ok( ret == ERROR_USER_MAPPED_FILE, "wrong error code %d for %x\n", ret, mapping_modes[a1] );
1871         }
1872         if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 );
1873
1874         /* try DELETE_ON_CLOSE over an existing mapping */
1875         SetLastError(0xdeadbeef);
1876         h2 = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1877                           NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0 );
1878         ret = GetLastError();
1879         if (is_win9x)
1880         {
1881             ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] );
1882             ok( ret == ERROR_SHARING_VIOLATION, "wrong error code %d for %x\n", ret, mapping_modes[a1] );
1883         }
1884         else if (mapping_modes[a1] & SEC_IMAGE)
1885         {
1886             ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] );
1887             ok( ret == ERROR_ACCESS_DENIED, "wrong error code %d for %x\n", ret, mapping_modes[a1] );
1888         }
1889         else
1890         {
1891             ok( h2 != INVALID_HANDLE_VALUE, "open failed for map %x err %u\n", mapping_modes[a1], ret );
1892         }
1893         if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 );
1894
1895         CloseHandle( m );
1896     }
1897
1898     SetLastError(0xdeadbeef);
1899     h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, 0 );
1900     ok( h != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError() );
1901
1902     SetLastError(0xdeadbeef);
1903     h2 = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
1904     ok( h2 == INVALID_HANDLE_VALUE, "CreateFileA should fail\n");
1905     ok( GetLastError() == ERROR_SHARING_VIOLATION, "wrong error code %d\n", GetLastError() );
1906
1907     h2 = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
1908     ok( h2 != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError() );
1909
1910     CloseHandle(h);
1911     CloseHandle(h2);
1912
1913     DeleteFileA( filename );
1914 }
1915
1916 static char get_windows_drive(void)
1917 {
1918     char windowsdir[MAX_PATH];
1919     GetWindowsDirectory(windowsdir, sizeof(windowsdir));
1920     return windowsdir[0];
1921 }
1922
1923 static void test_FindFirstFileA(void)
1924 {
1925     HANDLE handle;
1926     WIN32_FIND_DATAA data;
1927     int err;
1928     char buffer[5] = "C:\\";
1929     char buffer2[100];
1930     char nonexistent[MAX_PATH];
1931
1932     /* try FindFirstFileA on "C:\" */
1933     buffer[0] = get_windows_drive();
1934     
1935     SetLastError( 0xdeadbeaf );
1936     handle = FindFirstFileA(buffer, &data);
1937     err = GetLastError();
1938     ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on root directory should fail\n" );
1939     ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err );
1940
1941     /* try FindFirstFileA on "C:\*" */
1942     strcpy(buffer2, buffer);
1943     strcat(buffer2, "*");
1944     handle = FindFirstFileA(buffer2, &data);
1945     ok ( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s should succeed\n", buffer2 );
1946     ok ( strcmp( data.cFileName, "." ) && strcmp( data.cFileName, ".." ),
1947          "FindFirstFile shouldn't return '%s' in drive root\n", data.cFileName );
1948     if (FindNextFileA( handle, &data ))
1949         ok ( strcmp( data.cFileName, "." ) && strcmp( data.cFileName, ".." ),
1950              "FindNextFile shouldn't return '%s' in drive root\n", data.cFileName );
1951     ok ( FindClose(handle) == TRUE, "Failed to close handle %s\n", buffer2 );
1952
1953     /* try FindFirstFileA on windows dir */
1954     GetWindowsDirectory( buffer2, sizeof(buffer2) );
1955     strcat(buffer2, "\\*");
1956     handle = FindFirstFileA(buffer2, &data);
1957     ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s should succeed\n", buffer2 );
1958     ok( !strcmp( data.cFileName, "." ), "FindFirstFile should return '.' first\n" );
1959     ok( FindNextFileA( handle, &data ), "FindNextFile failed\n" );
1960     ok( !strcmp( data.cFileName, ".." ), "FindNextFile should return '..' as second entry\n" );
1961     while (FindNextFileA( handle, &data ))
1962         ok ( strcmp( data.cFileName, "." ) && strcmp( data.cFileName, ".." ),
1963              "FindNextFile shouldn't return '%s'\n", data.cFileName );
1964     ok ( FindClose(handle) == TRUE, "Failed to close handle %s\n", buffer2 );
1965
1966     /* try FindFirstFileA on "C:\foo\" */
1967     SetLastError( 0xdeadbeaf );
1968     if (!GetTempFileNameA( buffer, "foo", 0, nonexistent ) && GetLastError() == ERROR_ACCESS_DENIED)
1969     {
1970         char tmp[MAX_PATH];
1971         GetTempPathA( sizeof(tmp), tmp );
1972         GetTempFileNameA( tmp, "foo", 0, nonexistent );
1973     }
1974     DeleteFileA( nonexistent );
1975     strcpy(buffer2, nonexistent);
1976     strcat(buffer2, "\\");
1977     handle = FindFirstFileA(buffer2, &data);
1978     err = GetLastError();
1979     ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
1980     todo_wine {
1981         ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
1982     }
1983
1984     /* try FindFirstFileA on "C:\foo\bar.txt" */
1985     SetLastError( 0xdeadbeaf );
1986     strcpy(buffer2, nonexistent);
1987     strcat(buffer2, "\\bar.txt");
1988     handle = FindFirstFileA(buffer2, &data);
1989     err = GetLastError();
1990     ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
1991     ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
1992
1993     /* try FindFirstFileA on "C:\foo\*.*" */
1994     SetLastError( 0xdeadbeaf );
1995     strcpy(buffer2, nonexistent);
1996     strcat(buffer2, "\\*.*");
1997     handle = FindFirstFileA(buffer2, &data);
1998     err = GetLastError();
1999     ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2000     ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2001
2002     /* try FindFirstFileA on "foo\bar.txt" */
2003     SetLastError( 0xdeadbeaf );
2004     strcpy(buffer2, nonexistent + 3);
2005     strcat(buffer2, "\\bar.txt");
2006     handle = FindFirstFileA(buffer2, &data);
2007     err = GetLastError();
2008     ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2009     ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2010
2011     /* try FindFirstFileA on "c:\nul" */
2012     SetLastError( 0xdeadbeaf );
2013     strcpy(buffer2, buffer);
2014     strcat(buffer2, "nul");
2015     handle = FindFirstFileA(buffer2, &data);
2016     err = GetLastError();
2017     ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s failed\n", buffer2 );
2018     ok( 0 == lstrcmpiA(data.cFileName, "nul"), "wrong name %s\n", data.cFileName );
2019     ok( FILE_ATTRIBUTE_ARCHIVE == data.dwFileAttributes ||
2020         FILE_ATTRIBUTE_DEVICE == data.dwFileAttributes /* Win9x */,
2021         "wrong attributes %x\n", data.dwFileAttributes );
2022     if (data.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE)
2023     {
2024         ok( 0 == data.nFileSizeHigh, "wrong size %d\n", data.nFileSizeHigh );
2025         ok( 0 == data.nFileSizeLow, "wrong size %d\n", data.nFileSizeLow );
2026     }
2027     SetLastError( 0xdeadbeaf );
2028     ok( !FindNextFileA( handle, &data ), "FindNextFileA succeeded\n" );
2029     ok( GetLastError() == ERROR_NO_MORE_FILES, "bad error %d\n", GetLastError() );
2030     ok( FindClose( handle ), "failed to close handle\n" );
2031
2032     /* try FindFirstFileA on "lpt1" */
2033     SetLastError( 0xdeadbeaf );
2034     strcpy(buffer2, "lpt1");
2035     handle = FindFirstFileA(buffer2, &data);
2036     err = GetLastError();
2037     ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s failed\n", buffer2 );
2038     ok( 0 == lstrcmpiA(data.cFileName, "lpt1"), "wrong name %s\n", data.cFileName );
2039     ok( FILE_ATTRIBUTE_ARCHIVE == data.dwFileAttributes ||
2040         FILE_ATTRIBUTE_DEVICE == data.dwFileAttributes /* Win9x */,
2041         "wrong attributes %x\n", data.dwFileAttributes );
2042     if (data.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE)
2043     {
2044         ok( 0 == data.nFileSizeHigh, "wrong size %d\n", data.nFileSizeHigh );
2045         ok( 0 == data.nFileSizeLow, "wrong size %d\n", data.nFileSizeLow );
2046     }
2047     SetLastError( 0xdeadbeaf );
2048     ok( !FindNextFileA( handle, &data ), "FindNextFileA succeeded\n" );
2049     ok( GetLastError() == ERROR_NO_MORE_FILES, "bad error %d\n", GetLastError() );
2050     ok( FindClose( handle ), "failed to close handle\n" );
2051
2052     /* try FindFirstFileA on "c:\nul\*" */
2053     SetLastError( 0xdeadbeaf );
2054     strcpy(buffer2, buffer);
2055     strcat(buffer2, "nul\\*");
2056     handle = FindFirstFileA(buffer2, &data);
2057     err = GetLastError();
2058     ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2059     ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2060
2061     /* try FindFirstFileA on "c:\nul*" */
2062     SetLastError( 0xdeadbeaf );
2063     strcpy(buffer2, buffer);
2064     strcat(buffer2, "nul*");
2065     handle = FindFirstFileA(buffer2, &data);
2066     err = GetLastError();
2067     ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2068     ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err );
2069
2070     /* try FindFirstFileA on "c:\foo\bar\nul" */
2071     SetLastError( 0xdeadbeaf );
2072     strcpy(buffer2, buffer);
2073     strcat(buffer2, "foo\\bar\\nul");
2074     handle = FindFirstFileA(buffer2, &data);
2075     err = GetLastError();
2076     ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2077     ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2078
2079     /* try FindFirstFileA on "c:\foo\nul\bar" */
2080     SetLastError( 0xdeadbeaf );
2081     strcpy(buffer2, buffer);
2082     strcat(buffer2, "foo\\nul\\bar");
2083     handle = FindFirstFileA(buffer2, &data);
2084     err = GetLastError();
2085     ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2086     ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2087 }
2088
2089 static void test_FindNextFileA(void)
2090 {
2091     HANDLE handle;
2092     WIN32_FIND_DATAA search_results;
2093     int err;
2094     char buffer[5] = "C:\\*";
2095
2096     buffer[0] = get_windows_drive();
2097     handle = FindFirstFileA(buffer,&search_results);
2098     ok ( handle != INVALID_HANDLE_VALUE, "FindFirstFile on C:\\* should succeed\n" );
2099     while (FindNextFile(handle, &search_results))
2100     {
2101         /* get to the end of the files */
2102     }
2103     ok ( FindClose(handle) == TRUE, "Failed to close handle\n");
2104     err = GetLastError();
2105     ok ( err == ERROR_NO_MORE_FILES, "GetLastError should return ERROR_NO_MORE_FILES\n");
2106 }
2107
2108 static void test_FindFirstFileExA(FINDEX_SEARCH_OPS search_ops)
2109 {
2110     WIN32_FIND_DATAA search_results;
2111     HANDLE handle;
2112     BOOL ret;
2113
2114     if (!pFindFirstFileExA)
2115     {
2116         win_skip("FindFirstFileExA() is missing\n");
2117         return;
2118     }
2119
2120     CreateDirectoryA("test-dir", NULL);
2121     _lclose(_lcreat("test-dir\\file1", 0));
2122     _lclose(_lcreat("test-dir\\file2", 0));
2123     CreateDirectoryA("test-dir\\dir1", NULL);
2124     SetLastError(0xdeadbeef);
2125     handle = pFindFirstFileExA("test-dir\\*", FindExInfoStandard, &search_results, search_ops, NULL, 0);
2126     if (handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
2127     {
2128         win_skip("FindFirstFileExA is not implemented\n");
2129         goto cleanup;
2130     }
2131     ok(handle != INVALID_HANDLE_VALUE, "FindFirstFile failed (err=%u)\n", GetLastError());
2132     ok(strcmp(search_results.cFileName, ".") == 0, "First entry should be '.', is %s\n", search_results.cFileName);
2133
2134 #define CHECK_NAME(fn) (strcmp((fn), "file1") == 0 || strcmp((fn), "file2") == 0 || strcmp((fn), "dir1") == 0)
2135
2136     ok(FindNextFile(handle, &search_results), "Fetching second file failed\n");
2137     ok(strcmp(search_results.cFileName, "..") == 0, "Second entry should be '..' is %s\n", search_results.cFileName);
2138
2139     ok(FindNextFile(handle, &search_results), "Fetching third file failed\n");
2140     ok(CHECK_NAME(search_results.cFileName), "Invalid third entry - %s\n", search_results.cFileName);
2141
2142     SetLastError(0xdeadbeef);
2143     ret = FindNextFile(handle, &search_results);
2144     if (!ret && (GetLastError() == ERROR_NO_MORE_FILES) && (search_ops == FindExSearchLimitToDirectories))
2145     {
2146         skip("File system supports directory filtering\n");
2147         /* Results from the previous call are not cleared */
2148         ok(strcmp(search_results.cFileName, "dir1") == 0, "Third entry should be 'dir1' is %s\n", search_results.cFileName);
2149         FindClose( handle );
2150         goto cleanup;
2151     }
2152
2153     ok(ret, "Fetching fourth file failed\n");
2154     ok(CHECK_NAME(search_results.cFileName), "Invalid fourth entry - %s\n", search_results.cFileName);
2155
2156     ok(FindNextFile(handle, &search_results), "Fetching fifth file failed\n");
2157     ok(CHECK_NAME(search_results.cFileName), "Invalid fifth entry - %s\n", search_results.cFileName);
2158
2159 #undef CHECK_NAME
2160
2161     ok(FindNextFile(handle, &search_results) == FALSE, "Fetching sixth file should fail\n");
2162
2163     FindClose( handle );
2164
2165 cleanup:
2166     DeleteFileA("test-dir\\file1");
2167     DeleteFileA("test-dir\\file2");
2168     RemoveDirectoryA("test-dir\\dir1");
2169     RemoveDirectoryA("test-dir");
2170 }
2171
2172 static int test_Mapfile_createtemp(HANDLE *handle)
2173 {
2174     SetFileAttributesA(filename,FILE_ATTRIBUTE_NORMAL);
2175     DeleteFile(filename);
2176     *handle = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, 0,
2177                          CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2178     if (*handle != INVALID_HANDLE_VALUE) {
2179
2180         return 1;
2181     }
2182
2183     return 0;
2184 }
2185
2186 static void test_MapFile(void)
2187 {
2188     HANDLE handle;
2189     HANDLE hmap;
2190
2191     ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
2192
2193     hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0x1000, "named_file_map" );
2194     ok( hmap != NULL, "mapping should work, I named it!\n" );
2195
2196     ok( CloseHandle( hmap ), "can't close mapping handle\n");
2197
2198     /* We have to close file before we try new stuff with mapping again.
2199        Else we would always succeed on XP or block descriptors on 95. */
2200     hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
2201     ok( hmap != NULL, "We should still be able to map!\n" );
2202     ok( CloseHandle( hmap ), "can't close mapping handle\n");
2203     ok( CloseHandle( handle ), "can't close file handle\n");
2204     handle = NULL;
2205
2206     ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
2207
2208     hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
2209     ok( hmap == NULL, "mapped zero size file\n");
2210     ok( GetLastError() == ERROR_FILE_INVALID, "not ERROR_FILE_INVALID\n");
2211
2212     hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0x80000000, 0, NULL );
2213     ok( hmap == NULL || broken(hmap != NULL) /* NT4 */, "mapping should fail\n");
2214     /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */
2215     if ( hmap )
2216         CloseHandle( hmap );
2217
2218     hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0x80000000, 0x10000, NULL );
2219     ok( hmap == NULL || broken(hmap != NULL) /* NT4 */, "mapping should fail\n");
2220     /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */
2221     if ( hmap )
2222         CloseHandle( hmap );
2223
2224     /* On XP you can now map again, on Win 95 you cannot. */
2225
2226     ok( CloseHandle( handle ), "can't close file handle\n");
2227     ok( DeleteFileA( filename ), "DeleteFile failed after map\n" );
2228 }
2229
2230 static void test_GetFileType(void)
2231 {
2232     DWORD type;
2233     HANDLE h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2234     ok( h != INVALID_HANDLE_VALUE, "open %s failed\n", filename );
2235     type = GetFileType(h);
2236     ok( type == FILE_TYPE_DISK, "expected type disk got %d\n", type );
2237     CloseHandle( h );
2238     h = CreateFileA( "nul", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2239     ok( h != INVALID_HANDLE_VALUE, "open nul failed\n" );
2240     type = GetFileType(h);
2241     ok( type == FILE_TYPE_CHAR, "expected type char for nul got %d\n", type );
2242     CloseHandle( h );
2243     DeleteFileA( filename );
2244 }
2245
2246 static int completion_count;
2247
2248 static void CALLBACK FileIOComplete(DWORD dwError, DWORD dwBytes, LPOVERLAPPED ovl)
2249 {
2250 /*      printf("(%ld, %ld, %p { %ld, %ld, %ld, %ld, %p })\n", dwError, dwBytes, ovl, ovl->Internal, ovl->InternalHigh, ovl->Offset, ovl->OffsetHigh, ovl->hEvent);*/
2251         ReleaseSemaphore(ovl->hEvent, 1, NULL);
2252         completion_count++;
2253 }
2254
2255 static void test_async_file_errors(void)
2256 {
2257     char szFile[MAX_PATH];
2258     HANDLE hSem = CreateSemaphoreW(NULL, 1, 1, NULL);
2259     HANDLE hFile;
2260     LPVOID lpBuffer = HeapAlloc(GetProcessHeap(), 0, 4096);
2261     OVERLAPPED ovl;
2262     S(U(ovl)).Offset = 0;
2263     S(U(ovl)).OffsetHigh = 0;
2264     ovl.hEvent = hSem;
2265     completion_count = 0;
2266     szFile[0] = '\0';
2267     GetWindowsDirectoryA(szFile, sizeof(szFile)/sizeof(szFile[0])-1-strlen("\\win.ini"));
2268     strcat(szFile, "\\win.ini");
2269     hFile = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
2270                         NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
2271     if (hFile == INVALID_HANDLE_VALUE)  /* win9x doesn't like FILE_SHARE_DELETE */
2272         hFile = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
2273                             NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
2274     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA(%s ...) failed\n", szFile);
2275     while (TRUE)
2276     {
2277         BOOL res;
2278         DWORD count;
2279         while (WaitForSingleObjectEx(hSem, INFINITE, TRUE) == WAIT_IO_COMPLETION)
2280             ;
2281         res = ReadFileEx(hFile, lpBuffer, 4096, &ovl, FileIOComplete);
2282         /*printf("Offset = %ld, result = %s\n", ovl.Offset, res ? "TRUE" : "FALSE");*/
2283         if (!res)
2284             break;
2285         if (!GetOverlappedResult(hFile, &ovl, &count, FALSE))
2286             break;
2287         S(U(ovl)).Offset += count;
2288         /* i/o completion routine only called if ReadFileEx returned success.
2289          * we only care about violations of this rule so undo what should have
2290          * been done */
2291         completion_count--;
2292     }
2293     ok(completion_count == 0, "completion routine should only be called when ReadFileEx succeeds (this rule was violated %d times)\n", completion_count);
2294     /*printf("Error = %ld\n", GetLastError());*/
2295     HeapFree(GetProcessHeap(), 0, lpBuffer);
2296 }
2297
2298 static void test_read_write(void)
2299 {
2300     DWORD bytes, ret, old_prot;
2301     HANDLE hFile;
2302     char temp_path[MAX_PATH];
2303     char filename[MAX_PATH];
2304     char *mem;
2305     static const char prefix[] = "pfx";
2306
2307     ret = GetTempPathA(MAX_PATH, temp_path);
2308     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
2309     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
2310
2311     ret = GetTempFileNameA(temp_path, prefix, 0, filename);
2312     ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
2313
2314     hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
2315                         CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
2316     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
2317
2318     SetLastError(12345678);
2319     bytes = 12345678;
2320     ret = WriteFile(hFile, NULL, 0, &bytes, NULL);
2321     ok(ret && GetLastError() == 12345678,
2322         "ret = %d, error %d\n", ret, GetLastError());
2323     ok(!bytes, "bytes = %d\n", bytes);
2324
2325     SetLastError(12345678);
2326     bytes = 12345678;
2327     ret = WriteFile(hFile, NULL, 10, &bytes, NULL);
2328     ok((!ret && GetLastError() == ERROR_INVALID_USER_BUFFER) || /* Win2k */
2329         (ret && GetLastError() == 12345678), /* Win9x */
2330         "ret = %d, error %d\n", ret, GetLastError());
2331     ok(!bytes || /* Win2k */
2332         bytes == 10, /* Win9x */
2333         "bytes = %d\n", bytes);
2334
2335     /* make sure the file contains data */
2336     WriteFile(hFile, "this is the test data", 21, &bytes, NULL);
2337     SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
2338
2339     SetLastError(12345678);
2340     bytes = 12345678;
2341     ret = ReadFile(hFile, NULL, 0, &bytes, NULL);
2342     ok(ret && GetLastError() == 12345678,
2343         "ret = %d, error %d\n", ret, GetLastError());
2344     ok(!bytes, "bytes = %d\n", bytes);
2345
2346     SetLastError(12345678);
2347     bytes = 12345678;
2348     ret = ReadFile(hFile, NULL, 10, &bytes, NULL);
2349     ok(!ret && (GetLastError() == ERROR_NOACCESS || /* Win2k */
2350                 GetLastError() == ERROR_INVALID_PARAMETER), /* Win9x */
2351         "ret = %d, error %d\n", ret, GetLastError());
2352     ok(!bytes, "bytes = %d\n", bytes);
2353
2354     /* test passing protected memory as buffer */
2355
2356     mem = VirtualAlloc( NULL, 0x4000, MEM_COMMIT, PAGE_READWRITE );
2357     ok( mem != NULL, "failed to allocate virtual mem error %u\n", GetLastError() );
2358
2359     ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
2360     ok( ret, "WriteFile failed error %u\n", GetLastError() );
2361     ok( bytes == 0x4000, "only wrote %x bytes\n", bytes );
2362
2363     ret = VirtualProtect( mem + 0x2000, 0x2000, PAGE_NOACCESS, &old_prot );
2364     ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2365
2366     ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
2367     ok( !ret, "WriteFile succeeded\n" );
2368     ok( GetLastError() == ERROR_INVALID_USER_BUFFER ||
2369         GetLastError() == ERROR_INVALID_PARAMETER,  /* win9x */
2370         "wrong error %u\n", GetLastError() );
2371     ok( bytes == 0, "wrote %x bytes\n", bytes );
2372
2373     ret = WriteFile( (HANDLE)0xdead, mem, 0x4000, &bytes, NULL );
2374     ok( !ret, "WriteFile succeeded\n" );
2375     ok( GetLastError() == ERROR_INVALID_HANDLE || /* handle is checked before buffer on NT */
2376         GetLastError() == ERROR_INVALID_PARAMETER,  /* win9x */
2377         "wrong error %u\n", GetLastError() );
2378     ok( bytes == 0, "wrote %x bytes\n", bytes );
2379
2380     ret = VirtualProtect( mem, 0x2000, PAGE_NOACCESS, &old_prot );
2381     ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2382
2383     ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
2384     ok( !ret, "WriteFile succeeded\n" );
2385     ok( GetLastError() == ERROR_INVALID_USER_BUFFER ||
2386         GetLastError() == ERROR_INVALID_PARAMETER,  /* win9x */
2387         "wrong error %u\n", GetLastError() );
2388     ok( bytes == 0, "wrote %x bytes\n", bytes );
2389
2390     SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
2391
2392     ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2393     ok( !ret, "ReadFile succeeded\n" );
2394     ok( GetLastError() == ERROR_NOACCESS ||
2395         GetLastError() == ERROR_INVALID_PARAMETER,  /* win9x */
2396         "wrong error %u\n", GetLastError() );
2397     ok( bytes == 0, "read %x bytes\n", bytes );
2398
2399     ret = VirtualProtect( mem, 0x2000, PAGE_READONLY, &old_prot );
2400     ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2401
2402     ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2403     ok( !ret, "ReadFile succeeded\n" );
2404     ok( GetLastError() == ERROR_NOACCESS ||
2405         GetLastError() == ERROR_INVALID_PARAMETER,  /* win9x */
2406         "wrong error %u\n", GetLastError() );
2407     ok( bytes == 0, "read %x bytes\n", bytes );
2408
2409     ret = VirtualProtect( mem, 0x2000, PAGE_READWRITE, &old_prot );
2410     ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2411
2412     ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2413     ok( !ret, "ReadFile succeeded\n" );
2414     ok( GetLastError() == ERROR_NOACCESS ||
2415         GetLastError() == ERROR_INVALID_PARAMETER,  /* win9x */
2416         "wrong error %u\n", GetLastError() );
2417     ok( bytes == 0, "read %x bytes\n", bytes );
2418
2419     SetFilePointer( hFile, 0x1234, NULL, FILE_BEGIN );
2420     SetEndOfFile( hFile );
2421     SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
2422
2423     ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2424     ok( !ret, "ReadFile succeeded\n" );
2425     ok( GetLastError() == ERROR_NOACCESS ||
2426         GetLastError() == ERROR_INVALID_PARAMETER,  /* win9x */
2427         "wrong error %u\n", GetLastError() );
2428     ok( bytes == 0, "read %x bytes\n", bytes );
2429
2430     ret = ReadFile( hFile, mem, 0x2000, &bytes, NULL );
2431     ok( ret, "ReadFile failed error %u\n", GetLastError() );
2432     ok( bytes == 0x1234, "read %x bytes\n", bytes );
2433
2434     ret = ReadFile( hFile, NULL, 1, &bytes, NULL );
2435     ok( !ret, "ReadFile succeeded\n" );
2436     ok( GetLastError() == ERROR_NOACCESS ||
2437         GetLastError() == ERROR_INVALID_PARAMETER,  /* win9x */
2438         "wrong error %u\n", GetLastError() );
2439     ok( bytes == 0, "read %x bytes\n", bytes );
2440
2441     VirtualFree( mem, 0, MEM_FREE );
2442
2443     ret = CloseHandle(hFile);
2444     ok( ret, "CloseHandle: error %d\n", GetLastError());
2445     ret = DeleteFileA(filename);
2446     ok( ret, "DeleteFileA: error %d\n", GetLastError());
2447 }
2448
2449 static void test_OpenFile(void)
2450 {
2451     HFILE hFile;
2452     OFSTRUCT ofs;
2453     BOOL ret;
2454     DWORD retval;
2455     
2456     static const char file[] = "regedit.exe";
2457     static const char foo[] = ".\\foo-bar-foo.baz";
2458     static const char *foo_too_long = ".\\foo-bar-foo.baz+++++++++++++++"
2459         "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2460         "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2461         "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2462         "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2463         "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
2464     char buff[MAX_PATH];
2465     char buff_long[4*MAX_PATH];
2466     char filled_0xA5[OFS_MAXPATHNAME];
2467     char *p;
2468     UINT length;
2469     
2470     /* Check for existing file */
2471     if (!pGetSystemWindowsDirectoryA)
2472         length = GetWindowsDirectoryA(buff, MAX_PATH);
2473     else
2474         length = pGetSystemWindowsDirectoryA(buff, MAX_PATH);
2475
2476     if (length + sizeof(file) < MAX_PATH)
2477     {
2478         p = buff + strlen(buff);
2479         if (p > buff && p[-1] != '\\') *p++ = '\\';
2480         strcpy( p, file );
2481         memset(&ofs, 0xA5, sizeof(ofs));
2482         SetLastError(0xfaceabee);
2483
2484         hFile = OpenFile(buff, &ofs, OF_EXIST);
2485         ok( hFile == TRUE, "%s not found : %d\n", buff, GetLastError() );
2486         ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 
2487             "GetLastError() returns %d\n", GetLastError() );
2488         ok( ofs.cBytes == sizeof(ofs), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2489         ok( ofs.nErrCode == ERROR_SUCCESS, "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2490         ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2491             "OpenFile returned '%s', but was expected to return '%s' or string filled with 0xA5\n",
2492             ofs.szPathName, buff );
2493     }
2494
2495     memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
2496     length = GetCurrentDirectoryA(MAX_PATH, buff);
2497
2498     /* Check for nonexistent file */
2499     if (length + sizeof(foo) < MAX_PATH)
2500     {
2501         p = buff + strlen(buff);
2502         if (p > buff && p[-1] != '\\') *p++ = '\\';
2503         strcpy( p, foo + 2 );
2504         memset(&ofs, 0xA5, sizeof(ofs));
2505         SetLastError(0xfaceabee);
2506
2507         hFile = OpenFile(foo, &ofs, OF_EXIST);
2508         ok( hFile == HFILE_ERROR, "hFile != HFILE_ERROR : %d\n", GetLastError());
2509         ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError() returns %d\n", GetLastError() );
2510         todo_wine
2511         ok( ofs.cBytes == 0xA5, "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2512         ok( ofs.nErrCode == ERROR_FILE_NOT_FOUND, "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2513         ok( lstrcmpiA(ofs.szPathName, buff) == 0 || strncmp(ofs.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0,
2514             "OpenFile returned '%s', but was expected to return '%s' or string filled with 0xA5\n", 
2515             ofs.szPathName, buff );
2516     }
2517
2518     length = GetCurrentDirectoryA(MAX_PATH, buff_long);
2519     length += lstrlenA(foo_too_long + 1);
2520
2521     /* Check for nonexistent file with too long filename */ 
2522     if (length >= OFS_MAXPATHNAME && length < sizeof(buff_long)) 
2523     {
2524         lstrcatA(buff_long, foo_too_long + 1); /* Avoid '.' during concatenation */
2525         memset(&ofs, 0xA5, sizeof(ofs));
2526         SetLastError(0xfaceabee);
2527
2528         hFile = OpenFile(foo_too_long, &ofs, OF_EXIST);
2529         ok( hFile == HFILE_ERROR, "hFile != HFILE_ERROR : %d\n", GetLastError());
2530         ok( GetLastError() == ERROR_INVALID_DATA || GetLastError() == ERROR_FILENAME_EXCED_RANGE, 
2531             "GetLastError() returns %d\n", GetLastError() );
2532         todo_wine
2533         ok( ofs.cBytes == 0xA5, "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2534         ok( ofs.nErrCode == ERROR_INVALID_DATA || ofs.nErrCode == ERROR_FILENAME_EXCED_RANGE,
2535             "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2536         ok( strncmp(ofs.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, 
2537             "OpenFile returned '%s', but was expected to return string filled with 0xA5\n", 
2538             ofs.szPathName );
2539     }
2540
2541     length = GetCurrentDirectoryA(MAX_PATH, buff) + sizeof(filename);
2542
2543     if (length >= MAX_PATH) 
2544     {
2545         trace("Buffer too small, requested length = %d, but MAX_PATH = %d.  Skipping test.\n", length, MAX_PATH);
2546         return;
2547     }
2548     p = buff + strlen(buff);
2549     if (p > buff && p[-1] != '\\') *p++ = '\\';
2550     strcpy( p, filename );
2551
2552     memset(&ofs, 0xA5, sizeof(ofs));
2553     SetLastError(0xfaceabee);
2554     /* Create an empty file */
2555     hFile = OpenFile(filename, &ofs, OF_CREATE);
2556     ok( hFile != HFILE_ERROR, "OpenFile failed to create nonexistent file\n" );
2557     ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 
2558         "GetLastError() returns %d\n", GetLastError() );
2559     ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2560     ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
2561         "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2562     ret = _lclose(hFile);
2563     ok( !ret, "_lclose() returns %d\n", ret );
2564     retval = GetFileAttributesA(filename);
2565     ok( retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %d\n", GetLastError() );
2566
2567     memset(&ofs, 0xA5, sizeof(ofs));
2568     SetLastError(0xfaceabee);
2569     /* Check various opening options: */
2570     /* for reading only, */
2571     hFile = OpenFile(filename, &ofs, OF_READ);
2572     ok( hFile != HFILE_ERROR, "OpenFile failed on read\n" );
2573     ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 
2574         "GetLastError() returns %d\n", GetLastError() );
2575     ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2576     ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
2577         "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2578     ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2579         "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
2580     ret = _lclose(hFile);
2581     ok( !ret, "_lclose() returns %d\n", ret );
2582
2583     memset(&ofs, 0xA5, sizeof(ofs));
2584     SetLastError(0xfaceabee);
2585     /* for writing only, */
2586     hFile = OpenFile(filename, &ofs, OF_WRITE);
2587     ok( hFile != HFILE_ERROR, "OpenFile failed on write\n" );
2588     ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 
2589         "GetLastError() returns %d\n", GetLastError() );
2590     ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2591     ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
2592         "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2593     ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2594         "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
2595     ret = _lclose(hFile);
2596     ok( !ret, "_lclose() returns %d\n", ret );
2597
2598     memset(&ofs, 0xA5, sizeof(ofs));
2599     SetLastError(0xfaceabee);
2600     /* for reading and writing, */
2601     hFile = OpenFile(filename, &ofs, OF_READWRITE);
2602     ok( hFile != HFILE_ERROR, "OpenFile failed on read/write\n" );
2603     ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 
2604         "GetLastError() returns %d\n", GetLastError() );
2605     ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2606     ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
2607         "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2608     ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2609         "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
2610     ret = _lclose(hFile);
2611     ok( !ret, "_lclose() returns %d\n", ret );
2612
2613     memset(&ofs, 0xA5, sizeof(ofs));
2614     SetLastError(0xfaceabee);
2615     /* for checking file presence. */
2616     hFile = OpenFile(filename, &ofs, OF_EXIST);
2617     ok( hFile == 1, "OpenFile failed on finding our created file\n" );
2618     ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 
2619         "GetLastError() returns %d\n", GetLastError() );
2620     ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2621     ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
2622         "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2623     ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2624         "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
2625
2626     memset(&ofs, 0xA5, sizeof(ofs));
2627     SetLastError(0xfaceabee);
2628     /* Delete the file and make sure it doesn't exist anymore */
2629     hFile = OpenFile(filename, &ofs, OF_DELETE);
2630     ok( hFile == 1, "OpenFile failed on delete (%d)\n", hFile );
2631     ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 
2632         "GetLastError() returns %d\n", GetLastError() );
2633     ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2634     ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
2635         "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2636     ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2637         "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
2638
2639     retval = GetFileAttributesA(filename);
2640     ok( retval == INVALID_FILE_ATTRIBUTES, "GetFileAttributesA succeeded on deleted file\n" );
2641 }
2642
2643 static void test_overlapped(void)
2644 {
2645     OVERLAPPED ov;
2646     DWORD r, result;
2647
2648     /* GetOverlappedResult crashes if the 2nd or 3rd param are NULL */
2649     if (0) /* tested: WinXP */
2650     {
2651         GetOverlappedResult(0, NULL, &result, FALSE);
2652         GetOverlappedResult(0, &ov, NULL, FALSE);
2653         GetOverlappedResult(0, NULL, NULL, FALSE);
2654     }
2655
2656     memset( &ov, 0,  sizeof ov );
2657     result = 1;
2658     r = GetOverlappedResult(0, &ov, &result, 0);
2659     if (r)
2660         ok( result == 0, "wrong result %u\n", result );
2661     else  /* win9x */
2662         ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
2663
2664     result = 0;
2665     ov.Internal = 0;
2666     ov.InternalHigh = 0xabcd;
2667     r = GetOverlappedResult(0, &ov, &result, 0);
2668     if (r)
2669         ok( result == 0xabcd, "wrong result %u\n", result );
2670     else  /* win9x */
2671         ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
2672
2673     SetLastError( 0xb00 );
2674     result = 0;
2675     ov.Internal = STATUS_INVALID_HANDLE;
2676     ov.InternalHigh = 0xabcd;
2677     r = GetOverlappedResult(0, &ov, &result, 0);
2678     ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
2679     ok( r == FALSE, "should return false\n");
2680     ok( result == 0xabcd || result == 0 /* win9x */, "wrong result %u\n", result );
2681
2682     SetLastError( 0xb00 );
2683     result = 0;
2684     ov.Internal = STATUS_PENDING;
2685     ov.InternalHigh = 0xabcd;
2686     r = GetOverlappedResult(0, &ov, &result, 0);
2687     ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
2688         "wrong error %u\n", GetLastError() );
2689     ok( r == FALSE, "should return false\n");
2690     ok( result == 0, "wrong result %u\n", result );
2691
2692     SetLastError( 0xb00 );
2693     ov.hEvent = CreateEvent( NULL, 1, 1, NULL );
2694     ov.Internal = STATUS_PENDING;
2695     ov.InternalHigh = 0xabcd;
2696     r = GetOverlappedResult(0, &ov, &result, 0);
2697     ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
2698         "wrong error %u\n", GetLastError() );
2699     ok( r == FALSE, "should return false\n");
2700
2701     ResetEvent( ov.hEvent );
2702
2703     SetLastError( 0xb00 );
2704     ov.Internal = STATUS_PENDING;
2705     ov.InternalHigh = 0;
2706     r = GetOverlappedResult(0, &ov, &result, 0);
2707     ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
2708         "wrong error %u\n", GetLastError() );
2709     ok( r == FALSE, "should return false\n");
2710
2711     r = CloseHandle( ov.hEvent );
2712     ok( r == TRUE, "close handle failed\n");
2713 }
2714
2715 static void test_RemoveDirectory(void)
2716 {
2717     int rc;
2718     char directory[] = "removeme";
2719
2720     rc = CreateDirectory(directory, NULL);
2721     ok( rc, "Createdirectory failed, gle=%d\n", GetLastError() );
2722
2723     rc = SetCurrentDirectory(directory);
2724     ok( rc, "SetCurrentDirectory failed, gle=%d\n", GetLastError() );
2725
2726     rc = RemoveDirectory(".");
2727     if (!rc)
2728     {
2729         rc = SetCurrentDirectory("..");
2730         ok( rc, "SetCurrentDirectory failed, gle=%d\n", GetLastError() );
2731
2732         rc = RemoveDirectory(directory);
2733         ok( rc, "RemoveDirectory failed, gle=%d\n", GetLastError() );
2734     }
2735 }
2736
2737 static BOOL check_file_time( const FILETIME *ft1, const FILETIME *ft2, UINT tolerance )
2738 {
2739     ULONGLONG t1 = ((ULONGLONG)ft1->dwHighDateTime << 32) | ft1->dwLowDateTime;
2740     ULONGLONG t2 = ((ULONGLONG)ft2->dwHighDateTime << 32) | ft2->dwLowDateTime;
2741     return abs(t1 - t2) <= tolerance;
2742 }
2743
2744 static void test_ReplaceFileA(void)
2745 {
2746     char replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH];
2747     HANDLE hReplacedFile, hReplacementFile, hBackupFile;
2748     static const char replacedData[] = "file-to-replace";
2749     static const char replacementData[] = "new-file";
2750     static const char backupData[] = "backup-file";
2751     FILETIME ftReplaced, ftReplacement, ftBackup;
2752     static const char prefix[] = "pfx";
2753     char temp_path[MAX_PATH];
2754     DWORD ret;
2755     BOOL retok, removeBackup = FALSE;
2756
2757     if (!pReplaceFileA)
2758     {
2759         win_skip("ReplaceFileA() is missing\n");
2760         return;
2761     }
2762
2763     ret = GetTempPathA(MAX_PATH, temp_path);
2764     ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
2765     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
2766
2767     ret = GetTempFileNameA(temp_path, prefix, 0, replaced);
2768     ok(ret != 0, "GetTempFileNameA error (replaced) %d\n", GetLastError());
2769
2770     ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
2771     ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
2772
2773     ret = GetTempFileNameA(temp_path, prefix, 0, backup);
2774     ok(ret != 0, "GetTempFileNameA error (backup) %d\n", GetLastError());
2775
2776     /* place predictable data in the file to be replaced */
2777     hReplacedFile = CreateFileA(replaced, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2778     ok(hReplacedFile != INVALID_HANDLE_VALUE,
2779         "failed to open replaced file\n");
2780     retok = WriteFile(hReplacedFile, replacedData, sizeof(replacedData), &ret, NULL );
2781     ok( retok && ret == sizeof(replacedData),
2782        "WriteFile error (replaced) %d\n", GetLastError());
2783     ok(GetFileSize(hReplacedFile, NULL) == sizeof(replacedData),
2784         "replaced file has wrong size\n");
2785     /* place predictable data in the file to be the replacement */
2786     hReplacementFile = CreateFileA(replacement, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2787     ok(hReplacementFile != INVALID_HANDLE_VALUE,
2788         "failed to open replacement file\n");
2789     retok = WriteFile(hReplacementFile, replacementData, sizeof(replacementData), &ret, NULL );
2790     ok( retok && ret == sizeof(replacementData),
2791        "WriteFile error (replacement) %d\n", GetLastError());
2792     ok(GetFileSize(hReplacementFile, NULL) == sizeof(replacementData),
2793         "replacement file has wrong size\n");
2794     /* place predictable data in the backup file (to be over-written) */
2795     hBackupFile = CreateFileA(backup, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2796     ok(hBackupFile != INVALID_HANDLE_VALUE,
2797         "failed to open backup file\n");
2798     retok = WriteFile(hBackupFile, backupData, sizeof(backupData), &ret, NULL );
2799     ok( retok && ret == sizeof(backupData),
2800        "WriteFile error (replacement) %d\n", GetLastError());
2801     ok(GetFileSize(hBackupFile, NULL) == sizeof(backupData),
2802         "backup file has wrong size\n");
2803     /* change the filetime on the "replaced" file to ensure that it changes */
2804     ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
2805     ok( ret, "GetFileTime error (replaced) %d\n", GetLastError());
2806     ftReplaced.dwLowDateTime -= 600000000; /* 60 second */
2807     ret = SetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
2808     ok( ret, "SetFileTime error (replaced) %d\n", GetLastError());
2809     GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);  /* get the actual time back */
2810     CloseHandle(hReplacedFile);
2811     /* change the filetime on the backup to ensure that it changes */
2812     ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
2813     ok( ret, "GetFileTime error (backup) %d\n", GetLastError());
2814     ftBackup.dwLowDateTime -= 1200000000; /* 120 second */
2815     ret = SetFileTime(hBackupFile, NULL, NULL, &ftBackup);
2816     ok( ret, "SetFileTime error (backup) %d\n", GetLastError());
2817     GetFileTime(hBackupFile, NULL, NULL, &ftBackup);  /* get the actual time back */
2818     CloseHandle(hBackupFile);
2819     /* get the filetime on the replacement file to perform checks */
2820     ret = GetFileTime(hReplacementFile, NULL, NULL, &ftReplacement);
2821     ok( ret, "GetFileTime error (replacement) %d\n", GetLastError());
2822     CloseHandle(hReplacementFile);
2823
2824     /* perform replacement w/ backup
2825      * TODO: flags are not implemented
2826      */
2827     SetLastError(0xdeadbeef);
2828     ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
2829     ok(ret, "ReplaceFileA: unexpected error %d\n", GetLastError());
2830     /* make sure that the backup has the size of the old "replaced" file */
2831     hBackupFile = CreateFileA(backup, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
2832     ok(hBackupFile != INVALID_HANDLE_VALUE,
2833         "failed to open backup file\n");
2834     ret = GetFileSize(hBackupFile, NULL);
2835     ok(ret == sizeof(replacedData),
2836         "backup file has wrong size %d\n", ret);
2837     /* make sure that the "replaced" file has the size of the replacement file */
2838     hReplacedFile = CreateFileA(replaced, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
2839     ok(hReplacedFile != INVALID_HANDLE_VALUE,
2840         "failed to open replaced file: %d\n", GetLastError());
2841     if (hReplacedFile != INVALID_HANDLE_VALUE)
2842     {
2843         ret = GetFileSize(hReplacedFile, NULL);
2844         ok(ret == sizeof(replacementData),
2845             "replaced file has wrong size %d\n", ret);
2846         /* make sure that the replacement file no-longer exists */
2847         hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
2848         ok(hReplacementFile == INVALID_HANDLE_VALUE,
2849            "unexpected error, replacement file should not exist %d\n", GetLastError());
2850         /* make sure that the backup has the old "replaced" filetime */
2851         ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
2852         ok( ret, "GetFileTime error (backup %d\n", GetLastError());
2853         ok(check_file_time(&ftBackup, &ftReplaced, 20000000), "backup file has wrong filetime\n");
2854         CloseHandle(hBackupFile);
2855         /* make sure that the "replaced" has the old replacement filetime */
2856         ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
2857         ok( ret, "GetFileTime error (backup %d\n", GetLastError());
2858         ok(check_file_time(&ftReplaced, &ftReplacement, 20000000),
2859            "replaced file has wrong filetime %x%08x / %x%08x\n",
2860            ftReplaced.dwHighDateTime, ftReplaced.dwLowDateTime,
2861            ftReplacement.dwHighDateTime, ftReplacement.dwLowDateTime );
2862         CloseHandle(hReplacedFile);
2863     }
2864     else
2865         skip("couldn't open replacement file, skipping tests\n");
2866
2867     /* re-create replacement file for pass w/o backup (blank) */
2868     ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
2869     ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
2870     /* perform replacement w/o backup
2871      * TODO: flags are not implemented
2872      */
2873     SetLastError(0xdeadbeef);
2874     ret = pReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
2875     ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
2876        "ReplaceFileA: unexpected error %d\n", GetLastError());
2877
2878     /* re-create replacement file for pass w/ backup (backup-file not existing) */
2879     ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
2880     ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
2881     ret = DeleteFileA(backup);
2882     ok(ret, "DeleteFileA: error (backup) %d\n", GetLastError());
2883     /* perform replacement w/ backup (no pre-existing backup)
2884      * TODO: flags are not implemented
2885      */
2886     SetLastError(0xdeadbeef);
2887     ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
2888     ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
2889        "ReplaceFileA: unexpected error %d\n", GetLastError());
2890     if (ret)
2891         removeBackup = TRUE;
2892
2893     /* re-create replacement file for pass w/ no permissions to "replaced" */
2894     ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
2895     ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
2896     ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_READONLY);
2897     ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
2898        "SetFileAttributesA: error setting to read only %d\n", GetLastError());
2899     /* perform replacement w/ backup (no permission to "replaced")
2900      * TODO: flags are not implemented
2901      */
2902     SetLastError(0xdeadbeef);
2903     ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
2904     ok(ret != ERROR_UNABLE_TO_REMOVE_REPLACED, "ReplaceFileA: unexpected error %d\n", GetLastError());
2905     /* make sure that the replacement file still exists */
2906     hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
2907     ok(hReplacementFile != INVALID_HANDLE_VALUE ||
2908        broken(GetLastError() == ERROR_FILE_NOT_FOUND), /* win2k */
2909        "unexpected error, replacement file should still exist %d\n", GetLastError());
2910     CloseHandle(hReplacementFile);
2911     ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_NORMAL);
2912     ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
2913        "SetFileAttributesA: error setting to normal %d\n", GetLastError());
2914
2915     /* replacement file still exists, make pass w/o "replaced" */
2916     ret = DeleteFileA(replaced);
2917     ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
2918        "DeleteFileA: error (replaced) %d\n", GetLastError());
2919     /* perform replacement w/ backup (no pre-existing backup or "replaced")
2920      * TODO: flags are not implemented
2921      */
2922     SetLastError(0xdeadbeef);
2923     ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
2924     ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
2925        GetLastError() == ERROR_ACCESS_DENIED),
2926        "ReplaceFileA: unexpected error %d\n", GetLastError());
2927
2928     /* perform replacement w/o existing "replacement" file
2929      * TODO: flags are not implemented
2930      */
2931     SetLastError(0xdeadbeef);
2932     ret = pReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
2933     ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
2934         GetLastError() == ERROR_ACCESS_DENIED),
2935         "ReplaceFileA: unexpected error %d\n", GetLastError());
2936
2937     /*
2938      * if the first round (w/ backup) worked then as long as there is no
2939      * failure then there is no need to check this round (w/ backup is the
2940      * more complete case)
2941      */
2942
2943     /* delete temporary files, replacement and replaced are already deleted */
2944     if (removeBackup)
2945     {
2946         ret = DeleteFileA(backup);
2947         ok(ret ||
2948            broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */
2949            "DeleteFileA: error (backup) %d\n", GetLastError());
2950     }
2951 }
2952
2953 /*
2954  * ReplaceFileW is a simpler case of ReplaceFileA, there is no
2955  * need to be as thorough.
2956  */
2957 static void test_ReplaceFileW(void)
2958 {
2959     WCHAR replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH];
2960     static const WCHAR prefix[] = {'p','f','x',0};
2961     WCHAR temp_path[MAX_PATH];
2962     DWORD ret;
2963     BOOL removeBackup = FALSE;
2964
2965     if (!pReplaceFileW)
2966     {
2967         win_skip("ReplaceFileW() is missing\n");
2968         return;
2969     }
2970
2971     ret = GetTempPathW(MAX_PATH, temp_path);
2972     if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
2973     {
2974         win_skip("GetTempPathW is not available\n");
2975         return;
2976     }
2977     ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
2978     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
2979
2980     ret = GetTempFileNameW(temp_path, prefix, 0, replaced);
2981     ok(ret != 0, "GetTempFileNameW error (replaced) %d\n", GetLastError());
2982
2983     ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
2984     ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
2985
2986     ret = GetTempFileNameW(temp_path, prefix, 0, backup);
2987     ok(ret != 0, "GetTempFileNameW error (backup) %d\n", GetLastError());
2988
2989     ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
2990     ok(ret, "ReplaceFileW: error %d\n", GetLastError());
2991
2992     ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
2993     ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
2994     ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0);
2995     ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
2996        "ReplaceFileW: error %d\n", GetLastError());
2997
2998     ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
2999     ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3000     ret = DeleteFileW(backup);
3001     ok(ret, "DeleteFileW: error (backup) %d\n", GetLastError());
3002     ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3003     ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3004        "ReplaceFileW: error %d\n", GetLastError());
3005
3006     ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3007     ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3008     ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_READONLY);
3009     ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3010        "SetFileAttributesW: error setting to read only %d\n", GetLastError());
3011
3012     ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3013     ok(ret != ERROR_UNABLE_TO_REMOVE_REPLACED,
3014         "ReplaceFileW: unexpected error %d\n", GetLastError());
3015     ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_NORMAL);
3016     ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3017        "SetFileAttributesW: error setting to normal %d\n", GetLastError());
3018     if (ret)
3019         removeBackup = TRUE;
3020
3021     ret = DeleteFileW(replaced);
3022     ok(ret, "DeleteFileW: error (replaced) %d\n", GetLastError());
3023     ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3024     ok(!ret, "ReplaceFileW: error %d\n", GetLastError());
3025
3026     ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0);
3027     ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
3028        GetLastError() == ERROR_ACCESS_DENIED),
3029         "ReplaceFileW: unexpected error %d\n", GetLastError());
3030
3031     if (removeBackup)
3032     {
3033         ret = DeleteFileW(backup);
3034         ok(ret ||
3035            broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */
3036            "DeleteFileW: error (backup) %d\n", GetLastError());
3037     }
3038 }
3039
3040 START_TEST(file)
3041 {
3042     InitFunctionPointers();
3043
3044     test__hread(  );
3045     test__hwrite(  );
3046     test__lclose(  );
3047     test__lcreat(  );
3048     test__llseek(  );
3049     test__llopen(  );
3050     test__lread(  );
3051     test__lwrite(  );
3052     test_GetTempFileNameA();
3053     test_CopyFileA();
3054     test_CopyFileW();
3055     test_CreateFileA();
3056     test_CreateFileW();
3057     test_DeleteFileA();
3058     test_DeleteFileW();
3059     test_MoveFileA();
3060     test_MoveFileW();
3061     test_FindFirstFileA();
3062     test_FindNextFileA();
3063     test_FindFirstFileExA(0);
3064     /* FindExLimitToDirectories is ignored if the file system doesn't support directory filtering */
3065     test_FindFirstFileExA(FindExSearchLimitToDirectories);
3066     test_LockFile();
3067     test_file_sharing();
3068     test_offset_in_overlapped_structure();
3069     test_MapFile();
3070     test_GetFileType();
3071     test_async_file_errors();
3072     test_read_write();
3073     test_OpenFile();
3074     test_overlapped();
3075     test_RemoveDirectory();
3076     test_ReplaceFileA();
3077     test_ReplaceFileW();
3078 }