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