ntdll: Buffer pagemap reads in fill_working_set_info().
[wine.git] / dlls / kernel32 / tests / file.c
blob9e0371452b312042af603637172c3e89c05b3af8
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 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <time.h>
26 #include <stdio.h>
28 #include "ntstatus.h"
29 #define WIN32_NO_STATUS
30 #include "wine/test.h"
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winerror.h"
34 #include "winternl.h"
35 #include "winnls.h"
36 #include "fileapi.h"
38 #undef DeleteFile /* needed for FILE_DISPOSITION_INFO */
40 static HANDLE (WINAPI *pFindFirstFileExA)(LPCSTR,FINDEX_INFO_LEVELS,LPVOID,FINDEX_SEARCH_OPS,LPVOID,DWORD);
41 static BOOL (WINAPI *pReplaceFileW)(LPCWSTR, LPCWSTR, LPCWSTR, DWORD, LPVOID, LPVOID);
42 static UINT (WINAPI *pGetSystemWindowsDirectoryA)(LPSTR, UINT);
43 static BOOL (WINAPI *pGetVolumeNameForVolumeMountPointA)(LPCSTR, LPSTR, DWORD);
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*);
49 static DWORD (WINAPI *pGetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD, DWORD);
50 static DWORD (WINAPI *pGetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD, DWORD);
51 static NTSTATUS (WINAPI *pNtCreateFile)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
52 PLARGE_INTEGER, ULONG, ULONG, ULONG, ULONG, PVOID, ULONG);
53 static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(LPCWSTR, PUNICODE_STRING, PWSTR*, CURDIR*);
54 static NTSTATUS (WINAPI *pRtlAnsiStringToUnicodeString)(PUNICODE_STRING, PCANSI_STRING, BOOLEAN);
55 static BOOL (WINAPI *pSetFileInformationByHandle)(HANDLE, FILE_INFO_BY_HANDLE_CLASS, void*, DWORD);
56 static BOOL (WINAPI *pGetQueuedCompletionStatusEx)(HANDLE, OVERLAPPED_ENTRY*, ULONG, ULONG*, DWORD, BOOL);
57 static HANDLE (WINAPI *pReOpenFile)(HANDLE, DWORD, DWORD, DWORD);
58 static void (WINAPI *pRtlInitAnsiString)(PANSI_STRING,PCSZ);
59 static void (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);
60 static BOOL (WINAPI *pSetFileCompletionNotificationModes)(HANDLE, UCHAR);
61 static HANDLE (WINAPI *pFindFirstStreamW)(LPCWSTR filename, STREAM_INFO_LEVELS infolevel, void *data, DWORD flags);
63 static char filename[MAX_PATH];
64 static const char sillytext[] =
65 "en larvig liten text dx \033 gx hej 84 hej 4484 ! \001\033 bla bl\na.. bla bla."
66 "1234 43 4kljf lf &%%%&&&&&& 34 4 34 3############# 33 3 3 3 # 3## 3"
67 "1234 43 4kljf lf &%%%&&&&&& 34 4 34 3############# 33 3 3 3 # 3## 3"
68 "1234 43 4kljf lf &%%%&&&&&& 34 4 34 3############# 33 3 3 3 # 3## 3"
69 "1234 43 4kljf lf &%%%&&&&&& 34 4 34 3############# 33 3 3 3 # 3## 3"
70 "1234 43 4kljf lf &%%%&&&&&& 34 4 34 3############# 33 3 3 3 # 3## 3"
71 "1234 43 4kljf lf &%%%&&&&&& 34 4 34 3############# 33 3 3 3 # 3## 3"
72 "1234 43 4kljf lf &%%%&&&&&& 34 4 34 3############# 33 3 3 3 # 3## 3"
73 "1234 43 4kljf lf &%%%&&&&&& 34 4 34 3############# 33 3 3 3 # 3## 3"
74 "sdlkfjasdlkfj a dslkj adsklf \n \nasdklf askldfa sdlkf \nsadklf asdklf asdf ";
76 struct test_list {
77 const char *file; /* file string to test */
78 const DWORD err; /* Win NT and further error code */
79 const LONG err2; /* Win 9x & ME error code or -1 */
80 const DWORD options; /* option flag to use for open */
81 const BOOL todo_flag; /* todo_wine indicator */
82 } ;
84 static void InitFunctionPointers(void)
86 HMODULE hntdll = GetModuleHandleA("ntdll");
87 HMODULE hkernel32 = GetModuleHandleA("kernel32");
89 pNtCreateFile = (void *)GetProcAddress(hntdll, "NtCreateFile");
90 pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U");
91 pRtlAnsiStringToUnicodeString = (void *)GetProcAddress(hntdll, "RtlAnsiStringToUnicodeString");
92 pRtlInitAnsiString = (void *)GetProcAddress(hntdll, "RtlInitAnsiString");
93 pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString");
95 pFindFirstFileExA=(void*)GetProcAddress(hkernel32, "FindFirstFileExA");
96 pReplaceFileW=(void*)GetProcAddress(hkernel32, "ReplaceFileW");
97 pGetSystemWindowsDirectoryA=(void*)GetProcAddress(hkernel32, "GetSystemWindowsDirectoryA");
98 pGetVolumeNameForVolumeMountPointA = (void *) GetProcAddress(hkernel32, "GetVolumeNameForVolumeMountPointA");
99 pGetFileInformationByHandleEx = (void *) GetProcAddress(hkernel32, "GetFileInformationByHandleEx");
100 pOpenFileById = (void *) GetProcAddress(hkernel32, "OpenFileById");
101 pSetFileValidData = (void *) GetProcAddress(hkernel32, "SetFileValidData");
102 pCopyFile2 = (void *) GetProcAddress(hkernel32, "CopyFile2");
103 pCreateFile2 = (void *) GetProcAddress(hkernel32, "CreateFile2");
104 pGetFinalPathNameByHandleA = (void *) GetProcAddress(hkernel32, "GetFinalPathNameByHandleA");
105 pGetFinalPathNameByHandleW = (void *) GetProcAddress(hkernel32, "GetFinalPathNameByHandleW");
106 pSetFileInformationByHandle = (void *) GetProcAddress(hkernel32, "SetFileInformationByHandle");
107 pGetQueuedCompletionStatusEx = (void *) GetProcAddress(hkernel32, "GetQueuedCompletionStatusEx");
108 pReOpenFile = (void *) GetProcAddress(hkernel32, "ReOpenFile");
109 pSetFileCompletionNotificationModes = (void *)GetProcAddress(hkernel32, "SetFileCompletionNotificationModes");
110 pFindFirstStreamW = (void *)GetProcAddress(hkernel32, "FindFirstStreamW");
113 static void create_file( const char *path )
115 FILE *f = fopen( path, "wb" );
116 fputs( path, f );
117 fclose( f );
120 static void test__hread( void )
122 HFILE filehandle;
123 char buffer[10000];
124 LONG bytes_read;
125 LONG bytes_wanted;
126 LONG i;
127 BOOL ret;
129 SetFileAttributesA(filename,FILE_ATTRIBUTE_NORMAL); /* be sure to remove stale files */
130 DeleteFileA( filename );
131 filehandle = _lcreat( filename, 0 );
132 if (filehandle == HFILE_ERROR)
134 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
135 return;
138 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
140 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
142 filehandle = _lopen( filename, OF_READ );
144 ok( HFILE_ERROR != filehandle, "couldn't open file \"%s\" again (err=%ld)\n", filename, GetLastError( ) );
146 bytes_read = _hread( filehandle, buffer, 2 * strlen( sillytext ) );
148 ok( lstrlenA( sillytext ) == bytes_read, "file read size error\n" );
150 for (bytes_wanted = 0; bytes_wanted < lstrlenA( sillytext ); bytes_wanted++)
152 ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
153 ok( _hread( filehandle, buffer, bytes_wanted ) == bytes_wanted, "erratic _hread return value\n" );
154 for (i = 0; i < bytes_wanted; i++)
156 ok( buffer[i] == sillytext[i], "that's not what's written\n" );
160 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
162 ret = DeleteFileA( filename );
163 ok( ret != 0, "DeleteFile failed (%ld)\n", GetLastError( ) );
167 static void test__hwrite( void )
169 HFILE filehandle;
170 char buffer[10000];
171 LONG bytes_read;
172 LONG bytes_written;
173 ULONG blocks;
174 LONG i;
175 char *contents;
176 HLOCAL memory_object;
177 char checksum[1];
178 BOOL ret;
180 filehandle = _lcreat( filename, 0 );
181 if (filehandle == HFILE_ERROR)
183 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
184 return;
187 ok( HFILE_ERROR != _hwrite( filehandle, "", 0 ), "_hwrite complains\n" );
189 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
191 filehandle = _lopen( filename, OF_READ );
193 bytes_read = _hread( filehandle, buffer, 1);
195 ok( 0 == bytes_read, "file read size error\n" );
197 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
199 filehandle = _lopen( filename, OF_READWRITE );
201 bytes_written = 0;
202 checksum[0] = '\0';
203 srand( (unsigned)time( NULL ) );
204 for (blocks = 0; blocks < 100; blocks++)
206 for (i = 0; i < (LONG)sizeof( buffer ); i++)
208 buffer[i] = rand( );
209 checksum[0] = checksum[0] + buffer[i];
211 ok( HFILE_ERROR != _hwrite( filehandle, buffer, sizeof( buffer ) ), "_hwrite complains\n" );
212 bytes_written = bytes_written + sizeof( buffer );
215 ok( HFILE_ERROR != _hwrite( filehandle, checksum, 1 ), "_hwrite complains\n" );
216 bytes_written++;
218 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
220 memory_object = LocalAlloc( LPTR, bytes_written );
222 ok( 0 != memory_object, "LocalAlloc fails. (Could be out of memory.)\n" );
224 contents = LocalLock( memory_object );
225 ok( NULL != contents, "LocalLock whines\n" );
227 filehandle = _lopen( filename, OF_READ );
229 contents = LocalLock( memory_object );
230 ok( NULL != contents, "LocalLock whines\n" );
232 ok( bytes_written == _hread( filehandle, contents, bytes_written), "read length differ from write length\n" );
234 checksum[0] = '\0';
235 i = 0;
238 checksum[0] = checksum[0] + contents[i];
239 i++;
241 while (i < bytes_written - 1);
243 ok( checksum[0] == contents[i], "stored checksum differ from computed checksum\n" );
245 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
247 ret = DeleteFileA( filename );
248 ok( ret != 0, "DeleteFile failed (%ld)\n", GetLastError( ) );
250 LocalFree( contents );
254 static void test__lclose( void )
256 HFILE filehandle;
257 BOOL ret;
259 filehandle = _lcreat( filename, 0 );
260 if (filehandle == HFILE_ERROR)
262 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
263 return;
266 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
268 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
270 ret = DeleteFileA( filename );
271 ok( ret != 0, "DeleteFile failed (%ld)\n", GetLastError( ) );
274 /* helper function for test__lcreat */
275 static void get_nt_pathW( const char *name, UNICODE_STRING *nameW )
277 UNICODE_STRING strW;
278 ANSI_STRING str;
279 NTSTATUS status;
280 BOOLEAN ret;
282 pRtlInitAnsiString( &str, name );
284 status = pRtlAnsiStringToUnicodeString( &strW, &str, TRUE );
285 ok( !status, "RtlAnsiStringToUnicodeString failed with %08lx\n", status );
287 ret = pRtlDosPathNameToNtPathName_U( strW.Buffer, nameW, NULL, NULL );
288 ok( ret, "RtlDosPathNameToNtPathName_U failed\n" );
290 pRtlFreeUnicodeString( &strW );
293 static void test__lcreat( void )
295 UNICODE_STRING filenameW;
296 OBJECT_ATTRIBUTES attr;
297 IO_STATUS_BLOCK io;
298 HFILE filehandle;
299 char buffer[10000];
300 WIN32_FIND_DATAA search_results;
301 char slashname[] = "testfi/";
302 int err;
303 HANDLE find, file;
304 NTSTATUS status;
305 BOOL ret;
307 filehandle = _lcreat( filename, 0 );
308 if (filehandle == HFILE_ERROR)
310 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
311 return;
314 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
316 ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
318 ok( _hread( filehandle, buffer, strlen( sillytext ) ) == lstrlenA( sillytext ), "erratic _hread return value\n" );
320 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
322 find = FindFirstFileA( filename, &search_results );
323 ok( INVALID_HANDLE_VALUE != find, "should be able to find file\n" );
324 FindClose( find );
326 ret = DeleteFileA(filename);
327 ok( ret != 0, "DeleteFile failed (%ld)\n", GetLastError());
329 filehandle = _lcreat( filename, 1 ); /* readonly */
330 ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%ld)\n", filename, GetLastError( ) );
332 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite shouldn't be able to write never the less\n" );
334 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
336 find = FindFirstFileA( filename, &search_results );
337 ok( INVALID_HANDLE_VALUE != find, "should be able to find file\n" );
338 FindClose( find );
340 SetLastError( 0xdeadbeef );
341 ok( 0 == DeleteFileA( filename ), "shouldn't be able to delete a readonly file\n" );
342 ok( GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError() );
344 ok( SetFileAttributesA(filename, FILE_ATTRIBUTE_NORMAL ) != 0, "couldn't change attributes on file\n" );
346 ok( DeleteFileA( filename ) != 0, "now it should be possible to delete the file!\n" );
348 filehandle = _lcreat( filename, 1 ); /* readonly */
349 ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%ld)\n", filename, GetLastError() );
350 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen(sillytext) ),
351 "_hwrite shouldn't be able to write never the less\n" );
352 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
354 find = FindFirstFileA( filename, &search_results );
355 ok( INVALID_HANDLE_VALUE != find, "should be able to find file\n" );
356 FindClose( find );
358 get_nt_pathW( filename, &filenameW );
359 attr.Length = sizeof(attr);
360 attr.RootDirectory = 0;
361 attr.Attributes = OBJ_CASE_INSENSITIVE;
362 attr.ObjectName = &filenameW;
363 attr.SecurityDescriptor = NULL;
364 attr.SecurityQualityOfService = NULL;
366 status = pNtCreateFile( &file, GENERIC_READ | GENERIC_WRITE | DELETE, &attr, &io, NULL, 0,
367 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
368 FILE_OPEN, FILE_DELETE_ON_CLOSE | FILE_NON_DIRECTORY_FILE, NULL, 0 );
369 ok( status == STATUS_ACCESS_DENIED, "expected STATUS_ACCESS_DENIED, got %08lx\n", status );
370 ok( GetFileAttributesA( filename ) != INVALID_FILE_ATTRIBUTES, "file was deleted\n" );
372 status = pNtCreateFile( &file, DELETE, &attr, &io, NULL, 0,
373 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
374 FILE_OPEN, FILE_DELETE_ON_CLOSE | FILE_NON_DIRECTORY_FILE, NULL, 0 );
375 ok( status == STATUS_CANNOT_DELETE, "expected STATUS_CANNOT_DELETE, got %08lx\n", status );
377 status = pNtCreateFile( &file, DELETE, &attr, &io, NULL, 0,
378 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
379 FILE_OPEN, FILE_DELETE_ON_CLOSE | FILE_DIRECTORY_FILE, NULL, 0 );
380 ok( status == STATUS_NOT_A_DIRECTORY, "expected STATUS_NOT_A_DIRECTORY, got %08lx\n", status );
382 status = pNtCreateFile( &file, DELETE, &attr, &io, NULL, 0,
383 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
384 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE | FILE_NON_DIRECTORY_FILE, NULL, 0 );
385 todo_wine
386 ok( status == STATUS_CANNOT_DELETE, "expected STATUS_CANNOT_DELETE, got %08lx\n", status );
387 if (!status) CloseHandle( file );
389 pRtlFreeUnicodeString( &filenameW );
391 todo_wine
392 ok( GetFileAttributesA( filename ) != INVALID_FILE_ATTRIBUTES, "file was deleted\n" );
393 todo_wine
394 ok( SetFileAttributesA(filename, FILE_ATTRIBUTE_NORMAL ) != 0, "couldn't change attributes on file\n" );
395 todo_wine
396 ok( DeleteFileA( filename ) != 0, "now it should be possible to delete the file\n" );
398 filehandle = _lcreat( filename, 2 );
399 ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%ld)\n", filename, GetLastError( ) );
401 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
403 ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
405 ok( _hread( filehandle, buffer, strlen( sillytext ) ) == lstrlenA( sillytext ), "erratic _hread return value\n" );
407 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
409 find = FindFirstFileA( filename, &search_results );
410 ok( INVALID_HANDLE_VALUE != find, "should STILL be able to find file\n" );
411 FindClose( find );
413 ret = DeleteFileA( filename );
414 ok( ret, "DeleteFile failed (%ld)\n", GetLastError( ) );
416 filehandle = _lcreat( filename, 4 ); /* SYSTEM file */
417 ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%ld)\n", filename, GetLastError( ) );
419 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
421 ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
423 ok( _hread( filehandle, buffer, strlen( sillytext ) ) == lstrlenA( sillytext ), "erratic _hread return value\n" );
425 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
427 find = FindFirstFileA( filename, &search_results );
428 ok( INVALID_HANDLE_VALUE != find, "should STILL be able to find file\n" );
429 FindClose( find );
431 ret = DeleteFileA( filename );
432 ok( ret, "DeleteFile failed (%ld)\n", GetLastError( ) );
434 filehandle=_lcreat (slashname, 0); /* illegal name */
435 ok( filehandle == HFILE_ERROR, "succeeded\n" );
436 err=GetLastError ();
437 ok (err==ERROR_INVALID_NAME || err==ERROR_PATH_NOT_FOUND,
438 "creating file \"%s\" failed with error %d\n", slashname, err);
440 filehandle=_lcreat (filename, 8); /* illegal attribute */
441 if (HFILE_ERROR==filehandle)
442 ok (0, "couldn't create volume label \"%s\"\n", filename);
443 else {
444 _lclose(filehandle);
445 find=FindFirstFileA (filename, &search_results);
446 if (INVALID_HANDLE_VALUE==find)
447 ok (0, "file \"%s\" not found\n", filename);
448 else {
449 const char *name = strrchr(filename, '\\');
451 if (name) name++;
452 else name = filename;
454 ret = FindClose(find);
455 ok ( 0 != ret, "FindClose complains (%ld)\n", GetLastError ());
456 ok (!strcmp (name, search_results.cFileName),
457 "expected \"%s\", got \"%s\"\n", name, search_results.cFileName);
458 search_results.dwFileAttributes &= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
459 search_results.dwFileAttributes &= ~FILE_ATTRIBUTE_COMPRESSED;
460 ok (FILE_ATTRIBUTE_ARCHIVE==search_results.dwFileAttributes,
461 "attributes of file \"%s\" are 0x%04lx\n", search_results.cFileName,
462 search_results.dwFileAttributes);
464 ret = DeleteFileA( filename );
465 ok( ret, "DeleteFile failed (%ld)\n", GetLastError( ) );
470 static void test__llseek( void )
472 INT i;
473 HFILE filehandle;
474 char buffer[1];
475 LONG bytes_read;
476 BOOL ret;
478 filehandle = _lcreat( filename, 0 );
479 if (filehandle == HFILE_ERROR)
481 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
482 return;
485 for (i = 0; i < 400; i++)
487 ok( _hwrite( filehandle, sillytext, strlen( sillytext ) ) != -1, "_hwrite complains\n" );
489 ok( _llseek( filehandle, 400 * strlen( sillytext ), FILE_CURRENT ) != -1, "should be able to seek\n" );
490 ok( _llseek( filehandle, 27 + 35 * strlen( sillytext ), FILE_BEGIN ) != -1, "should be able to seek\n" );
492 bytes_read = _hread( filehandle, buffer, 1);
493 ok( 1 == bytes_read, "file read size error\n" );
494 ok( buffer[0] == sillytext[27], "_llseek error, it got lost seeking\n" );
495 ok( _llseek( filehandle, -400 * (LONG)strlen( sillytext ), FILE_END ) != -1, "should be able to seek\n" );
497 bytes_read = _hread( filehandle, buffer, 1);
498 ok( 1 == bytes_read, "file read size error\n" );
499 ok( buffer[0] == sillytext[0], "_llseek error, it got lost seeking\n" );
500 ok( _llseek( filehandle, 1000000, FILE_END ) != -1, "should be able to seek past file; poor, poor Windows programmers\n" );
501 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
503 ret = DeleteFileA( filename );
504 ok( ret, "DeleteFile failed (%ld)\n", GetLastError( ) );
508 static void test__llopen( void )
510 HFILE filehandle;
511 UINT bytes_read;
512 char buffer[10000];
513 BOOL ret;
515 filehandle = _lcreat( filename, 0 );
516 if (filehandle == HFILE_ERROR)
518 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
519 return;
522 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
523 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
525 filehandle = _lopen( filename, OF_READ );
526 ok( HFILE_ERROR == _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite shouldn't be able to write!\n" );
527 bytes_read = _hread( filehandle, buffer, strlen( sillytext ) );
528 ok( strlen( sillytext ) == bytes_read, "file read size error\n" );
529 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
531 filehandle = _lopen( filename, OF_READWRITE );
532 bytes_read = _hread( filehandle, buffer, 2 * strlen( sillytext ) );
533 ok( strlen( sillytext ) == bytes_read, "file read size error\n" );
534 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite should write just fine\n" );
535 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
537 filehandle = _lopen( filename, OF_WRITE );
538 ok( HFILE_ERROR == _hread( filehandle, buffer, 1 ), "you should only be able to write this file\n" );
539 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite should write just fine\n" );
540 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
542 ret = DeleteFileA( filename );
543 ok( ret, "DeleteFile failed (%ld)\n", GetLastError( ) );
544 /* TODO - add tests for the SHARE modes - use two processes to pull this one off */
548 static void test__lread( void )
550 HFILE filehandle;
551 char buffer[10000];
552 UINT bytes_read;
553 UINT bytes_wanted;
554 UINT i;
555 BOOL ret;
557 filehandle = _lcreat( filename, 0 );
558 if (filehandle == HFILE_ERROR)
560 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
561 return;
564 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
566 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
568 filehandle = _lopen( filename, OF_READ );
570 ok( HFILE_ERROR != filehandle, "couldn't open file \"%s\" again (err=%ld)\n", filename, GetLastError());
572 bytes_read = _lread( filehandle, buffer, 2 * strlen( sillytext ) );
574 ok( lstrlenA( sillytext ) == bytes_read, "file read size error\n" );
576 for (bytes_wanted = 0; bytes_wanted < strlen( sillytext ); bytes_wanted++)
578 ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
579 ok( _lread( filehandle, buffer, bytes_wanted ) == bytes_wanted, "erratic _hread return value\n" );
580 for (i = 0; i < bytes_wanted; i++)
582 ok( buffer[i] == sillytext[i], "that's not what's written\n" );
586 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
588 ret = DeleteFileA( filename );
589 ok( ret, "DeleteFile failed (%ld)\n", GetLastError( ) );
593 static void test__lwrite( void )
595 HFILE filehandle;
596 char buffer[10000];
597 UINT bytes_read;
598 UINT bytes_written;
599 UINT blocks;
600 INT i;
601 char *contents;
602 HLOCAL memory_object;
603 char checksum[1];
604 BOOL ret;
606 filehandle = _lcreat( filename, 0 );
607 if (filehandle == HFILE_ERROR)
609 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
610 return;
613 ok( HFILE_ERROR != _lwrite( filehandle, "", 0 ), "_hwrite complains\n" );
615 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
617 filehandle = _lopen( filename, OF_READ );
619 bytes_read = _hread( filehandle, buffer, 1);
621 ok( 0 == bytes_read, "file read size error\n" );
623 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
625 filehandle = _lopen( filename, OF_READWRITE );
627 bytes_written = 0;
628 checksum[0] = '\0';
629 srand( (unsigned)time( NULL ) );
630 for (blocks = 0; blocks < 100; blocks++)
632 for (i = 0; i < (INT)sizeof( buffer ); i++)
634 buffer[i] = rand( );
635 checksum[0] = checksum[0] + buffer[i];
637 ok( HFILE_ERROR != _lwrite( filehandle, buffer, sizeof( buffer ) ), "_hwrite complains\n" );
638 bytes_written = bytes_written + sizeof( buffer );
641 ok( HFILE_ERROR != _lwrite( filehandle, checksum, 1 ), "_hwrite complains\n" );
642 bytes_written++;
644 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
646 memory_object = LocalAlloc( LPTR, bytes_written );
648 ok( 0 != memory_object, "LocalAlloc fails, could be out of memory\n" );
650 contents = LocalLock( memory_object );
651 ok( NULL != contents, "LocalLock whines\n" );
653 filehandle = _lopen( filename, OF_READ );
655 contents = LocalLock( memory_object );
656 ok( NULL != contents, "LocalLock whines\n" );
658 ok( bytes_written == _hread( filehandle, contents, bytes_written), "read length differ from write length\n" );
660 checksum[0] = '\0';
661 i = 0;
664 checksum[0] += contents[i];
665 i++;
667 while (i < bytes_written - 1);
669 ok( checksum[0] == contents[i], "stored checksum differ from computed checksum\n" );
671 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
673 ret = DeleteFileA( filename );
674 ok( ret, "DeleteFile failed (%ld)\n", GetLastError( ) );
676 LocalFree( contents );
679 static void test_CopyFileA(void)
681 char temp_path[MAX_PATH];
682 char source[MAX_PATH], dest[MAX_PATH];
683 static const char prefix[] = "pfx";
684 HANDLE hfile;
685 HANDLE hmapfile;
686 FILETIME ft1, ft2;
687 char buf[10];
688 DWORD ret;
689 BOOL retok;
691 ret = GetTempPathA(MAX_PATH, temp_path);
692 ok(ret != 0, "GetTempPathA error %ld\n", GetLastError());
693 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
695 ret = GetTempFileNameA(temp_path, prefix, 0, source);
696 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
698 /* copying a file to itself must fail */
699 retok = CopyFileA(source, source, FALSE);
700 ok( !retok && (GetLastError() == ERROR_SHARING_VIOLATION || broken(GetLastError() == ERROR_FILE_EXISTS) /* Win 9x */),
701 "copying a file to itself didn't fail (ret=%d, err=%ld)\n", retok, GetLastError());
703 /* make the source have not zero size */
704 hfile = CreateFileA(source, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
705 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
706 retok = WriteFile(hfile, prefix, sizeof(prefix), &ret, NULL );
707 ok( retok && ret == sizeof(prefix),
708 "WriteFile error %ld\n", GetLastError());
709 ok(GetFileSize(hfile, NULL) == sizeof(prefix), "source file has wrong size\n");
710 /* get the file time and change it to prove the difference */
711 ret = GetFileTime(hfile, NULL, NULL, &ft1);
712 ok( ret, "GetFileTime error %ld\n", GetLastError());
713 ft1.dwLowDateTime -= 600000000; /* 60 second */
714 ret = SetFileTime(hfile, NULL, NULL, &ft1);
715 ok( ret, "SetFileTime error %ld\n", GetLastError());
716 GetFileTime(hfile, NULL, NULL, &ft1); /* get the actual time back */
717 CloseHandle(hfile);
719 ret = GetTempFileNameA(temp_path, prefix, 0, dest);
720 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
722 SetLastError(0xdeadbeef);
723 ret = CopyFileA(source, dest, TRUE);
724 ok(!ret && GetLastError() == ERROR_FILE_EXISTS,
725 "CopyFileA: unexpected error %ld\n", GetLastError());
727 ret = CopyFileA(source, dest, FALSE);
728 ok(ret, "CopyFileA: error %ld\n", GetLastError());
730 /* NULL checks */
731 retok = CopyFileA(NULL, dest, TRUE);
732 ok(!retok && GetLastError() == ERROR_PATH_NOT_FOUND,
733 "CopyFileA: ret = %d, unexpected error %ld\n", retok, GetLastError());
734 retok = CopyFileA(source, NULL, TRUE);
735 ok(!retok && GetLastError() == ERROR_PATH_NOT_FOUND,
736 "CopyFileA: ret = %d, unexpected error %ld\n", retok, GetLastError());
738 /* copying from a read-locked source fails */
739 hfile = CreateFileA(source, GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
740 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %ld\n", GetLastError());
741 retok = CopyFileA(source, dest, FALSE);
742 ok(!retok && GetLastError() == ERROR_SHARING_VIOLATION,
743 "copying from a read-locked file succeeded when it shouldn't have\n");
744 /* in addition, the source is opened before the destination */
745 retok = CopyFileA("25f99d3b-4ba4-4f66-88f5-2906886993cc", dest, FALSE);
746 ok(!retok && GetLastError() == ERROR_FILE_NOT_FOUND,
747 "copying from a file that doesn't exist failed in an unexpected way (ret=%d, err=%ld)\n", retok, GetLastError());
748 CloseHandle(hfile);
750 /* copying from a r+w opened, r shared source succeeds */
751 hfile = CreateFileA(source, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
752 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %ld\n", GetLastError());
753 retok = CopyFileA(source, dest, FALSE);
754 ok(retok,
755 "copying from an r+w opened and r shared file failed (ret=%d, err=%ld)\n", retok, GetLastError());
756 CloseHandle(hfile);
758 /* copying from a delete-locked source mostly succeeds */
759 hfile = CreateFileA(source, DELETE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
760 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %ld\n", GetLastError());
761 retok = CopyFileA(source, dest, FALSE);
762 ok(retok || broken(!retok && GetLastError() == ERROR_SHARING_VIOLATION) /* NT, 2000, XP */,
763 "copying from a delete-locked file failed (ret=%d, err=%ld)\n", retok, GetLastError());
764 CloseHandle(hfile);
766 /* copying to a write-locked destination fails */
767 hfile = CreateFileA(dest, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
768 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %ld\n", GetLastError());
769 retok = CopyFileA(source, dest, FALSE);
770 ok(!retok && GetLastError() == ERROR_SHARING_VIOLATION,
771 "copying to a write-locked file didn't fail (ret=%d, err=%ld)\n", retok, GetLastError());
772 CloseHandle(hfile);
774 /* copying to a r+w opened, w shared destination mostly succeeds */
775 hfile = CreateFileA(dest, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
776 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %ld\n", GetLastError());
777 retok = CopyFileA(source, dest, FALSE);
778 ok(retok || broken(!retok && GetLastError() == ERROR_SHARING_VIOLATION) /* Win 9x */,
779 "copying to a r+w opened and w shared file failed (ret=%d, err=%ld)\n", retok, GetLastError());
780 CloseHandle(hfile);
782 /* copying to a delete-locked destination fails, even when the destination is delete-shared */
783 hfile = CreateFileA(dest, DELETE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0);
784 ok(hfile != INVALID_HANDLE_VALUE || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Win 9x */,
785 "failed to open destination file, error %ld\n", GetLastError());
786 if (hfile != INVALID_HANDLE_VALUE)
788 retok = CopyFileA(source, dest, FALSE);
789 ok(!retok && GetLastError() == ERROR_SHARING_VIOLATION,
790 "copying to a delete-locked shared file didn't fail (ret=%d, err=%ld)\n", retok, GetLastError());
791 CloseHandle(hfile);
794 /* copy to a file that's opened the way Wine opens the source */
795 hfile = CreateFileA(dest, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
796 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %ld\n", GetLastError());
797 retok = CopyFileA(source, dest, FALSE);
798 ok(retok || broken(GetLastError() == ERROR_SHARING_VIOLATION) /* Win 9x */,
799 "copying to a file opened the way Wine opens the source failed (ret=%d, err=%ld)\n", retok, GetLastError());
800 CloseHandle(hfile);
802 /* make sure that destination has correct size */
803 hfile = CreateFileA(dest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
804 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n");
805 ret = GetFileSize(hfile, NULL);
806 ok(ret == sizeof(prefix), "destination file has wrong size %ld\n", ret);
808 /* make sure that destination has the same filetime */
809 ret = GetFileTime(hfile, NULL, NULL, &ft2);
810 ok( ret, "GetFileTime error %ld\n", GetLastError());
811 ok(CompareFileTime(&ft1, &ft2) == 0, "destination file has wrong filetime\n");
813 SetLastError(0xdeadbeef);
814 ret = CopyFileA(source, dest, FALSE);
815 ok(!ret && GetLastError() == ERROR_SHARING_VIOLATION,
816 "CopyFileA: ret = %ld, unexpected error %ld\n", ret, GetLastError());
818 /* make sure that destination still has correct size */
819 ret = GetFileSize(hfile, NULL);
820 ok(ret == sizeof(prefix), "destination file has wrong size %ld\n", ret);
821 retok = ReadFile(hfile, buf, sizeof(buf), &ret, NULL);
822 ok( retok && ret == sizeof(prefix),
823 "ReadFile: error %ld\n", GetLastError());
824 ok(!memcmp(prefix, buf, sizeof(prefix)), "buffer contents mismatch\n");
826 /* check error on copying over a mapped file that was opened with FILE_SHARE_READ */
827 hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
828 ok(hmapfile != NULL, "CreateFileMapping: error %ld\n", GetLastError());
830 ret = CopyFileA(source, dest, FALSE);
831 ok(!ret && GetLastError() == ERROR_SHARING_VIOLATION,
832 "CopyFileA with mapped dest file: expected ERROR_SHARING_VIOLATION, got %ld\n", GetLastError());
834 CloseHandle(hmapfile);
835 CloseHandle(hfile);
837 hfile = CreateFileA(dest, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
838 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n");
840 /* check error on copying over a mapped file that was opened with FILE_SHARE_WRITE */
841 hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
842 ok(hmapfile != NULL, "CreateFileMapping: error %ld\n", GetLastError());
844 ret = CopyFileA(source, dest, FALSE);
845 ok(!ret, "CopyFileA: expected failure\n");
846 ok(GetLastError() == ERROR_USER_MAPPED_FILE ||
847 broken(GetLastError() == ERROR_SHARING_VIOLATION), /* Win9x */
848 "CopyFileA with mapped dest file: expected ERROR_USER_MAPPED_FILE, got %ld\n", GetLastError());
850 CloseHandle(hmapfile);
851 CloseHandle(hfile);
853 /* check read-only attribute */
854 ret = GetFileAttributesA(source);
855 ok(ret != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %ld\n", GetLastError());
856 ok(!(ret & FILE_ATTRIBUTE_READONLY), "source is read-only\n");
857 ret = GetFileAttributesA(dest);
858 ok(ret != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %ld\n", GetLastError());
859 ok(!(ret & FILE_ATTRIBUTE_READONLY), "dest is read-only\n");
861 /* make source read-only */
862 ret = SetFileAttributesA(source, FILE_ATTRIBUTE_READONLY);
863 ok(ret, "SetFileAttributesA: error %ld\n", GetLastError());
864 ret = GetFileAttributesA(source);
865 ok(ret != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %ld\n", GetLastError());
866 ok(ret & FILE_ATTRIBUTE_READONLY, "source is not read-only\n");
867 ret = GetFileAttributesA(dest);
868 ok(ret != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %ld\n", GetLastError());
869 ok(!(ret & FILE_ATTRIBUTE_READONLY), "dest is read-only\n");
871 /* dest becomes read-only after copied from read-only source */
872 ret = SetFileAttributesA(source, FILE_ATTRIBUTE_READONLY);
873 ok(ret, "SetFileAttributesA: error %ld\n", GetLastError());
874 ret = GetFileAttributesA(source);
875 ok(ret != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %ld\n", GetLastError());
876 ok(ret & FILE_ATTRIBUTE_READONLY, "source is not read-only\n");
877 ret = GetFileAttributesA(dest);
878 ok(ret != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %ld\n", GetLastError());
879 ok(!(ret & FILE_ATTRIBUTE_READONLY), "dest is read-only\n");
881 ret = CopyFileA(source, dest, FALSE);
882 ok(ret, "CopyFileA: error %ld\n", GetLastError());
883 ret = GetFileAttributesA(dest);
884 ok(ret != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %ld\n", GetLastError());
885 ok(ret & FILE_ATTRIBUTE_READONLY, "dest is not read-only\n");
887 /* same when dest does not exist */
888 ret = SetFileAttributesA(dest, FILE_ATTRIBUTE_NORMAL);
889 ok(ret, "SetFileAttributesA: error %ld\n", GetLastError());
890 ret = DeleteFileA(dest);
891 ok(ret, "DeleteFileA: error %ld\n", GetLastError());
892 ret = CopyFileA(source, dest, TRUE);
893 ok(ret, "CopyFileA: error %ld\n", GetLastError());
894 ret = GetFileAttributesA(dest);
895 ok(ret != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %ld\n", GetLastError());
896 ok(ret & FILE_ATTRIBUTE_READONLY, "dest is not read-only\n");
898 ret = SetFileAttributesA(source, FILE_ATTRIBUTE_NORMAL);
899 ok(ret, "SetFileAttributesA: error %ld\n", GetLastError());
900 ret = SetFileAttributesA(dest, FILE_ATTRIBUTE_NORMAL);
901 ok(ret, "SetFileAttributesA: error %ld\n", GetLastError());
903 ret = DeleteFileA(source);
904 ok(ret, "DeleteFileA: error %ld\n", GetLastError());
905 ret = DeleteFileA(dest);
906 ok(ret, "DeleteFileA: error %ld\n", GetLastError());
909 static void test_CopyFileW(void)
911 WCHAR temp_path[MAX_PATH];
912 WCHAR source[MAX_PATH], dest[MAX_PATH];
913 static const WCHAR prefix[] = {'p','f','x',0};
914 DWORD ret;
916 ret = GetTempPathW(MAX_PATH, temp_path);
917 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
919 win_skip("GetTempPathW is not available\n");
920 return;
922 ok(ret != 0, "GetTempPathW error %ld\n", GetLastError());
923 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
925 ret = GetTempFileNameW(temp_path, prefix, 0, source);
926 ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError());
928 ret = GetTempFileNameW(temp_path, prefix, 0, dest);
929 ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError());
931 ret = CopyFileW(source, dest, TRUE);
932 ok(!ret && GetLastError() == ERROR_FILE_EXISTS,
933 "CopyFileW: unexpected error %ld\n", GetLastError());
935 SetLastError(0xdeadbeef);
936 ret = CopyFileW(source, dest, FALSE);
937 ok(ret, "CopyFileW: error %ld\n", GetLastError());
938 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* some win8 machines */,
939 "Unexpected error %lu.\n", GetLastError());
941 SetLastError(0xdeadbeef);
942 ret = CopyFileExW(source, dest, NULL, NULL, NULL, 0 );
943 ok(ret, "CopyFileExW: error %ld\n", GetLastError());
944 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* some win8 machines */,
945 "Unexpected error %lu.\n", GetLastError());
947 ret = DeleteFileW(source);
948 ok(ret, "DeleteFileW: error %ld\n", GetLastError());
949 ret = DeleteFileW(dest);
950 ok(ret, "DeleteFileW: error %ld\n", GetLastError());
953 static void test_CopyFile2(void)
955 static const WCHAR doesntexistW[] = {'d','o','e','s','n','t','e','x','i','s','t',0};
956 static const WCHAR prefix[] = {'p','f','x',0};
957 WCHAR source[MAX_PATH], dest[MAX_PATH], temp_path[MAX_PATH];
958 COPYFILE2_EXTENDED_PARAMETERS params;
959 HANDLE hfile, hmapfile;
960 FILETIME ft1, ft2;
961 DWORD ret, len;
962 char buf[10];
963 HRESULT hr;
965 if (!pCopyFile2)
967 todo_wine win_skip("CopyFile2 is not available\n");
968 return;
971 ret = GetTempPathW(MAX_PATH, temp_path);
972 ok(ret != 0, "GetTempPathW error %ld\n", GetLastError());
973 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
975 ret = GetTempFileNameW(temp_path, prefix, 0, source);
976 ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError());
978 ret = GetTempFileNameW(temp_path, prefix, 0, dest);
979 ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError());
981 /* fail if exists */
982 memset(&params, 0, sizeof(params));
983 params.dwSize = sizeof(params);
984 params.dwCopyFlags = COPY_FILE_FAIL_IF_EXISTS;
986 SetLastError(0xdeadbeef);
987 hr = pCopyFile2(source, dest, &params);
988 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "CopyFile2: unexpected error 0x%08lx\n", hr);
989 ok(GetLastError() == ERROR_FILE_EXISTS, "CopyFile2: last error %ld\n", GetLastError());
991 /* don't fail if exists */
992 params.dwSize = sizeof(params);
993 params.dwCopyFlags = 0;
995 hr = pCopyFile2(source, dest, &params);
996 ok(hr == S_OK, "CopyFile2: error 0x%08lx\n", hr);
998 /* copying a file to itself must fail */
999 params.dwSize = sizeof(params);
1000 params.dwCopyFlags = 0;
1002 SetLastError(0xdeadbeef);
1003 hr = pCopyFile2(source, source, &params);
1004 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: copying a file to itself didn't fail, 0x%08lx\n", hr);
1005 ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %ld\n", GetLastError());
1007 /* make the source have not zero size */
1008 hfile = CreateFileW(source, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
1009 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
1010 ret = WriteFile(hfile, prefix, sizeof(prefix), &len, NULL );
1011 ok(ret && len == sizeof(prefix), "WriteFile error %ld\n", GetLastError());
1012 ok(GetFileSize(hfile, NULL) == sizeof(prefix), "source file has wrong size\n");
1014 /* get the file time and change it to prove the difference */
1015 ret = GetFileTime(hfile, NULL, NULL, &ft1);
1016 ok(ret, "GetFileTime error %ld\n", GetLastError());
1017 ft1.dwLowDateTime -= 600000000; /* 60 second */
1018 ret = SetFileTime(hfile, NULL, NULL, &ft1);
1019 ok(ret, "SetFileTime error %ld\n", GetLastError());
1020 GetFileTime(hfile, NULL, NULL, &ft1); /* get the actual time back */
1021 CloseHandle(hfile);
1023 ret = GetTempFileNameW(temp_path, prefix, 0, dest);
1024 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
1026 params.dwSize = sizeof(params);
1027 params.dwCopyFlags = COPY_FILE_FAIL_IF_EXISTS;
1029 SetLastError(0xdeadbeef);
1030 hr = pCopyFile2(source, dest, &params);
1031 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "CopyFile2: unexpected error 0x%08lx\n", hr);
1032 ok(GetLastError() == ERROR_FILE_EXISTS, "CopyFile2: last error %ld\n", GetLastError());
1034 params.dwSize = sizeof(params);
1035 params.dwCopyFlags = 0;
1036 hr = pCopyFile2(source, dest, &params);
1037 ok(ret, "CopyFile2: error 0x%08lx\n", hr);
1039 /* copying from a read-locked source fails */
1040 hfile = CreateFileW(source, GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
1041 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %ld\n", GetLastError());
1043 params.dwSize = sizeof(params);
1044 params.dwCopyFlags = 0;
1045 SetLastError(0xdeadbeef);
1046 hr = pCopyFile2(source, dest, &params);
1047 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08lx\n", hr);
1048 ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %ld\n", GetLastError());
1050 /* in addition, the source is opened before the destination */
1051 params.dwSize = sizeof(params);
1052 params.dwCopyFlags = 0;
1053 SetLastError(0xdeadbeef);
1054 hr = pCopyFile2(doesntexistW, dest, &params);
1055 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08lx\n", hr);
1056 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "CopyFile2: last error %ld\n", GetLastError());
1057 CloseHandle(hfile);
1059 /* copying from a r+w opened, r shared source succeeds */
1060 hfile = CreateFileW(source, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
1061 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %ld\n", GetLastError());
1063 params.dwSize = sizeof(params);
1064 params.dwCopyFlags = 0;
1065 hr = pCopyFile2(source, dest, &params);
1066 ok(hr == S_OK, "failed 0x%08lx\n", hr);
1067 CloseHandle(hfile);
1069 /* copying from a delete-locked source mostly succeeds */
1070 hfile = CreateFileW(source, DELETE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
1071 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %ld\n", GetLastError());
1073 params.dwSize = sizeof(params);
1074 params.dwCopyFlags = 0;
1075 hr = pCopyFile2(source, dest, &params);
1076 ok(hr == S_OK, "failed 0x%08lx\n", hr);
1077 CloseHandle(hfile);
1079 /* copying to a write-locked destination fails */
1080 hfile = CreateFileW(dest, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
1081 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %ld\n", GetLastError());
1083 params.dwSize = sizeof(params);
1084 params.dwCopyFlags = 0;
1085 SetLastError(0xdeadbeef);
1086 hr = pCopyFile2(source, dest, FALSE);
1087 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08lx\n", hr);
1088 ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %ld\n", GetLastError());
1089 CloseHandle(hfile);
1091 /* copying to a r+w opened, w shared destination mostly succeeds */
1092 hfile = CreateFileW(dest, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
1093 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %ld\n", GetLastError());
1095 params.dwSize = sizeof(params);
1096 params.dwCopyFlags = 0;
1097 hr = pCopyFile2(source, dest, FALSE);
1098 ok(hr == S_OK, "got 0x%08lx\n", hr);
1099 CloseHandle(hfile);
1101 /* copying to a delete-locked destination fails, even when the destination is delete-shared */
1102 hfile = CreateFileW(dest, DELETE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0);
1103 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %ld\n", GetLastError());
1105 params.dwSize = sizeof(params);
1106 params.dwCopyFlags = 0;
1107 SetLastError(0xdeadbeef);
1108 hr = pCopyFile2(source, dest, &params);
1109 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08lx\n", hr);
1110 ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %ld\n", GetLastError());
1111 CloseHandle(hfile);
1113 /* copy to a file that's opened the way Wine opens the source */
1114 hfile = CreateFileW(dest, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
1115 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %ld\n", GetLastError());
1117 params.dwSize = sizeof(params);
1118 params.dwCopyFlags = 0;
1119 hr = pCopyFile2(source, dest, &params);
1120 ok(hr == S_OK, "got 0x%08lx\n", hr);
1121 CloseHandle(hfile);
1123 /* make sure that destination has correct size */
1124 hfile = CreateFileW(dest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
1125 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n");
1126 ret = GetFileSize(hfile, NULL);
1127 ok(ret == sizeof(prefix), "destination file has wrong size %ld\n", ret);
1129 /* make sure that destination has the same filetime */
1130 ret = GetFileTime(hfile, NULL, NULL, &ft2);
1131 ok(ret, "GetFileTime error %ld\n", GetLastError());
1132 ok(CompareFileTime(&ft1, &ft2) == 0, "destination file has wrong filetime\n");
1134 params.dwSize = sizeof(params);
1135 params.dwCopyFlags = 0;
1136 SetLastError(0xdeadbeef);
1137 hr = pCopyFile2(source, dest, &params);
1138 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08lx\n", hr);
1139 ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %ld\n", GetLastError());
1141 /* make sure that destination still has correct size */
1142 ret = GetFileSize(hfile, NULL);
1143 ok(ret == sizeof(prefix), "destination file has wrong size %ld\n", ret);
1144 ret = ReadFile(hfile, buf, sizeof(buf), &len, NULL);
1145 ok(ret && len == sizeof(prefix), "ReadFile: error %ld\n", GetLastError());
1146 ok(!memcmp(prefix, buf, sizeof(prefix)), "buffer contents mismatch\n");
1148 /* check error on copying over a mapped file that was opened with FILE_SHARE_READ */
1149 hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
1150 ok(hmapfile != NULL, "CreateFileMapping: error %ld\n", GetLastError());
1152 params.dwSize = sizeof(params);
1153 params.dwCopyFlags = 0;
1154 SetLastError(0xdeadbeef);
1155 hr = pCopyFile2(source, dest, &params);
1156 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "CopyFile2: unexpected error 0x%08lx\n", hr);
1157 ok(GetLastError() == ERROR_SHARING_VIOLATION, "CopyFile2: last error %ld\n", GetLastError());
1159 CloseHandle(hmapfile);
1160 CloseHandle(hfile);
1162 hfile = CreateFileW(dest, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
1163 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n");
1165 /* check error on copying over a mapped file that was opened with FILE_SHARE_WRITE */
1166 hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
1167 ok(hmapfile != NULL, "CreateFileMapping: error %ld\n", GetLastError());
1169 params.dwSize = sizeof(params);
1170 params.dwCopyFlags = 0;
1171 hr = pCopyFile2(source, dest, &params);
1172 ok(hr == HRESULT_FROM_WIN32(ERROR_USER_MAPPED_FILE), "CopyFile2: unexpected error 0x%08lx\n", hr);
1173 ok(GetLastError() == ERROR_USER_MAPPED_FILE, "CopyFile2: last error %ld\n", GetLastError());
1175 CloseHandle(hmapfile);
1176 CloseHandle(hfile);
1178 DeleteFileW(source);
1179 DeleteFileW(dest);
1182 static DWORD WINAPI copy_progress_cb(LARGE_INTEGER total_size, LARGE_INTEGER total_transferred,
1183 LARGE_INTEGER stream_size, LARGE_INTEGER stream_transferred,
1184 DWORD stream, DWORD reason, HANDLE source, HANDLE dest, LPVOID userdata)
1186 ok(reason == CALLBACK_STREAM_SWITCH, "expected CALLBACK_STREAM_SWITCH, got %lu\n", reason);
1187 CloseHandle(userdata);
1188 return PROGRESS_CANCEL;
1191 static void test_CopyFileEx(void)
1193 char temp_path[MAX_PATH];
1194 char source[MAX_PATH], dest[MAX_PATH];
1195 static const char prefix[] = "pfx";
1196 HANDLE hfile;
1197 DWORD ret;
1198 BOOL retok;
1200 ret = GetTempPathA(MAX_PATH, temp_path);
1201 ok(ret != 0, "GetTempPathA error %ld\n", GetLastError());
1202 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
1204 ret = GetTempFileNameA(temp_path, prefix, 0, source);
1205 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
1207 ret = GetTempFileNameA(temp_path, prefix, 0, dest);
1208 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
1210 hfile = CreateFileA(dest, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
1211 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %ld\n", GetLastError());
1212 SetLastError(0xdeadbeef);
1213 retok = CopyFileExA(source, dest, copy_progress_cb, hfile, NULL, 0);
1214 todo_wine
1215 ok(!retok, "CopyFileExA unexpectedly succeeded\n");
1216 todo_wine
1217 ok(GetLastError() == ERROR_REQUEST_ABORTED, "expected ERROR_REQUEST_ABORTED, got %ld\n", GetLastError());
1218 ok(GetFileAttributesA(dest) != INVALID_FILE_ATTRIBUTES, "file was deleted\n");
1220 hfile = CreateFileA(dest, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_DELETE,
1221 NULL, OPEN_EXISTING, 0, 0);
1222 todo_wine
1223 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %ld\n", GetLastError());
1224 SetLastError(0xdeadbeef);
1225 retok = CopyFileExA(source, dest, copy_progress_cb, hfile, NULL, 0);
1226 todo_wine
1227 ok(!retok, "CopyFileExA unexpectedly succeeded\n");
1228 todo_wine
1229 ok(GetLastError() == ERROR_REQUEST_ABORTED, "expected ERROR_REQUEST_ABORTED, got %ld\n", GetLastError());
1230 todo_wine
1231 ok(GetFileAttributesA(dest) == INVALID_FILE_ATTRIBUTES, "file was not deleted\n");
1233 retok = CopyFileExA(source, NULL, copy_progress_cb, hfile, NULL, 0);
1234 ok(!retok, "CopyFileExA unexpectedly succeeded\n");
1235 ok(GetLastError() == ERROR_PATH_NOT_FOUND, "expected ERROR_PATH_NOT_FOUND, got %ld\n", GetLastError());
1236 retok = CopyFileExA(NULL, dest, copy_progress_cb, hfile, NULL, 0);
1237 ok(!retok, "CopyFileExA unexpectedly succeeded\n");
1238 ok(GetLastError() == ERROR_PATH_NOT_FOUND, "expected ERROR_PATH_NOT_FOUND, got %ld\n", GetLastError());
1240 ret = DeleteFileA(source);
1241 ok(ret, "DeleteFileA failed with error %ld\n", GetLastError());
1242 ret = DeleteFileA(dest);
1243 ok(!ret, "DeleteFileA unexpectedly succeeded\n");
1247 * Debugging routine to dump a buffer in a hexdump-like fashion.
1249 static void dumpmem(unsigned char *mem, int len)
1251 int x = 0;
1252 char hex[49], *p;
1253 char txt[17], *c;
1255 while (x < len)
1257 p = hex;
1258 c = txt;
1259 do {
1260 p += sprintf(p, "%02x ", mem[x]);
1261 *c++ = (mem[x] >= 32 && mem[x] <= 127) ? mem[x] : '.';
1262 } while (++x % 16 && x < len);
1263 *c = '\0';
1264 trace("%04x: %-48s- %s\n", x, hex, txt);
1268 static void test_CreateFileA(void)
1270 HANDLE hFile;
1271 char temp_path[MAX_PATH], dirname[MAX_PATH];
1272 char filename[MAX_PATH];
1273 static const char prefix[] = "pfx";
1274 char windowsdir[MAX_PATH];
1275 char Volume_1[MAX_PATH];
1276 unsigned char buffer[512];
1277 char directory[] = "removeme";
1278 static const char nt_drive[] = "\\\\?\\A:";
1279 DWORD i, ret, len;
1280 static const struct test_list p[] =
1282 {"", ERROR_PATH_NOT_FOUND, -1, FILE_ATTRIBUTE_NORMAL, TRUE }, /* dir as file w \ */
1283 {"", ERROR_SUCCESS, ERROR_PATH_NOT_FOUND, FILE_FLAG_BACKUP_SEMANTICS, FALSE }, /* dir as dir w \ */
1284 {"a", ERROR_FILE_NOT_FOUND, -1, FILE_ATTRIBUTE_NORMAL, FALSE }, /* non-exist file */
1285 {"a\\", ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND, FILE_ATTRIBUTE_NORMAL, FALSE }, /* non-exist dir */
1286 {"removeme", ERROR_ACCESS_DENIED, -1, FILE_ATTRIBUTE_NORMAL, FALSE }, /* exist dir w/o \ */
1287 {"removeme\\", ERROR_PATH_NOT_FOUND, -1, FILE_ATTRIBUTE_NORMAL, TRUE }, /* exst dir w \ */
1288 {"c:", ERROR_ACCESS_DENIED, ERROR_PATH_NOT_FOUND, FILE_ATTRIBUTE_NORMAL, FALSE }, /* device in file namespace */
1289 {"c:", ERROR_SUCCESS, ERROR_PATH_NOT_FOUND, FILE_FLAG_BACKUP_SEMANTICS, FALSE }, /* device in file namespace as dir */
1290 {"c:\\", ERROR_PATH_NOT_FOUND, ERROR_ACCESS_DENIED, FILE_ATTRIBUTE_NORMAL, TRUE }, /* root dir w \ */
1291 {"c:\\", ERROR_SUCCESS, ERROR_ACCESS_DENIED, FILE_FLAG_BACKUP_SEMANTICS, FALSE }, /* root dir w \ as dir */
1292 {"c:c:\\windows", ERROR_INVALID_NAME, -1, FILE_ATTRIBUTE_NORMAL, TRUE }, /* invalid path */
1293 {"\\\\?\\c:", ERROR_SUCCESS, ERROR_BAD_NETPATH, FILE_ATTRIBUTE_NORMAL,FALSE }, /* dev namespace drive */
1294 {"\\\\?\\c:\\", ERROR_PATH_NOT_FOUND, ERROR_BAD_NETPATH, FILE_ATTRIBUTE_NORMAL, TRUE }, /* dev namespace drive w \ */
1295 {NULL, 0, -1, 0, FALSE}
1297 BY_HANDLE_FILE_INFORMATION Finfo;
1298 WCHAR curdir[MAX_PATH];
1300 ret = GetTempPathA(MAX_PATH, temp_path);
1301 ok(ret != 0, "GetTempPathA error %ld\n", GetLastError());
1302 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
1304 ret = GetTempFileNameA(temp_path, prefix, 0, filename);
1305 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
1307 SetLastError(0xdeadbeef);
1308 hFile = CreateFileA(filename, GENERIC_READ, 0, NULL,
1309 CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
1310 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS,
1311 "CREATE_NEW should fail if file exists and last error value should be ERROR_FILE_EXISTS\n");
1313 SetLastError(0xdeadbeef);
1314 hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
1315 CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
1316 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
1317 "hFile %p, last error %lu\n", hFile, GetLastError());
1319 CloseHandle(hFile);
1321 SetLastError(0xdeadbeef);
1322 hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
1323 OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
1324 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
1325 "hFile %p, last error %lu\n", hFile, GetLastError());
1327 CloseHandle(hFile);
1329 ret = DeleteFileA(filename);
1330 ok(ret, "DeleteFileA: error %ld\n", GetLastError());
1332 SetLastError(0xdeadbeef);
1333 hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
1334 OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
1335 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == 0,
1336 "hFile %p, last error %lu\n", hFile, GetLastError());
1338 CloseHandle(hFile);
1340 ret = DeleteFileA(filename);
1341 ok(ret, "DeleteFileA: error %ld\n", GetLastError());
1343 SetLastError(0xdeadbeef);
1344 hFile = CreateFileA("c:\\*.*", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1345 ok(hFile == INVALID_HANDLE_VALUE, "hFile should have been INVALID_HANDLE_VALUE\n");
1346 ok(GetLastError() == ERROR_INVALID_NAME ||
1347 broken(GetLastError() == ERROR_FILE_NOT_FOUND), /* Win98 */
1348 "LastError should have been ERROR_INVALID_NAME or ERROR_FILE_NOT_FOUND but got %lu\n", GetLastError());
1350 /* get windows drive letter */
1351 ret = GetWindowsDirectoryA(windowsdir, sizeof(windowsdir));
1352 ok(ret < sizeof(windowsdir), "windowsdir is abnormally long!\n");
1353 ok(ret != 0, "GetWindowsDirectory: error %ld\n", GetLastError());
1355 /* test error return codes from CreateFile for some cases */
1356 ret = GetTempPathA(MAX_PATH, temp_path);
1357 ok(ret != 0, "GetTempPathA error %ld\n", GetLastError());
1358 strcpy(dirname, temp_path);
1359 strcat(dirname, directory);
1360 ret = CreateDirectoryA(dirname, NULL);
1361 ok( ret, "Createdirectory failed, gle=%ld\n", GetLastError() );
1362 /* set current drive & directory to known location */
1363 GetCurrentDirectoryW( MAX_PATH, curdir);
1364 SetCurrentDirectoryA( temp_path );
1365 i = 0;
1366 while (p[i].file)
1368 filename[0] = 0;
1369 /* update the drive id in the table entry with the current one */
1370 if (p[i].file[1] == ':')
1372 strcpy(filename, p[i].file);
1373 filename[0] = windowsdir[0];
1375 else if (p[i].file[0] == '\\' && p[i].file[5] == ':')
1377 strcpy(filename, p[i].file);
1378 filename[4] = windowsdir[0];
1380 else
1382 /* prefix the table entry with the current temp directory */
1383 strcpy(filename, temp_path);
1384 strcat(filename, p[i].file);
1386 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1387 FILE_SHARE_READ | FILE_SHARE_WRITE,
1388 NULL, OPEN_EXISTING,
1389 p[i].options, NULL );
1390 /* if we get ACCESS_DENIED when we do not expect it, assume
1391 * no access to the volume
1393 if (hFile == INVALID_HANDLE_VALUE &&
1394 GetLastError() == ERROR_ACCESS_DENIED &&
1395 p[i].err != ERROR_ACCESS_DENIED)
1397 if (p[i].todo_flag)
1398 skip("Either no authority to volume, or is todo_wine for %s err=%ld should be %ld\n", filename, GetLastError(), p[i].err);
1399 else
1400 skip("Do not have authority to access volumes. Test for %s skipped\n", filename);
1402 /* otherwise validate results with expectations */
1403 else
1405 todo_wine_if (p[i].todo_flag)
1406 ok((hFile == INVALID_HANDLE_VALUE &&
1407 (p[i].err == GetLastError() || p[i].err2 == GetLastError())) ||
1408 (hFile != INVALID_HANDLE_VALUE && p[i].err == ERROR_SUCCESS),
1409 "CreateFileA failed on %s, hFile %p, err=%lu, should be %lu\n",
1410 filename, hFile, GetLastError(), p[i].err);
1412 if (hFile != INVALID_HANDLE_VALUE)
1413 CloseHandle( hFile );
1414 i++;
1416 ret = RemoveDirectoryA(dirname);
1417 ok(ret, "RemoveDirectoryA: error %ld\n", GetLastError());
1418 SetCurrentDirectoryW(curdir);
1420 /* test opening directory as a directory */
1421 hFile = CreateFileA( temp_path, GENERIC_READ,
1422 FILE_SHARE_READ,
1423 NULL,
1424 OPEN_EXISTING,
1425 FILE_FLAG_BACKUP_SEMANTICS, NULL );
1426 if (hFile != INVALID_HANDLE_VALUE && GetLastError() != ERROR_PATH_NOT_FOUND)
1428 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_SUCCESS,
1429 "CreateFileA did not work, last error %lu on volume <%s>\n",
1430 GetLastError(), temp_path );
1432 if (hFile != INVALID_HANDLE_VALUE)
1434 ret = GetFileInformationByHandle( hFile, &Finfo );
1435 if (ret)
1437 ok(Finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY,
1438 "CreateFileA probably did not open temp directory %s correctly\n file information does not include FILE_ATTRIBUTE_DIRECTORY, actual=0x%08lx\n",
1439 temp_path, Finfo.dwFileAttributes);
1441 CloseHandle( hFile );
1444 else
1445 skip("Probable Win9x, got ERROR_PATH_NOT_FOUND w/ FILE_FLAG_BACKUP_SEMANTICS or %s\n", temp_path);
1448 /* *** Test opening volumes/devices using drive letter *** */
1450 /* test using drive letter in non-rewrite format without trailing \ */
1451 /* this should work */
1452 strcpy(filename, nt_drive);
1453 filename[4] = windowsdir[0];
1454 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1455 FILE_SHARE_READ | FILE_SHARE_WRITE,
1456 NULL, OPEN_EXISTING,
1457 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
1458 if (hFile != INVALID_HANDLE_VALUE ||
1459 (GetLastError() != ERROR_ACCESS_DENIED && GetLastError() != ERROR_BAD_NETPATH))
1461 /* if we have adm rights to volume, then try rest of tests */
1462 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA did not open %s, last error=%lu\n",
1463 filename, GetLastError());
1464 if (hFile != INVALID_HANDLE_VALUE)
1466 /* if we opened the volume/device, try to read it. Since it */
1467 /* opened, we should be able to read it. We don't care about*/
1468 /* what the data is at this time. */
1469 len = 512;
1470 ret = ReadFile( hFile, buffer, len, &len, NULL );
1471 todo_wine ok(ret, "Failed to read volume, last error %lu, %lu, for %s\n",
1472 GetLastError(), ret, filename);
1473 if (ret)
1475 trace("buffer is\n");
1476 dumpmem(buffer, 64);
1478 CloseHandle( hFile );
1481 /* test using drive letter with trailing \ and in non-rewrite */
1482 /* this should not work */
1483 strcpy(filename, nt_drive);
1484 filename[4] = windowsdir[0];
1485 strcat( filename, "\\" );
1486 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1487 FILE_SHARE_READ | FILE_SHARE_WRITE,
1488 NULL, OPEN_EXISTING,
1489 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
1490 todo_wine
1491 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
1492 "CreateFileA should have returned ERROR_PATH_NOT_FOUND on %s, but got %lu\n",
1493 filename, GetLastError());
1494 if (hFile != INVALID_HANDLE_VALUE)
1495 CloseHandle( hFile );
1497 /* test using temp path with trailing \ and in non-rewrite as dir */
1498 /* this should work */
1499 strcpy(filename, nt_drive);
1500 filename[4] = 0;
1501 strcat( filename, temp_path );
1502 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1503 FILE_SHARE_READ | FILE_SHARE_WRITE,
1504 NULL, OPEN_EXISTING,
1505 FILE_FLAG_BACKUP_SEMANTICS, NULL );
1506 ok(hFile != INVALID_HANDLE_VALUE,
1507 "CreateFileA should have worked on %s, but got %lu\n",
1508 filename, GetLastError());
1509 if (hFile != INVALID_HANDLE_VALUE)
1510 CloseHandle( hFile );
1512 /* test using drive letter without trailing \ and in device ns */
1513 /* this should work */
1514 strcpy(filename, nt_drive);
1515 filename[4] = windowsdir[0];
1516 filename[2] = '.';
1517 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1518 FILE_SHARE_READ | FILE_SHARE_WRITE,
1519 NULL, OPEN_EXISTING,
1520 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
1521 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA did not open %s, last error=%lu\n",
1522 filename, GetLastError());
1523 if (hFile != INVALID_HANDLE_VALUE)
1524 CloseHandle( hFile );
1526 /* If we see ERROR_BAD_NETPATH then on Win9x or WinME, so skip */
1527 else if (GetLastError() == ERROR_BAD_NETPATH)
1528 skip("Probable Win9x, got ERROR_BAD_NETPATH (53)\n");
1529 else
1530 skip("Do not have authority to access volumes. Tests skipped\n");
1533 /* *** Test opening volumes/devices using GUID *** */
1535 if (pGetVolumeNameForVolumeMountPointA)
1537 strcpy(filename, "c:\\");
1538 filename[0] = windowsdir[0];
1539 ret = pGetVolumeNameForVolumeMountPointA( filename, Volume_1, MAX_PATH );
1540 ok(ret, "GetVolumeNameForVolumeMountPointA failed, for %s, last error=%ld\n", filename, GetLastError());
1541 if (ret)
1543 ok(strlen(Volume_1) == 49, "GetVolumeNameForVolumeMountPointA returned wrong length name <%s>\n", Volume_1);
1545 /* test the result of opening a unique volume name (GUID)
1546 * with the trailing \
1547 * this should error out
1549 strcpy(filename, Volume_1);
1550 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1551 FILE_SHARE_READ | FILE_SHARE_WRITE,
1552 NULL, OPEN_EXISTING,
1553 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
1554 todo_wine
1555 ok(hFile == INVALID_HANDLE_VALUE,
1556 "CreateFileA should not have opened %s, hFile %p\n",
1557 filename, hFile);
1558 todo_wine
1559 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
1560 "CreateFileA should have returned ERROR_PATH_NOT_FOUND on %s, but got %lu\n",
1561 filename, GetLastError());
1562 if (hFile != INVALID_HANDLE_VALUE)
1563 CloseHandle( hFile );
1565 /* test the result of opening a unique volume name (GUID)
1566 * with the temp path string as dir
1567 * this should work
1569 strcpy(filename, Volume_1);
1570 strcat(filename, temp_path+3);
1571 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1572 FILE_SHARE_READ | FILE_SHARE_WRITE,
1573 NULL, OPEN_EXISTING,
1574 FILE_FLAG_BACKUP_SEMANTICS, NULL );
1575 todo_wine
1576 ok(hFile != INVALID_HANDLE_VALUE,
1577 "CreateFileA should have opened %s, but got %lu\n",
1578 filename, GetLastError());
1579 if (hFile != INVALID_HANDLE_VALUE)
1580 CloseHandle( hFile );
1582 /* test the result of opening a unique volume name (GUID)
1583 * without the trailing \ and in device namespace
1584 * this should work
1586 strcpy(filename, Volume_1);
1587 filename[2] = '.';
1588 filename[48] = 0;
1589 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1590 FILE_SHARE_READ | FILE_SHARE_WRITE,
1591 NULL, OPEN_EXISTING,
1592 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
1593 if (hFile != INVALID_HANDLE_VALUE || GetLastError() != ERROR_ACCESS_DENIED)
1595 /* if we have adm rights to volume, then try rest of tests */
1596 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA did not open %s, last error=%lu\n",
1597 filename, GetLastError());
1598 if (hFile != INVALID_HANDLE_VALUE)
1600 /* if we opened the volume/device, try to read it. Since it */
1601 /* opened, we should be able to read it. We don't care about*/
1602 /* what the data is at this time. */
1603 len = 512;
1604 ret = ReadFile( hFile, buffer, len, &len, NULL );
1605 todo_wine ok(ret, "Failed to read volume, last error %lu, %lu, for %s\n",
1606 GetLastError(), ret, filename);
1607 if (ret)
1609 trace("buffer is\n");
1610 dumpmem(buffer, 64);
1612 CloseHandle( hFile );
1615 else
1616 skip("Do not have authority to access volumes. Tests skipped\n");
1618 else
1619 win_skip("GetVolumeNameForVolumeMountPointA not functioning\n");
1621 else
1622 win_skip("GetVolumeNameForVolumeMountPointA not found\n");
1625 static void test_CreateFileW(void)
1627 HANDLE hFile;
1628 WCHAR temp_path[MAX_PATH];
1629 WCHAR filename[MAX_PATH];
1630 static const WCHAR emptyW[]={'\0'};
1631 static const WCHAR prefix[] = {'p','f','x',0};
1632 static const WCHAR bogus[] = { '\\', '\\', '.', '\\', 'B', 'O', 'G', 'U', 'S', 0 };
1633 DWORD ret;
1635 ret = GetTempPathW(MAX_PATH, temp_path);
1636 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1638 win_skip("GetTempPathW is not available\n");
1639 return;
1641 ok(ret != 0, "GetTempPathW error %ld\n", GetLastError());
1642 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
1644 ret = GetTempFileNameW(temp_path, prefix, 0, filename);
1645 ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError());
1647 SetLastError(0xdeadbeef);
1648 hFile = CreateFileW(filename, GENERIC_READ, 0, NULL,
1649 CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
1650 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS,
1651 "CREATE_NEW should fail if file exists and last error value should be ERROR_FILE_EXISTS\n");
1653 SetLastError(0xdeadbeef);
1654 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
1655 CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
1656 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
1657 "hFile %p, last error %lu\n", hFile, GetLastError());
1659 CloseHandle(hFile);
1661 SetLastError(0xdeadbeef);
1662 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
1663 OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
1664 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
1665 "hFile %p, last error %lu\n", hFile, GetLastError());
1667 CloseHandle(hFile);
1669 ret = DeleteFileW(filename);
1670 ok(ret, "DeleteFileW: error %ld\n", GetLastError());
1672 SetLastError(0xdeadbeef);
1673 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
1674 OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
1675 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == 0,
1676 "hFile %p, last error %lu\n", hFile, GetLastError());
1678 CloseHandle(hFile);
1680 ret = DeleteFileW(filename);
1681 ok(ret, "DeleteFileW: error %ld\n", GetLastError());
1683 if (0)
1685 /* this crashes on NT4.0 */
1686 hFile = CreateFileW(NULL, GENERIC_READ, 0, NULL,
1687 CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
1688 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
1689 "CreateFileW(NULL) returned ret=%p error=%lu\n",hFile,GetLastError());
1692 hFile = CreateFileW(emptyW, GENERIC_READ, 0, NULL,
1693 CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
1694 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
1695 "CreateFileW(\"\") returned ret=%p error=%ld\n",hFile,GetLastError());
1697 /* test the result of opening a nonexistent driver name */
1698 hFile = CreateFileW(bogus, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1699 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1700 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND,
1701 "CreateFileW on invalid VxD name returned ret=%p error=%ld\n",hFile,GetLastError());
1703 ret = CreateDirectoryW(filename, NULL);
1704 ok(ret == TRUE, "couldn't create temporary directory\n");
1705 hFile = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
1706 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL);
1707 ok(hFile != INVALID_HANDLE_VALUE,
1708 "expected CreateFile to succeed on existing directory, error: %ld\n", GetLastError());
1709 CloseHandle(hFile);
1710 ret = RemoveDirectoryW(filename);
1711 ok(ret, "DeleteFileW: error %ld\n", GetLastError());
1714 static void test_CreateFile2(void)
1716 HANDLE hFile, iocp;
1717 WCHAR temp_path[MAX_PATH];
1718 WCHAR filename[MAX_PATH];
1719 CREATEFILE2_EXTENDED_PARAMETERS exparams;
1720 static const WCHAR emptyW[]={'\0'};
1721 static const WCHAR prefix[] = {'p','f','x',0};
1722 static const WCHAR bogus[] = { '\\', '\\', '.', '\\', 'B', 'O', 'G', 'U', 'S', 0 };
1723 DWORD i, ret;
1725 if (!pCreateFile2)
1727 win_skip("CreateFile2 is missing\n");
1728 return;
1731 ret = GetTempPathW(MAX_PATH, temp_path);
1732 ok(ret != 0, "GetTempPathW error %ld\n", GetLastError());
1733 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
1735 ret = GetTempFileNameW(temp_path, prefix, 0, filename);
1736 ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError());
1738 SetLastError(0xdeadbeef);
1739 exparams.dwSize = sizeof(exparams);
1740 exparams.dwFileAttributes = 0;
1741 exparams.dwFileFlags = FILE_FLAG_RANDOM_ACCESS;
1742 exparams.dwSecurityQosFlags = 0;
1743 exparams.lpSecurityAttributes = NULL;
1744 exparams.hTemplateFile = 0;
1745 hFile = pCreateFile2(filename, GENERIC_READ, 0, CREATE_NEW, &exparams);
1746 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS,
1747 "CREATE_NEW should fail if file exists and last error value should be ERROR_FILE_EXISTS\n");
1749 SetLastError(0xdeadbeef);
1750 hFile = pCreateFile2(filename, GENERIC_READ, FILE_SHARE_READ, CREATE_ALWAYS, &exparams);
1751 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
1752 "hFile %p, last error %lu\n", hFile, GetLastError());
1753 CloseHandle(hFile);
1755 SetLastError(0xdeadbeef);
1756 hFile = pCreateFile2(filename, GENERIC_READ, FILE_SHARE_READ, OPEN_ALWAYS, &exparams);
1757 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
1758 "hFile %p, last error %lu\n", hFile, GetLastError());
1759 CloseHandle(hFile);
1761 ret = DeleteFileW(filename);
1762 ok(ret, "DeleteFileW: error %ld\n", GetLastError());
1764 SetLastError(0xdeadbeef);
1765 hFile = pCreateFile2(filename, GENERIC_READ, FILE_SHARE_READ, OPEN_ALWAYS, &exparams);
1766 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == 0,
1767 "hFile %p, last error %lu\n", hFile, GetLastError());
1768 CloseHandle(hFile);
1770 ret = DeleteFileW(filename);
1771 ok(ret, "DeleteFileW: error %ld\n", GetLastError());
1773 hFile = pCreateFile2(emptyW, GENERIC_READ, 0, CREATE_NEW, &exparams);
1774 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
1775 "CreateFile2(\"\") returned ret=%p error=%ld\n",hFile,GetLastError());
1777 /* test the result of opening a nonexistent driver name */
1778 exparams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
1779 hFile = pCreateFile2(bogus, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING, &exparams);
1780 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND,
1781 "CreateFile2 on invalid VxD name returned ret=%p error=%ld\n",hFile,GetLastError());
1783 ret = CreateDirectoryW(filename, NULL);
1784 ok(ret == TRUE, "couldn't create temporary directory\n");
1785 exparams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
1786 exparams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
1787 SetLastError(0xdeadbeef);
1788 hFile = pCreateFile2(filename, GENERIC_READ | GENERIC_WRITE, 0, OPEN_ALWAYS, &exparams);
1789 ok(hFile != INVALID_HANDLE_VALUE,
1790 "CreateFile2 failed with FILE_FLAG_BACKUP_SEMANTICS on existing directory, error: %ld\n", GetLastError());
1791 CloseHandle(hFile);
1792 ret = RemoveDirectoryW(filename);
1793 ok(ret, "DeleteFileW: error %ld\n", GetLastError());
1795 for (i = 0; i < 2; ++i)
1797 memset(&exparams, 0, sizeof(exparams));
1798 exparams.dwSize = sizeof(exparams);
1799 if (i == 0)
1801 exparams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
1802 exparams.dwFileFlags = FILE_FLAG_OVERLAPPED | FILE_FLAG_DELETE_ON_CLOSE;
1804 else
1806 exparams.dwFileFlags = FILE_ATTRIBUTE_NORMAL;
1807 exparams.dwFileAttributes = FILE_FLAG_OVERLAPPED | FILE_FLAG_DELETE_ON_CLOSE;
1810 SetLastError(0xdeadbeef);
1811 hFile = pCreateFile2(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, CREATE_ALWAYS, &exparams);
1812 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == 0, "%ld: hFile %p, last error %lu\n", i, hFile, GetLastError());
1814 iocp = CreateIoCompletionPort(hFile, NULL, 0, 2);
1815 if (i == 1) ok(iocp == NULL && GetLastError() == ERROR_INVALID_PARAMETER, "%ld: CreateIoCompletionPort returned %p, error %lu\n", i, iocp, GetLastError());
1816 else ok(iocp != INVALID_HANDLE_VALUE && GetLastError() == 0, "%ld: CreateIoCompletionPort returned %p, error %lu\n", i, iocp, GetLastError());
1818 CloseHandle(iocp);
1819 CloseHandle(hFile);
1821 ret = DeleteFileW(filename);
1822 if (i == 1) ok(ret, "%ld: unexpected DeleteFileW failure, error %lu\n", i, GetLastError());
1823 else ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, "%ld: unexpected DeleteFileW result, ret %ld error %lu\n", i, ret, GetLastError());
1827 static void test_GetTempFileNameA(void)
1829 UINT result;
1830 char out[MAX_PATH];
1831 char expected[MAX_PATH + 10];
1832 char windowsdir[MAX_PATH + 10];
1833 char windowsdrive[3];
1835 result = GetWindowsDirectoryA(windowsdir, sizeof(windowsdir));
1836 ok(result < sizeof(windowsdir), "windowsdir is abnormally long!\n");
1837 ok(result != 0, "GetWindowsDirectory: error %ld\n", GetLastError());
1839 /* If the Windows directory is the root directory, it ends in backslash, not else. */
1840 if (strlen(windowsdir) != 3) /* As in "C:\" or "F:\" */
1842 strcat(windowsdir, "\\");
1845 windowsdrive[0] = windowsdir[0];
1846 windowsdrive[1] = windowsdir[1];
1847 windowsdrive[2] = '\0';
1849 result = GetTempFileNameA(windowsdrive, "abc", 1, out);
1850 ok(result != 0, "GetTempFileNameA: error %ld\n", GetLastError());
1851 ok(((out[0] == windowsdrive[0]) && (out[1] == ':')) && (out[2] == '\\'),
1852 "GetTempFileNameA: first three characters should be %c:\\, string was actually %s\n",
1853 windowsdrive[0], out);
1855 result = GetTempFileNameA(windowsdir, "abc", 2, out);
1856 ok(result != 0, "GetTempFileNameA: error %ld\n", GetLastError());
1857 expected[0] = '\0';
1858 strcat(expected, windowsdir);
1859 strcat(expected, "abc2.tmp");
1860 ok(lstrcmpiA(out, expected) == 0, "GetTempFileNameA: Unexpected output \"%s\" vs \"%s\"\n",
1861 out, expected);
1864 static void test_DeleteFileA( void )
1866 BOOL ret;
1867 char temp_path[MAX_PATH], temp_file[MAX_PATH];
1868 HANDLE hfile, mapping;
1869 char **argv;
1871 ret = DeleteFileA(NULL);
1872 ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER ||
1873 GetLastError() == ERROR_PATH_NOT_FOUND),
1874 "DeleteFileA(NULL) returned ret=%d error=%ld\n",ret,GetLastError());
1876 ret = DeleteFileA("");
1877 ok(!ret && (GetLastError() == ERROR_PATH_NOT_FOUND ||
1878 GetLastError() == ERROR_BAD_PATHNAME),
1879 "DeleteFileA(\"\") returned ret=%d error=%ld\n",ret,GetLastError());
1881 ret = DeleteFileA("nul");
1882 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
1883 GetLastError() == ERROR_INVALID_PARAMETER ||
1884 GetLastError() == ERROR_ACCESS_DENIED ||
1885 GetLastError() == ERROR_INVALID_FUNCTION),
1886 "DeleteFileA(\"nul\") returned ret=%d error=%ld\n",ret,GetLastError());
1888 ret = DeleteFileA("nonexist.txt");
1889 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, "DeleteFileA(\"nonexist.txt\") returned ret=%d error=%ld\n",ret,GetLastError());
1891 GetTempPathA(MAX_PATH, temp_path);
1892 GetTempFileNameA(temp_path, "tst", 0, temp_file);
1894 SetLastError(0xdeadbeef);
1895 hfile = CreateFileA(temp_file, GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
1896 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
1898 SetLastError(0xdeadbeef);
1899 ret = DeleteFileA(temp_file);
1900 ok(ret, "DeleteFile error %ld\n", GetLastError());
1902 SetLastError(0xdeadbeef);
1903 ret = CloseHandle(hfile);
1904 ok(ret, "CloseHandle error %ld\n", GetLastError());
1905 ret = DeleteFileA(temp_file);
1906 ok(!ret, "DeleteFile should fail\n");
1908 SetLastError(0xdeadbeef);
1909 ret = CreateDirectoryA("testdir", NULL);
1910 ok(ret, "CreateDirectory failed, got err %ld\n", GetLastError());
1911 ret = DeleteFileA("testdir");
1912 ok(!ret && GetLastError() == ERROR_ACCESS_DENIED,
1913 "Expected ERROR_ACCESS_DENIED, got error %ld\n", GetLastError());
1914 ret = RemoveDirectoryA("testdir");
1915 ok(ret, "Remove a directory failed, got error %ld\n", GetLastError());
1917 winetest_get_mainargs(&argv);
1919 ret = CopyFileA(argv[0], temp_file, FALSE);
1920 ok(ret, "got error %lu\n", GetLastError());
1921 hfile = CreateFileA(temp_file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0);
1922 ok(hfile != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError());
1924 mapping = CreateFileMappingA(hfile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL);
1925 ok(!!mapping, "got error %lu\n", GetLastError());
1927 SetLastError(0xdeadbeef);
1928 ret = DeleteFileA(temp_file);
1929 ok(!ret, "expected failure\n");
1930 ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
1932 CloseHandle(mapping);
1934 ret = DeleteFileA(temp_file);
1935 ok(ret, "got error %lu\n", GetLastError());
1937 CloseHandle(hfile);
1940 static void test_DeleteFileW( void )
1942 BOOL ret;
1943 WCHAR pathW[MAX_PATH];
1944 WCHAR pathsubW[MAX_PATH];
1945 static const WCHAR dirW[] = {'d','e','l','e','t','e','f','i','l','e',0};
1946 static const WCHAR subdirW[] = {'\\','s','u','b',0};
1947 static const WCHAR emptyW[]={'\0'};
1949 ret = DeleteFileW(NULL);
1950 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1952 win_skip("DeleteFileW is not available\n");
1953 return;
1955 ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND,
1956 "DeleteFileW(NULL) returned ret=%d error=%ld\n",ret,GetLastError());
1958 ret = DeleteFileW(emptyW);
1959 ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND,
1960 "DeleteFileW(\"\") returned ret=%d error=%ld\n",ret,GetLastError());
1962 /* test DeleteFile on empty directory */
1963 ret = GetTempPathW(MAX_PATH, pathW);
1964 if (ret + ARRAY_SIZE(dirW)-1 + ARRAY_SIZE(subdirW)-1 >= MAX_PATH)
1966 ok(0, "MAX_PATH exceeded in constructing paths\n");
1967 return;
1969 lstrcatW(pathW, dirW);
1970 lstrcpyW(pathsubW, pathW);
1971 lstrcatW(pathsubW, subdirW);
1972 ret = CreateDirectoryW(pathW, NULL);
1973 ok(ret == TRUE, "couldn't create directory deletefile\n");
1974 ret = DeleteFileW(pathW);
1975 ok(ret == FALSE, "DeleteFile should fail for empty directories\n");
1976 ret = RemoveDirectoryW(pathW);
1977 ok(ret == TRUE, "expected to remove directory deletefile\n");
1979 /* test DeleteFile on non-empty directory */
1980 ret = CreateDirectoryW(pathW, NULL);
1981 ok(ret == TRUE, "couldn't create directory deletefile\n");
1982 ret = CreateDirectoryW(pathsubW, NULL);
1983 ok(ret == TRUE, "couldn't create directory deletefile\\sub\n");
1984 ret = DeleteFileW(pathW);
1985 ok(ret == FALSE, "DeleteFile should fail for non-empty directories\n");
1986 ret = RemoveDirectoryW(pathsubW);
1987 ok(ret == TRUE, "expected to remove directory deletefile\\sub\n");
1988 ret = RemoveDirectoryW(pathW);
1989 ok(ret == TRUE, "expected to remove directory deletefile\n");
1992 #define IsDotDir(x) ((x[0] == '.') && ((x[1] == 0) || ((x[1] == '.') && (x[2] == 0))))
1994 static void test_MoveFileA(void)
1996 char tempdir[MAX_PATH];
1997 char source[MAX_PATH], dest[MAX_PATH];
1998 static const char prefix[] = "pfx";
1999 WIN32_FIND_DATAA find_data;
2000 HANDLE hfile;
2001 HANDLE hmapfile;
2002 DWORD ret;
2003 BOOL retok;
2005 ret = GetTempPathA(MAX_PATH, tempdir);
2006 ok(ret != 0, "GetTempPathA error %ld\n", GetLastError());
2007 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
2009 ret = GetTempFileNameA(tempdir, prefix, 0, source);
2010 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
2012 ret = GetTempFileNameA(tempdir, prefix, 0, dest);
2013 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
2015 ret = MoveFileA(source, source);
2016 ok(ret, "MoveFileA: failed, error %ld\n", GetLastError());
2018 ret = MoveFileA(source, dest);
2019 ok(!ret && GetLastError() == ERROR_ALREADY_EXISTS,
2020 "MoveFileA: unexpected error %ld\n", GetLastError());
2022 ret = DeleteFileA(dest);
2023 ok(ret, "DeleteFileA: error %ld\n", GetLastError());
2025 hfile = CreateFileA(source, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
2026 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
2028 retok = WriteFile(hfile, prefix, sizeof(prefix), &ret, NULL );
2029 ok( retok && ret == sizeof(prefix),
2030 "WriteFile error %ld\n", GetLastError());
2032 hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
2033 ok(hmapfile != NULL, "CreateFileMapping: error %ld\n", GetLastError());
2035 ret = MoveFileA(source, dest);
2036 ok(!ret, "MoveFileA: expected failure\n");
2037 ok(GetLastError() == ERROR_SHARING_VIOLATION ||
2038 broken(GetLastError() == ERROR_ACCESS_DENIED), /* Win9x and WinMe */
2039 "MoveFileA: expected ERROR_SHARING_VIOLATION, got %ld\n", GetLastError());
2041 CloseHandle(hmapfile);
2042 CloseHandle(hfile);
2044 /* if MoveFile succeeded, move back to dest */
2045 if (ret) MoveFileA(dest, source);
2047 hfile = CreateFileA(source, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
2048 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
2050 hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
2051 ok(hmapfile != NULL, "CreateFileMapping: error %ld\n", GetLastError());
2053 ret = MoveFileA(source, dest);
2054 ok(!ret, "MoveFileA: expected failure\n");
2055 ok(GetLastError() == ERROR_SHARING_VIOLATION ||
2056 broken(GetLastError() == ERROR_ACCESS_DENIED), /* Win9x and WinMe */
2057 "MoveFileA: expected ERROR_SHARING_VIOLATION, got %ld\n", GetLastError());
2059 CloseHandle(hmapfile);
2060 CloseHandle(hfile);
2062 /* if MoveFile succeeded, move back to dest */
2063 if (ret) MoveFileA(dest, source);
2065 ret = MoveFileA(source, dest);
2066 ok(ret, "MoveFileA: failed, error %ld\n", GetLastError());
2068 lstrcatA(tempdir, "Remove Me");
2070 /* test renaming a file "Remove Me" to itself but in lowercase "me" */
2071 lstrcpyA(source, tempdir);
2072 tempdir[lstrlenA(tempdir) - 2] = 'm';
2074 hfile = CreateFileA(source, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, 0);
2075 ok(hfile != INVALID_HANDLE_VALUE, "failed to create %s\n", source);
2076 CloseHandle(hfile);
2078 ret = MoveFileA(source, tempdir);
2079 ok(ret, "MoveFileA: failed, error %ld\n", GetLastError());
2081 hfile = FindFirstFileA(tempdir, &find_data);
2082 ok(hfile != INVALID_HANDLE_VALUE, "FindFirstFileA: failed, error %ld\n", GetLastError());
2083 if (hfile != INVALID_HANDLE_VALUE)
2085 todo_wine ok(!lstrcmpA(strrchr(tempdir, '\\') + 1, find_data.cFileName),
2086 "MoveFile failed to change casing on same file: got %s\n", find_data.cFileName);
2088 CloseHandle(hfile);
2090 /* test renaming another file "Remove Be" to "Remove Me", which replaces the existing "Remove me" */
2091 tempdir[lstrlenA(tempdir) - 2] = 'B';
2093 hfile = CreateFileA(tempdir, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, 0);
2094 ok(hfile != INVALID_HANDLE_VALUE, "failed to create %s\n", tempdir);
2095 CloseHandle(hfile);
2097 ret = MoveFileA(tempdir, source);
2098 ok(!ret, "MoveFileA: expected failure\n");
2099 ok(GetLastError() == ERROR_ALREADY_EXISTS, "MoveFileA: expected ERROR_ALREADY_EXISTS, got %ld\n", GetLastError());
2100 ret = MoveFileExA(tempdir, source, MOVEFILE_REPLACE_EXISTING);
2101 ok(ret, "MoveFileExA: failed, error %ld\n", GetLastError());
2103 tempdir[lstrlenA(tempdir) - 2] = 'm';
2105 hfile = FindFirstFileA(tempdir, &find_data);
2106 ok(hfile != INVALID_HANDLE_VALUE, "FindFirstFileA: failed, error %ld\n", GetLastError());
2107 if (hfile != INVALID_HANDLE_VALUE)
2109 ok(!lstrcmpA(strrchr(source, '\\') + 1, find_data.cFileName),
2110 "MoveFile failed to change casing on existing target file: got %s\n", find_data.cFileName);
2112 CloseHandle(hfile);
2114 ret = DeleteFileA(tempdir);
2115 ok(ret, "DeleteFileA: error %ld\n", GetLastError());
2117 /* now test a directory from "Remove me" to uppercase "Me" */
2118 ret = CreateDirectoryA(tempdir, NULL);
2119 ok(ret == TRUE, "CreateDirectoryA failed\n");
2121 lstrcpyA(source, tempdir);
2122 tempdir[lstrlenA(tempdir) - 2] = 'M';
2123 ret = MoveFileA(source, tempdir);
2124 ok(ret, "MoveFileA: failed, error %ld\n", GetLastError());
2126 hfile = FindFirstFileA(tempdir, &find_data);
2127 ok(hfile != INVALID_HANDLE_VALUE, "FindFirstFileA: failed, error %ld\n", GetLastError());
2128 if (hfile != INVALID_HANDLE_VALUE)
2130 todo_wine ok(!lstrcmpA(strrchr(tempdir, '\\') + 1, find_data.cFileName),
2131 "MoveFile failed to change casing on same directory: got %s\n", find_data.cFileName);
2133 CloseHandle(hfile);
2135 lstrcpyA(source, dest);
2136 lstrcpyA(dest, tempdir);
2137 lstrcatA(dest, "\\wild?.*");
2138 /* FIXME: if we create a file with wildcards we can't delete it now that DeleteFile works correctly */
2139 ret = MoveFileA(source, dest);
2140 ok(!ret, "MoveFileA: shouldn't move to wildcard file\n");
2141 ok(GetLastError() == ERROR_INVALID_NAME || /* NT */
2142 GetLastError() == ERROR_FILE_NOT_FOUND, /* Win9x */
2143 "MoveFileA: with wildcards, unexpected error %ld\n", GetLastError());
2144 if (ret || (GetLastError() != ERROR_INVALID_NAME))
2146 WIN32_FIND_DATAA fd;
2147 char temppath[MAX_PATH];
2148 HANDLE hFind;
2150 lstrcpyA(temppath, tempdir);
2151 lstrcatA(temppath, "\\*.*");
2152 hFind = FindFirstFileA(temppath, &fd);
2153 if (INVALID_HANDLE_VALUE != hFind)
2155 LPSTR lpName;
2158 lpName = fd.cAlternateFileName;
2159 if (!lpName[0])
2160 lpName = fd.cFileName;
2161 ok(IsDotDir(lpName), "MoveFileA: wildcards file created!\n");
2163 while (FindNextFileA(hFind, &fd));
2164 FindClose(hFind);
2167 ret = DeleteFileA(source);
2168 ok(ret, "DeleteFileA: error %ld\n", GetLastError());
2169 ret = DeleteFileA(dest);
2170 ok(!ret, "DeleteFileA: error %ld\n", GetLastError());
2171 ret = RemoveDirectoryA(tempdir);
2172 ok(ret, "DeleteDirectoryA: error %ld\n", GetLastError());
2175 static void test_MoveFileW(void)
2177 WCHAR temp_path[MAX_PATH];
2178 WCHAR source[MAX_PATH], dest[MAX_PATH];
2179 static const WCHAR prefix[] = {'p','f','x',0};
2180 DWORD ret;
2182 ret = GetTempPathW(MAX_PATH, temp_path);
2183 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
2185 win_skip("GetTempPathW is not available\n");
2186 return;
2188 ok(ret != 0, "GetTempPathW error %ld\n", GetLastError());
2189 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
2191 ret = GetTempFileNameW(temp_path, prefix, 0, source);
2192 ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError());
2194 ret = GetTempFileNameW(temp_path, prefix, 0, dest);
2195 ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError());
2197 ret = MoveFileW(source, dest);
2198 ok(!ret && GetLastError() == ERROR_ALREADY_EXISTS,
2199 "MoveFileW: unexpected error %ld\n", GetLastError());
2201 ret = DeleteFileW(source);
2202 ok(ret, "DeleteFileW: error %ld\n", GetLastError());
2203 ret = DeleteFileW(dest);
2204 ok(ret, "DeleteFileW: error %ld\n", GetLastError());
2207 #define PATTERN_OFFSET 0x10
2209 static void test_offset_in_overlapped_structure(void)
2211 HANDLE hFile;
2212 OVERLAPPED ov;
2213 DWORD done, offset;
2214 BOOL rc;
2215 BYTE buf[256], pattern[] = "TeSt";
2216 UINT i;
2217 char temp_path[MAX_PATH], temp_fname[MAX_PATH];
2218 BOOL ret;
2220 ret =GetTempPathA(MAX_PATH, temp_path);
2221 ok( ret, "GetTempPathA error %ld\n", GetLastError());
2222 ret =GetTempFileNameA(temp_path, "pfx", 0, temp_fname);
2223 ok( ret, "GetTempFileNameA error %ld\n", GetLastError());
2225 /*** Write File *****************************************************/
2227 hFile = CreateFileA(temp_fname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
2228 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA error %ld\n", GetLastError());
2230 for(i = 0; i < sizeof(buf); i++) buf[i] = i;
2231 ret = WriteFile(hFile, buf, sizeof(buf), &done, NULL);
2232 ok( ret, "WriteFile error %ld\n", GetLastError());
2233 ok(done == sizeof(buf), "expected number of bytes written %lu\n", done);
2235 memset(&ov, 0, sizeof(ov));
2236 ov.Offset = PATTERN_OFFSET;
2237 ov.OffsetHigh = 0;
2238 rc=WriteFile(hFile, pattern, sizeof(pattern), &done, &ov);
2239 /* Win 9x does not support the overlapped I/O on files */
2240 if (rc || GetLastError()!=ERROR_INVALID_PARAMETER) {
2241 ok(rc, "WriteFile error %ld\n", GetLastError());
2242 ok(done == sizeof(pattern), "expected number of bytes written %lu\n", done);
2243 offset = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
2244 ok(offset == PATTERN_OFFSET + sizeof(pattern), "wrong file offset %ld\n", offset);
2246 ov.Offset = sizeof(buf) * 2;
2247 ov.OffsetHigh = 0;
2248 ret = WriteFile(hFile, pattern, sizeof(pattern), &done, &ov);
2249 ok( ret, "WriteFile error %ld\n", GetLastError());
2250 ok(done == sizeof(pattern), "expected number of bytes written %lu\n", done);
2251 offset = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
2252 ok(offset == sizeof(buf) * 2 + sizeof(pattern), "wrong file offset %ld\n", offset);
2255 CloseHandle(hFile);
2257 /*** Read File *****************************************************/
2259 hFile = CreateFileA(temp_fname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
2260 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA error %ld\n", GetLastError());
2262 memset(buf, 0, sizeof(buf));
2263 memset(&ov, 0, sizeof(ov));
2264 ov.Offset = PATTERN_OFFSET;
2265 ov.OffsetHigh = 0;
2266 rc=ReadFile(hFile, buf, sizeof(pattern), &done, &ov);
2267 /* Win 9x does not support the overlapped I/O on files */
2268 if (rc || GetLastError()!=ERROR_INVALID_PARAMETER) {
2269 ok(rc, "ReadFile error %ld\n", GetLastError());
2270 ok(done == sizeof(pattern), "expected number of bytes read %lu\n", done);
2271 offset = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
2272 ok(offset == PATTERN_OFFSET + sizeof(pattern), "wrong file offset %ld\n", offset);
2273 ok(!memcmp(buf, pattern, sizeof(pattern)), "pattern match failed\n");
2276 CloseHandle(hFile);
2278 ret = DeleteFileA(temp_fname);
2279 ok( ret, "DeleteFileA error %ld\n", GetLastError());
2282 static void test_LockFile(void)
2284 HANDLE handle, handle2;
2285 DWORD written;
2286 OVERLAPPED overlapped;
2287 int limited_LockFile;
2288 int limited_UnLockFile;
2289 BOOL ret;
2291 handle = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
2292 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
2293 CREATE_ALWAYS, 0, 0 );
2294 if (handle == INVALID_HANDLE_VALUE)
2296 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
2297 return;
2299 handle2 = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
2300 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
2301 OPEN_EXISTING, 0, 0 );
2302 if (handle2 == INVALID_HANDLE_VALUE)
2304 ok( 0, "couldn't open file \"%s\" (err=%ld)\n", filename, GetLastError() );
2305 goto cleanup;
2307 ok( WriteFile( handle, sillytext, strlen(sillytext), &written, NULL ), "write failed\n" );
2309 ok( LockFile( handle, 0, 0, 0, 0 ), "LockFile failed\n" );
2310 ok( UnlockFile( handle, 0, 0, 0, 0 ), "UnlockFile failed\n" );
2312 limited_UnLockFile = 0;
2313 if (UnlockFile( handle, 0, 0, 0, 0 ))
2315 limited_UnLockFile = 1;
2318 ok( LockFile( handle, 10, 0, 20, 0 ), "LockFile 10,20 failed\n" );
2319 /* overlapping locks must fail */
2320 ok( !LockFile( handle, 12, 0, 10, 0 ), "LockFile 12,10 succeeded\n" );
2321 ok( !LockFile( handle, 5, 0, 6, 0 ), "LockFile 5,6 succeeded\n" );
2322 /* non-overlapping locks must succeed */
2323 ok( LockFile( handle, 5, 0, 5, 0 ), "LockFile 5,5 failed\n" );
2325 ok( !UnlockFile( handle, 10, 0, 10, 0 ), "UnlockFile 10,10 succeeded\n" );
2326 ok( UnlockFile( handle, 10, 0, 20, 0 ), "UnlockFile 10,20 failed\n" );
2327 ok( !UnlockFile( handle, 10, 0, 20, 0 ), "UnlockFile 10,20 again succeeded\n" );
2328 ok( UnlockFile( handle, 5, 0, 5, 0 ), "UnlockFile 5,5 failed\n" );
2330 overlapped.Offset = 100;
2331 overlapped.OffsetHigh = 0;
2332 overlapped.hEvent = 0;
2334 /* Test for broken LockFileEx a la Windows 95 OSR2. */
2335 if (LockFileEx( handle, 0, 0, 100, 0, &overlapped ))
2337 /* LockFileEx is probably OK, test it more. */
2338 ok( LockFileEx( handle, 0, 0, 100, 0, &overlapped ),
2339 "LockFileEx 100,100 failed\n" );
2342 /* overlapping shared locks are OK */
2343 overlapped.Offset = 150;
2344 limited_UnLockFile || ok( LockFileEx( handle, 0, 0, 100, 0, &overlapped ), "LockFileEx 150,100 failed\n" );
2346 /* but exclusive is not */
2347 ok( !LockFileEx( handle, LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,
2348 0, 50, 0, &overlapped ),
2349 "LockFileEx exclusive 150,50 succeeded\n" );
2350 if (!UnlockFileEx( handle, 0, 100, 0, &overlapped ))
2351 { /* UnLockFile is capable. */
2352 overlapped.Offset = 100;
2353 ok( !UnlockFileEx( handle, 0, 100, 0, &overlapped ),
2354 "UnlockFileEx 150,100 again succeeded\n" );
2357 /* shared lock can overlap exclusive if handles are equal */
2358 overlapped.Offset = 300;
2359 ok( LockFileEx( handle, LOCKFILE_EXCLUSIVE_LOCK, 0, 100, 0, &overlapped ),
2360 "LockFileEx exclusive 300,100 failed\n" );
2361 ok( !LockFileEx( handle2, LOCKFILE_FAIL_IMMEDIATELY, 0, 100, 0, &overlapped ),
2362 "LockFileEx handle2 300,100 succeeded\n" );
2363 ret = LockFileEx( handle, LOCKFILE_FAIL_IMMEDIATELY, 0, 100, 0, &overlapped );
2364 ok( ret, "LockFileEx 300,100 failed\n" );
2365 ok( UnlockFileEx( handle, 0, 100, 0, &overlapped ), "UnlockFileEx 300,100 failed\n" );
2366 /* exclusive lock is removed first */
2367 ok( LockFileEx( handle2, LOCKFILE_FAIL_IMMEDIATELY, 0, 100, 0, &overlapped ),
2368 "LockFileEx handle2 300,100 failed\n" );
2369 ok( UnlockFileEx( handle2, 0, 100, 0, &overlapped ), "UnlockFileEx 300,100 failed\n" );
2370 if (ret)
2371 ok( UnlockFileEx( handle, 0, 100, 0, &overlapped ), "UnlockFileEx 300,100 failed\n" );
2373 ret = LockFile( handle, 0, 0x10000000, 0, 0xf0000000 );
2374 if (ret)
2376 ok( !LockFile( handle, ~0, ~0, 1, 0 ), "LockFile ~0,1 succeeded\n" );
2377 ok( !LockFile( handle, 0, 0x20000000, 20, 0 ), "LockFile 0x20000000,20 succeeded\n" );
2378 ok( UnlockFile( handle, 0, 0x10000000, 0, 0xf0000000 ), "UnlockFile failed\n" );
2380 else /* win9x */
2381 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong LockFile error %lu\n", GetLastError() );
2383 /* wrap-around lock should not do anything */
2384 /* (but still succeeds on NT4 so we don't check result) */
2385 LockFile( handle, 0, 0x10000000, 0, 0xf0000001 );
2387 limited_LockFile = 0;
2388 if (!LockFile( handle, ~0, ~0, 1, 0 ))
2390 limited_LockFile = 1;
2393 limited_UnLockFile || ok( UnlockFile( handle, ~0, ~0, 1, 0 ), "Unlockfile ~0,1 failed\n" );
2395 /* zero-byte lock */
2396 ok( LockFile( handle, 100, 0, 0, 0 ), "LockFile 100,0 failed\n" );
2397 if (!limited_LockFile) ok( !LockFile( handle, 98, 0, 4, 0 ), "LockFile 98,4 succeeded\n" );
2398 ok( LockFile( handle, 90, 0, 10, 0 ), "LockFile 90,10 failed\n" );
2399 if (!limited_LockFile) ok( !LockFile( handle, 100, 0, 10, 0 ), "LockFile 100,10 failed\n" );
2401 ok( UnlockFile( handle, 90, 0, 10, 0 ), "UnlockFile 90,10 failed\n" );
2402 ok( !UnlockFile( handle, 100, 0, 10, 0 ), "UnlockFile 100,10 succeeded\n" );
2404 ok( UnlockFile( handle, 100, 0, 0, 0 ), "UnlockFile 100,0 failed\n" );
2406 CloseHandle( handle2 );
2407 cleanup:
2408 CloseHandle( handle );
2409 DeleteFileA( filename );
2412 static BOOL create_fake_dll( LPCSTR filename )
2414 IMAGE_DOS_HEADER *dos;
2415 IMAGE_NT_HEADERS *nt;
2416 IMAGE_SECTION_HEADER *sec;
2417 BYTE *buffer;
2418 DWORD lfanew = sizeof(*dos);
2419 DWORD size = lfanew + sizeof(*nt) + sizeof(*sec);
2420 DWORD written;
2421 BOOL ret;
2423 HANDLE file = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2424 if (file == INVALID_HANDLE_VALUE) return FALSE;
2426 buffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size );
2428 dos = (IMAGE_DOS_HEADER *)buffer;
2429 dos->e_magic = IMAGE_DOS_SIGNATURE;
2430 dos->e_cblp = sizeof(*dos);
2431 dos->e_cp = 1;
2432 dos->e_cparhdr = lfanew / 16;
2433 dos->e_minalloc = 0;
2434 dos->e_maxalloc = 0xffff;
2435 dos->e_ss = 0x0000;
2436 dos->e_sp = 0x00b8;
2437 dos->e_lfarlc = lfanew;
2438 dos->e_lfanew = lfanew;
2440 nt = (IMAGE_NT_HEADERS *)(buffer + lfanew);
2441 nt->Signature = IMAGE_NT_SIGNATURE;
2442 #if defined __i386__
2443 nt->FileHeader.Machine = IMAGE_FILE_MACHINE_I386;
2444 #elif defined __x86_64__
2445 nt->FileHeader.Machine = IMAGE_FILE_MACHINE_AMD64;
2446 #elif defined __arm__
2447 nt->FileHeader.Machine = IMAGE_FILE_MACHINE_ARMNT;
2448 #elif defined __aarch64__
2449 nt->FileHeader.Machine = IMAGE_FILE_MACHINE_ARM64;
2450 #else
2451 # error You must specify the machine type
2452 #endif
2453 nt->FileHeader.NumberOfSections = 1;
2454 nt->FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER);
2455 nt->FileHeader.Characteristics = IMAGE_FILE_DLL | IMAGE_FILE_EXECUTABLE_IMAGE;
2456 nt->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
2457 nt->OptionalHeader.MajorLinkerVersion = 1;
2458 nt->OptionalHeader.MinorLinkerVersion = 0;
2459 nt->OptionalHeader.ImageBase = 0x10000000;
2460 nt->OptionalHeader.SectionAlignment = 0x1000;
2461 nt->OptionalHeader.FileAlignment = 0x1000;
2462 nt->OptionalHeader.MajorOperatingSystemVersion = 1;
2463 nt->OptionalHeader.MinorOperatingSystemVersion = 0;
2464 nt->OptionalHeader.MajorImageVersion = 1;
2465 nt->OptionalHeader.MinorImageVersion = 0;
2466 nt->OptionalHeader.MajorSubsystemVersion = 4;
2467 nt->OptionalHeader.MinorSubsystemVersion = 0;
2468 nt->OptionalHeader.SizeOfImage = 0x2000;
2469 nt->OptionalHeader.SizeOfHeaders = size;
2470 nt->OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
2471 nt->OptionalHeader.DllCharacteristics = IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT;
2472 nt->OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
2474 sec = (IMAGE_SECTION_HEADER *)(nt + 1);
2475 memcpy( sec->Name, ".rodata", sizeof(".rodata") );
2476 sec->Misc.VirtualSize = 0x1000;
2477 sec->VirtualAddress = 0x1000;
2478 sec->SizeOfRawData = 0;
2479 sec->PointerToRawData = 0;
2480 sec->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
2482 ret = WriteFile( file, buffer, size, &written, NULL ) && written == size;
2483 HeapFree( GetProcessHeap(), 0, buffer );
2484 CloseHandle( file );
2485 return ret;
2488 static unsigned int map_file_access( unsigned int access )
2490 if (access & GENERIC_READ) access |= FILE_GENERIC_READ;
2491 if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE;
2492 if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE;
2493 if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS;
2494 return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
2497 static BOOL is_sharing_compatible( DWORD access1, DWORD sharing1, DWORD access2, DWORD sharing2 )
2499 access1 = map_file_access( access1 );
2500 access2 = map_file_access( access2 );
2501 access1 &= FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_EXECUTE | DELETE;
2502 access2 &= FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_EXECUTE | DELETE;
2504 if (!access1) sharing1 = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
2505 if (!access2) sharing2 = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
2507 if ((access1 & (FILE_READ_DATA|FILE_EXECUTE)) && !(sharing2 & FILE_SHARE_READ)) return FALSE;
2508 if ((access1 & (FILE_WRITE_DATA|FILE_APPEND_DATA)) && !(sharing2 & FILE_SHARE_WRITE)) return FALSE;
2509 if ((access1 & DELETE) && !(sharing2 & FILE_SHARE_DELETE)) return FALSE;
2510 if ((access2 & (FILE_READ_DATA|FILE_EXECUTE)) && !(sharing1 & FILE_SHARE_READ)) return FALSE;
2511 if ((access2 & (FILE_WRITE_DATA|FILE_APPEND_DATA)) && !(sharing1 & FILE_SHARE_WRITE)) return FALSE;
2512 if ((access2 & DELETE) && !(sharing1 & FILE_SHARE_DELETE)) return FALSE;
2513 return TRUE;
2516 static BOOL is_sharing_map_compatible( DWORD map_access, DWORD access2, DWORD sharing2 )
2518 if ((map_access == PAGE_READWRITE || map_access == PAGE_EXECUTE_READWRITE) &&
2519 !(sharing2 & FILE_SHARE_WRITE)) return FALSE;
2520 access2 = map_file_access( access2 );
2521 if ((map_access & SEC_IMAGE) && (access2 & FILE_WRITE_DATA)) return FALSE;
2522 return TRUE;
2525 static void test_file_sharing(void)
2527 struct mode { DWORD dw; const char* str; };
2528 #define M(x) {x, # x}
2529 static const struct mode access_modes[] =
2530 { M(0), M(GENERIC_READ), M(GENERIC_WRITE), M(GENERIC_READ|GENERIC_WRITE),
2531 M(DELETE), M(GENERIC_READ|DELETE), M(GENERIC_WRITE|DELETE), M(GENERIC_READ|GENERIC_WRITE|DELETE),
2532 M(GENERIC_EXECUTE), M(GENERIC_EXECUTE | DELETE),
2533 M(FILE_READ_DATA), M(FILE_WRITE_DATA), M(FILE_APPEND_DATA), M(FILE_READ_EA), M(FILE_WRITE_EA),
2534 M(FILE_READ_DATA | FILE_EXECUTE), M(FILE_WRITE_DATA | FILE_EXECUTE), M(FILE_APPEND_DATA | FILE_EXECUTE),
2535 M(FILE_READ_EA | FILE_EXECUTE), M(FILE_WRITE_EA | FILE_EXECUTE), M(FILE_EXECUTE),
2536 M(FILE_DELETE_CHILD), M(FILE_READ_ATTRIBUTES), M(FILE_WRITE_ATTRIBUTES) };
2537 static const struct mode sharing_modes[] =
2538 { M(0), M(FILE_SHARE_READ),
2539 M(FILE_SHARE_WRITE), M(FILE_SHARE_READ|FILE_SHARE_WRITE),
2540 M(FILE_SHARE_DELETE), M(FILE_SHARE_READ|FILE_SHARE_DELETE),
2541 M(FILE_SHARE_WRITE|FILE_SHARE_DELETE), M(FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE) };
2542 static const struct mode mapping_modes[] =
2543 { M(PAGE_READONLY), M(PAGE_WRITECOPY), M(PAGE_READWRITE), M(SEC_IMAGE | PAGE_WRITECOPY) };
2544 #undef M
2545 int a1, s1, a2, s2;
2546 int ret;
2547 HANDLE h, h2;
2549 /* make sure the file exists */
2550 if (!create_fake_dll( filename ))
2552 ok(0, "couldn't create file \"%s\" (err=%ld)\n", filename, GetLastError());
2553 return;
2556 for (a1 = 0; a1 < ARRAY_SIZE(access_modes); a1++)
2558 for (s1 = 0; s1 < ARRAY_SIZE(sharing_modes); s1++)
2560 SetLastError(0xdeadbeef);
2561 h = CreateFileA( filename, access_modes[a1].dw, sharing_modes[s1].dw,
2562 NULL, OPEN_EXISTING, 0, 0 );
2563 if (h == INVALID_HANDLE_VALUE)
2565 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
2566 return;
2568 for (a2 = 0; a2 < ARRAY_SIZE(access_modes); a2++)
2570 for (s2 = 0; s2 < ARRAY_SIZE(sharing_modes); s2++)
2572 SetLastError(0xdeadbeef);
2573 h2 = CreateFileA( filename, access_modes[a2].dw, sharing_modes[s2].dw,
2574 NULL, OPEN_EXISTING, 0, 0 );
2575 ret = GetLastError();
2576 if (is_sharing_compatible( access_modes[a1].dw, sharing_modes[s1].dw,
2577 access_modes[a2].dw, sharing_modes[s2].dw ))
2579 ok( h2 != INVALID_HANDLE_VALUE,
2580 "open failed for modes %s / %s / %s / %s\n",
2581 access_modes[a1].str, sharing_modes[s1].str,
2582 access_modes[a2].str, sharing_modes[s2].str );
2583 ok( ret == 0, "wrong error code %d\n", ret );
2585 else
2587 ok( h2 == INVALID_HANDLE_VALUE,
2588 "open succeeded for modes %s / %s / %s / %s\n",
2589 access_modes[a1].str, sharing_modes[s1].str,
2590 access_modes[a2].str, sharing_modes[s2].str );
2591 ok( ret == ERROR_SHARING_VIOLATION,
2592 "wrong error code %d\n", ret );
2594 if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 );
2597 CloseHandle( h );
2601 for (a1 = 0; a1 < ARRAY_SIZE(mapping_modes); a1++)
2603 HANDLE m;
2605 create_fake_dll( filename );
2606 SetLastError(0xdeadbeef);
2607 h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2608 if (h == INVALID_HANDLE_VALUE)
2610 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError());
2611 return;
2613 m = CreateFileMappingA( h, NULL, mapping_modes[a1].dw, 0, 0, NULL );
2614 ok( m != 0, "failed to create mapping %s err %lu\n", mapping_modes[a1].str, GetLastError() );
2615 CloseHandle( h );
2616 if (!m) continue;
2618 for (a2 = 0; a2 < ARRAY_SIZE(access_modes); a2++)
2620 for (s2 = 0; s2 < ARRAY_SIZE(sharing_modes); s2++)
2622 SetLastError(0xdeadbeef);
2623 h2 = CreateFileA( filename, access_modes[a2].dw, sharing_modes[s2].dw,
2624 NULL, OPEN_EXISTING, 0, 0 );
2626 ret = GetLastError();
2627 if (h2 == INVALID_HANDLE_VALUE)
2629 ok( !is_sharing_map_compatible(mapping_modes[a1].dw, access_modes[a2].dw, sharing_modes[s2].dw),
2630 "open failed for modes map %s / %s / %s\n",
2631 mapping_modes[a1].str, access_modes[a2].str, sharing_modes[s2].str );
2632 ok( ret == ERROR_SHARING_VIOLATION,
2633 "wrong error code %d\n", ret );
2635 else
2637 if (!is_sharing_map_compatible(mapping_modes[a1].dw, access_modes[a2].dw, sharing_modes[s2].dw))
2638 ok( broken(1), /* no checking on nt4 */
2639 "open succeeded for modes map %s / %s / %s\n",
2640 mapping_modes[a1].str, access_modes[a2].str, sharing_modes[s2].str );
2641 ok( ret == 0xdeadbeef /* Win9x */ ||
2642 ret == 0, /* XP */
2643 "wrong error code %d\n", ret );
2644 CloseHandle( h2 );
2649 /* try CREATE_ALWAYS over an existing mapping */
2650 SetLastError(0xdeadbeef);
2651 h2 = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
2652 NULL, CREATE_ALWAYS, 0, 0 );
2653 ret = GetLastError();
2654 if (mapping_modes[a1].dw & SEC_IMAGE)
2656 ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %s\n", mapping_modes[a1].str );
2657 ok( ret == ERROR_SHARING_VIOLATION, "wrong error code %d for %s\n", ret, mapping_modes[a1].str );
2659 else
2661 ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %s\n", mapping_modes[a1].str );
2662 ok( ret == ERROR_USER_MAPPED_FILE, "wrong error code %d for %s\n", ret, mapping_modes[a1].str );
2664 if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 );
2666 /* try DELETE_ON_CLOSE over an existing mapping */
2667 SetLastError(0xdeadbeef);
2668 h2 = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
2669 NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0 );
2670 ret = GetLastError();
2671 if (mapping_modes[a1].dw & SEC_IMAGE)
2673 ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %s\n", mapping_modes[a1].str );
2674 ok( ret == ERROR_ACCESS_DENIED, "wrong error code %d for %s\n", ret, mapping_modes[a1].str );
2676 else
2678 ok( h2 != INVALID_HANDLE_VALUE, "open failed for map %s err %u\n", mapping_modes[a1].str, ret );
2680 if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 );
2682 CloseHandle( m );
2685 SetLastError(0xdeadbeef);
2686 h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, 0 );
2687 ok( h != INVALID_HANDLE_VALUE, "CreateFileA error %ld\n", GetLastError() );
2689 SetLastError(0xdeadbeef);
2690 h2 = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
2691 ok( h2 == INVALID_HANDLE_VALUE, "CreateFileA should fail\n");
2692 ok( GetLastError() == ERROR_SHARING_VIOLATION, "wrong error code %ld\n", GetLastError() );
2694 h2 = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
2695 ok( h2 != INVALID_HANDLE_VALUE, "CreateFileA error %ld\n", GetLastError() );
2697 CloseHandle(h);
2698 CloseHandle(h2);
2700 DeleteFileA( filename );
2703 static char get_windows_drive(void)
2705 char windowsdir[MAX_PATH];
2706 GetWindowsDirectoryA(windowsdir, sizeof(windowsdir));
2707 return windowsdir[0];
2710 static void test_FindFirstFileA(void)
2712 HANDLE handle;
2713 WIN32_FIND_DATAA data;
2714 int err;
2715 char buffer[5] = "C:\\";
2716 char buffer2[100];
2717 char nonexistent[MAX_PATH];
2718 BOOL found = FALSE;
2720 /* try FindFirstFileA on "C:\" */
2721 buffer[0] = get_windows_drive();
2723 SetLastError( 0xdeadbeaf );
2724 handle = FindFirstFileA(buffer, &data);
2725 err = GetLastError();
2726 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on root directory should fail\n" );
2727 ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err );
2729 /* try FindFirstFileA on "C:\*" */
2730 strcpy(buffer2, buffer);
2731 strcat(buffer2, "*");
2732 handle = FindFirstFileA(buffer2, &data);
2733 ok ( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s should succeed\n", buffer2 );
2734 ok ( strcmp( data.cFileName, "." ) && strcmp( data.cFileName, ".." ),
2735 "FindFirstFile shouldn't return '%s' in drive root\n", data.cFileName );
2736 if (FindNextFileA( handle, &data ))
2737 ok ( strcmp( data.cFileName, "." ) && strcmp( data.cFileName, ".." ),
2738 "FindNextFile shouldn't return '%s' in drive root\n", data.cFileName );
2739 ok ( FindClose(handle) == TRUE, "Failed to close handle %s\n", buffer2 );
2741 /* try FindFirstFileA on windows dir */
2742 GetWindowsDirectoryA( buffer2, sizeof(buffer2) );
2743 strcat(buffer2, "\\*");
2744 handle = FindFirstFileA(buffer2, &data);
2745 ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s should succeed\n", buffer2 );
2746 ok( !strcmp( data.cFileName, "." ), "FindFirstFile should return '.' first\n" );
2747 ok( FindNextFileA( handle, &data ), "FindNextFile failed\n" );
2748 ok( !strcmp( data.cFileName, ".." ), "FindNextFile should return '..' as second entry\n" );
2749 while (FindNextFileA( handle, &data ))
2751 ok ( strcmp( data.cFileName, "." ) && strcmp( data.cFileName, ".." ),
2752 "FindNextFile shouldn't return '%s'\n", data.cFileName );
2753 if (!found && (data.dwFileAttributes == FILE_ATTRIBUTE_NORMAL ||
2754 data.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE))
2756 GetWindowsDirectoryA( buffer2, sizeof(buffer2) );
2757 strcat(buffer2, "\\");
2758 strcat(buffer2, data.cFileName);
2759 strcat(buffer2, "\\*");
2760 found = TRUE;
2763 ok ( FindClose(handle) == TRUE, "Failed to close handle %s\n", buffer2 );
2765 ok ( found, "Windows dir should not be empty\n" );
2766 if (found)
2768 SetLastError( 0xdeadbeef );
2769 handle = FindFirstFileA(buffer2, &data);
2770 err = GetLastError();
2771 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 );
2772 ok ( err == ERROR_DIRECTORY, "Bad Error number %x\n", err );
2775 /* try FindFirstFileA on "C:\foo\" */
2776 SetLastError( 0xdeadbeaf );
2777 if (!GetTempFileNameA( buffer, "foo", 0, nonexistent ))
2779 char tmp[MAX_PATH];
2780 GetTempPathA( sizeof(tmp), tmp );
2781 GetTempFileNameA( tmp, "foo", 0, nonexistent );
2783 DeleteFileA( nonexistent );
2784 strcpy(buffer2, nonexistent);
2785 strcat(buffer2, "\\");
2786 handle = FindFirstFileA(buffer2, &data);
2787 err = GetLastError();
2788 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 );
2789 todo_wine {
2790 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2793 /* try FindFirstFileA without trailing backslash */
2794 SetLastError( 0xdeadbeaf );
2795 strcpy(buffer2, nonexistent);
2796 handle = FindFirstFileA(buffer2, &data);
2797 err = GetLastError();
2798 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 );
2799 ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err );
2801 /* try FindFirstFileA on "C:\foo\bar.txt" */
2802 SetLastError( 0xdeadbeaf );
2803 strcpy(buffer2, nonexistent);
2804 strcat(buffer2, "\\bar.txt");
2805 handle = FindFirstFileA(buffer2, &data);
2806 err = GetLastError();
2807 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 );
2808 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2810 /* try FindFirstFileA on "C:\foo\*.*" */
2811 SetLastError( 0xdeadbeaf );
2812 strcpy(buffer2, nonexistent);
2813 strcat(buffer2, "\\*.*");
2814 handle = FindFirstFileA(buffer2, &data);
2815 err = GetLastError();
2816 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 );
2817 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2819 /* try FindFirstFileA on "foo\bar.txt" */
2820 SetLastError( 0xdeadbeaf );
2821 strcpy(buffer2, nonexistent + 3);
2822 strcat(buffer2, "\\bar.txt");
2823 handle = FindFirstFileA(buffer2, &data);
2824 err = GetLastError();
2825 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 );
2826 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2828 /* try FindFirstFileA on "c:\nul" */
2829 SetLastError( 0xdeadbeaf );
2830 strcpy(buffer2, buffer);
2831 strcat(buffer2, "nul");
2832 handle = FindFirstFileA(buffer2, &data);
2833 err = GetLastError();
2834 ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s failed: %d\n", buffer2, err );
2835 ok( 0 == lstrcmpiA(data.cFileName, "nul"), "wrong name %s\n", data.cFileName );
2836 ok( FILE_ATTRIBUTE_ARCHIVE == data.dwFileAttributes ||
2837 FILE_ATTRIBUTE_DEVICE == data.dwFileAttributes /* Win9x */,
2838 "wrong attributes %lx\n", data.dwFileAttributes );
2839 if (data.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE)
2841 ok( 0 == data.nFileSizeHigh, "wrong size %ld\n", data.nFileSizeHigh );
2842 ok( 0 == data.nFileSizeLow, "wrong size %ld\n", data.nFileSizeLow );
2844 SetLastError( 0xdeadbeaf );
2845 ok( !FindNextFileA( handle, &data ), "FindNextFileA succeeded\n" );
2846 ok( GetLastError() == ERROR_NO_MORE_FILES, "bad error %ld\n", GetLastError() );
2847 ok( FindClose( handle ), "failed to close handle\n" );
2849 /* try FindFirstFileA on "lpt1" */
2850 SetLastError( 0xdeadbeaf );
2851 strcpy(buffer2, "lpt1");
2852 handle = FindFirstFileA(buffer2, &data);
2853 err = GetLastError();
2854 ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s failed: %d\n", buffer2, err );
2855 ok( 0 == lstrcmpiA(data.cFileName, "lpt1"), "wrong name %s\n", data.cFileName );
2856 ok( FILE_ATTRIBUTE_ARCHIVE == data.dwFileAttributes ||
2857 FILE_ATTRIBUTE_DEVICE == data.dwFileAttributes /* Win9x */,
2858 "wrong attributes %lx\n", data.dwFileAttributes );
2859 if (data.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE)
2861 ok( 0 == data.nFileSizeHigh, "wrong size %ld\n", data.nFileSizeHigh );
2862 ok( 0 == data.nFileSizeLow, "wrong size %ld\n", data.nFileSizeLow );
2864 SetLastError( 0xdeadbeaf );
2865 ok( !FindNextFileA( handle, &data ), "FindNextFileA succeeded\n" );
2866 ok( GetLastError() == ERROR_NO_MORE_FILES, "bad error %ld\n", GetLastError() );
2867 ok( FindClose( handle ), "failed to close handle\n" );
2869 /* try FindFirstFileA on "c:\nul\*" */
2870 SetLastError( 0xdeadbeaf );
2871 strcpy(buffer2, buffer);
2872 strcat(buffer2, "nul\\*");
2873 handle = FindFirstFileA(buffer2, &data);
2874 err = GetLastError();
2875 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 );
2876 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2878 /* try FindFirstFileA on "c:\nul*" */
2879 SetLastError( 0xdeadbeaf );
2880 strcpy(buffer2, buffer);
2881 strcat(buffer2, "nul*");
2882 handle = FindFirstFileA(buffer2, &data);
2883 err = GetLastError();
2884 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 );
2885 ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err );
2887 /* try FindFirstFileA on "c:\foo\bar\nul" */
2888 SetLastError( 0xdeadbeaf );
2889 strcpy(buffer2, buffer);
2890 strcat(buffer2, "foo\\bar\\nul");
2891 handle = FindFirstFileA(buffer2, &data);
2892 err = GetLastError();
2893 ok( handle == INVALID_HANDLE_VALUE || broken(1), /* win8 */
2894 "FindFirstFile on %s should fail\n", buffer2 );
2895 if (handle == INVALID_HANDLE_VALUE)
2896 ok( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2897 else
2898 CloseHandle( handle );
2900 /* try FindFirstFileA on "c:\foo\nul\bar" */
2901 SetLastError( 0xdeadbeaf );
2902 strcpy(buffer2, buffer);
2903 strcat(buffer2, "foo\\nul\\bar");
2904 handle = FindFirstFileA(buffer2, &data);
2905 err = GetLastError();
2906 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should fail\n", buffer2 );
2907 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2910 static void test_FindNextFileA(void)
2912 HANDLE handle;
2913 WIN32_FIND_DATAA search_results;
2914 int err;
2915 char buffer[5] = "C:\\*";
2917 buffer[0] = get_windows_drive();
2918 handle = FindFirstFileA(buffer,&search_results);
2919 ok ( handle != INVALID_HANDLE_VALUE, "FindFirstFile on C:\\* should succeed\n" );
2920 while (FindNextFileA(handle, &search_results))
2922 /* get to the end of the files */
2924 ok ( FindClose(handle) == TRUE, "Failed to close handle\n");
2925 err = GetLastError();
2926 ok ( err == ERROR_NO_MORE_FILES, "GetLastError should return ERROR_NO_MORE_FILES\n");
2929 static void test_FindFirstFileExA(FINDEX_INFO_LEVELS level, FINDEX_SEARCH_OPS search_ops, DWORD flags)
2931 WIN32_FIND_DATAA search_results;
2932 HANDLE handle;
2933 BOOL ret;
2935 if (!pFindFirstFileExA)
2937 win_skip("FindFirstFileExA() is missing\n");
2938 return;
2941 trace("Running FindFirstFileExA tests with level=%d, search_ops=%d, flags=%lu\n",
2942 level, search_ops, flags);
2944 CreateDirectoryA("test-dir", NULL);
2945 _lclose(_lcreat("test-dir\\file1", 0));
2946 _lclose(_lcreat("test-dir\\file2", 0));
2947 CreateDirectoryA("test-dir\\dir1", NULL);
2948 SetLastError(0xdeadbeef);
2949 handle = pFindFirstFileExA("test-dir\\*", level, &search_results, search_ops, NULL, flags);
2950 if (handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
2952 win_skip("FindFirstFileExA is not implemented\n");
2953 goto cleanup;
2955 if ((flags & FIND_FIRST_EX_LARGE_FETCH) && handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER)
2957 win_skip("FindFirstFileExA flag FIND_FIRST_EX_LARGE_FETCH not supported, skipping test\n");
2958 goto cleanup;
2960 if ((level == FindExInfoBasic) && handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER)
2962 win_skip("FindFirstFileExA level FindExInfoBasic not supported, skipping test\n");
2963 goto cleanup;
2966 #define CHECK_NAME(fn) (strcmp((fn), "file1") == 0 || strcmp((fn), "file2") == 0 || strcmp((fn), "dir1") == 0)
2967 #define CHECK_LEVEL(fn) (level != FindExInfoBasic || !(fn)[0])
2969 ok(handle != INVALID_HANDLE_VALUE, "FindFirstFile failed (err=%lu)\n", GetLastError());
2970 ok(strcmp(search_results.cFileName, ".") == 0, "First entry should be '.', is %s\n", search_results.cFileName);
2971 ok(CHECK_LEVEL(search_results.cAlternateFileName), "FindFirstFile unexpectedly returned an alternate filename\n");
2973 ok(FindNextFileA(handle, &search_results), "Fetching second file failed\n");
2974 ok(strcmp(search_results.cFileName, "..") == 0, "Second entry should be '..' is %s\n", search_results.cFileName);
2975 ok(CHECK_LEVEL(search_results.cAlternateFileName), "FindFirstFile unexpectedly returned an alternate filename\n");
2977 ok(FindNextFileA(handle, &search_results), "Fetching third file failed\n");
2978 ok(CHECK_NAME(search_results.cFileName), "Invalid third entry - %s\n", search_results.cFileName);
2979 ok(CHECK_LEVEL(search_results.cAlternateFileName), "FindFirstFile unexpectedly returned an alternate filename\n");
2981 SetLastError(0xdeadbeef);
2982 ret = FindNextFileA(handle, &search_results);
2983 if (!ret && (GetLastError() == ERROR_NO_MORE_FILES) && (search_ops == FindExSearchLimitToDirectories))
2985 skip("File system supports directory filtering\n");
2986 /* Results from the previous call are not cleared */
2987 ok(strcmp(search_results.cFileName, "dir1") == 0, "Third entry should be 'dir1' is %s\n", search_results.cFileName);
2988 ok(CHECK_LEVEL(search_results.cAlternateFileName), "FindFirstFile unexpectedly returned an alternate filename\n");
2991 else
2993 ok(ret, "Fetching fourth file failed\n");
2994 ok(CHECK_NAME(search_results.cFileName), "Invalid fourth entry - %s\n", search_results.cFileName);
2995 ok(CHECK_LEVEL(search_results.cAlternateFileName), "FindFirstFile unexpectedly returned an alternate filename\n");
2997 ok(FindNextFileA(handle, &search_results), "Fetching fifth file failed\n");
2998 ok(CHECK_NAME(search_results.cFileName), "Invalid fifth entry - %s\n", search_results.cFileName);
2999 ok(CHECK_LEVEL(search_results.cAlternateFileName), "FindFirstFile unexpectedly returned an alternate filename\n");
3001 ok(FindNextFileA(handle, &search_results) == FALSE, "Fetching sixth file should fail\n");
3004 #undef CHECK_NAME
3005 #undef CHECK_LEVEL
3007 FindClose( handle );
3009 /* Most Windows systems seem to ignore the FIND_FIRST_EX_CASE_SENSITIVE flag. Unofficial documentation
3010 * suggests that there are registry keys and that it might depend on the used filesystem. */
3011 SetLastError(0xdeadbeef);
3012 handle = pFindFirstFileExA("TEST-DIR\\*", level, &search_results, search_ops, NULL, flags);
3013 if (flags & FIND_FIRST_EX_CASE_SENSITIVE)
3015 ok(handle != INVALID_HANDLE_VALUE || GetLastError() == ERROR_PATH_NOT_FOUND,
3016 "Unexpected error %lx, expected valid handle or ERROR_PATH_NOT_FOUND\n", GetLastError());
3017 trace("FindFirstFileExA flag FIND_FIRST_EX_CASE_SENSITIVE is %signored\n",
3018 (handle == INVALID_HANDLE_VALUE) ? "not " : "");
3020 else
3021 ok(handle != INVALID_HANDLE_VALUE, "Unexpected error %lx, expected valid handle\n", GetLastError());
3022 if (handle != INVALID_HANDLE_VALUE)
3023 FindClose( handle );
3025 cleanup:
3026 DeleteFileA("test-dir\\file1");
3027 DeleteFileA("test-dir\\file2");
3028 RemoveDirectoryA("test-dir\\dir1");
3029 RemoveDirectoryA("test-dir");
3032 static void test_FindFirstFile_wildcards(void)
3034 WIN32_FIND_DATAA find_data;
3035 HANDLE handle;
3036 int i;
3037 static const char* files[] = {
3038 "..a", "..a.a", ".a", ".a..a", ".a.a", ".aaa",
3039 "a", "a..a", "a.a", "a.a.a", "aa", "aaa", "aaaa", " .a"
3041 static const struct {
3042 const char *pattern, *result;
3043 } tests[] = {
3044 {"*.*.*", ", '.', '..', '..a', '..a.a', '.a', '.a..a', '.a.a', '.aaa', 'a', 'a..a', 'a.a', 'a.a.a', 'aa', 'aaa', 'aaaa', ' .a'"},
3045 {"*.*.", ", '.', '..', '..a', '..a.a', '.a', '.a..a', '.a.a', '.aaa', 'a', 'a..a', 'a.a', 'a.a.a', 'aa', 'aaa', 'aaaa', ' .a'"},
3046 {".*.*", ", '.', '..', '..a', '..a.a', '.a', '.a..a', '.a.a', '.aaa'"},
3047 {"*.*", ", '.', '..', '..a', '..a.a', '.a', '.a..a', '.a.a', '.aaa', 'a', 'a..a', 'a.a', 'a.a.a', 'aa', 'aaa', 'aaaa', ' .a'"},
3048 {".*", ", '.', '..', '..a', '..a.a', '.a', '.a..a', '.a.a', '.aaa'"},
3049 {". *", ""},
3050 {"*.", ", '.', '..', 'a', '.a', '..a', 'aa', 'aaa', 'aaaa', '.aaa'"},
3051 {"*", ", '.', '..', '..a', '..a.a', '.a', '.a..a', '.a.a', '.aaa', 'a', 'a..a', 'a.a', 'a.a.a', 'aa', 'aaa', 'aaaa', ' .a'"},
3052 {"*..*", ", '.', '..', '..a', '..a.a', '.a..a', 'a..a'"},
3053 {"*..", ", '.', '..', 'a', '.a', '..a', 'aa', 'aaa', 'aaaa', '.aaa'"},
3054 {".*.", ", '.', '..', '.a', '.aaa'"},
3055 {"..*", ", '.', '..', '..a', '..a.a'"},
3056 {"**", ", '.', '..', '..a', '..a.a', '.a', '.a..a', '.a.a', '.aaa', 'a', 'a..a', 'a.a', 'a.a.a', 'aa', 'aaa', 'aaaa', ' .a'"},
3057 {"**.", ", '.', '..', '..a', '..a.a', '.a', '.a..a', '.a.a', '.aaa', 'a', 'a..a', 'a.a', 'a.a.a', 'aa', 'aaa', 'aaaa', ' .a'"},
3058 {"*. ", ", '.', '..', '..a', '..a.a', '.a', '.a..a', '.a.a', '.aaa', 'a', 'a..a', 'a.a', 'a.a.a', 'aa', 'aaa', 'aaaa', ' .a'"},
3059 {"* .", ", '.', '..', 'a', '.a', '..a', 'aa', 'aaa', 'aaaa', '.aaa'"},
3060 {"* . ", ", '.', '..', '..a', '..a.a', '.a', '.a..a', '.a.a', '.aaa', 'a', 'a..a', 'a.a', 'a.a.a', 'aa', 'aaa', 'aaaa', ' .a'"},
3061 {"* . *", ""},
3062 {"*.. ", ", '.', '..', '..a', '..a.a', '.a', '.a..a', '.a.a', '.aaa', 'a', 'a..a', 'a.a', 'a.a.a', 'aa', 'aaa', 'aaaa', ' .a'"},
3063 {"*. .", ", '.', '..', 'a', '.a', '..a', 'aa', 'aaa', 'aaaa', '.aaa'"},
3064 {"* ..", ", '.', '..', 'a', '.a', '..a', 'aa', 'aaa', 'aaaa', '.aaa'"},
3065 {" *..", ""},
3066 {"..* ", ", '.', '..', '..a', '..a.a'"},
3067 {"* .*.", ", ' .a'"},
3069 {"a*.", ", '..a', '.a', '.aaa', 'a', 'aa', 'aaa', 'aaaa'"},
3070 {"*a ", ", '..a', '..a.a', '.a', '.a..a', '.a.a', '.aaa', 'a', 'a..a', 'a.a', 'a.a.a', 'aa', 'aaa', 'aaaa', ' .a'"},
3071 {"*aa*", ", '.aaa', 'a.a.a', 'aa', 'aaa', 'aaaa'"},
3072 {"aa*.", ", '.aaa', 'aa', 'aaa', 'aaaa'"},
3073 {"aa.*", ", 'aa'"},
3074 {"a a*.*", ""},
3075 {"a\"*\"a", ", 'a..a', 'a.a.a'"},
3076 {"aa*.*", ", '.aaa', 'a.a.a', 'aa', 'aaa', 'aaaa'"},
3077 {"a ?.*", ""},
3078 {"? a.*", ""},
3079 {"a* a", ""},
3080 {" *a", ", ' .a'"},
3081 {"* *", ", ' .a'"},
3082 {"a* .", ", 'a', '.a', '..a', 'aa', 'aaa', 'aaaa', '.aaa'"},
3083 {" ?a", ""},
3084 {"* .a", ", ' .a'"},
3085 {"< .a", ", ' .a'"},
3086 {"** .a", ", ' .a'"},
3087 {"<< .a", ", ' .a'"},
3088 {"aa? ", ", 'aa', 'aaa'"},
3089 {"aa\"*", ", 'aa'"},
3090 {"*.a", ", '..a', '..a.a', '.a', '.a..a', '.a.a', 'a..a', 'a.a', 'a.a.a', ' .a'"},
3091 {"<.a", ", '..a', '..a.a', '.a', '.a..a', '.a.a', 'a..a', 'a.a', 'a.a.a', ' .a'"},
3093 {"<.<.<", ", '..a', '..a.a', '.a..a', '.a.a', 'a..a', 'a.a.a'"},
3094 {"<.<.< ", ", '..a', '..a.a', '.a..a', '.a.a', 'a..a', 'a.a.a'"},
3095 {"<.<.", ", '.', '..', '..a', '..a.a', '.a', '.a..a', '.a.a', '.aaa', 'a..a', 'a.a', 'a.a.a', ' .a'"},
3096 {"< .<.", ", ' .a'"},
3097 {"< .<. ", ", ' .a'"},
3098 {"<.<. ", ", '.', '..', '..a', '..a.a', '.a', '.a..a', '.a.a', '.aaa', 'a..a', 'a.a', 'a.a.a', ' .a'"},
3099 {".<.<", ", '..a', '..a.a', '.a..a', '.a.a'"},
3100 {"<.<", ", '.', '..', '..a', '..a.a', '.a', '.a..a', '.a.a', '.aaa', 'a..a', 'a.a', 'a.a.a', ' .a'"},
3101 {".<", ", '.', '..', '.a', '.aaa'"},
3102 {"<.", ", '.', '..', 'a', '.a', '..a', 'aa', 'aaa', 'aaaa', '.aaa'"},
3103 {"<", ", '.', '..', '..a', '.a', '.aaa', 'a', 'aa', 'aaa', 'aaaa'"},
3104 {"<..<", ", '..a', '.a..a', 'a..a'"},
3105 {"<..", ", '.', '..', 'a', '.a', '..a', 'aa', 'aaa', 'aaaa', '.aaa'"},
3106 {".<.", ", '.', '..', '.a', '.aaa'"},
3107 {"..<", ", '..a'"},
3108 {"<<", ", '.', '..', '..a', '..a.a', '.a', '.a..a', '.a.a', '.aaa', 'a', 'a..a', 'a.a', 'a.a.a', 'aa', 'aaa', 'aaaa', ' .a'"},
3109 {"<<.", ", '.', '..', '..a', '..a.a', '.a', '.a..a', '.a.a', '.aaa', 'a', 'a..a', 'a.a', 'a.a.a', 'aa', 'aaa', 'aaaa', ' .a'"},
3110 {"<. ", ", '.', '..', '..a', '.a', '.aaa', 'a', 'aa', 'aaa', 'aaaa'"},
3111 {"< .", ", '.', '..', 'a', '.a', '..a', 'aa', 'aaa', 'aaaa', '.aaa'"},
3112 {"< . ", ", '.', '..', '..a', '.a', '.aaa', 'a', 'aa', 'aaa', 'aaaa'"},
3113 {"<.. ", ", '.', '..', '..a', '.a', '.aaa', 'a', 'aa', 'aaa', 'aaaa'"},
3114 {"<. .", ", '.', '..', 'a', '.a', '..a', 'aa', 'aaa', 'aaaa', '.aaa'"},
3115 {"< ..", ", '.', '..', 'a', '.a', '..a', 'aa', 'aaa', 'aaaa', '.aaa'"},
3116 {" <..", ""},
3117 {"..< ", ", '..a'"},
3119 {"?", ", '.', '..', 'a'"},
3120 {"?.", ", '.', '..', 'a'"},
3121 {"?. ", ", '.', '..', 'a'"},
3122 {"? .*", ""},
3123 {"??.", ", '.', '..', 'a', 'aa'"},
3124 {"??. ", ", '.', '..', 'a', 'aa'"},
3125 {"???.", ", '.', '..', 'a', 'aa', 'aaa'"},
3126 {"?.??.", ", '.', '..', '.a', 'a', 'a.a', ' .a'"},
3127 {". ?", ""},
3129 {">", ", '.', '..', 'a'"},
3130 {">.", ", '.', '..', 'a'"},
3131 {">. ", ", '.', '..', 'a'"},
3132 {">>.", ", '.', '..', 'a', 'aa'"},
3133 {">>. ", ", '.', '..', 'a', 'aa'"},
3134 {">>>.", ", '.', '..', 'a', 'aa', 'aaa'"},
3135 {">.>>.", ", '.', '..', '.a', 'a.a', ' .a'"},
3138 CreateDirectoryA("test-dir", NULL);
3139 SetCurrentDirectoryA("test-dir");
3140 for (i = 0; i < ARRAY_SIZE(files); ++i)
3141 _lclose(_lcreat(files[i], 0));
3143 for (i = 0; i < ARRAY_SIZE(tests); ++i)
3145 char correct[512];
3146 char incorrect[512];
3147 char missing[512];
3149 strcpy(missing, tests[i].result);
3150 correct[0] = incorrect[0] = 0;
3152 handle = FindFirstFileA(tests[i].pattern, &find_data);
3153 if (handle != INVALID_HANDLE_VALUE)
3155 do {
3156 char *ptr;
3157 char quoted[16];
3159 sprintf(quoted, ", '%.10s'", find_data.cFileName);
3161 if ((ptr = strstr(missing, quoted)))
3163 int len = strlen(quoted);
3164 while ((ptr[0] = ptr[len]) != 0)
3165 ++ptr;
3166 strcat(correct, quoted);
3168 else
3169 strcat(incorrect, quoted);
3170 } while (FindNextFileA(handle, &find_data));
3171 FindClose(handle);
3174 ok(missing[0] == 0 && incorrect[0] == 0,
3175 "FindFirstFile with '%s' found correctly %s, found incorrectly %s, and missed %s\n",
3176 tests[i].pattern,
3177 correct[0] ? correct+2 : "none",
3178 incorrect[0] ? incorrect+2 : "none",
3179 missing[0] ? missing+2 : "none");
3182 for (i = 0; i < ARRAY_SIZE(files); ++i)
3183 DeleteFileA(files[i]);
3184 SetCurrentDirectoryA("..");
3185 RemoveDirectoryA("test-dir");
3188 static int test_Mapfile_createtemp(HANDLE *handle)
3190 SetFileAttributesA(filename,FILE_ATTRIBUTE_NORMAL);
3191 DeleteFileA(filename);
3192 *handle = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, 0, 0,
3193 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
3194 if (*handle != INVALID_HANDLE_VALUE) {
3196 return 1;
3199 return 0;
3202 static void test_MapFile(void)
3204 HANDLE handle;
3205 HANDLE hmap;
3206 UINT err;
3208 ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
3210 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 0x1000, "named_file_map" );
3211 ok( hmap != NULL, "mapping should work, I named it!\n" );
3213 ok( CloseHandle( hmap ), "can't close mapping handle\n");
3215 /* We have to close file before we try new stuff with mapping again.
3216 Else we would always succeed on XP or block descriptors on 95. */
3217 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
3218 ok( hmap != NULL, "We should still be able to map!\n" );
3219 ok( CloseHandle( hmap ), "can't close mapping handle\n");
3220 ok( CloseHandle( handle ), "can't close file handle\n");
3221 handle = NULL;
3223 ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
3225 SetLastError( 0xdeadbeef );
3226 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
3227 err = GetLastError();
3228 ok( hmap == NULL, "mapped zero size file\n");
3229 ok( err == ERROR_FILE_INVALID, "got %u\n", err );
3231 SetLastError( 0xdeadbeef );
3232 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0x8000000, 0x10000, NULL );
3233 err = GetLastError();
3234 ok( hmap == NULL, "mapping should fail\n");
3235 ok( err == ERROR_NOT_ENOUGH_MEMORY || err == ERROR_INVALID_PARAMETER, "got %u\n", err );
3237 /* On XP you can now map again, on Win 95 you cannot. */
3239 ok( CloseHandle( handle ), "can't close file handle\n");
3240 ok( DeleteFileA( filename ), "DeleteFile failed after map\n" );
3243 static void test_GetFileType(void)
3245 DWORD type, type2;
3246 HANDLE h, h2;
3247 BOOL ret;
3248 h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
3249 ok( h != INVALID_HANDLE_VALUE, "open %s failed\n", filename );
3250 type = GetFileType(h);
3251 ok( type == FILE_TYPE_DISK, "expected type disk got %ld\n", type );
3252 CloseHandle( h );
3253 h = CreateFileA( "nul", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
3254 ok( h != INVALID_HANDLE_VALUE, "open nul failed\n" );
3255 type = GetFileType(h);
3256 ok( type == FILE_TYPE_CHAR, "expected type char for nul got %ld\n", type );
3257 CloseHandle( h );
3258 DeleteFileA( filename );
3259 h = GetStdHandle( STD_OUTPUT_HANDLE );
3260 ok( h != INVALID_HANDLE_VALUE, "GetStdHandle failed\n" );
3261 type = GetFileType( (HANDLE)STD_OUTPUT_HANDLE );
3262 type2 = GetFileType( h );
3263 ok(type == type2, "expected type %ld for STD_OUTPUT_HANDLE got %ld\n", type2, type);
3265 ret = CreatePipe( &h, &h2, NULL, 0 );
3266 ok( ret, "CreatePipe failed\n" );
3267 type = GetFileType( h );
3268 ok( type == FILE_TYPE_PIPE, "expected type pipe got %ld\n", type );
3269 type = GetFileType( h2 );
3270 ok( type == FILE_TYPE_PIPE, "expected type pipe got %ld\n", type );
3271 CloseHandle( h2 );
3272 CloseHandle( h );
3274 h = CreateNamedPipeW( L"\\\\.\\pipe\\wine_test", PIPE_ACCESS_DUPLEX, 0, 2, 32, 32, 0, NULL );
3275 ok( h != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n" );
3276 type = GetFileType( h );
3277 ok( type == FILE_TYPE_PIPE, "expected type pipe got %ld\n", type );
3278 CloseHandle( h );
3280 h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
3281 ok( h != INVALID_HANDLE_VALUE, "open %s failed\n", filename );
3282 h2 = CreateFileMappingW( h, NULL, PAGE_READWRITE, 0, 0x1000, NULL );
3283 ok( h2 != NULL, "CreateFileMapping failed\n" );
3284 SetLastError( 12345678 );
3285 type = GetFileType( h2 );
3286 todo_wine
3287 ok( type == FILE_TYPE_UNKNOWN, "expected type unknown got %ld\n", type );
3288 todo_wine
3289 ok( GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE got %lx\n", GetLastError() );
3290 CloseHandle( h2 );
3291 CloseHandle( h );
3292 DeleteFileA( filename );
3294 h = CreateFileMappingW( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 0x1000, NULL );
3295 ok( h != NULL, "CreateFileMapping failed\n" );
3296 SetLastError( 12345678 );
3297 type = GetFileType( h );
3298 todo_wine
3299 ok( type == FILE_TYPE_UNKNOWN, "expected type unknown got %ld\n", type );
3300 todo_wine
3301 ok( GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE got %lx\n", GetLastError() );
3302 CloseHandle( h );
3304 h = CreateMailslotW( L"\\\\.\\mailslot\\wine_test", 0, 0, NULL );
3305 ok( h != INVALID_HANDLE_VALUE, "CreateMailslot failed\n" );
3306 SetLastError( 12345678 );
3307 type = GetFileType( h );
3308 todo_wine
3309 ok( type == FILE_TYPE_UNKNOWN, "expected type unknown got %ld\n", type );
3310 todo_wine
3311 ok( GetLastError() == NO_ERROR, "expected ERROR_NO_ERROR got %lx\n", GetLastError() );
3312 CloseHandle( h );
3314 SetLastError( 12345678 );
3315 type = GetFileType( GetCurrentProcess() );
3316 ok( type == FILE_TYPE_UNKNOWN, "expected type unknown got %ld\n", type );
3317 ok( GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE got %lx\n", GetLastError() );
3319 SetLastError( 12345678 );
3320 type = GetFileType( GetCurrentThread() );
3321 ok( type == FILE_TYPE_UNKNOWN, "expected type unknown got %ld\n", type );
3322 ok( GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE got %lx\n", GetLastError() );
3324 h = CreateMutexW( NULL, TRUE, NULL );
3325 ok( h != NULL, "CreateMutex failed\n" );
3326 SetLastError( 12345678 );
3327 type = GetFileType( h );
3328 ok( type == FILE_TYPE_UNKNOWN, "expected type unknown got %ld\n", type );
3329 ok( GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE got %lx\n", GetLastError() );
3330 CloseHandle( h );
3333 static int completion_count;
3335 static void CALLBACK FileIOComplete(DWORD dwError, DWORD dwBytes, LPOVERLAPPED ovl)
3337 /* printf("(%ld, %ld, %p { %ld, %ld, %ld, %ld, %p })\n", dwError, dwBytes, ovl, ovl->Internal, ovl->InternalHigh, ovl->Offset, ovl->OffsetHigh, ovl->hEvent);*/
3338 ReleaseSemaphore(ovl->hEvent, 1, NULL);
3339 completion_count++;
3342 static void test_async_file_errors(void)
3344 char szFile[MAX_PATH];
3345 HANDLE hSem = CreateSemaphoreW(NULL, 1, 1, NULL);
3346 HANDLE hFile;
3347 LPVOID lpBuffer = HeapAlloc(GetProcessHeap(), 0, 4096);
3348 OVERLAPPED ovl;
3349 ovl.Offset = 0;
3350 ovl.OffsetHigh = 0;
3351 ovl.hEvent = hSem;
3352 completion_count = 0;
3353 szFile[0] = '\0';
3354 GetWindowsDirectoryA(szFile, ARRAY_SIZE(szFile)-1-strlen("\\win.ini"));
3355 strcat(szFile, "\\win.ini");
3356 hFile = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
3357 NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
3358 if (hFile == INVALID_HANDLE_VALUE) /* win9x doesn't like FILE_SHARE_DELETE */
3359 hFile = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
3360 NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
3361 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA(%s ...) failed\n", szFile);
3362 while (TRUE)
3364 BOOL res;
3365 DWORD count;
3366 while (WaitForSingleObjectEx(hSem, INFINITE, TRUE) == WAIT_IO_COMPLETION)
3368 res = ReadFileEx(hFile, lpBuffer, 4096, &ovl, FileIOComplete);
3369 /*printf("Offset = %ld, result = %s\n", ovl.Offset, res ? "TRUE" : "FALSE");*/
3370 if (!res)
3371 break;
3372 if (!GetOverlappedResult(hFile, &ovl, &count, FALSE))
3373 break;
3374 ovl.Offset += count;
3375 /* i/o completion routine only called if ReadFileEx returned success.
3376 * we only care about violations of this rule so undo what should have
3377 * been done */
3378 completion_count--;
3380 ok(completion_count == 0, "completion routine should only be called when ReadFileEx succeeds (this rule was violated %d times)\n", completion_count);
3381 /*printf("Error = %ld\n", GetLastError());*/
3382 HeapFree(GetProcessHeap(), 0, lpBuffer);
3385 static BOOL user_apc_ran;
3386 static void CALLBACK user_apc(ULONG_PTR param)
3388 user_apc_ran = TRUE;
3391 static void test_read_write(void)
3393 DWORD bytes, ret, old_prot;
3394 HANDLE hFile;
3395 char temp_path[MAX_PATH];
3396 char filename[MAX_PATH];
3397 char *mem;
3398 static const char prefix[] = "pfx";
3400 ret = GetTempPathA(MAX_PATH, temp_path);
3401 ok(ret != 0, "GetTempPathA error %ld\n", GetLastError());
3402 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
3404 ret = GetTempFileNameA(temp_path, prefix, 0, filename);
3405 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
3407 hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
3408 CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
3409 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %ld\n", GetLastError());
3411 user_apc_ran = FALSE;
3412 ret = QueueUserAPC(&user_apc, GetCurrentThread(), 0);
3413 ok(ret, "QueueUserAPC failed: %ld\n", GetLastError());
3415 SetLastError(12345678);
3416 bytes = 12345678;
3417 ret = WriteFile(hFile, NULL, 0, &bytes, NULL);
3418 ok(ret && GetLastError() == 12345678,
3419 "ret = %ld, error %ld\n", ret, GetLastError());
3420 ok(!bytes, "bytes = %ld\n", bytes);
3422 SetLastError(12345678);
3423 bytes = 12345678;
3424 ret = WriteFile(hFile, NULL, 10, &bytes, NULL);
3425 ok((!ret && GetLastError() == ERROR_INVALID_USER_BUFFER) || /* Win2k */
3426 (ret && GetLastError() == 12345678), /* Win9x */
3427 "ret = %ld, error %ld\n", ret, GetLastError());
3428 ok(!bytes || /* Win2k */
3429 bytes == 10, /* Win9x */
3430 "bytes = %ld\n", bytes);
3432 /* make sure the file contains data */
3433 WriteFile(hFile, "this is the test data", 21, &bytes, NULL);
3434 SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
3436 SetLastError(12345678);
3437 bytes = 12345678;
3438 ret = ReadFile(hFile, NULL, 0, &bytes, NULL);
3439 ok(ret && GetLastError() == 12345678,
3440 "ret = %ld, error %ld\n", ret, GetLastError());
3441 ok(!bytes, "bytes = %ld\n", bytes);
3443 SetLastError(12345678);
3444 bytes = 12345678;
3445 ret = ReadFile(hFile, NULL, 10, &bytes, NULL);
3446 ok(!ret && (GetLastError() == ERROR_NOACCESS || /* Win2k */
3447 GetLastError() == ERROR_INVALID_PARAMETER), /* Win9x */
3448 "ret = %ld, error %ld\n", ret, GetLastError());
3449 ok(!bytes, "bytes = %ld\n", bytes);
3451 ok(user_apc_ran == FALSE, "UserAPC ran, file using alertable io mode\n");
3452 SleepEx(0, TRUE); /* get rid of apc */
3454 /* test passing protected memory as buffer */
3456 mem = VirtualAlloc( NULL, 0x4000, MEM_COMMIT, PAGE_READWRITE );
3457 ok( mem != NULL, "failed to allocate virtual mem error %lu\n", GetLastError() );
3459 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
3460 ok( ret, "WriteFile failed error %lu\n", GetLastError() );
3461 ok( bytes == 0x4000, "only wrote %lx bytes\n", bytes );
3463 ret = VirtualProtect( mem + 0x2000, 0x2000, PAGE_NOACCESS, &old_prot );
3464 ok( ret, "VirtualProtect failed error %lu\n", GetLastError() );
3466 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
3467 ok( !ret, "WriteFile succeeded\n" );
3468 ok( GetLastError() == ERROR_INVALID_USER_BUFFER ||
3469 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
3470 "wrong error %lu\n", GetLastError() );
3471 ok( bytes == 0, "wrote %lx bytes\n", bytes );
3473 ret = WriteFile( (HANDLE)0xdead, mem, 0x4000, &bytes, NULL );
3474 ok( !ret, "WriteFile succeeded\n" );
3475 ok( GetLastError() == ERROR_INVALID_HANDLE || /* handle is checked before buffer on NT */
3476 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
3477 "wrong error %lu\n", GetLastError() );
3478 ok( bytes == 0, "wrote %lx bytes\n", bytes );
3480 ret = VirtualProtect( mem, 0x2000, PAGE_NOACCESS, &old_prot );
3481 ok( ret, "VirtualProtect failed error %lu\n", GetLastError() );
3483 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
3484 ok( !ret, "WriteFile succeeded\n" );
3485 ok( GetLastError() == ERROR_INVALID_USER_BUFFER ||
3486 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
3487 "wrong error %lu\n", GetLastError() );
3488 ok( bytes == 0, "wrote %lx bytes\n", bytes );
3490 SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
3492 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
3493 ok( !ret, "ReadFile succeeded\n" );
3494 ok( GetLastError() == ERROR_NOACCESS ||
3495 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
3496 "wrong error %lu\n", GetLastError() );
3497 ok( bytes == 0, "read %lx bytes\n", bytes );
3499 ret = VirtualProtect( mem, 0x2000, PAGE_READONLY, &old_prot );
3500 ok( ret, "VirtualProtect failed error %lu\n", GetLastError() );
3502 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
3503 ok( !ret, "ReadFile succeeded\n" );
3504 ok( GetLastError() == ERROR_NOACCESS ||
3505 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
3506 "wrong error %lu\n", GetLastError() );
3507 ok( bytes == 0, "read %lx bytes\n", bytes );
3509 ret = VirtualProtect( mem, 0x2000, PAGE_READWRITE, &old_prot );
3510 ok( ret, "VirtualProtect failed error %lu\n", GetLastError() );
3512 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
3513 ok( !ret, "ReadFile succeeded\n" );
3514 ok( GetLastError() == ERROR_NOACCESS ||
3515 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
3516 "wrong error %lu\n", GetLastError() );
3517 ok( bytes == 0, "read %lx bytes\n", bytes );
3519 SetFilePointer( hFile, 0x1234, NULL, FILE_BEGIN );
3520 SetEndOfFile( hFile );
3521 SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
3523 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
3524 ok( !ret, "ReadFile succeeded\n" );
3525 ok( GetLastError() == ERROR_NOACCESS ||
3526 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
3527 "wrong error %lu\n", GetLastError() );
3528 ok( bytes == 0, "read %lx bytes\n", bytes );
3530 ret = ReadFile( hFile, mem, 0x2000, &bytes, NULL );
3531 ok( ret, "ReadFile failed error %lu\n", GetLastError() );
3532 ok( bytes == 0x1234, "read %lx bytes\n", bytes );
3534 ret = ReadFile( hFile, NULL, 1, &bytes, NULL );
3535 ok( !ret, "ReadFile succeeded\n" );
3536 ok( GetLastError() == ERROR_NOACCESS ||
3537 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
3538 "wrong error %lu\n", GetLastError() );
3539 ok( bytes == 0, "read %lx bytes\n", bytes );
3541 VirtualFree( mem, 0, MEM_RELEASE );
3543 ret = CloseHandle(hFile);
3544 ok( ret, "CloseHandle: error %ld\n", GetLastError());
3545 ret = DeleteFileA(filename);
3546 ok( ret, "DeleteFileA: error %ld\n", GetLastError());
3549 static void test_OpenFile(void)
3551 HFILE hFile;
3552 OFSTRUCT ofs;
3553 BOOL ret;
3554 DWORD retval;
3556 static const char file[] = "regedit.exe";
3557 static const char foo[] = ".\\foo-bar-foo.baz";
3558 static const char *foo_too_long = ".\\foo-bar-foo.baz+++++++++++++++"
3559 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
3560 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
3561 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
3562 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
3563 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
3564 char buff[MAX_PATH];
3565 char buff_long[4*MAX_PATH];
3566 char filled_0xA5[OFS_MAXPATHNAME];
3567 char *p;
3568 UINT length;
3570 /* Check for existing file */
3571 if (!pGetSystemWindowsDirectoryA)
3572 length = GetWindowsDirectoryA(buff, MAX_PATH);
3573 else
3574 length = pGetSystemWindowsDirectoryA(buff, MAX_PATH);
3576 if (length + sizeof(file) < MAX_PATH)
3578 p = buff + strlen(buff);
3579 if (p > buff && p[-1] != '\\') *p++ = '\\';
3580 strcpy( p, file );
3581 memset(&ofs, 0xA5, sizeof(ofs));
3582 SetLastError(0xfaceabee);
3584 hFile = OpenFile(buff, &ofs, OF_EXIST);
3585 ok( hFile == TRUE, "%s not found : %ld\n", buff, GetLastError() );
3586 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3587 "GetLastError() returns %ld\n", GetLastError() );
3588 ok( ofs.cBytes == sizeof(ofs), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3589 ok( ofs.nErrCode == ERROR_SUCCESS, "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3590 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
3591 "OpenFile returned '%s', but was expected to return '%s' or string filled with 0xA5\n",
3592 ofs.szPathName, buff );
3595 memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
3596 length = GetCurrentDirectoryA(MAX_PATH, buff);
3598 /* Check for nonexistent file */
3599 if (length + sizeof(foo) < MAX_PATH)
3601 p = buff + strlen(buff);
3602 if (p > buff && p[-1] != '\\') *p++ = '\\';
3603 strcpy( p, foo + 2 );
3604 memset(&ofs, 0xA5, sizeof(ofs));
3605 SetLastError(0xfaceabee);
3607 hFile = OpenFile(foo, &ofs, OF_EXIST);
3608 ok( hFile == HFILE_ERROR, "hFile != HFILE_ERROR : %ld\n", GetLastError());
3609 ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError() returns %ld\n", GetLastError() );
3610 todo_wine
3611 ok( ofs.cBytes == 0xA5, "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3612 ok( ofs.nErrCode == ERROR_FILE_NOT_FOUND, "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3613 ok( lstrcmpiA(ofs.szPathName, buff) == 0 || strncmp(ofs.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0,
3614 "OpenFile returned '%s', but was expected to return '%s' or string filled with 0xA5\n",
3615 ofs.szPathName, buff );
3618 length = GetCurrentDirectoryA(MAX_PATH, buff_long);
3619 length += lstrlenA(foo_too_long + 1);
3621 /* Check for nonexistent file with too long filename */
3622 if (length >= OFS_MAXPATHNAME && length < sizeof(buff_long))
3624 lstrcatA(buff_long, foo_too_long + 1); /* Avoid '.' during concatenation */
3625 memset(&ofs, 0xA5, sizeof(ofs));
3626 SetLastError(0xfaceabee);
3628 hFile = OpenFile(foo_too_long, &ofs, OF_EXIST);
3629 ok( hFile == HFILE_ERROR, "hFile != HFILE_ERROR : %ld\n", GetLastError());
3630 ok( GetLastError() == ERROR_INVALID_DATA || GetLastError() == ERROR_FILENAME_EXCED_RANGE,
3631 "GetLastError() returns %ld\n", GetLastError() );
3632 todo_wine
3633 ok( ofs.cBytes == 0xA5, "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3634 ok( ofs.nErrCode == ERROR_INVALID_DATA || ofs.nErrCode == ERROR_FILENAME_EXCED_RANGE,
3635 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3636 ok( strncmp(ofs.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0,
3637 "OpenFile returned '%s', but was expected to return string filled with 0xA5\n",
3638 ofs.szPathName );
3641 memset(&ofs, 0xA5, sizeof(ofs));
3642 SetLastError(0xfaceabee);
3643 /* Create an empty file */
3644 hFile = OpenFile(filename, &ofs, OF_CREATE);
3645 ok( hFile != HFILE_ERROR, "OpenFile failed to create nonexistent file\n" );
3646 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3647 "GetLastError() returns %ld\n", GetLastError() );
3648 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3649 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3650 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3651 ret = _lclose(hFile);
3652 ok( !ret, "_lclose() returns %d\n", ret );
3653 retval = GetFileAttributesA(filename);
3654 ok( retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %ld\n", GetLastError() );
3656 memset(&ofs, 0xA5, sizeof(ofs));
3657 SetLastError(0xfaceabee);
3658 /* Check various opening options: */
3659 /* for reading only, */
3660 hFile = OpenFile(filename, &ofs, OF_READ);
3661 ok( hFile != HFILE_ERROR, "OpenFile failed on read\n" );
3662 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3663 "GetLastError() returns %ld\n", GetLastError() );
3664 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3665 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3666 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3667 ok( lstrcmpiA(ofs.szPathName, filename) == 0,
3668 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, filename );
3669 ret = _lclose(hFile);
3670 ok( !ret, "_lclose() returns %d\n", ret );
3672 memset(&ofs, 0xA5, sizeof(ofs));
3673 SetLastError(0xfaceabee);
3674 /* for writing only, */
3675 hFile = OpenFile(filename, &ofs, OF_WRITE);
3676 ok( hFile != HFILE_ERROR, "OpenFile failed on write\n" );
3677 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3678 "GetLastError() returns %ld\n", GetLastError() );
3679 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3680 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3681 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3682 ok( lstrcmpiA(ofs.szPathName, filename) == 0,
3683 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, filename );
3684 ret = _lclose(hFile);
3685 ok( !ret, "_lclose() returns %d\n", ret );
3687 memset(&ofs, 0xA5, sizeof(ofs));
3688 SetLastError(0xfaceabee);
3689 /* for reading and writing, */
3690 hFile = OpenFile(filename, &ofs, OF_READWRITE);
3691 ok( hFile != HFILE_ERROR, "OpenFile failed on read/write\n" );
3692 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3693 "GetLastError() returns %ld\n", GetLastError() );
3694 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3695 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3696 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3697 ok( lstrcmpiA(ofs.szPathName, filename) == 0,
3698 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, filename );
3699 ret = _lclose(hFile);
3700 ok( !ret, "_lclose() returns %d\n", ret );
3702 memset(&ofs, 0xA5, sizeof(ofs));
3703 SetLastError(0xfaceabee);
3704 /* for checking file presence. */
3705 hFile = OpenFile(filename, &ofs, OF_EXIST);
3706 ok( hFile == 1, "OpenFile failed on finding our created file\n" );
3707 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3708 "GetLastError() returns %ld\n", GetLastError() );
3709 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3710 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3711 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3712 ok( lstrcmpiA(ofs.szPathName, filename) == 0,
3713 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, filename );
3715 memset(&ofs, 0xA5, sizeof(ofs));
3716 SetLastError(0xfaceabee);
3717 /* Delete the file and make sure it doesn't exist anymore */
3718 hFile = OpenFile(filename, &ofs, OF_DELETE);
3719 ok( hFile == 1, "OpenFile failed on delete (%d)\n", hFile );
3720 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
3721 "GetLastError() returns %ld\n", GetLastError() );
3722 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
3723 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
3724 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
3725 ok( lstrcmpiA(ofs.szPathName, filename) == 0,
3726 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, filename );
3728 retval = GetFileAttributesA(filename);
3729 ok( retval == INVALID_FILE_ATTRIBUTES, "GetFileAttributesA succeeded on deleted file\n" );
3732 static void test_overlapped(void)
3734 OVERLAPPED ov;
3735 DWORD r, result;
3737 /* GetOverlappedResult crashes if the 2nd or 3rd param are NULL */
3738 if (0) /* tested: WinXP */
3740 GetOverlappedResult(0, NULL, &result, FALSE);
3741 GetOverlappedResult(0, &ov, NULL, FALSE);
3742 GetOverlappedResult(0, NULL, NULL, FALSE);
3745 memset( &ov, 0, sizeof ov );
3746 result = 1;
3747 r = GetOverlappedResult(0, &ov, &result, 0);
3748 if (r)
3749 ok( result == 0, "wrong result %lu\n", result );
3750 else /* win9x */
3751 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %lu\n", GetLastError() );
3753 result = 0;
3754 ov.Internal = 0;
3755 ov.InternalHigh = 0xabcd;
3756 r = GetOverlappedResult(0, &ov, &result, 0);
3757 if (r)
3758 ok( result == 0xabcd, "wrong result %lu\n", result );
3759 else /* win9x */
3760 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %lu\n", GetLastError() );
3762 SetLastError( 0xb00 );
3763 result = 0;
3764 ov.Internal = STATUS_INVALID_HANDLE;
3765 ov.InternalHigh = 0xabcd;
3766 r = GetOverlappedResult(0, &ov, &result, 0);
3767 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %lu\n", GetLastError() );
3768 ok( r == FALSE, "should return false\n");
3769 ok( result == 0xabcd || result == 0 /* win9x */, "wrong result %lu\n", result );
3771 SetLastError( 0xb00 );
3772 result = 0;
3773 ov.Internal = STATUS_PENDING;
3774 ov.InternalHigh = 0xabcd;
3775 r = GetOverlappedResult(0, &ov, &result, 0);
3776 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
3777 "wrong error %lu\n", GetLastError() );
3778 ok( r == FALSE, "should return false\n");
3779 ok( result == 0, "wrong result %lu\n", result );
3781 SetLastError( 0xb00 );
3782 ov.hEvent = CreateEventW( NULL, 1, 1, NULL );
3783 ov.Internal = STATUS_PENDING;
3784 ov.InternalHigh = 0xabcd;
3785 r = GetOverlappedResult(0, &ov, &result, 0);
3786 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
3787 "wrong error %lu\n", GetLastError() );
3788 ok( r == FALSE, "should return false\n");
3790 r = GetOverlappedResult( 0, &ov, &result, TRUE );
3791 ok( r == TRUE, "should return TRUE\n" );
3792 ok( result == 0xabcd, "wrong result %lu\n", result );
3793 ok( ov.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %08Ix\n", ov.Internal );
3795 ResetEvent( ov.hEvent );
3797 SetLastError( 0xb00 );
3798 ov.Internal = STATUS_PENDING;
3799 ov.InternalHigh = 0;
3800 r = GetOverlappedResult(0, &ov, &result, 0);
3801 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
3802 "wrong error %lu\n", GetLastError() );
3803 ok( r == FALSE, "should return false\n");
3805 r = CloseHandle( ov.hEvent );
3806 ok( r == TRUE, "close handle failed\n");
3809 static void test_RemoveDirectory(void)
3811 int rc;
3812 char directory[] = "removeme";
3814 rc = CreateDirectoryA(directory, NULL);
3815 ok( rc, "Createdirectory failed, gle=%ld\n", GetLastError() );
3817 rc = SetCurrentDirectoryA(directory);
3818 ok( rc, "SetCurrentDirectory failed, gle=%ld\n", GetLastError() );
3820 rc = RemoveDirectoryA(".");
3821 if (!rc)
3823 rc = SetCurrentDirectoryA("..");
3824 ok( rc, "SetCurrentDirectory failed, gle=%ld\n", GetLastError() );
3826 rc = RemoveDirectoryA(directory);
3827 ok( rc, "RemoveDirectory failed, gle=%ld\n", GetLastError() );
3831 static BOOL check_file_time( const FILETIME *ft1, const FILETIME *ft2, UINT tolerance )
3833 ULONGLONG t1 = ((ULONGLONG)ft1->dwHighDateTime << 32) | ft1->dwLowDateTime;
3834 ULONGLONG t2 = ((ULONGLONG)ft2->dwHighDateTime << 32) | ft2->dwLowDateTime;
3835 return (t1 > t2 ? t1 - t2 : t2 - t1) <= tolerance;
3838 static void test_ReplaceFileA(void)
3840 char replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH];
3841 HANDLE hReplacedFile, hReplacementFile, hBackupFile, mapping;
3842 static const char replacedData[] = "file-to-replace";
3843 static const char replacementData[] = "new-file";
3844 static const char backupData[] = "backup-file";
3845 FILETIME ftReplaced, ftReplacement, ftBackup;
3846 static const char prefix[] = "pfx";
3847 char temp_path[MAX_PATH];
3848 DWORD ret;
3849 BOOL retok, removeBackup = FALSE;
3850 char **argv;
3852 ret = GetTempPathA(MAX_PATH, temp_path);
3853 ok(ret != 0, "GetTempPathA error %ld\n", GetLastError());
3854 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
3856 ret = GetTempFileNameA(temp_path, prefix, 0, replaced);
3857 ok(ret != 0, "GetTempFileNameA error (replaced) %ld\n", GetLastError());
3859 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3860 ok(ret != 0, "GetTempFileNameA error (replacement) %ld\n", GetLastError());
3862 ret = GetTempFileNameA(temp_path, prefix, 0, backup);
3863 ok(ret != 0, "GetTempFileNameA error (backup) %ld\n", GetLastError());
3865 /* place predictable data in the file to be replaced */
3866 hReplacedFile = CreateFileA(replaced, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
3867 ok(hReplacedFile != INVALID_HANDLE_VALUE,
3868 "failed to open replaced file\n");
3869 retok = WriteFile(hReplacedFile, replacedData, sizeof(replacedData), &ret, NULL );
3870 ok( retok && ret == sizeof(replacedData),
3871 "WriteFile error (replaced) %ld\n", GetLastError());
3872 ok(GetFileSize(hReplacedFile, NULL) == sizeof(replacedData),
3873 "replaced file has wrong size\n");
3874 /* place predictable data in the file to be the replacement */
3875 hReplacementFile = CreateFileA(replacement, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
3876 ok(hReplacementFile != INVALID_HANDLE_VALUE,
3877 "failed to open replacement file\n");
3878 retok = WriteFile(hReplacementFile, replacementData, sizeof(replacementData), &ret, NULL );
3879 ok( retok && ret == sizeof(replacementData),
3880 "WriteFile error (replacement) %ld\n", GetLastError());
3881 ok(GetFileSize(hReplacementFile, NULL) == sizeof(replacementData),
3882 "replacement file has wrong size\n");
3883 /* place predictable data in the backup file (to be over-written) */
3884 hBackupFile = CreateFileA(backup, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
3885 ok(hBackupFile != INVALID_HANDLE_VALUE,
3886 "failed to open backup file\n");
3887 retok = WriteFile(hBackupFile, backupData, sizeof(backupData), &ret, NULL );
3888 ok( retok && ret == sizeof(backupData),
3889 "WriteFile error (replacement) %ld\n", GetLastError());
3890 ok(GetFileSize(hBackupFile, NULL) == sizeof(backupData),
3891 "backup file has wrong size\n");
3892 /* change the filetime on the "replaced" file to ensure that it changes */
3893 ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
3894 ok( ret, "GetFileTime error (replaced) %ld\n", GetLastError());
3895 ftReplaced.dwLowDateTime -= 600000000; /* 60 second */
3896 ret = SetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
3897 ok( ret, "SetFileTime error (replaced) %ld\n", GetLastError());
3898 GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced); /* get the actual time back */
3899 CloseHandle(hReplacedFile);
3900 /* change the filetime on the backup to ensure that it changes */
3901 ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
3902 ok( ret, "GetFileTime error (backup) %ld\n", GetLastError());
3903 ftBackup.dwLowDateTime -= 1200000000; /* 120 second */
3904 ret = SetFileTime(hBackupFile, NULL, NULL, &ftBackup);
3905 ok( ret, "SetFileTime error (backup) %ld\n", GetLastError());
3906 GetFileTime(hBackupFile, NULL, NULL, &ftBackup); /* get the actual time back */
3907 CloseHandle(hBackupFile);
3908 /* get the filetime on the replacement file to perform checks */
3909 ret = GetFileTime(hReplacementFile, NULL, NULL, &ftReplacement);
3910 ok( ret, "GetFileTime error (replacement) %ld\n", GetLastError());
3911 CloseHandle(hReplacementFile);
3913 /* perform replacement w/ backup
3914 * TODO: flags are not implemented
3916 SetLastError(0xdeadbeef);
3917 ret = ReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3918 ok(ret, "ReplaceFileA: unexpected error %ld\n", GetLastError());
3919 /* make sure that the backup has the size of the old "replaced" file */
3920 hBackupFile = CreateFileA(backup, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
3921 ok(hBackupFile != INVALID_HANDLE_VALUE,
3922 "failed to open backup file\n");
3923 ret = GetFileSize(hBackupFile, NULL);
3924 ok(ret == sizeof(replacedData),
3925 "backup file has wrong size %ld\n", ret);
3926 /* make sure that the "replaced" file has the size of the replacement file */
3927 hReplacedFile = CreateFileA(replaced, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
3928 ok(hReplacedFile != INVALID_HANDLE_VALUE,
3929 "failed to open replaced file: %ld\n", GetLastError());
3930 if (hReplacedFile != INVALID_HANDLE_VALUE)
3932 ret = GetFileSize(hReplacedFile, NULL);
3933 ok(ret == sizeof(replacementData),
3934 "replaced file has wrong size %ld\n", ret);
3935 /* make sure that the replacement file no-longer exists */
3936 hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
3937 ok(hReplacementFile == INVALID_HANDLE_VALUE,
3938 "unexpected error, replacement file should not exist %ld\n", GetLastError());
3939 /* make sure that the backup has the old "replaced" filetime */
3940 ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
3941 ok( ret, "GetFileTime error (backup %ld\n", GetLastError());
3942 ok(check_file_time(&ftBackup, &ftReplaced, 20000000), "backup file has wrong filetime\n");
3943 CloseHandle(hBackupFile);
3944 /* make sure that the "replaced" has the old replacement filetime */
3945 ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
3946 ok( ret, "GetFileTime error (backup %ld\n", GetLastError());
3947 ok(check_file_time(&ftReplaced, &ftReplacement, 20000000),
3948 "replaced file has wrong filetime %lx%08lx / %lx%08lx\n",
3949 ftReplaced.dwHighDateTime, ftReplaced.dwLowDateTime,
3950 ftReplacement.dwHighDateTime, ftReplacement.dwLowDateTime );
3951 CloseHandle(hReplacedFile);
3953 else
3954 skip("couldn't open replacement file, skipping tests\n");
3956 /* re-create replacement file for pass w/o backup (blank) */
3957 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3958 ok(ret != 0, "GetTempFileNameA error (replacement) %ld\n", GetLastError());
3959 /* perform replacement w/o backup
3960 * TODO: flags are not implemented
3962 SetLastError(0xdeadbeef);
3963 ret = ReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
3964 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3965 "ReplaceFileA: unexpected error %ld\n", GetLastError());
3967 /* re-create replacement file for pass w/ backup (backup-file not existing) */
3968 DeleteFileA(replacement);
3969 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3970 ok(ret != 0, "GetTempFileNameA error (replacement) %ld\n", GetLastError());
3971 ret = DeleteFileA(backup);
3972 ok(ret, "DeleteFileA: error (backup) %ld\n", GetLastError());
3973 /* perform replacement w/ backup (no pre-existing backup)
3974 * TODO: flags are not implemented
3976 SetLastError(0xdeadbeef);
3977 ret = ReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3978 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3979 "ReplaceFileA: unexpected error %ld\n", GetLastError());
3980 if (ret)
3981 removeBackup = TRUE;
3983 /* re-create replacement file for pass w/ no permissions to "replaced" */
3984 DeleteFileA(replacement);
3985 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3986 ok(ret != 0, "GetTempFileNameA error (replacement) %ld\n", GetLastError());
3987 ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_READONLY);
3988 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3989 "SetFileAttributesA: error setting to read only %ld\n", GetLastError());
3990 /* perform replacement w/ backup (no permission to "replaced")
3991 * TODO: flags are not implemented
3993 SetLastError(0xdeadbeef);
3994 ret = ReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3995 ok(ret == 0 && GetLastError() == ERROR_ACCESS_DENIED, "ReplaceFileA: unexpected error %ld\n", GetLastError());
3996 /* make sure that the replacement file still exists */
3997 hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
3998 ok(hReplacementFile != INVALID_HANDLE_VALUE ||
3999 broken(GetLastError() == ERROR_FILE_NOT_FOUND), /* win2k */
4000 "unexpected error, replacement file should still exist %ld\n", GetLastError());
4001 CloseHandle(hReplacementFile);
4002 ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_NORMAL);
4003 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
4004 "SetFileAttributesA: error setting to normal %ld\n", GetLastError());
4006 /* replacement readonly */
4007 DeleteFileA(replacement);
4008 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
4009 ok(ret != 0, "GetTempFileNameA error (replacement) %#lx\n", GetLastError());
4010 ret = SetFileAttributesA(replacement, FILE_ATTRIBUTE_READONLY);
4011 ok(ret, "SetFileAttributesA: error setting to readonly %#lx\n", GetLastError());
4012 ret = ReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
4013 ok(GetLastError() == ERROR_ACCESS_DENIED, "ReplaceFileA: unexpected error %#lx\n", GetLastError());
4014 ret = SetFileAttributesA(replacement, FILE_ATTRIBUTE_NORMAL);
4015 ok(ret, "SetFileAttributesA: error setting to normal %#lx\n", GetLastError());
4017 /* re-create replacement file for pass w/ replaced opened with
4018 * the same permissions as an exe (Replicating an exe trying to
4019 * replace itself)
4021 DeleteFileA(replacement);
4022 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
4023 ok(ret != 0, "GetTempFileNameA error (replacement) %ld\n", GetLastError());
4025 /* make sure that the replaced file is opened like an exe*/
4026 hReplacedFile = CreateFileA(replaced, GENERIC_READ | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0);
4027 ok(hReplacedFile != INVALID_HANDLE_VALUE,
4028 "unexpected error, replaced file should be able to be opened %ld\n", GetLastError());
4029 /*Calling ReplaceFileA on an exe should succeed*/
4030 ret = ReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
4031 ok(ret, "ReplaceFileA: unexpected error %ld\n", GetLastError());
4032 CloseHandle(hReplacedFile);
4034 /* replace file while replacement is opened */
4035 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
4036 ok(ret != 0, "GetTempFileNameA error (replacement) %ld\n", GetLastError());
4037 hReplacementFile = CreateFileA(replacement, GENERIC_READ | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0);
4038 ok(hReplacementFile != INVALID_HANDLE_VALUE, "unexpected error, replacement file should be able to be opened %ld\n",
4039 GetLastError());
4040 ret = ReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
4041 ok(!ret, "expect failure\n");
4042 ok(GetLastError() == ERROR_SHARING_VIOLATION, "expect ERROR_SHARING_VIOLATION, got %#lx.\n", GetLastError());
4043 CloseHandle(hReplacementFile);
4045 /* replacement file still exists, make pass w/o "replaced" */
4046 ret = DeleteFileA(replaced);
4047 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
4048 "DeleteFileA: error (replaced) %ld\n", GetLastError());
4049 /* perform replacement w/ backup (no pre-existing backup or "replaced")
4050 * TODO: flags are not implemented
4052 SetLastError(0xdeadbeef);
4053 ret = ReplaceFileA(replaced, replacement, backup, 0, 0, 0);
4054 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
4055 GetLastError() == ERROR_ACCESS_DENIED),
4056 "ReplaceFileA: unexpected error %ld\n", GetLastError());
4058 /* perform replacement w/o existing "replacement" file
4059 * TODO: flags are not implemented
4061 SetLastError(0xdeadbeef);
4062 ret = ReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
4063 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
4064 GetLastError() == ERROR_ACCESS_DENIED),
4065 "ReplaceFileA: unexpected error %ld\n", GetLastError());
4066 DeleteFileA( replacement );
4069 * if the first round (w/ backup) worked then as long as there is no
4070 * failure then there is no need to check this round (w/ backup is the
4071 * more complete case)
4074 /* delete temporary files, replacement and replaced are already deleted */
4075 if (removeBackup)
4077 ret = DeleteFileA(backup);
4078 ok(ret ||
4079 broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */
4080 "DeleteFileA: error (backup) %ld\n", GetLastError());
4083 ret = GetTempFileNameA(temp_path, prefix, 0, replaced);
4084 ok(ret, "got error %lu\n", GetLastError());
4085 hReplacedFile = CreateFileA(replaced, 0, 0, NULL, OPEN_EXISTING, 0, 0);
4086 ok(hReplacedFile != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError());
4088 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
4089 ok(ret, "got error %lu\n", GetLastError());
4091 ret = ReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
4092 ok(ret, "got error %lu\n", GetLastError());
4094 CloseHandle(hReplacedFile);
4095 ret = DeleteFileA(replaced);
4096 ok(ret, "got error %lu\n", GetLastError());
4098 winetest_get_mainargs(&argv);
4100 ret = CopyFileA(argv[0], replaced, FALSE);
4101 ok(ret, "got error %lu\n", GetLastError());
4102 hReplacedFile = CreateFileA(replaced, GENERIC_READ,
4103 FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0);
4104 ok(hReplacedFile != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError());
4106 mapping = CreateFileMappingA(hReplacedFile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL);
4107 ok(!!mapping, "got error %lu\n", GetLastError());
4109 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
4110 ok(ret, "got error %lu\n", GetLastError());
4112 ret = ReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
4113 ok(ret, "got error %lu\n", GetLastError());
4115 CloseHandle(mapping);
4116 CloseHandle(hReplacedFile);
4117 ret = DeleteFileA(replaced);
4118 ok(ret, "got error %lu\n", GetLastError());
4122 * ReplaceFileW is a simpler case of ReplaceFileA, there is no
4123 * need to be as thorough.
4125 static void test_ReplaceFileW(void)
4127 WCHAR replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH];
4128 static const WCHAR prefix[] = {'p','f','x',0};
4129 WCHAR temp_path[MAX_PATH];
4130 DWORD ret;
4131 BOOL removeBackup = FALSE;
4133 if (!pReplaceFileW)
4135 win_skip("ReplaceFileW() is missing\n");
4136 return;
4139 ret = GetTempPathW(MAX_PATH, temp_path);
4140 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
4142 win_skip("GetTempPathW is not available\n");
4143 return;
4145 ok(ret != 0, "GetTempPathW error %ld\n", GetLastError());
4146 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
4148 ret = GetTempFileNameW(temp_path, prefix, 0, replaced);
4149 ok(ret != 0, "GetTempFileNameW error (replaced) %ld\n", GetLastError());
4151 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
4152 ok(ret != 0, "GetTempFileNameW error (replacement) %ld\n", GetLastError());
4154 ret = GetTempFileNameW(temp_path, prefix, 0, backup);
4155 ok(ret != 0, "GetTempFileNameW error (backup) %ld\n", GetLastError());
4157 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
4158 ok(ret, "ReplaceFileW: error %ld\n", GetLastError());
4160 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
4161 ok(ret != 0, "GetTempFileNameW error (replacement) %ld\n", GetLastError());
4162 ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0);
4163 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
4164 "ReplaceFileW: error %ld\n", GetLastError());
4166 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
4167 ok(ret != 0, "GetTempFileNameW error (replacement) %ld\n", GetLastError());
4168 ret = DeleteFileW(backup);
4169 ok(ret, "DeleteFileW: error (backup) %ld\n", GetLastError());
4170 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
4171 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
4172 "ReplaceFileW: error %ld\n", GetLastError());
4174 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
4175 ok(ret != 0, "GetTempFileNameW error (replacement) %ld\n", GetLastError());
4176 ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_READONLY);
4177 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
4178 "SetFileAttributesW: error setting to read only %ld\n", GetLastError());
4180 SetLastError(0xdeadbeef);
4181 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
4182 ok(!ret, "expected failure\n");
4183 ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
4184 ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_NORMAL);
4185 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
4186 "SetFileAttributesW: error setting to normal %ld\n", GetLastError());
4187 if (ret)
4188 removeBackup = TRUE;
4190 ret = DeleteFileW(replaced);
4191 ok(ret, "DeleteFileW: error (replaced) %ld\n", GetLastError());
4192 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
4193 ok(!ret, "ReplaceFileW: error %ld\n", GetLastError());
4195 ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0);
4196 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
4197 GetLastError() == ERROR_ACCESS_DENIED),
4198 "ReplaceFileW: unexpected error %ld\n", GetLastError());
4199 DeleteFileW( replacement );
4201 if (removeBackup)
4203 ret = DeleteFileW(backup);
4204 ok(ret ||
4205 broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */
4206 "DeleteFileW: error (backup) %ld\n", GetLastError());
4210 static void test_CreateFile(void)
4212 static const struct test_data
4214 DWORD disposition, access, error, clean_up;
4215 } td[] =
4217 /* 0 */ { 0, 0, ERROR_INVALID_PARAMETER, 0 },
4218 /* 1 */ { 0, GENERIC_READ, ERROR_INVALID_PARAMETER, 0 },
4219 /* 2 */ { 0, GENERIC_READ|GENERIC_WRITE, ERROR_INVALID_PARAMETER, 0 },
4220 /* 3 */ { CREATE_NEW, 0, ERROR_FILE_EXISTS, 1 },
4221 /* 4 */ { CREATE_NEW, 0, 0, 1 },
4222 /* 5 */ { CREATE_NEW, GENERIC_READ, 0, 1 },
4223 /* 6 */ { CREATE_NEW, GENERIC_WRITE, 0, 1 },
4224 /* 7 */ { CREATE_NEW, GENERIC_READ|GENERIC_WRITE, 0, 0 },
4225 /* 8 */ { CREATE_ALWAYS, 0, 0, 0 },
4226 /* 9 */ { CREATE_ALWAYS, GENERIC_READ, 0, 0 },
4227 /* 10*/ { CREATE_ALWAYS, GENERIC_WRITE, 0, 0 },
4228 /* 11*/ { CREATE_ALWAYS, GENERIC_READ|GENERIC_WRITE, 0, 1 },
4229 /* 12*/ { OPEN_EXISTING, 0, ERROR_FILE_NOT_FOUND, 0 },
4230 /* 13*/ { CREATE_ALWAYS, 0, 0, 0 },
4231 /* 14*/ { OPEN_EXISTING, 0, 0, 0 },
4232 /* 15*/ { OPEN_EXISTING, GENERIC_READ, 0, 0 },
4233 /* 16*/ { OPEN_EXISTING, GENERIC_WRITE, 0, 0 },
4234 /* 17*/ { OPEN_EXISTING, GENERIC_READ|GENERIC_WRITE, 0, 1 },
4235 /* 18*/ { OPEN_ALWAYS, 0, 0, 0 },
4236 /* 19*/ { OPEN_ALWAYS, GENERIC_READ, 0, 0 },
4237 /* 20*/ { OPEN_ALWAYS, GENERIC_WRITE, 0, 0 },
4238 /* 21*/ { OPEN_ALWAYS, GENERIC_READ|GENERIC_WRITE, 0, 0 },
4239 /* 22*/ { TRUNCATE_EXISTING, 0, ERROR_INVALID_PARAMETER, 0 },
4240 /* 23*/ { TRUNCATE_EXISTING, GENERIC_READ, ERROR_INVALID_PARAMETER, 0 },
4241 /* 24*/ { TRUNCATE_EXISTING, GENERIC_WRITE, 0, 0 },
4242 /* 25*/ { TRUNCATE_EXISTING, GENERIC_READ|GENERIC_WRITE, 0, 0 },
4243 /* 26*/ { TRUNCATE_EXISTING, FILE_WRITE_DATA, ERROR_INVALID_PARAMETER, 0 }
4245 char temp_path[MAX_PATH];
4246 char file_name[MAX_PATH];
4247 DWORD i, ret, written;
4248 HANDLE hfile;
4250 GetTempPathA(MAX_PATH, temp_path);
4251 GetTempFileNameA(temp_path, "tmp", 0, file_name);
4253 i = strlen(temp_path);
4254 if (i && temp_path[i - 1] == '\\') temp_path[i - 1] = 0;
4256 for (i = 0; i <= 5; i++)
4258 SetLastError(0xdeadbeef);
4259 hfile = CreateFileA(temp_path, GENERIC_READ, 0, NULL, i, 0, 0);
4260 ok(hfile == INVALID_HANDLE_VALUE, "CreateFile should fail\n");
4261 if (i == 0 || i == 5)
4263 /* FIXME: remove once Wine is fixed */
4264 todo_wine_if (i == 5)
4265 ok(GetLastError() == ERROR_INVALID_PARAMETER, "%ld: expected ERROR_INVALID_PARAMETER, got %ld\n", i, GetLastError());
4267 else
4269 /* FIXME: remove once Wine is fixed */
4270 todo_wine_if (i == 1)
4271 ok(GetLastError() == ERROR_ACCESS_DENIED, "%ld: expected ERROR_ACCESS_DENIED, got %ld\n", i, GetLastError());
4274 SetLastError(0xdeadbeef);
4275 hfile = CreateFileA(temp_path, GENERIC_WRITE, 0, NULL, i, 0, 0);
4276 ok(hfile == INVALID_HANDLE_VALUE, "CreateFile should fail\n");
4277 if (i == 0)
4278 ok(GetLastError() == ERROR_INVALID_PARAMETER, "%ld: expected ERROR_INVALID_PARAMETER, got %ld\n", i, GetLastError());
4279 else
4281 /* FIXME: remove once Wine is fixed */
4282 todo_wine_if (i == 1)
4283 ok(GetLastError() == ERROR_ACCESS_DENIED, "%ld: expected ERROR_ACCESS_DENIED, got %ld\n", i, GetLastError());
4287 for (i = 0; i < ARRAY_SIZE(td); i++)
4289 SetLastError(0xdeadbeef);
4290 hfile = CreateFileA(file_name, td[i].access, 0, NULL, td[i].disposition, 0, 0);
4291 if (!td[i].error)
4293 ok(hfile != INVALID_HANDLE_VALUE, "%ld: CreateFile error %ld\n", i, GetLastError());
4294 written = 0xdeadbeef;
4295 SetLastError(0xdeadbeef);
4296 ret = WriteFile(hfile, &td[i].error, sizeof(td[i].error), &written, NULL);
4297 if (td[i].access & GENERIC_WRITE)
4298 ok(ret, "%ld: WriteFile error %ld\n", i, GetLastError());
4299 else
4301 ok(!ret, "%ld: WriteFile should fail\n", i);
4302 ok(GetLastError() == ERROR_ACCESS_DENIED, "%ld: expected ERROR_ACCESS_DENIED, got %ld\n", i, GetLastError());
4304 SetLastError(0xdeadbeef);
4305 ret = SetFileTime(hfile, NULL, NULL, NULL);
4306 if (td[i].access & GENERIC_WRITE) /* actually FILE_WRITE_ATTRIBUTES */
4307 ok(ret, "%ld: SetFileTime error %ld\n", i, GetLastError());
4308 else
4310 todo_wine
4312 ok(!ret, "%ld: SetFileTime should fail\n", i);
4313 ok(GetLastError() == ERROR_ACCESS_DENIED, "%ld: expected ERROR_ACCESS_DENIED, got %ld\n", i, GetLastError());
4316 CloseHandle(hfile);
4318 else
4320 /* FIXME: remove the condition below once Wine is fixed */
4321 if (td[i].disposition == TRUNCATE_EXISTING && !(td[i].access & GENERIC_WRITE))
4323 todo_wine
4325 ok(hfile == INVALID_HANDLE_VALUE, "%ld: CreateFile should fail\n", i);
4326 ok(GetLastError() == td[i].error, "%ld: expected %ld, got %ld\n", i, td[i].error, GetLastError());
4328 CloseHandle(hfile);
4330 else
4332 ok(hfile == INVALID_HANDLE_VALUE, "%ld: CreateFile should fail\n", i);
4333 ok(GetLastError() == td[i].error, "%ld: expected %ld, got %ld\n", i, td[i].error, GetLastError());
4337 if (td[i].clean_up) DeleteFileA(file_name);
4340 DeleteFileA(file_name);
4343 static void test_GetFileInformationByHandleEx(void)
4345 int i;
4346 char tempPath[MAX_PATH], tempFileName[MAX_PATH], buffer[1024], *strPtr;
4347 BOOL ret;
4348 DWORD ret2, written;
4349 HANDLE directory, file;
4350 FILE_ID_BOTH_DIR_INFO *bothDirInfo;
4351 FILE_BASIC_INFO *basicInfo;
4352 FILE_STANDARD_INFO *standardInfo;
4353 FILE_NAME_INFO *nameInfo;
4354 LARGE_INTEGER prevWrite;
4355 FILE_IO_PRIORITY_HINT_INFO priohintinfo;
4356 FILE_ALLOCATION_INFO allocinfo;
4357 FILE_DISPOSITION_INFO dispinfo;
4358 FILE_END_OF_FILE_INFO eofinfo;
4359 FILE_RENAME_INFO renameinfo;
4361 struct {
4362 FILE_INFO_BY_HANDLE_CLASS handleClass;
4363 void *ptr;
4364 DWORD size;
4365 DWORD errorCode;
4366 } checks[] = {
4367 {0xdeadbeef, NULL, 0, ERROR_INVALID_PARAMETER},
4368 {FileIdBothDirectoryInfo, NULL, 0, ERROR_BAD_LENGTH},
4369 {FileIdBothDirectoryInfo, NULL, sizeof(buffer), ERROR_NOACCESS},
4370 {FileIdBothDirectoryInfo, buffer, 0, ERROR_BAD_LENGTH}};
4372 if (!pGetFileInformationByHandleEx)
4374 win_skip("GetFileInformationByHandleEx is missing.\n");
4375 return;
4378 ret2 = GetTempPathA(sizeof(tempPath), tempPath);
4379 ok(ret2, "GetFileInformationByHandleEx: GetTempPathA failed, got error %lu.\n", GetLastError());
4381 /* ensure the existence of a file in the temp folder */
4382 ret2 = GetTempFileNameA(tempPath, "abc", 0, tempFileName);
4383 ok(ret2, "GetFileInformationByHandleEx: GetTempFileNameA failed, got error %lu.\n", GetLastError());
4384 ret2 = GetFileAttributesA(tempFileName);
4385 ok(ret2 != INVALID_FILE_ATTRIBUTES, "GetFileInformationByHandleEx: "
4386 "GetFileAttributesA failed to find the temp file, got error %lu.\n", GetLastError());
4388 directory = CreateFileA(tempPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4389 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
4390 ok(directory != INVALID_HANDLE_VALUE, "GetFileInformationByHandleEx: failed to open the temp folder, "
4391 "got error %lu.\n", GetLastError());
4393 for (i = 0; i < ARRAY_SIZE(checks); i += 1)
4395 SetLastError(0xdeadbeef);
4396 ret = pGetFileInformationByHandleEx(directory, checks[i].handleClass, checks[i].ptr, checks[i].size);
4397 ok(!ret && GetLastError() == checks[i].errorCode, "GetFileInformationByHandleEx: expected error %lu, "
4398 "got %lu.\n", checks[i].errorCode, GetLastError());
4401 while (TRUE)
4403 memset(buffer, 0xff, sizeof(buffer));
4404 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer));
4405 if (!ret && GetLastError() == ERROR_NO_MORE_FILES)
4406 break;
4407 ok(ret, "GetFileInformationByHandleEx: failed to query for FileIdBothDirectoryInfo, got error %lu.\n", GetLastError());
4408 if (!ret)
4409 break;
4410 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
4411 while (TRUE)
4413 ok(bothDirInfo->FileAttributes != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file attributes.\n");
4414 ok(bothDirInfo->FileId.u.LowPart != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file id.\n");
4415 ok(bothDirInfo->FileNameLength != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file name length.\n");
4416 if (!bothDirInfo->NextEntryOffset)
4417 break;
4418 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)(((char *)bothDirInfo) + bothDirInfo->NextEntryOffset);
4422 CloseHandle(directory);
4424 file = CreateFileA(tempFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4425 NULL, OPEN_EXISTING, 0, NULL);
4426 ok(file != INVALID_HANDLE_VALUE, "GetFileInformationByHandleEx: failed to open the temp file, "
4427 "got error %lu.\n", GetLastError());
4429 /* Test FileBasicInfo; make sure the write time changes when a file is updated */
4430 memset(buffer, 0xff, sizeof(buffer));
4431 ret = pGetFileInformationByHandleEx(file, FileBasicInfo, buffer, sizeof(buffer));
4432 ok(ret, "GetFileInformationByHandleEx: failed to get FileBasicInfo, %lu\n", GetLastError());
4433 basicInfo = (FILE_BASIC_INFO *)buffer;
4434 prevWrite = basicInfo->LastWriteTime;
4435 CloseHandle(file);
4437 Sleep(30); /* Make sure a new write time is different from the previous */
4439 /* Write something to the file, to make sure the write time has changed */
4440 file = CreateFileA(tempFileName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4441 NULL, OPEN_EXISTING, 0, NULL);
4442 ok(file != INVALID_HANDLE_VALUE, "GetFileInformationByHandleEx: failed to open the temp file, "
4443 "got error %lu.\n", GetLastError());
4444 ret = WriteFile(file, tempFileName, strlen(tempFileName), &written, NULL);
4445 ok(ret, "GetFileInformationByHandleEx: Write failed\n");
4446 CloseHandle(file);
4448 file = CreateFileA(tempFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4449 NULL, OPEN_EXISTING, 0, NULL);
4450 ok(file != INVALID_HANDLE_VALUE, "GetFileInformationByHandleEx: failed to open the temp file, "
4451 "got error %lu.\n", GetLastError());
4453 memset(buffer, 0xff, sizeof(buffer));
4454 ret = pGetFileInformationByHandleEx(file, FileBasicInfo, buffer, sizeof(buffer));
4455 ok(ret, "GetFileInformationByHandleEx: failed to get FileBasicInfo, %lu\n", GetLastError());
4456 basicInfo = (FILE_BASIC_INFO *)buffer;
4457 /* Could also check that the creation time didn't change - on windows
4458 * it doesn't, but on wine, it does change even if it shouldn't. */
4459 ok(basicInfo->LastWriteTime.QuadPart != prevWrite.QuadPart,
4460 "GetFileInformationByHandleEx: last write time didn't change\n");
4462 /* Test FileStandardInfo, check some basic parameters */
4463 memset(buffer, 0xff, sizeof(buffer));
4464 ret = pGetFileInformationByHandleEx(file, FileStandardInfo, buffer, sizeof(buffer));
4465 ok(ret, "GetFileInformationByHandleEx: failed to get FileStandardInfo, %lu\n", GetLastError());
4466 standardInfo = (FILE_STANDARD_INFO *)buffer;
4467 ok(standardInfo->NumberOfLinks == 1, "GetFileInformationByHandleEx: Unexpected number of links\n");
4468 ok(standardInfo->DeletePending == FALSE, "GetFileInformationByHandleEx: Unexpected pending delete\n");
4469 ok(standardInfo->Directory == FALSE, "GetFileInformationByHandleEx: Incorrect directory flag\n");
4471 /* Test FileNameInfo */
4472 memset(buffer, 0xff, sizeof(buffer));
4473 ret = pGetFileInformationByHandleEx(file, FileNameInfo, buffer, sizeof(buffer));
4474 ok(ret, "GetFileInformationByHandleEx: failed to get FileNameInfo, %lu\n", GetLastError());
4475 nameInfo = (FILE_NAME_INFO *)buffer;
4476 strPtr = strchr(tempFileName, '\\');
4477 ok(strPtr != NULL, "GetFileInformationByHandleEx: Temp filename didn't contain backslash\n");
4478 ok(nameInfo->FileNameLength == strlen(strPtr) * 2,
4479 "GetFileInformationByHandleEx: Incorrect file name length\n");
4480 for (i = 0; i < nameInfo->FileNameLength/2; i++)
4481 ok(strPtr[i] == nameInfo->FileName[i], "Incorrect filename char %d: %c vs %c\n",
4482 i, strPtr[i], nameInfo->FileName[i]);
4484 /* invalid classes */
4485 SetLastError(0xdeadbeef);
4486 ret = pGetFileInformationByHandleEx(file, FileEndOfFileInfo, &eofinfo, sizeof(eofinfo));
4487 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError());
4489 SetLastError(0xdeadbeef);
4490 ret = pGetFileInformationByHandleEx(file, FileIoPriorityHintInfo, &priohintinfo, sizeof(priohintinfo));
4491 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError());
4493 SetLastError(0xdeadbeef);
4494 ret = pGetFileInformationByHandleEx(file, FileAllocationInfo, &allocinfo, sizeof(allocinfo));
4495 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError());
4497 SetLastError(0xdeadbeef);
4498 ret = pGetFileInformationByHandleEx(file, FileDispositionInfo, &dispinfo, sizeof(dispinfo));
4499 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError());
4501 SetLastError(0xdeadbeef);
4502 ret = pGetFileInformationByHandleEx(file, FileRenameInfo, &renameinfo, sizeof(renameinfo));
4503 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError());
4505 CloseHandle(file);
4506 DeleteFileA(tempFileName);
4509 static void test_OpenFileById(void)
4511 char tempPath[MAX_PATH], tempFileName[MAX_PATH], buffer[256], tickCount[256];
4512 WCHAR tempFileNameW[MAX_PATH];
4513 BOOL ret, found;
4514 DWORD ret2, count, tempFileNameLen;
4515 HANDLE directory, handle, tempFile;
4516 FILE_ID_BOTH_DIR_INFO *bothDirInfo;
4517 FILE_ID_DESCRIPTOR fileIdDescr;
4519 if (!pGetFileInformationByHandleEx || !pOpenFileById)
4521 win_skip("GetFileInformationByHandleEx or OpenFileById is missing.\n");
4522 return;
4525 ret2 = GetTempPathA(sizeof(tempPath), tempPath);
4526 ok(ret2, "OpenFileById: GetTempPath failed, got error %lu.\n", GetLastError());
4528 /* ensure the existence of a file in the temp folder */
4529 ret2 = GetTempFileNameA(tempPath, "abc", 0, tempFileName);
4530 ok(ret2, "OpenFileById: GetTempFileNameA failed, got error %lu.\n", GetLastError());
4531 ret2 = GetFileAttributesA(tempFileName);
4532 ok(ret2 != INVALID_FILE_ATTRIBUTES,
4533 "OpenFileById: GetFileAttributesA failed to find the temp file, got error %lu\n", GetLastError());
4535 ret2 = MultiByteToWideChar(CP_ACP, 0, tempFileName + strlen(tempPath), -1, tempFileNameW, ARRAY_SIZE(tempFileNameW));
4536 ok(ret2, "OpenFileById: MultiByteToWideChar failed to convert tempFileName, got error %lu.\n", GetLastError());
4537 tempFileNameLen = ret2 - 1;
4539 tempFile = CreateFileA(tempFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
4540 ok(tempFile != INVALID_HANDLE_VALUE, "OpenFileById: failed to create a temp file, "
4541 "got error %lu.\n", GetLastError());
4542 ret2 = sprintf(tickCount, "%lu", GetTickCount());
4543 ret = WriteFile(tempFile, tickCount, ret2, &count, NULL);
4544 ok(ret, "OpenFileById: WriteFile failed, got error %lu.\n", GetLastError());
4545 CloseHandle(tempFile);
4547 directory = CreateFileA(tempPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4548 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
4549 ok(directory != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the temp folder, "
4550 "got error %lu.\n", GetLastError());
4552 /* get info about the temp folder itself */
4553 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
4554 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer));
4555 ok(ret, "OpenFileById: failed to query for FileIdBothDirectoryInfo, got error %lu.\n", GetLastError());
4556 ok(bothDirInfo->FileNameLength == sizeof(WCHAR) && bothDirInfo->FileName[0] == '.',
4557 "OpenFileById: failed to return the temp folder at the first entry, got error %lu.\n", GetLastError());
4559 /* open the temp folder itself */
4560 fileIdDescr.dwSize = sizeof(fileIdDescr);
4561 fileIdDescr.Type = FileIdType;
4562 fileIdDescr.FileId = bothDirInfo->FileId;
4563 handle = pOpenFileById(directory, &fileIdDescr, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0);
4564 todo_wine
4565 ok(handle != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the temp folder itself, got error %lu.\n", GetLastError());
4566 CloseHandle(handle);
4568 /* find the temp file in the temp folder */
4569 found = FALSE;
4570 while (!found)
4572 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer));
4573 ok(ret, "OpenFileById: failed to query for FileIdBothDirectoryInfo, got error %lu.\n", GetLastError());
4574 if (!ret)
4575 break;
4576 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
4577 while (TRUE)
4579 if (tempFileNameLen == bothDirInfo->FileNameLength / sizeof(WCHAR) &&
4580 memcmp(tempFileNameW, bothDirInfo->FileName, bothDirInfo->FileNameLength) == 0)
4582 found = TRUE;
4583 break;
4585 if (!bothDirInfo->NextEntryOffset)
4586 break;
4587 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)(((char *)bothDirInfo) + bothDirInfo->NextEntryOffset);
4590 ok(found, "OpenFileById: failed to find the temp file in the temp folder.\n");
4592 SetLastError(0xdeadbeef);
4593 handle = pOpenFileById(directory, NULL, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0);
4594 ok(handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER,
4595 "OpenFileById: expected ERROR_INVALID_PARAMETER, got error %lu.\n", GetLastError());
4597 fileIdDescr.dwSize = sizeof(fileIdDescr);
4598 fileIdDescr.Type = FileIdType;
4599 fileIdDescr.FileId = bothDirInfo->FileId;
4600 handle = pOpenFileById(directory, &fileIdDescr, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0);
4601 ok(handle != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the file, got error %lu.\n", GetLastError());
4603 ret = ReadFile(handle, buffer, sizeof(buffer), &count, NULL);
4604 buffer[count] = 0;
4605 ok(ret, "OpenFileById: ReadFile failed, got error %lu.\n", GetLastError());
4606 ok(strcmp(tickCount, buffer) == 0, "OpenFileById: invalid contents of the temp file.\n");
4608 CloseHandle(handle);
4609 CloseHandle(directory);
4610 DeleteFileA(tempFileName);
4613 static void test_SetFileValidData(void)
4615 BOOL ret;
4616 HANDLE handle;
4617 DWORD error, count;
4618 char path[MAX_PATH], filename[MAX_PATH];
4619 TOKEN_PRIVILEGES privs;
4620 HANDLE token = NULL;
4622 if (!pSetFileValidData)
4624 win_skip("SetFileValidData is missing\n");
4625 return;
4627 GetTempPathA(sizeof(path), path);
4628 GetTempFileNameA(path, "tst", 0, filename);
4629 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
4630 WriteFile(handle, "test", sizeof("test") - 1, &count, NULL);
4631 CloseHandle(handle);
4633 SetLastError(0xdeadbeef);
4634 ret = pSetFileValidData(INVALID_HANDLE_VALUE, 0);
4635 error = GetLastError();
4636 ok(!ret, "SetFileValidData succeeded\n");
4637 ok(error == ERROR_INVALID_HANDLE, "got %lu\n", error);
4639 SetLastError(0xdeadbeef);
4640 ret = pSetFileValidData(INVALID_HANDLE_VALUE, -1);
4641 error = GetLastError();
4642 ok(!ret, "SetFileValidData succeeded\n");
4643 ok(error == ERROR_INVALID_HANDLE, "got %lu\n", error);
4645 /* file opened for reading */
4646 handle = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
4648 SetLastError(0xdeadbeef);
4649 ret = pSetFileValidData(handle, 0);
4650 ok(!ret, "SetFileValidData succeeded\n");
4651 error = GetLastError();
4652 ok(error == ERROR_ACCESS_DENIED, "got %lu\n", error);
4654 SetLastError(0xdeadbeef);
4655 ret = pSetFileValidData(handle, -1);
4656 error = GetLastError();
4657 ok(!ret, "SetFileValidData succeeded\n");
4658 ok(error == ERROR_ACCESS_DENIED, "got %lu\n", error);
4659 CloseHandle(handle);
4661 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
4663 SetLastError(0xdeadbeef);
4664 ret = pSetFileValidData(handle, 0);
4665 error = GetLastError();
4666 ok(!ret, "SetFileValidData succeeded\n");
4667 todo_wine ok(error == ERROR_PRIVILEGE_NOT_HELD, "got %lu\n", error);
4668 CloseHandle(handle);
4670 privs.PrivilegeCount = 1;
4671 privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
4673 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token) ||
4674 !LookupPrivilegeValueA(NULL, SE_MANAGE_VOLUME_NAME, &privs.Privileges[0].Luid) ||
4675 !AdjustTokenPrivileges(token, FALSE, &privs, sizeof(privs), NULL, NULL) ||
4676 GetLastError() == ERROR_NOT_ALL_ASSIGNED)
4678 win_skip("cannot enable SE_MANAGE_VOLUME_NAME privilege\n");
4679 CloseHandle(token);
4680 DeleteFileA(filename);
4681 return;
4683 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
4685 SetLastError(0xdeadbeef);
4686 ret = pSetFileValidData(handle, 0);
4687 error = GetLastError();
4688 ok(!ret, "SetFileValidData succeeded\n");
4689 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
4691 SetLastError(0xdeadbeef);
4692 ret = pSetFileValidData(handle, -1);
4693 error = GetLastError();
4694 ok(!ret, "SetFileValidData succeeded\n");
4695 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
4697 SetLastError(0xdeadbeef);
4698 ret = pSetFileValidData(handle, 2);
4699 error = GetLastError();
4700 todo_wine ok(!ret, "SetFileValidData succeeded\n");
4701 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
4703 ret = pSetFileValidData(handle, 4);
4704 ok(ret, "SetFileValidData failed %lu\n", GetLastError());
4706 SetLastError(0xdeadbeef);
4707 ret = pSetFileValidData(handle, 8);
4708 error = GetLastError();
4709 ok(!ret, "SetFileValidData succeeded\n");
4710 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
4712 count = SetFilePointer(handle, 1024, NULL, FILE_END);
4713 ok(count != INVALID_SET_FILE_POINTER, "SetFilePointer failed %lu\n", GetLastError());
4714 ret = SetEndOfFile(handle);
4715 ok(ret, "SetEndOfFile failed %lu\n", GetLastError());
4717 SetLastError(0xdeadbeef);
4718 ret = pSetFileValidData(handle, 2);
4719 error = GetLastError();
4720 todo_wine ok(!ret, "SetFileValidData succeeded\n");
4721 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
4723 ret = pSetFileValidData(handle, 4);
4724 ok(ret, "SetFileValidData failed %lu\n", GetLastError());
4726 ret = pSetFileValidData(handle, 8);
4727 ok(ret, "SetFileValidData failed %lu\n", GetLastError());
4729 ret = pSetFileValidData(handle, 4);
4730 error = GetLastError();
4731 todo_wine ok(!ret, "SetFileValidData succeeded\n");
4732 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
4734 ret = pSetFileValidData(handle, 1024);
4735 ok(ret, "SetFileValidData failed %lu\n", GetLastError());
4737 ret = pSetFileValidData(handle, 2048);
4738 error = GetLastError();
4739 ok(!ret, "SetFileValidData succeeded\n");
4740 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error);
4742 privs.Privileges[0].Attributes = 0;
4743 AdjustTokenPrivileges(token, FALSE, &privs, sizeof(privs), NULL, NULL);
4745 CloseHandle(token);
4746 CloseHandle(handle);
4747 DeleteFileA(filename);
4750 static void test_ReOpenFile(void)
4752 char path[MAX_PATH], filename[MAX_PATH], buffer[4];
4753 HANDLE file, new;
4754 unsigned int i;
4755 DWORD size;
4756 BOOL ret;
4758 static const DWORD invalid_attributes[] =
4760 FILE_ATTRIBUTE_ARCHIVE,
4761 FILE_ATTRIBUTE_ENCRYPTED,
4762 FILE_ATTRIBUTE_HIDDEN,
4763 FILE_ATTRIBUTE_NORMAL,
4764 FILE_ATTRIBUTE_OFFLINE,
4765 FILE_ATTRIBUTE_READONLY,
4766 FILE_ATTRIBUTE_SYSTEM,
4767 FILE_ATTRIBUTE_TEMPORARY,
4770 static const DWORD valid_attributes[] =
4772 FILE_FLAG_BACKUP_SEMANTICS,
4773 FILE_FLAG_NO_BUFFERING,
4774 FILE_FLAG_OVERLAPPED,
4775 FILE_FLAG_RANDOM_ACCESS,
4776 FILE_FLAG_SEQUENTIAL_SCAN,
4777 FILE_FLAG_WRITE_THROUGH,
4780 if (!pReOpenFile)
4782 win_skip("ReOpenFile() is not available\n");
4783 return;
4786 GetTempPathA(sizeof(path), path);
4787 GetTempFileNameA(path, "tst", 0, filename);
4789 file = CreateFileA(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
4790 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
4791 ok(file != INVALID_HANDLE_VALUE, "failed to create file, error %lu\n", GetLastError());
4792 ret = WriteFile(file, "foo", 4, &size, NULL);
4793 ok(ret, "failed to write file, error %lu\n", GetLastError());
4795 for (i = 0; i < ARRAY_SIZE(invalid_attributes); ++i)
4797 SetLastError(0xdeadbeef);
4798 new = pReOpenFile(file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, invalid_attributes[i]);
4799 ok(new == INVALID_HANDLE_VALUE, "got %p\n", new);
4800 ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError());
4803 new = pReOpenFile(file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0);
4804 ok(new != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError());
4806 ret = ReadFile(new, buffer, sizeof(buffer), &size, NULL);
4807 ok(ret, "failed to read file, error %lu\n", GetLastError());
4808 ok(size == 4, "got size %lu\n", size);
4809 ok(!strcmp(buffer, "foo"), "got wrong data\n");
4810 CloseHandle(new);
4812 for (i = 0; i < ARRAY_SIZE(valid_attributes); ++i)
4814 new = pReOpenFile(file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, valid_attributes[i]);
4815 ok(new != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError());
4816 CloseHandle(new);
4819 SetLastError(0xdeadbeef);
4820 new = pReOpenFile(file, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0);
4821 ok(new == INVALID_HANDLE_VALUE, "got %p\n", new);
4822 ok(GetLastError() == ERROR_SHARING_VIOLATION, "got error %lu\n", GetLastError());
4824 CloseHandle(file);
4825 ret = DeleteFileA(filename);
4826 ok(ret, "failed to delete file, error %lu\n", GetLastError());
4828 file = CreateNamedPipeA("\\\\.\\pipe\\test_pipe", PIPE_ACCESS_DUPLEX, 0, 1, 1000, 1000, 1000, NULL);
4829 ok(file != INVALID_HANDLE_VALUE, "failed to create pipe, error %lu\n", GetLastError());
4831 new = pReOpenFile(file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0);
4832 ok(new != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError());
4834 ret = WriteFile(file, "foo", 4, &size, NULL);
4835 ok(ret, "failed to write file, error %lu\n", GetLastError());
4836 ret = ReadFile(new, buffer, sizeof(buffer), &size, NULL);
4837 ok(ret, "failed to read file, error %lu\n", GetLastError());
4838 ok(size == 4, "got size %lu\n", size);
4839 ok(!strcmp(buffer, "foo"), "got wrong data\n");
4841 CloseHandle(new);
4842 CloseHandle(file);
4845 static void test_WriteFileGather(void)
4847 char temp_path[MAX_PATH], filename[MAX_PATH];
4848 HANDLE hfile, hiocp1, hiocp2, evt;
4849 DWORD ret, size, tx;
4850 ULONG_PTR key;
4851 FILE_SEGMENT_ELEMENT fse[2];
4852 OVERLAPPED ovl, *povl = NULL;
4853 SYSTEM_INFO si;
4854 char *wbuf = NULL, *rbuf1, *rbuf2;
4855 BOOL br;
4857 evt = CreateEventW( NULL, TRUE, FALSE, NULL );
4859 ret = GetTempPathA( MAX_PATH, temp_path );
4860 ok( ret != 0, "GetTempPathA error %ld\n", GetLastError() );
4861 ok( ret < MAX_PATH, "temp path should fit into MAX_PATH\n" );
4862 ret = GetTempFileNameA( temp_path, "wfg", 0, filename );
4863 ok( ret != 0, "GetTempFileNameA error %ld\n", GetLastError() );
4865 hfile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
4866 FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL, 0 );
4867 ok( hfile != INVALID_HANDLE_VALUE, "CreateFile failed err %lu\n", GetLastError() );
4868 if (hfile == INVALID_HANDLE_VALUE) return;
4870 hiocp1 = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 999, 0 );
4871 hiocp2 = CreateIoCompletionPort( hfile, hiocp1, 999, 0 );
4872 ok( hiocp2 != 0, "CreateIoCompletionPort failed err %lu\n", GetLastError() );
4874 GetSystemInfo( &si );
4875 wbuf = VirtualAlloc( NULL, si.dwPageSize, MEM_COMMIT, PAGE_READWRITE );
4876 ok( wbuf != NULL, "VirtualAlloc failed err %lu\n", GetLastError() );
4878 rbuf1 = VirtualAlloc( NULL, si.dwPageSize, MEM_COMMIT, PAGE_READWRITE );
4879 ok( rbuf1 != NULL, "VirtualAlloc failed err %lu\n", GetLastError() );
4881 rbuf2 = VirtualAlloc( NULL, si.dwPageSize, MEM_COMMIT, PAGE_READWRITE );
4882 ok( rbuf2 != NULL, "VirtualAlloc failed err %lu\n", GetLastError() );
4884 memset( &ovl, 0, sizeof(ovl) );
4885 ovl.hEvent = evt;
4886 memset( fse, 0, sizeof(fse) );
4887 fse[0].Buffer = wbuf;
4888 memset( wbuf, 0x42, si.dwPageSize );
4889 SetLastError( 0xdeadbeef );
4890 if (!WriteFileGather( hfile, fse, si.dwPageSize, NULL, &ovl ))
4891 ok( GetLastError() == ERROR_IO_PENDING, "WriteFileGather failed err %lu\n", GetLastError() );
4893 ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 1000 );
4894 ok( ret, "GetQueuedCompletionStatus failed err %lu\n", GetLastError());
4895 ok( povl == &ovl, "wrong ovl %p\n", povl );
4897 tx = 0;
4898 br = GetOverlappedResult( hfile, &ovl, &tx, TRUE );
4899 ok( br == TRUE, "GetOverlappedResult failed: %lu\n", GetLastError() );
4900 ok( tx == si.dwPageSize, "got unexpected bytes transferred: %lu\n", tx );
4902 ResetEvent( evt );
4904 /* read exact size */
4905 memset( &ovl, 0, sizeof(ovl) );
4906 ovl.hEvent = evt;
4907 memset( fse, 0, sizeof(fse) );
4908 fse[0].Buffer = rbuf1;
4909 memset( rbuf1, 0, si.dwPageSize );
4910 SetLastError( 0xdeadbeef );
4911 br = ReadFileScatter( hfile, fse, si.dwPageSize, NULL, &ovl );
4912 ok( br == FALSE, "ReadFileScatter should be asynchronous\n" );
4913 ok( GetLastError() == ERROR_IO_PENDING, "ReadFileScatter failed err %lu\n", GetLastError() );
4915 ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 1000 );
4916 ok( ret, "GetQueuedCompletionStatus failed err %lu\n", GetLastError());
4917 ok( povl == &ovl, "wrong ovl %p\n", povl );
4919 tx = 0;
4920 br = GetOverlappedResult( hfile, &ovl, &tx, TRUE );
4921 ok( br == TRUE, "GetOverlappedResult failed: %lu\n", GetLastError() );
4922 ok( tx == si.dwPageSize, "got unexpected bytes transferred: %lu\n", tx );
4924 ok( memcmp( rbuf1, wbuf, si.dwPageSize ) == 0,
4925 "data was not read into buffer\n" );
4927 ResetEvent( evt );
4929 /* start read at EOF */
4930 memset( &ovl, 0, sizeof(ovl) );
4931 ovl.hEvent = evt;
4932 ovl.OffsetHigh = 0;
4933 ovl.Offset = si.dwPageSize;
4934 memset( fse, 0, sizeof(fse) );
4935 fse[0].Buffer = rbuf1;
4936 SetLastError( 0xdeadbeef );
4937 br = ReadFileScatter( hfile, fse, si.dwPageSize, NULL, &ovl );
4938 ok( br == FALSE, "ReadFileScatter should have failed\n" );
4939 ok( GetLastError() == ERROR_HANDLE_EOF ||
4940 GetLastError() == ERROR_IO_PENDING, "ReadFileScatter gave wrong error %lu\n", GetLastError() );
4941 if (GetLastError() == ERROR_IO_PENDING)
4943 SetLastError( 0xdeadbeef );
4944 ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 1000 );
4945 ok( !ret, "GetQueuedCompletionStatus should have returned failure\n" );
4946 ok( GetLastError() == ERROR_HANDLE_EOF, "Got wrong error: %lu\n", GetLastError() );
4947 ok( povl == &ovl, "wrong ovl %p\n", povl );
4949 SetLastError( 0xdeadbeef );
4950 br = GetOverlappedResult( hfile, &ovl, &tx, TRUE );
4951 ok( br == FALSE, "GetOverlappedResult should have failed\n" );
4952 ok( GetLastError() == ERROR_HANDLE_EOF, "Got wrong error: %lu\n", GetLastError() );
4954 else
4956 SetLastError( 0xdeadbeef );
4957 ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 100 );
4958 ok( !ret, "GetQueuedCompletionStatus failed err %lu\n", GetLastError() );
4959 ok( GetLastError() == WAIT_TIMEOUT, "GetQueuedCompletionStatus gave wrong error %lu\n", GetLastError() );
4960 ok( povl == NULL, "wrong ovl %p\n", povl );
4963 ResetEvent( evt );
4965 /* read past EOF */
4966 memset( &ovl, 0, sizeof(ovl) );
4967 ovl.hEvent = evt;
4968 memset( fse, 0, sizeof(fse) );
4969 fse[0].Buffer = rbuf1;
4970 fse[1].Buffer = rbuf2;
4971 memset( rbuf1, 0, si.dwPageSize );
4972 memset( rbuf2, 0x17, si.dwPageSize );
4973 SetLastError( 0xdeadbeef );
4974 br = ReadFileScatter( hfile, fse, si.dwPageSize * 2, NULL, &ovl );
4975 ok( br == FALSE, "ReadFileScatter should be asynchronous\n" );
4976 ok( GetLastError() == ERROR_IO_PENDING, "ReadFileScatter failed err %lu\n", GetLastError() );
4978 ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 1000 );
4979 ok( ret, "GetQueuedCompletionStatus failed err %lu\n", GetLastError() );
4980 ok( povl == &ovl, "wrong ovl %p\n", povl );
4982 tx = 0;
4983 br = GetOverlappedResult( hfile, &ovl, &tx, TRUE );
4984 ok( br == TRUE, "GetOverlappedResult failed: %lu\n", GetLastError() );
4985 ok( tx == si.dwPageSize, "got unexpected bytes transferred: %lu\n", tx );
4987 ok( memcmp( rbuf1, wbuf, si.dwPageSize ) == 0,
4988 "data was not read into buffer\n" );
4989 memset( rbuf1, 0x17, si.dwPageSize );
4990 ok( memcmp( rbuf2, rbuf1, si.dwPageSize ) == 0,
4991 "data should not have been read into buffer\n" );
4993 ResetEvent( evt );
4995 /* partial page read */
4996 memset( &ovl, 0, sizeof(ovl) );
4997 ovl.hEvent = evt;
4998 memset( fse, 0, sizeof(fse) );
4999 fse[0].Buffer = rbuf1;
5000 memset( rbuf1, 0, si.dwPageSize );
5001 SetLastError( 0xdeadbeef );
5002 br = ReadFileScatter( hfile, fse, si.dwPageSize / 2, NULL, &ovl );
5003 ok( br == FALSE, "ReadFileScatter should be asynchronous\n" );
5004 ok( GetLastError() == ERROR_IO_PENDING, "ReadFileScatter failed err %lu\n", GetLastError() );
5006 ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 1000 );
5007 ok( ret, "GetQueuedCompletionStatus failed err %lu\n", GetLastError() );
5008 ok( povl == &ovl, "wrong ovl %p\n", povl );
5010 tx = 0;
5011 br = GetOverlappedResult( hfile, &ovl, &tx, TRUE );
5012 ok( br == TRUE, "GetOverlappedResult failed: %lu\n", GetLastError() );
5013 ok( tx == si.dwPageSize / 2, "got unexpected bytes transferred: %lu\n", tx );
5015 ok( memcmp( rbuf1, wbuf, si.dwPageSize / 2 ) == 0,
5016 "invalid data was read into buffer\n" );
5017 memset( rbuf2, 0, si.dwPageSize );
5018 ok( memcmp( rbuf1 + si.dwPageSize / 2, rbuf2, si.dwPageSize - si.dwPageSize / 2 ) == 0,
5019 "invalid data was read into buffer\n" );
5021 if (pSetFileCompletionNotificationModes)
5023 br = pSetFileCompletionNotificationModes(hfile, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS);
5024 ok(br, "SetFileCompletionNotificationModes failed, error %lu.\n", GetLastError());
5026 br = ReadFileScatter(hfile, fse, si.dwPageSize, NULL, &ovl);
5027 ok(br == FALSE, "ReadFileScatter should be asynchronous.\n");
5028 ok(GetLastError() == ERROR_IO_PENDING, "ReadFileScatter failed, error %lu.\n", GetLastError());
5030 br = GetQueuedCompletionStatus(hiocp2, &size, &key, &povl, 1000);
5031 ok(br, "GetQueuedCompletionStatus failed, err %lu.\n", GetLastError());
5032 ok(povl == &ovl, "Wrong ovl %p.\n", povl);
5034 br = GetOverlappedResult(hfile, &ovl, &tx, TRUE);
5035 ok(br, "GetOverlappedResult failed, err %lu.\n", GetLastError());
5036 ok(tx == si.dwPageSize, "Got unexpected size %lu.\n", tx);
5038 ResetEvent(evt);
5040 else
5041 win_skip("SetFileCompletionNotificationModes not available.\n");
5043 CloseHandle( hfile );
5044 CloseHandle( hiocp1 );
5045 CloseHandle( hiocp2 );
5047 /* file handle must be overlapped */
5048 hfile = CreateFileA( filename, GENERIC_READ, 0, 0, OPEN_EXISTING,
5049 FILE_FLAG_NO_BUFFERING | FILE_ATTRIBUTE_NORMAL, 0 );
5050 ok( hfile != INVALID_HANDLE_VALUE, "CreateFile failed err %lu\n", GetLastError() );
5052 memset( &ovl, 0, sizeof(ovl) );
5053 memset( fse, 0, sizeof(fse) );
5054 fse[0].Buffer = rbuf1;
5055 memset( rbuf1, 0, si.dwPageSize );
5056 SetLastError( 0xdeadbeef );
5057 br = ReadFileScatter( hfile, fse, si.dwPageSize, NULL, &ovl );
5058 ok( br == FALSE, "ReadFileScatter should fail\n" );
5059 ok( GetLastError() == ERROR_INVALID_PARAMETER, "ReadFileScatter failed err %lu\n", GetLastError() );
5061 VirtualFree( wbuf, 0, MEM_RELEASE );
5062 VirtualFree( rbuf1, 0, MEM_RELEASE );
5063 VirtualFree( rbuf2, 0, MEM_RELEASE );
5064 CloseHandle( evt );
5065 DeleteFileA( filename );
5068 static unsigned file_map_access(unsigned access)
5070 if (access & GENERIC_READ) access |= FILE_GENERIC_READ;
5071 if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE;
5072 if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE;
5073 if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS;
5074 return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
5077 static BOOL is_access_compatible(unsigned obj_access, unsigned desired_access)
5079 obj_access = file_map_access(obj_access);
5080 desired_access = file_map_access(desired_access);
5081 return (obj_access & desired_access) == desired_access;
5084 static void test_file_access(void)
5086 static const struct
5088 unsigned access, create_error, write_error, read_error;
5089 } td[] =
5091 { GENERIC_READ | GENERIC_WRITE, 0, 0, 0 },
5092 { GENERIC_WRITE, 0, 0, ERROR_ACCESS_DENIED },
5093 { GENERIC_READ, 0, ERROR_ACCESS_DENIED, 0 },
5094 { FILE_READ_DATA | FILE_WRITE_DATA, 0, 0, 0 },
5095 { FILE_WRITE_DATA, 0, 0, ERROR_ACCESS_DENIED },
5096 { FILE_READ_DATA, 0, ERROR_ACCESS_DENIED, 0 },
5097 { FILE_APPEND_DATA, 0, 0, ERROR_ACCESS_DENIED },
5098 { FILE_READ_DATA | FILE_APPEND_DATA, 0, 0, 0 },
5099 { FILE_WRITE_DATA | FILE_APPEND_DATA, 0, 0, ERROR_ACCESS_DENIED },
5100 { 0, 0, ERROR_ACCESS_DENIED, ERROR_ACCESS_DENIED },
5102 char path[MAX_PATH], fname[MAX_PATH];
5103 unsigned char buf[16];
5104 HANDLE hfile, hdup;
5105 DWORD i, j, ret, bytes;
5107 GetTempPathA(MAX_PATH, path);
5108 GetTempFileNameA(path, "foo", 0, fname);
5110 for (i = 0; i < ARRAY_SIZE(td); i++)
5112 SetLastError(0xdeadbeef);
5113 hfile = CreateFileA(fname, td[i].access, 0, NULL, CREATE_ALWAYS,
5114 FILE_FLAG_DELETE_ON_CLOSE, 0);
5115 if (td[i].create_error)
5117 ok(hfile == INVALID_HANDLE_VALUE, "%ld: CreateFile should fail\n", i);
5118 ok(td[i].create_error == GetLastError(), "%ld: expected %d, got %ld\n", i, td[i].create_error, GetLastError());
5119 continue;
5121 else
5122 ok(hfile != INVALID_HANDLE_VALUE, "%ld: CreateFile error %ld\n", i, GetLastError());
5124 for (j = 0; j < ARRAY_SIZE(td); j++)
5126 SetLastError(0xdeadbeef);
5127 ret = DuplicateHandle(GetCurrentProcess(), hfile, GetCurrentProcess(), &hdup,
5128 td[j].access, 0, 0);
5129 if (is_access_compatible(td[i].access, td[j].access))
5130 ok(ret, "DuplicateHandle(%#x => %#x) error %ld\n", td[i].access, td[j].access, GetLastError());
5131 else
5133 /* FIXME: Remove once Wine is fixed */
5134 todo_wine_if((td[j].access & (GENERIC_READ | GENERIC_WRITE) ||
5135 (!(td[i].access & (GENERIC_WRITE | FILE_WRITE_DATA)) && (td[j].access & FILE_WRITE_DATA)) ||
5136 (!(td[i].access & (GENERIC_READ | FILE_READ_DATA)) && (td[j].access & FILE_READ_DATA)) ||
5137 (!(td[i].access & (GENERIC_WRITE)) && (td[j].access & FILE_APPEND_DATA))))
5139 ok(!ret, "DuplicateHandle(%#x => %#x) should fail\n", td[i].access, td[j].access);
5140 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
5143 if (ret) CloseHandle(hdup);
5146 SetLastError(0xdeadbeef);
5147 bytes = 0xdeadbeef;
5148 ret = WriteFile(hfile, "\x5e\xa7", 2, &bytes, NULL);
5149 if (td[i].write_error)
5151 ok(!ret, "%ld: WriteFile should fail\n", i);
5152 ok(td[i].write_error == GetLastError(), "%ld: expected %d, got %ld\n", i, td[i].write_error, GetLastError());
5153 ok(bytes == 0, "%ld: expected 0, got %lu\n", i, bytes);
5155 else
5157 ok(ret, "%ld: WriteFile error %ld\n", i, GetLastError());
5158 ok(bytes == 2, "%ld: expected 2, got %lu\n", i, bytes);
5161 SetLastError(0xdeadbeef);
5162 ret = SetFilePointer(hfile, 0, NULL, FILE_BEGIN);
5163 ok(ret != INVALID_SET_FILE_POINTER, "SetFilePointer error %ld\n", GetLastError());
5165 SetLastError(0xdeadbeef);
5166 bytes = 0xdeadbeef;
5167 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, NULL);
5168 if (td[i].read_error)
5170 ok(!ret, "%ld: ReadFile should fail\n", i);
5171 ok(td[i].read_error == GetLastError(), "%ld: expected %d, got %ld\n", i, td[i].read_error, GetLastError());
5172 ok(bytes == 0, "%ld: expected 0, got %lu\n", i, bytes);
5174 else
5176 ok(ret, "%ld: ReadFile error %ld\n", i, GetLastError());
5177 if (td[i].write_error)
5178 ok(bytes == 0, "%ld: expected 0, got %lu\n", i, bytes);
5179 else
5181 ok(bytes == 2, "%ld: expected 2, got %lu\n", i, bytes);
5182 ok(buf[0] == 0x5e && buf[1] == 0xa7, "%ld: expected 5ea7, got %02x%02x\n", i, buf[0], buf[1]);
5186 CloseHandle(hfile);
5190 static void test_GetFinalPathNameByHandleA(void)
5192 static char prefix[] = "GetFinalPathNameByHandleA";
5193 static char dos_prefix[] = "\\\\?\\";
5194 char temp_path[MAX_PATH], test_path[MAX_PATH];
5195 char long_path[MAX_PATH], result_path[MAX_PATH];
5196 char dos_path[MAX_PATH + sizeof(dos_prefix)];
5197 HANDLE file;
5198 DWORD count;
5199 UINT ret;
5201 if (!pGetFinalPathNameByHandleA)
5203 win_skip("GetFinalPathNameByHandleA is missing\n");
5204 return;
5207 /* Test calling with INVALID_HANDLE_VALUE */
5208 SetLastError(0xdeadbeaf);
5209 count = pGetFinalPathNameByHandleA(INVALID_HANDLE_VALUE, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
5210 ok(count == 0, "Expected length 0, got %lu\n", count);
5211 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %lu\n", GetLastError());
5213 count = GetTempPathA(MAX_PATH, temp_path);
5214 ok(count, "Failed to get temp path, error %lu\n", GetLastError());
5215 ret = GetTempFileNameA(temp_path, prefix, 0, test_path);
5216 ok(ret != 0, "GetTempFileNameA error %lu\n", GetLastError());
5217 ret = GetLongPathNameA(test_path, long_path, MAX_PATH);
5218 ok(ret != 0, "GetLongPathNameA error %lu\n", GetLastError());
5219 strcpy(dos_path, dos_prefix);
5220 strcat(dos_path, long_path);
5222 count = pGetFinalPathNameByHandleA(INVALID_HANDLE_VALUE, NULL, 0, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
5223 ok(count == 0, "Expected length 0, got %lu\n", count);
5224 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %lu\n", GetLastError());
5226 file = CreateFileA(test_path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
5227 CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0);
5228 ok(file != INVALID_HANDLE_VALUE, "CreateFileA error %lu\n", GetLastError());
5230 if (0) {
5231 /* Windows crashes on NULL path */
5232 count = pGetFinalPathNameByHandleA(file, NULL, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
5233 ok(count == 0, "Expected length 0, got %lu\n", count);
5234 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %lu\n", GetLastError());
5237 /* Test 0-length path */
5238 count = pGetFinalPathNameByHandleA(file, result_path, 0, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
5239 ok(count == strlen(dos_path), "Expected length %u, got %lu\n", lstrlenA(dos_path), count);
5241 /* Test 0 and NULL path */
5242 count = pGetFinalPathNameByHandleA(file, NULL, 0, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
5243 ok(count == strlen(dos_path), "Expected length %u, got %lu\n", lstrlenA(dos_path), count);
5245 /* Test VOLUME_NAME_DOS with sufficient buffer size */
5246 memset(result_path, 0x11, sizeof(result_path));
5247 count = pGetFinalPathNameByHandleA(file, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
5248 ok(count == strlen(dos_path), "Expected length %lu, got %lu\n", (DWORD)strlen(dos_path), count);
5249 ok(lstrcmpiA(dos_path, result_path) == 0, "Expected %s, got %s\n", dos_path, result_path);
5251 /* Test VOLUME_NAME_DOS with insufficient buffer size */
5252 memset(result_path, 0x11, sizeof(result_path));
5253 count = pGetFinalPathNameByHandleA(file, result_path, strlen(dos_path)-2, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
5254 ok(count == strlen(dos_path), "Expected length %lu, got %lu\n", (DWORD)strlen(dos_path), count);
5255 ok(result_path[0] == 0x11, "Result path was modified\n");
5257 memset(result_path, 0x11, sizeof(result_path));
5258 count = pGetFinalPathNameByHandleA(file, result_path, strlen(dos_path)-1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
5259 ok(count == strlen(dos_path), "Expected length %lu, got %lu\n", (DWORD)strlen(dos_path), count);
5260 ok(result_path[0] == 0x11, "Result path was modified\n");
5262 memset(result_path, 0x11, sizeof(result_path));
5263 count = pGetFinalPathNameByHandleA(file, result_path, strlen(dos_path), FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
5264 ok(count == strlen(dos_path), "Expected length %lu, got %lu\n", (DWORD)strlen(dos_path), count);
5265 ok(result_path[0] == 0x11, "Result path was modified\n");
5267 memset(result_path, 0x11, sizeof(result_path));
5268 count = pGetFinalPathNameByHandleA(file, result_path, strlen(dos_path)+1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
5269 ok(count == strlen(dos_path), "Expected length %lu, got %lu\n", (DWORD)strlen(dos_path), count);
5270 ok(result_path[0] != 0x11, "Result path was not modified\n");
5271 ok(!result_path[strlen(dos_path)], "Expected nullterminated string\n");
5272 ok(result_path[strlen(dos_path)+1] == 0x11, "Buffer overflow\n");
5274 CloseHandle(file);
5277 static void test_GetFinalPathNameByHandleW(void)
5279 static WCHAR prefix[] = {'G','e','t','F','i','n','a','l','P','a','t','h',
5280 'N','a','m','e','B','y','H','a','n','d','l','e','W','\0'};
5281 static WCHAR dos_prefix[] = {'\\','\\','?','\\','\0'};
5282 WCHAR temp_path[MAX_PATH], test_path[MAX_PATH];
5283 WCHAR long_path[MAX_PATH], result_path[MAX_PATH];
5284 WCHAR dos_path[MAX_PATH + sizeof(dos_prefix)];
5285 WCHAR drive_part[MAX_PATH];
5286 WCHAR *file_part;
5287 WCHAR volume_path[MAX_PATH + 50];
5288 WCHAR nt_path[2 * MAX_PATH];
5289 BOOL success;
5290 HANDLE file;
5291 DWORD count;
5292 UINT ret;
5294 if (!pGetFinalPathNameByHandleW)
5296 win_skip("GetFinalPathNameByHandleW is missing\n");
5297 return;
5300 /* Test calling with INVALID_HANDLE_VALUE */
5301 SetLastError(0xdeadbeaf);
5302 count = pGetFinalPathNameByHandleW(INVALID_HANDLE_VALUE, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
5303 ok(count == 0, "Expected length 0, got %lu\n", count);
5304 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %lu\n", GetLastError());
5306 count = pGetFinalPathNameByHandleW(INVALID_HANDLE_VALUE, NULL, 0, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
5307 ok(count == 0, "Expected length 0, got %lu\n", count);
5308 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %lu\n", GetLastError());
5310 count = GetTempPathW(MAX_PATH, temp_path);
5311 ok(count, "Failed to get temp path, error %lu\n", GetLastError());
5312 ret = GetTempFileNameW(temp_path, prefix, 0, test_path);
5313 ok(ret != 0, "GetTempFileNameW error %lu\n", GetLastError());
5314 ret = GetLongPathNameW(test_path, long_path, MAX_PATH);
5315 ok(ret != 0, "GetLongPathNameW error %lu\n", GetLastError());
5316 lstrcpyW(dos_path, dos_prefix);
5317 lstrcatW(dos_path, long_path);
5319 file = CreateFileW(test_path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
5320 CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0);
5321 ok(file != INVALID_HANDLE_VALUE, "CreateFileW error %lu\n", GetLastError());
5323 if (0) {
5324 /* Windows crashes on NULL path */
5325 count = pGetFinalPathNameByHandleW(file, NULL, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
5326 ok(count == 0, "Expected length 0, got %lu\n", count);
5327 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %lu\n", GetLastError());
5330 /* Test 0-length path */
5331 count = pGetFinalPathNameByHandleW(file, result_path, 0, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
5332 ok(count == lstrlenW(dos_path) + 1 ||
5333 broken(count == lstrlenW(dos_path) + 2), "Expected length %u, got %lu\n", lstrlenW(dos_path) + 1, count);
5335 /* Test 0 and NULL path */
5336 count = pGetFinalPathNameByHandleW(file, NULL, 0, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
5337 ok(count == lstrlenW(dos_path) + 1 ||
5338 broken(count == lstrlenW(dos_path) + 2), "Expected length %u, got %lu\n", lstrlenW(dos_path) + 1, count);
5340 /* Test VOLUME_NAME_DOS with sufficient buffer size */
5341 memset(result_path, 0x11, sizeof(result_path));
5342 count = pGetFinalPathNameByHandleW(file, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
5343 ok(count == lstrlenW(dos_path), "Expected length %u, got %lu\n", lstrlenW(dos_path), count);
5344 ok(lstrcmpiW(dos_path, result_path) == 0, "Expected %s, got %s\n", wine_dbgstr_w(dos_path), wine_dbgstr_w(result_path));
5346 /* Test VOLUME_NAME_DOS with insufficient buffer size */
5347 memset(result_path, 0x11, sizeof(result_path));
5348 count = pGetFinalPathNameByHandleW(file, result_path, lstrlenW(dos_path)-1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
5349 ok(count == lstrlenW(dos_path) + 1, "Expected length %u, got %lu\n", lstrlenW(dos_path) + 1, count);
5350 ok(result_path[0] == 0x1111, "Result path was modified\n");
5352 memset(result_path, 0x11, sizeof(result_path));
5353 count = pGetFinalPathNameByHandleW(file, result_path, lstrlenW(dos_path), FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
5354 ok(count == lstrlenW(dos_path) + 1, "Expected length %u, got %lu\n", lstrlenW(dos_path) + 1, count);
5355 ok(result_path[0] == 0x1111, "Result path was modified\n");
5357 memset(result_path, 0x11, sizeof(result_path));
5358 count = pGetFinalPathNameByHandleW(file, result_path, lstrlenW(dos_path)+1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
5359 ok(count == lstrlenW(dos_path), "Expected length %u, got %lu\n", lstrlenW(dos_path), count);
5360 ok(result_path[0] != 0x1111, "Result path was not modified\n");
5361 ok(!result_path[lstrlenW(dos_path)], "Expected nullterminated string\n");
5362 ok(result_path[lstrlenW(dos_path)+1] == 0x1111, "Buffer overflow\n");
5364 success = GetVolumePathNameW(long_path, drive_part, MAX_PATH);
5365 ok(success, "GetVolumePathNameW error %lu\n", GetLastError());
5366 success = GetVolumeNameForVolumeMountPointW(drive_part, volume_path, ARRAY_SIZE(volume_path));
5367 ok(success, "GetVolumeNameForVolumeMountPointW error %lu\n", GetLastError());
5369 /* Test for VOLUME_NAME_GUID */
5370 lstrcatW(volume_path, long_path + lstrlenW(drive_part));
5371 memset(result_path, 0x11, sizeof(result_path));
5372 count = pGetFinalPathNameByHandleW(file, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_GUID);
5373 ok(count == lstrlenW(volume_path), "Expected length %u, got %lu\n", lstrlenW(volume_path), count);
5374 ok(lstrcmpiW(volume_path, result_path) == 0, "Expected %s, got %s\n",
5375 wine_dbgstr_w(volume_path), wine_dbgstr_w(result_path));
5377 /* Test for VOLUME_NAME_NONE */
5378 file_part = long_path + lstrlenW(drive_part) - 1;
5379 memset(result_path, 0x11, sizeof(result_path));
5380 count = pGetFinalPathNameByHandleW(file, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_NONE);
5381 ok(count == lstrlenW(file_part), "Expected length %u, got %lu\n", lstrlenW(file_part), count);
5382 ok(lstrcmpiW(file_part, result_path) == 0, "Expected %s, got %s\n",
5383 wine_dbgstr_w(file_part), wine_dbgstr_w(result_path));
5385 drive_part[lstrlenW(drive_part)-1] = 0;
5386 success = QueryDosDeviceW(drive_part, nt_path, ARRAY_SIZE(nt_path));
5387 ok(success, "QueryDosDeviceW error %lu\n", GetLastError());
5389 /* Test for VOLUME_NAME_NT */
5390 lstrcatW(nt_path, file_part);
5391 memset(result_path, 0x11, sizeof(result_path));
5392 count = pGetFinalPathNameByHandleW(file, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_NT);
5393 ok(count == lstrlenW(nt_path), "Expected length %u, got %lu\n", lstrlenW(nt_path), count);
5394 ok(lstrcmpiW(nt_path, result_path) == 0, "Expected %s, got %s\n",
5395 wine_dbgstr_w(nt_path), wine_dbgstr_w(result_path));
5397 CloseHandle(file);
5400 static void test_SetFileInformationByHandle(void)
5402 FILE_ATTRIBUTE_TAG_INFO fileattrinfo = { 0 };
5403 FILE_REMOTE_PROTOCOL_INFO protinfo = { 0 };
5404 FILE_STANDARD_INFO stdinfo = { {{0}},{{0}},0,FALSE,FALSE };
5405 FILE_COMPRESSION_INFO compressinfo;
5406 FILE_DISPOSITION_INFO dispinfo;
5407 DECLSPEC_ALIGN(8) FILE_IO_PRIORITY_HINT_INFO hintinfo;
5408 FILE_BASIC_INFO basicinfo = { {{0}} };
5409 char tempFileName[MAX_PATH];
5410 char tempPath[MAX_PATH];
5411 LARGE_INTEGER atime;
5412 HANDLE file;
5413 BOOL ret;
5415 if (!pSetFileInformationByHandle)
5417 win_skip("SetFileInformationByHandle is not supported\n");
5418 return;
5421 ret = GetTempPathA(sizeof(tempPath), tempPath);
5422 ok(ret, "GetTempPathA failed, got error %lu.\n", GetLastError());
5424 /* ensure the existence of a file in the temp folder */
5425 ret = GetTempFileNameA(tempPath, "abc", 0, tempFileName);
5426 ok(ret, "GetTempFileNameA failed, got error %lu.\n", GetLastError());
5428 file = CreateFileA(tempFileName, GENERIC_READ | FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
5429 NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL);
5430 ok(file != INVALID_HANDLE_VALUE, "failed to open the temp file, error %lu.\n", GetLastError());
5432 /* invalid classes */
5433 SetLastError(0xdeadbeef);
5434 ret = pSetFileInformationByHandle(file, FileStandardInfo, &stdinfo, sizeof(stdinfo));
5435 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError());
5437 memset(&compressinfo, 0, sizeof(compressinfo));
5438 SetLastError(0xdeadbeef);
5439 ret = pSetFileInformationByHandle(file, FileCompressionInfo, &compressinfo, sizeof(compressinfo));
5440 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError());
5442 SetLastError(0xdeadbeef);
5443 ret = pSetFileInformationByHandle(file, FileAttributeTagInfo, &fileattrinfo, sizeof(fileattrinfo));
5444 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError());
5446 SetLastError(0xdeadbeef);
5447 hintinfo.PriorityHint = MaximumIoPriorityHintType;
5448 ret = pSetFileInformationByHandle(file, FileIoPriorityHintInfo, &hintinfo, sizeof(hintinfo));
5449 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError());
5451 hintinfo.PriorityHint = IoPriorityHintNormal;
5452 ret = pSetFileInformationByHandle(file, FileIoPriorityHintInfo, &hintinfo, sizeof(hintinfo));
5453 ok(ret, "setting FileIoPriorityHintInfo got %d, error %ld\n", ret, GetLastError());
5455 hintinfo.PriorityHint = IoPriorityHintVeryLow;
5456 ret = pSetFileInformationByHandle(file, FileIoPriorityHintInfo, &hintinfo, sizeof(hintinfo));
5457 ok(ret, "setting FileIoPriorityHintInfo got %d, error %ld\n", ret, GetLastError());
5459 SetLastError(0xdeadbeef);
5460 ret = pSetFileInformationByHandle(file, FileIoPriorityHintInfo, &hintinfo, sizeof(hintinfo) - 1);
5461 ok(!ret && GetLastError() == ERROR_BAD_LENGTH, "got %d, error %ld\n", ret, GetLastError());
5463 SetLastError(0xdeadbeef);
5464 hintinfo.PriorityHint = IoPriorityHintVeryLow - 1;
5465 ret = pSetFileInformationByHandle(file, FileIoPriorityHintInfo, &hintinfo, sizeof(hintinfo));
5466 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError());
5468 memset(&protinfo, 0, sizeof(protinfo));
5469 protinfo.StructureVersion = 1;
5470 protinfo.StructureSize = sizeof(protinfo);
5471 SetLastError(0xdeadbeef);
5472 ret = pSetFileInformationByHandle(file, FileRemoteProtocolInfo, &protinfo, sizeof(protinfo));
5473 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError());
5475 /* test FileDispositionInfo, additional details already covered by ntdll tests */
5476 SetLastError(0xdeadbeef);
5477 ret = pSetFileInformationByHandle(file, FileDispositionInfo, &dispinfo, 0);
5478 todo_wine
5479 ok(!ret && GetLastError() == ERROR_BAD_LENGTH, "got %d, error %ld\n", ret, GetLastError());
5481 SetLastError(0xdeadbeef);
5482 ret = pSetFileInformationByHandle(file, FileBasicInfo, &basicinfo, 0);
5483 todo_wine
5484 ok(!ret && GetLastError() == ERROR_BAD_LENGTH, "got %d, error %ld\n", ret, GetLastError());
5486 memset(&basicinfo, 0, sizeof(basicinfo));
5487 ret = pGetFileInformationByHandleEx(file, FileBasicInfo, &basicinfo, sizeof(basicinfo));
5488 ok(ret, "Failed to get basic info, error %ld.\n", GetLastError());
5489 atime = basicinfo.LastAccessTime;
5491 basicinfo.LastAccessTime.QuadPart++;
5492 ret = pSetFileInformationByHandle(file, FileBasicInfo, &basicinfo, sizeof(basicinfo));
5493 ok(ret, "Failed to set basic info, error %ld.\n", GetLastError());
5495 memset(&basicinfo, 0, sizeof(basicinfo));
5496 ret = pGetFileInformationByHandleEx(file, FileBasicInfo, &basicinfo, sizeof(basicinfo));
5497 ok(ret, "Failed to get basic info, error %ld.\n", GetLastError());
5498 ok(atime.QuadPart + 1 == basicinfo.LastAccessTime.QuadPart, "Unexpected access time.\n");
5500 memset(&basicinfo, 0, sizeof(basicinfo));
5501 basicinfo.LastAccessTime.QuadPart = -1;
5502 ret = pSetFileInformationByHandle(file, FileBasicInfo, &basicinfo, sizeof(basicinfo));
5503 ok(ret, "Failed to set basic info, error %ld.\n", GetLastError());
5505 memset(&basicinfo, 0, sizeof(basicinfo));
5506 ret = pGetFileInformationByHandleEx(file, FileBasicInfo, &basicinfo, sizeof(basicinfo));
5507 ok(ret, "Failed to get basic info, error %ld.\n", GetLastError());
5508 ok(atime.QuadPart + 1 == basicinfo.LastAccessTime.QuadPart, "Unexpected access time.\n");
5510 dispinfo.DeleteFile = TRUE;
5511 ret = pSetFileInformationByHandle(file, FileDispositionInfo, &dispinfo, sizeof(dispinfo));
5512 ok(ret, "setting FileDispositionInfo failed, error %ld\n", GetLastError());
5514 CloseHandle(file);
5517 static void test_SetFileRenameInfo(void)
5519 WCHAR tempFileFrom[MAX_PATH], tempFileTo1[MAX_PATH], tempFileTo2[MAX_PATH];
5520 WCHAR tempPath[MAX_PATH];
5521 FILE_RENAME_INFORMATION *fri;
5522 HANDLE file;
5523 DWORD size;
5524 BOOL ret;
5526 if (!pSetFileInformationByHandle)
5528 win_skip("SetFileInformationByHandle is not supported\n");
5529 return;
5532 ret = GetTempPathW(MAX_PATH, tempPath);
5533 ok(ret, "GetTempPathW failed, got error %lu.\n", GetLastError());
5535 ret = GetTempFileNameW(tempPath, L"abc", 0, tempFileFrom);
5536 ok(ret, "GetTempFileNameW failed, got error %lu.\n", GetLastError());
5538 ret = GetTempFileNameW(tempPath, L"abc", 0, tempFileTo1);
5539 ok(ret, "GetTempFileNameW failed, got error %lu.\n", GetLastError());
5541 ret = GetTempFileNameW(tempPath, L"abc", 1, tempFileTo2);
5542 ok(ret, "GetTempFileNameW failed, got error %lu.\n", GetLastError());
5544 file = CreateFileW(tempFileFrom, GENERIC_READ | GENERIC_WRITE | DELETE, 0, 0, OPEN_EXISTING, 0, 0);
5545 ok(file != INVALID_HANDLE_VALUE, "failed to create temp file, error %lu.\n", GetLastError());
5547 size = sizeof(FILE_RENAME_INFORMATION) + MAX_PATH;
5548 fri = HeapAlloc(GetProcessHeap(), 0, size);
5550 fri->ReplaceIfExists = FALSE;
5551 fri->RootDirectory = NULL;
5552 fri->FileNameLength = wcslen(tempFileTo1) * sizeof(WCHAR);
5553 memcpy(fri->FileName, tempFileTo1, fri->FileNameLength + sizeof(WCHAR));
5554 ret = pSetFileInformationByHandle(file, FileRenameInfo, fri, size);
5555 ok(!ret && GetLastError() == ERROR_ALREADY_EXISTS, "FileRenameInfo unexpected result %ld\n", GetLastError());
5557 fri->ReplaceIfExists = TRUE;
5558 ret = pSetFileInformationByHandle(file, FileRenameInfo, fri, size);
5559 ok(ret, "FileRenameInfo failed, error %ld\n", GetLastError());
5561 fri->ReplaceIfExists = FALSE;
5562 fri->FileNameLength = wcslen(tempFileTo2) * sizeof(WCHAR);
5563 memcpy(fri->FileName, tempFileTo2, fri->FileNameLength + sizeof(WCHAR));
5564 ret = pSetFileInformationByHandle(file, FileRenameInfo, fri, size);
5565 ok(ret, "FileRenameInfo failed, error %ld\n", GetLastError());
5566 CloseHandle(file);
5568 file = CreateFileW(tempFileTo2, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
5569 ok(file != INVALID_HANDLE_VALUE, "file not renamed, error %ld\n", GetLastError());
5571 fri->FileNameLength = wcslen(tempFileTo1) * sizeof(WCHAR);
5572 memcpy(fri->FileName, tempFileTo1, fri->FileNameLength + sizeof(WCHAR));
5573 ret = pSetFileInformationByHandle(file, FileRenameInfo, fri, size);
5574 todo_wine
5575 ok(!ret && GetLastError() == ERROR_ACCESS_DENIED, "FileRenameInfo unexpected result %ld\n", GetLastError());
5576 CloseHandle(file);
5578 HeapFree(GetProcessHeap(), 0, fri);
5579 DeleteFileW(tempFileFrom);
5580 DeleteFileW(tempFileTo1);
5581 DeleteFileW(tempFileTo2);
5584 static void test_GetFileAttributesExW(void)
5586 static const struct
5588 const WCHAR *path;
5589 DWORD expected_error;
5591 tests[] =
5593 {L"\\\\?\\", ERROR_INVALID_NAME},
5594 {L"\\??\\", ERROR_INVALID_NAME},
5595 {L"\\DosDevices\\", ERROR_FILE_NOT_FOUND},
5596 {L"\\\\?\\C:\\windows\\system32\\..\\system32\\kernel32.dll", ERROR_INVALID_NAME},
5598 WIN32_FILE_ATTRIBUTE_DATA info;
5599 DWORD error, test_idx;
5600 BOOL ret;
5602 for (test_idx = 0; test_idx < ARRAY_SIZE(tests); ++test_idx)
5604 winetest_push_context("Test %lu", test_idx);
5606 SetLastError(0xdeadbeef);
5607 ret = GetFileAttributesExW(tests[test_idx].path, GetFileExInfoStandard, &info);
5608 error = GetLastError();
5609 ok(!ret, "GetFileAttributesExW succeeded\n");
5610 ok(error == tests[test_idx].expected_error, "Expected error %lu, got %lu\n",
5611 tests[test_idx].expected_error, error);
5613 winetest_pop_context();
5617 static void test_post_completion(void)
5619 OVERLAPPED ovl, ovl2, *povl;
5620 OVERLAPPED_ENTRY entries[2];
5621 ULONG_PTR key;
5622 HANDLE port;
5623 ULONG count;
5624 DWORD size;
5625 BOOL ret;
5627 port = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 999, 0 );
5628 ok(port != NULL, "CreateIoCompletionPort failed: %lu\n", GetLastError());
5630 ret = GetQueuedCompletionStatus( port, &size, &key, &povl, 0 );
5631 ok(!ret, "GetQueuedCompletionStatus succeeded\n");
5632 ok(GetLastError() == WAIT_TIMEOUT, "wrong error %lu\n", GetLastError());
5634 ret = PostQueuedCompletionStatus( port, 123, 456, &ovl );
5635 ok(ret, "PostQueuedCompletionStatus failed: %lu\n", GetLastError());
5637 ret = GetQueuedCompletionStatus( port, &size, &key, &povl, 0 );
5638 ok(ret, "GetQueuedCompletionStatus failed: %lu\n", GetLastError());
5639 ok(size == 123, "wrong size %lu\n", size);
5640 ok(key == 456, "wrong key %Iu\n", key);
5641 ok(povl == &ovl, "wrong ovl %p\n", povl);
5643 ret = GetQueuedCompletionStatus( port, &size, &key, &povl, 0 );
5644 ok(!ret, "GetQueuedCompletionStatus succeeded\n");
5645 ok(GetLastError() == WAIT_TIMEOUT, "wrong error %lu\n", GetLastError());
5647 if (!pGetQueuedCompletionStatusEx)
5649 win_skip("GetQueuedCompletionStatusEx not available\n");
5650 CloseHandle( port );
5651 return;
5654 count = 0xdeadbeef;
5655 ret = pGetQueuedCompletionStatusEx( port, entries, 2, &count, 0, FALSE );
5656 ok(!ret, "GetQueuedCompletionStatusEx succeeded\n");
5657 ok(GetLastError() == WAIT_TIMEOUT, "wrong error %lu\n", GetLastError());
5658 ok(count <= 1, "wrong count %lu\n", count);
5660 ret = PostQueuedCompletionStatus( port, 123, 456, &ovl );
5661 ok(ret, "PostQueuedCompletionStatus failed: %lu\n", GetLastError());
5663 count = 0xdeadbeef;
5664 memset( entries, 0xcc, sizeof(entries) );
5665 ret = pGetQueuedCompletionStatusEx( port, entries, 2, &count, 0, FALSE );
5666 ok(ret, "GetQueuedCompletionStatusEx failed\n");
5667 ok(count == 1, "wrong count %lu\n", count);
5668 ok(entries[0].lpCompletionKey == 456, "wrong key %Iu\n", entries[0].lpCompletionKey);
5669 ok(entries[0].lpOverlapped == &ovl, "wrong ovl %p\n", entries[0].lpOverlapped);
5670 ok(!(ULONG)entries[0].Internal, "wrong internal %#lx\n", (ULONG)entries[0].Internal);
5671 ok(entries[0].dwNumberOfBytesTransferred == 123, "wrong size %lu\n", entries[0].dwNumberOfBytesTransferred);
5673 ret = PostQueuedCompletionStatus( port, 123, 456, &ovl );
5674 ok(ret, "PostQueuedCompletionStatus failed: %lu\n", GetLastError());
5676 ret = PostQueuedCompletionStatus( port, 654, 321, &ovl2 );
5677 ok(ret, "PostQueuedCompletionStatus failed: %lu\n", GetLastError());
5679 count = 0xdeadbeef;
5680 memset( entries, 0xcc, sizeof(entries) );
5681 ret = pGetQueuedCompletionStatusEx( port, entries, 2, &count, 0, FALSE );
5682 ok(ret, "GetQueuedCompletionStatusEx failed\n");
5683 ok(count == 2, "wrong count %lu\n", count);
5684 ok(entries[0].lpCompletionKey == 456, "wrong key %Iu\n", entries[0].lpCompletionKey);
5685 ok(entries[0].lpOverlapped == &ovl, "wrong ovl %p\n", entries[0].lpOverlapped);
5686 ok(!(ULONG)entries[0].Internal, "wrong internal %#lx\n", (ULONG)entries[0].Internal);
5687 ok(entries[0].dwNumberOfBytesTransferred == 123, "wrong size %lu\n", entries[0].dwNumberOfBytesTransferred);
5688 ok(entries[1].lpCompletionKey == 321, "wrong key %Iu\n", entries[1].lpCompletionKey);
5689 ok(entries[1].lpOverlapped == &ovl2, "wrong ovl %p\n", entries[1].lpOverlapped);
5690 ok(!(ULONG)entries[1].Internal, "wrong internal %#lx\n", (ULONG)entries[1].Internal);
5691 ok(entries[1].dwNumberOfBytesTransferred == 654, "wrong size %lu\n", entries[1].dwNumberOfBytesTransferred);
5693 user_apc_ran = FALSE;
5694 QueueUserAPC( user_apc, GetCurrentThread(), 0 );
5696 ret = pGetQueuedCompletionStatusEx( port, entries, 2, &count, 0, FALSE );
5697 ok(!ret, "GetQueuedCompletionStatusEx succeeded\n");
5698 ok(GetLastError() == WAIT_TIMEOUT, "wrong error %lu\n", GetLastError());
5699 ok(count <= 1, "wrong count %lu\n", count);
5700 ok(!user_apc_ran, "user APC should not have run\n");
5702 ret = pGetQueuedCompletionStatusEx( port, entries, 2, &count, 0, TRUE );
5703 ok(!ret || broken(ret) /* Vista */, "GetQueuedCompletionStatusEx succeeded\n");
5704 if (!ret)
5705 ok(GetLastError() == WAIT_IO_COMPLETION, "wrong error %lu\n", GetLastError());
5706 ok(count <= 1, "wrong count %lu\n", count);
5707 ok(user_apc_ran, "user APC should have run\n");
5709 user_apc_ran = FALSE;
5710 QueueUserAPC( user_apc, GetCurrentThread(), 0 );
5712 ret = PostQueuedCompletionStatus( port, 123, 456, &ovl );
5713 ok(ret, "PostQueuedCompletionStatus failed: %lu\n", GetLastError());
5715 ret = pGetQueuedCompletionStatusEx( port, entries, 2, &count, 0, TRUE );
5716 ok(ret, "GetQueuedCompletionStatusEx failed\n");
5717 ok(count == 1, "wrong count %lu\n", count);
5718 ok(!user_apc_ran, "user APC should not have run\n");
5720 SleepEx(0, TRUE);
5722 CloseHandle( port );
5725 #define TEST_OVERLAPPED_READ_SIZE 4096
5727 static void test_overlapped_read(void)
5729 DECLSPEC_ALIGN(TEST_OVERLAPPED_READ_SIZE) static unsigned char buffer[TEST_OVERLAPPED_READ_SIZE];
5730 static const char prefix[] = "pfx";
5731 char temp_path[MAX_PATH];
5732 char file_name[MAX_PATH];
5733 DWORD bytes_count;
5734 OVERLAPPED ov;
5735 HANDLE hfile;
5736 DWORD err;
5737 DWORD ret;
5739 ret = GetTempPathA(MAX_PATH, temp_path);
5740 ok(ret, "Unexpected error %lu.\n", GetLastError());
5741 ret = GetTempFileNameA(temp_path, prefix, 0, file_name);
5742 ok(ret, "Unexpected error %lu.\n", GetLastError());
5744 hfile = CreateFileA(file_name, GENERIC_WRITE, 0,
5745 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL);
5746 ok(hfile != INVALID_HANDLE_VALUE, "Failed to create file, GetLastError() %lu.\n", GetLastError());
5747 memset(buffer, 0x55, sizeof(buffer));
5748 ret = WriteFile(hfile, buffer, TEST_OVERLAPPED_READ_SIZE, &bytes_count, NULL);
5749 ok(ret && bytes_count == TEST_OVERLAPPED_READ_SIZE,
5750 "Unexpected WriteFile result, ret %#lx, bytes_count %lu, GetLastError() %lu.\n",
5751 ret, bytes_count, GetLastError());
5752 CloseHandle(hfile);
5754 hfile = CreateFileA(file_name, GENERIC_READ, FILE_SHARE_READ,
5755 NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL);
5756 ok(hfile != INVALID_HANDLE_VALUE, "Failed to create file, GetLastError() %lu.\n", GetLastError());
5758 memset(&ov, 0, sizeof(ov));
5760 bytes_count = 0xffffffff;
5761 ret = ReadFile(hfile, buffer, TEST_OVERLAPPED_READ_SIZE, &bytes_count, &ov);
5762 ok(!ret && GetLastError() == ERROR_IO_PENDING,
5763 "Unexpected ReadFile result, ret %#lx, GetLastError() %lu.\n", ret, GetLastError());
5764 ok(!bytes_count, "Unexpected read size %lu.\n", bytes_count);
5765 ret = GetOverlappedResult(hfile, &ov, &bytes_count, TRUE);
5766 ok(ret, "Unexpected error %lu.\n", GetLastError());
5767 ok(bytes_count == TEST_OVERLAPPED_READ_SIZE, "Unexpected read size %lu.\n", bytes_count);
5769 ov.Offset = bytes_count;
5770 ret = ReadFile(hfile, buffer, TEST_OVERLAPPED_READ_SIZE, &bytes_count, &ov);
5771 err = GetLastError();
5772 /* Win8+ return ERROR_IO_PENDING like stated in MSDN, while older ones
5773 * return ERROR_HANDLE_EOF right away. */
5774 ok(!ret && (err == ERROR_IO_PENDING || broken(err == ERROR_HANDLE_EOF)),
5775 "Unexpected ReadFile result, ret %#lx, GetLastError() %lu.\n", ret, GetLastError());
5776 if (err == ERROR_IO_PENDING)
5778 ret = GetOverlappedResult(hfile, &ov, &bytes_count, TRUE);
5779 ok(!ret && GetLastError() == ERROR_HANDLE_EOF, "Unexpected result %#lx, GetLasttError() %lu.\n",
5780 ret, GetLastError());
5782 ok(!bytes_count, "Unexpected read size %lu.\n", bytes_count);
5784 CloseHandle(hfile);
5785 ret = DeleteFileA(file_name);
5786 ok(ret, "Unexpected error %lu.\n", GetLastError());
5789 static void test_file_readonly_access(void)
5791 static const DWORD default_sharing = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
5792 static const CHAR prefix[] = "pfx";
5793 CHAR file_name[MAX_PATH], file_name2[MAX_PATH];
5794 CHAR temp_path[MAX_PATH];
5795 HANDLE handle;
5796 DWORD error;
5797 DWORD ret;
5799 /* Set up */
5800 ret = GetTempPathA(MAX_PATH, temp_path);
5801 ok(ret != 0, "GetTempPathA error %ld\n", GetLastError());
5802 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
5804 ret = GetTempFileNameA(temp_path, prefix, 0, file_name);
5805 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
5806 ret = DeleteFileA(file_name);
5807 ok(ret, "expect success\n");
5809 ret = GetTempFileNameA(temp_path, prefix, 0, file_name2);
5810 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError());
5811 ret = DeleteFileA(file_name2);
5812 ok(ret, "expect success\n");
5814 handle = CreateFileA(file_name, 0, default_sharing, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_READONLY, 0);
5815 ok(handle != INVALID_HANDLE_VALUE, "CreateFileA: error %ld\n", GetLastError());
5816 CloseHandle(handle);
5818 /* CreateFile GENERIC_WRITE */
5819 SetLastError(0xdeadbeef);
5820 handle = CreateFileA(file_name, GENERIC_WRITE, default_sharing, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
5821 error = GetLastError();
5822 ok(handle == INVALID_HANDLE_VALUE, "expect failure\n");
5823 ok(error == ERROR_ACCESS_DENIED, "wrong error code: %#lx\n", error);
5825 /* CreateFile DELETE without FILE_FLAG_DELETE_ON_CLOSE */
5826 handle = CreateFileA(file_name, DELETE, default_sharing, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
5827 ok(handle != INVALID_HANDLE_VALUE, "expect success\n");
5828 CloseHandle(handle);
5830 /* CreateFile DELETE with FILE_FLAG_DELETE_ON_CLOSE */
5831 SetLastError(0xdeadbeef);
5832 handle = CreateFileA(file_name, DELETE, default_sharing, NULL, OPEN_EXISTING,
5833 FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_NORMAL, 0);
5834 error = GetLastError();
5835 ok(handle == INVALID_HANDLE_VALUE, "expect failure\n");
5836 ok(error == ERROR_ACCESS_DENIED, "wrong error code: %#lx\n", error);
5838 ret = MoveFileA(file_name, file_name2);
5839 ok(ret, "expect success\n");
5840 ret = MoveFileA(file_name2, file_name);
5841 ok(ret, "expect success\n");
5843 SetLastError(0xdeadbeef);
5844 ret = DeleteFileA(file_name);
5845 error = GetLastError();
5846 ok(!ret, "expect failure\n");
5847 ok(error == ERROR_ACCESS_DENIED, "wrong error code: %#lx\n", error);
5849 ret = GetFileAttributesA(file_name);
5850 ok(ret & FILE_ATTRIBUTE_READONLY, "got wrong attribute: %#lx.\n", ret);
5852 /* Clean up */
5853 SetFileAttributesA(file_name, FILE_ATTRIBUTE_NORMAL);
5854 ret = DeleteFileA(file_name);
5855 ok(ret, "DeleteFileA: error %ld\n", GetLastError());
5858 static void test_find_file_stream(void)
5860 WCHAR path[] = {'C',':','\\','w','i','n','d','o','w','s',0};
5861 HANDLE handle;
5862 int error;
5863 WIN32_FIND_STREAM_DATA data;
5865 if (!pFindFirstStreamW)
5867 win_skip("FindFirstStreamW is missing\n");
5868 return;
5871 SetLastError(0xdeadbeef);
5872 handle = pFindFirstStreamW(path, FindStreamInfoStandard, &data, 0);
5873 error = GetLastError();
5874 ok(handle == INVALID_HANDLE_VALUE, "Expected INVALID_HANDLE_VALUE, got %p\n", handle);
5875 ok(error == ERROR_HANDLE_EOF, "Expected ERROR_HANDLE_EOF, got %d\n", error);
5878 static void test_SetFileTime(void)
5880 static const WCHAR prefix[] = {'p','f','x',0};
5881 WCHAR path[MAX_PATH], temp_path[MAX_PATH];
5882 FILETIME ft1, ft2;
5883 DWORD ret, len;
5884 HANDLE hfile;
5886 ret = GetTempPathW(MAX_PATH, temp_path);
5887 ok(ret != 0, "GetTempPathW error %ld\n", GetLastError());
5888 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
5890 ret = GetTempFileNameW(temp_path, prefix, 0, path);
5891 ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError());
5893 hfile = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0);
5894 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
5895 ret = WriteFile(hfile, prefix, sizeof(prefix), &len, NULL );
5896 ok(ret && len == sizeof(prefix), "WriteFile error %ld\n", GetLastError());
5897 ok(GetFileSize(hfile, NULL) == sizeof(prefix), "source file has wrong size\n");
5899 ret = GetFileTime(hfile, NULL, NULL, &ft1);
5900 ok(ret, "GetFileTime error %ld\n", GetLastError());
5901 ft2 = ft1;
5902 ft2.dwLowDateTime -= 600000000; /* 60 second */
5903 ret = SetFileTime(hfile, NULL, NULL, &ft2);
5904 ok(ret, "SetFileTime error %ld\n", GetLastError());
5905 memset(&ft2, 0, sizeof(ft2));
5906 ret = GetFileTime(hfile, NULL, NULL, &ft2); /* get the actual time back */
5907 ok(ret, "GetFileTime error %ld\n", GetLastError());
5908 ok(memcmp(&ft1, &ft2, sizeof(ft1)), "Unexpected write time.\n");
5910 memset(&ft1, 0xff, sizeof(ft1));
5911 ret = SetFileTime(hfile, NULL, NULL, &ft1);
5912 ok(ret, "SetFileTime error %ld\n", GetLastError());
5913 memset(&ft1, 0, sizeof(ft1));
5914 ret = GetFileTime(hfile, NULL, NULL, &ft1); /* get the actual time back */
5915 ok(ret, "GetFileTime error %ld\n", GetLastError());
5916 ok(!memcmp(&ft1, &ft2, sizeof(ft1)), "Unexpected write time.\n");
5918 CloseHandle(hfile);
5921 static void test_hard_link(void)
5923 char cwd[MAX_PATH], temp_dir[MAX_PATH], name_buffer[200], buffer[20];
5924 FILE_NAME_INFORMATION *name_info = (FILE_NAME_INFORMATION *)name_buffer;
5925 IO_STATUS_BLOCK io;
5926 NTSTATUS status;
5927 HANDLE file;
5928 DWORD size;
5929 BOOL ret;
5931 GetCurrentDirectoryA( sizeof(cwd), cwd );
5932 GetTempPathA( sizeof(temp_dir), temp_dir );
5933 SetCurrentDirectoryA( temp_dir );
5935 ret = CreateDirectoryA( "winetest_dir1", NULL );
5936 ok(ret, "failed to create directory, error %lu\n", GetLastError());
5937 ret = CreateDirectoryA( "winetest_dir2", NULL );
5938 ok(ret, "failed to create directory, error %lu\n", GetLastError());
5939 create_file( "winetest_file1" );
5940 create_file( "winetest_file2" );
5942 ret = CreateHardLinkA( "winetest_file3", "winetest_file1", NULL );
5943 ok(ret, "got error %lu\n", GetLastError());
5945 file = CreateFileA( "winetest_file3", FILE_READ_DATA, 0, NULL, OPEN_EXISTING, 0, NULL );
5946 ok(file != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError());
5948 status = NtQueryInformationFile( file, &io, name_buffer, sizeof(name_buffer), FileNameInformation );
5949 ok(!status, "got status %#lx\n", status);
5950 ok(!wcsncmp(name_info->FileName + (name_info->FileNameLength / sizeof(WCHAR)) - wcslen(L"\\winetest_file3"),
5951 L"\\winetest_file3", wcslen(L"\\winetest_file3")), "got name %s\n",
5952 debugstr_wn(name_info->FileName, name_info->FileNameLength / sizeof(WCHAR)));
5954 ret = ReadFile( file, buffer, sizeof(buffer), &size, NULL );
5955 ok(ret, "got error %lu\n", GetLastError());
5956 ok(!memcmp( buffer, "winetest_file1", size ), "got file contents %s\n", debugstr_an( buffer, size ));
5958 CloseHandle( file );
5960 ret = DeleteFileA( "winetest_file3" );
5961 ok(ret, "failed to delete file, error %lu\n", GetLastError());
5963 SetLastError(0xdeadbeef);
5964 ret = CreateHardLinkA( "winetest_file2", "winetest_file1", NULL );
5965 ok(!ret, "expected failure\n");
5966 ok(GetLastError() == ERROR_ALREADY_EXISTS, "got error %lu\n", GetLastError());
5968 SetLastError(0xdeadbeef);
5969 ret = CreateHardLinkA( "WineTest_File1", "winetest_file1", NULL );
5970 ok(!ret, "expected failure\n");
5971 ok(GetLastError() == ERROR_ALREADY_EXISTS, "got error %lu\n", GetLastError());
5973 SetLastError(0xdeadbeef);
5974 ret = CreateHardLinkA( "winetest_file3", "winetest_dir1", NULL );
5975 ok(!ret, "expected failure\n");
5976 ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
5978 SetLastError(0xdeadbeef);
5979 ret = CreateHardLinkA( "winetest_dir2", "winetest_dir1", NULL );
5980 ok(!ret, "expected failure\n");
5981 ok(GetLastError() == ERROR_ACCESS_DENIED
5982 || GetLastError() == ERROR_ALREADY_EXISTS /* XP */, "got error %lu\n", GetLastError());
5984 SetLastError(0xdeadbeef);
5985 ret = CreateHardLinkA( "winetest_dir1", "winetest_file1", NULL );
5986 ok(!ret, "expected failure\n");
5987 ok(GetLastError() == ERROR_ALREADY_EXISTS, "got error %lu\n", GetLastError());
5989 ret = RemoveDirectoryA( "winetest_dir1" );
5990 ok(ret, "failed to remove directory, error %lu\n", GetLastError());
5991 ret = RemoveDirectoryA( "winetest_dir2" );
5992 ok(ret, "failed to remove directory, error %lu\n", GetLastError());
5993 ret = DeleteFileA( "winetest_file1" );
5994 ok(ret, "failed to delete file, error %lu\n", GetLastError());
5995 ret = DeleteFileA( "winetest_file2" );
5996 ok(ret, "failed to delete file, error %lu\n", GetLastError());
5997 SetCurrentDirectoryA( cwd );
6000 static void test_move_file(void)
6002 char cwd[MAX_PATH], temp_dir[MAX_PATH];
6003 HANDLE file;
6004 BOOL ret;
6006 GetCurrentDirectoryA( sizeof(cwd), cwd );
6007 GetTempPathA( sizeof(temp_dir), temp_dir );
6008 SetCurrentDirectoryA( temp_dir );
6010 ret = CreateDirectoryA( "winetest_dir1", NULL );
6011 ok(ret, "failed to create directory, error %lu\n", GetLastError());
6012 ret = CreateDirectoryA( "winetest_dir2", NULL );
6013 ok(ret, "failed to create directory, error %lu\n", GetLastError());
6014 create_file( "winetest_file1" );
6015 create_file( "winetest_file2" );
6017 ret = MoveFileA( "winetest_file1", "winetest_file3" );
6018 ok(ret, "failed to move file, error %lu\n", GetLastError());
6019 ret = GetFileAttributesA( "winetest_file1" );
6020 ok(ret == INVALID_FILE_ATTRIBUTES, "got %#x\n", ret);
6021 ret = GetFileAttributesA( "winetest_file3" );
6022 ok(ret != INVALID_FILE_ATTRIBUTES, "got %#x\n", ret);
6024 SetLastError(0xdeadbeef);
6025 ret = MoveFileA( "winetest_file3", "winetest_file2" );
6026 ok(!ret, "expected failure\n");
6027 ok(GetLastError() == ERROR_ALREADY_EXISTS, "got error %lu\n", GetLastError());
6029 SetLastError(0xdeadbeef);
6030 ret = MoveFileA( "winetest_file1", "winetest_file4" );
6031 ok(!ret, "expected failure\n");
6032 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "got error %lu\n", GetLastError());
6034 ret = MoveFileA( "winetest_dir1", "winetest_dir3" );
6035 ok(ret, "failed to move file, error %lu\n", GetLastError());
6037 SetLastError(0xdeadbeef);
6038 ret = MoveFileA( "winetest_dir3", "winetest_dir2" );
6039 ok(!ret, "expected failure\n");
6040 ok(GetLastError() == ERROR_ALREADY_EXISTS, "got error %lu\n", GetLastError());
6042 file = CreateFileA( "winetest_file3", DELETE, 0, NULL, OPEN_EXISTING, 0, 0 );
6043 ok(file != INVALID_HANDLE_VALUE, "failed to open file, error %lu\n", GetLastError());
6044 ret = MoveFileA( "winetest_file3", "winetest_file1" );
6045 ok(!ret, "expected failure\n");
6046 ok(GetLastError() == ERROR_SHARING_VIOLATION, "got error %lu\n", GetLastError());
6047 CloseHandle( file );
6049 file = CreateFileA( "winetest_file3", 0, 0, NULL, OPEN_EXISTING, 0, 0 );
6050 ok(file != INVALID_HANDLE_VALUE, "failed to open file, error %lu\n", GetLastError());
6051 ret = MoveFileA( "winetest_file3", "winetest_file1" );
6052 ok(ret, "failed to move file, error %lu\n", GetLastError());
6053 ret = GetFileAttributesA( "winetest_file1" );
6054 ok(ret != INVALID_FILE_ATTRIBUTES, "got %#x\n", ret);
6055 ret = GetFileAttributesA( "winetest_file3" );
6056 ok(ret == INVALID_FILE_ATTRIBUTES, "got %#x\n", ret);
6057 CloseHandle( file );
6059 ret = MoveFileExA( "winetest_file1", "winetest_file2", MOVEFILE_REPLACE_EXISTING );
6060 ok(ret, "failed to move file, error %lu\n", GetLastError());
6062 file = CreateFileA( "winetest_file1", GENERIC_ALL,
6063 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, CREATE_NEW, 0, 0 );
6064 ok(file != INVALID_HANDLE_VALUE, "failed to open file, error %lu\n", GetLastError());
6065 SetLastError(0xdeadbeef);
6066 ret = MoveFileExA( "winetest_file2", "winetest_file1", MOVEFILE_REPLACE_EXISTING );
6067 ok(!ret, "expected failure\n");
6068 ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
6069 CloseHandle( file );
6071 SetLastError(0xdeadbeef);
6072 ret = MoveFileExA( "winetest_file2", "winetest_dir2", MOVEFILE_REPLACE_EXISTING );
6073 ok(!ret, "expected failure\n");
6074 ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
6076 SetLastError(0xdeadbeef);
6077 ret = MoveFileExA( "winetest_dir3", "winetest_dir2", MOVEFILE_REPLACE_EXISTING );
6078 ok(!ret, "expected failure\n");
6079 ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
6081 ret = MoveFileExA( "winetest_dir2", "winetest_file2", MOVEFILE_REPLACE_EXISTING );
6082 ok(ret, "failed to move file, error %lu\n", GetLastError());
6084 ret = RemoveDirectoryA( "winetest_dir3" );
6085 ok(ret, "failed to remove directory, error %lu\n", GetLastError());
6086 ret = RemoveDirectoryA( "winetest_file2" );
6087 ok(ret, "failed to remove directory, error %lu\n", GetLastError());
6088 ret = DeleteFileA( "winetest_file1" );
6089 ok(ret, "failed to delete file, error %lu\n", GetLastError());
6090 SetCurrentDirectoryA( cwd );
6093 static void test_eof(void)
6095 char temp_path[MAX_PATH], filename[MAX_PATH], buffer[20];
6096 OVERLAPPED overlapped = {0};
6097 LARGE_INTEGER file_size;
6098 HANDLE file, mapping;
6099 unsigned int i;
6100 void *view;
6101 DWORD size;
6102 BOOL ret;
6104 static const struct
6106 DWORD protection;
6107 DWORD view_access;
6109 map_tests[] =
6111 {PAGE_READONLY, FILE_MAP_READ},
6112 {PAGE_READWRITE, FILE_MAP_WRITE},
6115 GetTempPathA(sizeof(temp_path), temp_path);
6116 GetTempFileNameA(temp_path, "eof", 0, filename);
6118 file = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0);
6119 ok(file != INVALID_HANDLE_VALUE, "failed to create file, error %lu\n", GetLastError());
6121 ret = GetFileSizeEx(file, &file_size);
6122 ok(ret, "failed to get size, error %lu\n", GetLastError());
6123 ok(!file_size.QuadPart, "got size %I64d\n", file_size.QuadPart);
6125 SetFilePointer(file, 2, NULL, SEEK_SET);
6127 ret = GetFileSizeEx(file, &file_size);
6128 ok(ret, "failed to get size, error %lu\n", GetLastError());
6129 ok(!file_size.QuadPart, "got size %I64d\n", file_size.QuadPart);
6131 SetLastError(0xdeadbeef);
6132 ret = ReadFile(file, buffer, sizeof(buffer), &size, NULL);
6133 ok(ret, "failed to read, error %lu\n", GetLastError());
6134 ok(!size, "got size %lu\n", size);
6135 ok(GetLastError() == 0xdeadbeef, "got error %lu\n", GetLastError());
6137 SetFilePointer(file, 2, NULL, SEEK_SET);
6139 SetLastError(0xdeadbeef);
6140 size = 0xdeadbeef;
6141 overlapped.Offset = 2;
6142 ret = ReadFile(file, buffer, sizeof(buffer), &size, &overlapped);
6143 ok(!ret, "expected failure\n");
6144 ok(GetLastError() == ERROR_HANDLE_EOF, "got error %lu\n", GetLastError());
6145 ok(!size, "got size %lu\n", size);
6146 ok((NTSTATUS)overlapped.Internal == STATUS_PENDING || (NTSTATUS)overlapped.Internal == STATUS_END_OF_FILE,
6147 "got status %#lx\n", (NTSTATUS)overlapped.Internal);
6148 ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh);
6150 SetFilePointer(file, 2, NULL, SEEK_SET);
6152 ret = SetEndOfFile(file);
6153 ok(ret, "failed to set EOF, error %lu\n", GetLastError());
6155 ret = GetFileSizeEx(file, &file_size);
6156 ok(ret, "failed to get size, error %lu\n", GetLastError());
6157 ok(file_size.QuadPart == 2, "got size %I64d\n", file_size.QuadPart);
6159 ret = WriteFile(file, "data", 4, &size, NULL);
6160 ok(ret, "failed to write, error %lu\n", GetLastError());
6161 ok(size == 4, "got size %lu\n", size);
6163 ret = GetFileSizeEx(file, &file_size);
6164 ok(ret, "failed to get size, error %lu\n", GetLastError());
6165 ok(file_size.QuadPart == 6, "got size %I64d\n", file_size.QuadPart);
6167 SetFilePointer(file, 4, NULL, SEEK_SET);
6168 ret = SetEndOfFile(file);
6169 ok(ret, "failed to set EOF, error %lu\n", GetLastError());
6171 ret = GetFileSizeEx(file, &file_size);
6172 ok(ret, "failed to get size, error %lu\n", GetLastError());
6173 ok(file_size.QuadPart == 4, "got size %I64d\n", file_size.QuadPart);
6175 SetFilePointer(file, 0, NULL, SEEK_SET);
6176 ret = ReadFile(file, buffer, sizeof(buffer), &size, NULL);
6177 ok(ret, "failed to read, error %lu\n", GetLastError());
6178 ok(size == 4, "got size %lu\n", size);
6179 ok(!memcmp(buffer, "\0\0da", 4), "wrong data\n");
6181 SetFilePointer(file, 6, NULL, SEEK_SET);
6182 ret = SetEndOfFile(file);
6183 ok(ret, "failed to set EOF, error %lu\n", GetLastError());
6185 ret = GetFileSizeEx(file, &file_size);
6186 ok(ret, "failed to get size, error %lu\n", GetLastError());
6187 ok(file_size.QuadPart == 6, "got size %I64d\n", file_size.QuadPart);
6189 SetFilePointer(file, 0, NULL, SEEK_SET);
6190 ret = ReadFile(file, buffer, sizeof(buffer), &size, NULL);
6191 ok(ret, "failed to read, error %lu\n", GetLastError());
6192 ok(size == 6, "got size %lu\n", size);
6193 ok(!memcmp(buffer, "\0\0da\0\0", 6), "wrong data\n");
6195 ret = SetEndOfFile(file);
6196 ok(ret, "failed to set EOF, error %lu\n", GetLastError());
6198 SetFilePointer(file, 2, NULL, SEEK_SET);
6199 ret = WriteFile(file, "data", 4, &size, NULL);
6200 ok(ret, "failed to write, error %lu\n", GetLastError());
6201 ok(size == 4, "got size %lu\n", size);
6203 ret = GetFileSizeEx(file, &file_size);
6204 ok(ret, "failed to get size, error %lu\n", GetLastError());
6205 ok(file_size.QuadPart == 6, "got size %I64d\n", file_size.QuadPart);
6207 SetFilePointer(file, 0, NULL, SEEK_SET);
6208 ret = ReadFile(file, buffer, sizeof(buffer), &size, NULL);
6209 ok(ret, "failed to read, error %lu\n", GetLastError());
6210 ok(size == 6, "got size %lu\n", size);
6211 ok(!memcmp(buffer, "\0\0data", 6), "wrong data\n");
6213 for (i = 0; i < ARRAY_SIZE(map_tests); ++i)
6215 mapping = CreateFileMappingA(file, NULL, map_tests[i].protection, 0, 4, NULL);
6216 ok(!!mapping, "failed to create mapping, error %lu\n", GetLastError());
6218 ret = GetFileSizeEx(file, &file_size);
6219 ok(ret, "failed to get size, error %lu\n", GetLastError());
6220 ok(file_size.QuadPart == 6, "got size %I64d\n", file_size.QuadPart);
6222 SetFilePointer(file, 6, NULL, SEEK_SET);
6223 ret = SetEndOfFile(file);
6224 ok(ret, "failed to set EOF, error %lu\n", GetLastError());
6225 ret = GetFileSizeEx(file, &file_size);
6226 ok(ret, "failed to get size, error %lu\n", GetLastError());
6227 ok(file_size.QuadPart == 6, "got size %I64d\n", file_size.QuadPart);
6229 SetFilePointer(file, 8, NULL, SEEK_SET);
6230 ret = SetEndOfFile(file);
6231 ok(ret, "failed to set EOF, error %lu\n", GetLastError());
6232 ret = GetFileSizeEx(file, &file_size);
6233 ok(ret, "failed to get size, error %lu\n", GetLastError());
6234 ok(file_size.QuadPart == 8, "got size %I64d\n", file_size.QuadPart);
6236 SetLastError(0xdeadbeef);
6237 SetFilePointer(file, 6, NULL, SEEK_SET);
6238 ret = SetEndOfFile(file);
6239 ok(!ret, "expected failure\n");
6240 ok(GetLastError() == ERROR_USER_MAPPED_FILE, "got error %lu\n", GetLastError());
6241 ret = GetFileSizeEx(file, &file_size);
6242 ok(ret, "failed to get size, error %lu\n", GetLastError());
6243 ok(file_size.QuadPart == 8, "got size %I64d\n", file_size.QuadPart);
6245 SetFilePointer(file, 8192, NULL, SEEK_SET);
6246 ret = SetEndOfFile(file);
6247 ok(ret, "failed to set EOF, error %lu\n", GetLastError());
6248 ret = GetFileSizeEx(file, &file_size);
6249 ok(ret, "failed to get size, error %lu\n", GetLastError());
6250 ok(file_size.QuadPart == 8192, "got size %I64d\n", file_size.QuadPart);
6252 SetFilePointer(file, 8191, NULL, SEEK_SET);
6253 ret = SetEndOfFile(file);
6254 ok(!ret, "expected failure\n");
6255 ok(GetLastError() == ERROR_USER_MAPPED_FILE, "got error %lu\n", GetLastError());
6256 ret = GetFileSizeEx(file, &file_size);
6257 ok(ret, "failed to get size, error %lu\n", GetLastError());
6258 ok(file_size.QuadPart == 8192, "got size %I64d\n", file_size.QuadPart);
6260 view = MapViewOfFile(mapping, map_tests[i].view_access, 0, 0, 4);
6261 ok(!!view, "failed to map view, error %lu\n", GetLastError());
6263 CloseHandle(mapping);
6265 SetFilePointer(file, 16384, NULL, SEEK_SET);
6266 ret = SetEndOfFile(file);
6267 ok(ret, "failed to set EOF, error %lu\n", GetLastError());
6268 ret = GetFileSizeEx(file, &file_size);
6269 ok(ret, "failed to get size, error %lu\n", GetLastError());
6270 ok(file_size.QuadPart == 16384, "got size %I64d\n", file_size.QuadPart);
6272 SetFilePointer(file, 16383, NULL, SEEK_SET);
6273 ret = SetEndOfFile(file);
6274 ok(!ret, "expected failure\n");
6275 ok(GetLastError() == ERROR_USER_MAPPED_FILE, "got error %lu\n", GetLastError());
6276 ret = GetFileSizeEx(file, &file_size);
6277 ok(ret, "failed to get size, error %lu\n", GetLastError());
6278 ok(file_size.QuadPart == 16384, "got size %I64d\n", file_size.QuadPart);
6280 ret = UnmapViewOfFile(view);
6281 ok(ret, "failed to unmap view, error %lu\n", GetLastError());
6283 SetFilePointer(file, 6, NULL, SEEK_SET);
6284 ret = SetEndOfFile(file);
6285 ok(ret, "failed to set EOF, error %lu\n", GetLastError());
6286 ret = GetFileSizeEx(file, &file_size);
6287 ok(ret, "failed to get size, error %lu\n", GetLastError());
6288 ok(file_size.QuadPart == 6, "got size %I64d\n", file_size.QuadPart);
6291 CloseHandle(file);
6292 ret = DeleteFileA(filename);
6293 ok(ret, "failed to delete %s, error %lu\n", debugstr_a(filename), GetLastError());
6296 START_TEST(file)
6298 char temp_path[MAX_PATH];
6299 DWORD ret;
6301 InitFunctionPointers();
6303 ret = GetTempPathA(MAX_PATH, temp_path);
6304 ok(ret != 0, "GetTempPath error %lu\n", GetLastError());
6305 ret = GetTempFileNameA(temp_path, "tmp", 0, filename);
6306 ok(ret != 0, "GetTempFileName error %lu\n", GetLastError());
6307 ret = DeleteFileA(filename);
6308 ok(ret != 0, "DeleteFile error %lu\n", GetLastError());
6310 test__hread( );
6311 test__hwrite( );
6312 test__lclose( );
6313 test__lcreat( );
6314 test__llseek( );
6315 test__llopen( );
6316 test__lread( );
6317 test__lwrite( );
6318 test_GetTempFileNameA();
6319 test_CopyFileA();
6320 test_CopyFileW();
6321 test_CopyFile2();
6322 test_CopyFileEx();
6323 test_CreateFile();
6324 test_CreateFileA();
6325 test_CreateFileW();
6326 test_CreateFile2();
6327 test_DeleteFileA();
6328 test_DeleteFileW();
6329 test_MoveFileA();
6330 test_MoveFileW();
6331 test_FindFirstFileA();
6332 test_FindNextFileA();
6333 test_FindFirstFile_wildcards();
6334 test_FindFirstFileExA(FindExInfoStandard, 0, 0);
6335 test_FindFirstFileExA(FindExInfoStandard, 0, FIND_FIRST_EX_CASE_SENSITIVE);
6336 test_FindFirstFileExA(FindExInfoStandard, 0, FIND_FIRST_EX_LARGE_FETCH);
6337 test_FindFirstFileExA(FindExInfoBasic, 0, 0);
6338 /* FindExLimitToDirectories is ignored if the file system doesn't support directory filtering */
6339 test_FindFirstFileExA(FindExInfoStandard, FindExSearchLimitToDirectories, 0);
6340 test_FindFirstFileExA(FindExInfoStandard, FindExSearchLimitToDirectories, FIND_FIRST_EX_CASE_SENSITIVE);
6341 test_FindFirstFileExA(FindExInfoStandard, FindExSearchLimitToDirectories, FIND_FIRST_EX_LARGE_FETCH);
6342 test_FindFirstFileExA(FindExInfoBasic, FindExSearchLimitToDirectories, 0);
6343 test_LockFile();
6344 test_file_sharing();
6345 test_offset_in_overlapped_structure();
6346 test_MapFile();
6347 test_GetFileType();
6348 test_async_file_errors();
6349 test_read_write();
6350 test_OpenFile();
6351 test_overlapped();
6352 test_RemoveDirectory();
6353 test_ReplaceFileA();
6354 test_ReplaceFileW();
6355 test_GetFileInformationByHandleEx();
6356 test_OpenFileById();
6357 test_SetFileValidData();
6358 test_WriteFileGather();
6359 test_file_access();
6360 test_GetFinalPathNameByHandleA();
6361 test_GetFinalPathNameByHandleW();
6362 test_SetFileInformationByHandle();
6363 test_SetFileRenameInfo();
6364 test_GetFileAttributesExW();
6365 test_post_completion();
6366 test_overlapped_read();
6367 test_file_readonly_access();
6368 test_find_file_stream();
6369 test_SetFileTime();
6370 test_ReOpenFile();
6371 test_hard_link();
6372 test_move_file();
6373 test_eof();