kernel32/tests: Add tests for FindFirstFileExA with FIND_FIRST_EX_LARGE_FETCH flag.
[wine.git] / dlls / kernel32 / tests / file.c
blob106e68ad8143f11f2e52a81a5b9af9254c8323e4
1 /*
2 * Unit tests for file functions in Wine
4 * Copyright (c) 2002, 2004 Jakob Eriksson
5 * Copyright (c) 2008 Jeff Zaroyko
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.
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.
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
23 /* ReplaceFile requires Windows 2000 or newer */
24 #define _WIN32_WINNT 0x0500
26 #include <stdarg.h>
27 #include <stdlib.h>
28 #include <time.h>
29 #include <stdio.h>
31 #include "wine/test.h"
32 #include "windef.h"
33 #include "winbase.h"
34 #include "winerror.h"
35 #include "winnls.h"
36 #include "fileapi.h"
38 static HANDLE (WINAPI *pFindFirstFileExA)(LPCSTR,FINDEX_INFO_LEVELS,LPVOID,FINDEX_SEARCH_OPS,LPVOID,DWORD);
39 static BOOL (WINAPI *pReplaceFileA)(LPCSTR, LPCSTR, LPCSTR, DWORD, LPVOID, LPVOID);
40 static BOOL (WINAPI *pReplaceFileW)(LPCWSTR, LPCWSTR, LPCWSTR, DWORD, LPVOID, LPVOID);
41 static UINT (WINAPI *pGetSystemWindowsDirectoryA)(LPSTR, UINT);
42 static BOOL (WINAPI *pGetVolumeNameForVolumeMountPointA)(LPCSTR, LPSTR, DWORD);
43 static DWORD (WINAPI *pQueueUserAPC)(PAPCFUNC pfnAPC, HANDLE hThread, ULONG_PTR dwData);
44 static BOOL (WINAPI *pGetFileInformationByHandleEx)(HANDLE, FILE_INFO_BY_HANDLE_CLASS, LPVOID, DWORD);
45 static HANDLE (WINAPI *pOpenFileById)(HANDLE, LPFILE_ID_DESCRIPTOR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD);
46 static BOOL (WINAPI *pSetFileValidData)(HANDLE, LONGLONG);
47 static HRESULT (WINAPI *pCopyFile2)(PCWSTR,PCWSTR,COPYFILE2_EXTENDED_PARAMETERS*);
48 static HANDLE (WINAPI *pCreateFile2)(LPCWSTR, DWORD, DWORD, DWORD, CREATEFILE2_EXTENDED_PARAMETERS*);
50 /* keep filename and filenameW the same */
51 static const char filename[] = "testfile.xxx";
52 static const WCHAR filenameW[] = { 't','e','s','t','f','i','l','e','.','x','x','x',0 };
53 static const char sillytext[] =
54 "en larvig liten text dx \033 gx hej 84 hej 4484 ! \001\033 bla bl\na.. bla bla."
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 "1234 43 4kljf lf &%%%&&&&&& 34 4 34 3############# 33 3 3 3 # 3## 3"
61 "1234 43 4kljf lf &%%%&&&&&& 34 4 34 3############# 33 3 3 3 # 3## 3"
62 "1234 43 4kljf lf &%%%&&&&&& 34 4 34 3############# 33 3 3 3 # 3## 3"
63 "sdlkfjasdlkfj a dslkj adsklf \n \nasdklf askldfa sdlkf \nsadklf asdklf asdf ";
65 struct test_list {
66 const char *file; /* file string to test */
67 const DWORD err; /* Win NT and further error code */
68 const LONG err2; /* Win 9x & ME error code or -1 */
69 const DWORD options; /* option flag to use for open */
70 const BOOL todo_flag; /* todo_wine indicator */
71 } ;
73 static void InitFunctionPointers(void)
75 HMODULE hkernel32 = GetModuleHandleA("kernel32");
77 pFindFirstFileExA=(void*)GetProcAddress(hkernel32, "FindFirstFileExA");
78 pReplaceFileA=(void*)GetProcAddress(hkernel32, "ReplaceFileA");
79 pReplaceFileW=(void*)GetProcAddress(hkernel32, "ReplaceFileW");
80 pGetSystemWindowsDirectoryA=(void*)GetProcAddress(hkernel32, "GetSystemWindowsDirectoryA");
81 pGetVolumeNameForVolumeMountPointA = (void *) GetProcAddress(hkernel32, "GetVolumeNameForVolumeMountPointA");
82 pQueueUserAPC = (void *) GetProcAddress(hkernel32, "QueueUserAPC");
83 pGetFileInformationByHandleEx = (void *) GetProcAddress(hkernel32, "GetFileInformationByHandleEx");
84 pOpenFileById = (void *) GetProcAddress(hkernel32, "OpenFileById");
85 pSetFileValidData = (void *) GetProcAddress(hkernel32, "SetFileValidData");
86 pCopyFile2 = (void *) GetProcAddress(hkernel32, "CopyFile2");
87 pCreateFile2 = (void *) GetProcAddress(hkernel32, "CreateFile2");
90 static void test__hread( void )
92 HFILE filehandle;
93 char buffer[10000];
94 LONG bytes_read;
95 LONG bytes_wanted;
96 LONG i;
97 BOOL ret;
99 SetFileAttributesA(filename,FILE_ATTRIBUTE_NORMAL); /* be sure to remove stale files */
100 DeleteFileA( filename );
101 filehandle = _lcreat( filename, 0 );
102 if (filehandle == HFILE_ERROR)
104 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
105 return;
108 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
110 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
112 filehandle = _lopen( filename, OF_READ );
114 ok( HFILE_ERROR != filehandle, "couldn't open file \"%s\" again (err=%d)\n", filename, GetLastError( ) );
116 bytes_read = _hread( filehandle, buffer, 2 * strlen( sillytext ) );
118 ok( lstrlenA( sillytext ) == bytes_read, "file read size error\n" );
120 for (bytes_wanted = 0; bytes_wanted < lstrlenA( sillytext ); bytes_wanted++)
122 ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
123 ok( _hread( filehandle, buffer, bytes_wanted ) == bytes_wanted, "erratic _hread return value\n" );
124 for (i = 0; i < bytes_wanted; i++)
126 ok( buffer[i] == sillytext[i], "that's not what's written\n" );
130 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
132 ret = DeleteFileA( filename );
133 ok( ret != 0, "DeleteFile failed (%d)\n", GetLastError( ) );
137 static void test__hwrite( void )
139 HFILE filehandle;
140 char buffer[10000];
141 LONG bytes_read;
142 LONG bytes_written;
143 ULONG blocks;
144 LONG i;
145 char *contents;
146 HLOCAL memory_object;
147 char checksum[1];
148 BOOL ret;
150 filehandle = _lcreat( filename, 0 );
151 if (filehandle == HFILE_ERROR)
153 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
154 return;
157 ok( HFILE_ERROR != _hwrite( filehandle, "", 0 ), "_hwrite complains\n" );
159 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
161 filehandle = _lopen( filename, OF_READ );
163 bytes_read = _hread( filehandle, buffer, 1);
165 ok( 0 == bytes_read, "file read size error\n" );
167 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
169 filehandle = _lopen( filename, OF_READWRITE );
171 bytes_written = 0;
172 checksum[0] = '\0';
173 srand( (unsigned)time( NULL ) );
174 for (blocks = 0; blocks < 100; blocks++)
176 for (i = 0; i < (LONG)sizeof( buffer ); i++)
178 buffer[i] = rand( );
179 checksum[0] = checksum[0] + buffer[i];
181 ok( HFILE_ERROR != _hwrite( filehandle, buffer, sizeof( buffer ) ), "_hwrite complains\n" );
182 bytes_written = bytes_written + sizeof( buffer );
185 ok( HFILE_ERROR != _hwrite( filehandle, checksum, 1 ), "_hwrite complains\n" );
186 bytes_written++;
188 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
190 memory_object = LocalAlloc( LPTR, bytes_written );
192 ok( 0 != memory_object, "LocalAlloc fails. (Could be out of memory.)\n" );
194 contents = LocalLock( memory_object );
195 ok( NULL != contents, "LocalLock whines\n" );
197 filehandle = _lopen( filename, OF_READ );
199 contents = LocalLock( memory_object );
200 ok( NULL != contents, "LocalLock whines\n" );
202 ok( bytes_written == _hread( filehandle, contents, bytes_written), "read length differ from write length\n" );
204 checksum[0] = '\0';
205 i = 0;
208 checksum[0] = checksum[0] + contents[i];
209 i++;
211 while (i < bytes_written - 1);
213 ok( checksum[0] == contents[i], "stored checksum differ from computed checksum\n" );
215 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
217 ret = DeleteFileA( filename );
218 ok( ret != 0, "DeleteFile failed (%d)\n", GetLastError( ) );
220 LocalFree( contents );
224 static void test__lclose( void )
226 HFILE filehandle;
227 BOOL ret;
229 filehandle = _lcreat( filename, 0 );
230 if (filehandle == HFILE_ERROR)
232 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
233 return;
236 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
238 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
240 ret = DeleteFileA( filename );
241 ok( ret != 0, "DeleteFile failed (%d)\n", GetLastError( ) );
245 static void test__lcreat( void )
247 HFILE filehandle;
248 char buffer[10000];
249 WIN32_FIND_DATAA search_results;
250 char slashname[] = "testfi/";
251 int err;
252 HANDLE find;
253 BOOL ret;
255 filehandle = _lcreat( filename, 0 );
256 if (filehandle == HFILE_ERROR)
258 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
259 return;
262 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
264 ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
266 ok( _hread( filehandle, buffer, strlen( sillytext ) ) == lstrlenA( sillytext ), "erratic _hread return value\n" );
268 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
270 find = FindFirstFileA( filename, &search_results );
271 ok( INVALID_HANDLE_VALUE != find, "should be able to find file\n" );
272 FindClose( find );
274 ret = DeleteFileA(filename);
275 ok( ret != 0, "DeleteFile failed (%d)\n", GetLastError());
277 filehandle = _lcreat( filename, 1 ); /* readonly */
278 ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%d)\n", filename, GetLastError( ) );
280 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite shouldn't be able to write never the less\n" );
282 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
284 find = FindFirstFileA( filename, &search_results );
285 ok( INVALID_HANDLE_VALUE != find, "should be able to find file\n" );
286 FindClose( find );
288 ok( 0 == DeleteFileA( filename ), "shouldn't be able to delete a readonly file\n" );
290 ok( SetFileAttributesA(filename, FILE_ATTRIBUTE_NORMAL ) != 0, "couldn't change attributes on file\n" );
292 ok( DeleteFileA( filename ) != 0, "now it should be possible to delete the file!\n" );
294 filehandle = _lcreat( filename, 2 );
295 ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%d)\n", filename, GetLastError( ) );
297 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
299 ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
301 ok( _hread( filehandle, buffer, strlen( sillytext ) ) == lstrlenA( sillytext ), "erratic _hread return value\n" );
303 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
305 find = FindFirstFileA( filename, &search_results );
306 ok( INVALID_HANDLE_VALUE != find, "should STILL be able to find file\n" );
307 FindClose( find );
309 ret = DeleteFileA( filename );
310 ok( ret, "DeleteFile failed (%d)\n", GetLastError( ) );
312 filehandle = _lcreat( filename, 4 ); /* SYSTEM file */
313 ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%d)\n", filename, GetLastError( ) );
315 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
317 ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
319 ok( _hread( filehandle, buffer, strlen( sillytext ) ) == lstrlenA( sillytext ), "erratic _hread return value\n" );
321 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
323 find = FindFirstFileA( filename, &search_results );
324 ok( INVALID_HANDLE_VALUE != find, "should STILL be able to find file\n" );
325 FindClose( find );
327 ret = DeleteFileA( filename );
328 ok( ret, "DeleteFile failed (%d)\n", GetLastError( ) );
330 filehandle=_lcreat (slashname, 0); /* illegal name */
331 if (HFILE_ERROR==filehandle) {
332 err=GetLastError ();
333 ok (err==ERROR_INVALID_NAME || err==ERROR_PATH_NOT_FOUND,
334 "creating file \"%s\" failed with error %d\n", slashname, err);
335 } else { /* only NT succeeds */
336 _lclose(filehandle);
337 find=FindFirstFileA (slashname, &search_results);
338 if (INVALID_HANDLE_VALUE!=find)
340 ret = FindClose (find);
341 ok (0 != ret, "FindClose complains (%d)\n", GetLastError ());
342 slashname[strlen(slashname)-1]=0;
343 ok (!strcmp (slashname, search_results.cFileName),
344 "found unexpected name \"%s\"\n", search_results.cFileName);
345 ok (FILE_ATTRIBUTE_ARCHIVE==search_results.dwFileAttributes,
346 "attributes of file \"%s\" are 0x%04x\n", search_results.cFileName,
347 search_results.dwFileAttributes);
349 ret = DeleteFileA( slashname );
350 ok( ret, "DeleteFile failed (%d)\n", GetLastError( ) );
353 filehandle=_lcreat (filename, 8); /* illegal attribute */
354 if (HFILE_ERROR==filehandle)
355 ok (0, "couldn't create volume label \"%s\"\n", filename);
356 else {
357 _lclose(filehandle);
358 find=FindFirstFileA (filename, &search_results);
359 if (INVALID_HANDLE_VALUE==find)
360 ok (0, "file \"%s\" not found\n", filename);
361 else {
362 ret = FindClose(find);
363 ok ( 0 != ret, "FindClose complains (%d)\n", GetLastError ());
364 ok (!strcmp (filename, search_results.cFileName),
365 "found unexpected name \"%s\"\n", search_results.cFileName);
366 search_results.dwFileAttributes &= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
367 ok (FILE_ATTRIBUTE_ARCHIVE==search_results.dwFileAttributes,
368 "attributes of file \"%s\" are 0x%04x\n", search_results.cFileName,
369 search_results.dwFileAttributes);
371 ret = DeleteFileA( filename );
372 ok( ret, "DeleteFile failed (%d)\n", GetLastError( ) );
377 static void test__llseek( void )
379 INT i;
380 HFILE filehandle;
381 char buffer[1];
382 LONG bytes_read;
383 BOOL ret;
385 filehandle = _lcreat( filename, 0 );
386 if (filehandle == HFILE_ERROR)
388 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
389 return;
392 for (i = 0; i < 400; i++)
394 ok( _hwrite( filehandle, sillytext, strlen( sillytext ) ) != -1, "_hwrite complains\n" );
396 ok( _llseek( filehandle, 400 * strlen( sillytext ), FILE_CURRENT ) != -1, "should be able to seek\n" );
397 ok( _llseek( filehandle, 27 + 35 * strlen( sillytext ), FILE_BEGIN ) != -1, "should be able to seek\n" );
399 bytes_read = _hread( filehandle, buffer, 1);
400 ok( 1 == bytes_read, "file read size error\n" );
401 ok( buffer[0] == sillytext[27], "_llseek error, it got lost seeking\n" );
402 ok( _llseek( filehandle, -400 * (LONG)strlen( sillytext ), FILE_END ) != -1, "should be able to seek\n" );
404 bytes_read = _hread( filehandle, buffer, 1);
405 ok( 1 == bytes_read, "file read size error\n" );
406 ok( buffer[0] == sillytext[0], "_llseek error, it got lost seeking\n" );
407 ok( _llseek( filehandle, 1000000, FILE_END ) != -1, "should be able to seek past file; poor, poor Windows programmers\n" );
408 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
410 ret = DeleteFileA( filename );
411 ok( ret, "DeleteFile failed (%d)\n", GetLastError( ) );
415 static void test__llopen( void )
417 HFILE filehandle;
418 UINT bytes_read;
419 char buffer[10000];
420 BOOL ret;
422 filehandle = _lcreat( filename, 0 );
423 if (filehandle == HFILE_ERROR)
425 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
426 return;
429 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
430 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
432 filehandle = _lopen( filename, OF_READ );
433 ok( HFILE_ERROR == _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite shouldn't be able to write!\n" );
434 bytes_read = _hread( filehandle, buffer, strlen( sillytext ) );
435 ok( strlen( sillytext ) == bytes_read, "file read size error\n" );
436 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
438 filehandle = _lopen( filename, OF_READWRITE );
439 bytes_read = _hread( filehandle, buffer, 2 * strlen( sillytext ) );
440 ok( strlen( sillytext ) == bytes_read, "file read size error\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" );
444 filehandle = _lopen( filename, OF_WRITE );
445 ok( HFILE_ERROR == _hread( filehandle, buffer, 1 ), "you should only be able to write this file\n" );
446 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite should write just fine\n" );
447 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
449 ret = DeleteFileA( filename );
450 ok( ret, "DeleteFile failed (%d)\n", GetLastError( ) );
451 /* TODO - add tests for the SHARE modes - use two processes to pull this one off */
455 static void test__lread( void )
457 HFILE filehandle;
458 char buffer[10000];
459 UINT bytes_read;
460 UINT bytes_wanted;
461 UINT i;
462 BOOL ret;
464 filehandle = _lcreat( filename, 0 );
465 if (filehandle == HFILE_ERROR)
467 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
468 return;
471 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
473 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
475 filehandle = _lopen( filename, OF_READ );
477 ok( HFILE_ERROR != filehandle, "couldn't open file \"%s\" again (err=%d)\n", filename, GetLastError());
479 bytes_read = _lread( filehandle, buffer, 2 * strlen( sillytext ) );
481 ok( lstrlenA( sillytext ) == bytes_read, "file read size error\n" );
483 for (bytes_wanted = 0; bytes_wanted < strlen( sillytext ); bytes_wanted++)
485 ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
486 ok( _lread( filehandle, buffer, bytes_wanted ) == bytes_wanted, "erratic _hread return value\n" );
487 for (i = 0; i < bytes_wanted; i++)
489 ok( buffer[i] == sillytext[i], "that's not what's written\n" );
493 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
495 ret = DeleteFileA( filename );
496 ok( ret, "DeleteFile failed (%d)\n", GetLastError( ) );
500 static void test__lwrite( void )
502 HFILE filehandle;
503 char buffer[10000];
504 UINT bytes_read;
505 UINT bytes_written;
506 UINT blocks;
507 INT i;
508 char *contents;
509 HLOCAL memory_object;
510 char checksum[1];
511 BOOL ret;
513 filehandle = _lcreat( filename, 0 );
514 if (filehandle == HFILE_ERROR)
516 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
517 return;
520 ok( HFILE_ERROR != _lwrite( filehandle, "", 0 ), "_hwrite complains\n" );
522 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
524 filehandle = _lopen( filename, OF_READ );
526 bytes_read = _hread( filehandle, buffer, 1);
528 ok( 0 == bytes_read, "file read size error\n" );
530 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
532 filehandle = _lopen( filename, OF_READWRITE );
534 bytes_written = 0;
535 checksum[0] = '\0';
536 srand( (unsigned)time( NULL ) );
537 for (blocks = 0; blocks < 100; blocks++)
539 for (i = 0; i < (INT)sizeof( buffer ); i++)
541 buffer[i] = rand( );
542 checksum[0] = checksum[0] + buffer[i];
544 ok( HFILE_ERROR != _lwrite( filehandle, buffer, sizeof( buffer ) ), "_hwrite complains\n" );
545 bytes_written = bytes_written + sizeof( buffer );
548 ok( HFILE_ERROR != _lwrite( filehandle, checksum, 1 ), "_hwrite complains\n" );
549 bytes_written++;
551 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
553 memory_object = LocalAlloc( LPTR, bytes_written );
555 ok( 0 != memory_object, "LocalAlloc fails, could be out of memory\n" );
557 contents = LocalLock( memory_object );
558 ok( NULL != contents, "LocalLock whines\n" );
560 filehandle = _lopen( filename, OF_READ );
562 contents = LocalLock( memory_object );
563 ok( NULL != contents, "LocalLock whines\n" );
565 ok( bytes_written == _hread( filehandle, contents, bytes_written), "read length differ from write length\n" );
567 checksum[0] = '\0';
568 i = 0;
571 checksum[0] += contents[i];
572 i++;
574 while (i < bytes_written - 1);
576 ok( checksum[0] == contents[i], "stored checksum differ from computed checksum\n" );
578 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
580 ret = DeleteFileA( filename );
581 ok( ret, "DeleteFile failed (%d)\n", GetLastError( ) );
583 LocalFree( contents );
586 static void test_CopyFileA(void)
588 char temp_path[MAX_PATH];
589 char source[MAX_PATH], dest[MAX_PATH];
590 static const char prefix[] = "pfx";
591 HANDLE hfile;
592 HANDLE hmapfile;
593 FILETIME ft1, ft2;
594 char buf[10];
595 DWORD ret;
596 BOOL retok;
598 ret = GetTempPathA(MAX_PATH, temp_path);
599 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
600 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
602 ret = GetTempFileNameA(temp_path, prefix, 0, source);
603 ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
605 ret = MoveFileA(source, source);
606 todo_wine ok(ret, "MoveFileA: failed, error %d\n", GetLastError());
608 /* copying a file to itself must fail */
609 retok = CopyFileA(source, source, FALSE);
610 ok( !retok && (GetLastError() == ERROR_SHARING_VIOLATION || broken(GetLastError() == ERROR_FILE_EXISTS) /* Win 9x */),
611 "copying a file to itself didn't fail (ret=%d, err=%d)\n", retok, GetLastError());
613 /* make the source have not zero size */
614 hfile = CreateFileA(source, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
615 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
616 retok = WriteFile(hfile, prefix, sizeof(prefix), &ret, NULL );
617 ok( retok && ret == sizeof(prefix),
618 "WriteFile error %d\n", GetLastError());
619 ok(GetFileSize(hfile, NULL) == sizeof(prefix), "source file has wrong size\n");
620 /* get the file time and change it to prove the difference */
621 ret = GetFileTime(hfile, NULL, NULL, &ft1);
622 ok( ret, "GetFileTime error %d\n", GetLastError());
623 ft1.dwLowDateTime -= 600000000; /* 60 second */
624 ret = SetFileTime(hfile, NULL, NULL, &ft1);
625 ok( ret, "SetFileTime error %d\n", GetLastError());
626 GetFileTime(hfile, NULL, NULL, &ft1); /* get the actual time back */
627 CloseHandle(hfile);
629 ret = GetTempFileNameA(temp_path, prefix, 0, dest);
630 ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
632 SetLastError(0xdeadbeef);
633 ret = CopyFileA(source, dest, TRUE);
634 ok(!ret && GetLastError() == ERROR_FILE_EXISTS,
635 "CopyFileA: unexpected error %d\n", GetLastError());
637 ret = CopyFileA(source, dest, FALSE);
638 ok(ret, "CopyFileA: error %d\n", GetLastError());
640 /* copying from a read-locked source fails */
641 hfile = CreateFileA(source, GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
642 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %d\n", GetLastError());
643 retok = CopyFileA(source, dest, FALSE);
644 ok(!retok && GetLastError() == ERROR_SHARING_VIOLATION,
645 "copying from a read-locked file succeeded when it shouldn't have\n");
646 /* in addition, the source is opened before the destination */
647 retok = CopyFileA("25f99d3b-4ba4-4f66-88f5-2906886993cc", dest, FALSE);
648 ok(!retok && GetLastError() == ERROR_FILE_NOT_FOUND,
649 "copying from a file that doesn't exist failed in an unexpected way (ret=%d, err=%d)\n", retok, GetLastError());
650 CloseHandle(hfile);
652 /* copying from a r+w opened, r shared source succeeds */
653 hfile = CreateFileA(source, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
654 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %d\n", GetLastError());
655 retok = CopyFileA(source, dest, FALSE);
656 ok(retok,
657 "copying from an r+w opened and r shared file failed (ret=%d, err=%d)\n", retok, GetLastError());
658 CloseHandle(hfile);
660 /* copying from a delete-locked source mostly succeeds */
661 hfile = CreateFileA(source, DELETE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
662 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %d\n", GetLastError());
663 retok = CopyFileA(source, dest, FALSE);
664 ok(retok || broken(!retok && GetLastError() == ERROR_SHARING_VIOLATION) /* NT, 2000, XP */,
665 "copying from a delete-locked file failed (ret=%d, err=%d)\n", retok, GetLastError());
666 CloseHandle(hfile);
668 /* copying to a write-locked destination fails */
669 hfile = CreateFileA(dest, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
670 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError());
671 retok = CopyFileA(source, dest, FALSE);
672 ok(!retok && GetLastError() == ERROR_SHARING_VIOLATION,
673 "copying to a write-locked file didn't fail (ret=%d, err=%d)\n", retok, GetLastError());
674 CloseHandle(hfile);
676 /* copying to a r+w opened, w shared destination mostly succeeds */
677 hfile = CreateFileA(dest, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
678 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError());
679 retok = CopyFileA(source, dest, FALSE);
680 ok(retok || broken(!retok && GetLastError() == ERROR_SHARING_VIOLATION) /* Win 9x */,
681 "copying to a r+w opened and w shared file failed (ret=%d, err=%d)\n", retok, GetLastError());
682 CloseHandle(hfile);
684 /* copying to a delete-locked destination fails, even when the destination is delete-shared */
685 hfile = CreateFileA(dest, DELETE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0);
686 ok(hfile != INVALID_HANDLE_VALUE || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Win 9x */,
687 "failed to open destination file, error %d\n", GetLastError());
688 if (hfile != INVALID_HANDLE_VALUE)
690 retok = CopyFileA(source, dest, FALSE);
691 ok(!retok && GetLastError() == ERROR_SHARING_VIOLATION,
692 "copying to a delete-locked shared file didn't fail (ret=%d, err=%d)\n", retok, GetLastError());
693 CloseHandle(hfile);
696 /* copy to a file that's opened the way Wine opens the source */
697 hfile = CreateFileA(dest, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
698 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError());
699 retok = CopyFileA(source, dest, FALSE);
700 ok(retok || broken(GetLastError() == ERROR_SHARING_VIOLATION) /* Win 9x */,
701 "copying to a file opened the way Wine opens the source failed (ret=%d, err=%d)\n", retok, GetLastError());
702 CloseHandle(hfile);
704 /* make sure that destination has correct size */
705 hfile = CreateFileA(dest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
706 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n");
707 ret = GetFileSize(hfile, NULL);
708 ok(ret == sizeof(prefix), "destination file has wrong size %d\n", ret);
710 /* make sure that destination has the same filetime */
711 ret = GetFileTime(hfile, NULL, NULL, &ft2);
712 ok( ret, "GetFileTime error %d\n", GetLastError());
713 ok(CompareFileTime(&ft1, &ft2) == 0, "destination file has wrong filetime\n");
715 SetLastError(0xdeadbeef);
716 ret = CopyFileA(source, dest, FALSE);
717 ok(!ret && GetLastError() == ERROR_SHARING_VIOLATION,
718 "CopyFileA: ret = %d, unexpected error %d\n", ret, GetLastError());
720 /* make sure that destination still has correct size */
721 ret = GetFileSize(hfile, NULL);
722 ok(ret == sizeof(prefix), "destination file has wrong size %d\n", ret);
723 retok = ReadFile(hfile, buf, sizeof(buf), &ret, NULL);
724 ok( retok && ret == sizeof(prefix),
725 "ReadFile: error %d\n", GetLastError());
726 ok(!memcmp(prefix, buf, sizeof(prefix)), "buffer contents mismatch\n");
728 /* check error on copying over a mapped file that was opened with FILE_SHARE_READ */
729 hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
730 ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError());
732 ret = CopyFileA(source, dest, FALSE);
733 ok(!ret && GetLastError() == ERROR_SHARING_VIOLATION,
734 "CopyFileA with mapped dest file: expected ERROR_SHARING_VIOLATION, got %d\n", GetLastError());
736 CloseHandle(hmapfile);
737 CloseHandle(hfile);
739 hfile = CreateFileA(dest, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
740 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n");
742 /* check error on copying over a mapped file that was opened with FILE_SHARE_WRITE */
743 hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
744 ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError());
746 ret = CopyFileA(source, dest, FALSE);
747 ok(!ret, "CopyFileA: expected failure\n");
748 ok(GetLastError() == ERROR_USER_MAPPED_FILE ||
749 broken(GetLastError() == ERROR_SHARING_VIOLATION), /* Win9x */
750 "CopyFileA with mapped dest file: expected ERROR_USER_MAPPED_FILE, got %d\n", GetLastError());
752 CloseHandle(hmapfile);
753 CloseHandle(hfile);
755 ret = DeleteFileA(source);
756 ok(ret, "DeleteFileA: error %d\n", GetLastError());
757 ret = DeleteFileA(dest);
758 ok(ret, "DeleteFileA: error %d\n", GetLastError());
761 static void test_CopyFileW(void)
763 WCHAR temp_path[MAX_PATH];
764 WCHAR source[MAX_PATH], dest[MAX_PATH];
765 static const WCHAR prefix[] = {'p','f','x',0};
766 DWORD ret;
768 ret = GetTempPathW(MAX_PATH, temp_path);
769 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
771 win_skip("GetTempPathW is not available\n");
772 return;
774 ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
775 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
777 ret = GetTempFileNameW(temp_path, prefix, 0, source);
778 ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
780 ret = GetTempFileNameW(temp_path, prefix, 0, dest);
781 ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
783 ret = CopyFileW(source, dest, TRUE);
784 ok(!ret && GetLastError() == ERROR_FILE_EXISTS,
785 "CopyFileW: unexpected error %d\n", GetLastError());
787 ret = CopyFileW(source, dest, FALSE);
788 ok(ret, "CopyFileW: error %d\n", GetLastError());
790 ret = DeleteFileW(source);
791 ok(ret, "DeleteFileW: error %d\n", GetLastError());
792 ret = DeleteFileW(dest);
793 ok(ret, "DeleteFileW: error %d\n", GetLastError());
796 static void test_CopyFile2(void)
798 static const WCHAR doesntexistW[] = {'d','o','e','s','n','t','e','x','i','s','t',0};
799 static const WCHAR prefix[] = {'p','f','x',0};
800 WCHAR source[MAX_PATH], dest[MAX_PATH], temp_path[MAX_PATH];
801 COPYFILE2_EXTENDED_PARAMETERS params;
802 HANDLE hfile, hmapfile;
803 FILETIME ft1, ft2;
804 DWORD ret, len;
805 char buf[10];
806 HRESULT hr;
808 if (!pCopyFile2)
810 skip("CopyFile2 is not available\n");
811 return;
814 ret = GetTempPathW(MAX_PATH, temp_path);
815 ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
816 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
818 ret = GetTempFileNameW(temp_path, prefix, 0, source);
819 ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
821 ret = GetTempFileNameW(temp_path, prefix, 0, dest);
822 ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
824 /* fail if exists */
825 memset(&params, 0, sizeof(params));
826 params.dwSize = sizeof(params);
827 params.dwCopyFlags = COPY_FILE_FAIL_IF_EXISTS;
829 SetLastError(0xdeadbeef);
830 hr = pCopyFile2(source, dest, &params);
831 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "CopyFile2: unexpected error 0x%08x\n", hr);
832 ok(GetLastError() == ERROR_FILE_EXISTS, "CopyFile2: last error %d\n", GetLastError());
834 /* don't fail if exists */
835 params.dwSize = sizeof(params);
836 params.dwCopyFlags = 0;
838 hr = pCopyFile2(source, dest, &params);
839 ok(hr == S_OK, "CopyFile2: error 0x%08x\n", hr);
841 /* copying a file to itself must fail */
842 params.dwSize = sizeof(params);
843 params.dwCopyFlags = 0;
845 SetLastError(0xdeadbeef);
846 hr = pCopyFile2(source, source, &params);
847 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: copying a file to itself didn't fail, 0x%08x\n", hr);
848 ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %d\n", GetLastError());
850 /* make the source have not zero size */
851 hfile = CreateFileW(source, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
852 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
853 ret = WriteFile(hfile, prefix, sizeof(prefix), &len, NULL );
854 ok(ret && len == sizeof(prefix), "WriteFile error %d\n", GetLastError());
855 ok(GetFileSize(hfile, NULL) == sizeof(prefix), "source file has wrong size\n");
857 /* get the file time and change it to prove the difference */
858 ret = GetFileTime(hfile, NULL, NULL, &ft1);
859 ok(ret, "GetFileTime error %d\n", GetLastError());
860 ft1.dwLowDateTime -= 600000000; /* 60 second */
861 ret = SetFileTime(hfile, NULL, NULL, &ft1);
862 ok(ret, "SetFileTime error %d\n", GetLastError());
863 GetFileTime(hfile, NULL, NULL, &ft1); /* get the actual time back */
864 CloseHandle(hfile);
866 ret = GetTempFileNameW(temp_path, prefix, 0, dest);
867 ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
869 params.dwSize = sizeof(params);
870 params.dwCopyFlags = COPY_FILE_FAIL_IF_EXISTS;
872 SetLastError(0xdeadbeef);
873 hr = pCopyFile2(source, dest, &params);
874 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "CopyFile2: unexpected error 0x%08x\n", hr);
875 ok(GetLastError() == ERROR_FILE_EXISTS, "CopyFile2: last error %d\n", GetLastError());
877 params.dwSize = sizeof(params);
878 params.dwCopyFlags = 0;
879 hr = pCopyFile2(source, dest, &params);
880 ok(ret, "CopyFile2: error 0x%08x\n", hr);
882 /* copying from a read-locked source fails */
883 hfile = CreateFileW(source, GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
884 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %d\n", GetLastError());
886 params.dwSize = sizeof(params);
887 params.dwCopyFlags = 0;
888 SetLastError(0xdeadbeef);
889 hr = pCopyFile2(source, dest, &params);
890 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08x\n", hr);
891 ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %d\n", GetLastError());
893 /* in addition, the source is opened before the destination */
894 params.dwSize = sizeof(params);
895 params.dwCopyFlags = 0;
896 SetLastError(0xdeadbeef);
897 hr = pCopyFile2(doesntexistW, dest, &params);
898 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
899 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "CopyFile2: last error %d\n", GetLastError());
900 CloseHandle(hfile);
902 /* copying from a r+w opened, r shared source succeeds */
903 hfile = CreateFileW(source, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
904 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %d\n", GetLastError());
906 params.dwSize = sizeof(params);
907 params.dwCopyFlags = 0;
908 hr = pCopyFile2(source, dest, &params);
909 ok(hr == S_OK, "failed 0x%08x\n", hr);
910 CloseHandle(hfile);
912 /* copying from a delete-locked source mostly succeeds */
913 hfile = CreateFileW(source, DELETE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
914 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %d\n", GetLastError());
916 params.dwSize = sizeof(params);
917 params.dwCopyFlags = 0;
918 hr = pCopyFile2(source, dest, &params);
919 ok(hr == S_OK, "failed 0x%08x\n", hr);
920 CloseHandle(hfile);
922 /* copying to a write-locked destination fails */
923 hfile = CreateFileW(dest, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
924 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError());
926 params.dwSize = sizeof(params);
927 params.dwCopyFlags = 0;
928 SetLastError(0xdeadbeef);
929 hr = pCopyFile2(source, dest, FALSE);
930 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08x\n", hr);
931 ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %d\n", GetLastError());
932 CloseHandle(hfile);
934 /* copying to a r+w opened, w shared destination mostly succeeds */
935 hfile = CreateFileW(dest, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
936 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError());
938 params.dwSize = sizeof(params);
939 params.dwCopyFlags = 0;
940 hr = pCopyFile2(source, dest, FALSE);
941 ok(hr == S_OK, "got 0x%08x\n", hr);
942 CloseHandle(hfile);
944 /* copying to a delete-locked destination fails, even when the destination is delete-shared */
945 hfile = CreateFileW(dest, DELETE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0);
946 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError());
948 params.dwSize = sizeof(params);
949 params.dwCopyFlags = 0;
950 SetLastError(0xdeadbeef);
951 hr = pCopyFile2(source, dest, &params);
952 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08x\n", hr);
953 ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %d\n", GetLastError());
954 CloseHandle(hfile);
956 /* copy to a file that's opened the way Wine opens the source */
957 hfile = CreateFileW(dest, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
958 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError());
960 params.dwSize = sizeof(params);
961 params.dwCopyFlags = 0;
962 hr = pCopyFile2(source, dest, &params);
963 ok(hr == S_OK, "got 0x%08x\n", hr);
964 CloseHandle(hfile);
966 /* make sure that destination has correct size */
967 hfile = CreateFileW(dest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
968 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n");
969 ret = GetFileSize(hfile, NULL);
970 ok(ret == sizeof(prefix), "destination file has wrong size %d\n", ret);
972 /* make sure that destination has the same filetime */
973 ret = GetFileTime(hfile, NULL, NULL, &ft2);
974 ok(ret, "GetFileTime error %d\n", GetLastError());
975 ok(CompareFileTime(&ft1, &ft2) == 0, "destination file has wrong filetime\n");
977 params.dwSize = sizeof(params);
978 params.dwCopyFlags = 0;
979 SetLastError(0xdeadbeef);
980 hr = pCopyFile2(source, dest, &params);
981 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08x\n", hr);
982 ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %d\n", GetLastError());
984 /* make sure that destination still has correct size */
985 ret = GetFileSize(hfile, NULL);
986 ok(ret == sizeof(prefix), "destination file has wrong size %d\n", ret);
987 ret = ReadFile(hfile, buf, sizeof(buf), &len, NULL);
988 ok(ret && len == sizeof(prefix), "ReadFile: error %d\n", GetLastError());
989 ok(!memcmp(prefix, buf, sizeof(prefix)), "buffer contents mismatch\n");
991 /* check error on copying over a mapped file that was opened with FILE_SHARE_READ */
992 hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
993 ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError());
995 params.dwSize = sizeof(params);
996 params.dwCopyFlags = 0;
997 SetLastError(0xdeadbeef);
998 hr = pCopyFile2(source, dest, &params);
999 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08x\n", hr);
1000 ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %d\n", GetLastError());
1002 CloseHandle(hmapfile);
1003 CloseHandle(hfile);
1005 hfile = CreateFileW(dest, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
1006 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n");
1008 /* check error on copying over a mapped file that was opened with FILE_SHARE_WRITE */
1009 hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
1010 ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError());
1012 params.dwSize = sizeof(params);
1013 params.dwCopyFlags = 0;
1014 hr = pCopyFile2(source, dest, &params);
1015 ok(hr == HRESULT_FROM_WIN32(ERROR_USER_MAPPED_FILE), "CopyFile2: unexpected error 0x%08x\n", hr);
1016 ok(GetLastError() == ERROR_USER_MAPPED_FILE, "CopyFile2: last error %d\n", GetLastError());
1018 CloseHandle(hmapfile);
1019 CloseHandle(hfile);
1021 DeleteFileW(source);
1022 DeleteFileW(dest);
1026 * Debugging routine to dump a buffer in a hexdump-like fashion.
1028 static void dumpmem(unsigned char *mem, int len)
1030 int x = 0;
1031 char hex[49], *p;
1032 char txt[17], *c;
1034 while (x < len)
1036 p = hex;
1037 c = txt;
1038 do {
1039 p += sprintf(p, "%02x ", mem[x]);
1040 *c++ = (mem[x] >= 32 && mem[x] <= 127) ? mem[x] : '.';
1041 } while (++x % 16 && x < len);
1042 *c = '\0';
1043 trace("%04x: %-48s- %s\n", x, hex, txt);
1047 static void test_CreateFileA(void)
1049 HANDLE hFile;
1050 char temp_path[MAX_PATH], dirname[MAX_PATH];
1051 char filename[MAX_PATH];
1052 static const char prefix[] = "pfx";
1053 char windowsdir[MAX_PATH];
1054 char Volume_1[MAX_PATH];
1055 unsigned char buffer[512];
1056 char directory[] = "removeme";
1057 static const char nt_drive[] = "\\\\?\\A:";
1058 DWORD i, ret, len;
1059 struct test_list p[] = {
1060 {"", ERROR_PATH_NOT_FOUND, -1, FILE_ATTRIBUTE_NORMAL, TRUE }, /* dir as file w \ */
1061 {"", ERROR_SUCCESS, ERROR_PATH_NOT_FOUND, FILE_FLAG_BACKUP_SEMANTICS, FALSE }, /* dir as dir w \ */
1062 {"a", ERROR_FILE_NOT_FOUND, -1, FILE_ATTRIBUTE_NORMAL, FALSE }, /* non-exist file */
1063 {"a\\", ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND, FILE_ATTRIBUTE_NORMAL, FALSE }, /* non-exist dir */
1064 {"removeme", ERROR_ACCESS_DENIED, -1, FILE_ATTRIBUTE_NORMAL, FALSE }, /* exist dir w/o \ */
1065 {"removeme\\", ERROR_PATH_NOT_FOUND, -1, FILE_ATTRIBUTE_NORMAL, TRUE }, /* exst dir w \ */
1066 {"c:", ERROR_ACCESS_DENIED, ERROR_PATH_NOT_FOUND, FILE_ATTRIBUTE_NORMAL, FALSE }, /* device in file namespace */
1067 {"c:", ERROR_SUCCESS, ERROR_PATH_NOT_FOUND, FILE_FLAG_BACKUP_SEMANTICS, FALSE }, /* device in file namespace as dir */
1068 {"c:\\", ERROR_PATH_NOT_FOUND, ERROR_ACCESS_DENIED, FILE_ATTRIBUTE_NORMAL, TRUE }, /* root dir w \ */
1069 {"c:\\", ERROR_SUCCESS, ERROR_ACCESS_DENIED, FILE_FLAG_BACKUP_SEMANTICS, FALSE }, /* root dir w \ as dir */
1070 {"\\\\?\\c:", ERROR_SUCCESS, ERROR_BAD_NETPATH, FILE_ATTRIBUTE_NORMAL,FALSE }, /* dev namespace drive */
1071 {"\\\\?\\c:\\", ERROR_PATH_NOT_FOUND, ERROR_BAD_NETPATH, FILE_ATTRIBUTE_NORMAL, TRUE }, /* dev namespace drive w \ */
1072 {NULL, 0, -1, 0, FALSE}
1074 BY_HANDLE_FILE_INFORMATION Finfo;
1076 ret = GetTempPathA(MAX_PATH, temp_path);
1077 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
1078 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
1080 ret = GetTempFileNameA(temp_path, prefix, 0, filename);
1081 ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
1083 SetLastError(0xdeadbeef);
1084 hFile = CreateFileA(filename, GENERIC_READ, 0, NULL,
1085 CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
1086 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS,
1087 "CREATE_NEW should fail if file exists and last error value should be ERROR_FILE_EXISTS\n");
1089 SetLastError(0xdeadbeef);
1090 hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
1091 CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
1092 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
1093 "hFile %p, last error %u\n", hFile, GetLastError());
1095 CloseHandle(hFile);
1097 SetLastError(0xdeadbeef);
1098 hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
1099 OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
1100 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
1101 "hFile %p, last error %u\n", hFile, GetLastError());
1103 CloseHandle(hFile);
1105 ret = DeleteFileA(filename);
1106 ok(ret, "DeleteFileA: error %d\n", GetLastError());
1108 SetLastError(0xdeadbeef);
1109 hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
1110 OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
1111 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == 0,
1112 "hFile %p, last error %u\n", hFile, GetLastError());
1114 CloseHandle(hFile);
1116 ret = DeleteFileA(filename);
1117 ok(ret, "DeleteFileA: error %d\n", GetLastError());
1119 SetLastError(0xdeadbeef);
1120 hFile = CreateFileA("c:\\*.*", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1121 ok(hFile == INVALID_HANDLE_VALUE, "hFile should have been INVALID_HANDLE_VALUE\n");
1122 ok(GetLastError() == ERROR_INVALID_NAME ||
1123 broken(GetLastError() == ERROR_FILE_NOT_FOUND), /* Win98 */
1124 "LastError should have been ERROR_INVALID_NAME or ERROR_FILE_NOT_FOUND but got %u\n", GetLastError());
1126 /* get windows drive letter */
1127 ret = GetWindowsDirectoryA(windowsdir, sizeof(windowsdir));
1128 ok(ret < sizeof(windowsdir), "windowsdir is abnormally long!\n");
1129 ok(ret != 0, "GetWindowsDirectory: error %d\n", GetLastError());
1131 /* test error return codes from CreateFile for some cases */
1132 ret = GetTempPathA(MAX_PATH, temp_path);
1133 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
1134 strcpy(dirname, temp_path);
1135 strcat(dirname, directory);
1136 ret = CreateDirectoryA(dirname, NULL);
1137 ok( ret, "Createdirectory failed, gle=%d\n", GetLastError() );
1138 /* set current drive & directory to known location */
1139 SetCurrentDirectoryA( temp_path );
1140 i = 0;
1141 while (p[i].file)
1143 filename[0] = 0;
1144 /* update the drive id in the table entry with the current one */
1145 if (p[i].file[1] == ':')
1147 strcpy(filename, p[i].file);
1148 filename[0] = windowsdir[0];
1150 else if (p[i].file[0] == '\\' && p[i].file[5] == ':')
1152 strcpy(filename, p[i].file);
1153 filename[4] = windowsdir[0];
1155 else
1157 /* prefix the table entry with the current temp directory */
1158 strcpy(filename, temp_path);
1159 strcat(filename, p[i].file);
1161 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1162 FILE_SHARE_READ | FILE_SHARE_WRITE,
1163 NULL, OPEN_EXISTING,
1164 p[i].options, NULL );
1165 /* if we get ACCESS_DENIED when we do not expect it, assume
1166 * no access to the volume
1168 if (hFile == INVALID_HANDLE_VALUE &&
1169 GetLastError() == ERROR_ACCESS_DENIED &&
1170 p[i].err != ERROR_ACCESS_DENIED)
1172 if (p[i].todo_flag)
1173 skip("Either no authority to volume, or is todo_wine for %s err=%d should be %d\n", filename, GetLastError(), p[i].err);
1174 else
1175 skip("Do not have authority to access volumes. Test for %s skipped\n", filename);
1177 /* otherwise validate results with expectations */
1178 else if (p[i].todo_flag)
1179 todo_wine ok(
1180 (hFile == INVALID_HANDLE_VALUE &&
1181 (p[i].err == GetLastError() || p[i].err2 == GetLastError())) ||
1182 (hFile != INVALID_HANDLE_VALUE && p[i].err == ERROR_SUCCESS),
1183 "CreateFileA failed on %s, hFile %p, err=%u, should be %u\n",
1184 filename, hFile, GetLastError(), p[i].err);
1185 else
1187 (hFile == INVALID_HANDLE_VALUE &&
1188 (p[i].err == GetLastError() || p[i].err2 == GetLastError())) ||
1189 (hFile != INVALID_HANDLE_VALUE && p[i].err == ERROR_SUCCESS),
1190 "CreateFileA failed on %s, hFile %p, err=%u, should be %u\n",
1191 filename, hFile, GetLastError(), p[i].err);
1192 if (hFile != INVALID_HANDLE_VALUE)
1193 CloseHandle( hFile );
1194 i++;
1196 ret = RemoveDirectoryA(dirname);
1197 ok(ret, "RemoveDirectoryA: error %d\n", GetLastError());
1200 /* test opening directory as a directory */
1201 hFile = CreateFileA( temp_path, GENERIC_READ,
1202 FILE_SHARE_READ,
1203 NULL,
1204 OPEN_EXISTING,
1205 FILE_FLAG_BACKUP_SEMANTICS, NULL );
1206 if (hFile != INVALID_HANDLE_VALUE && GetLastError() != ERROR_PATH_NOT_FOUND)
1208 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_SUCCESS,
1209 "CreateFileA did not work, last error %u on volume <%s>\n",
1210 GetLastError(), temp_path );
1212 if (hFile != INVALID_HANDLE_VALUE)
1214 ret = GetFileInformationByHandle( hFile, &Finfo );
1215 if (ret)
1217 ok(Finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY,
1218 "CreateFileA probably did not open temp directory %s correctly\n file information does not include FILE_ATTRIBUTE_DIRECTORY, actual=0x%08x\n",
1219 temp_path, Finfo.dwFileAttributes);
1221 CloseHandle( hFile );
1224 else
1225 skip("Probable Win9x, got ERROR_PATH_NOT_FOUND w/ FILE_FLAG_BACKUP_SEMANTICS or %s\n", temp_path);
1228 /* *** Test opening volumes/devices using drive letter *** */
1230 /* test using drive letter in non-rewrite format without trailing \ */
1231 /* this should work */
1232 strcpy(filename, nt_drive);
1233 filename[4] = windowsdir[0];
1234 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1235 FILE_SHARE_READ | FILE_SHARE_WRITE,
1236 NULL, OPEN_EXISTING,
1237 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
1238 if (hFile != INVALID_HANDLE_VALUE ||
1239 (GetLastError() != ERROR_ACCESS_DENIED && GetLastError() != ERROR_BAD_NETPATH))
1241 /* if we have adm rights to volume, then try rest of tests */
1242 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA did not open %s, last error=%u\n",
1243 filename, GetLastError());
1244 if (hFile != INVALID_HANDLE_VALUE)
1246 /* if we opened the volume/device, try to read it. Since it */
1247 /* opened, we should be able to read it. We don't care about*/
1248 /* what the data is at this time. */
1249 len = 512;
1250 ret = ReadFile( hFile, buffer, len, &len, NULL );
1251 todo_wine ok(ret, "Failed to read volume, last error %u, %u, for %s\n",
1252 GetLastError(), ret, filename);
1253 if (ret)
1255 trace("buffer is\n");
1256 dumpmem(buffer, 64);
1258 CloseHandle( hFile );
1261 /* test using drive letter with trailing \ and in non-rewrite */
1262 /* this should not work */
1263 strcpy(filename, nt_drive);
1264 filename[4] = windowsdir[0];
1265 strcat( filename, "\\" );
1266 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1267 FILE_SHARE_READ | FILE_SHARE_WRITE,
1268 NULL, OPEN_EXISTING,
1269 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
1270 todo_wine
1271 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
1272 "CreateFileA should have returned ERROR_PATH_NOT_FOUND on %s, but got %u\n",
1273 filename, GetLastError());
1274 if (hFile != INVALID_HANDLE_VALUE)
1275 CloseHandle( hFile );
1277 /* test using temp path with trailing \ and in non-rewrite as dir */
1278 /* this should work */
1279 strcpy(filename, nt_drive);
1280 filename[4] = 0;
1281 strcat( filename, temp_path );
1282 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1283 FILE_SHARE_READ | FILE_SHARE_WRITE,
1284 NULL, OPEN_EXISTING,
1285 FILE_FLAG_BACKUP_SEMANTICS, NULL );
1286 ok(hFile != INVALID_HANDLE_VALUE,
1287 "CreateFileA should have worked on %s, but got %u\n",
1288 filename, GetLastError());
1289 if (hFile != INVALID_HANDLE_VALUE)
1290 CloseHandle( hFile );
1292 /* test using drive letter without trailing \ and in device ns */
1293 /* this should work */
1294 strcpy(filename, nt_drive);
1295 filename[4] = windowsdir[0];
1296 filename[2] = '.';
1297 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1298 FILE_SHARE_READ | FILE_SHARE_WRITE,
1299 NULL, OPEN_EXISTING,
1300 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
1301 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA did not open %s, last error=%u\n",
1302 filename, GetLastError());
1303 if (hFile != INVALID_HANDLE_VALUE)
1304 CloseHandle( hFile );
1306 /* If we see ERROR_BAD_NETPATH then on Win9x or WinME, so skip */
1307 else if (GetLastError() == ERROR_BAD_NETPATH)
1308 skip("Probable Win9x, got ERROR_BAD_NETPATH (53)\n");
1309 else
1310 skip("Do not have authority to access volumes. Tests skipped\n");
1313 /* *** Test opening volumes/devices using GUID *** */
1315 if (pGetVolumeNameForVolumeMountPointA)
1317 strcpy(filename, "c:\\");
1318 filename[0] = windowsdir[0];
1319 ret = pGetVolumeNameForVolumeMountPointA( filename, Volume_1, MAX_PATH );
1320 ok(ret, "GetVolumeNameForVolumeMountPointA failed, for %s, last error=%d\n", filename, GetLastError());
1321 if (ret)
1323 ok(strlen(Volume_1) == 49, "GetVolumeNameForVolumeMountPointA returned wrong length name <%s>\n", Volume_1);
1325 /* test the result of opening a unique volume name (GUID)
1326 * with the trailing \
1327 * this should error out
1329 strcpy(filename, Volume_1);
1330 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1331 FILE_SHARE_READ | FILE_SHARE_WRITE,
1332 NULL, OPEN_EXISTING,
1333 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
1334 todo_wine
1335 ok(hFile == INVALID_HANDLE_VALUE,
1336 "CreateFileA should not have opened %s, hFile %p\n",
1337 filename, hFile);
1338 todo_wine
1339 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
1340 "CreateFileA should have returned ERROR_PATH_NOT_FOUND on %s, but got %u\n",
1341 filename, GetLastError());
1342 if (hFile != INVALID_HANDLE_VALUE)
1343 CloseHandle( hFile );
1345 /* test the result of opening a unique volume name (GUID)
1346 * with the temp path string as dir
1347 * this should work
1349 strcpy(filename, Volume_1);
1350 strcat(filename, temp_path+3);
1351 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1352 FILE_SHARE_READ | FILE_SHARE_WRITE,
1353 NULL, OPEN_EXISTING,
1354 FILE_FLAG_BACKUP_SEMANTICS, NULL );
1355 todo_wine
1356 ok(hFile != INVALID_HANDLE_VALUE,
1357 "CreateFileA should have opened %s, but got %u\n",
1358 filename, GetLastError());
1359 if (hFile != INVALID_HANDLE_VALUE)
1360 CloseHandle( hFile );
1362 /* test the result of opening a unique volume name (GUID)
1363 * without the trailing \ and in device namespace
1364 * this should work
1366 strcpy(filename, Volume_1);
1367 filename[2] = '.';
1368 filename[48] = 0;
1369 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1370 FILE_SHARE_READ | FILE_SHARE_WRITE,
1371 NULL, OPEN_EXISTING,
1372 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
1373 if (hFile != INVALID_HANDLE_VALUE || GetLastError() != ERROR_ACCESS_DENIED)
1375 /* if we have adm rights to volume, then try rest of tests */
1376 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA did not open %s, last error=%u\n",
1377 filename, GetLastError());
1378 if (hFile != INVALID_HANDLE_VALUE)
1380 /* if we opened the volume/device, try to read it. Since it */
1381 /* opened, we should be able to read it. We don't care about*/
1382 /* what the data is at this time. */
1383 len = 512;
1384 ret = ReadFile( hFile, buffer, len, &len, NULL );
1385 todo_wine ok(ret, "Failed to read volume, last error %u, %u, for %s\n",
1386 GetLastError(), ret, filename);
1387 if (ret)
1389 trace("buffer is\n");
1390 dumpmem(buffer, 64);
1392 CloseHandle( hFile );
1395 else
1396 skip("Do not have authority to access volumes. Tests skipped\n");
1398 else
1399 win_skip("GetVolumeNameForVolumeMountPointA not functioning\n");
1401 else
1402 win_skip("GetVolumeNameForVolumeMountPointA not found\n");
1405 static void test_CreateFileW(void)
1407 HANDLE hFile;
1408 WCHAR temp_path[MAX_PATH];
1409 WCHAR filename[MAX_PATH];
1410 static const WCHAR emptyW[]={'\0'};
1411 static const WCHAR prefix[] = {'p','f','x',0};
1412 static const WCHAR bogus[] = { '\\', '\\', '.', '\\', 'B', 'O', 'G', 'U', 'S', 0 };
1413 DWORD ret;
1415 ret = GetTempPathW(MAX_PATH, temp_path);
1416 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1418 win_skip("GetTempPathW is not available\n");
1419 return;
1421 ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
1422 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
1424 ret = GetTempFileNameW(temp_path, prefix, 0, filename);
1425 ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
1427 SetLastError(0xdeadbeef);
1428 hFile = CreateFileW(filename, GENERIC_READ, 0, NULL,
1429 CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
1430 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS,
1431 "CREATE_NEW should fail if file exists and last error value should be ERROR_FILE_EXISTS\n");
1433 SetLastError(0xdeadbeef);
1434 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
1435 CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
1436 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
1437 "hFile %p, last error %u\n", hFile, GetLastError());
1439 CloseHandle(hFile);
1441 SetLastError(0xdeadbeef);
1442 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
1443 OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
1444 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
1445 "hFile %p, last error %u\n", hFile, GetLastError());
1447 CloseHandle(hFile);
1449 ret = DeleteFileW(filename);
1450 ok(ret, "DeleteFileW: error %d\n", GetLastError());
1452 SetLastError(0xdeadbeef);
1453 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
1454 OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
1455 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == 0,
1456 "hFile %p, last error %u\n", hFile, GetLastError());
1458 CloseHandle(hFile);
1460 ret = DeleteFileW(filename);
1461 ok(ret, "DeleteFileW: error %d\n", GetLastError());
1463 if (0)
1465 /* this crashes on NT4.0 */
1466 hFile = CreateFileW(NULL, GENERIC_READ, 0, NULL,
1467 CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
1468 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
1469 "CreateFileW(NULL) returned ret=%p error=%u\n",hFile,GetLastError());
1472 hFile = CreateFileW(emptyW, GENERIC_READ, 0, NULL,
1473 CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
1474 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
1475 "CreateFileW(\"\") returned ret=%p error=%d\n",hFile,GetLastError());
1477 /* test the result of opening a nonexistent driver name */
1478 hFile = CreateFileW(bogus, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1479 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1480 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND,
1481 "CreateFileW on invalid VxD name returned ret=%p error=%d\n",hFile,GetLastError());
1483 ret = CreateDirectoryW(filename, NULL);
1484 ok(ret == TRUE, "couldn't create temporary directory\n");
1485 hFile = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
1486 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL);
1487 ok(hFile != INVALID_HANDLE_VALUE,
1488 "expected CreateFile to succeed on existing directory, error: %d\n", GetLastError());
1489 CloseHandle(hFile);
1490 ret = RemoveDirectoryW(filename);
1491 ok(ret, "DeleteFileW: error %d\n", GetLastError());
1494 static void test_CreateFile2(void)
1496 HANDLE hFile;
1497 WCHAR temp_path[MAX_PATH];
1498 WCHAR filename[MAX_PATH];
1499 CREATEFILE2_EXTENDED_PARAMETERS exparams;
1500 static const WCHAR emptyW[]={'\0'};
1501 static const WCHAR prefix[] = {'p','f','x',0};
1502 static const WCHAR bogus[] = { '\\', '\\', '.', '\\', 'B', 'O', 'G', 'U', 'S', 0 };
1503 DWORD ret;
1505 if (!pCreateFile2)
1507 win_skip("CreateFile2 is missing\n");
1508 return;
1511 ret = GetTempPathW(MAX_PATH, temp_path);
1512 ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
1513 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
1515 ret = GetTempFileNameW(temp_path, prefix, 0, filename);
1516 ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
1518 SetLastError(0xdeadbeef);
1519 exparams.dwSize = sizeof(exparams);
1520 exparams.dwFileAttributes = FILE_FLAG_RANDOM_ACCESS;
1521 exparams.dwFileFlags = 0;
1522 exparams.dwSecurityQosFlags = 0;
1523 exparams.lpSecurityAttributes = NULL;
1524 exparams.hTemplateFile = 0;
1525 hFile = pCreateFile2(filename, GENERIC_READ, 0, CREATE_NEW, &exparams);
1526 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS,
1527 "CREATE_NEW should fail if file exists and last error value should be ERROR_FILE_EXISTS\n");
1529 SetLastError(0xdeadbeef);
1530 hFile = pCreateFile2(filename, GENERIC_READ, FILE_SHARE_READ, CREATE_ALWAYS, &exparams);
1531 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
1532 "hFile %p, last error %u\n", hFile, GetLastError());
1533 CloseHandle(hFile);
1535 SetLastError(0xdeadbeef);
1536 hFile = pCreateFile2(filename, GENERIC_READ, FILE_SHARE_READ, OPEN_ALWAYS, &exparams);
1537 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
1538 "hFile %p, last error %u\n", hFile, GetLastError());
1539 CloseHandle(hFile);
1541 ret = DeleteFileW(filename);
1542 ok(ret, "DeleteFileW: error %d\n", GetLastError());
1544 SetLastError(0xdeadbeef);
1545 hFile = pCreateFile2(filename, GENERIC_READ, FILE_SHARE_READ, OPEN_ALWAYS, &exparams);
1546 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == 0,
1547 "hFile %p, last error %u\n", hFile, GetLastError());
1548 CloseHandle(hFile);
1550 ret = DeleteFileW(filename);
1551 ok(ret, "DeleteFileW: error %d\n", GetLastError());
1553 hFile = pCreateFile2(emptyW, GENERIC_READ, 0, CREATE_NEW, &exparams);
1554 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
1555 "CreateFile2(\"\") returned ret=%p error=%d\n",hFile,GetLastError());
1557 /* test the result of opening a nonexistent driver name */
1558 exparams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
1559 hFile = pCreateFile2(bogus, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING, &exparams);
1560 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND,
1561 "CreateFile2 on invalid VxD name returned ret=%p error=%d\n",hFile,GetLastError());
1563 ret = CreateDirectoryW(filename, NULL);
1564 ok(ret == TRUE, "couldn't create temporary directory\n");
1565 exparams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS;
1566 hFile = pCreateFile2(filename, GENERIC_READ | GENERIC_WRITE, 0, OPEN_ALWAYS, &exparams);
1567 todo_wine
1568 ok(hFile == INVALID_HANDLE_VALUE,
1569 "expected CreateFile2 to fail on existing directory, error: %d\n", GetLastError());
1570 CloseHandle(hFile);
1571 ret = RemoveDirectoryW(filename);
1572 ok(ret, "DeleteFileW: error %d\n", GetLastError());
1575 static void test_GetTempFileNameA(void)
1577 UINT result;
1578 char out[MAX_PATH];
1579 char expected[MAX_PATH + 10];
1580 char windowsdir[MAX_PATH + 10];
1581 char windowsdrive[3];
1583 result = GetWindowsDirectoryA(windowsdir, sizeof(windowsdir));
1584 ok(result < sizeof(windowsdir), "windowsdir is abnormally long!\n");
1585 ok(result != 0, "GetWindowsDirectory: error %d\n", GetLastError());
1587 /* If the Windows directory is the root directory, it ends in backslash, not else. */
1588 if (strlen(windowsdir) != 3) /* As in "C:\" or "F:\" */
1590 strcat(windowsdir, "\\");
1593 windowsdrive[0] = windowsdir[0];
1594 windowsdrive[1] = windowsdir[1];
1595 windowsdrive[2] = '\0';
1597 result = GetTempFileNameA(windowsdrive, "abc", 1, out);
1598 ok(result != 0, "GetTempFileNameA: error %d\n", GetLastError());
1599 ok(((out[0] == windowsdrive[0]) && (out[1] == ':')) && (out[2] == '\\'),
1600 "GetTempFileNameA: first three characters should be %c:\\, string was actually %s\n",
1601 windowsdrive[0], out);
1603 result = GetTempFileNameA(windowsdir, "abc", 2, out);
1604 ok(result != 0, "GetTempFileNameA: error %d\n", GetLastError());
1605 expected[0] = '\0';
1606 strcat(expected, windowsdir);
1607 strcat(expected, "abc2.tmp");
1608 ok(lstrcmpiA(out, expected) == 0, "GetTempFileNameA: Unexpected output \"%s\" vs \"%s\"\n",
1609 out, expected);
1612 static void test_DeleteFileA( void )
1614 BOOL ret;
1615 char temp_path[MAX_PATH], temp_file[MAX_PATH];
1616 HANDLE hfile;
1618 ret = DeleteFileA(NULL);
1619 ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER ||
1620 GetLastError() == ERROR_PATH_NOT_FOUND),
1621 "DeleteFileA(NULL) returned ret=%d error=%d\n",ret,GetLastError());
1623 ret = DeleteFileA("");
1624 ok(!ret && (GetLastError() == ERROR_PATH_NOT_FOUND ||
1625 GetLastError() == ERROR_BAD_PATHNAME),
1626 "DeleteFileA(\"\") returned ret=%d error=%d\n",ret,GetLastError());
1628 ret = DeleteFileA("nul");
1629 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
1630 GetLastError() == ERROR_INVALID_PARAMETER ||
1631 GetLastError() == ERROR_ACCESS_DENIED ||
1632 GetLastError() == ERROR_INVALID_FUNCTION),
1633 "DeleteFileA(\"nul\") returned ret=%d error=%d\n",ret,GetLastError());
1635 ret = DeleteFileA("nonexist.txt");
1636 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, "DeleteFileA(\"nonexist.txt\") returned ret=%d error=%d\n",ret,GetLastError());
1638 GetTempPathA(MAX_PATH, temp_path);
1639 GetTempFileNameA(temp_path, "tst", 0, temp_file);
1641 SetLastError(0xdeadbeef);
1642 hfile = CreateFileA(temp_file, GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
1643 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
1645 SetLastError(0xdeadbeef);
1646 ret = DeleteFileA(temp_file);
1647 todo_wine
1648 ok(ret, "DeleteFile error %d\n", GetLastError());
1650 SetLastError(0xdeadbeef);
1651 ret = CloseHandle(hfile);
1652 ok(ret, "CloseHandle error %d\n", GetLastError());
1653 ret = DeleteFileA(temp_file);
1654 todo_wine
1655 ok(!ret, "DeleteFile should fail\n");
1657 SetLastError(0xdeadbeef);
1658 ret = CreateDirectoryA("testdir", NULL);
1659 ok(ret, "CreateDirectory failed, got err %d\n", GetLastError());
1660 ret = DeleteFileA("testdir");
1661 ok(!ret && GetLastError() == ERROR_ACCESS_DENIED,
1662 "Expected ERROR_ACCESS_DENIED, got error %d\n", GetLastError());
1663 ret = RemoveDirectoryA("testdir");
1664 ok(ret, "Remove a directory failed, got error %d\n", GetLastError());
1667 static void test_DeleteFileW( void )
1669 BOOL ret;
1670 WCHAR pathW[MAX_PATH];
1671 WCHAR pathsubW[MAX_PATH];
1672 static const WCHAR dirW[] = {'d','e','l','e','t','e','f','i','l','e',0};
1673 static const WCHAR subdirW[] = {'\\','s','u','b',0};
1674 static const WCHAR emptyW[]={'\0'};
1676 ret = DeleteFileW(NULL);
1677 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1679 win_skip("DeleteFileW is not available\n");
1680 return;
1682 ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND,
1683 "DeleteFileW(NULL) returned ret=%d error=%d\n",ret,GetLastError());
1685 ret = DeleteFileW(emptyW);
1686 ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND,
1687 "DeleteFileW(\"\") returned ret=%d error=%d\n",ret,GetLastError());
1689 /* test DeleteFile on empty directory */
1690 ret = GetTempPathW(MAX_PATH, pathW);
1691 if (ret + sizeof(dirW)/sizeof(WCHAR)-1 + sizeof(subdirW)/sizeof(WCHAR)-1 >= MAX_PATH)
1693 ok(0, "MAX_PATH exceeded in constructing paths\n");
1694 return;
1696 lstrcatW(pathW, dirW);
1697 lstrcpyW(pathsubW, pathW);
1698 lstrcatW(pathsubW, subdirW);
1699 ret = CreateDirectoryW(pathW, NULL);
1700 ok(ret == TRUE, "couldn't create directory deletefile\n");
1701 ret = DeleteFileW(pathW);
1702 ok(ret == FALSE, "DeleteFile should fail for empty directories\n");
1703 ret = RemoveDirectoryW(pathW);
1704 ok(ret == TRUE, "expected to remove directory deletefile\n");
1706 /* test DeleteFile on non-empty directory */
1707 ret = CreateDirectoryW(pathW, NULL);
1708 ok(ret == TRUE, "couldn't create directory deletefile\n");
1709 ret = CreateDirectoryW(pathsubW, NULL);
1710 ok(ret == TRUE, "couldn't create directory deletefile\\sub\n");
1711 ret = DeleteFileW(pathW);
1712 ok(ret == FALSE, "DeleteFile should fail for non-empty directories\n");
1713 ret = RemoveDirectoryW(pathsubW);
1714 ok(ret == TRUE, "expected to remove directory deletefile\\sub\n");
1715 ret = RemoveDirectoryW(pathW);
1716 ok(ret == TRUE, "expected to remove directory deletefile\n");
1719 #define IsDotDir(x) ((x[0] == '.') && ((x[1] == 0) || ((x[1] == '.') && (x[2] == 0))))
1721 static void test_MoveFileA(void)
1723 char tempdir[MAX_PATH];
1724 char source[MAX_PATH], dest[MAX_PATH];
1725 static const char prefix[] = "pfx";
1726 HANDLE hfile;
1727 HANDLE hmapfile;
1728 DWORD ret;
1729 BOOL retok;
1731 ret = GetTempPathA(MAX_PATH, tempdir);
1732 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
1733 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
1735 ret = GetTempFileNameA(tempdir, prefix, 0, source);
1736 ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
1738 ret = GetTempFileNameA(tempdir, prefix, 0, dest);
1739 ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
1741 ret = MoveFileA(source, dest);
1742 ok(!ret && GetLastError() == ERROR_ALREADY_EXISTS,
1743 "MoveFileA: unexpected error %d\n", GetLastError());
1745 ret = DeleteFileA(dest);
1746 ok(ret, "DeleteFileA: error %d\n", GetLastError());
1748 hfile = CreateFileA(source, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
1749 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
1751 retok = WriteFile(hfile, prefix, sizeof(prefix), &ret, NULL );
1752 ok( retok && ret == sizeof(prefix),
1753 "WriteFile error %d\n", GetLastError());
1755 hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
1756 ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError());
1758 ret = MoveFileA(source, dest);
1759 todo_wine {
1760 ok(!ret, "MoveFileA: expected failure\n");
1761 ok(GetLastError() == ERROR_SHARING_VIOLATION ||
1762 broken(GetLastError() == ERROR_ACCESS_DENIED), /* Win9x and WinMe */
1763 "MoveFileA: expected ERROR_SHARING_VIOLATION, got %d\n", GetLastError());
1766 CloseHandle(hmapfile);
1767 CloseHandle(hfile);
1769 /* if MoveFile succeeded, move back to dest */
1770 if (ret) MoveFileA(dest, source);
1772 hfile = CreateFileA(source, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
1773 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
1775 hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
1776 ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError());
1778 ret = MoveFileA(source, dest);
1779 todo_wine {
1780 ok(!ret, "MoveFileA: expected failure\n");
1781 ok(GetLastError() == ERROR_SHARING_VIOLATION ||
1782 broken(GetLastError() == ERROR_ACCESS_DENIED), /* Win9x and WinMe */
1783 "MoveFileA: expected ERROR_SHARING_VIOLATION, got %d\n", GetLastError());
1786 CloseHandle(hmapfile);
1787 CloseHandle(hfile);
1789 /* if MoveFile succeeded, move back to dest */
1790 if (ret) MoveFileA(dest, source);
1792 ret = MoveFileA(source, dest);
1793 ok(ret, "MoveFileA: failed, error %d\n", GetLastError());
1795 lstrcatA(tempdir, "Remove Me");
1796 ret = CreateDirectoryA(tempdir, NULL);
1797 ok(ret == TRUE, "CreateDirectoryA failed\n");
1799 lstrcpyA(source, dest);
1800 lstrcpyA(dest, tempdir);
1801 lstrcatA(dest, "\\wild?.*");
1802 /* FIXME: if we create a file with wildcards we can't delete it now that DeleteFile works correctly */
1803 ret = MoveFileA(source, dest);
1804 ok(!ret, "MoveFileA: shouldn't move to wildcard file\n");
1805 ok(GetLastError() == ERROR_INVALID_NAME || /* NT */
1806 GetLastError() == ERROR_FILE_NOT_FOUND, /* Win9x */
1807 "MoveFileA: with wildcards, unexpected error %d\n", GetLastError());
1808 if (ret || (GetLastError() != ERROR_INVALID_NAME))
1810 WIN32_FIND_DATAA fd;
1811 char temppath[MAX_PATH];
1812 HANDLE hFind;
1814 lstrcpyA(temppath, tempdir);
1815 lstrcatA(temppath, "\\*.*");
1816 hFind = FindFirstFileA(temppath, &fd);
1817 if (INVALID_HANDLE_VALUE != hFind)
1819 LPSTR lpName;
1822 lpName = fd.cAlternateFileName;
1823 if (!lpName[0])
1824 lpName = fd.cFileName;
1825 ok(IsDotDir(lpName), "MoveFileA: wildcards file created!\n");
1827 while (FindNextFileA(hFind, &fd));
1828 FindClose(hFind);
1831 ret = DeleteFileA(source);
1832 ok(ret, "DeleteFileA: error %d\n", GetLastError());
1833 ret = DeleteFileA(dest);
1834 ok(!ret, "DeleteFileA: error %d\n", GetLastError());
1835 ret = RemoveDirectoryA(tempdir);
1836 ok(ret, "DeleteDirectoryA: error %d\n", GetLastError());
1839 static void test_MoveFileW(void)
1841 WCHAR temp_path[MAX_PATH];
1842 WCHAR source[MAX_PATH], dest[MAX_PATH];
1843 static const WCHAR prefix[] = {'p','f','x',0};
1844 DWORD ret;
1846 ret = GetTempPathW(MAX_PATH, temp_path);
1847 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1849 win_skip("GetTempPathW is not available\n");
1850 return;
1852 ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
1853 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
1855 ret = GetTempFileNameW(temp_path, prefix, 0, source);
1856 ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
1858 ret = GetTempFileNameW(temp_path, prefix, 0, dest);
1859 ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
1861 ret = MoveFileW(source, dest);
1862 ok(!ret && GetLastError() == ERROR_ALREADY_EXISTS,
1863 "CopyFileW: unexpected error %d\n", GetLastError());
1865 ret = DeleteFileW(source);
1866 ok(ret, "DeleteFileW: error %d\n", GetLastError());
1867 ret = DeleteFileW(dest);
1868 ok(ret, "DeleteFileW: error %d\n", GetLastError());
1871 #define PATTERN_OFFSET 0x10
1873 static void test_offset_in_overlapped_structure(void)
1875 HANDLE hFile;
1876 OVERLAPPED ov;
1877 DWORD done, offset;
1878 BOOL rc;
1879 BYTE buf[256], pattern[] = "TeSt";
1880 UINT i;
1881 char temp_path[MAX_PATH], temp_fname[MAX_PATH];
1882 BOOL ret;
1884 ret =GetTempPathA(MAX_PATH, temp_path);
1885 ok( ret, "GetTempPathA error %d\n", GetLastError());
1886 ret =GetTempFileNameA(temp_path, "pfx", 0, temp_fname);
1887 ok( ret, "GetTempFileNameA error %d\n", GetLastError());
1889 /*** Write File *****************************************************/
1891 hFile = CreateFileA(temp_fname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
1892 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError());
1894 for(i = 0; i < sizeof(buf); i++) buf[i] = i;
1895 ret = WriteFile(hFile, buf, sizeof(buf), &done, NULL);
1896 ok( ret, "WriteFile error %d\n", GetLastError());
1897 ok(done == sizeof(buf), "expected number of bytes written %u\n", done);
1899 memset(&ov, 0, sizeof(ov));
1900 S(U(ov)).Offset = PATTERN_OFFSET;
1901 S(U(ov)).OffsetHigh = 0;
1902 rc=WriteFile(hFile, pattern, sizeof(pattern), &done, &ov);
1903 /* Win 9x does not support the overlapped I/O on files */
1904 if (rc || GetLastError()!=ERROR_INVALID_PARAMETER) {
1905 ok(rc, "WriteFile error %d\n", GetLastError());
1906 ok(done == sizeof(pattern), "expected number of bytes written %u\n", done);
1907 offset = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
1908 ok(offset == PATTERN_OFFSET + sizeof(pattern), "wrong file offset %d\n", offset);
1910 S(U(ov)).Offset = sizeof(buf) * 2;
1911 S(U(ov)).OffsetHigh = 0;
1912 ret = WriteFile(hFile, pattern, sizeof(pattern), &done, &ov);
1913 ok( ret, "WriteFile error %d\n", GetLastError());
1914 ok(done == sizeof(pattern), "expected number of bytes written %u\n", done);
1915 offset = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
1916 ok(offset == sizeof(buf) * 2 + sizeof(pattern), "wrong file offset %d\n", offset);
1919 CloseHandle(hFile);
1921 /*** Read File *****************************************************/
1923 hFile = CreateFileA(temp_fname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
1924 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError());
1926 memset(buf, 0, sizeof(buf));
1927 memset(&ov, 0, sizeof(ov));
1928 S(U(ov)).Offset = PATTERN_OFFSET;
1929 S(U(ov)).OffsetHigh = 0;
1930 rc=ReadFile(hFile, buf, sizeof(pattern), &done, &ov);
1931 /* Win 9x does not support the overlapped I/O on files */
1932 if (rc || GetLastError()!=ERROR_INVALID_PARAMETER) {
1933 ok(rc, "ReadFile error %d\n", GetLastError());
1934 ok(done == sizeof(pattern), "expected number of bytes read %u\n", done);
1935 offset = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
1936 ok(offset == PATTERN_OFFSET + sizeof(pattern), "wrong file offset %d\n", offset);
1937 ok(!memcmp(buf, pattern, sizeof(pattern)), "pattern match failed\n");
1940 CloseHandle(hFile);
1942 ret = DeleteFileA(temp_fname);
1943 ok( ret, "DeleteFileA error %d\n", GetLastError());
1946 static void test_LockFile(void)
1948 HANDLE handle, handle2;
1949 DWORD written;
1950 OVERLAPPED overlapped;
1951 int limited_LockFile;
1952 int limited_UnLockFile;
1953 BOOL ret;
1955 handle = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1956 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1957 CREATE_ALWAYS, 0, 0 );
1958 if (handle == INVALID_HANDLE_VALUE)
1960 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
1961 return;
1963 handle2 = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1964 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1965 OPEN_EXISTING, 0, 0 );
1966 if (handle2 == INVALID_HANDLE_VALUE)
1968 ok( 0, "couldn't open file \"%s\" (err=%d)\n", filename, GetLastError() );
1969 goto cleanup;
1971 ok( WriteFile( handle, sillytext, strlen(sillytext), &written, NULL ), "write failed\n" );
1973 ok( LockFile( handle, 0, 0, 0, 0 ), "LockFile failed\n" );
1974 ok( UnlockFile( handle, 0, 0, 0, 0 ), "UnlockFile failed\n" );
1976 limited_UnLockFile = 0;
1977 if (UnlockFile( handle, 0, 0, 0, 0 ))
1979 limited_UnLockFile = 1;
1982 ok( LockFile( handle, 10, 0, 20, 0 ), "LockFile 10,20 failed\n" );
1983 /* overlapping locks must fail */
1984 ok( !LockFile( handle, 12, 0, 10, 0 ), "LockFile 12,10 succeeded\n" );
1985 ok( !LockFile( handle, 5, 0, 6, 0 ), "LockFile 5,6 succeeded\n" );
1986 /* non-overlapping locks must succeed */
1987 ok( LockFile( handle, 5, 0, 5, 0 ), "LockFile 5,5 failed\n" );
1989 ok( !UnlockFile( handle, 10, 0, 10, 0 ), "UnlockFile 10,10 succeeded\n" );
1990 ok( UnlockFile( handle, 10, 0, 20, 0 ), "UnlockFile 10,20 failed\n" );
1991 ok( !UnlockFile( handle, 10, 0, 20, 0 ), "UnlockFile 10,20 again succeeded\n" );
1992 ok( UnlockFile( handle, 5, 0, 5, 0 ), "UnlockFile 5,5 failed\n" );
1994 S(U(overlapped)).Offset = 100;
1995 S(U(overlapped)).OffsetHigh = 0;
1996 overlapped.hEvent = 0;
1998 /* Test for broken LockFileEx a la Windows 95 OSR2. */
1999 if (LockFileEx( handle, 0, 0, 100, 0, &overlapped ))
2001 /* LockFileEx is probably OK, test it more. */
2002 ok( LockFileEx( handle, 0, 0, 100, 0, &overlapped ),
2003 "LockFileEx 100,100 failed\n" );
2006 /* overlapping shared locks are OK */
2007 S(U(overlapped)).Offset = 150;
2008 limited_UnLockFile || ok( LockFileEx( handle, 0, 0, 100, 0, &overlapped ), "LockFileEx 150,100 failed\n" );
2010 /* but exclusive is not */
2011 ok( !LockFileEx( handle, LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,
2012 0, 50, 0, &overlapped ),
2013 "LockFileEx exclusive 150,50 succeeded\n" );
2014 if (!UnlockFileEx( handle, 0, 100, 0, &overlapped ))
2015 { /* UnLockFile is capable. */
2016 S(U(overlapped)).Offset = 100;
2017 ok( !UnlockFileEx( handle, 0, 100, 0, &overlapped ),
2018 "UnlockFileEx 150,100 again succeeded\n" );
2021 /* shared lock can overlap exclusive if handles are equal */
2022 S(U(overlapped)).Offset = 300;
2023 ok( LockFileEx( handle, LOCKFILE_EXCLUSIVE_LOCK, 0, 100, 0, &overlapped ),
2024 "LockFileEx exclusive 300,100 failed\n" );
2025 ok( !LockFileEx( handle2, LOCKFILE_FAIL_IMMEDIATELY, 0, 100, 0, &overlapped ),
2026 "LockFileEx handle2 300,100 succeeded\n" );
2027 ret = LockFileEx( handle, LOCKFILE_FAIL_IMMEDIATELY, 0, 100, 0, &overlapped );
2028 ok( ret, "LockFileEx 300,100 failed\n" );
2029 ok( UnlockFileEx( handle, 0, 100, 0, &overlapped ), "UnlockFileEx 300,100 failed\n" );
2030 /* exclusive lock is removed first */
2031 ok( LockFileEx( handle2, LOCKFILE_FAIL_IMMEDIATELY, 0, 100, 0, &overlapped ),
2032 "LockFileEx handle2 300,100 failed\n" );
2033 ok( UnlockFileEx( handle2, 0, 100, 0, &overlapped ), "UnlockFileEx 300,100 failed\n" );
2034 if (ret)
2035 ok( UnlockFileEx( handle, 0, 100, 0, &overlapped ), "UnlockFileEx 300,100 failed\n" );
2037 ret = LockFile( handle, 0, 0x10000000, 0, 0xf0000000 );
2038 if (ret)
2040 ok( !LockFile( handle, ~0, ~0, 1, 0 ), "LockFile ~0,1 succeeded\n" );
2041 ok( !LockFile( handle, 0, 0x20000000, 20, 0 ), "LockFile 0x20000000,20 succeeded\n" );
2042 ok( UnlockFile( handle, 0, 0x10000000, 0, 0xf0000000 ), "UnlockFile failed\n" );
2044 else /* win9x */
2045 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong LockFile error %u\n", GetLastError() );
2047 /* wrap-around lock should not do anything */
2048 /* (but still succeeds on NT4 so we don't check result) */
2049 LockFile( handle, 0, 0x10000000, 0, 0xf0000001 );
2051 limited_LockFile = 0;
2052 if (!LockFile( handle, ~0, ~0, 1, 0 ))
2054 limited_LockFile = 1;
2057 limited_UnLockFile || ok( UnlockFile( handle, ~0, ~0, 1, 0 ), "Unlockfile ~0,1 failed\n" );
2059 /* zero-byte lock */
2060 ok( LockFile( handle, 100, 0, 0, 0 ), "LockFile 100,0 failed\n" );
2061 if (!limited_LockFile) ok( !LockFile( handle, 98, 0, 4, 0 ), "LockFile 98,4 succeeded\n" );
2062 ok( LockFile( handle, 90, 0, 10, 0 ), "LockFile 90,10 failed\n" );
2063 if (!limited_LockFile) ok( !LockFile( handle, 100, 0, 10, 0 ), "LockFile 100,10 failed\n" );
2065 ok( UnlockFile( handle, 90, 0, 10, 0 ), "UnlockFile 90,10 failed\n" );
2066 ok( !UnlockFile( handle, 100, 0, 10, 0 ), "UnlockFile 100,10 succeeded\n" );
2068 ok( UnlockFile( handle, 100, 0, 0, 0 ), "UnlockFile 100,0 failed\n" );
2070 CloseHandle( handle2 );
2071 cleanup:
2072 CloseHandle( handle );
2073 DeleteFileA( filename );
2076 static BOOL create_fake_dll( LPCSTR filename )
2078 IMAGE_DOS_HEADER *dos;
2079 IMAGE_NT_HEADERS *nt;
2080 IMAGE_SECTION_HEADER *sec;
2081 BYTE *buffer;
2082 DWORD lfanew = sizeof(*dos);
2083 DWORD size = lfanew + sizeof(*nt) + sizeof(*sec);
2084 DWORD written;
2085 BOOL ret;
2087 HANDLE file = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2088 if (file == INVALID_HANDLE_VALUE) return FALSE;
2090 buffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size );
2092 dos = (IMAGE_DOS_HEADER *)buffer;
2093 dos->e_magic = IMAGE_DOS_SIGNATURE;
2094 dos->e_cblp = sizeof(*dos);
2095 dos->e_cp = 1;
2096 dos->e_cparhdr = lfanew / 16;
2097 dos->e_minalloc = 0;
2098 dos->e_maxalloc = 0xffff;
2099 dos->e_ss = 0x0000;
2100 dos->e_sp = 0x00b8;
2101 dos->e_lfarlc = lfanew;
2102 dos->e_lfanew = lfanew;
2104 nt = (IMAGE_NT_HEADERS *)(buffer + lfanew);
2105 nt->Signature = IMAGE_NT_SIGNATURE;
2106 #if defined __i386__
2107 nt->FileHeader.Machine = IMAGE_FILE_MACHINE_I386;
2108 #elif defined __x86_64__
2109 nt->FileHeader.Machine = IMAGE_FILE_MACHINE_AMD64;
2110 #elif defined __powerpc__
2111 nt->FileHeader.Machine = IMAGE_FILE_MACHINE_POWERPC;
2112 #elif defined __arm__
2113 nt->FileHeader.Machine = IMAGE_FILE_MACHINE_ARMNT;
2114 #elif defined __aarch64__
2115 nt->FileHeader.Machine = IMAGE_FILE_MACHINE_ARM64;
2116 #else
2117 # error You must specify the machine type
2118 #endif
2119 nt->FileHeader.NumberOfSections = 1;
2120 nt->FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER);
2121 nt->FileHeader.Characteristics = IMAGE_FILE_DLL | IMAGE_FILE_EXECUTABLE_IMAGE;
2122 nt->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
2123 nt->OptionalHeader.MajorLinkerVersion = 1;
2124 nt->OptionalHeader.MinorLinkerVersion = 0;
2125 nt->OptionalHeader.ImageBase = 0x10000000;
2126 nt->OptionalHeader.SectionAlignment = 0x1000;
2127 nt->OptionalHeader.FileAlignment = 0x1000;
2128 nt->OptionalHeader.MajorOperatingSystemVersion = 1;
2129 nt->OptionalHeader.MinorOperatingSystemVersion = 0;
2130 nt->OptionalHeader.MajorImageVersion = 1;
2131 nt->OptionalHeader.MinorImageVersion = 0;
2132 nt->OptionalHeader.MajorSubsystemVersion = 4;
2133 nt->OptionalHeader.MinorSubsystemVersion = 0;
2134 nt->OptionalHeader.SizeOfImage = 0x2000;
2135 nt->OptionalHeader.SizeOfHeaders = size;
2136 nt->OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
2137 nt->OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
2139 sec = (IMAGE_SECTION_HEADER *)(nt + 1);
2140 memcpy( sec->Name, ".rodata", sizeof(".rodata") );
2141 sec->Misc.VirtualSize = 0x1000;
2142 sec->VirtualAddress = 0x1000;
2143 sec->SizeOfRawData = 0;
2144 sec->PointerToRawData = 0;
2145 sec->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
2147 ret = WriteFile( file, buffer, size, &written, NULL ) && written == size;
2148 HeapFree( GetProcessHeap(), 0, buffer );
2149 CloseHandle( file );
2150 return ret;
2153 static unsigned int map_file_access( unsigned int access )
2155 if (access & GENERIC_READ) access |= FILE_GENERIC_READ;
2156 if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE;
2157 if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE;
2158 if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS;
2159 return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
2162 static BOOL is_sharing_compatible( DWORD access1, DWORD sharing1, DWORD access2, DWORD sharing2 )
2164 access1 = map_file_access( access1 );
2165 access2 = map_file_access( access2 );
2166 access1 &= FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_EXECUTE | DELETE;
2167 access2 &= FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_EXECUTE | DELETE;
2169 if (!access1) sharing1 = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
2170 if (!access2) sharing2 = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
2172 if ((access1 & (FILE_READ_DATA|FILE_EXECUTE)) && !(sharing2 & FILE_SHARE_READ)) return FALSE;
2173 if ((access1 & (FILE_WRITE_DATA|FILE_APPEND_DATA)) && !(sharing2 & FILE_SHARE_WRITE)) return FALSE;
2174 if ((access1 & DELETE) && !(sharing2 & FILE_SHARE_DELETE)) return FALSE;
2175 if ((access2 & (FILE_READ_DATA|FILE_EXECUTE)) && !(sharing1 & FILE_SHARE_READ)) return FALSE;
2176 if ((access2 & (FILE_WRITE_DATA|FILE_APPEND_DATA)) && !(sharing1 & FILE_SHARE_WRITE)) return FALSE;
2177 if ((access2 & DELETE) && !(sharing1 & FILE_SHARE_DELETE)) return FALSE;
2178 return TRUE;
2181 static BOOL is_sharing_map_compatible( DWORD map_access, DWORD access2, DWORD sharing2 )
2183 if ((map_access == PAGE_READWRITE || map_access == PAGE_EXECUTE_READWRITE) &&
2184 !(sharing2 & FILE_SHARE_WRITE)) return FALSE;
2185 access2 = map_file_access( access2 );
2186 if ((map_access & SEC_IMAGE) && (access2 & FILE_WRITE_DATA)) return FALSE;
2187 return TRUE;
2190 static void test_file_sharing(void)
2192 static const DWORD access_modes[] =
2193 { 0, GENERIC_READ, GENERIC_WRITE, GENERIC_READ|GENERIC_WRITE,
2194 DELETE, GENERIC_READ|DELETE, GENERIC_WRITE|DELETE, GENERIC_READ|GENERIC_WRITE|DELETE,
2195 GENERIC_EXECUTE, GENERIC_EXECUTE | DELETE,
2196 FILE_READ_DATA, FILE_WRITE_DATA, FILE_APPEND_DATA, FILE_READ_EA, FILE_WRITE_EA,
2197 FILE_READ_DATA | FILE_EXECUTE, FILE_WRITE_DATA | FILE_EXECUTE, FILE_APPEND_DATA | FILE_EXECUTE,
2198 FILE_READ_EA | FILE_EXECUTE, FILE_WRITE_EA | FILE_EXECUTE, FILE_EXECUTE,
2199 FILE_DELETE_CHILD, FILE_READ_ATTRIBUTES, FILE_WRITE_ATTRIBUTES };
2200 static const DWORD sharing_modes[] =
2201 { 0, FILE_SHARE_READ,
2202 FILE_SHARE_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
2203 FILE_SHARE_DELETE, FILE_SHARE_READ|FILE_SHARE_DELETE,
2204 FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE };
2205 static const DWORD mapping_modes[] =
2206 { PAGE_READONLY, PAGE_WRITECOPY, PAGE_READWRITE, SEC_IMAGE | PAGE_WRITECOPY };
2207 int a1, s1, a2, s2;
2208 int ret;
2209 HANDLE h, h2;
2211 /* make sure the file exists */
2212 if (!create_fake_dll( filename ))
2214 ok(0, "couldn't create file \"%s\" (err=%d)\n", filename, GetLastError());
2215 return;
2218 for (a1 = 0; a1 < sizeof(access_modes)/sizeof(access_modes[0]); a1++)
2220 for (s1 = 0; s1 < sizeof(sharing_modes)/sizeof(sharing_modes[0]); s1++)
2222 SetLastError(0xdeadbeef);
2223 h = CreateFileA( filename, access_modes[a1], sharing_modes[s1],
2224 NULL, OPEN_EXISTING, 0, 0 );
2225 if (h == INVALID_HANDLE_VALUE)
2227 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
2228 return;
2230 for (a2 = 0; a2 < sizeof(access_modes)/sizeof(access_modes[0]); a2++)
2232 for (s2 = 0; s2 < sizeof(sharing_modes)/sizeof(sharing_modes[0]); s2++)
2234 SetLastError(0xdeadbeef);
2235 h2 = CreateFileA( filename, access_modes[a2], sharing_modes[s2],
2236 NULL, OPEN_EXISTING, 0, 0 );
2237 ret = GetLastError();
2238 if (is_sharing_compatible( access_modes[a1], sharing_modes[s1],
2239 access_modes[a2], sharing_modes[s2] ))
2241 ok( h2 != INVALID_HANDLE_VALUE,
2242 "open failed for modes %x/%x/%x/%x\n",
2243 access_modes[a1], sharing_modes[s1],
2244 access_modes[a2], sharing_modes[s2] );
2245 ok( ret == 0, "wrong error code %d\n", ret );
2247 else
2249 ok( h2 == INVALID_HANDLE_VALUE,
2250 "open succeeded for modes %x/%x/%x/%x\n",
2251 access_modes[a1], sharing_modes[s1],
2252 access_modes[a2], sharing_modes[s2] );
2253 ok( ret == ERROR_SHARING_VIOLATION,
2254 "wrong error code %d\n", ret );
2256 if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 );
2259 CloseHandle( h );
2263 for (a1 = 0; a1 < sizeof(mapping_modes)/sizeof(mapping_modes[0]); a1++)
2265 HANDLE m;
2267 create_fake_dll( filename );
2268 SetLastError(0xdeadbeef);
2269 h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2270 if (h == INVALID_HANDLE_VALUE)
2272 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
2273 return;
2275 m = CreateFileMappingA( h, NULL, mapping_modes[a1], 0, 0, NULL );
2276 ok( m != 0, "failed to create mapping %x err %u\n", mapping_modes[a1], GetLastError() );
2277 CloseHandle( h );
2278 if (!m) continue;
2280 for (a2 = 0; a2 < sizeof(access_modes)/sizeof(access_modes[0]); a2++)
2282 for (s2 = 0; s2 < sizeof(sharing_modes)/sizeof(sharing_modes[0]); s2++)
2284 SetLastError(0xdeadbeef);
2285 h2 = CreateFileA( filename, access_modes[a2], sharing_modes[s2],
2286 NULL, OPEN_EXISTING, 0, 0 );
2288 ret = GetLastError();
2289 if (h2 == INVALID_HANDLE_VALUE)
2291 ok( !is_sharing_map_compatible(mapping_modes[a1], access_modes[a2], sharing_modes[s2]),
2292 "open failed for modes map %x/%x/%x\n",
2293 mapping_modes[a1], access_modes[a2], sharing_modes[s2] );
2294 ok( ret == ERROR_SHARING_VIOLATION,
2295 "wrong error code %d\n", ret );
2297 else
2299 if (!is_sharing_map_compatible(mapping_modes[a1], access_modes[a2], sharing_modes[s2]))
2300 ok( broken(1), /* no checking on nt4 */
2301 "open succeeded for modes map %x/%x/%x\n",
2302 mapping_modes[a1], access_modes[a2], sharing_modes[s2] );
2303 ok( ret == 0xdeadbeef /* Win9x */ ||
2304 ret == 0, /* XP */
2305 "wrong error code %d\n", ret );
2306 CloseHandle( h2 );
2311 /* try CREATE_ALWAYS over an existing mapping */
2312 SetLastError(0xdeadbeef);
2313 h2 = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
2314 NULL, CREATE_ALWAYS, 0, 0 );
2315 ret = GetLastError();
2316 if (mapping_modes[a1] & SEC_IMAGE)
2318 ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] );
2319 ok( ret == ERROR_SHARING_VIOLATION, "wrong error code %d for %x\n", ret, mapping_modes[a1] );
2321 else
2323 ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] );
2324 ok( ret == ERROR_USER_MAPPED_FILE, "wrong error code %d for %x\n", ret, mapping_modes[a1] );
2326 if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 );
2328 /* try DELETE_ON_CLOSE over an existing mapping */
2329 SetLastError(0xdeadbeef);
2330 h2 = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
2331 NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0 );
2332 ret = GetLastError();
2333 if (mapping_modes[a1] & SEC_IMAGE)
2335 ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] );
2336 ok( ret == ERROR_ACCESS_DENIED, "wrong error code %d for %x\n", ret, mapping_modes[a1] );
2338 else
2340 ok( h2 != INVALID_HANDLE_VALUE, "open failed for map %x err %u\n", mapping_modes[a1], ret );
2342 if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 );
2344 CloseHandle( m );
2347 SetLastError(0xdeadbeef);
2348 h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, 0 );
2349 ok( h != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError() );
2351 SetLastError(0xdeadbeef);
2352 h2 = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
2353 ok( h2 == INVALID_HANDLE_VALUE, "CreateFileA should fail\n");
2354 ok( GetLastError() == ERROR_SHARING_VIOLATION, "wrong error code %d\n", GetLastError() );
2356 h2 = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
2357 ok( h2 != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError() );
2359 CloseHandle(h);
2360 CloseHandle(h2);
2362 DeleteFileA( filename );
2365 static char get_windows_drive(void)
2367 char windowsdir[MAX_PATH];
2368 GetWindowsDirectoryA(windowsdir, sizeof(windowsdir));
2369 return windowsdir[0];
2372 static void test_FindFirstFileA(void)
2374 HANDLE handle;
2375 WIN32_FIND_DATAA data;
2376 int err;
2377 char buffer[5] = "C:\\";
2378 char buffer2[100];
2379 char nonexistent[MAX_PATH];
2381 /* try FindFirstFileA on "C:\" */
2382 buffer[0] = get_windows_drive();
2384 SetLastError( 0xdeadbeaf );
2385 handle = FindFirstFileA(buffer, &data);
2386 err = GetLastError();
2387 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on root directory should fail\n" );
2388 ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err );
2390 /* try FindFirstFileA on "C:\*" */
2391 strcpy(buffer2, buffer);
2392 strcat(buffer2, "*");
2393 handle = FindFirstFileA(buffer2, &data);
2394 ok ( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s should succeed\n", buffer2 );
2395 ok ( strcmp( data.cFileName, "." ) && strcmp( data.cFileName, ".." ),
2396 "FindFirstFile shouldn't return '%s' in drive root\n", data.cFileName );
2397 if (FindNextFileA( handle, &data ))
2398 ok ( strcmp( data.cFileName, "." ) && strcmp( data.cFileName, ".." ),
2399 "FindNextFile shouldn't return '%s' in drive root\n", data.cFileName );
2400 ok ( FindClose(handle) == TRUE, "Failed to close handle %s\n", buffer2 );
2402 /* try FindFirstFileA on windows dir */
2403 GetWindowsDirectoryA( buffer2, sizeof(buffer2) );
2404 strcat(buffer2, "\\*");
2405 handle = FindFirstFileA(buffer2, &data);
2406 ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s should succeed\n", buffer2 );
2407 ok( !strcmp( data.cFileName, "." ), "FindFirstFile should return '.' first\n" );
2408 ok( FindNextFileA( handle, &data ), "FindNextFile failed\n" );
2409 ok( !strcmp( data.cFileName, ".." ), "FindNextFile should return '..' as second entry\n" );
2410 while (FindNextFileA( handle, &data ))
2411 ok ( strcmp( data.cFileName, "." ) && strcmp( data.cFileName, ".." ),
2412 "FindNextFile shouldn't return '%s'\n", data.cFileName );
2413 ok ( FindClose(handle) == TRUE, "Failed to close handle %s\n", buffer2 );
2415 /* try FindFirstFileA on "C:\foo\" */
2416 SetLastError( 0xdeadbeaf );
2417 if (!GetTempFileNameA( buffer, "foo", 0, nonexistent ) && GetLastError() == ERROR_ACCESS_DENIED)
2419 char tmp[MAX_PATH];
2420 GetTempPathA( sizeof(tmp), tmp );
2421 GetTempFileNameA( tmp, "foo", 0, nonexistent );
2423 DeleteFileA( nonexistent );
2424 strcpy(buffer2, nonexistent);
2425 strcat(buffer2, "\\");
2426 handle = FindFirstFileA(buffer2, &data);
2427 err = GetLastError();
2428 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 );
2429 todo_wine {
2430 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2433 /* try FindFirstFileA without trailing backslash */
2434 SetLastError( 0xdeadbeaf );
2435 strcpy(buffer2, nonexistent);
2436 handle = FindFirstFileA(buffer2, &data);
2437 err = GetLastError();
2438 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 );
2439 ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err );
2441 /* try FindFirstFileA on "C:\foo\bar.txt" */
2442 SetLastError( 0xdeadbeaf );
2443 strcpy(buffer2, nonexistent);
2444 strcat(buffer2, "\\bar.txt");
2445 handle = FindFirstFileA(buffer2, &data);
2446 err = GetLastError();
2447 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 );
2448 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2450 /* try FindFirstFileA on "C:\foo\*.*" */
2451 SetLastError( 0xdeadbeaf );
2452 strcpy(buffer2, nonexistent);
2453 strcat(buffer2, "\\*.*");
2454 handle = FindFirstFileA(buffer2, &data);
2455 err = GetLastError();
2456 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 );
2457 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2459 /* try FindFirstFileA on "foo\bar.txt" */
2460 SetLastError( 0xdeadbeaf );
2461 strcpy(buffer2, nonexistent + 3);
2462 strcat(buffer2, "\\bar.txt");
2463 handle = FindFirstFileA(buffer2, &data);
2464 err = GetLastError();
2465 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 );
2466 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2468 /* try FindFirstFileA on "c:\nul" */
2469 SetLastError( 0xdeadbeaf );
2470 strcpy(buffer2, buffer);
2471 strcat(buffer2, "nul");
2472 handle = FindFirstFileA(buffer2, &data);
2473 err = GetLastError();
2474 ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s failed: %d\n", buffer2, err );
2475 ok( 0 == lstrcmpiA(data.cFileName, "nul"), "wrong name %s\n", data.cFileName );
2476 ok( FILE_ATTRIBUTE_ARCHIVE == data.dwFileAttributes ||
2477 FILE_ATTRIBUTE_DEVICE == data.dwFileAttributes /* Win9x */,
2478 "wrong attributes %x\n", data.dwFileAttributes );
2479 if (data.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE)
2481 ok( 0 == data.nFileSizeHigh, "wrong size %d\n", data.nFileSizeHigh );
2482 ok( 0 == data.nFileSizeLow, "wrong size %d\n", data.nFileSizeLow );
2484 SetLastError( 0xdeadbeaf );
2485 ok( !FindNextFileA( handle, &data ), "FindNextFileA succeeded\n" );
2486 ok( GetLastError() == ERROR_NO_MORE_FILES, "bad error %d\n", GetLastError() );
2487 ok( FindClose( handle ), "failed to close handle\n" );
2489 /* try FindFirstFileA on "lpt1" */
2490 SetLastError( 0xdeadbeaf );
2491 strcpy(buffer2, "lpt1");
2492 handle = FindFirstFileA(buffer2, &data);
2493 err = GetLastError();
2494 ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s failed: %d\n", buffer2, err );
2495 ok( 0 == lstrcmpiA(data.cFileName, "lpt1"), "wrong name %s\n", data.cFileName );
2496 ok( FILE_ATTRIBUTE_ARCHIVE == data.dwFileAttributes ||
2497 FILE_ATTRIBUTE_DEVICE == data.dwFileAttributes /* Win9x */,
2498 "wrong attributes %x\n", data.dwFileAttributes );
2499 if (data.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE)
2501 ok( 0 == data.nFileSizeHigh, "wrong size %d\n", data.nFileSizeHigh );
2502 ok( 0 == data.nFileSizeLow, "wrong size %d\n", data.nFileSizeLow );
2504 SetLastError( 0xdeadbeaf );
2505 ok( !FindNextFileA( handle, &data ), "FindNextFileA succeeded\n" );
2506 ok( GetLastError() == ERROR_NO_MORE_FILES, "bad error %d\n", GetLastError() );
2507 ok( FindClose( handle ), "failed to close handle\n" );
2509 /* try FindFirstFileA on "c:\nul\*" */
2510 SetLastError( 0xdeadbeaf );
2511 strcpy(buffer2, buffer);
2512 strcat(buffer2, "nul\\*");
2513 handle = FindFirstFileA(buffer2, &data);
2514 err = GetLastError();
2515 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 );
2516 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2518 /* try FindFirstFileA on "c:\nul*" */
2519 SetLastError( 0xdeadbeaf );
2520 strcpy(buffer2, buffer);
2521 strcat(buffer2, "nul*");
2522 handle = FindFirstFileA(buffer2, &data);
2523 err = GetLastError();
2524 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 );
2525 ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err );
2527 /* try FindFirstFileA on "c:\foo\bar\nul" */
2528 SetLastError( 0xdeadbeaf );
2529 strcpy(buffer2, buffer);
2530 strcat(buffer2, "foo\\bar\\nul");
2531 handle = FindFirstFileA(buffer2, &data);
2532 err = GetLastError();
2533 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 );
2534 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2536 /* try FindFirstFileA on "c:\foo\nul\bar" */
2537 SetLastError( 0xdeadbeaf );
2538 strcpy(buffer2, buffer);
2539 strcat(buffer2, "foo\\nul\\bar");
2540 handle = FindFirstFileA(buffer2, &data);
2541 err = GetLastError();
2542 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 );
2543 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2546 static void test_FindNextFileA(void)
2548 HANDLE handle;
2549 WIN32_FIND_DATAA search_results;
2550 int err;
2551 char buffer[5] = "C:\\*";
2553 buffer[0] = get_windows_drive();
2554 handle = FindFirstFileA(buffer,&search_results);
2555 ok ( handle != INVALID_HANDLE_VALUE, "FindFirstFile on C:\\* should succeed\n" );
2556 while (FindNextFileA(handle, &search_results))
2558 /* get to the end of the files */
2560 ok ( FindClose(handle) == TRUE, "Failed to close handle\n");
2561 err = GetLastError();
2562 ok ( err == ERROR_NO_MORE_FILES, "GetLastError should return ERROR_NO_MORE_FILES\n");
2565 static void test_FindFirstFileExA(FINDEX_SEARCH_OPS search_ops, DWORD flags)
2567 WIN32_FIND_DATAA search_results;
2568 HANDLE handle;
2569 BOOL ret;
2571 if (!pFindFirstFileExA)
2573 win_skip("FindFirstFileExA() is missing\n");
2574 return;
2577 CreateDirectoryA("test-dir", NULL);
2578 _lclose(_lcreat("test-dir\\file1", 0));
2579 _lclose(_lcreat("test-dir\\file2", 0));
2580 CreateDirectoryA("test-dir\\dir1", NULL);
2581 SetLastError(0xdeadbeef);
2582 handle = pFindFirstFileExA("test-dir\\*", FindExInfoStandard, &search_results, search_ops, NULL, flags);
2583 if (handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
2585 win_skip("FindFirstFileExA is not implemented\n");
2586 goto cleanup;
2588 if ((flags & FIND_FIRST_EX_LARGE_FETCH) && handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER)
2590 win_skip("FindFirstFileExA flag FIND_FIRST_EX_LARGE_FETCH not supported, skipping test\n");
2591 goto cleanup;
2593 ok(handle != INVALID_HANDLE_VALUE, "FindFirstFile failed (err=%u)\n", GetLastError());
2594 ok(strcmp(search_results.cFileName, ".") == 0, "First entry should be '.', is %s\n", search_results.cFileName);
2596 #define CHECK_NAME(fn) (strcmp((fn), "file1") == 0 || strcmp((fn), "file2") == 0 || strcmp((fn), "dir1") == 0)
2598 ok(FindNextFileA(handle, &search_results), "Fetching second file failed\n");
2599 ok(strcmp(search_results.cFileName, "..") == 0, "Second entry should be '..' is %s\n", search_results.cFileName);
2601 ok(FindNextFileA(handle, &search_results), "Fetching third file failed\n");
2602 ok(CHECK_NAME(search_results.cFileName), "Invalid third entry - %s\n", search_results.cFileName);
2604 SetLastError(0xdeadbeef);
2605 ret = FindNextFileA(handle, &search_results);
2606 if (!ret && (GetLastError() == ERROR_NO_MORE_FILES) && (search_ops == FindExSearchLimitToDirectories))
2608 skip("File system supports directory filtering\n");
2609 /* Results from the previous call are not cleared */
2610 ok(strcmp(search_results.cFileName, "dir1") == 0, "Third entry should be 'dir1' is %s\n", search_results.cFileName);
2611 FindClose( handle );
2612 goto cleanup;
2615 ok(ret, "Fetching fourth file failed\n");
2616 ok(CHECK_NAME(search_results.cFileName), "Invalid fourth entry - %s\n", search_results.cFileName);
2618 ok(FindNextFileA(handle, &search_results), "Fetching fifth file failed\n");
2619 ok(CHECK_NAME(search_results.cFileName), "Invalid fifth entry - %s\n", search_results.cFileName);
2621 #undef CHECK_NAME
2623 ok(FindNextFileA(handle, &search_results) == FALSE, "Fetching sixth file should fail\n");
2625 FindClose( handle );
2627 cleanup:
2628 DeleteFileA("test-dir\\file1");
2629 DeleteFileA("test-dir\\file2");
2630 RemoveDirectoryA("test-dir\\dir1");
2631 RemoveDirectoryA("test-dir");
2634 static int test_Mapfile_createtemp(HANDLE *handle)
2636 SetFileAttributesA(filename,FILE_ATTRIBUTE_NORMAL);
2637 DeleteFileA(filename);
2638 *handle = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, 0, 0,
2639 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2640 if (*handle != INVALID_HANDLE_VALUE) {
2642 return 1;
2645 return 0;
2648 static void test_MapFile(void)
2650 HANDLE handle;
2651 HANDLE hmap;
2653 ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
2655 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 0x1000, "named_file_map" );
2656 ok( hmap != NULL, "mapping should work, I named it!\n" );
2658 ok( CloseHandle( hmap ), "can't close mapping handle\n");
2660 /* We have to close file before we try new stuff with mapping again.
2661 Else we would always succeed on XP or block descriptors on 95. */
2662 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
2663 ok( hmap != NULL, "We should still be able to map!\n" );
2664 ok( CloseHandle( hmap ), "can't close mapping handle\n");
2665 ok( CloseHandle( handle ), "can't close file handle\n");
2666 handle = NULL;
2668 ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
2670 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
2671 ok( hmap == NULL, "mapped zero size file\n");
2672 ok( GetLastError() == ERROR_FILE_INVALID, "not ERROR_FILE_INVALID\n");
2674 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0x80000000, 0, NULL );
2675 ok( hmap == NULL || broken(hmap != NULL) /* NT4 */, "mapping should fail\n");
2676 /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */
2677 if ( hmap )
2678 CloseHandle( hmap );
2680 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0x80000000, 0x10000, NULL );
2681 ok( hmap == NULL || broken(hmap != NULL) /* NT4 */, "mapping should fail\n");
2682 /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */
2683 if ( hmap )
2684 CloseHandle( hmap );
2686 /* On XP you can now map again, on Win 95 you cannot. */
2688 ok( CloseHandle( handle ), "can't close file handle\n");
2689 ok( DeleteFileA( filename ), "DeleteFile failed after map\n" );
2692 static void test_GetFileType(void)
2694 DWORD type, type2;
2695 HANDLE h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2696 ok( h != INVALID_HANDLE_VALUE, "open %s failed\n", filename );
2697 type = GetFileType(h);
2698 ok( type == FILE_TYPE_DISK, "expected type disk got %d\n", type );
2699 CloseHandle( h );
2700 h = CreateFileA( "nul", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2701 ok( h != INVALID_HANDLE_VALUE, "open nul failed\n" );
2702 type = GetFileType(h);
2703 ok( type == FILE_TYPE_CHAR, "expected type char for nul got %d\n", type );
2704 CloseHandle( h );
2705 DeleteFileA( filename );
2706 h = GetStdHandle( STD_OUTPUT_HANDLE );
2707 ok( h != INVALID_HANDLE_VALUE, "GetStdHandle failed\n" );
2708 type = GetFileType( (HANDLE)STD_OUTPUT_HANDLE );
2709 type2 = GetFileType( h );
2710 ok(type == type2, "expected type %d for STD_OUTPUT_HANDLE got %d\n", type2, type);
2713 static int completion_count;
2715 static void CALLBACK FileIOComplete(DWORD dwError, DWORD dwBytes, LPOVERLAPPED ovl)
2717 /* printf("(%ld, %ld, %p { %ld, %ld, %ld, %ld, %p })\n", dwError, dwBytes, ovl, ovl->Internal, ovl->InternalHigh, ovl->Offset, ovl->OffsetHigh, ovl->hEvent);*/
2718 ReleaseSemaphore(ovl->hEvent, 1, NULL);
2719 completion_count++;
2722 static void test_async_file_errors(void)
2724 char szFile[MAX_PATH];
2725 HANDLE hSem = CreateSemaphoreW(NULL, 1, 1, NULL);
2726 HANDLE hFile;
2727 LPVOID lpBuffer = HeapAlloc(GetProcessHeap(), 0, 4096);
2728 OVERLAPPED ovl;
2729 S(U(ovl)).Offset = 0;
2730 S(U(ovl)).OffsetHigh = 0;
2731 ovl.hEvent = hSem;
2732 completion_count = 0;
2733 szFile[0] = '\0';
2734 GetWindowsDirectoryA(szFile, sizeof(szFile)/sizeof(szFile[0])-1-strlen("\\win.ini"));
2735 strcat(szFile, "\\win.ini");
2736 hFile = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
2737 NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
2738 if (hFile == INVALID_HANDLE_VALUE) /* win9x doesn't like FILE_SHARE_DELETE */
2739 hFile = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
2740 NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
2741 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA(%s ...) failed\n", szFile);
2742 while (TRUE)
2744 BOOL res;
2745 DWORD count;
2746 while (WaitForSingleObjectEx(hSem, INFINITE, TRUE) == WAIT_IO_COMPLETION)
2748 res = ReadFileEx(hFile, lpBuffer, 4096, &ovl, FileIOComplete);
2749 /*printf("Offset = %ld, result = %s\n", ovl.Offset, res ? "TRUE" : "FALSE");*/
2750 if (!res)
2751 break;
2752 if (!GetOverlappedResult(hFile, &ovl, &count, FALSE))
2753 break;
2754 S(U(ovl)).Offset += count;
2755 /* i/o completion routine only called if ReadFileEx returned success.
2756 * we only care about violations of this rule so undo what should have
2757 * been done */
2758 completion_count--;
2760 ok(completion_count == 0, "completion routine should only be called when ReadFileEx succeeds (this rule was violated %d times)\n", completion_count);
2761 /*printf("Error = %ld\n", GetLastError());*/
2762 HeapFree(GetProcessHeap(), 0, lpBuffer);
2765 static BOOL user_apc_ran;
2766 static void CALLBACK user_apc(ULONG_PTR param)
2768 user_apc_ran = TRUE;
2771 static void test_read_write(void)
2773 DWORD bytes, ret, old_prot;
2774 HANDLE hFile;
2775 char temp_path[MAX_PATH];
2776 char filename[MAX_PATH];
2777 char *mem;
2778 static const char prefix[] = "pfx";
2780 ret = GetTempPathA(MAX_PATH, temp_path);
2781 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
2782 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
2784 ret = GetTempFileNameA(temp_path, prefix, 0, filename);
2785 ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
2787 hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
2788 CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
2789 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
2791 user_apc_ran = FALSE;
2792 if (pQueueUserAPC) {
2793 trace("Queueing an user APC\n"); /* verify the file is non alerable */
2794 ret = pQueueUserAPC(&user_apc, GetCurrentThread(), 0);
2795 ok(ret, "QueueUserAPC failed: %d\n", GetLastError());
2798 SetLastError(12345678);
2799 bytes = 12345678;
2800 ret = WriteFile(hFile, NULL, 0, &bytes, NULL);
2801 ok(ret && GetLastError() == 12345678,
2802 "ret = %d, error %d\n", ret, GetLastError());
2803 ok(!bytes, "bytes = %d\n", bytes);
2805 SetLastError(12345678);
2806 bytes = 12345678;
2807 ret = WriteFile(hFile, NULL, 10, &bytes, NULL);
2808 ok((!ret && GetLastError() == ERROR_INVALID_USER_BUFFER) || /* Win2k */
2809 (ret && GetLastError() == 12345678), /* Win9x */
2810 "ret = %d, error %d\n", ret, GetLastError());
2811 ok(!bytes || /* Win2k */
2812 bytes == 10, /* Win9x */
2813 "bytes = %d\n", bytes);
2815 /* make sure the file contains data */
2816 WriteFile(hFile, "this is the test data", 21, &bytes, NULL);
2817 SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
2819 SetLastError(12345678);
2820 bytes = 12345678;
2821 ret = ReadFile(hFile, NULL, 0, &bytes, NULL);
2822 ok(ret && GetLastError() == 12345678,
2823 "ret = %d, error %d\n", ret, GetLastError());
2824 ok(!bytes, "bytes = %d\n", bytes);
2826 SetLastError(12345678);
2827 bytes = 12345678;
2828 ret = ReadFile(hFile, NULL, 10, &bytes, NULL);
2829 ok(!ret && (GetLastError() == ERROR_NOACCESS || /* Win2k */
2830 GetLastError() == ERROR_INVALID_PARAMETER), /* Win9x */
2831 "ret = %d, error %d\n", ret, GetLastError());
2832 ok(!bytes, "bytes = %d\n", bytes);
2834 ok(user_apc_ran == FALSE, "UserAPC ran, file using alertable io mode\n");
2835 if (pQueueUserAPC)
2836 SleepEx(0, TRUE); /* get rid of apc */
2838 /* test passing protected memory as buffer */
2840 mem = VirtualAlloc( NULL, 0x4000, MEM_COMMIT, PAGE_READWRITE );
2841 ok( mem != NULL, "failed to allocate virtual mem error %u\n", GetLastError() );
2843 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
2844 ok( ret, "WriteFile failed error %u\n", GetLastError() );
2845 ok( bytes == 0x4000, "only wrote %x bytes\n", bytes );
2847 ret = VirtualProtect( mem + 0x2000, 0x2000, PAGE_NOACCESS, &old_prot );
2848 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2850 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
2851 ok( !ret, "WriteFile succeeded\n" );
2852 ok( GetLastError() == ERROR_INVALID_USER_BUFFER ||
2853 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2854 "wrong error %u\n", GetLastError() );
2855 ok( bytes == 0, "wrote %x bytes\n", bytes );
2857 ret = WriteFile( (HANDLE)0xdead, mem, 0x4000, &bytes, NULL );
2858 ok( !ret, "WriteFile succeeded\n" );
2859 ok( GetLastError() == ERROR_INVALID_HANDLE || /* handle is checked before buffer on NT */
2860 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2861 "wrong error %u\n", GetLastError() );
2862 ok( bytes == 0, "wrote %x bytes\n", bytes );
2864 ret = VirtualProtect( mem, 0x2000, PAGE_NOACCESS, &old_prot );
2865 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2867 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
2868 ok( !ret, "WriteFile succeeded\n" );
2869 ok( GetLastError() == ERROR_INVALID_USER_BUFFER ||
2870 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2871 "wrong error %u\n", GetLastError() );
2872 ok( bytes == 0, "wrote %x bytes\n", bytes );
2874 SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
2876 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2877 ok( !ret, "ReadFile succeeded\n" );
2878 ok( GetLastError() == ERROR_NOACCESS ||
2879 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2880 "wrong error %u\n", GetLastError() );
2881 ok( bytes == 0, "read %x bytes\n", bytes );
2883 ret = VirtualProtect( mem, 0x2000, PAGE_READONLY, &old_prot );
2884 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2886 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2887 ok( !ret, "ReadFile succeeded\n" );
2888 ok( GetLastError() == ERROR_NOACCESS ||
2889 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2890 "wrong error %u\n", GetLastError() );
2891 ok( bytes == 0, "read %x bytes\n", bytes );
2893 ret = VirtualProtect( mem, 0x2000, PAGE_READWRITE, &old_prot );
2894 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2896 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2897 ok( !ret, "ReadFile succeeded\n" );
2898 ok( GetLastError() == ERROR_NOACCESS ||
2899 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2900 "wrong error %u\n", GetLastError() );
2901 ok( bytes == 0, "read %x bytes\n", bytes );
2903 SetFilePointer( hFile, 0x1234, NULL, FILE_BEGIN );
2904 SetEndOfFile( hFile );
2905 SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
2907 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2908 ok( !ret, "ReadFile succeeded\n" );
2909 ok( GetLastError() == ERROR_NOACCESS ||
2910 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2911 "wrong error %u\n", GetLastError() );
2912 ok( bytes == 0, "read %x bytes\n", bytes );
2914 ret = ReadFile( hFile, mem, 0x2000, &bytes, NULL );
2915 ok( ret, "ReadFile failed error %u\n", GetLastError() );
2916 ok( bytes == 0x1234, "read %x bytes\n", bytes );
2918 ret = ReadFile( hFile, NULL, 1, &bytes, NULL );
2919 ok( !ret, "ReadFile succeeded\n" );
2920 ok( GetLastError() == ERROR_NOACCESS ||
2921 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2922 "wrong error %u\n", GetLastError() );
2923 ok( bytes == 0, "read %x bytes\n", bytes );
2925 VirtualFree( mem, 0, MEM_FREE );
2927 ret = CloseHandle(hFile);
2928 ok( ret, "CloseHandle: error %d\n", GetLastError());
2929 ret = DeleteFileA(filename);
2930 ok( ret, "DeleteFileA: error %d\n", GetLastError());
2933 static void test_OpenFile(void)
2935 HFILE hFile;
2936 OFSTRUCT ofs;
2937 BOOL ret;
2938 DWORD retval;
2940 static const char file[] = "regedit.exe";
2941 static const char foo[] = ".\\foo-bar-foo.baz";
2942 static const char *foo_too_long = ".\\foo-bar-foo.baz+++++++++++++++"
2943 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2944 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2945 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2946 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2947 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
2948 char buff[MAX_PATH];
2949 char buff_long[4*MAX_PATH];
2950 char filled_0xA5[OFS_MAXPATHNAME];
2951 char *p;
2952 UINT length;
2954 /* Check for existing file */
2955 if (!pGetSystemWindowsDirectoryA)
2956 length = GetWindowsDirectoryA(buff, MAX_PATH);
2957 else
2958 length = pGetSystemWindowsDirectoryA(buff, MAX_PATH);
2960 if (length + sizeof(file) < MAX_PATH)
2962 p = buff + strlen(buff);
2963 if (p > buff && p[-1] != '\\') *p++ = '\\';
2964 strcpy( p, file );
2965 memset(&ofs, 0xA5, sizeof(ofs));
2966 SetLastError(0xfaceabee);
2968 hFile = OpenFile(buff, &ofs, OF_EXIST);
2969 ok( hFile == TRUE, "%s not found : %d\n", buff, GetLastError() );
2970 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
2971 "GetLastError() returns %d\n", GetLastError() );
2972 ok( ofs.cBytes == sizeof(ofs), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2973 ok( ofs.nErrCode == ERROR_SUCCESS, "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2974 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2975 "OpenFile returned '%s', but was expected to return '%s' or string filled with 0xA5\n",
2976 ofs.szPathName, buff );
2979 memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
2980 length = GetCurrentDirectoryA(MAX_PATH, buff);
2982 /* Check for nonexistent file */
2983 if (length + sizeof(foo) < MAX_PATH)
2985 p = buff + strlen(buff);
2986 if (p > buff && p[-1] != '\\') *p++ = '\\';
2987 strcpy( p, foo + 2 );
2988 memset(&ofs, 0xA5, sizeof(ofs));
2989 SetLastError(0xfaceabee);
2991 hFile = OpenFile(foo, &ofs, OF_EXIST);
2992 ok( hFile == HFILE_ERROR, "hFile != HFILE_ERROR : %d\n", GetLastError());
2993 ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError() returns %d\n", GetLastError() );
2994 todo_wine
2995 ok( ofs.cBytes == 0xA5, "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2996 ok( ofs.nErrCode == ERROR_FILE_NOT_FOUND, "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2997 ok( lstrcmpiA(ofs.szPathName, buff) == 0 || strncmp(ofs.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0,
2998 "OpenFile returned '%s', but was expected to return '%s' or string filled with 0xA5\n",
2999 ofs.szPathName, buff );
3002 length = GetCurrentDirectoryA(MAX_PATH, buff_long);
3003 length += lstrlenA(foo_too_long + 1);
3005 /* Check for nonexistent file with too long filename */
3006 if (length >= OFS_MAXPATHNAME && length < sizeof(buff_long))
3008 lstrcatA(buff_long, foo_too_long + 1); /* Avoid '.' during concatenation */
3009 memset(&ofs, 0xA5, sizeof(ofs));
3010 SetLastError(0xfaceabee);
3012 hFile = OpenFile(foo_too_long, &ofs, OF_EXIST);
3013 ok( hFile == HFILE_ERROR, "hFile != HFILE_ERROR : %d\n", GetLastError());
3014 ok( GetLastError() == ERROR_INVALID_DATA || GetLastError() == ERROR_FILENAME_EXCED_RANGE,
3015 "GetLastError() returns %d\n", GetLastError() );
3016 todo_wine
3017 ok( ofs.cBytes == 0xA5, "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3018 ok( ofs.nErrCode == ERROR_INVALID_DATA || ofs.nErrCode == ERROR_FILENAME_EXCED_RANGE,
3019 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3020 ok( strncmp(ofs.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0,
3021 "OpenFile returned '%s', but was expected to return string filled with 0xA5\n",
3022 ofs.szPathName );
3025 length = GetCurrentDirectoryA(MAX_PATH, buff) + sizeof(filename);
3027 if (length >= MAX_PATH)
3029 trace("Buffer too small, requested length = %d, but MAX_PATH = %d. Skipping test.\n", length, MAX_PATH);
3030 return;
3032 p = buff + strlen(buff);
3033 if (p > buff && p[-1] != '\\') *p++ = '\\';
3034 strcpy( p, filename );
3036 memset(&ofs, 0xA5, sizeof(ofs));
3037 SetLastError(0xfaceabee);
3038 /* Create an empty file */
3039 hFile = OpenFile(filename, &ofs, OF_CREATE);
3040 ok( hFile != HFILE_ERROR, "OpenFile failed to create nonexistent file\n" );
3041 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3042 "GetLastError() returns %d\n", GetLastError() );
3043 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3044 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3045 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3046 ret = _lclose(hFile);
3047 ok( !ret, "_lclose() returns %d\n", ret );
3048 retval = GetFileAttributesA(filename);
3049 ok( retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %d\n", GetLastError() );
3051 memset(&ofs, 0xA5, sizeof(ofs));
3052 SetLastError(0xfaceabee);
3053 /* Check various opening options: */
3054 /* for reading only, */
3055 hFile = OpenFile(filename, &ofs, OF_READ);
3056 ok( hFile != HFILE_ERROR, "OpenFile failed on read\n" );
3057 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3058 "GetLastError() returns %d\n", GetLastError() );
3059 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3060 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3061 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3062 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
3063 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
3064 ret = _lclose(hFile);
3065 ok( !ret, "_lclose() returns %d\n", ret );
3067 memset(&ofs, 0xA5, sizeof(ofs));
3068 SetLastError(0xfaceabee);
3069 /* for writing only, */
3070 hFile = OpenFile(filename, &ofs, OF_WRITE);
3071 ok( hFile != HFILE_ERROR, "OpenFile failed on write\n" );
3072 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3073 "GetLastError() returns %d\n", GetLastError() );
3074 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3075 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3076 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3077 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
3078 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
3079 ret = _lclose(hFile);
3080 ok( !ret, "_lclose() returns %d\n", ret );
3082 memset(&ofs, 0xA5, sizeof(ofs));
3083 SetLastError(0xfaceabee);
3084 /* for reading and writing, */
3085 hFile = OpenFile(filename, &ofs, OF_READWRITE);
3086 ok( hFile != HFILE_ERROR, "OpenFile failed on read/write\n" );
3087 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3088 "GetLastError() returns %d\n", GetLastError() );
3089 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3090 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3091 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3092 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
3093 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
3094 ret = _lclose(hFile);
3095 ok( !ret, "_lclose() returns %d\n", ret );
3097 memset(&ofs, 0xA5, sizeof(ofs));
3098 SetLastError(0xfaceabee);
3099 /* for checking file presence. */
3100 hFile = OpenFile(filename, &ofs, OF_EXIST);
3101 ok( hFile == 1, "OpenFile failed on finding our created file\n" );
3102 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3103 "GetLastError() returns %d\n", GetLastError() );
3104 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3105 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3106 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3107 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
3108 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
3110 memset(&ofs, 0xA5, sizeof(ofs));
3111 SetLastError(0xfaceabee);
3112 /* Delete the file and make sure it doesn't exist anymore */
3113 hFile = OpenFile(filename, &ofs, OF_DELETE);
3114 ok( hFile == 1, "OpenFile failed on delete (%d)\n", hFile );
3115 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3116 "GetLastError() returns %d\n", GetLastError() );
3117 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3118 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3119 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3120 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
3121 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
3123 retval = GetFileAttributesA(filename);
3124 ok( retval == INVALID_FILE_ATTRIBUTES, "GetFileAttributesA succeeded on deleted file\n" );
3127 static void test_overlapped(void)
3129 OVERLAPPED ov;
3130 DWORD r, result;
3132 /* GetOverlappedResult crashes if the 2nd or 3rd param are NULL */
3133 if (0) /* tested: WinXP */
3135 GetOverlappedResult(0, NULL, &result, FALSE);
3136 GetOverlappedResult(0, &ov, NULL, FALSE);
3137 GetOverlappedResult(0, NULL, NULL, FALSE);
3140 memset( &ov, 0, sizeof ov );
3141 result = 1;
3142 r = GetOverlappedResult(0, &ov, &result, 0);
3143 if (r)
3144 ok( result == 0, "wrong result %u\n", result );
3145 else /* win9x */
3146 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
3148 result = 0;
3149 ov.Internal = 0;
3150 ov.InternalHigh = 0xabcd;
3151 r = GetOverlappedResult(0, &ov, &result, 0);
3152 if (r)
3153 ok( result == 0xabcd, "wrong result %u\n", result );
3154 else /* win9x */
3155 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
3157 SetLastError( 0xb00 );
3158 result = 0;
3159 ov.Internal = STATUS_INVALID_HANDLE;
3160 ov.InternalHigh = 0xabcd;
3161 r = GetOverlappedResult(0, &ov, &result, 0);
3162 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
3163 ok( r == FALSE, "should return false\n");
3164 ok( result == 0xabcd || result == 0 /* win9x */, "wrong result %u\n", result );
3166 SetLastError( 0xb00 );
3167 result = 0;
3168 ov.Internal = STATUS_PENDING;
3169 ov.InternalHigh = 0xabcd;
3170 r = GetOverlappedResult(0, &ov, &result, 0);
3171 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
3172 "wrong error %u\n", GetLastError() );
3173 ok( r == FALSE, "should return false\n");
3174 ok( result == 0, "wrong result %u\n", result );
3176 SetLastError( 0xb00 );
3177 ov.hEvent = CreateEventW( NULL, 1, 1, NULL );
3178 ov.Internal = STATUS_PENDING;
3179 ov.InternalHigh = 0xabcd;
3180 r = GetOverlappedResult(0, &ov, &result, 0);
3181 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
3182 "wrong error %u\n", GetLastError() );
3183 ok( r == FALSE, "should return false\n");
3185 ResetEvent( ov.hEvent );
3187 SetLastError( 0xb00 );
3188 ov.Internal = STATUS_PENDING;
3189 ov.InternalHigh = 0;
3190 r = GetOverlappedResult(0, &ov, &result, 0);
3191 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
3192 "wrong error %u\n", GetLastError() );
3193 ok( r == FALSE, "should return false\n");
3195 r = CloseHandle( ov.hEvent );
3196 ok( r == TRUE, "close handle failed\n");
3199 static void test_RemoveDirectory(void)
3201 int rc;
3202 char directory[] = "removeme";
3204 rc = CreateDirectoryA(directory, NULL);
3205 ok( rc, "Createdirectory failed, gle=%d\n", GetLastError() );
3207 rc = SetCurrentDirectoryA(directory);
3208 ok( rc, "SetCurrentDirectory failed, gle=%d\n", GetLastError() );
3210 rc = RemoveDirectoryA(".");
3211 if (!rc)
3213 rc = SetCurrentDirectoryA("..");
3214 ok( rc, "SetCurrentDirectory failed, gle=%d\n", GetLastError() );
3216 rc = RemoveDirectoryA(directory);
3217 ok( rc, "RemoveDirectory failed, gle=%d\n", GetLastError() );
3221 static BOOL check_file_time( const FILETIME *ft1, const FILETIME *ft2, UINT tolerance )
3223 ULONGLONG t1 = ((ULONGLONG)ft1->dwHighDateTime << 32) | ft1->dwLowDateTime;
3224 ULONGLONG t2 = ((ULONGLONG)ft2->dwHighDateTime << 32) | ft2->dwLowDateTime;
3225 return abs(t1 - t2) <= tolerance;
3228 static void test_ReplaceFileA(void)
3230 char replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH];
3231 HANDLE hReplacedFile, hReplacementFile, hBackupFile;
3232 static const char replacedData[] = "file-to-replace";
3233 static const char replacementData[] = "new-file";
3234 static const char backupData[] = "backup-file";
3235 FILETIME ftReplaced, ftReplacement, ftBackup;
3236 static const char prefix[] = "pfx";
3237 char temp_path[MAX_PATH];
3238 DWORD ret;
3239 BOOL retok, removeBackup = FALSE;
3241 if (!pReplaceFileA)
3243 win_skip("ReplaceFileA() is missing\n");
3244 return;
3247 ret = GetTempPathA(MAX_PATH, temp_path);
3248 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
3249 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
3251 ret = GetTempFileNameA(temp_path, prefix, 0, replaced);
3252 ok(ret != 0, "GetTempFileNameA error (replaced) %d\n", GetLastError());
3254 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3255 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
3257 ret = GetTempFileNameA(temp_path, prefix, 0, backup);
3258 ok(ret != 0, "GetTempFileNameA error (backup) %d\n", GetLastError());
3260 /* place predictable data in the file to be replaced */
3261 hReplacedFile = CreateFileA(replaced, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
3262 ok(hReplacedFile != INVALID_HANDLE_VALUE,
3263 "failed to open replaced file\n");
3264 retok = WriteFile(hReplacedFile, replacedData, sizeof(replacedData), &ret, NULL );
3265 ok( retok && ret == sizeof(replacedData),
3266 "WriteFile error (replaced) %d\n", GetLastError());
3267 ok(GetFileSize(hReplacedFile, NULL) == sizeof(replacedData),
3268 "replaced file has wrong size\n");
3269 /* place predictable data in the file to be the replacement */
3270 hReplacementFile = CreateFileA(replacement, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
3271 ok(hReplacementFile != INVALID_HANDLE_VALUE,
3272 "failed to open replacement file\n");
3273 retok = WriteFile(hReplacementFile, replacementData, sizeof(replacementData), &ret, NULL );
3274 ok( retok && ret == sizeof(replacementData),
3275 "WriteFile error (replacement) %d\n", GetLastError());
3276 ok(GetFileSize(hReplacementFile, NULL) == sizeof(replacementData),
3277 "replacement file has wrong size\n");
3278 /* place predictable data in the backup file (to be over-written) */
3279 hBackupFile = CreateFileA(backup, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
3280 ok(hBackupFile != INVALID_HANDLE_VALUE,
3281 "failed to open backup file\n");
3282 retok = WriteFile(hBackupFile, backupData, sizeof(backupData), &ret, NULL );
3283 ok( retok && ret == sizeof(backupData),
3284 "WriteFile error (replacement) %d\n", GetLastError());
3285 ok(GetFileSize(hBackupFile, NULL) == sizeof(backupData),
3286 "backup file has wrong size\n");
3287 /* change the filetime on the "replaced" file to ensure that it changes */
3288 ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
3289 ok( ret, "GetFileTime error (replaced) %d\n", GetLastError());
3290 ftReplaced.dwLowDateTime -= 600000000; /* 60 second */
3291 ret = SetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
3292 ok( ret, "SetFileTime error (replaced) %d\n", GetLastError());
3293 GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced); /* get the actual time back */
3294 CloseHandle(hReplacedFile);
3295 /* change the filetime on the backup to ensure that it changes */
3296 ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
3297 ok( ret, "GetFileTime error (backup) %d\n", GetLastError());
3298 ftBackup.dwLowDateTime -= 1200000000; /* 120 second */
3299 ret = SetFileTime(hBackupFile, NULL, NULL, &ftBackup);
3300 ok( ret, "SetFileTime error (backup) %d\n", GetLastError());
3301 GetFileTime(hBackupFile, NULL, NULL, &ftBackup); /* get the actual time back */
3302 CloseHandle(hBackupFile);
3303 /* get the filetime on the replacement file to perform checks */
3304 ret = GetFileTime(hReplacementFile, NULL, NULL, &ftReplacement);
3305 ok( ret, "GetFileTime error (replacement) %d\n", GetLastError());
3306 CloseHandle(hReplacementFile);
3308 /* perform replacement w/ backup
3309 * TODO: flags are not implemented
3311 SetLastError(0xdeadbeef);
3312 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3313 ok(ret, "ReplaceFileA: unexpected error %d\n", GetLastError());
3314 /* make sure that the backup has the size of the old "replaced" file */
3315 hBackupFile = CreateFileA(backup, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
3316 ok(hBackupFile != INVALID_HANDLE_VALUE,
3317 "failed to open backup file\n");
3318 ret = GetFileSize(hBackupFile, NULL);
3319 ok(ret == sizeof(replacedData),
3320 "backup file has wrong size %d\n", ret);
3321 /* make sure that the "replaced" file has the size of the replacement file */
3322 hReplacedFile = CreateFileA(replaced, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
3323 ok(hReplacedFile != INVALID_HANDLE_VALUE,
3324 "failed to open replaced file: %d\n", GetLastError());
3325 if (hReplacedFile != INVALID_HANDLE_VALUE)
3327 ret = GetFileSize(hReplacedFile, NULL);
3328 ok(ret == sizeof(replacementData),
3329 "replaced file has wrong size %d\n", ret);
3330 /* make sure that the replacement file no-longer exists */
3331 hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
3332 ok(hReplacementFile == INVALID_HANDLE_VALUE,
3333 "unexpected error, replacement file should not exist %d\n", GetLastError());
3334 /* make sure that the backup has the old "replaced" filetime */
3335 ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
3336 ok( ret, "GetFileTime error (backup %d\n", GetLastError());
3337 ok(check_file_time(&ftBackup, &ftReplaced, 20000000), "backup file has wrong filetime\n");
3338 CloseHandle(hBackupFile);
3339 /* make sure that the "replaced" has the old replacement filetime */
3340 ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
3341 ok( ret, "GetFileTime error (backup %d\n", GetLastError());
3342 ok(check_file_time(&ftReplaced, &ftReplacement, 20000000),
3343 "replaced file has wrong filetime %x%08x / %x%08x\n",
3344 ftReplaced.dwHighDateTime, ftReplaced.dwLowDateTime,
3345 ftReplacement.dwHighDateTime, ftReplacement.dwLowDateTime );
3346 CloseHandle(hReplacedFile);
3348 else
3349 skip("couldn't open replacement file, skipping tests\n");
3351 /* re-create replacement file for pass w/o backup (blank) */
3352 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3353 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
3354 /* perform replacement w/o backup
3355 * TODO: flags are not implemented
3357 SetLastError(0xdeadbeef);
3358 ret = pReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
3359 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3360 "ReplaceFileA: unexpected error %d\n", GetLastError());
3362 /* re-create replacement file for pass w/ backup (backup-file not existing) */
3363 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3364 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
3365 ret = DeleteFileA(backup);
3366 ok(ret, "DeleteFileA: error (backup) %d\n", GetLastError());
3367 /* perform replacement w/ backup (no pre-existing backup)
3368 * TODO: flags are not implemented
3370 SetLastError(0xdeadbeef);
3371 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3372 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3373 "ReplaceFileA: unexpected error %d\n", GetLastError());
3374 if (ret)
3375 removeBackup = TRUE;
3377 /* re-create replacement file for pass w/ no permissions to "replaced" */
3378 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3379 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
3380 ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_READONLY);
3381 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3382 "SetFileAttributesA: error setting to read only %d\n", GetLastError());
3383 /* perform replacement w/ backup (no permission to "replaced")
3384 * TODO: flags are not implemented
3386 SetLastError(0xdeadbeef);
3387 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3388 ok(ret != ERROR_UNABLE_TO_REMOVE_REPLACED, "ReplaceFileA: unexpected error %d\n", GetLastError());
3389 /* make sure that the replacement file still exists */
3390 hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
3391 ok(hReplacementFile != INVALID_HANDLE_VALUE ||
3392 broken(GetLastError() == ERROR_FILE_NOT_FOUND), /* win2k */
3393 "unexpected error, replacement file should still exist %d\n", GetLastError());
3394 CloseHandle(hReplacementFile);
3395 ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_NORMAL);
3396 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3397 "SetFileAttributesA: error setting to normal %d\n", GetLastError());
3399 /* replacement file still exists, make pass w/o "replaced" */
3400 ret = DeleteFileA(replaced);
3401 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3402 "DeleteFileA: error (replaced) %d\n", GetLastError());
3403 /* perform replacement w/ backup (no pre-existing backup or "replaced")
3404 * TODO: flags are not implemented
3406 SetLastError(0xdeadbeef);
3407 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3408 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
3409 GetLastError() == ERROR_ACCESS_DENIED),
3410 "ReplaceFileA: unexpected error %d\n", GetLastError());
3412 /* perform replacement w/o existing "replacement" file
3413 * TODO: flags are not implemented
3415 SetLastError(0xdeadbeef);
3416 ret = pReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
3417 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
3418 GetLastError() == ERROR_ACCESS_DENIED),
3419 "ReplaceFileA: unexpected error %d\n", GetLastError());
3420 DeleteFileA( replacement );
3423 * if the first round (w/ backup) worked then as long as there is no
3424 * failure then there is no need to check this round (w/ backup is the
3425 * more complete case)
3428 /* delete temporary files, replacement and replaced are already deleted */
3429 if (removeBackup)
3431 ret = DeleteFileA(backup);
3432 ok(ret ||
3433 broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */
3434 "DeleteFileA: error (backup) %d\n", GetLastError());
3439 * ReplaceFileW is a simpler case of ReplaceFileA, there is no
3440 * need to be as thorough.
3442 static void test_ReplaceFileW(void)
3444 WCHAR replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH];
3445 static const WCHAR prefix[] = {'p','f','x',0};
3446 WCHAR temp_path[MAX_PATH];
3447 DWORD ret;
3448 BOOL removeBackup = FALSE;
3450 if (!pReplaceFileW)
3452 win_skip("ReplaceFileW() is missing\n");
3453 return;
3456 ret = GetTempPathW(MAX_PATH, temp_path);
3457 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
3459 win_skip("GetTempPathW is not available\n");
3460 return;
3462 ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
3463 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
3465 ret = GetTempFileNameW(temp_path, prefix, 0, replaced);
3466 ok(ret != 0, "GetTempFileNameW error (replaced) %d\n", GetLastError());
3468 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3469 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3471 ret = GetTempFileNameW(temp_path, prefix, 0, backup);
3472 ok(ret != 0, "GetTempFileNameW error (backup) %d\n", GetLastError());
3474 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3475 ok(ret, "ReplaceFileW: error %d\n", GetLastError());
3477 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3478 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3479 ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0);
3480 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3481 "ReplaceFileW: error %d\n", GetLastError());
3483 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3484 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3485 ret = DeleteFileW(backup);
3486 ok(ret, "DeleteFileW: error (backup) %d\n", GetLastError());
3487 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3488 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3489 "ReplaceFileW: error %d\n", GetLastError());
3491 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3492 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3493 ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_READONLY);
3494 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3495 "SetFileAttributesW: error setting to read only %d\n", GetLastError());
3497 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3498 ok(ret != ERROR_UNABLE_TO_REMOVE_REPLACED,
3499 "ReplaceFileW: unexpected error %d\n", GetLastError());
3500 ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_NORMAL);
3501 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3502 "SetFileAttributesW: error setting to normal %d\n", GetLastError());
3503 if (ret)
3504 removeBackup = TRUE;
3506 ret = DeleteFileW(replaced);
3507 ok(ret, "DeleteFileW: error (replaced) %d\n", GetLastError());
3508 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3509 ok(!ret, "ReplaceFileW: error %d\n", GetLastError());
3511 ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0);
3512 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
3513 GetLastError() == ERROR_ACCESS_DENIED),
3514 "ReplaceFileW: unexpected error %d\n", GetLastError());
3515 DeleteFileW( replacement );
3517 if (removeBackup)
3519 ret = DeleteFileW(backup);
3520 ok(ret ||
3521 broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */
3522 "DeleteFileW: error (backup) %d\n", GetLastError());
3526 static void test_CreateFile(void)
3528 static const struct test_data
3530 DWORD disposition, access, error, clean_up;
3531 } td[] =
3533 /* 0 */ { 0, 0, ERROR_INVALID_PARAMETER, 0 },
3534 /* 1 */ { 0, GENERIC_READ, ERROR_INVALID_PARAMETER, 0 },
3535 /* 2 */ { 0, GENERIC_READ|GENERIC_WRITE, ERROR_INVALID_PARAMETER, 0 },
3536 /* 3 */ { CREATE_NEW, 0, ERROR_FILE_EXISTS, 1 },
3537 /* 4 */ { CREATE_NEW, 0, 0, 1 },
3538 /* 5 */ { CREATE_NEW, GENERIC_READ, 0, 1 },
3539 /* 6 */ { CREATE_NEW, GENERIC_WRITE, 0, 1 },
3540 /* 7 */ { CREATE_NEW, GENERIC_READ|GENERIC_WRITE, 0, 0 },
3541 /* 8 */ { CREATE_ALWAYS, 0, 0, 0 },
3542 /* 9 */ { CREATE_ALWAYS, GENERIC_READ, 0, 0 },
3543 /* 10*/ { CREATE_ALWAYS, GENERIC_WRITE, 0, 0 },
3544 /* 11*/ { CREATE_ALWAYS, GENERIC_READ|GENERIC_WRITE, 0, 1 },
3545 /* 12*/ { OPEN_EXISTING, 0, ERROR_FILE_NOT_FOUND, 0 },
3546 /* 13*/ { CREATE_ALWAYS, 0, 0, 0 },
3547 /* 14*/ { OPEN_EXISTING, 0, 0, 0 },
3548 /* 15*/ { OPEN_EXISTING, GENERIC_READ, 0, 0 },
3549 /* 16*/ { OPEN_EXISTING, GENERIC_WRITE, 0, 0 },
3550 /* 17*/ { OPEN_EXISTING, GENERIC_READ|GENERIC_WRITE, 0, 1 },
3551 /* 18*/ { OPEN_ALWAYS, 0, 0, 0 },
3552 /* 19*/ { OPEN_ALWAYS, GENERIC_READ, 0, 0 },
3553 /* 20*/ { OPEN_ALWAYS, GENERIC_WRITE, 0, 0 },
3554 /* 21*/ { OPEN_ALWAYS, GENERIC_READ|GENERIC_WRITE, 0, 0 },
3555 /* 22*/ { TRUNCATE_EXISTING, 0, ERROR_INVALID_PARAMETER, 0 },
3556 /* 23*/ { TRUNCATE_EXISTING, GENERIC_READ, ERROR_INVALID_PARAMETER, 0 },
3557 /* 24*/ { TRUNCATE_EXISTING, GENERIC_WRITE, 0, 0 },
3558 /* 25*/ { TRUNCATE_EXISTING, GENERIC_READ|GENERIC_WRITE, 0, 0 },
3559 /* 26*/ { TRUNCATE_EXISTING, FILE_WRITE_DATA, ERROR_INVALID_PARAMETER, 0 }
3561 char temp_path[MAX_PATH];
3562 char file_name[MAX_PATH];
3563 DWORD i, ret, written;
3564 HANDLE hfile;
3566 GetTempPathA(MAX_PATH, temp_path);
3567 GetTempFileNameA(temp_path, "tmp", 0, file_name);
3569 i = strlen(temp_path);
3570 if (i && temp_path[i - 1] == '\\') temp_path[i - 1] = 0;
3572 for (i = 0; i <= 5; i++)
3574 SetLastError(0xdeadbeef);
3575 hfile = CreateFileA(temp_path, GENERIC_READ, 0, NULL, i, 0, 0);
3576 ok(hfile == INVALID_HANDLE_VALUE, "CreateFile should fail\n");
3577 if (i == 0 || i == 5)
3579 /* FIXME: remove once Wine is fixed */
3580 if (i == 5) todo_wine
3581 ok(GetLastError() == ERROR_INVALID_PARAMETER, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i, GetLastError());
3582 else
3583 ok(GetLastError() == ERROR_INVALID_PARAMETER, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i, GetLastError());
3585 else
3587 /* FIXME: remove once Wine is fixed */
3588 if (i == 1) todo_wine
3589 ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
3590 else
3591 ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
3594 SetLastError(0xdeadbeef);
3595 hfile = CreateFileA(temp_path, GENERIC_WRITE, 0, NULL, i, 0, 0);
3596 ok(hfile == INVALID_HANDLE_VALUE, "CreateFile should fail\n");
3597 if (i == 0)
3598 ok(GetLastError() == ERROR_INVALID_PARAMETER, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i, GetLastError());
3599 else
3601 /* FIXME: remove once Wine is fixed */
3602 if (i == 1) todo_wine
3603 ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
3604 else
3605 ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
3609 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
3611 SetLastError(0xdeadbeef);
3612 hfile = CreateFileA(file_name, td[i].access, 0, NULL, td[i].disposition, 0, 0);
3613 if (!td[i].error)
3615 ok(hfile != INVALID_HANDLE_VALUE, "%d: CreateFile error %d\n", i, GetLastError());
3616 written = 0xdeadbeef;
3617 SetLastError(0xdeadbeef);
3618 ret = WriteFile(hfile, &td[i].error, sizeof(td[i].error), &written, NULL);
3619 if (td[i].access & GENERIC_WRITE)
3620 ok(ret, "%d: WriteFile error %d\n", i, GetLastError());
3621 else
3623 ok(!ret, "%d: WriteFile should fail\n", i);
3624 ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
3626 CloseHandle(hfile);
3628 else
3630 /* FIXME: remove the condition below once Wine is fixed */
3631 if (td[i].disposition == TRUNCATE_EXISTING && !(td[i].access & GENERIC_WRITE))
3633 todo_wine
3635 ok(hfile == INVALID_HANDLE_VALUE, "%d: CreateFile should fail\n", i);
3636 ok(GetLastError() == td[i].error, "%d: expected %d, got %d\n", i, td[i].error, GetLastError());
3638 CloseHandle(hfile);
3640 else
3642 ok(hfile == INVALID_HANDLE_VALUE, "%d: CreateFile should fail\n", i);
3643 ok(GetLastError() == td[i].error, "%d: expected %d, got %d\n", i, td[i].error, GetLastError());
3647 if (td[i].clean_up) DeleteFileA(file_name);
3650 DeleteFileA(file_name);
3653 static void test_GetFileInformationByHandleEx(void)
3655 int i;
3656 char tempPath[MAX_PATH], tempFileName[MAX_PATH], buffer[1024];
3657 BOOL ret;
3658 DWORD ret2;
3659 HANDLE directory;
3660 FILE_ID_BOTH_DIR_INFO *bothDirInfo;
3661 struct {
3662 FILE_INFO_BY_HANDLE_CLASS handleClass;
3663 void *ptr;
3664 DWORD size;
3665 DWORD errorCode;
3666 } checks[] = {
3667 {0xdeadbeef, NULL, 0, ERROR_INVALID_PARAMETER},
3668 {FileIdBothDirectoryInfo, NULL, 0, ERROR_BAD_LENGTH},
3669 {FileIdBothDirectoryInfo, NULL, sizeof(buffer), ERROR_NOACCESS},
3670 {FileIdBothDirectoryInfo, buffer, 0, ERROR_BAD_LENGTH}};
3672 if (!pGetFileInformationByHandleEx)
3674 win_skip("GetFileInformationByHandleEx is missing.\n");
3675 return;
3678 ret2 = GetTempPathA(sizeof(tempPath), tempPath);
3679 ok(ret2, "GetFileInformationByHandleEx: GetTempPathA failed, got error %u.\n", GetLastError());
3681 /* ensure the existence of a file in the temp folder */
3682 ret2 = GetTempFileNameA(tempPath, "abc", 0, tempFileName);
3683 ok(ret2, "GetFileInformationByHandleEx: GetTempFileNameA failed, got error %u.\n", GetLastError());
3684 ret2 = GetFileAttributesA(tempFileName);
3685 ok(ret2 != INVALID_FILE_ATTRIBUTES, "GetFileInformationByHandleEx: "
3686 "GetFileAttributesA failed to find the temp file, got error %u.\n", GetLastError());
3688 directory = CreateFileA(tempPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
3689 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
3690 ok(directory != INVALID_HANDLE_VALUE, "GetFileInformationByHandleEx: failed to open the temp folder, "
3691 "got error %u.\n", GetLastError());
3693 for (i = 0; i < sizeof(checks) / sizeof(checks[0]); i += 1)
3695 SetLastError(0xdeadbeef);
3696 ret = pGetFileInformationByHandleEx(directory, checks[i].handleClass, checks[i].ptr, checks[i].size);
3697 ok(!ret && GetLastError() == checks[i].errorCode, "GetFileInformationByHandleEx: expected error %u, "
3698 "got %u.\n", checks[i].errorCode, GetLastError());
3701 while (TRUE)
3703 memset(buffer, 0xff, sizeof(buffer));
3704 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer));
3705 if (!ret && GetLastError() == ERROR_NO_MORE_FILES)
3706 break;
3707 ok(ret, "GetFileInformationByHandleEx: failed to query for FileIdBothDirectoryInfo, got error %u.\n", GetLastError());
3708 if (!ret)
3709 break;
3710 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
3711 while (TRUE)
3713 ok(bothDirInfo->FileAttributes != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file attributes.\n");
3714 ok(bothDirInfo->FileId.u.LowPart != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file id.\n");
3715 ok(bothDirInfo->FileNameLength != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file name length.\n");
3716 if (!bothDirInfo->NextEntryOffset)
3717 break;
3718 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)(((char *)bothDirInfo) + bothDirInfo->NextEntryOffset);
3722 CloseHandle(directory);
3723 DeleteFileA(tempFileName);
3726 static void test_OpenFileById(void)
3728 char tempPath[MAX_PATH], tempFileName[MAX_PATH], buffer[256], tickCount[256];
3729 WCHAR tempFileNameW[MAX_PATH];
3730 BOOL ret, found;
3731 DWORD ret2, count, tempFileNameLen;
3732 HANDLE directory, handle, tempFile;
3733 FILE_ID_BOTH_DIR_INFO *bothDirInfo;
3734 FILE_ID_DESCRIPTOR fileIdDescr;
3736 if (!pGetFileInformationByHandleEx || !pOpenFileById)
3738 win_skip("GetFileInformationByHandleEx or OpenFileById is missing.\n");
3739 return;
3742 ret2 = GetTempPathA(sizeof(tempPath), tempPath);
3743 ok(ret2, "OpenFileById: GetTempPath failed, got error %u.\n", GetLastError());
3745 /* ensure the existence of a file in the temp folder */
3746 ret2 = GetTempFileNameA(tempPath, "abc", 0, tempFileName);
3747 ok(ret2, "OpenFileById: GetTempFileNameA failed, got error %u.\n", GetLastError());
3748 ret2 = GetFileAttributesA(tempFileName);
3749 ok(ret2 != INVALID_FILE_ATTRIBUTES,
3750 "OpenFileById: GetFileAttributesA failed to find the temp file, got error %u\n", GetLastError());
3752 ret2 = MultiByteToWideChar(CP_ACP, 0, tempFileName + strlen(tempPath), -1, tempFileNameW, sizeof(tempFileNameW)/sizeof(tempFileNameW[0]));
3753 ok(ret2, "OpenFileById: MultiByteToWideChar failed to convert tempFileName, got error %u.\n", GetLastError());
3754 tempFileNameLen = ret2 - 1;
3756 tempFile = CreateFileA(tempFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
3757 ok(tempFile != INVALID_HANDLE_VALUE, "OpenFileById: failed to create a temp file, "
3758 "got error %u.\n", GetLastError());
3759 ret2 = sprintf(tickCount, "%u", GetTickCount());
3760 ret = WriteFile(tempFile, tickCount, ret2, &count, NULL);
3761 ok(ret, "OpenFileById: WriteFile failed, got error %u.\n", GetLastError());
3762 CloseHandle(tempFile);
3764 directory = CreateFileA(tempPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
3765 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
3766 ok(directory != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the temp folder, "
3767 "got error %u.\n", GetLastError());
3769 /* get info about the temp folder itself */
3770 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
3771 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer));
3772 ok(ret, "OpenFileById: failed to query for FileIdBothDirectoryInfo, got error %u.\n", GetLastError());
3773 ok(bothDirInfo->FileNameLength == sizeof(WCHAR) && bothDirInfo->FileName[0] == '.',
3774 "OpenFileById: failed to return the temp folder at the first entry, got error %u.\n", GetLastError());
3776 /* open the temp folder itself */
3777 fileIdDescr.dwSize = sizeof(fileIdDescr);
3778 fileIdDescr.Type = FileIdType;
3779 U(fileIdDescr).FileId = bothDirInfo->FileId;
3780 handle = pOpenFileById(directory, &fileIdDescr, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0);
3781 todo_wine
3782 ok(handle != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the temp folder itself, got error %u.\n", GetLastError());
3783 CloseHandle(handle);
3785 /* find the temp file in the temp folder */
3786 found = FALSE;
3787 while (!found)
3789 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer));
3790 ok(ret, "OpenFileById: failed to query for FileIdBothDirectoryInfo, got error %u.\n", GetLastError());
3791 if (!ret)
3792 break;
3793 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
3794 while (TRUE)
3796 if (tempFileNameLen == bothDirInfo->FileNameLength / sizeof(WCHAR) &&
3797 memcmp(tempFileNameW, bothDirInfo->FileName, bothDirInfo->FileNameLength) == 0)
3799 found = TRUE;
3800 break;
3802 if (!bothDirInfo->NextEntryOffset)
3803 break;
3804 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)(((char *)bothDirInfo) + bothDirInfo->NextEntryOffset);
3807 ok(found, "OpenFileById: failed to find the temp file in the temp folder.\n");
3809 SetLastError(0xdeadbeef);
3810 handle = pOpenFileById(directory, NULL, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0);
3811 ok(handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER,
3812 "OpenFileById: expected ERROR_INVALID_PARAMETER, got error %u.\n", GetLastError());
3814 fileIdDescr.dwSize = sizeof(fileIdDescr);
3815 fileIdDescr.Type = FileIdType;
3816 U(fileIdDescr).FileId = bothDirInfo->FileId;
3817 handle = pOpenFileById(directory, &fileIdDescr, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0);
3818 ok(handle != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the file, got error %u.\n", GetLastError());
3820 ret = ReadFile(handle, buffer, sizeof(buffer), &count, NULL);
3821 buffer[count] = 0;
3822 ok(ret, "OpenFileById: ReadFile failed, got error %u.\n", GetLastError());
3823 ok(strcmp(tickCount, buffer) == 0, "OpenFileById: invalid contents of the temp file.\n");
3825 CloseHandle(handle);
3826 CloseHandle(directory);
3827 DeleteFileA(tempFileName);
3830 static void test_SetFileValidData(void)
3832 BOOL ret;
3833 HANDLE handle;
3834 DWORD error, count;
3835 char path[MAX_PATH], filename[MAX_PATH];
3836 TOKEN_PRIVILEGES privs;
3837 HANDLE token = NULL;
3839 if (!pSetFileValidData)
3841 win_skip("SetFileValidData is missing\n");
3842 return;
3844 GetTempPathA(sizeof(path), path);
3845 GetTempFileNameA(path, "tst", 0, filename);
3846 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
3847 WriteFile(handle, "test", sizeof("test") - 1, &count, NULL);
3848 CloseHandle(handle);
3850 SetLastError(0xdeadbeef);
3851 ret = pSetFileValidData(INVALID_HANDLE_VALUE, 0);
3852 error = GetLastError();
3853 ok(!ret, "SetFileValidData succeeded\n");
3854 ok(error == ERROR_INVALID_HANDLE, "got %u\n", error);
3856 SetLastError(0xdeadbeef);
3857 ret = pSetFileValidData(INVALID_HANDLE_VALUE, -1);
3858 error = GetLastError();
3859 ok(!ret, "SetFileValidData succeeded\n");
3860 ok(error == ERROR_INVALID_HANDLE, "got %u\n", error);
3862 /* file opened for reading */
3863 handle = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
3865 SetLastError(0xdeadbeef);
3866 ret = pSetFileValidData(handle, 0);
3867 ok(!ret, "SetFileValidData succeeded\n");
3868 error = GetLastError();
3869 ok(error == ERROR_ACCESS_DENIED, "got %u\n", error);
3871 SetLastError(0xdeadbeef);
3872 ret = pSetFileValidData(handle, -1);
3873 error = GetLastError();
3874 ok(!ret, "SetFileValidData succeeded\n");
3875 ok(error == ERROR_ACCESS_DENIED, "got %u\n", error);
3876 CloseHandle(handle);
3878 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
3880 SetLastError(0xdeadbeef);
3881 ret = pSetFileValidData(handle, 0);
3882 error = GetLastError();
3883 ok(!ret, "SetFileValidData succeeded\n");
3884 todo_wine ok(error == ERROR_PRIVILEGE_NOT_HELD, "got %u\n", error);
3885 CloseHandle(handle);
3887 privs.PrivilegeCount = 1;
3888 privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
3890 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token) ||
3891 !LookupPrivilegeValueA(NULL, SE_MANAGE_VOLUME_NAME, &privs.Privileges[0].Luid) ||
3892 !AdjustTokenPrivileges(token, FALSE, &privs, sizeof(privs), NULL, NULL) ||
3893 GetLastError() == ERROR_NOT_ALL_ASSIGNED)
3895 win_skip("cannot enable SE_MANAGE_VOLUME_NAME privilege\n");
3896 CloseHandle(token);
3897 DeleteFileA(filename);
3898 return;
3900 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
3902 SetLastError(0xdeadbeef);
3903 ret = pSetFileValidData(handle, 0);
3904 error = GetLastError();
3905 ok(!ret, "SetFileValidData succeeded\n");
3906 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3908 SetLastError(0xdeadbeef);
3909 ret = pSetFileValidData(handle, -1);
3910 error = GetLastError();
3911 ok(!ret, "SetFileValidData succeeded\n");
3912 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3914 SetLastError(0xdeadbeef);
3915 ret = pSetFileValidData(handle, 2);
3916 error = GetLastError();
3917 todo_wine ok(!ret, "SetFileValidData succeeded\n");
3918 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3920 ret = pSetFileValidData(handle, 4);
3921 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3923 SetLastError(0xdeadbeef);
3924 ret = pSetFileValidData(handle, 8);
3925 error = GetLastError();
3926 ok(!ret, "SetFileValidData succeeded\n");
3927 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3929 count = SetFilePointer(handle, 1024, NULL, FILE_END);
3930 ok(count != INVALID_SET_FILE_POINTER, "SetFilePointer failed %u\n", GetLastError());
3931 ret = SetEndOfFile(handle);
3932 ok(ret, "SetEndOfFile failed %u\n", GetLastError());
3934 SetLastError(0xdeadbeef);
3935 ret = pSetFileValidData(handle, 2);
3936 error = GetLastError();
3937 todo_wine ok(!ret, "SetFileValidData succeeded\n");
3938 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3940 ret = pSetFileValidData(handle, 4);
3941 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3943 ret = pSetFileValidData(handle, 8);
3944 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3946 ret = pSetFileValidData(handle, 4);
3947 error = GetLastError();
3948 todo_wine ok(!ret, "SetFileValidData succeeded\n");
3949 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3951 ret = pSetFileValidData(handle, 1024);
3952 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3954 ret = pSetFileValidData(handle, 2048);
3955 error = GetLastError();
3956 ok(!ret, "SetFileValidData succeeded\n");
3957 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3959 privs.Privileges[0].Attributes = 0;
3960 AdjustTokenPrivileges(token, FALSE, &privs, sizeof(privs), NULL, NULL);
3962 CloseHandle(token);
3963 CloseHandle(handle);
3964 DeleteFileA(filename);
3967 static void test_WriteFileGather(void)
3969 char temp_path[MAX_PATH], filename[MAX_PATH];
3970 HANDLE hfile, hiocp1, hiocp2;
3971 DWORD ret, size;
3972 ULONG_PTR key;
3973 FILE_SEGMENT_ELEMENT fse[2];
3974 OVERLAPPED ovl, *povl = NULL;
3975 SYSTEM_INFO si;
3976 LPVOID buf = NULL;
3978 ret = GetTempPathA( MAX_PATH, temp_path );
3979 ok( ret != 0, "GetTempPathA error %d\n", GetLastError() );
3980 ok( ret < MAX_PATH, "temp path should fit into MAX_PATH\n" );
3981 ret = GetTempFileNameA( temp_path, "wfg", 0, filename );
3982 ok( ret != 0, "GetTempFileNameA error %d\n", GetLastError() );
3984 hfile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
3985 FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL, 0 );
3986 ok( hfile != INVALID_HANDLE_VALUE, "CreateFile failed err %u\n", GetLastError() );
3987 if (hfile == INVALID_HANDLE_VALUE) return;
3989 hiocp1 = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 999, 0 );
3990 hiocp2 = CreateIoCompletionPort( hfile, hiocp1, 999, 0 );
3991 ok( hiocp2 != 0, "CreateIoCompletionPort failed err %u\n", GetLastError() );
3993 GetSystemInfo( &si );
3994 buf = VirtualAlloc( NULL, si.dwPageSize, MEM_COMMIT, PAGE_READWRITE );
3995 ok( buf != NULL, "VirtualAlloc failed err %u\n", GetLastError() );
3997 memset( &ovl, 0, sizeof(ovl) );
3998 memset( fse, 0, sizeof(fse) );
3999 fse[0].Buffer = buf;
4000 if (!WriteFileGather( hfile, fse, si.dwPageSize, NULL, &ovl ))
4001 ok( GetLastError() == ERROR_IO_PENDING, "WriteFileGather failed err %u\n", GetLastError() );
4003 ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 1000 );
4004 ok( ret, "GetQueuedCompletionStatus failed err %u\n", GetLastError());
4005 ok( povl == &ovl, "wrong ovl %p\n", povl );
4007 memset( &ovl, 0, sizeof(ovl) );
4008 memset( fse, 0, sizeof(fse) );
4009 fse[0].Buffer = buf;
4010 if (!ReadFileScatter( hfile, fse, si.dwPageSize, NULL, &ovl ))
4011 ok( GetLastError() == ERROR_IO_PENDING, "ReadFileScatter failed err %u\n", GetLastError() );
4013 ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 1000 );
4014 ok( ret, "GetQueuedCompletionStatus failed err %u\n", GetLastError());
4015 ok( povl == &ovl, "wrong ovl %p\n", povl );
4017 CloseHandle( hfile );
4018 CloseHandle( hiocp1 );
4019 CloseHandle( hiocp2 );
4020 VirtualFree( buf, 0, MEM_RELEASE );
4021 DeleteFileA( filename );
4024 static unsigned file_map_access(unsigned access)
4026 if (access & GENERIC_READ) access |= FILE_GENERIC_READ;
4027 if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE;
4028 if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE;
4029 if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS;
4030 return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
4033 static BOOL is_access_compatible(unsigned obj_access, unsigned desired_access)
4035 obj_access = file_map_access(obj_access);
4036 desired_access = file_map_access(desired_access);
4037 return (obj_access & desired_access) == desired_access;
4040 static void test_file_access(void)
4042 static const struct
4044 unsigned access, create_error, write_error, read_error;
4045 } td[] =
4047 { GENERIC_READ | GENERIC_WRITE, 0, 0, 0 },
4048 { GENERIC_WRITE, 0, 0, ERROR_ACCESS_DENIED },
4049 { GENERIC_READ, 0, ERROR_ACCESS_DENIED, 0 },
4050 { FILE_READ_DATA | FILE_WRITE_DATA, 0, 0, 0 },
4051 { FILE_WRITE_DATA, 0, 0, ERROR_ACCESS_DENIED },
4052 { FILE_READ_DATA, 0, ERROR_ACCESS_DENIED, 0 },
4053 { FILE_APPEND_DATA, 0, 0, ERROR_ACCESS_DENIED },
4054 { FILE_READ_DATA | FILE_APPEND_DATA, 0, 0, 0 },
4055 { FILE_WRITE_DATA | FILE_APPEND_DATA, 0, 0, ERROR_ACCESS_DENIED },
4056 { 0, 0, ERROR_ACCESS_DENIED, ERROR_ACCESS_DENIED },
4058 char path[MAX_PATH], fname[MAX_PATH];
4059 unsigned char buf[16];
4060 HANDLE hfile, hdup;
4061 DWORD i, j, ret, bytes;
4063 GetTempPathA(MAX_PATH, path);
4064 GetTempFileNameA(path, "foo", 0, fname);
4066 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
4068 SetLastError(0xdeadbeef);
4069 hfile = CreateFileA(fname, td[i].access, 0, NULL, CREATE_ALWAYS,
4070 FILE_FLAG_DELETE_ON_CLOSE, 0);
4071 if (td[i].create_error)
4073 ok(hfile == INVALID_HANDLE_VALUE, "%d: CreateFile should fail\n", i);
4074 ok(td[i].create_error == GetLastError(), "%d: expected %d, got %d\n", i, td[i].create_error, GetLastError());
4075 continue;
4077 else
4078 ok(hfile != INVALID_HANDLE_VALUE, "%d: CreateFile error %d\n", i, GetLastError());
4080 for (j = 0; j < sizeof(td)/sizeof(td[0]); j++)
4082 SetLastError(0xdeadbeef);
4083 ret = DuplicateHandle(GetCurrentProcess(), hfile, GetCurrentProcess(), &hdup,
4084 td[j].access, 0, 0);
4085 if (is_access_compatible(td[i].access, td[j].access))
4086 ok(ret, "DuplicateHandle(%#x => %#x) error %d\n", td[i].access, td[j].access, GetLastError());
4087 else
4089 /* FIXME: Remove once Wine is fixed */
4090 if ((td[j].access & (GENERIC_READ | GENERIC_WRITE)) ||
4091 (!(td[i].access & (GENERIC_WRITE | FILE_WRITE_DATA)) && (td[j].access & FILE_WRITE_DATA)) ||
4092 (!(td[i].access & (GENERIC_READ | FILE_READ_DATA)) && (td[j].access & FILE_READ_DATA)) ||
4093 (!(td[i].access & (GENERIC_WRITE)) && (td[j].access & FILE_APPEND_DATA)))
4095 todo_wine
4096 ok(!ret, "DuplicateHandle(%#x => %#x) should fail\n", td[i].access, td[j].access);
4097 todo_wine
4098 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
4100 else
4102 ok(!ret, "DuplicateHandle(%#x => %#x) should fail\n", td[i].access, td[j].access);
4103 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
4106 if (ret) CloseHandle(hdup);
4109 SetLastError(0xdeadbeef);
4110 bytes = 0xdeadbeef;
4111 ret = WriteFile(hfile, "\x5e\xa7", 2, &bytes, NULL);
4112 if (td[i].write_error)
4114 ok(!ret, "%d: WriteFile should fail\n", i);
4115 ok(td[i].write_error == GetLastError(), "%d: expected %d, got %d\n", i, td[i].write_error, GetLastError());
4116 ok(bytes == 0, "%d: expected 0, got %u\n", i, bytes);
4118 else
4120 ok(ret, "%d: WriteFile error %d\n", i, GetLastError());
4121 ok(bytes == 2, "%d: expected 2, got %u\n", i, bytes);
4124 SetLastError(0xdeadbeef);
4125 ret = SetFilePointer(hfile, 0, NULL, FILE_BEGIN);
4126 ok(ret != INVALID_SET_FILE_POINTER, "SetFilePointer error %d\n", GetLastError());
4128 SetLastError(0xdeadbeef);
4129 bytes = 0xdeadbeef;
4130 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, NULL);
4131 if (td[i].read_error)
4133 ok(!ret, "%d: ReadFile should fail\n", i);
4134 ok(td[i].read_error == GetLastError(), "%d: expected %d, got %d\n", i, td[i].read_error, GetLastError());
4135 ok(bytes == 0, "%d: expected 0, got %u\n", i, bytes);
4137 else
4139 ok(ret, "%d: ReadFile error %d\n", i, GetLastError());
4140 if (td[i].write_error)
4141 ok(bytes == 0, "%d: expected 0, got %u\n", i, bytes);
4142 else
4144 ok(bytes == 2, "%d: expected 2, got %u\n", i, bytes);
4145 ok(buf[0] == 0x5e && buf[1] == 0xa7, "%d: expected 5ea7, got %02x%02x\n", i, buf[0], buf[1]);
4149 CloseHandle(hfile);
4153 START_TEST(file)
4155 InitFunctionPointers();
4157 test__hread( );
4158 test__hwrite( );
4159 test__lclose( );
4160 test__lcreat( );
4161 test__llseek( );
4162 test__llopen( );
4163 test__lread( );
4164 test__lwrite( );
4165 test_GetTempFileNameA();
4166 test_CopyFileA();
4167 test_CopyFileW();
4168 test_CopyFile2();
4169 test_CreateFile();
4170 test_CreateFileA();
4171 test_CreateFileW();
4172 test_CreateFile2();
4173 test_DeleteFileA();
4174 test_DeleteFileW();
4175 test_MoveFileA();
4176 test_MoveFileW();
4177 test_FindFirstFileA();
4178 test_FindNextFileA();
4179 test_FindFirstFileExA(0, 0);
4180 test_FindFirstFileExA(0, FIND_FIRST_EX_LARGE_FETCH);
4181 /* FindExLimitToDirectories is ignored if the file system doesn't support directory filtering */
4182 test_FindFirstFileExA(FindExSearchLimitToDirectories, 0);
4183 test_FindFirstFileExA(FindExSearchLimitToDirectories, FIND_FIRST_EX_LARGE_FETCH);
4184 test_LockFile();
4185 test_file_sharing();
4186 test_offset_in_overlapped_structure();
4187 test_MapFile();
4188 test_GetFileType();
4189 test_async_file_errors();
4190 test_read_write();
4191 test_OpenFile();
4192 test_overlapped();
4193 test_RemoveDirectory();
4194 test_ReplaceFileA();
4195 test_ReplaceFileW();
4196 test_GetFileInformationByHandleEx();
4197 test_OpenFileById();
4198 test_SetFileValidData();
4199 test_WriteFileGather();
4200 test_file_access();