oleacc: Added CAccPropServices stub implementation.
[wine/multimedia.git] / dlls / kernel32 / tests / file.c
blobddfa0197adfc79dd40bf43152e1e3ed1a0616e55
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)
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, 0);
2583 if (handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
2585 win_skip("FindFirstFileExA is not implemented\n");
2586 goto cleanup;
2588 ok(handle != INVALID_HANDLE_VALUE, "FindFirstFile failed (err=%u)\n", GetLastError());
2589 ok(strcmp(search_results.cFileName, ".") == 0, "First entry should be '.', is %s\n", search_results.cFileName);
2591 #define CHECK_NAME(fn) (strcmp((fn), "file1") == 0 || strcmp((fn), "file2") == 0 || strcmp((fn), "dir1") == 0)
2593 ok(FindNextFileA(handle, &search_results), "Fetching second file failed\n");
2594 ok(strcmp(search_results.cFileName, "..") == 0, "Second entry should be '..' is %s\n", search_results.cFileName);
2596 ok(FindNextFileA(handle, &search_results), "Fetching third file failed\n");
2597 ok(CHECK_NAME(search_results.cFileName), "Invalid third entry - %s\n", search_results.cFileName);
2599 SetLastError(0xdeadbeef);
2600 ret = FindNextFileA(handle, &search_results);
2601 if (!ret && (GetLastError() == ERROR_NO_MORE_FILES) && (search_ops == FindExSearchLimitToDirectories))
2603 skip("File system supports directory filtering\n");
2604 /* Results from the previous call are not cleared */
2605 ok(strcmp(search_results.cFileName, "dir1") == 0, "Third entry should be 'dir1' is %s\n", search_results.cFileName);
2606 FindClose( handle );
2607 goto cleanup;
2610 ok(ret, "Fetching fourth file failed\n");
2611 ok(CHECK_NAME(search_results.cFileName), "Invalid fourth entry - %s\n", search_results.cFileName);
2613 ok(FindNextFileA(handle, &search_results), "Fetching fifth file failed\n");
2614 ok(CHECK_NAME(search_results.cFileName), "Invalid fifth entry - %s\n", search_results.cFileName);
2616 #undef CHECK_NAME
2618 ok(FindNextFileA(handle, &search_results) == FALSE, "Fetching sixth file should fail\n");
2620 FindClose( handle );
2622 cleanup:
2623 DeleteFileA("test-dir\\file1");
2624 DeleteFileA("test-dir\\file2");
2625 RemoveDirectoryA("test-dir\\dir1");
2626 RemoveDirectoryA("test-dir");
2629 static int test_Mapfile_createtemp(HANDLE *handle)
2631 SetFileAttributesA(filename,FILE_ATTRIBUTE_NORMAL);
2632 DeleteFileA(filename);
2633 *handle = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, 0, 0,
2634 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2635 if (*handle != INVALID_HANDLE_VALUE) {
2637 return 1;
2640 return 0;
2643 static void test_MapFile(void)
2645 HANDLE handle;
2646 HANDLE hmap;
2648 ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
2650 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 0x1000, "named_file_map" );
2651 ok( hmap != NULL, "mapping should work, I named it!\n" );
2653 ok( CloseHandle( hmap ), "can't close mapping handle\n");
2655 /* We have to close file before we try new stuff with mapping again.
2656 Else we would always succeed on XP or block descriptors on 95. */
2657 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
2658 ok( hmap != NULL, "We should still be able to map!\n" );
2659 ok( CloseHandle( hmap ), "can't close mapping handle\n");
2660 ok( CloseHandle( handle ), "can't close file handle\n");
2661 handle = NULL;
2663 ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
2665 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
2666 ok( hmap == NULL, "mapped zero size file\n");
2667 ok( GetLastError() == ERROR_FILE_INVALID, "not ERROR_FILE_INVALID\n");
2669 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0x80000000, 0, NULL );
2670 ok( hmap == NULL || broken(hmap != NULL) /* NT4 */, "mapping should fail\n");
2671 /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */
2672 if ( hmap )
2673 CloseHandle( hmap );
2675 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0x80000000, 0x10000, NULL );
2676 ok( hmap == NULL || broken(hmap != NULL) /* NT4 */, "mapping should fail\n");
2677 /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */
2678 if ( hmap )
2679 CloseHandle( hmap );
2681 /* On XP you can now map again, on Win 95 you cannot. */
2683 ok( CloseHandle( handle ), "can't close file handle\n");
2684 ok( DeleteFileA( filename ), "DeleteFile failed after map\n" );
2687 static void test_GetFileType(void)
2689 DWORD type, type2;
2690 HANDLE h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2691 ok( h != INVALID_HANDLE_VALUE, "open %s failed\n", filename );
2692 type = GetFileType(h);
2693 ok( type == FILE_TYPE_DISK, "expected type disk got %d\n", type );
2694 CloseHandle( h );
2695 h = CreateFileA( "nul", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2696 ok( h != INVALID_HANDLE_VALUE, "open nul failed\n" );
2697 type = GetFileType(h);
2698 ok( type == FILE_TYPE_CHAR, "expected type char for nul got %d\n", type );
2699 CloseHandle( h );
2700 DeleteFileA( filename );
2701 h = GetStdHandle( STD_OUTPUT_HANDLE );
2702 ok( h != INVALID_HANDLE_VALUE, "GetStdHandle failed\n" );
2703 type = GetFileType( (HANDLE)STD_OUTPUT_HANDLE );
2704 type2 = GetFileType( h );
2705 ok(type == type2, "expected type %d for STD_OUTPUT_HANDLE got %d\n", type2, type);
2708 static int completion_count;
2710 static void CALLBACK FileIOComplete(DWORD dwError, DWORD dwBytes, LPOVERLAPPED ovl)
2712 /* printf("(%ld, %ld, %p { %ld, %ld, %ld, %ld, %p })\n", dwError, dwBytes, ovl, ovl->Internal, ovl->InternalHigh, ovl->Offset, ovl->OffsetHigh, ovl->hEvent);*/
2713 ReleaseSemaphore(ovl->hEvent, 1, NULL);
2714 completion_count++;
2717 static void test_async_file_errors(void)
2719 char szFile[MAX_PATH];
2720 HANDLE hSem = CreateSemaphoreW(NULL, 1, 1, NULL);
2721 HANDLE hFile;
2722 LPVOID lpBuffer = HeapAlloc(GetProcessHeap(), 0, 4096);
2723 OVERLAPPED ovl;
2724 S(U(ovl)).Offset = 0;
2725 S(U(ovl)).OffsetHigh = 0;
2726 ovl.hEvent = hSem;
2727 completion_count = 0;
2728 szFile[0] = '\0';
2729 GetWindowsDirectoryA(szFile, sizeof(szFile)/sizeof(szFile[0])-1-strlen("\\win.ini"));
2730 strcat(szFile, "\\win.ini");
2731 hFile = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
2732 NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
2733 if (hFile == INVALID_HANDLE_VALUE) /* win9x doesn't like FILE_SHARE_DELETE */
2734 hFile = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
2735 NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
2736 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA(%s ...) failed\n", szFile);
2737 while (TRUE)
2739 BOOL res;
2740 DWORD count;
2741 while (WaitForSingleObjectEx(hSem, INFINITE, TRUE) == WAIT_IO_COMPLETION)
2743 res = ReadFileEx(hFile, lpBuffer, 4096, &ovl, FileIOComplete);
2744 /*printf("Offset = %ld, result = %s\n", ovl.Offset, res ? "TRUE" : "FALSE");*/
2745 if (!res)
2746 break;
2747 if (!GetOverlappedResult(hFile, &ovl, &count, FALSE))
2748 break;
2749 S(U(ovl)).Offset += count;
2750 /* i/o completion routine only called if ReadFileEx returned success.
2751 * we only care about violations of this rule so undo what should have
2752 * been done */
2753 completion_count--;
2755 ok(completion_count == 0, "completion routine should only be called when ReadFileEx succeeds (this rule was violated %d times)\n", completion_count);
2756 /*printf("Error = %ld\n", GetLastError());*/
2757 HeapFree(GetProcessHeap(), 0, lpBuffer);
2760 static BOOL user_apc_ran;
2761 static void CALLBACK user_apc(ULONG_PTR param)
2763 user_apc_ran = TRUE;
2766 static void test_read_write(void)
2768 DWORD bytes, ret, old_prot;
2769 HANDLE hFile;
2770 char temp_path[MAX_PATH];
2771 char filename[MAX_PATH];
2772 char *mem;
2773 static const char prefix[] = "pfx";
2775 ret = GetTempPathA(MAX_PATH, temp_path);
2776 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
2777 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
2779 ret = GetTempFileNameA(temp_path, prefix, 0, filename);
2780 ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
2782 hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
2783 CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
2784 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
2786 user_apc_ran = FALSE;
2787 if (pQueueUserAPC) {
2788 trace("Queueing an user APC\n"); /* verify the file is non alerable */
2789 ret = pQueueUserAPC(&user_apc, GetCurrentThread(), 0);
2790 ok(ret, "QueueUserAPC failed: %d\n", GetLastError());
2793 SetLastError(12345678);
2794 bytes = 12345678;
2795 ret = WriteFile(hFile, NULL, 0, &bytes, NULL);
2796 ok(ret && GetLastError() == 12345678,
2797 "ret = %d, error %d\n", ret, GetLastError());
2798 ok(!bytes, "bytes = %d\n", bytes);
2800 SetLastError(12345678);
2801 bytes = 12345678;
2802 ret = WriteFile(hFile, NULL, 10, &bytes, NULL);
2803 ok((!ret && GetLastError() == ERROR_INVALID_USER_BUFFER) || /* Win2k */
2804 (ret && GetLastError() == 12345678), /* Win9x */
2805 "ret = %d, error %d\n", ret, GetLastError());
2806 ok(!bytes || /* Win2k */
2807 bytes == 10, /* Win9x */
2808 "bytes = %d\n", bytes);
2810 /* make sure the file contains data */
2811 WriteFile(hFile, "this is the test data", 21, &bytes, NULL);
2812 SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
2814 SetLastError(12345678);
2815 bytes = 12345678;
2816 ret = ReadFile(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 = ReadFile(hFile, NULL, 10, &bytes, NULL);
2824 ok(!ret && (GetLastError() == ERROR_NOACCESS || /* Win2k */
2825 GetLastError() == ERROR_INVALID_PARAMETER), /* Win9x */
2826 "ret = %d, error %d\n", ret, GetLastError());
2827 ok(!bytes, "bytes = %d\n", bytes);
2829 ok(user_apc_ran == FALSE, "UserAPC ran, file using alertable io mode\n");
2830 if (pQueueUserAPC)
2831 SleepEx(0, TRUE); /* get rid of apc */
2833 /* test passing protected memory as buffer */
2835 mem = VirtualAlloc( NULL, 0x4000, MEM_COMMIT, PAGE_READWRITE );
2836 ok( mem != NULL, "failed to allocate virtual mem error %u\n", GetLastError() );
2838 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
2839 ok( ret, "WriteFile failed error %u\n", GetLastError() );
2840 ok( bytes == 0x4000, "only wrote %x bytes\n", bytes );
2842 ret = VirtualProtect( mem + 0x2000, 0x2000, PAGE_NOACCESS, &old_prot );
2843 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2845 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
2846 ok( !ret, "WriteFile succeeded\n" );
2847 ok( GetLastError() == ERROR_INVALID_USER_BUFFER ||
2848 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2849 "wrong error %u\n", GetLastError() );
2850 ok( bytes == 0, "wrote %x bytes\n", bytes );
2852 ret = WriteFile( (HANDLE)0xdead, mem, 0x4000, &bytes, NULL );
2853 ok( !ret, "WriteFile succeeded\n" );
2854 ok( GetLastError() == ERROR_INVALID_HANDLE || /* handle is checked before buffer on NT */
2855 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2856 "wrong error %u\n", GetLastError() );
2857 ok( bytes == 0, "wrote %x bytes\n", bytes );
2859 ret = VirtualProtect( mem, 0x2000, PAGE_NOACCESS, &old_prot );
2860 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2862 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
2863 ok( !ret, "WriteFile succeeded\n" );
2864 ok( GetLastError() == ERROR_INVALID_USER_BUFFER ||
2865 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2866 "wrong error %u\n", GetLastError() );
2867 ok( bytes == 0, "wrote %x bytes\n", bytes );
2869 SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
2871 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2872 ok( !ret, "ReadFile succeeded\n" );
2873 ok( GetLastError() == ERROR_NOACCESS ||
2874 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2875 "wrong error %u\n", GetLastError() );
2876 ok( bytes == 0, "read %x bytes\n", bytes );
2878 ret = VirtualProtect( mem, 0x2000, PAGE_READONLY, &old_prot );
2879 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2881 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2882 ok( !ret, "ReadFile succeeded\n" );
2883 ok( GetLastError() == ERROR_NOACCESS ||
2884 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2885 "wrong error %u\n", GetLastError() );
2886 ok( bytes == 0, "read %x bytes\n", bytes );
2888 ret = VirtualProtect( mem, 0x2000, PAGE_READWRITE, &old_prot );
2889 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2891 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2892 ok( !ret, "ReadFile succeeded\n" );
2893 ok( GetLastError() == ERROR_NOACCESS ||
2894 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2895 "wrong error %u\n", GetLastError() );
2896 ok( bytes == 0, "read %x bytes\n", bytes );
2898 SetFilePointer( hFile, 0x1234, NULL, FILE_BEGIN );
2899 SetEndOfFile( hFile );
2900 SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
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 = ReadFile( hFile, mem, 0x2000, &bytes, NULL );
2910 ok( ret, "ReadFile failed error %u\n", GetLastError() );
2911 ok( bytes == 0x1234, "read %x bytes\n", bytes );
2913 ret = ReadFile( hFile, NULL, 1, &bytes, NULL );
2914 ok( !ret, "ReadFile succeeded\n" );
2915 ok( GetLastError() == ERROR_NOACCESS ||
2916 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2917 "wrong error %u\n", GetLastError() );
2918 ok( bytes == 0, "read %x bytes\n", bytes );
2920 VirtualFree( mem, 0, MEM_FREE );
2922 ret = CloseHandle(hFile);
2923 ok( ret, "CloseHandle: error %d\n", GetLastError());
2924 ret = DeleteFileA(filename);
2925 ok( ret, "DeleteFileA: error %d\n", GetLastError());
2928 static void test_OpenFile(void)
2930 HFILE hFile;
2931 OFSTRUCT ofs;
2932 BOOL ret;
2933 DWORD retval;
2935 static const char file[] = "regedit.exe";
2936 static const char foo[] = ".\\foo-bar-foo.baz";
2937 static const char *foo_too_long = ".\\foo-bar-foo.baz+++++++++++++++"
2938 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2939 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2940 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2941 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2942 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
2943 char buff[MAX_PATH];
2944 char buff_long[4*MAX_PATH];
2945 char filled_0xA5[OFS_MAXPATHNAME];
2946 char *p;
2947 UINT length;
2949 /* Check for existing file */
2950 if (!pGetSystemWindowsDirectoryA)
2951 length = GetWindowsDirectoryA(buff, MAX_PATH);
2952 else
2953 length = pGetSystemWindowsDirectoryA(buff, MAX_PATH);
2955 if (length + sizeof(file) < MAX_PATH)
2957 p = buff + strlen(buff);
2958 if (p > buff && p[-1] != '\\') *p++ = '\\';
2959 strcpy( p, file );
2960 memset(&ofs, 0xA5, sizeof(ofs));
2961 SetLastError(0xfaceabee);
2963 hFile = OpenFile(buff, &ofs, OF_EXIST);
2964 ok( hFile == TRUE, "%s not found : %d\n", buff, GetLastError() );
2965 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
2966 "GetLastError() returns %d\n", GetLastError() );
2967 ok( ofs.cBytes == sizeof(ofs), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2968 ok( ofs.nErrCode == ERROR_SUCCESS, "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2969 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2970 "OpenFile returned '%s', but was expected to return '%s' or string filled with 0xA5\n",
2971 ofs.szPathName, buff );
2974 memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
2975 length = GetCurrentDirectoryA(MAX_PATH, buff);
2977 /* Check for nonexistent file */
2978 if (length + sizeof(foo) < MAX_PATH)
2980 p = buff + strlen(buff);
2981 if (p > buff && p[-1] != '\\') *p++ = '\\';
2982 strcpy( p, foo + 2 );
2983 memset(&ofs, 0xA5, sizeof(ofs));
2984 SetLastError(0xfaceabee);
2986 hFile = OpenFile(foo, &ofs, OF_EXIST);
2987 ok( hFile == HFILE_ERROR, "hFile != HFILE_ERROR : %d\n", GetLastError());
2988 ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError() returns %d\n", GetLastError() );
2989 todo_wine
2990 ok( ofs.cBytes == 0xA5, "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2991 ok( ofs.nErrCode == ERROR_FILE_NOT_FOUND, "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2992 ok( lstrcmpiA(ofs.szPathName, buff) == 0 || strncmp(ofs.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0,
2993 "OpenFile returned '%s', but was expected to return '%s' or string filled with 0xA5\n",
2994 ofs.szPathName, buff );
2997 length = GetCurrentDirectoryA(MAX_PATH, buff_long);
2998 length += lstrlenA(foo_too_long + 1);
3000 /* Check for nonexistent file with too long filename */
3001 if (length >= OFS_MAXPATHNAME && length < sizeof(buff_long))
3003 lstrcatA(buff_long, foo_too_long + 1); /* Avoid '.' during concatenation */
3004 memset(&ofs, 0xA5, sizeof(ofs));
3005 SetLastError(0xfaceabee);
3007 hFile = OpenFile(foo_too_long, &ofs, OF_EXIST);
3008 ok( hFile == HFILE_ERROR, "hFile != HFILE_ERROR : %d\n", GetLastError());
3009 ok( GetLastError() == ERROR_INVALID_DATA || GetLastError() == ERROR_FILENAME_EXCED_RANGE,
3010 "GetLastError() returns %d\n", GetLastError() );
3011 todo_wine
3012 ok( ofs.cBytes == 0xA5, "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3013 ok( ofs.nErrCode == ERROR_INVALID_DATA || ofs.nErrCode == ERROR_FILENAME_EXCED_RANGE,
3014 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3015 ok( strncmp(ofs.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0,
3016 "OpenFile returned '%s', but was expected to return string filled with 0xA5\n",
3017 ofs.szPathName );
3020 length = GetCurrentDirectoryA(MAX_PATH, buff) + sizeof(filename);
3022 if (length >= MAX_PATH)
3024 trace("Buffer too small, requested length = %d, but MAX_PATH = %d. Skipping test.\n", length, MAX_PATH);
3025 return;
3027 p = buff + strlen(buff);
3028 if (p > buff && p[-1] != '\\') *p++ = '\\';
3029 strcpy( p, filename );
3031 memset(&ofs, 0xA5, sizeof(ofs));
3032 SetLastError(0xfaceabee);
3033 /* Create an empty file */
3034 hFile = OpenFile(filename, &ofs, OF_CREATE);
3035 ok( hFile != HFILE_ERROR, "OpenFile failed to create nonexistent file\n" );
3036 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3037 "GetLastError() returns %d\n", GetLastError() );
3038 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3039 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3040 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3041 ret = _lclose(hFile);
3042 ok( !ret, "_lclose() returns %d\n", ret );
3043 retval = GetFileAttributesA(filename);
3044 ok( retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %d\n", GetLastError() );
3046 memset(&ofs, 0xA5, sizeof(ofs));
3047 SetLastError(0xfaceabee);
3048 /* Check various opening options: */
3049 /* for reading only, */
3050 hFile = OpenFile(filename, &ofs, OF_READ);
3051 ok( hFile != HFILE_ERROR, "OpenFile failed on read\n" );
3052 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3053 "GetLastError() returns %d\n", GetLastError() );
3054 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3055 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3056 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3057 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
3058 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
3059 ret = _lclose(hFile);
3060 ok( !ret, "_lclose() returns %d\n", ret );
3062 memset(&ofs, 0xA5, sizeof(ofs));
3063 SetLastError(0xfaceabee);
3064 /* for writing only, */
3065 hFile = OpenFile(filename, &ofs, OF_WRITE);
3066 ok( hFile != HFILE_ERROR, "OpenFile failed on write\n" );
3067 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3068 "GetLastError() returns %d\n", GetLastError() );
3069 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3070 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3071 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3072 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
3073 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
3074 ret = _lclose(hFile);
3075 ok( !ret, "_lclose() returns %d\n", ret );
3077 memset(&ofs, 0xA5, sizeof(ofs));
3078 SetLastError(0xfaceabee);
3079 /* for reading and writing, */
3080 hFile = OpenFile(filename, &ofs, OF_READWRITE);
3081 ok( hFile != HFILE_ERROR, "OpenFile failed on read/write\n" );
3082 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3083 "GetLastError() returns %d\n", GetLastError() );
3084 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3085 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3086 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3087 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
3088 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
3089 ret = _lclose(hFile);
3090 ok( !ret, "_lclose() returns %d\n", ret );
3092 memset(&ofs, 0xA5, sizeof(ofs));
3093 SetLastError(0xfaceabee);
3094 /* for checking file presence. */
3095 hFile = OpenFile(filename, &ofs, OF_EXIST);
3096 ok( hFile == 1, "OpenFile failed on finding our created file\n" );
3097 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3098 "GetLastError() returns %d\n", GetLastError() );
3099 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3100 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3101 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3102 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
3103 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
3105 memset(&ofs, 0xA5, sizeof(ofs));
3106 SetLastError(0xfaceabee);
3107 /* Delete the file and make sure it doesn't exist anymore */
3108 hFile = OpenFile(filename, &ofs, OF_DELETE);
3109 ok( hFile == 1, "OpenFile failed on delete (%d)\n", hFile );
3110 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3111 "GetLastError() returns %d\n", GetLastError() );
3112 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3113 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3114 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3115 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
3116 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
3118 retval = GetFileAttributesA(filename);
3119 ok( retval == INVALID_FILE_ATTRIBUTES, "GetFileAttributesA succeeded on deleted file\n" );
3122 static void test_overlapped(void)
3124 OVERLAPPED ov;
3125 DWORD r, result;
3127 /* GetOverlappedResult crashes if the 2nd or 3rd param are NULL */
3128 if (0) /* tested: WinXP */
3130 GetOverlappedResult(0, NULL, &result, FALSE);
3131 GetOverlappedResult(0, &ov, NULL, FALSE);
3132 GetOverlappedResult(0, NULL, NULL, FALSE);
3135 memset( &ov, 0, sizeof ov );
3136 result = 1;
3137 r = GetOverlappedResult(0, &ov, &result, 0);
3138 if (r)
3139 ok( result == 0, "wrong result %u\n", result );
3140 else /* win9x */
3141 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
3143 result = 0;
3144 ov.Internal = 0;
3145 ov.InternalHigh = 0xabcd;
3146 r = GetOverlappedResult(0, &ov, &result, 0);
3147 if (r)
3148 ok( result == 0xabcd, "wrong result %u\n", result );
3149 else /* win9x */
3150 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
3152 SetLastError( 0xb00 );
3153 result = 0;
3154 ov.Internal = STATUS_INVALID_HANDLE;
3155 ov.InternalHigh = 0xabcd;
3156 r = GetOverlappedResult(0, &ov, &result, 0);
3157 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
3158 ok( r == FALSE, "should return false\n");
3159 ok( result == 0xabcd || result == 0 /* win9x */, "wrong result %u\n", result );
3161 SetLastError( 0xb00 );
3162 result = 0;
3163 ov.Internal = STATUS_PENDING;
3164 ov.InternalHigh = 0xabcd;
3165 r = GetOverlappedResult(0, &ov, &result, 0);
3166 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
3167 "wrong error %u\n", GetLastError() );
3168 ok( r == FALSE, "should return false\n");
3169 ok( result == 0, "wrong result %u\n", result );
3171 SetLastError( 0xb00 );
3172 ov.hEvent = CreateEventW( NULL, 1, 1, NULL );
3173 ov.Internal = STATUS_PENDING;
3174 ov.InternalHigh = 0xabcd;
3175 r = GetOverlappedResult(0, &ov, &result, 0);
3176 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
3177 "wrong error %u\n", GetLastError() );
3178 ok( r == FALSE, "should return false\n");
3180 ResetEvent( ov.hEvent );
3182 SetLastError( 0xb00 );
3183 ov.Internal = STATUS_PENDING;
3184 ov.InternalHigh = 0;
3185 r = GetOverlappedResult(0, &ov, &result, 0);
3186 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
3187 "wrong error %u\n", GetLastError() );
3188 ok( r == FALSE, "should return false\n");
3190 r = CloseHandle( ov.hEvent );
3191 ok( r == TRUE, "close handle failed\n");
3194 static void test_RemoveDirectory(void)
3196 int rc;
3197 char directory[] = "removeme";
3199 rc = CreateDirectoryA(directory, NULL);
3200 ok( rc, "Createdirectory failed, gle=%d\n", GetLastError() );
3202 rc = SetCurrentDirectoryA(directory);
3203 ok( rc, "SetCurrentDirectory failed, gle=%d\n", GetLastError() );
3205 rc = RemoveDirectoryA(".");
3206 if (!rc)
3208 rc = SetCurrentDirectoryA("..");
3209 ok( rc, "SetCurrentDirectory failed, gle=%d\n", GetLastError() );
3211 rc = RemoveDirectoryA(directory);
3212 ok( rc, "RemoveDirectory failed, gle=%d\n", GetLastError() );
3216 static BOOL check_file_time( const FILETIME *ft1, const FILETIME *ft2, UINT tolerance )
3218 ULONGLONG t1 = ((ULONGLONG)ft1->dwHighDateTime << 32) | ft1->dwLowDateTime;
3219 ULONGLONG t2 = ((ULONGLONG)ft2->dwHighDateTime << 32) | ft2->dwLowDateTime;
3220 return abs(t1 - t2) <= tolerance;
3223 static void test_ReplaceFileA(void)
3225 char replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH];
3226 HANDLE hReplacedFile, hReplacementFile, hBackupFile;
3227 static const char replacedData[] = "file-to-replace";
3228 static const char replacementData[] = "new-file";
3229 static const char backupData[] = "backup-file";
3230 FILETIME ftReplaced, ftReplacement, ftBackup;
3231 static const char prefix[] = "pfx";
3232 char temp_path[MAX_PATH];
3233 DWORD ret;
3234 BOOL retok, removeBackup = FALSE;
3236 if (!pReplaceFileA)
3238 win_skip("ReplaceFileA() is missing\n");
3239 return;
3242 ret = GetTempPathA(MAX_PATH, temp_path);
3243 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
3244 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
3246 ret = GetTempFileNameA(temp_path, prefix, 0, replaced);
3247 ok(ret != 0, "GetTempFileNameA error (replaced) %d\n", GetLastError());
3249 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3250 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
3252 ret = GetTempFileNameA(temp_path, prefix, 0, backup);
3253 ok(ret != 0, "GetTempFileNameA error (backup) %d\n", GetLastError());
3255 /* place predictable data in the file to be replaced */
3256 hReplacedFile = CreateFileA(replaced, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
3257 ok(hReplacedFile != INVALID_HANDLE_VALUE,
3258 "failed to open replaced file\n");
3259 retok = WriteFile(hReplacedFile, replacedData, sizeof(replacedData), &ret, NULL );
3260 ok( retok && ret == sizeof(replacedData),
3261 "WriteFile error (replaced) %d\n", GetLastError());
3262 ok(GetFileSize(hReplacedFile, NULL) == sizeof(replacedData),
3263 "replaced file has wrong size\n");
3264 /* place predictable data in the file to be the replacement */
3265 hReplacementFile = CreateFileA(replacement, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
3266 ok(hReplacementFile != INVALID_HANDLE_VALUE,
3267 "failed to open replacement file\n");
3268 retok = WriteFile(hReplacementFile, replacementData, sizeof(replacementData), &ret, NULL );
3269 ok( retok && ret == sizeof(replacementData),
3270 "WriteFile error (replacement) %d\n", GetLastError());
3271 ok(GetFileSize(hReplacementFile, NULL) == sizeof(replacementData),
3272 "replacement file has wrong size\n");
3273 /* place predictable data in the backup file (to be over-written) */
3274 hBackupFile = CreateFileA(backup, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
3275 ok(hBackupFile != INVALID_HANDLE_VALUE,
3276 "failed to open backup file\n");
3277 retok = WriteFile(hBackupFile, backupData, sizeof(backupData), &ret, NULL );
3278 ok( retok && ret == sizeof(backupData),
3279 "WriteFile error (replacement) %d\n", GetLastError());
3280 ok(GetFileSize(hBackupFile, NULL) == sizeof(backupData),
3281 "backup file has wrong size\n");
3282 /* change the filetime on the "replaced" file to ensure that it changes */
3283 ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
3284 ok( ret, "GetFileTime error (replaced) %d\n", GetLastError());
3285 ftReplaced.dwLowDateTime -= 600000000; /* 60 second */
3286 ret = SetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
3287 ok( ret, "SetFileTime error (replaced) %d\n", GetLastError());
3288 GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced); /* get the actual time back */
3289 CloseHandle(hReplacedFile);
3290 /* change the filetime on the backup to ensure that it changes */
3291 ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
3292 ok( ret, "GetFileTime error (backup) %d\n", GetLastError());
3293 ftBackup.dwLowDateTime -= 1200000000; /* 120 second */
3294 ret = SetFileTime(hBackupFile, NULL, NULL, &ftBackup);
3295 ok( ret, "SetFileTime error (backup) %d\n", GetLastError());
3296 GetFileTime(hBackupFile, NULL, NULL, &ftBackup); /* get the actual time back */
3297 CloseHandle(hBackupFile);
3298 /* get the filetime on the replacement file to perform checks */
3299 ret = GetFileTime(hReplacementFile, NULL, NULL, &ftReplacement);
3300 ok( ret, "GetFileTime error (replacement) %d\n", GetLastError());
3301 CloseHandle(hReplacementFile);
3303 /* perform replacement w/ backup
3304 * TODO: flags are not implemented
3306 SetLastError(0xdeadbeef);
3307 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3308 ok(ret, "ReplaceFileA: unexpected error %d\n", GetLastError());
3309 /* make sure that the backup has the size of the old "replaced" file */
3310 hBackupFile = CreateFileA(backup, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
3311 ok(hBackupFile != INVALID_HANDLE_VALUE,
3312 "failed to open backup file\n");
3313 ret = GetFileSize(hBackupFile, NULL);
3314 ok(ret == sizeof(replacedData),
3315 "backup file has wrong size %d\n", ret);
3316 /* make sure that the "replaced" file has the size of the replacement file */
3317 hReplacedFile = CreateFileA(replaced, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
3318 ok(hReplacedFile != INVALID_HANDLE_VALUE,
3319 "failed to open replaced file: %d\n", GetLastError());
3320 if (hReplacedFile != INVALID_HANDLE_VALUE)
3322 ret = GetFileSize(hReplacedFile, NULL);
3323 ok(ret == sizeof(replacementData),
3324 "replaced file has wrong size %d\n", ret);
3325 /* make sure that the replacement file no-longer exists */
3326 hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
3327 ok(hReplacementFile == INVALID_HANDLE_VALUE,
3328 "unexpected error, replacement file should not exist %d\n", GetLastError());
3329 /* make sure that the backup has the old "replaced" filetime */
3330 ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
3331 ok( ret, "GetFileTime error (backup %d\n", GetLastError());
3332 ok(check_file_time(&ftBackup, &ftReplaced, 20000000), "backup file has wrong filetime\n");
3333 CloseHandle(hBackupFile);
3334 /* make sure that the "replaced" has the old replacement filetime */
3335 ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
3336 ok( ret, "GetFileTime error (backup %d\n", GetLastError());
3337 ok(check_file_time(&ftReplaced, &ftReplacement, 20000000),
3338 "replaced file has wrong filetime %x%08x / %x%08x\n",
3339 ftReplaced.dwHighDateTime, ftReplaced.dwLowDateTime,
3340 ftReplacement.dwHighDateTime, ftReplacement.dwLowDateTime );
3341 CloseHandle(hReplacedFile);
3343 else
3344 skip("couldn't open replacement file, skipping tests\n");
3346 /* re-create replacement file for pass w/o backup (blank) */
3347 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3348 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
3349 /* perform replacement w/o backup
3350 * TODO: flags are not implemented
3352 SetLastError(0xdeadbeef);
3353 ret = pReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
3354 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3355 "ReplaceFileA: unexpected error %d\n", GetLastError());
3357 /* re-create replacement file for pass w/ backup (backup-file not existing) */
3358 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3359 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
3360 ret = DeleteFileA(backup);
3361 ok(ret, "DeleteFileA: error (backup) %d\n", GetLastError());
3362 /* perform replacement w/ backup (no pre-existing backup)
3363 * TODO: flags are not implemented
3365 SetLastError(0xdeadbeef);
3366 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3367 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3368 "ReplaceFileA: unexpected error %d\n", GetLastError());
3369 if (ret)
3370 removeBackup = TRUE;
3372 /* re-create replacement file for pass w/ no permissions to "replaced" */
3373 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3374 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
3375 ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_READONLY);
3376 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3377 "SetFileAttributesA: error setting to read only %d\n", GetLastError());
3378 /* perform replacement w/ backup (no permission to "replaced")
3379 * TODO: flags are not implemented
3381 SetLastError(0xdeadbeef);
3382 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3383 ok(ret != ERROR_UNABLE_TO_REMOVE_REPLACED, "ReplaceFileA: unexpected error %d\n", GetLastError());
3384 /* make sure that the replacement file still exists */
3385 hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
3386 ok(hReplacementFile != INVALID_HANDLE_VALUE ||
3387 broken(GetLastError() == ERROR_FILE_NOT_FOUND), /* win2k */
3388 "unexpected error, replacement file should still exist %d\n", GetLastError());
3389 CloseHandle(hReplacementFile);
3390 ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_NORMAL);
3391 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3392 "SetFileAttributesA: error setting to normal %d\n", GetLastError());
3394 /* replacement file still exists, make pass w/o "replaced" */
3395 ret = DeleteFileA(replaced);
3396 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3397 "DeleteFileA: error (replaced) %d\n", GetLastError());
3398 /* perform replacement w/ backup (no pre-existing backup or "replaced")
3399 * TODO: flags are not implemented
3401 SetLastError(0xdeadbeef);
3402 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3403 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
3404 GetLastError() == ERROR_ACCESS_DENIED),
3405 "ReplaceFileA: unexpected error %d\n", GetLastError());
3407 /* perform replacement w/o existing "replacement" file
3408 * TODO: flags are not implemented
3410 SetLastError(0xdeadbeef);
3411 ret = pReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
3412 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
3413 GetLastError() == ERROR_ACCESS_DENIED),
3414 "ReplaceFileA: unexpected error %d\n", GetLastError());
3415 DeleteFileA( replacement );
3418 * if the first round (w/ backup) worked then as long as there is no
3419 * failure then there is no need to check this round (w/ backup is the
3420 * more complete case)
3423 /* delete temporary files, replacement and replaced are already deleted */
3424 if (removeBackup)
3426 ret = DeleteFileA(backup);
3427 ok(ret ||
3428 broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */
3429 "DeleteFileA: error (backup) %d\n", GetLastError());
3434 * ReplaceFileW is a simpler case of ReplaceFileA, there is no
3435 * need to be as thorough.
3437 static void test_ReplaceFileW(void)
3439 WCHAR replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH];
3440 static const WCHAR prefix[] = {'p','f','x',0};
3441 WCHAR temp_path[MAX_PATH];
3442 DWORD ret;
3443 BOOL removeBackup = FALSE;
3445 if (!pReplaceFileW)
3447 win_skip("ReplaceFileW() is missing\n");
3448 return;
3451 ret = GetTempPathW(MAX_PATH, temp_path);
3452 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
3454 win_skip("GetTempPathW is not available\n");
3455 return;
3457 ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
3458 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
3460 ret = GetTempFileNameW(temp_path, prefix, 0, replaced);
3461 ok(ret != 0, "GetTempFileNameW error (replaced) %d\n", GetLastError());
3463 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3464 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3466 ret = GetTempFileNameW(temp_path, prefix, 0, backup);
3467 ok(ret != 0, "GetTempFileNameW error (backup) %d\n", GetLastError());
3469 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3470 ok(ret, "ReplaceFileW: error %d\n", GetLastError());
3472 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3473 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3474 ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0);
3475 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3476 "ReplaceFileW: error %d\n", GetLastError());
3478 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3479 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3480 ret = DeleteFileW(backup);
3481 ok(ret, "DeleteFileW: error (backup) %d\n", GetLastError());
3482 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3483 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3484 "ReplaceFileW: error %d\n", GetLastError());
3486 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3487 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3488 ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_READONLY);
3489 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3490 "SetFileAttributesW: error setting to read only %d\n", GetLastError());
3492 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3493 ok(ret != ERROR_UNABLE_TO_REMOVE_REPLACED,
3494 "ReplaceFileW: unexpected error %d\n", GetLastError());
3495 ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_NORMAL);
3496 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3497 "SetFileAttributesW: error setting to normal %d\n", GetLastError());
3498 if (ret)
3499 removeBackup = TRUE;
3501 ret = DeleteFileW(replaced);
3502 ok(ret, "DeleteFileW: error (replaced) %d\n", GetLastError());
3503 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3504 ok(!ret, "ReplaceFileW: error %d\n", GetLastError());
3506 ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0);
3507 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
3508 GetLastError() == ERROR_ACCESS_DENIED),
3509 "ReplaceFileW: unexpected error %d\n", GetLastError());
3510 DeleteFileW( replacement );
3512 if (removeBackup)
3514 ret = DeleteFileW(backup);
3515 ok(ret ||
3516 broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */
3517 "DeleteFileW: error (backup) %d\n", GetLastError());
3521 static void test_CreateFile(void)
3523 static const struct test_data
3525 DWORD disposition, access, error, clean_up;
3526 } td[] =
3528 /* 0 */ { 0, 0, ERROR_INVALID_PARAMETER, 0 },
3529 /* 1 */ { 0, GENERIC_READ, ERROR_INVALID_PARAMETER, 0 },
3530 /* 2 */ { 0, GENERIC_READ|GENERIC_WRITE, ERROR_INVALID_PARAMETER, 0 },
3531 /* 3 */ { CREATE_NEW, 0, ERROR_FILE_EXISTS, 1 },
3532 /* 4 */ { CREATE_NEW, 0, 0, 1 },
3533 /* 5 */ { CREATE_NEW, GENERIC_READ, 0, 1 },
3534 /* 6 */ { CREATE_NEW, GENERIC_WRITE, 0, 1 },
3535 /* 7 */ { CREATE_NEW, GENERIC_READ|GENERIC_WRITE, 0, 0 },
3536 /* 8 */ { CREATE_ALWAYS, 0, 0, 0 },
3537 /* 9 */ { CREATE_ALWAYS, GENERIC_READ, 0, 0 },
3538 /* 10*/ { CREATE_ALWAYS, GENERIC_WRITE, 0, 0 },
3539 /* 11*/ { CREATE_ALWAYS, GENERIC_READ|GENERIC_WRITE, 0, 1 },
3540 /* 12*/ { OPEN_EXISTING, 0, ERROR_FILE_NOT_FOUND, 0 },
3541 /* 13*/ { CREATE_ALWAYS, 0, 0, 0 },
3542 /* 14*/ { OPEN_EXISTING, 0, 0, 0 },
3543 /* 15*/ { OPEN_EXISTING, GENERIC_READ, 0, 0 },
3544 /* 16*/ { OPEN_EXISTING, GENERIC_WRITE, 0, 0 },
3545 /* 17*/ { OPEN_EXISTING, GENERIC_READ|GENERIC_WRITE, 0, 1 },
3546 /* 18*/ { OPEN_ALWAYS, 0, 0, 0 },
3547 /* 19*/ { OPEN_ALWAYS, GENERIC_READ, 0, 0 },
3548 /* 20*/ { OPEN_ALWAYS, GENERIC_WRITE, 0, 0 },
3549 /* 21*/ { OPEN_ALWAYS, GENERIC_READ|GENERIC_WRITE, 0, 0 },
3550 /* 22*/ { TRUNCATE_EXISTING, 0, ERROR_INVALID_PARAMETER, 0 },
3551 /* 23*/ { TRUNCATE_EXISTING, GENERIC_READ, ERROR_INVALID_PARAMETER, 0 },
3552 /* 24*/ { TRUNCATE_EXISTING, GENERIC_WRITE, 0, 0 },
3553 /* 25*/ { TRUNCATE_EXISTING, GENERIC_READ|GENERIC_WRITE, 0, 0 },
3554 /* 26*/ { TRUNCATE_EXISTING, FILE_WRITE_DATA, ERROR_INVALID_PARAMETER, 0 }
3556 char temp_path[MAX_PATH];
3557 char file_name[MAX_PATH];
3558 DWORD i, ret, written;
3559 HANDLE hfile;
3561 GetTempPathA(MAX_PATH, temp_path);
3562 GetTempFileNameA(temp_path, "tmp", 0, file_name);
3564 i = strlen(temp_path);
3565 if (i && temp_path[i - 1] == '\\') temp_path[i - 1] = 0;
3567 for (i = 0; i <= 5; i++)
3569 SetLastError(0xdeadbeef);
3570 hfile = CreateFileA(temp_path, GENERIC_READ, 0, NULL, i, 0, 0);
3571 ok(hfile == INVALID_HANDLE_VALUE, "CreateFile should fail\n");
3572 if (i == 0 || i == 5)
3574 /* FIXME: remove once Wine is fixed */
3575 if (i == 5) todo_wine
3576 ok(GetLastError() == ERROR_INVALID_PARAMETER, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i, GetLastError());
3577 else
3578 ok(GetLastError() == ERROR_INVALID_PARAMETER, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i, GetLastError());
3580 else
3582 /* FIXME: remove once Wine is fixed */
3583 if (i == 1) todo_wine
3584 ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
3585 else
3586 ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
3589 SetLastError(0xdeadbeef);
3590 hfile = CreateFileA(temp_path, GENERIC_WRITE, 0, NULL, i, 0, 0);
3591 ok(hfile == INVALID_HANDLE_VALUE, "CreateFile should fail\n");
3592 if (i == 0)
3593 ok(GetLastError() == ERROR_INVALID_PARAMETER, "%d: expected ERROR_INVALID_PARAMETER, got %d\n", i, GetLastError());
3594 else
3596 /* FIXME: remove once Wine is fixed */
3597 if (i == 1) todo_wine
3598 ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
3599 else
3600 ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
3604 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
3606 SetLastError(0xdeadbeef);
3607 hfile = CreateFileA(file_name, td[i].access, 0, NULL, td[i].disposition, 0, 0);
3608 if (!td[i].error)
3610 ok(hfile != INVALID_HANDLE_VALUE, "%d: CreateFile error %d\n", i, GetLastError());
3611 written = 0xdeadbeef;
3612 SetLastError(0xdeadbeef);
3613 ret = WriteFile(hfile, &td[i].error, sizeof(td[i].error), &written, NULL);
3614 if (td[i].access & GENERIC_WRITE)
3615 ok(ret, "%d: WriteFile error %d\n", i, GetLastError());
3616 else
3618 ok(!ret, "%d: WriteFile should fail\n", i);
3619 ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
3621 CloseHandle(hfile);
3623 else
3625 /* FIXME: remove the condition below once Wine is fixed */
3626 if (td[i].disposition == TRUNCATE_EXISTING && !(td[i].access & GENERIC_WRITE))
3628 todo_wine
3630 ok(hfile == INVALID_HANDLE_VALUE, "%d: CreateFile should fail\n", i);
3631 ok(GetLastError() == td[i].error, "%d: expected %d, got %d\n", i, td[i].error, GetLastError());
3633 CloseHandle(hfile);
3635 else
3637 ok(hfile == INVALID_HANDLE_VALUE, "%d: CreateFile should fail\n", i);
3638 ok(GetLastError() == td[i].error, "%d: expected %d, got %d\n", i, td[i].error, GetLastError());
3642 if (td[i].clean_up) DeleteFileA(file_name);
3645 DeleteFileA(file_name);
3648 static void test_GetFileInformationByHandleEx(void)
3650 int i;
3651 char tempPath[MAX_PATH], tempFileName[MAX_PATH], buffer[1024];
3652 BOOL ret;
3653 DWORD ret2;
3654 HANDLE directory;
3655 FILE_ID_BOTH_DIR_INFO *bothDirInfo;
3656 struct {
3657 FILE_INFO_BY_HANDLE_CLASS handleClass;
3658 void *ptr;
3659 DWORD size;
3660 DWORD errorCode;
3661 } checks[] = {
3662 {0xdeadbeef, NULL, 0, ERROR_INVALID_PARAMETER},
3663 {FileIdBothDirectoryInfo, NULL, 0, ERROR_BAD_LENGTH},
3664 {FileIdBothDirectoryInfo, NULL, sizeof(buffer), ERROR_NOACCESS},
3665 {FileIdBothDirectoryInfo, buffer, 0, ERROR_BAD_LENGTH}};
3667 if (!pGetFileInformationByHandleEx)
3669 win_skip("GetFileInformationByHandleEx is missing.\n");
3670 return;
3673 ret2 = GetTempPathA(sizeof(tempPath), tempPath);
3674 ok(ret2, "GetFileInformationByHandleEx: GetTempPathA failed, got error %u.\n", GetLastError());
3676 /* ensure the existence of a file in the temp folder */
3677 ret2 = GetTempFileNameA(tempPath, "abc", 0, tempFileName);
3678 ok(ret2, "GetFileInformationByHandleEx: GetTempFileNameA failed, got error %u.\n", GetLastError());
3679 ret2 = GetFileAttributesA(tempFileName);
3680 ok(ret2 != INVALID_FILE_ATTRIBUTES, "GetFileInformationByHandleEx: "
3681 "GetFileAttributesA failed to find the temp file, got error %u.\n", GetLastError());
3683 directory = CreateFileA(tempPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
3684 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
3685 ok(directory != INVALID_HANDLE_VALUE, "GetFileInformationByHandleEx: failed to open the temp folder, "
3686 "got error %u.\n", GetLastError());
3688 for (i = 0; i < sizeof(checks) / sizeof(checks[0]); i += 1)
3690 SetLastError(0xdeadbeef);
3691 ret = pGetFileInformationByHandleEx(directory, checks[i].handleClass, checks[i].ptr, checks[i].size);
3692 ok(!ret && GetLastError() == checks[i].errorCode, "GetFileInformationByHandleEx: expected error %u, "
3693 "got %u.\n", checks[i].errorCode, GetLastError());
3696 while (TRUE)
3698 memset(buffer, 0xff, sizeof(buffer));
3699 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer));
3700 if (!ret && GetLastError() == ERROR_NO_MORE_FILES)
3701 break;
3702 ok(ret, "GetFileInformationByHandleEx: failed to query for FileIdBothDirectoryInfo, got error %u.\n", GetLastError());
3703 if (!ret)
3704 break;
3705 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
3706 while (TRUE)
3708 ok(bothDirInfo->FileAttributes != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file attributes.\n");
3709 ok(bothDirInfo->FileId.u.LowPart != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file id.\n");
3710 ok(bothDirInfo->FileNameLength != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file name length.\n");
3711 if (!bothDirInfo->NextEntryOffset)
3712 break;
3713 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)(((char *)bothDirInfo) + bothDirInfo->NextEntryOffset);
3717 CloseHandle(directory);
3718 DeleteFileA(tempFileName);
3721 static void test_OpenFileById(void)
3723 char tempPath[MAX_PATH], tempFileName[MAX_PATH], buffer[256], tickCount[256];
3724 WCHAR tempFileNameW[MAX_PATH];
3725 BOOL ret, found;
3726 DWORD ret2, count, tempFileNameLen;
3727 HANDLE directory, handle, tempFile;
3728 FILE_ID_BOTH_DIR_INFO *bothDirInfo;
3729 FILE_ID_DESCRIPTOR fileIdDescr;
3731 if (!pGetFileInformationByHandleEx || !pOpenFileById)
3733 win_skip("GetFileInformationByHandleEx or OpenFileById is missing.\n");
3734 return;
3737 ret2 = GetTempPathA(sizeof(tempPath), tempPath);
3738 ok(ret2, "OpenFileById: GetTempPath failed, got error %u.\n", GetLastError());
3740 /* ensure the existence of a file in the temp folder */
3741 ret2 = GetTempFileNameA(tempPath, "abc", 0, tempFileName);
3742 ok(ret2, "OpenFileById: GetTempFileNameA failed, got error %u.\n", GetLastError());
3743 ret2 = GetFileAttributesA(tempFileName);
3744 ok(ret2 != INVALID_FILE_ATTRIBUTES,
3745 "OpenFileById: GetFileAttributesA failed to find the temp file, got error %u\n", GetLastError());
3747 ret2 = MultiByteToWideChar(CP_ACP, 0, tempFileName + strlen(tempPath), -1, tempFileNameW, sizeof(tempFileNameW)/sizeof(tempFileNameW[0]));
3748 ok(ret2, "OpenFileById: MultiByteToWideChar failed to convert tempFileName, got error %u.\n", GetLastError());
3749 tempFileNameLen = ret2 - 1;
3751 tempFile = CreateFileA(tempFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
3752 ok(tempFile != INVALID_HANDLE_VALUE, "OpenFileById: failed to create a temp file, "
3753 "got error %u.\n", GetLastError());
3754 ret2 = sprintf(tickCount, "%u", GetTickCount());
3755 ret = WriteFile(tempFile, tickCount, ret2, &count, NULL);
3756 ok(ret, "OpenFileById: WriteFile failed, got error %u.\n", GetLastError());
3757 CloseHandle(tempFile);
3759 directory = CreateFileA(tempPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
3760 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
3761 ok(directory != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the temp folder, "
3762 "got error %u.\n", GetLastError());
3764 /* get info about the temp folder itself */
3765 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
3766 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer));
3767 ok(ret, "OpenFileById: failed to query for FileIdBothDirectoryInfo, got error %u.\n", GetLastError());
3768 ok(bothDirInfo->FileNameLength == sizeof(WCHAR) && bothDirInfo->FileName[0] == '.',
3769 "OpenFileById: failed to return the temp folder at the first entry, got error %u.\n", GetLastError());
3771 /* open the temp folder itself */
3772 fileIdDescr.dwSize = sizeof(fileIdDescr);
3773 fileIdDescr.Type = FileIdType;
3774 U(fileIdDescr).FileId = bothDirInfo->FileId;
3775 handle = pOpenFileById(directory, &fileIdDescr, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0);
3776 todo_wine
3777 ok(handle != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the temp folder itself, got error %u.\n", GetLastError());
3778 CloseHandle(handle);
3780 /* find the temp file in the temp folder */
3781 found = FALSE;
3782 while (!found)
3784 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer));
3785 ok(ret, "OpenFileById: failed to query for FileIdBothDirectoryInfo, got error %u.\n", GetLastError());
3786 if (!ret)
3787 break;
3788 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
3789 while (TRUE)
3791 if (tempFileNameLen == bothDirInfo->FileNameLength / sizeof(WCHAR) &&
3792 memcmp(tempFileNameW, bothDirInfo->FileName, bothDirInfo->FileNameLength) == 0)
3794 found = TRUE;
3795 break;
3797 if (!bothDirInfo->NextEntryOffset)
3798 break;
3799 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)(((char *)bothDirInfo) + bothDirInfo->NextEntryOffset);
3802 ok(found, "OpenFileById: failed to find the temp file in the temp folder.\n");
3804 SetLastError(0xdeadbeef);
3805 handle = pOpenFileById(directory, NULL, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0);
3806 ok(handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER,
3807 "OpenFileById: expected ERROR_INVALID_PARAMETER, got error %u.\n", GetLastError());
3809 fileIdDescr.dwSize = sizeof(fileIdDescr);
3810 fileIdDescr.Type = FileIdType;
3811 U(fileIdDescr).FileId = bothDirInfo->FileId;
3812 handle = pOpenFileById(directory, &fileIdDescr, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0);
3813 ok(handle != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the file, got error %u.\n", GetLastError());
3815 ret = ReadFile(handle, buffer, sizeof(buffer), &count, NULL);
3816 buffer[count] = 0;
3817 ok(ret, "OpenFileById: ReadFile failed, got error %u.\n", GetLastError());
3818 ok(strcmp(tickCount, buffer) == 0, "OpenFileById: invalid contents of the temp file.\n");
3820 CloseHandle(handle);
3821 CloseHandle(directory);
3822 DeleteFileA(tempFileName);
3825 static void test_SetFileValidData(void)
3827 BOOL ret;
3828 HANDLE handle;
3829 DWORD error, count;
3830 char path[MAX_PATH], filename[MAX_PATH];
3831 TOKEN_PRIVILEGES privs;
3832 HANDLE token = NULL;
3834 if (!pSetFileValidData)
3836 win_skip("SetFileValidData is missing\n");
3837 return;
3839 GetTempPathA(sizeof(path), path);
3840 GetTempFileNameA(path, "tst", 0, filename);
3841 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
3842 WriteFile(handle, "test", sizeof("test") - 1, &count, NULL);
3843 CloseHandle(handle);
3845 SetLastError(0xdeadbeef);
3846 ret = pSetFileValidData(INVALID_HANDLE_VALUE, 0);
3847 error = GetLastError();
3848 ok(!ret, "SetFileValidData succeeded\n");
3849 ok(error == ERROR_INVALID_HANDLE, "got %u\n", error);
3851 SetLastError(0xdeadbeef);
3852 ret = pSetFileValidData(INVALID_HANDLE_VALUE, -1);
3853 error = GetLastError();
3854 ok(!ret, "SetFileValidData succeeded\n");
3855 ok(error == ERROR_INVALID_HANDLE, "got %u\n", error);
3857 /* file opened for reading */
3858 handle = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
3860 SetLastError(0xdeadbeef);
3861 ret = pSetFileValidData(handle, 0);
3862 ok(!ret, "SetFileValidData succeeded\n");
3863 error = GetLastError();
3864 ok(error == ERROR_ACCESS_DENIED, "got %u\n", error);
3866 SetLastError(0xdeadbeef);
3867 ret = pSetFileValidData(handle, -1);
3868 error = GetLastError();
3869 ok(!ret, "SetFileValidData succeeded\n");
3870 ok(error == ERROR_ACCESS_DENIED, "got %u\n", error);
3871 CloseHandle(handle);
3873 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
3875 SetLastError(0xdeadbeef);
3876 ret = pSetFileValidData(handle, 0);
3877 error = GetLastError();
3878 ok(!ret, "SetFileValidData succeeded\n");
3879 todo_wine ok(error == ERROR_PRIVILEGE_NOT_HELD, "got %u\n", error);
3880 CloseHandle(handle);
3882 privs.PrivilegeCount = 1;
3883 privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
3885 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token) ||
3886 !LookupPrivilegeValueA(NULL, SE_MANAGE_VOLUME_NAME, &privs.Privileges[0].Luid) ||
3887 !AdjustTokenPrivileges(token, FALSE, &privs, sizeof(privs), NULL, NULL) ||
3888 GetLastError() == ERROR_NOT_ALL_ASSIGNED)
3890 win_skip("cannot enable SE_MANAGE_VOLUME_NAME privilege\n");
3891 CloseHandle(token);
3892 DeleteFileA(filename);
3893 return;
3895 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
3897 SetLastError(0xdeadbeef);
3898 ret = pSetFileValidData(handle, 0);
3899 error = GetLastError();
3900 ok(!ret, "SetFileValidData succeeded\n");
3901 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3903 SetLastError(0xdeadbeef);
3904 ret = pSetFileValidData(handle, -1);
3905 error = GetLastError();
3906 ok(!ret, "SetFileValidData succeeded\n");
3907 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3909 SetLastError(0xdeadbeef);
3910 ret = pSetFileValidData(handle, 2);
3911 error = GetLastError();
3912 todo_wine ok(!ret, "SetFileValidData succeeded\n");
3913 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3915 ret = pSetFileValidData(handle, 4);
3916 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3918 SetLastError(0xdeadbeef);
3919 ret = pSetFileValidData(handle, 8);
3920 error = GetLastError();
3921 ok(!ret, "SetFileValidData succeeded\n");
3922 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3924 count = SetFilePointer(handle, 1024, NULL, FILE_END);
3925 ok(count != INVALID_SET_FILE_POINTER, "SetFilePointer failed %u\n", GetLastError());
3926 ret = SetEndOfFile(handle);
3927 ok(ret, "SetEndOfFile failed %u\n", GetLastError());
3929 SetLastError(0xdeadbeef);
3930 ret = pSetFileValidData(handle, 2);
3931 error = GetLastError();
3932 todo_wine ok(!ret, "SetFileValidData succeeded\n");
3933 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3935 ret = pSetFileValidData(handle, 4);
3936 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3938 ret = pSetFileValidData(handle, 8);
3939 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3941 ret = pSetFileValidData(handle, 4);
3942 error = GetLastError();
3943 todo_wine ok(!ret, "SetFileValidData succeeded\n");
3944 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3946 ret = pSetFileValidData(handle, 1024);
3947 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3949 ret = pSetFileValidData(handle, 2048);
3950 error = GetLastError();
3951 ok(!ret, "SetFileValidData succeeded\n");
3952 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3954 privs.Privileges[0].Attributes = 0;
3955 AdjustTokenPrivileges(token, FALSE, &privs, sizeof(privs), NULL, NULL);
3957 CloseHandle(token);
3958 CloseHandle(handle);
3959 DeleteFileA(filename);
3962 static void test_WriteFileGather(void)
3964 char temp_path[MAX_PATH], filename[MAX_PATH];
3965 HANDLE hfile, hiocp1, hiocp2;
3966 DWORD ret, size;
3967 ULONG_PTR key;
3968 FILE_SEGMENT_ELEMENT fse[2];
3969 OVERLAPPED ovl, *povl = NULL;
3970 SYSTEM_INFO si;
3971 LPVOID buf = NULL;
3973 ret = GetTempPathA( MAX_PATH, temp_path );
3974 ok( ret != 0, "GetTempPathA error %d\n", GetLastError() );
3975 ok( ret < MAX_PATH, "temp path should fit into MAX_PATH\n" );
3976 ret = GetTempFileNameA( temp_path, "wfg", 0, filename );
3977 ok( ret != 0, "GetTempFileNameA error %d\n", GetLastError() );
3979 hfile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
3980 FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL, 0 );
3981 ok( hfile != INVALID_HANDLE_VALUE, "CreateFile failed err %u\n", GetLastError() );
3982 if (hfile == INVALID_HANDLE_VALUE) return;
3984 hiocp1 = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 999, 0 );
3985 hiocp2 = CreateIoCompletionPort( hfile, hiocp1, 999, 0 );
3986 ok( hiocp2 != 0, "CreateIoCompletionPort failed err %u\n", GetLastError() );
3988 GetSystemInfo( &si );
3989 buf = VirtualAlloc( NULL, si.dwPageSize, MEM_COMMIT, PAGE_READWRITE );
3990 ok( buf != NULL, "VirtualAlloc failed err %u\n", GetLastError() );
3992 memset( &ovl, 0, sizeof(ovl) );
3993 memset( fse, 0, sizeof(fse) );
3994 fse[0].Buffer = buf;
3995 if (!WriteFileGather( hfile, fse, si.dwPageSize, NULL, &ovl ))
3996 ok( GetLastError() == ERROR_IO_PENDING, "WriteFileGather failed err %u\n", GetLastError() );
3998 ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 1000 );
3999 ok( ret, "GetQueuedCompletionStatus failed err %u\n", GetLastError());
4000 ok( povl == &ovl, "wrong ovl %p\n", povl );
4002 memset( &ovl, 0, sizeof(ovl) );
4003 memset( fse, 0, sizeof(fse) );
4004 fse[0].Buffer = buf;
4005 if (!ReadFileScatter( hfile, fse, si.dwPageSize, NULL, &ovl ))
4006 ok( GetLastError() == ERROR_IO_PENDING, "ReadFileScatter failed err %u\n", GetLastError() );
4008 ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 1000 );
4009 ok( ret, "GetQueuedCompletionStatus failed err %u\n", GetLastError());
4010 ok( povl == &ovl, "wrong ovl %p\n", povl );
4012 CloseHandle( hfile );
4013 CloseHandle( hiocp1 );
4014 CloseHandle( hiocp2 );
4015 VirtualFree( buf, 0, MEM_RELEASE );
4016 DeleteFileA( filename );
4019 static unsigned file_map_access(unsigned access)
4021 if (access & GENERIC_READ) access |= FILE_GENERIC_READ;
4022 if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE;
4023 if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE;
4024 if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS;
4025 return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
4028 static BOOL is_access_compatible(unsigned obj_access, unsigned desired_access)
4030 obj_access = file_map_access(obj_access);
4031 desired_access = file_map_access(desired_access);
4032 return (obj_access & desired_access) == desired_access;
4035 static void test_file_access(void)
4037 static const struct
4039 unsigned access, create_error, write_error, read_error;
4040 } td[] =
4042 { GENERIC_READ | GENERIC_WRITE, 0, 0, 0 },
4043 { GENERIC_WRITE, 0, 0, ERROR_ACCESS_DENIED },
4044 { GENERIC_READ, 0, ERROR_ACCESS_DENIED, 0 },
4045 { FILE_READ_DATA | FILE_WRITE_DATA, 0, 0, 0 },
4046 { FILE_WRITE_DATA, 0, 0, ERROR_ACCESS_DENIED },
4047 { FILE_READ_DATA, 0, ERROR_ACCESS_DENIED, 0 },
4048 { FILE_APPEND_DATA, 0, 0, ERROR_ACCESS_DENIED },
4049 { FILE_READ_DATA | FILE_APPEND_DATA, 0, 0, 0 },
4050 { FILE_WRITE_DATA | FILE_APPEND_DATA, 0, 0, ERROR_ACCESS_DENIED },
4051 { 0, 0, ERROR_ACCESS_DENIED, ERROR_ACCESS_DENIED },
4053 char path[MAX_PATH], fname[MAX_PATH];
4054 unsigned char buf[16];
4055 HANDLE hfile, hdup;
4056 DWORD i, j, ret, bytes;
4058 GetTempPathA(MAX_PATH, path);
4059 GetTempFileNameA(path, "foo", 0, fname);
4061 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
4063 SetLastError(0xdeadbeef);
4064 hfile = CreateFileA(fname, td[i].access, 0, NULL, CREATE_ALWAYS,
4065 FILE_FLAG_DELETE_ON_CLOSE, 0);
4066 if (td[i].create_error)
4068 ok(hfile == INVALID_HANDLE_VALUE, "%d: CreateFile should fail\n", i);
4069 ok(td[i].create_error == GetLastError(), "%d: expected %d, got %d\n", i, td[i].create_error, GetLastError());
4070 continue;
4072 else
4073 ok(hfile != INVALID_HANDLE_VALUE, "%d: CreateFile error %d\n", i, GetLastError());
4075 for (j = 0; j < sizeof(td)/sizeof(td[0]); j++)
4077 SetLastError(0xdeadbeef);
4078 ret = DuplicateHandle(GetCurrentProcess(), hfile, GetCurrentProcess(), &hdup,
4079 td[j].access, 0, 0);
4080 if (is_access_compatible(td[i].access, td[j].access))
4081 ok(ret, "DuplicateHandle(%#x => %#x) error %d\n", td[i].access, td[j].access, GetLastError());
4082 else
4084 /* FIXME: Remove once Wine is fixed */
4085 if ((td[j].access & (GENERIC_READ | GENERIC_WRITE)) ||
4086 (!(td[i].access & (GENERIC_WRITE | FILE_WRITE_DATA)) && (td[j].access & FILE_WRITE_DATA)) ||
4087 (!(td[i].access & (GENERIC_READ | FILE_READ_DATA)) && (td[j].access & FILE_READ_DATA)) ||
4088 (!(td[i].access & (GENERIC_WRITE)) && (td[j].access & FILE_APPEND_DATA)))
4090 todo_wine
4091 ok(!ret, "DuplicateHandle(%#x => %#x) should fail\n", td[i].access, td[j].access);
4092 todo_wine
4093 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
4095 else
4097 ok(!ret, "DuplicateHandle(%#x => %#x) should fail\n", td[i].access, td[j].access);
4098 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
4101 if (ret) CloseHandle(hdup);
4104 SetLastError(0xdeadbeef);
4105 bytes = 0xdeadbeef;
4106 ret = WriteFile(hfile, "\x5e\xa7", 2, &bytes, NULL);
4107 if (td[i].write_error)
4109 ok(!ret, "%d: WriteFile should fail\n", i);
4110 ok(td[i].write_error == GetLastError(), "%d: expected %d, got %d\n", i, td[i].write_error, GetLastError());
4111 ok(bytes == 0, "%d: expected 0, got %u\n", i, bytes);
4113 else
4115 ok(ret, "%d: WriteFile error %d\n", i, GetLastError());
4116 ok(bytes == 2, "%d: expected 2, got %u\n", i, bytes);
4119 SetLastError(0xdeadbeef);
4120 ret = SetFilePointer(hfile, 0, NULL, FILE_BEGIN);
4121 ok(ret != INVALID_SET_FILE_POINTER, "SetFilePointer error %d\n", GetLastError());
4123 SetLastError(0xdeadbeef);
4124 bytes = 0xdeadbeef;
4125 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, NULL);
4126 if (td[i].read_error)
4128 ok(!ret, "%d: ReadFile should fail\n", i);
4129 ok(td[i].read_error == GetLastError(), "%d: expected %d, got %d\n", i, td[i].read_error, GetLastError());
4130 ok(bytes == 0, "%d: expected 0, got %u\n", i, bytes);
4132 else
4134 ok(ret, "%d: ReadFile error %d\n", i, GetLastError());
4135 if (td[i].write_error)
4136 ok(bytes == 0, "%d: expected 0, got %u\n", i, bytes);
4137 else
4139 ok(bytes == 2, "%d: expected 2, got %u\n", i, bytes);
4140 ok(buf[0] == 0x5e && buf[1] == 0xa7, "%d: expected 5ea7, got %02x%02x\n", i, buf[0], buf[1]);
4144 CloseHandle(hfile);
4148 START_TEST(file)
4150 InitFunctionPointers();
4152 test__hread( );
4153 test__hwrite( );
4154 test__lclose( );
4155 test__lcreat( );
4156 test__llseek( );
4157 test__llopen( );
4158 test__lread( );
4159 test__lwrite( );
4160 test_GetTempFileNameA();
4161 test_CopyFileA();
4162 test_CopyFileW();
4163 test_CopyFile2();
4164 test_CreateFile();
4165 test_CreateFileA();
4166 test_CreateFileW();
4167 test_CreateFile2();
4168 test_DeleteFileA();
4169 test_DeleteFileW();
4170 test_MoveFileA();
4171 test_MoveFileW();
4172 test_FindFirstFileA();
4173 test_FindNextFileA();
4174 test_FindFirstFileExA(0);
4175 /* FindExLimitToDirectories is ignored if the file system doesn't support directory filtering */
4176 test_FindFirstFileExA(FindExSearchLimitToDirectories);
4177 test_LockFile();
4178 test_file_sharing();
4179 test_offset_in_overlapped_structure();
4180 test_MapFile();
4181 test_GetFileType();
4182 test_async_file_errors();
4183 test_read_write();
4184 test_OpenFile();
4185 test_overlapped();
4186 test_RemoveDirectory();
4187 test_ReplaceFileA();
4188 test_ReplaceFileW();
4189 test_GetFileInformationByHandleEx();
4190 test_OpenFileById();
4191 test_SetFileValidData();
4192 test_WriteFileGather();
4193 test_file_access();