ntdll: Ensure force_exec_prot is also used for views with write watch permissions.
[wine.git] / dlls / kernel32 / tests / file.c
blob0973efe2c9b0d9df3a75bf0db401cb5dd60cf6c0
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);
2612 else
2614 ok(ret, "Fetching fourth file failed\n");
2615 ok(CHECK_NAME(search_results.cFileName), "Invalid fourth entry - %s\n", search_results.cFileName);
2617 ok(FindNextFileA(handle, &search_results), "Fetching fifth file failed\n");
2618 ok(CHECK_NAME(search_results.cFileName), "Invalid fifth entry - %s\n", search_results.cFileName);
2620 ok(FindNextFileA(handle, &search_results) == FALSE, "Fetching sixth file should fail\n");
2623 #undef CHECK_NAME
2625 FindClose( handle );
2627 /* Most Windows systems seem to ignore the FIND_FIRST_EX_CASE_SENSITIVE flag. Unofficial documentation
2628 * suggests that there are registry keys and that it might depend on the used filesystem. */
2629 SetLastError(0xdeadbeef);
2630 handle = pFindFirstFileExA("TEST-DIR\\*", FindExInfoStandard, &search_results, search_ops, NULL, flags);
2631 if (flags & FIND_FIRST_EX_CASE_SENSITIVE)
2633 ok(handle != INVALID_HANDLE_VALUE || GetLastError() == ERROR_PATH_NOT_FOUND,
2634 "Unexpected error %x, expected valid handle or ERROR_PATH_NOT_FOUND\n", GetLastError());
2635 trace("FindFirstFileExA flag FIND_FIRST_EX_CASE_SENSITIVE is %signored\n",
2636 (handle == INVALID_HANDLE_VALUE) ? "not " : "");
2638 else
2639 ok(handle != INVALID_HANDLE_VALUE, "Unexpected error %x, expected valid handle\n", GetLastError());
2640 if (handle != INVALID_HANDLE_VALUE)
2641 FindClose( handle );
2643 cleanup:
2644 DeleteFileA("test-dir\\file1");
2645 DeleteFileA("test-dir\\file2");
2646 RemoveDirectoryA("test-dir\\dir1");
2647 RemoveDirectoryA("test-dir");
2650 static int test_Mapfile_createtemp(HANDLE *handle)
2652 SetFileAttributesA(filename,FILE_ATTRIBUTE_NORMAL);
2653 DeleteFileA(filename);
2654 *handle = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, 0, 0,
2655 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2656 if (*handle != INVALID_HANDLE_VALUE) {
2658 return 1;
2661 return 0;
2664 static void test_MapFile(void)
2666 HANDLE handle;
2667 HANDLE hmap;
2669 ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
2671 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 0x1000, "named_file_map" );
2672 ok( hmap != NULL, "mapping should work, I named it!\n" );
2674 ok( CloseHandle( hmap ), "can't close mapping handle\n");
2676 /* We have to close file before we try new stuff with mapping again.
2677 Else we would always succeed on XP or block descriptors on 95. */
2678 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
2679 ok( hmap != NULL, "We should still be able to map!\n" );
2680 ok( CloseHandle( hmap ), "can't close mapping handle\n");
2681 ok( CloseHandle( handle ), "can't close file handle\n");
2682 handle = NULL;
2684 ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
2686 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
2687 ok( hmap == NULL, "mapped zero size file\n");
2688 ok( GetLastError() == ERROR_FILE_INVALID, "not ERROR_FILE_INVALID\n");
2690 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0x80000000, 0, NULL );
2691 ok( hmap == NULL || broken(hmap != NULL) /* NT4 */, "mapping should fail\n");
2692 /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */
2693 if ( hmap )
2694 CloseHandle( hmap );
2696 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0x80000000, 0x10000, NULL );
2697 ok( hmap == NULL || broken(hmap != NULL) /* NT4 */, "mapping should fail\n");
2698 /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */
2699 if ( hmap )
2700 CloseHandle( hmap );
2702 /* On XP you can now map again, on Win 95 you cannot. */
2704 ok( CloseHandle( handle ), "can't close file handle\n");
2705 ok( DeleteFileA( filename ), "DeleteFile failed after map\n" );
2708 static void test_GetFileType(void)
2710 DWORD type, type2;
2711 HANDLE h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2712 ok( h != INVALID_HANDLE_VALUE, "open %s failed\n", filename );
2713 type = GetFileType(h);
2714 ok( type == FILE_TYPE_DISK, "expected type disk got %d\n", type );
2715 CloseHandle( h );
2716 h = CreateFileA( "nul", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2717 ok( h != INVALID_HANDLE_VALUE, "open nul failed\n" );
2718 type = GetFileType(h);
2719 ok( type == FILE_TYPE_CHAR, "expected type char for nul got %d\n", type );
2720 CloseHandle( h );
2721 DeleteFileA( filename );
2722 h = GetStdHandle( STD_OUTPUT_HANDLE );
2723 ok( h != INVALID_HANDLE_VALUE, "GetStdHandle failed\n" );
2724 type = GetFileType( (HANDLE)STD_OUTPUT_HANDLE );
2725 type2 = GetFileType( h );
2726 ok(type == type2, "expected type %d for STD_OUTPUT_HANDLE got %d\n", type2, type);
2729 static int completion_count;
2731 static void CALLBACK FileIOComplete(DWORD dwError, DWORD dwBytes, LPOVERLAPPED ovl)
2733 /* printf("(%ld, %ld, %p { %ld, %ld, %ld, %ld, %p })\n", dwError, dwBytes, ovl, ovl->Internal, ovl->InternalHigh, ovl->Offset, ovl->OffsetHigh, ovl->hEvent);*/
2734 ReleaseSemaphore(ovl->hEvent, 1, NULL);
2735 completion_count++;
2738 static void test_async_file_errors(void)
2740 char szFile[MAX_PATH];
2741 HANDLE hSem = CreateSemaphoreW(NULL, 1, 1, NULL);
2742 HANDLE hFile;
2743 LPVOID lpBuffer = HeapAlloc(GetProcessHeap(), 0, 4096);
2744 OVERLAPPED ovl;
2745 S(U(ovl)).Offset = 0;
2746 S(U(ovl)).OffsetHigh = 0;
2747 ovl.hEvent = hSem;
2748 completion_count = 0;
2749 szFile[0] = '\0';
2750 GetWindowsDirectoryA(szFile, sizeof(szFile)/sizeof(szFile[0])-1-strlen("\\win.ini"));
2751 strcat(szFile, "\\win.ini");
2752 hFile = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
2753 NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
2754 if (hFile == INVALID_HANDLE_VALUE) /* win9x doesn't like FILE_SHARE_DELETE */
2755 hFile = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
2756 NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
2757 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA(%s ...) failed\n", szFile);
2758 while (TRUE)
2760 BOOL res;
2761 DWORD count;
2762 while (WaitForSingleObjectEx(hSem, INFINITE, TRUE) == WAIT_IO_COMPLETION)
2764 res = ReadFileEx(hFile, lpBuffer, 4096, &ovl, FileIOComplete);
2765 /*printf("Offset = %ld, result = %s\n", ovl.Offset, res ? "TRUE" : "FALSE");*/
2766 if (!res)
2767 break;
2768 if (!GetOverlappedResult(hFile, &ovl, &count, FALSE))
2769 break;
2770 S(U(ovl)).Offset += count;
2771 /* i/o completion routine only called if ReadFileEx returned success.
2772 * we only care about violations of this rule so undo what should have
2773 * been done */
2774 completion_count--;
2776 ok(completion_count == 0, "completion routine should only be called when ReadFileEx succeeds (this rule was violated %d times)\n", completion_count);
2777 /*printf("Error = %ld\n", GetLastError());*/
2778 HeapFree(GetProcessHeap(), 0, lpBuffer);
2781 static BOOL user_apc_ran;
2782 static void CALLBACK user_apc(ULONG_PTR param)
2784 user_apc_ran = TRUE;
2787 static void test_read_write(void)
2789 DWORD bytes, ret, old_prot;
2790 HANDLE hFile;
2791 char temp_path[MAX_PATH];
2792 char filename[MAX_PATH];
2793 char *mem;
2794 static const char prefix[] = "pfx";
2796 ret = GetTempPathA(MAX_PATH, temp_path);
2797 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
2798 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
2800 ret = GetTempFileNameA(temp_path, prefix, 0, filename);
2801 ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
2803 hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
2804 CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
2805 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
2807 user_apc_ran = FALSE;
2808 if (pQueueUserAPC) {
2809 trace("Queueing an user APC\n"); /* verify the file is non alerable */
2810 ret = pQueueUserAPC(&user_apc, GetCurrentThread(), 0);
2811 ok(ret, "QueueUserAPC failed: %d\n", GetLastError());
2814 SetLastError(12345678);
2815 bytes = 12345678;
2816 ret = WriteFile(hFile, NULL, 0, &bytes, NULL);
2817 ok(ret && GetLastError() == 12345678,
2818 "ret = %d, error %d\n", ret, GetLastError());
2819 ok(!bytes, "bytes = %d\n", bytes);
2821 SetLastError(12345678);
2822 bytes = 12345678;
2823 ret = WriteFile(hFile, NULL, 10, &bytes, NULL);
2824 ok((!ret && GetLastError() == ERROR_INVALID_USER_BUFFER) || /* Win2k */
2825 (ret && GetLastError() == 12345678), /* Win9x */
2826 "ret = %d, error %d\n", ret, GetLastError());
2827 ok(!bytes || /* Win2k */
2828 bytes == 10, /* Win9x */
2829 "bytes = %d\n", bytes);
2831 /* make sure the file contains data */
2832 WriteFile(hFile, "this is the test data", 21, &bytes, NULL);
2833 SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
2835 SetLastError(12345678);
2836 bytes = 12345678;
2837 ret = ReadFile(hFile, NULL, 0, &bytes, NULL);
2838 ok(ret && GetLastError() == 12345678,
2839 "ret = %d, error %d\n", ret, GetLastError());
2840 ok(!bytes, "bytes = %d\n", bytes);
2842 SetLastError(12345678);
2843 bytes = 12345678;
2844 ret = ReadFile(hFile, NULL, 10, &bytes, NULL);
2845 ok(!ret && (GetLastError() == ERROR_NOACCESS || /* Win2k */
2846 GetLastError() == ERROR_INVALID_PARAMETER), /* Win9x */
2847 "ret = %d, error %d\n", ret, GetLastError());
2848 ok(!bytes, "bytes = %d\n", bytes);
2850 ok(user_apc_ran == FALSE, "UserAPC ran, file using alertable io mode\n");
2851 if (pQueueUserAPC)
2852 SleepEx(0, TRUE); /* get rid of apc */
2854 /* test passing protected memory as buffer */
2856 mem = VirtualAlloc( NULL, 0x4000, MEM_COMMIT, PAGE_READWRITE );
2857 ok( mem != NULL, "failed to allocate virtual mem error %u\n", GetLastError() );
2859 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
2860 ok( ret, "WriteFile failed error %u\n", GetLastError() );
2861 ok( bytes == 0x4000, "only wrote %x bytes\n", bytes );
2863 ret = VirtualProtect( mem + 0x2000, 0x2000, PAGE_NOACCESS, &old_prot );
2864 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2866 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
2867 ok( !ret, "WriteFile succeeded\n" );
2868 ok( GetLastError() == ERROR_INVALID_USER_BUFFER ||
2869 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2870 "wrong error %u\n", GetLastError() );
2871 ok( bytes == 0, "wrote %x bytes\n", bytes );
2873 ret = WriteFile( (HANDLE)0xdead, mem, 0x4000, &bytes, NULL );
2874 ok( !ret, "WriteFile succeeded\n" );
2875 ok( GetLastError() == ERROR_INVALID_HANDLE || /* handle is checked before buffer on NT */
2876 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2877 "wrong error %u\n", GetLastError() );
2878 ok( bytes == 0, "wrote %x bytes\n", bytes );
2880 ret = VirtualProtect( mem, 0x2000, PAGE_NOACCESS, &old_prot );
2881 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2883 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
2884 ok( !ret, "WriteFile succeeded\n" );
2885 ok( GetLastError() == ERROR_INVALID_USER_BUFFER ||
2886 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2887 "wrong error %u\n", GetLastError() );
2888 ok( bytes == 0, "wrote %x bytes\n", bytes );
2890 SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
2892 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2893 ok( !ret, "ReadFile succeeded\n" );
2894 ok( GetLastError() == ERROR_NOACCESS ||
2895 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2896 "wrong error %u\n", GetLastError() );
2897 ok( bytes == 0, "read %x bytes\n", bytes );
2899 ret = VirtualProtect( mem, 0x2000, PAGE_READONLY, &old_prot );
2900 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2902 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2903 ok( !ret, "ReadFile succeeded\n" );
2904 ok( GetLastError() == ERROR_NOACCESS ||
2905 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2906 "wrong error %u\n", GetLastError() );
2907 ok( bytes == 0, "read %x bytes\n", bytes );
2909 ret = VirtualProtect( mem, 0x2000, PAGE_READWRITE, &old_prot );
2910 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2912 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2913 ok( !ret, "ReadFile succeeded\n" );
2914 ok( GetLastError() == ERROR_NOACCESS ||
2915 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2916 "wrong error %u\n", GetLastError() );
2917 ok( bytes == 0, "read %x bytes\n", bytes );
2919 SetFilePointer( hFile, 0x1234, NULL, FILE_BEGIN );
2920 SetEndOfFile( hFile );
2921 SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
2923 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2924 ok( !ret, "ReadFile succeeded\n" );
2925 ok( GetLastError() == ERROR_NOACCESS ||
2926 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2927 "wrong error %u\n", GetLastError() );
2928 ok( bytes == 0, "read %x bytes\n", bytes );
2930 ret = ReadFile( hFile, mem, 0x2000, &bytes, NULL );
2931 ok( ret, "ReadFile failed error %u\n", GetLastError() );
2932 ok( bytes == 0x1234, "read %x bytes\n", bytes );
2934 ret = ReadFile( hFile, NULL, 1, &bytes, NULL );
2935 ok( !ret, "ReadFile succeeded\n" );
2936 ok( GetLastError() == ERROR_NOACCESS ||
2937 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2938 "wrong error %u\n", GetLastError() );
2939 ok( bytes == 0, "read %x bytes\n", bytes );
2941 VirtualFree( mem, 0, MEM_FREE );
2943 ret = CloseHandle(hFile);
2944 ok( ret, "CloseHandle: error %d\n", GetLastError());
2945 ret = DeleteFileA(filename);
2946 ok( ret, "DeleteFileA: error %d\n", GetLastError());
2949 static void test_OpenFile(void)
2951 HFILE hFile;
2952 OFSTRUCT ofs;
2953 BOOL ret;
2954 DWORD retval;
2956 static const char file[] = "regedit.exe";
2957 static const char foo[] = ".\\foo-bar-foo.baz";
2958 static const char *foo_too_long = ".\\foo-bar-foo.baz+++++++++++++++"
2959 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2960 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2961 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2962 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2963 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
2964 char buff[MAX_PATH];
2965 char buff_long[4*MAX_PATH];
2966 char filled_0xA5[OFS_MAXPATHNAME];
2967 char *p;
2968 UINT length;
2970 /* Check for existing file */
2971 if (!pGetSystemWindowsDirectoryA)
2972 length = GetWindowsDirectoryA(buff, MAX_PATH);
2973 else
2974 length = pGetSystemWindowsDirectoryA(buff, MAX_PATH);
2976 if (length + sizeof(file) < MAX_PATH)
2978 p = buff + strlen(buff);
2979 if (p > buff && p[-1] != '\\') *p++ = '\\';
2980 strcpy( p, file );
2981 memset(&ofs, 0xA5, sizeof(ofs));
2982 SetLastError(0xfaceabee);
2984 hFile = OpenFile(buff, &ofs, OF_EXIST);
2985 ok( hFile == TRUE, "%s not found : %d\n", buff, GetLastError() );
2986 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
2987 "GetLastError() returns %d\n", GetLastError() );
2988 ok( ofs.cBytes == sizeof(ofs), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2989 ok( ofs.nErrCode == ERROR_SUCCESS, "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2990 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2991 "OpenFile returned '%s', but was expected to return '%s' or string filled with 0xA5\n",
2992 ofs.szPathName, buff );
2995 memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
2996 length = GetCurrentDirectoryA(MAX_PATH, buff);
2998 /* Check for nonexistent file */
2999 if (length + sizeof(foo) < MAX_PATH)
3001 p = buff + strlen(buff);
3002 if (p > buff && p[-1] != '\\') *p++ = '\\';
3003 strcpy( p, foo + 2 );
3004 memset(&ofs, 0xA5, sizeof(ofs));
3005 SetLastError(0xfaceabee);
3007 hFile = OpenFile(foo, &ofs, OF_EXIST);
3008 ok( hFile == HFILE_ERROR, "hFile != HFILE_ERROR : %d\n", GetLastError());
3009 ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError() returns %d\n", GetLastError() );
3010 todo_wine
3011 ok( ofs.cBytes == 0xA5, "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3012 ok( ofs.nErrCode == ERROR_FILE_NOT_FOUND, "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3013 ok( lstrcmpiA(ofs.szPathName, buff) == 0 || strncmp(ofs.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0,
3014 "OpenFile returned '%s', but was expected to return '%s' or string filled with 0xA5\n",
3015 ofs.szPathName, buff );
3018 length = GetCurrentDirectoryA(MAX_PATH, buff_long);
3019 length += lstrlenA(foo_too_long + 1);
3021 /* Check for nonexistent file with too long filename */
3022 if (length >= OFS_MAXPATHNAME && length < sizeof(buff_long))
3024 lstrcatA(buff_long, foo_too_long + 1); /* Avoid '.' during concatenation */
3025 memset(&ofs, 0xA5, sizeof(ofs));
3026 SetLastError(0xfaceabee);
3028 hFile = OpenFile(foo_too_long, &ofs, OF_EXIST);
3029 ok( hFile == HFILE_ERROR, "hFile != HFILE_ERROR : %d\n", GetLastError());
3030 ok( GetLastError() == ERROR_INVALID_DATA || GetLastError() == ERROR_FILENAME_EXCED_RANGE,
3031 "GetLastError() returns %d\n", GetLastError() );
3032 todo_wine
3033 ok( ofs.cBytes == 0xA5, "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3034 ok( ofs.nErrCode == ERROR_INVALID_DATA || ofs.nErrCode == ERROR_FILENAME_EXCED_RANGE,
3035 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3036 ok( strncmp(ofs.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0,
3037 "OpenFile returned '%s', but was expected to return string filled with 0xA5\n",
3038 ofs.szPathName );
3041 length = GetCurrentDirectoryA(MAX_PATH, buff) + sizeof(filename);
3043 if (length >= MAX_PATH)
3045 trace("Buffer too small, requested length = %d, but MAX_PATH = %d. Skipping test.\n", length, MAX_PATH);
3046 return;
3048 p = buff + strlen(buff);
3049 if (p > buff && p[-1] != '\\') *p++ = '\\';
3050 strcpy( p, filename );
3052 memset(&ofs, 0xA5, sizeof(ofs));
3053 SetLastError(0xfaceabee);
3054 /* Create an empty file */
3055 hFile = OpenFile(filename, &ofs, OF_CREATE);
3056 ok( hFile != HFILE_ERROR, "OpenFile failed to create nonexistent file\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 ret = _lclose(hFile);
3063 ok( !ret, "_lclose() returns %d\n", ret );
3064 retval = GetFileAttributesA(filename);
3065 ok( retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %d\n", GetLastError() );
3067 memset(&ofs, 0xA5, sizeof(ofs));
3068 SetLastError(0xfaceabee);
3069 /* Check various opening options: */
3070 /* for reading only, */
3071 hFile = OpenFile(filename, &ofs, OF_READ);
3072 ok( hFile != HFILE_ERROR, "OpenFile failed on read\n" );
3073 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3074 "GetLastError() returns %d\n", GetLastError() );
3075 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3076 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3077 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3078 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
3079 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
3080 ret = _lclose(hFile);
3081 ok( !ret, "_lclose() returns %d\n", ret );
3083 memset(&ofs, 0xA5, sizeof(ofs));
3084 SetLastError(0xfaceabee);
3085 /* for writing only, */
3086 hFile = OpenFile(filename, &ofs, OF_WRITE);
3087 ok( hFile != HFILE_ERROR, "OpenFile failed on write\n" );
3088 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3089 "GetLastError() returns %d\n", GetLastError() );
3090 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3091 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3092 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3093 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
3094 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
3095 ret = _lclose(hFile);
3096 ok( !ret, "_lclose() returns %d\n", ret );
3098 memset(&ofs, 0xA5, sizeof(ofs));
3099 SetLastError(0xfaceabee);
3100 /* for reading and writing, */
3101 hFile = OpenFile(filename, &ofs, OF_READWRITE);
3102 ok( hFile != HFILE_ERROR, "OpenFile failed on read/write\n" );
3103 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3104 "GetLastError() returns %d\n", GetLastError() );
3105 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3106 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3107 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3108 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
3109 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
3110 ret = _lclose(hFile);
3111 ok( !ret, "_lclose() returns %d\n", ret );
3113 memset(&ofs, 0xA5, sizeof(ofs));
3114 SetLastError(0xfaceabee);
3115 /* for checking file presence. */
3116 hFile = OpenFile(filename, &ofs, OF_EXIST);
3117 ok( hFile == 1, "OpenFile failed on finding our created file\n" );
3118 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3119 "GetLastError() returns %d\n", GetLastError() );
3120 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3121 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3122 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3123 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
3124 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
3126 memset(&ofs, 0xA5, sizeof(ofs));
3127 SetLastError(0xfaceabee);
3128 /* Delete the file and make sure it doesn't exist anymore */
3129 hFile = OpenFile(filename, &ofs, OF_DELETE);
3130 ok( hFile == 1, "OpenFile failed on delete (%d)\n", hFile );
3131 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3132 "GetLastError() returns %d\n", GetLastError() );
3133 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3134 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3135 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3136 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
3137 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
3139 retval = GetFileAttributesA(filename);
3140 ok( retval == INVALID_FILE_ATTRIBUTES, "GetFileAttributesA succeeded on deleted file\n" );
3143 static void test_overlapped(void)
3145 OVERLAPPED ov;
3146 DWORD r, result;
3148 /* GetOverlappedResult crashes if the 2nd or 3rd param are NULL */
3149 if (0) /* tested: WinXP */
3151 GetOverlappedResult(0, NULL, &result, FALSE);
3152 GetOverlappedResult(0, &ov, NULL, FALSE);
3153 GetOverlappedResult(0, NULL, NULL, FALSE);
3156 memset( &ov, 0, sizeof ov );
3157 result = 1;
3158 r = GetOverlappedResult(0, &ov, &result, 0);
3159 if (r)
3160 ok( result == 0, "wrong result %u\n", result );
3161 else /* win9x */
3162 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
3164 result = 0;
3165 ov.Internal = 0;
3166 ov.InternalHigh = 0xabcd;
3167 r = GetOverlappedResult(0, &ov, &result, 0);
3168 if (r)
3169 ok( result == 0xabcd, "wrong result %u\n", result );
3170 else /* win9x */
3171 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
3173 SetLastError( 0xb00 );
3174 result = 0;
3175 ov.Internal = STATUS_INVALID_HANDLE;
3176 ov.InternalHigh = 0xabcd;
3177 r = GetOverlappedResult(0, &ov, &result, 0);
3178 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
3179 ok( r == FALSE, "should return false\n");
3180 ok( result == 0xabcd || result == 0 /* win9x */, "wrong result %u\n", result );
3182 SetLastError( 0xb00 );
3183 result = 0;
3184 ov.Internal = STATUS_PENDING;
3185 ov.InternalHigh = 0xabcd;
3186 r = GetOverlappedResult(0, &ov, &result, 0);
3187 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
3188 "wrong error %u\n", GetLastError() );
3189 ok( r == FALSE, "should return false\n");
3190 ok( result == 0, "wrong result %u\n", result );
3192 SetLastError( 0xb00 );
3193 ov.hEvent = CreateEventW( NULL, 1, 1, NULL );
3194 ov.Internal = STATUS_PENDING;
3195 ov.InternalHigh = 0xabcd;
3196 r = GetOverlappedResult(0, &ov, &result, 0);
3197 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
3198 "wrong error %u\n", GetLastError() );
3199 ok( r == FALSE, "should return false\n");
3201 ResetEvent( ov.hEvent );
3203 SetLastError( 0xb00 );
3204 ov.Internal = STATUS_PENDING;
3205 ov.InternalHigh = 0;
3206 r = GetOverlappedResult(0, &ov, &result, 0);
3207 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
3208 "wrong error %u\n", GetLastError() );
3209 ok( r == FALSE, "should return false\n");
3211 r = CloseHandle( ov.hEvent );
3212 ok( r == TRUE, "close handle failed\n");
3215 static void test_RemoveDirectory(void)
3217 int rc;
3218 char directory[] = "removeme";
3220 rc = CreateDirectoryA(directory, NULL);
3221 ok( rc, "Createdirectory failed, gle=%d\n", GetLastError() );
3223 rc = SetCurrentDirectoryA(directory);
3224 ok( rc, "SetCurrentDirectory failed, gle=%d\n", GetLastError() );
3226 rc = RemoveDirectoryA(".");
3227 if (!rc)
3229 rc = SetCurrentDirectoryA("..");
3230 ok( rc, "SetCurrentDirectory failed, gle=%d\n", GetLastError() );
3232 rc = RemoveDirectoryA(directory);
3233 ok( rc, "RemoveDirectory failed, gle=%d\n", GetLastError() );
3237 static BOOL check_file_time( const FILETIME *ft1, const FILETIME *ft2, UINT tolerance )
3239 ULONGLONG t1 = ((ULONGLONG)ft1->dwHighDateTime << 32) | ft1->dwLowDateTime;
3240 ULONGLONG t2 = ((ULONGLONG)ft2->dwHighDateTime << 32) | ft2->dwLowDateTime;
3241 return abs(t1 - t2) <= tolerance;
3244 static void test_ReplaceFileA(void)
3246 char replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH];
3247 HANDLE hReplacedFile, hReplacementFile, hBackupFile;
3248 static const char replacedData[] = "file-to-replace";
3249 static const char replacementData[] = "new-file";
3250 static const char backupData[] = "backup-file";
3251 FILETIME ftReplaced, ftReplacement, ftBackup;
3252 static const char prefix[] = "pfx";
3253 char temp_path[MAX_PATH];
3254 DWORD ret;
3255 BOOL retok, removeBackup = FALSE;
3257 if (!pReplaceFileA)
3259 win_skip("ReplaceFileA() is missing\n");
3260 return;
3263 ret = GetTempPathA(MAX_PATH, temp_path);
3264 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
3265 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
3267 ret = GetTempFileNameA(temp_path, prefix, 0, replaced);
3268 ok(ret != 0, "GetTempFileNameA error (replaced) %d\n", GetLastError());
3270 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3271 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
3273 ret = GetTempFileNameA(temp_path, prefix, 0, backup);
3274 ok(ret != 0, "GetTempFileNameA error (backup) %d\n", GetLastError());
3276 /* place predictable data in the file to be replaced */
3277 hReplacedFile = CreateFileA(replaced, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
3278 ok(hReplacedFile != INVALID_HANDLE_VALUE,
3279 "failed to open replaced file\n");
3280 retok = WriteFile(hReplacedFile, replacedData, sizeof(replacedData), &ret, NULL );
3281 ok( retok && ret == sizeof(replacedData),
3282 "WriteFile error (replaced) %d\n", GetLastError());
3283 ok(GetFileSize(hReplacedFile, NULL) == sizeof(replacedData),
3284 "replaced file has wrong size\n");
3285 /* place predictable data in the file to be the replacement */
3286 hReplacementFile = CreateFileA(replacement, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
3287 ok(hReplacementFile != INVALID_HANDLE_VALUE,
3288 "failed to open replacement file\n");
3289 retok = WriteFile(hReplacementFile, replacementData, sizeof(replacementData), &ret, NULL );
3290 ok( retok && ret == sizeof(replacementData),
3291 "WriteFile error (replacement) %d\n", GetLastError());
3292 ok(GetFileSize(hReplacementFile, NULL) == sizeof(replacementData),
3293 "replacement file has wrong size\n");
3294 /* place predictable data in the backup file (to be over-written) */
3295 hBackupFile = CreateFileA(backup, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
3296 ok(hBackupFile != INVALID_HANDLE_VALUE,
3297 "failed to open backup file\n");
3298 retok = WriteFile(hBackupFile, backupData, sizeof(backupData), &ret, NULL );
3299 ok( retok && ret == sizeof(backupData),
3300 "WriteFile error (replacement) %d\n", GetLastError());
3301 ok(GetFileSize(hBackupFile, NULL) == sizeof(backupData),
3302 "backup file has wrong size\n");
3303 /* change the filetime on the "replaced" file to ensure that it changes */
3304 ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
3305 ok( ret, "GetFileTime error (replaced) %d\n", GetLastError());
3306 ftReplaced.dwLowDateTime -= 600000000; /* 60 second */
3307 ret = SetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
3308 ok( ret, "SetFileTime error (replaced) %d\n", GetLastError());
3309 GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced); /* get the actual time back */
3310 CloseHandle(hReplacedFile);
3311 /* change the filetime on the backup to ensure that it changes */
3312 ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
3313 ok( ret, "GetFileTime error (backup) %d\n", GetLastError());
3314 ftBackup.dwLowDateTime -= 1200000000; /* 120 second */
3315 ret = SetFileTime(hBackupFile, NULL, NULL, &ftBackup);
3316 ok( ret, "SetFileTime error (backup) %d\n", GetLastError());
3317 GetFileTime(hBackupFile, NULL, NULL, &ftBackup); /* get the actual time back */
3318 CloseHandle(hBackupFile);
3319 /* get the filetime on the replacement file to perform checks */
3320 ret = GetFileTime(hReplacementFile, NULL, NULL, &ftReplacement);
3321 ok( ret, "GetFileTime error (replacement) %d\n", GetLastError());
3322 CloseHandle(hReplacementFile);
3324 /* perform replacement w/ backup
3325 * TODO: flags are not implemented
3327 SetLastError(0xdeadbeef);
3328 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3329 ok(ret, "ReplaceFileA: unexpected error %d\n", GetLastError());
3330 /* make sure that the backup has the size of the old "replaced" file */
3331 hBackupFile = CreateFileA(backup, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
3332 ok(hBackupFile != INVALID_HANDLE_VALUE,
3333 "failed to open backup file\n");
3334 ret = GetFileSize(hBackupFile, NULL);
3335 ok(ret == sizeof(replacedData),
3336 "backup file has wrong size %d\n", ret);
3337 /* make sure that the "replaced" file has the size of the replacement file */
3338 hReplacedFile = CreateFileA(replaced, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
3339 ok(hReplacedFile != INVALID_HANDLE_VALUE,
3340 "failed to open replaced file: %d\n", GetLastError());
3341 if (hReplacedFile != INVALID_HANDLE_VALUE)
3343 ret = GetFileSize(hReplacedFile, NULL);
3344 ok(ret == sizeof(replacementData),
3345 "replaced file has wrong size %d\n", ret);
3346 /* make sure that the replacement file no-longer exists */
3347 hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
3348 ok(hReplacementFile == INVALID_HANDLE_VALUE,
3349 "unexpected error, replacement file should not exist %d\n", GetLastError());
3350 /* make sure that the backup has the old "replaced" filetime */
3351 ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
3352 ok( ret, "GetFileTime error (backup %d\n", GetLastError());
3353 ok(check_file_time(&ftBackup, &ftReplaced, 20000000), "backup file has wrong filetime\n");
3354 CloseHandle(hBackupFile);
3355 /* make sure that the "replaced" has the old replacement filetime */
3356 ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
3357 ok( ret, "GetFileTime error (backup %d\n", GetLastError());
3358 ok(check_file_time(&ftReplaced, &ftReplacement, 20000000),
3359 "replaced file has wrong filetime %x%08x / %x%08x\n",
3360 ftReplaced.dwHighDateTime, ftReplaced.dwLowDateTime,
3361 ftReplacement.dwHighDateTime, ftReplacement.dwLowDateTime );
3362 CloseHandle(hReplacedFile);
3364 else
3365 skip("couldn't open replacement file, skipping tests\n");
3367 /* re-create replacement file for pass w/o backup (blank) */
3368 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3369 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
3370 /* perform replacement w/o backup
3371 * TODO: flags are not implemented
3373 SetLastError(0xdeadbeef);
3374 ret = pReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
3375 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3376 "ReplaceFileA: unexpected error %d\n", GetLastError());
3378 /* re-create replacement file for pass w/ backup (backup-file not existing) */
3379 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3380 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
3381 ret = DeleteFileA(backup);
3382 ok(ret, "DeleteFileA: error (backup) %d\n", GetLastError());
3383 /* perform replacement w/ backup (no pre-existing backup)
3384 * TODO: flags are not implemented
3386 SetLastError(0xdeadbeef);
3387 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3388 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3389 "ReplaceFileA: unexpected error %d\n", GetLastError());
3390 if (ret)
3391 removeBackup = TRUE;
3393 /* re-create replacement file for pass w/ no permissions to "replaced" */
3394 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3395 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
3396 ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_READONLY);
3397 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3398 "SetFileAttributesA: error setting to read only %d\n", GetLastError());
3399 /* perform replacement w/ backup (no permission to "replaced")
3400 * TODO: flags are not implemented
3402 SetLastError(0xdeadbeef);
3403 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3404 ok(ret != ERROR_UNABLE_TO_REMOVE_REPLACED, "ReplaceFileA: unexpected error %d\n", GetLastError());
3405 /* make sure that the replacement file still exists */
3406 hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
3407 ok(hReplacementFile != INVALID_HANDLE_VALUE ||
3408 broken(GetLastError() == ERROR_FILE_NOT_FOUND), /* win2k */
3409 "unexpected error, replacement file should still exist %d\n", GetLastError());
3410 CloseHandle(hReplacementFile);
3411 ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_NORMAL);
3412 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3413 "SetFileAttributesA: error setting to normal %d\n", GetLastError());
3415 /* replacement file still exists, make pass w/o "replaced" */
3416 ret = DeleteFileA(replaced);
3417 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3418 "DeleteFileA: error (replaced) %d\n", GetLastError());
3419 /* perform replacement w/ backup (no pre-existing backup or "replaced")
3420 * TODO: flags are not implemented
3422 SetLastError(0xdeadbeef);
3423 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3424 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
3425 GetLastError() == ERROR_ACCESS_DENIED),
3426 "ReplaceFileA: unexpected error %d\n", GetLastError());
3428 /* perform replacement w/o existing "replacement" file
3429 * TODO: flags are not implemented
3431 SetLastError(0xdeadbeef);
3432 ret = pReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
3433 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
3434 GetLastError() == ERROR_ACCESS_DENIED),
3435 "ReplaceFileA: unexpected error %d\n", GetLastError());
3436 DeleteFileA( replacement );
3439 * if the first round (w/ backup) worked then as long as there is no
3440 * failure then there is no need to check this round (w/ backup is the
3441 * more complete case)
3444 /* delete temporary files, replacement and replaced are already deleted */
3445 if (removeBackup)
3447 ret = DeleteFileA(backup);
3448 ok(ret ||
3449 broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */
3450 "DeleteFileA: error (backup) %d\n", GetLastError());
3455 * ReplaceFileW is a simpler case of ReplaceFileA, there is no
3456 * need to be as thorough.
3458 static void test_ReplaceFileW(void)
3460 WCHAR replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH];
3461 static const WCHAR prefix[] = {'p','f','x',0};
3462 WCHAR temp_path[MAX_PATH];
3463 DWORD ret;
3464 BOOL removeBackup = FALSE;
3466 if (!pReplaceFileW)
3468 win_skip("ReplaceFileW() is missing\n");
3469 return;
3472 ret = GetTempPathW(MAX_PATH, temp_path);
3473 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
3475 win_skip("GetTempPathW is not available\n");
3476 return;
3478 ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
3479 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
3481 ret = GetTempFileNameW(temp_path, prefix, 0, replaced);
3482 ok(ret != 0, "GetTempFileNameW error (replaced) %d\n", GetLastError());
3484 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3485 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3487 ret = GetTempFileNameW(temp_path, prefix, 0, backup);
3488 ok(ret != 0, "GetTempFileNameW error (backup) %d\n", GetLastError());
3490 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3491 ok(ret, "ReplaceFileW: error %d\n", GetLastError());
3493 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3494 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3495 ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0);
3496 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3497 "ReplaceFileW: error %d\n", GetLastError());
3499 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3500 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3501 ret = DeleteFileW(backup);
3502 ok(ret, "DeleteFileW: error (backup) %d\n", GetLastError());
3503 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3504 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3505 "ReplaceFileW: error %d\n", GetLastError());
3507 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3508 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3509 ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_READONLY);
3510 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3511 "SetFileAttributesW: error setting to read only %d\n", GetLastError());
3513 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3514 ok(ret != ERROR_UNABLE_TO_REMOVE_REPLACED,
3515 "ReplaceFileW: unexpected error %d\n", GetLastError());
3516 ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_NORMAL);
3517 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3518 "SetFileAttributesW: error setting to normal %d\n", GetLastError());
3519 if (ret)
3520 removeBackup = TRUE;
3522 ret = DeleteFileW(replaced);
3523 ok(ret, "DeleteFileW: error (replaced) %d\n", GetLastError());
3524 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3525 ok(!ret, "ReplaceFileW: error %d\n", GetLastError());
3527 ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0);
3528 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
3529 GetLastError() == ERROR_ACCESS_DENIED),
3530 "ReplaceFileW: unexpected error %d\n", GetLastError());
3531 DeleteFileW( replacement );
3533 if (removeBackup)
3535 ret = DeleteFileW(backup);
3536 ok(ret ||
3537 broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */
3538 "DeleteFileW: error (backup) %d\n", GetLastError());
3542 static void test_CreateFile(void)
3544 static const struct test_data
3546 DWORD disposition, access, error, clean_up;
3547 } td[] =
3549 /* 0 */ { 0, 0, ERROR_INVALID_PARAMETER, 0 },
3550 /* 1 */ { 0, GENERIC_READ, ERROR_INVALID_PARAMETER, 0 },
3551 /* 2 */ { 0, GENERIC_READ|GENERIC_WRITE, ERROR_INVALID_PARAMETER, 0 },
3552 /* 3 */ { CREATE_NEW, 0, ERROR_FILE_EXISTS, 1 },
3553 /* 4 */ { CREATE_NEW, 0, 0, 1 },
3554 /* 5 */ { CREATE_NEW, GENERIC_READ, 0, 1 },
3555 /* 6 */ { CREATE_NEW, GENERIC_WRITE, 0, 1 },
3556 /* 7 */ { CREATE_NEW, GENERIC_READ|GENERIC_WRITE, 0, 0 },
3557 /* 8 */ { CREATE_ALWAYS, 0, 0, 0 },
3558 /* 9 */ { CREATE_ALWAYS, GENERIC_READ, 0, 0 },
3559 /* 10*/ { CREATE_ALWAYS, GENERIC_WRITE, 0, 0 },
3560 /* 11*/ { CREATE_ALWAYS, GENERIC_READ|GENERIC_WRITE, 0, 1 },
3561 /* 12*/ { OPEN_EXISTING, 0, ERROR_FILE_NOT_FOUND, 0 },
3562 /* 13*/ { CREATE_ALWAYS, 0, 0, 0 },
3563 /* 14*/ { OPEN_EXISTING, 0, 0, 0 },
3564 /* 15*/ { OPEN_EXISTING, GENERIC_READ, 0, 0 },
3565 /* 16*/ { OPEN_EXISTING, GENERIC_WRITE, 0, 0 },
3566 /* 17*/ { OPEN_EXISTING, GENERIC_READ|GENERIC_WRITE, 0, 1 },
3567 /* 18*/ { OPEN_ALWAYS, 0, 0, 0 },
3568 /* 19*/ { OPEN_ALWAYS, GENERIC_READ, 0, 0 },
3569 /* 20*/ { OPEN_ALWAYS, GENERIC_WRITE, 0, 0 },
3570 /* 21*/ { OPEN_ALWAYS, GENERIC_READ|GENERIC_WRITE, 0, 0 },
3571 /* 22*/ { TRUNCATE_EXISTING, 0, ERROR_INVALID_PARAMETER, 0 },
3572 /* 23*/ { TRUNCATE_EXISTING, GENERIC_READ, ERROR_INVALID_PARAMETER, 0 },
3573 /* 24*/ { TRUNCATE_EXISTING, GENERIC_WRITE, 0, 0 },
3574 /* 25*/ { TRUNCATE_EXISTING, GENERIC_READ|GENERIC_WRITE, 0, 0 },
3575 /* 26*/ { TRUNCATE_EXISTING, FILE_WRITE_DATA, ERROR_INVALID_PARAMETER, 0 }
3577 char temp_path[MAX_PATH];
3578 char file_name[MAX_PATH];
3579 DWORD i, ret, written;
3580 HANDLE hfile;
3582 GetTempPathA(MAX_PATH, temp_path);
3583 GetTempFileNameA(temp_path, "tmp", 0, file_name);
3585 i = strlen(temp_path);
3586 if (i && temp_path[i - 1] == '\\') temp_path[i - 1] = 0;
3588 for (i = 0; i <= 5; i++)
3590 SetLastError(0xdeadbeef);
3591 hfile = CreateFileA(temp_path, GENERIC_READ, 0, NULL, i, 0, 0);
3592 ok(hfile == INVALID_HANDLE_VALUE, "CreateFile should fail\n");
3593 if (i == 0 || i == 5)
3595 /* FIXME: remove once Wine is fixed */
3596 if (i == 5) todo_wine
3597 ok(GetLastError() == ERROR_INVALID_PARAMETER, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i, GetLastError());
3598 else
3599 ok(GetLastError() == ERROR_INVALID_PARAMETER, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i, GetLastError());
3601 else
3603 /* FIXME: remove once Wine is fixed */
3604 if (i == 1) todo_wine
3605 ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
3606 else
3607 ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
3610 SetLastError(0xdeadbeef);
3611 hfile = CreateFileA(temp_path, GENERIC_WRITE, 0, NULL, i, 0, 0);
3612 ok(hfile == INVALID_HANDLE_VALUE, "CreateFile should fail\n");
3613 if (i == 0)
3614 ok(GetLastError() == ERROR_INVALID_PARAMETER, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i, GetLastError());
3615 else
3617 /* FIXME: remove once Wine is fixed */
3618 if (i == 1) todo_wine
3619 ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
3620 else
3621 ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
3625 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
3627 SetLastError(0xdeadbeef);
3628 hfile = CreateFileA(file_name, td[i].access, 0, NULL, td[i].disposition, 0, 0);
3629 if (!td[i].error)
3631 ok(hfile != INVALID_HANDLE_VALUE, "%d: CreateFile error %d\n", i, GetLastError());
3632 written = 0xdeadbeef;
3633 SetLastError(0xdeadbeef);
3634 ret = WriteFile(hfile, &td[i].error, sizeof(td[i].error), &written, NULL);
3635 if (td[i].access & GENERIC_WRITE)
3636 ok(ret, "%d: WriteFile error %d\n", i, GetLastError());
3637 else
3639 ok(!ret, "%d: WriteFile should fail\n", i);
3640 ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
3642 CloseHandle(hfile);
3644 else
3646 /* FIXME: remove the condition below once Wine is fixed */
3647 if (td[i].disposition == TRUNCATE_EXISTING && !(td[i].access & GENERIC_WRITE))
3649 todo_wine
3651 ok(hfile == INVALID_HANDLE_VALUE, "%d: CreateFile should fail\n", i);
3652 ok(GetLastError() == td[i].error, "%d: expected %d, got %d\n", i, td[i].error, GetLastError());
3654 CloseHandle(hfile);
3656 else
3658 ok(hfile == INVALID_HANDLE_VALUE, "%d: CreateFile should fail\n", i);
3659 ok(GetLastError() == td[i].error, "%d: expected %d, got %d\n", i, td[i].error, GetLastError());
3663 if (td[i].clean_up) DeleteFileA(file_name);
3666 DeleteFileA(file_name);
3669 static void test_GetFileInformationByHandleEx(void)
3671 int i;
3672 char tempPath[MAX_PATH], tempFileName[MAX_PATH], buffer[1024];
3673 BOOL ret;
3674 DWORD ret2;
3675 HANDLE directory;
3676 FILE_ID_BOTH_DIR_INFO *bothDirInfo;
3677 struct {
3678 FILE_INFO_BY_HANDLE_CLASS handleClass;
3679 void *ptr;
3680 DWORD size;
3681 DWORD errorCode;
3682 } checks[] = {
3683 {0xdeadbeef, NULL, 0, ERROR_INVALID_PARAMETER},
3684 {FileIdBothDirectoryInfo, NULL, 0, ERROR_BAD_LENGTH},
3685 {FileIdBothDirectoryInfo, NULL, sizeof(buffer), ERROR_NOACCESS},
3686 {FileIdBothDirectoryInfo, buffer, 0, ERROR_BAD_LENGTH}};
3688 if (!pGetFileInformationByHandleEx)
3690 win_skip("GetFileInformationByHandleEx is missing.\n");
3691 return;
3694 ret2 = GetTempPathA(sizeof(tempPath), tempPath);
3695 ok(ret2, "GetFileInformationByHandleEx: GetTempPathA failed, got error %u.\n", GetLastError());
3697 /* ensure the existence of a file in the temp folder */
3698 ret2 = GetTempFileNameA(tempPath, "abc", 0, tempFileName);
3699 ok(ret2, "GetFileInformationByHandleEx: GetTempFileNameA failed, got error %u.\n", GetLastError());
3700 ret2 = GetFileAttributesA(tempFileName);
3701 ok(ret2 != INVALID_FILE_ATTRIBUTES, "GetFileInformationByHandleEx: "
3702 "GetFileAttributesA failed to find the temp file, got error %u.\n", GetLastError());
3704 directory = CreateFileA(tempPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
3705 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
3706 ok(directory != INVALID_HANDLE_VALUE, "GetFileInformationByHandleEx: failed to open the temp folder, "
3707 "got error %u.\n", GetLastError());
3709 for (i = 0; i < sizeof(checks) / sizeof(checks[0]); i += 1)
3711 SetLastError(0xdeadbeef);
3712 ret = pGetFileInformationByHandleEx(directory, checks[i].handleClass, checks[i].ptr, checks[i].size);
3713 ok(!ret && GetLastError() == checks[i].errorCode, "GetFileInformationByHandleEx: expected error %u, "
3714 "got %u.\n", checks[i].errorCode, GetLastError());
3717 while (TRUE)
3719 memset(buffer, 0xff, sizeof(buffer));
3720 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer));
3721 if (!ret && GetLastError() == ERROR_NO_MORE_FILES)
3722 break;
3723 ok(ret, "GetFileInformationByHandleEx: failed to query for FileIdBothDirectoryInfo, got error %u.\n", GetLastError());
3724 if (!ret)
3725 break;
3726 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
3727 while (TRUE)
3729 ok(bothDirInfo->FileAttributes != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file attributes.\n");
3730 ok(bothDirInfo->FileId.u.LowPart != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file id.\n");
3731 ok(bothDirInfo->FileNameLength != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file name length.\n");
3732 if (!bothDirInfo->NextEntryOffset)
3733 break;
3734 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)(((char *)bothDirInfo) + bothDirInfo->NextEntryOffset);
3738 CloseHandle(directory);
3739 DeleteFileA(tempFileName);
3742 static void test_OpenFileById(void)
3744 char tempPath[MAX_PATH], tempFileName[MAX_PATH], buffer[256], tickCount[256];
3745 WCHAR tempFileNameW[MAX_PATH];
3746 BOOL ret, found;
3747 DWORD ret2, count, tempFileNameLen;
3748 HANDLE directory, handle, tempFile;
3749 FILE_ID_BOTH_DIR_INFO *bothDirInfo;
3750 FILE_ID_DESCRIPTOR fileIdDescr;
3752 if (!pGetFileInformationByHandleEx || !pOpenFileById)
3754 win_skip("GetFileInformationByHandleEx or OpenFileById is missing.\n");
3755 return;
3758 ret2 = GetTempPathA(sizeof(tempPath), tempPath);
3759 ok(ret2, "OpenFileById: GetTempPath failed, got error %u.\n", GetLastError());
3761 /* ensure the existence of a file in the temp folder */
3762 ret2 = GetTempFileNameA(tempPath, "abc", 0, tempFileName);
3763 ok(ret2, "OpenFileById: GetTempFileNameA failed, got error %u.\n", GetLastError());
3764 ret2 = GetFileAttributesA(tempFileName);
3765 ok(ret2 != INVALID_FILE_ATTRIBUTES,
3766 "OpenFileById: GetFileAttributesA failed to find the temp file, got error %u\n", GetLastError());
3768 ret2 = MultiByteToWideChar(CP_ACP, 0, tempFileName + strlen(tempPath), -1, tempFileNameW, sizeof(tempFileNameW)/sizeof(tempFileNameW[0]));
3769 ok(ret2, "OpenFileById: MultiByteToWideChar failed to convert tempFileName, got error %u.\n", GetLastError());
3770 tempFileNameLen = ret2 - 1;
3772 tempFile = CreateFileA(tempFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
3773 ok(tempFile != INVALID_HANDLE_VALUE, "OpenFileById: failed to create a temp file, "
3774 "got error %u.\n", GetLastError());
3775 ret2 = sprintf(tickCount, "%u", GetTickCount());
3776 ret = WriteFile(tempFile, tickCount, ret2, &count, NULL);
3777 ok(ret, "OpenFileById: WriteFile failed, got error %u.\n", GetLastError());
3778 CloseHandle(tempFile);
3780 directory = CreateFileA(tempPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
3781 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
3782 ok(directory != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the temp folder, "
3783 "got error %u.\n", GetLastError());
3785 /* get info about the temp folder itself */
3786 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
3787 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer));
3788 ok(ret, "OpenFileById: failed to query for FileIdBothDirectoryInfo, got error %u.\n", GetLastError());
3789 ok(bothDirInfo->FileNameLength == sizeof(WCHAR) && bothDirInfo->FileName[0] == '.',
3790 "OpenFileById: failed to return the temp folder at the first entry, got error %u.\n", GetLastError());
3792 /* open the temp folder itself */
3793 fileIdDescr.dwSize = sizeof(fileIdDescr);
3794 fileIdDescr.Type = FileIdType;
3795 U(fileIdDescr).FileId = bothDirInfo->FileId;
3796 handle = pOpenFileById(directory, &fileIdDescr, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0);
3797 todo_wine
3798 ok(handle != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the temp folder itself, got error %u.\n", GetLastError());
3799 CloseHandle(handle);
3801 /* find the temp file in the temp folder */
3802 found = FALSE;
3803 while (!found)
3805 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer));
3806 ok(ret, "OpenFileById: failed to query for FileIdBothDirectoryInfo, got error %u.\n", GetLastError());
3807 if (!ret)
3808 break;
3809 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
3810 while (TRUE)
3812 if (tempFileNameLen == bothDirInfo->FileNameLength / sizeof(WCHAR) &&
3813 memcmp(tempFileNameW, bothDirInfo->FileName, bothDirInfo->FileNameLength) == 0)
3815 found = TRUE;
3816 break;
3818 if (!bothDirInfo->NextEntryOffset)
3819 break;
3820 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)(((char *)bothDirInfo) + bothDirInfo->NextEntryOffset);
3823 ok(found, "OpenFileById: failed to find the temp file in the temp folder.\n");
3825 SetLastError(0xdeadbeef);
3826 handle = pOpenFileById(directory, NULL, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0);
3827 ok(handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER,
3828 "OpenFileById: expected ERROR_INVALID_PARAMETER, got error %u.\n", GetLastError());
3830 fileIdDescr.dwSize = sizeof(fileIdDescr);
3831 fileIdDescr.Type = FileIdType;
3832 U(fileIdDescr).FileId = bothDirInfo->FileId;
3833 handle = pOpenFileById(directory, &fileIdDescr, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0);
3834 ok(handle != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the file, got error %u.\n", GetLastError());
3836 ret = ReadFile(handle, buffer, sizeof(buffer), &count, NULL);
3837 buffer[count] = 0;
3838 ok(ret, "OpenFileById: ReadFile failed, got error %u.\n", GetLastError());
3839 ok(strcmp(tickCount, buffer) == 0, "OpenFileById: invalid contents of the temp file.\n");
3841 CloseHandle(handle);
3842 CloseHandle(directory);
3843 DeleteFileA(tempFileName);
3846 static void test_SetFileValidData(void)
3848 BOOL ret;
3849 HANDLE handle;
3850 DWORD error, count;
3851 char path[MAX_PATH], filename[MAX_PATH];
3852 TOKEN_PRIVILEGES privs;
3853 HANDLE token = NULL;
3855 if (!pSetFileValidData)
3857 win_skip("SetFileValidData is missing\n");
3858 return;
3860 GetTempPathA(sizeof(path), path);
3861 GetTempFileNameA(path, "tst", 0, filename);
3862 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
3863 WriteFile(handle, "test", sizeof("test") - 1, &count, NULL);
3864 CloseHandle(handle);
3866 SetLastError(0xdeadbeef);
3867 ret = pSetFileValidData(INVALID_HANDLE_VALUE, 0);
3868 error = GetLastError();
3869 ok(!ret, "SetFileValidData succeeded\n");
3870 ok(error == ERROR_INVALID_HANDLE, "got %u\n", error);
3872 SetLastError(0xdeadbeef);
3873 ret = pSetFileValidData(INVALID_HANDLE_VALUE, -1);
3874 error = GetLastError();
3875 ok(!ret, "SetFileValidData succeeded\n");
3876 ok(error == ERROR_INVALID_HANDLE, "got %u\n", error);
3878 /* file opened for reading */
3879 handle = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
3881 SetLastError(0xdeadbeef);
3882 ret = pSetFileValidData(handle, 0);
3883 ok(!ret, "SetFileValidData succeeded\n");
3884 error = GetLastError();
3885 ok(error == ERROR_ACCESS_DENIED, "got %u\n", error);
3887 SetLastError(0xdeadbeef);
3888 ret = pSetFileValidData(handle, -1);
3889 error = GetLastError();
3890 ok(!ret, "SetFileValidData succeeded\n");
3891 ok(error == ERROR_ACCESS_DENIED, "got %u\n", error);
3892 CloseHandle(handle);
3894 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
3896 SetLastError(0xdeadbeef);
3897 ret = pSetFileValidData(handle, 0);
3898 error = GetLastError();
3899 ok(!ret, "SetFileValidData succeeded\n");
3900 todo_wine ok(error == ERROR_PRIVILEGE_NOT_HELD, "got %u\n", error);
3901 CloseHandle(handle);
3903 privs.PrivilegeCount = 1;
3904 privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
3906 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token) ||
3907 !LookupPrivilegeValueA(NULL, SE_MANAGE_VOLUME_NAME, &privs.Privileges[0].Luid) ||
3908 !AdjustTokenPrivileges(token, FALSE, &privs, sizeof(privs), NULL, NULL) ||
3909 GetLastError() == ERROR_NOT_ALL_ASSIGNED)
3911 win_skip("cannot enable SE_MANAGE_VOLUME_NAME privilege\n");
3912 CloseHandle(token);
3913 DeleteFileA(filename);
3914 return;
3916 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
3918 SetLastError(0xdeadbeef);
3919 ret = pSetFileValidData(handle, 0);
3920 error = GetLastError();
3921 ok(!ret, "SetFileValidData succeeded\n");
3922 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3924 SetLastError(0xdeadbeef);
3925 ret = pSetFileValidData(handle, -1);
3926 error = GetLastError();
3927 ok(!ret, "SetFileValidData succeeded\n");
3928 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3930 SetLastError(0xdeadbeef);
3931 ret = pSetFileValidData(handle, 2);
3932 error = GetLastError();
3933 todo_wine ok(!ret, "SetFileValidData succeeded\n");
3934 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3936 ret = pSetFileValidData(handle, 4);
3937 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3939 SetLastError(0xdeadbeef);
3940 ret = pSetFileValidData(handle, 8);
3941 error = GetLastError();
3942 ok(!ret, "SetFileValidData succeeded\n");
3943 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3945 count = SetFilePointer(handle, 1024, NULL, FILE_END);
3946 ok(count != INVALID_SET_FILE_POINTER, "SetFilePointer failed %u\n", GetLastError());
3947 ret = SetEndOfFile(handle);
3948 ok(ret, "SetEndOfFile failed %u\n", GetLastError());
3950 SetLastError(0xdeadbeef);
3951 ret = pSetFileValidData(handle, 2);
3952 error = GetLastError();
3953 todo_wine ok(!ret, "SetFileValidData succeeded\n");
3954 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3956 ret = pSetFileValidData(handle, 4);
3957 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3959 ret = pSetFileValidData(handle, 8);
3960 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3962 ret = pSetFileValidData(handle, 4);
3963 error = GetLastError();
3964 todo_wine ok(!ret, "SetFileValidData succeeded\n");
3965 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3967 ret = pSetFileValidData(handle, 1024);
3968 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3970 ret = pSetFileValidData(handle, 2048);
3971 error = GetLastError();
3972 ok(!ret, "SetFileValidData succeeded\n");
3973 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3975 privs.Privileges[0].Attributes = 0;
3976 AdjustTokenPrivileges(token, FALSE, &privs, sizeof(privs), NULL, NULL);
3978 CloseHandle(token);
3979 CloseHandle(handle);
3980 DeleteFileA(filename);
3983 static void test_WriteFileGather(void)
3985 char temp_path[MAX_PATH], filename[MAX_PATH];
3986 HANDLE hfile, hiocp1, hiocp2;
3987 DWORD ret, size;
3988 ULONG_PTR key;
3989 FILE_SEGMENT_ELEMENT fse[2];
3990 OVERLAPPED ovl, *povl = NULL;
3991 SYSTEM_INFO si;
3992 LPVOID buf = NULL;
3994 ret = GetTempPathA( MAX_PATH, temp_path );
3995 ok( ret != 0, "GetTempPathA error %d\n", GetLastError() );
3996 ok( ret < MAX_PATH, "temp path should fit into MAX_PATH\n" );
3997 ret = GetTempFileNameA( temp_path, "wfg", 0, filename );
3998 ok( ret != 0, "GetTempFileNameA error %d\n", GetLastError() );
4000 hfile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
4001 FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL, 0 );
4002 ok( hfile != INVALID_HANDLE_VALUE, "CreateFile failed err %u\n", GetLastError() );
4003 if (hfile == INVALID_HANDLE_VALUE) return;
4005 hiocp1 = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 999, 0 );
4006 hiocp2 = CreateIoCompletionPort( hfile, hiocp1, 999, 0 );
4007 ok( hiocp2 != 0, "CreateIoCompletionPort failed err %u\n", GetLastError() );
4009 GetSystemInfo( &si );
4010 buf = VirtualAlloc( NULL, si.dwPageSize, MEM_COMMIT, PAGE_READWRITE );
4011 ok( buf != NULL, "VirtualAlloc failed err %u\n", GetLastError() );
4013 memset( &ovl, 0, sizeof(ovl) );
4014 memset( fse, 0, sizeof(fse) );
4015 fse[0].Buffer = buf;
4016 if (!WriteFileGather( hfile, fse, si.dwPageSize, NULL, &ovl ))
4017 ok( GetLastError() == ERROR_IO_PENDING, "WriteFileGather failed err %u\n", GetLastError() );
4019 ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 1000 );
4020 ok( ret, "GetQueuedCompletionStatus failed err %u\n", GetLastError());
4021 ok( povl == &ovl, "wrong ovl %p\n", povl );
4023 memset( &ovl, 0, sizeof(ovl) );
4024 memset( fse, 0, sizeof(fse) );
4025 fse[0].Buffer = buf;
4026 if (!ReadFileScatter( hfile, fse, si.dwPageSize, NULL, &ovl ))
4027 ok( GetLastError() == ERROR_IO_PENDING, "ReadFileScatter failed err %u\n", GetLastError() );
4029 ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 1000 );
4030 ok( ret, "GetQueuedCompletionStatus failed err %u\n", GetLastError());
4031 ok( povl == &ovl, "wrong ovl %p\n", povl );
4033 CloseHandle( hfile );
4034 CloseHandle( hiocp1 );
4035 CloseHandle( hiocp2 );
4036 VirtualFree( buf, 0, MEM_RELEASE );
4037 DeleteFileA( filename );
4040 static unsigned file_map_access(unsigned access)
4042 if (access & GENERIC_READ) access |= FILE_GENERIC_READ;
4043 if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE;
4044 if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE;
4045 if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS;
4046 return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
4049 static BOOL is_access_compatible(unsigned obj_access, unsigned desired_access)
4051 obj_access = file_map_access(obj_access);
4052 desired_access = file_map_access(desired_access);
4053 return (obj_access & desired_access) == desired_access;
4056 static void test_file_access(void)
4058 static const struct
4060 unsigned access, create_error, write_error, read_error;
4061 } td[] =
4063 { GENERIC_READ | GENERIC_WRITE, 0, 0, 0 },
4064 { GENERIC_WRITE, 0, 0, ERROR_ACCESS_DENIED },
4065 { GENERIC_READ, 0, ERROR_ACCESS_DENIED, 0 },
4066 { FILE_READ_DATA | FILE_WRITE_DATA, 0, 0, 0 },
4067 { FILE_WRITE_DATA, 0, 0, ERROR_ACCESS_DENIED },
4068 { FILE_READ_DATA, 0, ERROR_ACCESS_DENIED, 0 },
4069 { FILE_APPEND_DATA, 0, 0, ERROR_ACCESS_DENIED },
4070 { FILE_READ_DATA | FILE_APPEND_DATA, 0, 0, 0 },
4071 { FILE_WRITE_DATA | FILE_APPEND_DATA, 0, 0, ERROR_ACCESS_DENIED },
4072 { 0, 0, ERROR_ACCESS_DENIED, ERROR_ACCESS_DENIED },
4074 char path[MAX_PATH], fname[MAX_PATH];
4075 unsigned char buf[16];
4076 HANDLE hfile, hdup;
4077 DWORD i, j, ret, bytes;
4079 GetTempPathA(MAX_PATH, path);
4080 GetTempFileNameA(path, "foo", 0, fname);
4082 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
4084 SetLastError(0xdeadbeef);
4085 hfile = CreateFileA(fname, td[i].access, 0, NULL, CREATE_ALWAYS,
4086 FILE_FLAG_DELETE_ON_CLOSE, 0);
4087 if (td[i].create_error)
4089 ok(hfile == INVALID_HANDLE_VALUE, "%d: CreateFile should fail\n", i);
4090 ok(td[i].create_error == GetLastError(), "%d: expected %d, got %d\n", i, td[i].create_error, GetLastError());
4091 continue;
4093 else
4094 ok(hfile != INVALID_HANDLE_VALUE, "%d: CreateFile error %d\n", i, GetLastError());
4096 for (j = 0; j < sizeof(td)/sizeof(td[0]); j++)
4098 SetLastError(0xdeadbeef);
4099 ret = DuplicateHandle(GetCurrentProcess(), hfile, GetCurrentProcess(), &hdup,
4100 td[j].access, 0, 0);
4101 if (is_access_compatible(td[i].access, td[j].access))
4102 ok(ret, "DuplicateHandle(%#x => %#x) error %d\n", td[i].access, td[j].access, GetLastError());
4103 else
4105 /* FIXME: Remove once Wine is fixed */
4106 if ((td[j].access & (GENERIC_READ | GENERIC_WRITE)) ||
4107 (!(td[i].access & (GENERIC_WRITE | FILE_WRITE_DATA)) && (td[j].access & FILE_WRITE_DATA)) ||
4108 (!(td[i].access & (GENERIC_READ | FILE_READ_DATA)) && (td[j].access & FILE_READ_DATA)) ||
4109 (!(td[i].access & (GENERIC_WRITE)) && (td[j].access & FILE_APPEND_DATA)))
4111 todo_wine
4112 ok(!ret, "DuplicateHandle(%#x => %#x) should fail\n", td[i].access, td[j].access);
4113 todo_wine
4114 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
4116 else
4118 ok(!ret, "DuplicateHandle(%#x => %#x) should fail\n", td[i].access, td[j].access);
4119 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
4122 if (ret) CloseHandle(hdup);
4125 SetLastError(0xdeadbeef);
4126 bytes = 0xdeadbeef;
4127 ret = WriteFile(hfile, "\x5e\xa7", 2, &bytes, NULL);
4128 if (td[i].write_error)
4130 ok(!ret, "%d: WriteFile should fail\n", i);
4131 ok(td[i].write_error == GetLastError(), "%d: expected %d, got %d\n", i, td[i].write_error, GetLastError());
4132 ok(bytes == 0, "%d: expected 0, got %u\n", i, bytes);
4134 else
4136 ok(ret, "%d: WriteFile error %d\n", i, GetLastError());
4137 ok(bytes == 2, "%d: expected 2, got %u\n", i, bytes);
4140 SetLastError(0xdeadbeef);
4141 ret = SetFilePointer(hfile, 0, NULL, FILE_BEGIN);
4142 ok(ret != INVALID_SET_FILE_POINTER, "SetFilePointer error %d\n", GetLastError());
4144 SetLastError(0xdeadbeef);
4145 bytes = 0xdeadbeef;
4146 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, NULL);
4147 if (td[i].read_error)
4149 ok(!ret, "%d: ReadFile should fail\n", i);
4150 ok(td[i].read_error == GetLastError(), "%d: expected %d, got %d\n", i, td[i].read_error, GetLastError());
4151 ok(bytes == 0, "%d: expected 0, got %u\n", i, bytes);
4153 else
4155 ok(ret, "%d: ReadFile error %d\n", i, GetLastError());
4156 if (td[i].write_error)
4157 ok(bytes == 0, "%d: expected 0, got %u\n", i, bytes);
4158 else
4160 ok(bytes == 2, "%d: expected 2, got %u\n", i, bytes);
4161 ok(buf[0] == 0x5e && buf[1] == 0xa7, "%d: expected 5ea7, got %02x%02x\n", i, buf[0], buf[1]);
4165 CloseHandle(hfile);
4169 START_TEST(file)
4171 InitFunctionPointers();
4173 test__hread( );
4174 test__hwrite( );
4175 test__lclose( );
4176 test__lcreat( );
4177 test__llseek( );
4178 test__llopen( );
4179 test__lread( );
4180 test__lwrite( );
4181 test_GetTempFileNameA();
4182 test_CopyFileA();
4183 test_CopyFileW();
4184 test_CopyFile2();
4185 test_CreateFile();
4186 test_CreateFileA();
4187 test_CreateFileW();
4188 test_CreateFile2();
4189 test_DeleteFileA();
4190 test_DeleteFileW();
4191 test_MoveFileA();
4192 test_MoveFileW();
4193 test_FindFirstFileA();
4194 test_FindNextFileA();
4195 test_FindFirstFileExA(0, 0);
4196 test_FindFirstFileExA(0, FIND_FIRST_EX_CASE_SENSITIVE);
4197 test_FindFirstFileExA(0, FIND_FIRST_EX_LARGE_FETCH);
4198 /* FindExLimitToDirectories is ignored if the file system doesn't support directory filtering */
4199 test_FindFirstFileExA(FindExSearchLimitToDirectories, 0);
4200 test_FindFirstFileExA(FindExSearchLimitToDirectories, FIND_FIRST_EX_CASE_SENSITIVE);
4201 test_FindFirstFileExA(FindExSearchLimitToDirectories, FIND_FIRST_EX_LARGE_FETCH);
4202 test_LockFile();
4203 test_file_sharing();
4204 test_offset_in_overlapped_structure();
4205 test_MapFile();
4206 test_GetFileType();
4207 test_async_file_errors();
4208 test_read_write();
4209 test_OpenFile();
4210 test_overlapped();
4211 test_RemoveDirectory();
4212 test_ReplaceFileA();
4213 test_ReplaceFileW();
4214 test_GetFileInformationByHandleEx();
4215 test_OpenFileById();
4216 test_SetFileValidData();
4217 test_WriteFileGather();
4218 test_file_access();