Don't allocate a glyphset until we actually need it.
[wine] / dlls / kernel / tests / file.c
1 /*
2  * Unit tests for file functions in Wine
3  *
4  * Copyright (c) 2002, 2004 Jakob Eriksson
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <time.h>
25
26 #include "wine/test.h"
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30
31 static int dll_capable(const char *dll, const char *function)
32 {
33     HMODULE module = GetModuleHandleA(dll);
34     if (!module) return 0;
35
36     return (GetProcAddress(module, function) != NULL);
37 }
38
39
40 LPCSTR filename = "testfile.xxx";
41 LPCSTR sillytext =
42 "en larvig liten text dx \033 gx hej 84 hej 4484 ! \001\033 bla bl\na.. bla bla."
43 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
44 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
45 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
46 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
47 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
48 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
49 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
50 "1234 43 4kljf lf &%%%&&&&&& 34 4 34   3############# 33 3 3 3 # 3## 3"
51 "sdlkfjasdlkfj a dslkj adsklf  \n  \nasdklf askldfa sdlkf \nsadklf asdklf asdf ";
52
53
54 static void test__hread( void )
55 {
56     HFILE filehandle;
57     char buffer[10000];
58     long bytes_read;
59     long bytes_wanted;
60     long i;
61
62     SetFileAttributesA(filename,FILE_ATTRIBUTE_NORMAL); /* be sure to remove stale files */
63     DeleteFileA( filename );
64     filehandle = _lcreat( filename, 0 );
65     if (filehandle == HFILE_ERROR)
66     {
67         ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
68         return;
69     }
70
71     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
72
73     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
74
75     filehandle = _lopen( filename, OF_READ );
76
77     ok( HFILE_ERROR != filehandle, "couldn't open file \"%s\" again (err=%ld)\n", filename, GetLastError(  ) );
78
79     bytes_read = _hread( filehandle, buffer, 2 * strlen( sillytext ) );
80
81     ok( lstrlenA( sillytext ) == bytes_read, "file read size error\n" );
82
83     for (bytes_wanted = 0; bytes_wanted < lstrlenA( sillytext ); bytes_wanted++)
84     {
85         ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
86         ok( _hread( filehandle, buffer, bytes_wanted ) == bytes_wanted, "erratic _hread return value\n" );
87         for (i = 0; i < bytes_wanted; i++)
88         {
89             ok( buffer[i] == sillytext[i], "that's not what's written\n" );
90         }
91     }
92
93     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
94
95     ok( DeleteFileA( filename ) != 0, "DeleteFile failed (%ld)\n", GetLastError(  ) );
96 }
97
98
99 static void test__hwrite( void )
100 {
101     HFILE filehandle;
102     char buffer[10000];
103     long bytes_read;
104     long bytes_written;
105     long blocks;
106     long i;
107     char *contents;
108     HLOCAL memory_object;
109     char checksum[1];
110
111     filehandle = _lcreat( filename, 0 );
112     if (filehandle == HFILE_ERROR)
113     {
114         ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
115         return;
116     }
117
118     ok( HFILE_ERROR != _hwrite( filehandle, "", 0 ), "_hwrite complains\n" );
119
120     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
121
122     filehandle = _lopen( filename, OF_READ );
123
124     bytes_read = _hread( filehandle, buffer, 1);
125
126     ok( 0 == bytes_read, "file read size error\n" );
127
128     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
129
130     filehandle = _lopen( filename, OF_READWRITE );
131
132     bytes_written = 0;
133     checksum[0] = '\0';
134     srand( (unsigned)time( NULL ) );
135     for (blocks = 0; blocks < 100; blocks++)
136     {
137         for (i = 0; i < (long)sizeof( buffer ); i++)
138         {
139             buffer[i] = rand(  );
140             checksum[0] = checksum[0] + buffer[i];
141         }
142         ok( HFILE_ERROR != _hwrite( filehandle, buffer, sizeof( buffer ) ), "_hwrite complains\n" );
143         bytes_written = bytes_written + sizeof( buffer );
144     }
145
146     ok( HFILE_ERROR != _hwrite( filehandle, checksum, 1 ), "_hwrite complains\n" );
147     bytes_written++;
148
149     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
150
151     memory_object = LocalAlloc( LPTR, bytes_written );
152
153     ok( 0 != memory_object, "LocalAlloc fails. (Could be out of memory.)\n" );
154
155     contents = LocalLock( memory_object );
156
157     filehandle = _lopen( filename, OF_READ );
158
159     contents = LocalLock( memory_object );
160
161     ok( NULL != contents, "LocalLock whines\n" );
162
163     ok( bytes_written == _hread( filehandle, contents, bytes_written), "read length differ from write length\n" );
164
165     checksum[0] = '\0';
166     i = 0;
167     do
168     {
169         checksum[0] = checksum[0] + contents[i];
170         i++;
171     }
172     while (i < bytes_written - 1);
173
174     ok( checksum[0] == contents[i], "stored checksum differ from computed checksum\n" );
175
176     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
177
178     ok( DeleteFileA( filename ) != 0, "DeleteFile failed (%ld)\n", GetLastError(  ) );
179 }
180
181
182 static void test__lclose( void )
183 {
184     HFILE filehandle;
185
186     filehandle = _lcreat( filename, 0 );
187     if (filehandle == HFILE_ERROR)
188     {
189         ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
190         return;
191     }
192
193     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
194
195     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
196
197     ok( DeleteFileA( filename ) != 0, "DeleteFile failed (%ld)\n", GetLastError(  ) );
198 }
199
200
201 static void test__lcreat( void )
202 {
203     HFILE filehandle;
204     char buffer[10000];
205     WIN32_FIND_DATAA search_results;
206     char slashname[] = "testfi/";
207     int err;
208     HANDLE find;
209
210     filehandle = _lcreat( filename, 0 );
211     if (filehandle == HFILE_ERROR)
212     {
213         ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
214         return;
215     }
216
217     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
218
219     ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
220
221     ok( _hread( filehandle, buffer, strlen( sillytext ) ) ==  lstrlenA( sillytext ), "erratic _hread return value\n" );
222
223     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
224
225     ok( INVALID_HANDLE_VALUE != FindFirstFileA( filename, &search_results ), "should be able to find file\n" );
226
227     ok( DeleteFileA(filename) != 0, "DeleteFile failed (%ld)\n", GetLastError());
228
229     filehandle = _lcreat( filename, 1 ); /* readonly */
230     ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%ld)\n", filename, GetLastError(  ) );
231
232     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite shouldn't be able to write never the less\n" );
233
234     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
235
236     ok( INVALID_HANDLE_VALUE != FindFirstFileA( filename, &search_results ), "should be able to find file\n" );
237
238     ok( 0 == DeleteFileA( filename ), "shouldn't be able to delete a readonly file\n" );
239
240     ok( SetFileAttributesA(filename, FILE_ATTRIBUTE_NORMAL ) != 0, "couldn't change attributes on file\n" );
241
242     ok( DeleteFileA( filename ) != 0, "now it should be possible to delete the file!\n" );
243
244     filehandle = _lcreat( filename, 2 );
245     ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%ld)\n", filename, GetLastError(  ) );
246
247     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
248
249     ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
250
251     ok( _hread( filehandle, buffer, strlen( sillytext ) ) ==  lstrlenA( sillytext ), "erratic _hread return value\n" );
252
253     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
254
255     ok( INVALID_HANDLE_VALUE != FindFirstFileA( filename, &search_results ), "should STILL be able to find file\n" );
256
257     ok( DeleteFileA( filename ) != 0, "DeleteFile failed (%ld)\n", GetLastError(  ) );
258
259     filehandle = _lcreat( filename, 4 ); /* SYSTEM file */
260     ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%ld)\n", filename, GetLastError(  ) );
261
262     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
263
264     ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
265
266     ok( _hread( filehandle, buffer, strlen( sillytext ) ) ==  lstrlenA( sillytext ), "erratic _hread return value\n" );
267
268     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
269
270     ok( INVALID_HANDLE_VALUE != FindFirstFileA( filename, &search_results ), "should STILL be able to find file\n" );
271
272     ok( DeleteFileA( filename ) != 0, "DeleteFile failed (%ld)\n", GetLastError(  ) );
273
274     filehandle=_lcreat (slashname, 0); /* illegal name */
275     if (HFILE_ERROR==filehandle) {
276       err=GetLastError ();
277       ok (err==ERROR_INVALID_NAME || err==ERROR_PATH_NOT_FOUND,
278           "creating file \"%s\" failed with error %d\n", slashname, err);
279     } else { /* only NT succeeds */
280       _lclose(filehandle);
281       find=FindFirstFileA (slashname, &search_results);
282       if (INVALID_HANDLE_VALUE!=find)
283       {
284         ok (0!=FindClose (find), "FindClose complains (%ld)\n", GetLastError ());
285         slashname[strlen(slashname)-1]=0;
286         ok (!strcmp (slashname, search_results.cFileName),
287             "found unexpected name \"%s\"\n", search_results.cFileName);
288         ok (FILE_ATTRIBUTE_ARCHIVE==search_results.dwFileAttributes,
289             "attributes of file \"%s\" are 0x%04lx\n", search_results.cFileName,
290             search_results.dwFileAttributes);
291       }
292       ok (0!=DeleteFileA (slashname), "Can't delete \"%s\" (%ld)\n", slashname,
293           GetLastError ());
294     }
295
296     filehandle=_lcreat (filename, 8); /* illegal attribute */
297     if (HFILE_ERROR==filehandle)
298       ok (0, "couldn't create volume label \"%s\"\n", filename);
299     else {
300       _lclose(filehandle);
301       find=FindFirstFileA (filename, &search_results);
302       if (INVALID_HANDLE_VALUE==find)
303         ok (0, "file \"%s\" not found\n", filename);
304       else {
305         ok (0!=FindClose (find), "FindClose complains (%ld)\n", GetLastError ());
306         ok (!strcmp (filename, search_results.cFileName),
307             "found unexpected name \"%s\"\n", search_results.cFileName);
308         ok (FILE_ATTRIBUTE_ARCHIVE==search_results.dwFileAttributes,
309             "attributes of file \"%s\" are 0x%04lx\n", search_results.cFileName,
310             search_results.dwFileAttributes);
311       }
312       ok (0!=DeleteFileA (filename), "Can't delete \"%s\" (%ld)\n", slashname,
313           GetLastError ());
314     }
315 }
316
317
318 static void test__llseek( void )
319 {
320     INT i;
321     HFILE filehandle;
322     char buffer[1];
323     long bytes_read;
324
325     filehandle = _lcreat( filename, 0 );
326     if (filehandle == HFILE_ERROR)
327     {
328         ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
329         return;
330     }
331
332     for (i = 0; i < 400; i++)
333     {
334         ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
335     }
336     ok( HFILE_ERROR != _llseek( filehandle, 400 * strlen( sillytext ), FILE_CURRENT ), "should be able to seek\n" );
337     ok( HFILE_ERROR != _llseek( filehandle, 27 + 35 * strlen( sillytext ), FILE_BEGIN ), "should be able to seek\n" );
338
339     bytes_read = _hread( filehandle, buffer, 1);
340     ok( 1 == bytes_read, "file read size error\n" );
341     ok( buffer[0] == sillytext[27], "_llseek error, it got lost seeking\n" );
342     ok( HFILE_ERROR != _llseek( filehandle, -400 * strlen( sillytext ), FILE_END ), "should be able to seek\n" );
343
344     bytes_read = _hread( filehandle, buffer, 1);
345     ok( 1 == bytes_read, "file read size error\n" );
346     ok( buffer[0] == sillytext[0], "_llseek error, it got lost seeking\n" );
347     ok( HFILE_ERROR != _llseek( filehandle, 1000000, FILE_END ), "should be able to seek past file; poor, poor Windows programmers\n" );
348     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
349
350     ok( DeleteFileA( filename ) != 0, "DeleteFile failed (%ld)\n", GetLastError(  ) );
351 }
352
353
354 static void test__llopen( void )
355 {
356     HFILE filehandle;
357     UINT bytes_read;
358     char buffer[10000];
359
360     filehandle = _lcreat( filename, 0 );
361     if (filehandle == HFILE_ERROR)
362     {
363         ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
364         return;
365     }
366
367     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
368     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
369
370     filehandle = _lopen( filename, OF_READ );
371     ok( HFILE_ERROR == _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite shouldn't be able to write!\n" );
372     bytes_read = _hread( filehandle, buffer, strlen( sillytext ) );
373     ok( strlen( sillytext )  == bytes_read, "file read size error\n" );
374     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
375
376     filehandle = _lopen( filename, OF_READWRITE );
377     bytes_read = _hread( filehandle, buffer, 2 * strlen( sillytext ) );
378     ok( strlen( sillytext )  == bytes_read, "file read size error\n" );
379     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite should write just fine\n" );
380     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
381
382     filehandle = _lopen( filename, OF_WRITE );
383     ok( HFILE_ERROR == _hread( filehandle, buffer, 1 ), "you should only be able to write this file\n" );
384     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite should write just fine\n" );
385     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
386
387     ok( DeleteFileA( filename ) != 0, "DeleteFile failed (%ld)\n", GetLastError(  ) );
388     /* TODO - add tests for the SHARE modes  -  use two processes to pull this one off */
389 }
390
391
392 static void test__lread( void )
393 {
394     HFILE filehandle;
395     char buffer[10000];
396     long bytes_read;
397     UINT bytes_wanted;
398     UINT i;
399
400     filehandle = _lcreat( filename, 0 );
401     if (filehandle == HFILE_ERROR)
402     {
403         ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
404         return;
405     }
406
407     ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
408
409     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
410
411     filehandle = _lopen( filename, OF_READ );
412
413     ok( HFILE_ERROR != filehandle, "couldn't open file \"%s\" again (err=%ld)\n", filename, GetLastError());
414
415     bytes_read = _lread( filehandle, buffer, 2 * strlen( sillytext ) );
416
417     ok( lstrlenA( sillytext ) == bytes_read, "file read size error\n" );
418
419     for (bytes_wanted = 0; bytes_wanted < strlen( sillytext ); bytes_wanted++)
420     {
421         ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
422         ok( _lread( filehandle, buffer, bytes_wanted ) == bytes_wanted, "erratic _hread return value\n" );
423         for (i = 0; i < bytes_wanted; i++)
424         {
425             ok( buffer[i] == sillytext[i], "that's not what's written\n" );
426         }
427     }
428
429     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
430
431     ok( DeleteFileA( filename ) != 0, "DeleteFile failed (%ld)\n", GetLastError(  ) );
432 }
433
434
435 static void test__lwrite( void )
436 {
437     HFILE filehandle;
438     char buffer[10000];
439     long bytes_read;
440     long bytes_written;
441     long blocks;
442     long i;
443     char *contents;
444     HLOCAL memory_object;
445     char checksum[1];
446
447     filehandle = _lcreat( filename, 0 );
448     if (filehandle == HFILE_ERROR)
449     {
450         ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
451         return;
452     }
453
454     ok( HFILE_ERROR != _lwrite( filehandle, "", 0 ), "_hwrite complains\n" );
455
456     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
457
458     filehandle = _lopen( filename, OF_READ );
459
460     bytes_read = _hread( filehandle, buffer, 1);
461
462     ok( 0 == bytes_read, "file read size error\n" );
463
464     ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
465
466     filehandle = _lopen( filename, OF_READWRITE );
467
468     bytes_written = 0;
469     checksum[0] = '\0';
470     srand( (unsigned)time( NULL ) );
471     for (blocks = 0; blocks < 100; blocks++)
472     {
473         for (i = 0; i < (long)sizeof( buffer ); i++)
474         {
475             buffer[i] = rand(  );
476             checksum[0] = checksum[0] + buffer[i];
477         }
478         ok( HFILE_ERROR != _lwrite( filehandle, buffer, sizeof( buffer ) ), "_hwrite complains\n" );
479         bytes_written = bytes_written + sizeof( buffer );
480     }
481
482     ok( HFILE_ERROR != _lwrite( filehandle, checksum, 1 ), "_hwrite complains\n" );
483     bytes_written++;
484
485     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
486
487     memory_object = LocalAlloc( LPTR, bytes_written );
488
489     ok( 0 != memory_object, "LocalAlloc fails, could be out of memory\n" );
490
491     contents = LocalLock( memory_object );
492
493     filehandle = _lopen( filename, OF_READ );
494
495     contents = LocalLock( memory_object );
496
497     ok( NULL != contents, "LocalLock whines\n" );
498
499     ok( bytes_written == _hread( filehandle, contents, bytes_written), "read length differ from write length\n" );
500
501     checksum[0] = '\0';
502     i = 0;
503     do
504     {
505         checksum[0] += contents[i];
506         i++;
507     }
508     while (i < bytes_written - 1);
509
510     ok( checksum[0] == contents[i], "stored checksum differ from computed checksum\n" );
511
512     ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
513
514     ok( DeleteFileA( filename ) != 0, "DeleteFile failed (%ld)\n", GetLastError(  ) );
515 }
516
517 static void test_CopyFileA(void)
518 {
519     char temp_path[MAX_PATH];
520     char source[MAX_PATH], dest[MAX_PATH];
521     static const char prefix[] = "pfx";
522     HANDLE hfile;
523     char buf[10];
524     DWORD ret;
525
526     ret = GetTempPathA(MAX_PATH, temp_path);
527     ok(ret != 0, "GetTempPathA error %ld\n", GetLastError());
528     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
529
530     ret = GetTempFileNameA(temp_path, prefix, 0, source);
531     ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
532
533     /* make the source have not zero size */
534     hfile = CreateFileA(source, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
535     ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
536     ok(WriteFile(hfile, prefix, sizeof(prefix), &ret, NULL ) && ret == sizeof(prefix),
537        "WriteFile error %ld\n", GetLastError());
538     ok(GetFileSize(hfile, NULL) == sizeof(prefix), "source file has wrong size\n");
539     CloseHandle(hfile);
540
541     ret = GetTempFileNameA(temp_path, prefix, 0, dest);
542     ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
543
544     SetLastError(0xdeadbeef);
545     ret = CopyFileA(source, dest, TRUE);
546     ok(!ret && GetLastError() == ERROR_FILE_EXISTS,
547        "CopyFileA: unexpected error %ld\n", GetLastError());
548
549     ret = CopyFileA(source, dest, FALSE);
550     ok(ret, "CopyFileA: error %ld\n", GetLastError());
551
552     /* make sure that destination has correct size */
553     hfile = CreateFileA(dest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
554     ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n");
555     ret = GetFileSize(hfile, NULL);
556     ok(ret == sizeof(prefix), "destination file has wrong size %ld\n", ret);
557
558     SetLastError(0xdeadbeef);
559     ret = CopyFileA(source, dest, FALSE);
560     ok(!ret && GetLastError() == ERROR_SHARING_VIOLATION,
561        "CopyFileA: ret = %ld, unexpected error %ld\n", ret, GetLastError());
562
563     /* make sure that destination still has correct size */
564     ret = GetFileSize(hfile, NULL);
565     ok(ret == sizeof(prefix), "destination file has wrong size %ld\n", ret);
566     ok(ReadFile(hfile, buf, sizeof(buf), &ret, NULL) && ret == sizeof(prefix),
567        "ReadFile: error %ld\n", GetLastError());
568     ok(!memcmp(prefix, buf, sizeof(prefix)), "buffer contents mismatch\n");
569     CloseHandle(hfile);
570
571     ret = DeleteFileA(source);
572     ok(ret, "DeleteFileA: error %ld\n", GetLastError());
573     ret = DeleteFileA(dest);
574     ok(ret, "DeleteFileA: error %ld\n", GetLastError());
575 }
576
577 static void test_CopyFileW(void)
578 {
579     WCHAR temp_path[MAX_PATH];
580     WCHAR source[MAX_PATH], dest[MAX_PATH];
581     static const WCHAR prefix[] = {'p','f','x',0};
582     DWORD ret;
583
584     ret = GetTempPathW(MAX_PATH, temp_path);
585     if (ret==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
586         return;
587     ok(ret != 0, "GetTempPathW error %ld\n", GetLastError());
588     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
589
590     ret = GetTempFileNameW(temp_path, prefix, 0, source);
591     ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError());
592
593     ret = GetTempFileNameW(temp_path, prefix, 0, dest);
594     ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError());
595
596     ret = CopyFileW(source, dest, TRUE);
597     ok(!ret && GetLastError() == ERROR_FILE_EXISTS,
598        "CopyFileW: unexpected error %ld\n", GetLastError());
599
600     ret = CopyFileW(source, dest, FALSE);
601     ok(ret, "CopyFileW: error %ld\n", GetLastError());
602
603     ret = DeleteFileW(source);
604     ok(ret, "DeleteFileW: error %ld\n", GetLastError());
605     ret = DeleteFileW(dest);
606     ok(ret, "DeleteFileW: error %ld\n", GetLastError());
607 }
608
609 static void test_CreateFileA(void)
610 {
611     HANDLE hFile;
612     char temp_path[MAX_PATH];
613     char filename[MAX_PATH];
614     static const char prefix[] = "pfx";
615     DWORD ret;
616
617     ret = GetTempPathA(MAX_PATH, temp_path);
618     ok(ret != 0, "GetTempPathA error %ld\n", GetLastError());
619     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
620
621     ret = GetTempFileNameA(temp_path, prefix, 0, filename);
622     ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
623
624     hFile = CreateFileA(filename, GENERIC_READ, 0, NULL,
625                         CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
626     ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS,
627         "CREATE_NEW should fail if file exists and last error value should be ERROR_FILE_EXISTS\n");
628
629     ret = DeleteFileA(filename);
630     ok(ret, "DeleteFileA: error %ld\n", GetLastError());
631 }
632
633 static void test_CreateFileW(void)
634 {
635     HANDLE hFile;
636     WCHAR temp_path[MAX_PATH];
637     WCHAR filename[MAX_PATH];
638     static const WCHAR emptyW[]={'\0'};
639     static const WCHAR prefix[] = {'p','f','x',0};
640     DWORD ret;
641
642     ret = GetTempPathW(MAX_PATH, temp_path);
643     if (ret==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
644         return;
645     ok(ret != 0, "GetTempPathW error %ld\n", GetLastError());
646     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
647
648     ret = GetTempFileNameW(temp_path, prefix, 0, filename);
649     ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError());
650
651     hFile = CreateFileW(filename, GENERIC_READ, 0, NULL,
652                         CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
653     ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS,
654         "CREATE_NEW should fail if file exists and last error value should be ERROR_FILE_EXISTS\n");
655
656     ret = DeleteFileW(filename);
657     ok(ret, "DeleteFileW: error %ld\n", GetLastError());
658
659     hFile = CreateFileW(NULL, GENERIC_READ, 0, NULL,
660                         CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
661     ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
662        "CreateFileW(NULL) returned ret=%p error=%ld\n",hFile,GetLastError());
663
664     hFile = CreateFileW(emptyW, GENERIC_READ, 0, NULL,
665                         CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
666     ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
667        "CreateFileW(\"\") returned ret=%p error=%ld\n",hFile,GetLastError());
668 }
669
670 static void test_GetTempFileNameA()
671 {
672     UINT result;
673     char out[MAX_PATH];
674     char expected[MAX_PATH + 10];
675     char windowsdir[MAX_PATH + 10];
676     char windowsdrive[3];
677
678     result = GetWindowsDirectory(windowsdir, sizeof(windowsdir));
679     ok(result < sizeof(windowsdir), "windowsdir is abnormally long!\n");
680     ok(result != 0, "GetWindowsDirectory: error %ld\n", GetLastError());
681
682     /* If the Windows directory is the root directory, it ends in backslash, not else. */
683     if (strlen(windowsdir) != 3) /* As in  "C:\"  or  "F:\"  */
684     {
685         strcat(windowsdir, "\\");
686     }
687
688     windowsdrive[0] = windowsdir[0];
689     windowsdrive[1] = windowsdir[1];
690     windowsdrive[2] = '\0';
691
692     result = GetTempFileNameA(windowsdrive, "abc", 1, out);
693     ok(result != 0, "GetTempFileNameA: error %ld\n", GetLastError());
694     ok(((out[0] == windowsdrive[0]) && (out[1] == ':')) && (out[2] == '\\'),
695        "GetTempFileNameA: first three characters should be %c:\\, string was actually %s\n",
696        windowsdrive[0], out);
697
698     result = GetTempFileNameA(windowsdir, "abc", 2, out);
699     ok(result != 0, "GetTempFileNameA: error %ld\n", GetLastError());
700     expected[0] = '\0';
701     strcat(expected, windowsdir);
702     strcat(expected, "abc2.tmp");
703     ok(lstrcmpiA(out, expected) == 0, "GetTempFileNameA: Unexpected output \"%s\" vs \"%s\"\n",
704        out, expected);
705 }
706
707 static void test_DeleteFileA( void )
708 {
709     BOOL ret;
710
711     ret = DeleteFileA(NULL);
712     ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER ||
713                 GetLastError() == ERROR_PATH_NOT_FOUND),
714        "DeleteFileA(NULL) returned ret=%d error=%ld\n",ret,GetLastError());
715
716     ret = DeleteFileA("");
717     ok(!ret && (GetLastError() == ERROR_PATH_NOT_FOUND ||
718                 GetLastError() == ERROR_BAD_PATHNAME),
719        "DeleteFileA(\"\") returned ret=%d error=%ld\n",ret,GetLastError());
720
721     ret = DeleteFileA("nul");
722     ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
723                 GetLastError() == ERROR_INVALID_PARAMETER ||
724                 GetLastError() == ERROR_ACCESS_DENIED),
725        "DeleteFileA(\"nul\") returned ret=%d error=%ld\n",ret,GetLastError());
726 }
727
728 static void test_DeleteFileW( void )
729 {
730     BOOL ret;
731     static const WCHAR emptyW[]={'\0'};
732
733     ret = DeleteFileW(NULL);
734     if (ret==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
735         return;
736     ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND,
737        "DeleteFileW(NULL) returned ret=%d error=%ld\n",ret,GetLastError());
738
739     ret = DeleteFileW(emptyW);
740     ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND,
741        "DeleteFileW(\"\") returned ret=%d error=%ld\n",ret,GetLastError());
742 }
743
744 #define IsDotDir(x)     ((x[0] == '.') && ((x[1] == 0) || ((x[1] == '.') && (x[2] == 0))))
745
746 static void test_MoveFileA(void)
747 {
748     char tempdir[MAX_PATH];
749     char source[MAX_PATH], dest[MAX_PATH];
750     static const char prefix[] = "pfx";
751     DWORD ret;
752
753     ret = GetTempPathA(MAX_PATH, tempdir);
754     ok(ret != 0, "GetTempPathA error %ld\n", GetLastError());
755     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
756
757     ret = GetTempFileNameA(tempdir, prefix, 0, source);
758     ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
759
760     ret = GetTempFileNameA(tempdir, prefix, 0, dest);
761     ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
762
763     ret = MoveFileA(source, dest);
764     ok(!ret && GetLastError() == ERROR_ALREADY_EXISTS,
765        "MoveFileA: unexpected error %ld\n", GetLastError());
766
767     ret = DeleteFileA(dest);
768     ok(ret, "DeleteFileA: error %ld\n", GetLastError());
769
770     ret = MoveFileA(source, dest);
771     ok(ret, "MoveFileA: failed, error %ld\n", GetLastError());
772
773     lstrcatA(tempdir, "Remove Me");
774     ret = CreateDirectoryA(tempdir, NULL);
775     ok(ret == TRUE, "CreateDirectoryA failed\n");
776
777     lstrcpyA(source, dest);
778     lstrcpyA(dest, tempdir);
779     lstrcatA(dest, "\\wild?.*");
780     /* FIXME: if we create a file with wildcards we can't delete it now that DeleteFile works correctly */
781     ret = MoveFileA(source, dest);
782     ok(!ret, "MoveFileA: shouldn't move to wildcard file\n");
783     ok(GetLastError() == ERROR_INVALID_NAME || /* NT */
784        GetLastError() == ERROR_FILE_NOT_FOUND, /* Win9x */
785        "MoveFileA: with wildcards, unexpected error %ld\n", GetLastError());
786     if (ret || (GetLastError() != ERROR_INVALID_NAME))
787     {
788         WIN32_FIND_DATAA fd;
789         char temppath[MAX_PATH];
790         HANDLE hFind;
791
792         lstrcpyA(temppath, tempdir);
793         lstrcatA(temppath, "\\*.*");
794         hFind = FindFirstFileA(temppath, &fd);
795         if (INVALID_HANDLE_VALUE != hFind)
796         {
797           LPSTR lpName;
798           do
799           {
800             lpName = fd.cAlternateFileName;
801             if (!lpName[0])
802               lpName = fd.cFileName;
803             ok(IsDotDir(lpName), "MoveFileA: wildcards file created!\n");
804           }
805           while (FindNextFileA(hFind, &fd));
806           FindClose(hFind);
807         }
808     }
809     ret = DeleteFileA(source);
810     ok(ret, "DeleteFileA: error %ld\n", GetLastError());
811     ret = DeleteFileA(dest);
812     ok(!ret, "DeleteFileA: error %ld\n", GetLastError());
813     ret = RemoveDirectoryA(tempdir);
814     ok(ret, "DeleteDirectoryA: error %ld\n", GetLastError());
815 }
816
817 static void test_MoveFileW(void)
818 {
819     WCHAR temp_path[MAX_PATH];
820     WCHAR source[MAX_PATH], dest[MAX_PATH];
821     static const WCHAR prefix[] = {'p','f','x',0};
822     DWORD ret;
823
824     ret = GetTempPathW(MAX_PATH, temp_path);
825     if (ret==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
826         return;
827     ok(ret != 0, "GetTempPathW error %ld\n", GetLastError());
828     ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
829
830     ret = GetTempFileNameW(temp_path, prefix, 0, source);
831     ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError());
832
833     ret = GetTempFileNameW(temp_path, prefix, 0, dest);
834     ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError());
835
836     ret = MoveFileW(source, dest);
837     ok(!ret && GetLastError() == ERROR_ALREADY_EXISTS,
838        "CopyFileW: unexpected error %ld\n", GetLastError());
839
840     ret = DeleteFileW(source);
841     ok(ret, "DeleteFileW: error %ld\n", GetLastError());
842     ret = DeleteFileW(dest);
843     ok(ret, "DeleteFileW: error %ld\n", GetLastError());
844 }
845
846 #define PATTERN_OFFSET 0x10
847
848 static void test_offset_in_overlapped_structure(void)
849 {
850     HANDLE hFile;
851     OVERLAPPED ov;
852     DWORD done;
853     BOOL rc;
854     BYTE buf[256], pattern[] = "TeSt";
855     UINT i;
856     char temp_path[MAX_PATH], temp_fname[MAX_PATH];
857
858     ok(GetTempPathA(MAX_PATH, temp_path) != 0, "GetTempPathA error %ld\n", GetLastError());
859     ok(GetTempFileNameA(temp_path, "pfx", 0, temp_fname) != 0, "GetTempFileNameA error %ld\n", GetLastError());
860
861     /*** Write File *****************************************************/
862
863     hFile = CreateFileA(temp_fname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
864     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA error %ld\n", GetLastError());
865
866     for(i = 0; i < sizeof(buf); i++) buf[i] = i;
867     ok(WriteFile(hFile, buf, sizeof(buf), &done, NULL), "WriteFile error %ld\n", GetLastError());
868     ok(done == sizeof(buf), "expected number of bytes written %lu\n", done);
869
870     memset(&ov, 0, sizeof(ov));
871     ov.Offset = PATTERN_OFFSET;
872     ov.OffsetHigh = 0;
873     rc=WriteFile(hFile, pattern, sizeof(pattern), &done, &ov);
874     /* Win 9x does not support the overlapped I/O on files */
875     if (rc || GetLastError()!=ERROR_INVALID_PARAMETER) {
876         ok(rc, "WriteFile error %ld\n", GetLastError());
877         ok(done == sizeof(pattern), "expected number of bytes written %lu\n", done);
878         /*trace("Current offset = %04lx\n", SetFilePointer(hFile, 0, NULL, FILE_CURRENT));*/
879         ok(SetFilePointer(hFile, 0, NULL, FILE_CURRENT) == (PATTERN_OFFSET + sizeof(pattern)),
880            "expected file offset %d\n", PATTERN_OFFSET + sizeof(pattern));
881
882         ov.Offset = sizeof(buf) * 2;
883         ov.OffsetHigh = 0;
884         ok(WriteFile(hFile, pattern, sizeof(pattern), &done, &ov), "WriteFile error %ld\n", GetLastError());
885         ok(done == sizeof(pattern), "expected number of bytes written %lu\n", done);
886         /*trace("Current offset = %04lx\n", SetFilePointer(hFile, 0, NULL, FILE_CURRENT));*/
887         ok(SetFilePointer(hFile, 0, NULL, FILE_CURRENT) == (sizeof(buf) * 2 + sizeof(pattern)),
888            "expected file offset %d\n", sizeof(buf) * 2 + sizeof(pattern));
889     }
890
891     CloseHandle(hFile);
892
893     /*** Read File *****************************************************/
894
895     hFile = CreateFileA(temp_fname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
896     ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA error %ld\n", GetLastError());
897
898     memset(buf, 0, sizeof(buf));
899     memset(&ov, 0, sizeof(ov));
900     ov.Offset = PATTERN_OFFSET;
901     ov.OffsetHigh = 0;
902     rc=ReadFile(hFile, buf, sizeof(pattern), &done, &ov);
903     /* Win 9x does not support the overlapped I/O on files */
904     if (rc || GetLastError()!=ERROR_INVALID_PARAMETER) {
905         ok(rc, "ReadFile error %ld\n", GetLastError());
906         ok(done == sizeof(pattern), "expected number of bytes read %lu\n", done);
907         /*trace("Current offset = %04lx\n", SetFilePointer(hFile, 0, NULL, FILE_CURRENT));*/
908         ok(SetFilePointer(hFile, 0, NULL, FILE_CURRENT) == (PATTERN_OFFSET + sizeof(pattern)),
909            "expected file offset %d\n", PATTERN_OFFSET + sizeof(pattern));
910         ok(!memcmp(buf, pattern, sizeof(pattern)), "pattern match failed\n");
911     }
912
913     CloseHandle(hFile);
914
915     ok(DeleteFileA(temp_fname), "DeleteFileA error %ld\n", GetLastError());
916 }
917
918 static void test_LockFile(void)
919 {
920     HANDLE handle;
921     DWORD written;
922     OVERLAPPED overlapped;
923     int limited_LockFile;
924     int limited_UnLockFile;
925     int lockfileex_capable;
926
927     handle = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
928                           FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
929                           CREATE_ALWAYS, 0, 0 );
930     if (handle == INVALID_HANDLE_VALUE)
931     {
932         ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
933         return;
934     }
935     ok( WriteFile( handle, sillytext, strlen(sillytext), &written, NULL ), "write failed\n" );
936
937     ok( LockFile( handle, 0, 0, 0, 0 ), "LockFile failed\n" );
938     ok( UnlockFile( handle, 0, 0, 0, 0 ), "UnlockFile failed\n" );
939
940     limited_UnLockFile = 0;
941     if (UnlockFile( handle, 0, 0, 0, 0 ))
942     {
943         limited_UnLockFile = 1;
944     }
945
946     ok( LockFile( handle, 10, 0, 20, 0 ), "LockFile 10,20 failed\n" );
947     /* overlapping locks must fail */
948     ok( !LockFile( handle, 12, 0, 10, 0 ), "LockFile 12,10 succeeded\n" );
949     ok( !LockFile( handle, 5, 0, 6, 0 ), "LockFile 5,6 succeeded\n" );
950     /* non-overlapping locks must succeed */
951     ok( LockFile( handle, 5, 0, 5, 0 ), "LockFile 5,5 failed\n" );
952
953     ok( !UnlockFile( handle, 10, 0, 10, 0 ), "UnlockFile 10,10 succeeded\n" );
954     ok( UnlockFile( handle, 10, 0, 20, 0 ), "UnlockFile 10,20 failed\n" );
955     ok( !UnlockFile( handle, 10, 0, 20, 0 ), "UnlockFile 10,20 again succeeded\n" );
956     ok( UnlockFile( handle, 5, 0, 5, 0 ), "UnlockFile 5,5 failed\n" );
957
958     overlapped.Offset = 100;
959     overlapped.OffsetHigh = 0;
960     overlapped.hEvent = 0;
961
962     lockfileex_capable = dll_capable("kernel32", "LockFileEx");
963     if (lockfileex_capable)
964     {
965         /* Test for broken LockFileEx a la Windows 95 OSR2. */
966         if (LockFileEx( handle, 0, 0, 100, 0, &overlapped ))
967         {
968             /* LockFileEx is probably OK, test it more. */
969             ok( LockFileEx( handle, 0, 0, 100, 0, &overlapped ),
970                 "LockFileEx 100,100 failed\n" );
971         }
972     }
973
974     /* overlapping shared locks are OK */
975     overlapped.Offset = 150;
976     limited_UnLockFile || ok( LockFileEx( handle, 0, 0, 100, 0, &overlapped ), "LockFileEx 150,100 failed\n" );
977
978     /* but exclusive is not */
979     if (lockfileex_capable)
980     {
981         ok( !LockFileEx( handle, LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,
982                          0, 50, 0, &overlapped ),
983                          "LockFileEx exclusive 150,50 succeeded\n" );
984         if (dll_capable("kernel32.dll", "UnlockFileEx"))
985         {
986             if (!UnlockFileEx( handle, 0, 100, 0, &overlapped ))
987             { /* UnLockFile is capable. */
988                 overlapped.Offset = 100;
989                 ok( !UnlockFileEx( handle, 0, 100, 0, &overlapped ),
990                     "UnlockFileEx 150,100 again succeeded\n" );
991             }
992         }
993     }
994
995     ok( LockFile( handle, 0, 0x10000000, 0, 0xf0000000 ), "LockFile failed\n" );
996     ok( !LockFile( handle, ~0, ~0, 1, 0 ), "LockFile ~0,1 succeeded\n" );
997     ok( !LockFile( handle, 0, 0x20000000, 20, 0 ), "LockFile 0x20000000,20 succeeded\n" );
998     ok( UnlockFile( handle, 0, 0x10000000, 0, 0xf0000000 ), "UnlockFile failed\n" );
999
1000     /* wrap-around lock should not do anything */
1001     /* (but still succeeds on NT4 so we don't check result) */
1002     LockFile( handle, 0, 0x10000000, 0, 0xf0000001 );
1003
1004     limited_LockFile = 0;
1005     if (!LockFile( handle, ~0, ~0, 1, 0 ))
1006     {
1007         limited_LockFile = 1;
1008     }
1009
1010     limited_UnLockFile || ok( UnlockFile( handle, ~0, ~0, 1, 0 ), "Unlockfile ~0,1 failed\n" );
1011
1012     /* zero-byte lock */
1013     ok( LockFile( handle, 100, 0, 0, 0 ), "LockFile 100,0 failed\n" );
1014     limited_LockFile || ok( !LockFile( handle, 98, 0, 4, 0 ), "LockFile 98,4 succeeded\n" );
1015     ok( LockFile( handle, 90, 0, 10, 0 ), "LockFile 90,10 failed\n" );
1016     limited_LockFile || ok( !LockFile( handle, 100, 0, 10, 0 ), "LockFile 100,10 failed\n" );
1017
1018     ok( UnlockFile( handle, 90, 0, 10, 0 ), "UnlockFile 90,10 failed\n" );
1019     !ok( UnlockFile( handle, 100, 0, 10, 0 ), "UnlockFile 100,10 failed\n" );
1020
1021     ok( UnlockFile( handle, 100, 0, 0, 0 ), "UnlockFile 100,0 failed\n" );
1022
1023     CloseHandle( handle );
1024     DeleteFileA( filename );
1025 }
1026
1027 static inline int is_sharing_compatible( DWORD access1, DWORD sharing1, DWORD access2, DWORD sharing2 )
1028 {
1029     if (!access1 || !access2) return 1;
1030     if ((access1 & GENERIC_READ) && !(sharing2 & FILE_SHARE_READ)) return 0;
1031     if ((access1 & GENERIC_WRITE) && !(sharing2 & FILE_SHARE_WRITE)) return 0;
1032     if ((access2 & GENERIC_READ) && !(sharing1 & FILE_SHARE_READ)) return 0;
1033     if ((access2 & GENERIC_WRITE) && !(sharing1 & FILE_SHARE_WRITE)) return 0;
1034     return 1;
1035 }
1036
1037 static void test_file_sharing(void)
1038 {
1039     static const DWORD access_modes[4] = { 0, GENERIC_READ, GENERIC_WRITE, GENERIC_READ|GENERIC_WRITE };
1040     static const DWORD sharing_modes[4] = { 0, FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE };
1041     int a1, s1, a2, s2;
1042     int ret;
1043
1044     /* make sure the file exists */
1045     HANDLE h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1046     CloseHandle( h );
1047
1048     for (a1 = 0; a1 < 4; a1++)
1049     {
1050         for (s1 = 0; s1 < 4; s1++)
1051         {
1052             HANDLE h = CreateFileA( filename, access_modes[a1], sharing_modes[s1],
1053                                     NULL, OPEN_EXISTING, 0, 0 );
1054             if (h == INVALID_HANDLE_VALUE)
1055             {
1056                 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
1057                 return;
1058             }
1059             for (a2 = 0; a2 < 4; a2++)
1060             {
1061                 for (s2 = 0; s2 < 4; s2++)
1062                 {
1063                     HANDLE h2 = CreateFileA( filename, access_modes[a2], sharing_modes[s2],
1064                                           NULL, OPEN_EXISTING, 0, 0 );
1065                     if (is_sharing_compatible( access_modes[a1], sharing_modes[s1],
1066                                                access_modes[a2], sharing_modes[s2] ))
1067                     {
1068                         ret = GetLastError();
1069                         ok( ERROR_SHARING_VIOLATION == ret || 0 == ret,
1070                             "Windows 95 sets GetLastError() = ERROR_SHARING_VIOLATION and\n"
1071                             "  Windows XP GetLastError() = 0, but now it is %d.\n"
1072                             "  indexes = %d, %d, %d, %d\n"
1073                             "  modes   =\n  %lx/%lx/%lx/%lx\n",
1074                             ret,
1075                             a1, s1, a2, s2, 
1076                             access_modes[a1], sharing_modes[s1],
1077                             access_modes[a2], sharing_modes[s2]
1078                             );
1079                     }
1080                     else
1081                     {
1082                         ok( h2 == INVALID_HANDLE_VALUE,
1083                             "open succeeded for modes %lx/%lx/%lx/%lx\n",
1084                             access_modes[a1], sharing_modes[s1],
1085                             access_modes[a2], sharing_modes[s2] );
1086                         if (h2 == INVALID_HANDLE_VALUE)
1087                             ok( GetLastError() == ERROR_SHARING_VIOLATION,
1088                                 "wrong error code %ld\n", GetLastError() );
1089                     }
1090                     if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 );
1091                 }
1092             }
1093             CloseHandle( h );
1094         }
1095     }
1096     DeleteFileA( filename );
1097 }
1098
1099 static void test_FindFirstFileA()
1100 {
1101     HANDLE handle;
1102     WIN32_FIND_DATAA search_results;
1103     int err;
1104
1105     handle = FindFirstFileA("C:\\",&search_results);
1106     err = GetLastError();
1107     ok ( handle == INVALID_HANDLE_VALUE , "FindFirstFile on Root directory should Fail\n");
1108     if (handle == INVALID_HANDLE_VALUE)
1109       ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err);
1110     handle = FindFirstFileA("C:\\*",&search_results);
1111     ok ( handle != INVALID_HANDLE_VALUE, "FindFirstFile on C:\\* should succeed\n" );
1112     ok ( FindClose(handle) == TRUE, "Failed to close handle\n");
1113 }
1114
1115 static void test_FindNextFileA()
1116 {
1117     HANDLE handle;
1118     WIN32_FIND_DATAA search_results;
1119     int err;
1120
1121     handle = FindFirstFileA("C:\\*",&search_results);
1122     ok ( handle != INVALID_HANDLE_VALUE, "FindFirstFile on C:\\* should succeed\n" );
1123     while (FindNextFile(handle, &search_results))
1124     {
1125         /* get to the end of the files */
1126     }
1127     ok ( FindClose(handle) == TRUE, "Failed to close handle\n");
1128     err = GetLastError();
1129     ok ( err == ERROR_NO_MORE_FILES, "GetLastError should return ERROR_NO_MORE_FILES\n");
1130 }
1131
1132 static int test_Mapfile_createtemp(HANDLE *handle)
1133 {
1134     SetFileAttributesA(filename,FILE_ATTRIBUTE_NORMAL);
1135     DeleteFile(filename);
1136     *handle = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, 0,
1137                          CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1138     if (*handle != INVALID_HANDLE_VALUE) {
1139
1140         return 1;
1141     }
1142
1143     return 0;
1144 }
1145
1146 static void test_MapFile()
1147 {
1148     HANDLE handle;
1149     HANDLE hmap;
1150
1151     ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
1152
1153     hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0x1000, "named_file_map" );
1154     ok( hmap != NULL, "mapping should work, I named it!\n" );
1155
1156     ok( CloseHandle( hmap ), "can't close mapping handle\n");
1157
1158     /* We have to close file before we try new stuff with mapping again.
1159        Else we would always succeed on XP or block descriptors on 95. */
1160     hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
1161     ok( hmap != NULL, "We should still be able to map!\n" );
1162     ok( CloseHandle( hmap ), "can't close mapping handle\n");
1163     ok( CloseHandle( handle ), "can't close file handle\n");
1164     handle = NULL;
1165
1166     ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
1167
1168     hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
1169     ok( hmap == NULL, "Mapping should not work, no name provided.\n" );
1170
1171     ok( hmap == NULL, "mapped zero size file\n");
1172     ok( GetLastError() == ERROR_FILE_INVALID, "not ERROR_FILE_INVALID\n");
1173
1174     hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0x1000, 0, NULL );
1175     ok( hmap == NULL, "mapping should fail\n");
1176     /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */
1177
1178     hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0x1000, 0x10000, NULL );
1179     ok( hmap == NULL, "mapping should fail\n");
1180     /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */
1181
1182     /* On XP you can now map again, on Win 95 you can not. */
1183
1184     ok( CloseHandle( handle ), "can't close file handle\n");
1185     ok( DeleteFileA( filename ), "DeleteFile failed after map\n" );
1186 }
1187
1188 static void test_GetFileType(void)
1189 {
1190     DWORD type;
1191     HANDLE h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1192     ok( h != INVALID_HANDLE_VALUE, "open %s failed\n", filename );
1193     type = GetFileType(h);
1194     ok( type == FILE_TYPE_DISK, "expected type disk got %ld\n", type );
1195     CloseHandle( h );
1196     h = CreateFileA( "nul", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
1197     ok( h != INVALID_HANDLE_VALUE, "open nul failed\n" );
1198     type = GetFileType(h);
1199     ok( type == FILE_TYPE_CHAR, "expected type char for nul got %ld\n", type );
1200     CloseHandle( h );
1201     DeleteFileA( filename );
1202 }
1203
1204 START_TEST(file)
1205 {
1206     test__hread(  );
1207     test__hwrite(  );
1208     test__lclose(  );
1209     test__lcreat(  );
1210     test__llseek(  );
1211     test__llopen(  );
1212     test__lread(  );
1213     test__lwrite(  );
1214     test_GetTempFileNameA();
1215     test_CopyFileA();
1216     test_CopyFileW();
1217     test_CreateFileA();
1218     test_CreateFileW();
1219     test_DeleteFileA();
1220     test_DeleteFileW();
1221     test_MoveFileA();
1222     test_MoveFileW();
1223     test_FindFirstFileA();
1224     test_FindNextFileA();
1225     test_LockFile();
1226     test_file_sharing();
1227     test_offset_in_overlapped_structure();
1228     test_MapFile();
1229     test_GetFileType();
1230 }