Reactos
at master 6444 lines 277 kB view raw
1/* 2 * Unit tests for file functions in Wine 3 * 4 * Copyright (c) 2002, 2004 Jakob Eriksson 5 * Copyright (c) 2008 Jeff Zaroyko 6 * 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. 11 * 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. 16 * 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 20 * 21 */ 22 23#include <stdarg.h> 24#include <stdlib.h> 25#include <time.h> 26#include <stdio.h> 27 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" 37 38#undef DeleteFile /* needed for FILE_DISPOSITION_INFO */ 39 40static HANDLE (WINAPI *pFindFirstFileExA)(LPCSTR,FINDEX_INFO_LEVELS,LPVOID,FINDEX_SEARCH_OPS,LPVOID,DWORD); 41static BOOL (WINAPI *pReplaceFileW)(LPCWSTR, LPCWSTR, LPCWSTR, DWORD, LPVOID, LPVOID); 42static UINT (WINAPI *pGetSystemWindowsDirectoryA)(LPSTR, UINT); 43static BOOL (WINAPI *pGetVolumeNameForVolumeMountPointA)(LPCSTR, LPSTR, DWORD); 44static BOOL (WINAPI *pGetFileInformationByHandleEx)(HANDLE, FILE_INFO_BY_HANDLE_CLASS, LPVOID, DWORD); 45static HANDLE (WINAPI *pOpenFileById)(HANDLE, LPFILE_ID_DESCRIPTOR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD); 46static BOOL (WINAPI *pSetFileValidData)(HANDLE, LONGLONG); 47static HRESULT (WINAPI *pCopyFile2)(PCWSTR,PCWSTR,COPYFILE2_EXTENDED_PARAMETERS*); 48static HANDLE (WINAPI *pCreateFile2)(LPCWSTR, DWORD, DWORD, DWORD, CREATEFILE2_EXTENDED_PARAMETERS*); 49static DWORD (WINAPI *pGetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD, DWORD); 50static DWORD (WINAPI *pGetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD, DWORD); 51static NTSTATUS (WINAPI *pNtCreateFile)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, 52 PLARGE_INTEGER, ULONG, ULONG, ULONG, ULONG, PVOID, ULONG); 53static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(LPCWSTR, PUNICODE_STRING, PWSTR*, CURDIR*); 54static NTSTATUS (WINAPI *pRtlAnsiStringToUnicodeString)(PUNICODE_STRING, PCANSI_STRING, BOOLEAN); 55static BOOL (WINAPI *pSetFileInformationByHandle)(HANDLE, FILE_INFO_BY_HANDLE_CLASS, void*, DWORD); 56static BOOL (WINAPI *pGetQueuedCompletionStatusEx)(HANDLE, OVERLAPPED_ENTRY*, ULONG, ULONG*, DWORD, BOOL); 57static HANDLE (WINAPI *pReOpenFile)(HANDLE, DWORD, DWORD, DWORD); 58static void (WINAPI *pRtlInitAnsiString)(PANSI_STRING,PCSZ); 59static void (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING); 60static BOOL (WINAPI *pSetFileCompletionNotificationModes)(HANDLE, UCHAR); 61static HANDLE (WINAPI *pFindFirstStreamW)(LPCWSTR filename, STREAM_INFO_LEVELS infolevel, void *data, DWORD flags); 62 63static char filename[MAX_PATH]; 64static 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 "; 75 76struct 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} ; 83 84static void InitFunctionPointers(void) 85{ 86 HMODULE hntdll = GetModuleHandleA("ntdll"); 87 HMODULE hkernel32 = GetModuleHandleA("kernel32"); 88 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"); 94 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"); 111} 112 113static void create_file( const char *path ) 114{ 115 FILE *f = fopen( path, "wb" ); 116 fputs( path, f ); 117 fclose( f ); 118} 119 120static void test__hread( void ) 121{ 122 HFILE filehandle; 123 char buffer[10000]; 124 LONG bytes_read; 125 LONG bytes_wanted; 126 LONG i; 127 BOOL ret; 128 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) 133 { 134 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError()); 135 return; 136 } 137 138 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" ); 139 140 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" ); 141 142 filehandle = _lopen( filename, OF_READ ); 143 144 ok( HFILE_ERROR != filehandle, "couldn't open file \"%s\" again (err=%ld)\n", filename, GetLastError( ) ); 145 146 bytes_read = _hread( filehandle, buffer, 2 * strlen( sillytext ) ); 147 148 ok( lstrlenA( sillytext ) == bytes_read, "file read size error\n" ); 149 150 for (bytes_wanted = 0; bytes_wanted < lstrlenA( sillytext ); bytes_wanted++) 151 { 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++) 155 { 156 ok( buffer[i] == sillytext[i], "that's not what's written\n" ); 157 } 158 } 159 160 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" ); 161 162 ret = DeleteFileA( filename ); 163 ok( ret != 0, "DeleteFile failed (%ld)\n", GetLastError( ) ); 164} 165 166 167static void test__hwrite( void ) 168{ 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; 179 180 filehandle = _lcreat( filename, 0 ); 181 if (filehandle == HFILE_ERROR) 182 { 183 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError()); 184 return; 185 } 186 187 ok( HFILE_ERROR != _hwrite( filehandle, "", 0 ), "_hwrite complains\n" ); 188 189 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" ); 190 191 filehandle = _lopen( filename, OF_READ ); 192 193 bytes_read = _hread( filehandle, buffer, 1); 194 195 ok( 0 == bytes_read, "file read size error\n" ); 196 197 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" ); 198 199 filehandle = _lopen( filename, OF_READWRITE ); 200 201 bytes_written = 0; 202 checksum[0] = '\0'; 203 srand( (unsigned)time( NULL ) ); 204 for (blocks = 0; blocks < 100; blocks++) 205 { 206 for (i = 0; i < (LONG)sizeof( buffer ); i++) 207 { 208 buffer[i] = rand( ); 209 checksum[0] = checksum[0] + buffer[i]; 210 } 211 ok( HFILE_ERROR != _hwrite( filehandle, buffer, sizeof( buffer ) ), "_hwrite complains\n" ); 212 bytes_written = bytes_written + sizeof( buffer ); 213 } 214 215 ok( HFILE_ERROR != _hwrite( filehandle, checksum, 1 ), "_hwrite complains\n" ); 216 bytes_written++; 217 218 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" ); 219 220 memory_object = LocalAlloc( LPTR, bytes_written ); 221 222 ok( 0 != memory_object, "LocalAlloc fails. (Could be out of memory.)\n" ); 223 224 contents = LocalLock( memory_object ); 225 ok( NULL != contents, "LocalLock whines\n" ); 226 227 filehandle = _lopen( filename, OF_READ ); 228 229 contents = LocalLock( memory_object ); 230 ok( NULL != contents, "LocalLock whines\n" ); 231 232 ok( bytes_written == _hread( filehandle, contents, bytes_written), "read length differ from write length\n" ); 233 234 checksum[0] = '\0'; 235 i = 0; 236 do 237 { 238 checksum[0] = checksum[0] + contents[i]; 239 i++; 240 } 241 while (i < bytes_written - 1); 242 243 ok( checksum[0] == contents[i], "stored checksum differ from computed checksum\n" ); 244 245 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" ); 246 247 ret = DeleteFileA( filename ); 248 ok( ret != 0, "DeleteFile failed (%ld)\n", GetLastError( ) ); 249 250 LocalFree( contents ); 251} 252 253 254static void test__lclose( void ) 255{ 256 HFILE filehandle; 257 BOOL ret; 258 259 filehandle = _lcreat( filename, 0 ); 260 if (filehandle == HFILE_ERROR) 261 { 262 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError()); 263 return; 264 } 265 266 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" ); 267 268 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" ); 269 270 ret = DeleteFileA( filename ); 271 ok( ret != 0, "DeleteFile failed (%ld)\n", GetLastError( ) ); 272} 273 274/* helper function for test__lcreat */ 275static void get_nt_pathW( const char *name, UNICODE_STRING *nameW ) 276{ 277 UNICODE_STRING strW; 278 ANSI_STRING str; 279 NTSTATUS status; 280 BOOLEAN ret; 281 282 pRtlInitAnsiString( &str, name ); 283 284 status = pRtlAnsiStringToUnicodeString( &strW, &str, TRUE ); 285 ok( !status, "RtlAnsiStringToUnicodeString failed with %08lx\n", status ); 286 287 ret = pRtlDosPathNameToNtPathName_U( strW.Buffer, nameW, NULL, NULL ); 288 ok( ret, "RtlDosPathNameToNtPathName_U failed\n" ); 289 290 pRtlFreeUnicodeString( &strW ); 291} 292 293static void test__lcreat( void ) 294{ 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; 306 307 filehandle = _lcreat( filename, 0 ); 308 if (filehandle == HFILE_ERROR) 309 { 310 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError()); 311 return; 312 } 313 314 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" ); 315 316 ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" ); 317 318 ok( _hread( filehandle, buffer, strlen( sillytext ) ) == lstrlenA( sillytext ), "erratic _hread return value\n" ); 319 320 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" ); 321 322 find = FindFirstFileA( filename, &search_results ); 323 ok( INVALID_HANDLE_VALUE != find, "should be able to find file\n" ); 324 FindClose( find ); 325 326 ret = DeleteFileA(filename); 327 ok( ret != 0, "DeleteFile failed (%ld)\n", GetLastError()); 328 329 filehandle = _lcreat( filename, 1 ); /* readonly */ 330 ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%ld)\n", filename, GetLastError( ) ); 331 332 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite shouldn't be able to write never the less\n" ); 333 334 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" ); 335 336 find = FindFirstFileA( filename, &search_results ); 337 ok( INVALID_HANDLE_VALUE != find, "should be able to find file\n" ); 338 FindClose( find ); 339 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() ); 343 344 ok( SetFileAttributesA(filename, FILE_ATTRIBUTE_NORMAL ) != 0, "couldn't change attributes on file\n" ); 345 346 ok( DeleteFileA( filename ) != 0, "now it should be possible to delete the file!\n" ); 347 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" ); 353 354 find = FindFirstFileA( filename, &search_results ); 355 ok( INVALID_HANDLE_VALUE != find, "should be able to find file\n" ); 356 FindClose( find ); 357 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; 365 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" ); 371 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 ); 376 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 ); 381 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 ); 388 389 pRtlFreeUnicodeString( &filenameW ); 390 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" ); 397 398 filehandle = _lcreat( filename, 2 ); 399 ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%ld)\n", filename, GetLastError( ) ); 400 401 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" ); 402 403 ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" ); 404 405 ok( _hread( filehandle, buffer, strlen( sillytext ) ) == lstrlenA( sillytext ), "erratic _hread return value\n" ); 406 407 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" ); 408 409 find = FindFirstFileA( filename, &search_results ); 410 ok( INVALID_HANDLE_VALUE != find, "should STILL be able to find file\n" ); 411 FindClose( find ); 412 413 ret = DeleteFileA( filename ); 414 ok( ret, "DeleteFile failed (%ld)\n", GetLastError( ) ); 415 416 filehandle = _lcreat( filename, 4 ); /* SYSTEM file */ 417 ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%ld)\n", filename, GetLastError( ) ); 418 419 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" ); 420 421 ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" ); 422 423 ok( _hread( filehandle, buffer, strlen( sillytext ) ) == lstrlenA( sillytext ), "erratic _hread return value\n" ); 424 425 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" ); 426 427 find = FindFirstFileA( filename, &search_results ); 428 ok( INVALID_HANDLE_VALUE != find, "should STILL be able to find file\n" ); 429 FindClose( find ); 430 431 ret = DeleteFileA( filename ); 432 ok( ret, "DeleteFile failed (%ld)\n", GetLastError( ) ); 433 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); 439 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, '\\'); 450 451 if (name) name++; 452 else name = filename; 453 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); 463 } 464 ret = DeleteFileA( filename ); 465 ok( ret, "DeleteFile failed (%ld)\n", GetLastError( ) ); 466 } 467} 468 469 470static void test__llseek( void ) 471{ 472 INT i; 473 HFILE filehandle; 474 char buffer[1]; 475 LONG bytes_read; 476 BOOL ret; 477 478 filehandle = _lcreat( filename, 0 ); 479 if (filehandle == HFILE_ERROR) 480 { 481 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError()); 482 return; 483 } 484 485 for (i = 0; i < 400; i++) 486 { 487 ok( _hwrite( filehandle, sillytext, strlen( sillytext ) ) != -1, "_hwrite complains\n" ); 488 } 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" ); 491 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" ); 496 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" ); 502 503 ret = DeleteFileA( filename ); 504 ok( ret, "DeleteFile failed (%ld)\n", GetLastError( ) ); 505} 506 507 508static void test__llopen( void ) 509{ 510 HFILE filehandle; 511 UINT bytes_read; 512 char buffer[10000]; 513 BOOL ret; 514 515 filehandle = _lcreat( filename, 0 ); 516 if (filehandle == HFILE_ERROR) 517 { 518 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError()); 519 return; 520 } 521 522 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" ); 523 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" ); 524 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" ); 530 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" ); 536 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" ); 541 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 */ 545} 546 547 548static void test__lread( void ) 549{ 550 HFILE filehandle; 551 char buffer[10000]; 552 UINT bytes_read; 553 UINT bytes_wanted; 554 UINT i; 555 BOOL ret; 556 557 filehandle = _lcreat( filename, 0 ); 558 if (filehandle == HFILE_ERROR) 559 { 560 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError()); 561 return; 562 } 563 564 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" ); 565 566 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" ); 567 568 filehandle = _lopen( filename, OF_READ ); 569 570 ok( HFILE_ERROR != filehandle, "couldn't open file \"%s\" again (err=%ld)\n", filename, GetLastError()); 571 572 bytes_read = _lread( filehandle, buffer, 2 * strlen( sillytext ) ); 573 574 ok( lstrlenA( sillytext ) == bytes_read, "file read size error\n" ); 575 576 for (bytes_wanted = 0; bytes_wanted < strlen( sillytext ); bytes_wanted++) 577 { 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++) 581 { 582 ok( buffer[i] == sillytext[i], "that's not what's written\n" ); 583 } 584 } 585 586 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" ); 587 588 ret = DeleteFileA( filename ); 589 ok( ret, "DeleteFile failed (%ld)\n", GetLastError( ) ); 590} 591 592 593static void test__lwrite( void ) 594{ 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; 605 606 filehandle = _lcreat( filename, 0 ); 607 if (filehandle == HFILE_ERROR) 608 { 609 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError()); 610 return; 611 } 612 613 ok( HFILE_ERROR != _lwrite( filehandle, "", 0 ), "_hwrite complains\n" ); 614 615 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" ); 616 617 filehandle = _lopen( filename, OF_READ ); 618 619 bytes_read = _hread( filehandle, buffer, 1); 620 621 ok( 0 == bytes_read, "file read size error\n" ); 622 623 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" ); 624 625 filehandle = _lopen( filename, OF_READWRITE ); 626 627 bytes_written = 0; 628 checksum[0] = '\0'; 629 srand( (unsigned)time( NULL ) ); 630 for (blocks = 0; blocks < 100; blocks++) 631 { 632 for (i = 0; i < (INT)sizeof( buffer ); i++) 633 { 634 buffer[i] = rand( ); 635 checksum[0] = checksum[0] + buffer[i]; 636 } 637 ok( HFILE_ERROR != _lwrite( filehandle, buffer, sizeof( buffer ) ), "_hwrite complains\n" ); 638 bytes_written = bytes_written + sizeof( buffer ); 639 } 640 641 ok( HFILE_ERROR != _lwrite( filehandle, checksum, 1 ), "_hwrite complains\n" ); 642 bytes_written++; 643 644 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" ); 645 646 memory_object = LocalAlloc( LPTR, bytes_written ); 647 648 ok( 0 != memory_object, "LocalAlloc fails, could be out of memory\n" ); 649 650 contents = LocalLock( memory_object ); 651 ok( NULL != contents, "LocalLock whines\n" ); 652 653 filehandle = _lopen( filename, OF_READ ); 654 655 contents = LocalLock( memory_object ); 656 ok( NULL != contents, "LocalLock whines\n" ); 657 658 ok( bytes_written == _hread( filehandle, contents, bytes_written), "read length differ from write length\n" ); 659 660 checksum[0] = '\0'; 661 i = 0; 662 do 663 { 664 checksum[0] += contents[i]; 665 i++; 666 } 667 while (i < bytes_written - 1); 668 669 ok( checksum[0] == contents[i], "stored checksum differ from computed checksum\n" ); 670 671 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" ); 672 673 ret = DeleteFileA( filename ); 674 ok( ret, "DeleteFile failed (%ld)\n", GetLastError( ) ); 675 676 LocalFree( contents ); 677} 678 679static void test_CopyFileA(void) 680{ 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; 690 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"); 694 695 ret = GetTempFileNameA(temp_path, prefix, 0, source); 696 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError()); 697 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()); 702 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); 718 719 ret = GetTempFileNameA(temp_path, prefix, 0, dest); 720 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError()); 721 722 SetLastError(0xdeadbeef); 723 ret = CopyFileA(source, dest, TRUE); 724 ok(!ret && GetLastError() == ERROR_FILE_EXISTS, 725 "CopyFileA: unexpected error %ld\n", GetLastError()); 726 727 ret = CopyFileA(source, dest, FALSE); 728 ok(ret, "CopyFileA: error %ld\n", GetLastError()); 729 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()); 737 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); 749 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); 757 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); 765 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); 773 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); 781 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) 787 { 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); 792 } 793 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); 801 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); 807 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"); 812 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()); 817 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"); 825 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()); 829 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()); 833 834 CloseHandle(hmapfile); 835 CloseHandle(hfile); 836 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"); 839 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()); 843 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()); 849 850 CloseHandle(hmapfile); 851 CloseHandle(hfile); 852 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"); 860 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"); 870 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"); 880 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"); 886 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"); 897 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()); 902 903 ret = DeleteFileA(source); 904 ok(ret, "DeleteFileA: error %ld\n", GetLastError()); 905 ret = DeleteFileA(dest); 906 ok(ret, "DeleteFileA: error %ld\n", GetLastError()); 907} 908 909static void test_CopyFileW(void) 910{ 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; 915 916 ret = GetTempPathW(MAX_PATH, temp_path); 917 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 918 { 919 win_skip("GetTempPathW is not available\n"); 920 return; 921 } 922 ok(ret != 0, "GetTempPathW error %ld\n", GetLastError()); 923 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n"); 924 925 ret = GetTempFileNameW(temp_path, prefix, 0, source); 926 ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError()); 927 928 ret = GetTempFileNameW(temp_path, prefix, 0, dest); 929 ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError()); 930 931 ret = CopyFileW(source, dest, TRUE); 932 ok(!ret && GetLastError() == ERROR_FILE_EXISTS, 933 "CopyFileW: unexpected error %ld\n", GetLastError()); 934 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()); 940 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()); 946 947 ret = DeleteFileW(source); 948 ok(ret, "DeleteFileW: error %ld\n", GetLastError()); 949 ret = DeleteFileW(dest); 950 ok(ret, "DeleteFileW: error %ld\n", GetLastError()); 951} 952 953static void test_CopyFile2(void) 954{ 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; 964 965 if (!pCopyFile2) 966 { 967 todo_wine win_skip("CopyFile2 is not available\n"); 968 return; 969 } 970 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"); 974 975 ret = GetTempFileNameW(temp_path, prefix, 0, source); 976 ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError()); 977 978 ret = GetTempFileNameW(temp_path, prefix, 0, dest); 979 ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError()); 980 981 /* fail if exists */ 982 memset(&params, 0, sizeof(params)); 983 params.dwSize = sizeof(params); 984 params.dwCopyFlags = COPY_FILE_FAIL_IF_EXISTS; 985 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()); 990 991 /* don't fail if exists */ 992 params.dwSize = sizeof(params); 993 params.dwCopyFlags = 0; 994 995 hr = pCopyFile2(source, dest, &params); 996 ok(hr == S_OK, "CopyFile2: error 0x%08lx\n", hr); 997 998 /* copying a file to itself must fail */ 999 params.dwSize = sizeof(params); 1000 params.dwCopyFlags = 0; 1001 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()); 1006 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"); 1013 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); 1022 1023 ret = GetTempFileNameW(temp_path, prefix, 0, dest); 1024 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError()); 1025 1026 params.dwSize = sizeof(params); 1027 params.dwCopyFlags = COPY_FILE_FAIL_IF_EXISTS; 1028 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()); 1033 1034 params.dwSize = sizeof(params); 1035 params.dwCopyFlags = 0; 1036 hr = pCopyFile2(source, dest, &params); 1037 ok(ret, "CopyFile2: error 0x%08lx\n", hr); 1038 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()); 1042 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()); 1049 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); 1058 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()); 1062 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); 1068 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()); 1072 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); 1078 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()); 1082 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); 1090 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()); 1094 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); 1100 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()); 1104 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); 1112 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()); 1116 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); 1122 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); 1128 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"); 1133 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()); 1140 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"); 1147 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()); 1151 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()); 1158 1159 CloseHandle(hmapfile); 1160 CloseHandle(hfile); 1161 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"); 1164 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()); 1168 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()); 1174 1175 CloseHandle(hmapfile); 1176 CloseHandle(hfile); 1177 1178 DeleteFileW(source); 1179 DeleteFileW(dest); 1180} 1181 1182static 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) 1185{ 1186 ok(reason == CALLBACK_STREAM_SWITCH, "expected CALLBACK_STREAM_SWITCH, got %lu\n", reason); 1187 CloseHandle(userdata); 1188 return PROGRESS_CANCEL; 1189} 1190 1191static void test_CopyFileEx(void) 1192{ 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; 1199 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"); 1203 1204 ret = GetTempFileNameA(temp_path, prefix, 0, source); 1205 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError()); 1206 1207 ret = GetTempFileNameA(temp_path, prefix, 0, dest); 1208 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError()); 1209 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"); 1219 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"); 1232 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()); 1239 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"); 1244} 1245 1246/* 1247 * Debugging routine to dump a buffer in a hexdump-like fashion. 1248 */ 1249static void dumpmem(unsigned char *mem, int len) 1250{ 1251 int x = 0; 1252 char hex[49], *p; 1253 char txt[17], *c; 1254 1255 while (x < len) 1256 { 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); 1265 } 1266} 1267 1268static void test_CreateFileA(void) 1269{ 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[] = 1281 { 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} 1296 }; 1297 BY_HANDLE_FILE_INFORMATION Finfo; 1298 WCHAR curdir[MAX_PATH]; 1299 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"); 1303 1304 ret = GetTempFileNameA(temp_path, prefix, 0, filename); 1305 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError()); 1306 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"); 1312 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()); 1318 1319 CloseHandle(hFile); 1320 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()); 1326 1327 CloseHandle(hFile); 1328 1329 ret = DeleteFileA(filename); 1330 ok(ret, "DeleteFileA: error %ld\n", GetLastError()); 1331 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()); 1337 1338 CloseHandle(hFile); 1339 1340 ret = DeleteFileA(filename); 1341 ok(ret, "DeleteFileA: error %ld\n", GetLastError()); 1342 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()); 1349 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()); 1354 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) 1367 { 1368 filename[0] = 0; 1369 /* update the drive id in the table entry with the current one */ 1370 if (p[i].file[1] == ':') 1371 { 1372 strcpy(filename, p[i].file); 1373 filename[0] = windowsdir[0]; 1374 } 1375 else if (p[i].file[0] == '\\' && p[i].file[5] == ':') 1376 { 1377 strcpy(filename, p[i].file); 1378 filename[4] = windowsdir[0]; 1379 } 1380 else 1381 { 1382 /* prefix the table entry with the current temp directory */ 1383 strcpy(filename, temp_path); 1384 strcat(filename, p[i].file); 1385 } 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 1392 */ 1393 if (hFile == INVALID_HANDLE_VALUE && 1394 GetLastError() == ERROR_ACCESS_DENIED && 1395 p[i].err != ERROR_ACCESS_DENIED) 1396 { 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); 1401 } 1402 /* otherwise validate results with expectations */ 1403 else 1404 { 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); 1411 } 1412 if (hFile != INVALID_HANDLE_VALUE) 1413 CloseHandle( hFile ); 1414 i++; 1415 } 1416 ret = RemoveDirectoryA(dirname); 1417 ok(ret, "RemoveDirectoryA: error %ld\n", GetLastError()); 1418 SetCurrentDirectoryW(curdir); 1419 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) 1427 { 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 ); 1431 1432 if (hFile != INVALID_HANDLE_VALUE) 1433 { 1434 ret = GetFileInformationByHandle( hFile, &Finfo ); 1435 if (ret) 1436 { 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); 1440 } 1441 CloseHandle( hFile ); 1442 } 1443 } 1444 else 1445 skip("Probable Win9x, got ERROR_PATH_NOT_FOUND w/ FILE_FLAG_BACKUP_SEMANTICS or %s\n", temp_path); 1446 1447 1448 /* *** Test opening volumes/devices using drive letter *** */ 1449 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)) 1460 { 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) 1465 { 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) 1474 { 1475 trace("buffer is\n"); 1476 dumpmem(buffer, 64); 1477 } 1478 CloseHandle( hFile ); 1479 } 1480 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 ); 1496 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 ); 1511 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 ); 1525 } 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"); 1531 1532 1533 /* *** Test opening volumes/devices using GUID *** */ 1534 1535 if (pGetVolumeNameForVolumeMountPointA) 1536 { 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) 1542 { 1543 ok(strlen(Volume_1) == 49, "GetVolumeNameForVolumeMountPointA returned wrong length name <%s>\n", Volume_1); 1544 1545 /* test the result of opening a unique volume name (GUID) 1546 * with the trailing \ 1547 * this should error out 1548 */ 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 ); 1564 1565 /* test the result of opening a unique volume name (GUID) 1566 * with the temp path string as dir 1567 * this should work 1568 */ 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 ); 1581 1582 /* test the result of opening a unique volume name (GUID) 1583 * without the trailing \ and in device namespace 1584 * this should work 1585 */ 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) 1594 { 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) 1599 { 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) 1608 { 1609 trace("buffer is\n"); 1610 dumpmem(buffer, 64); 1611 } 1612 CloseHandle( hFile ); 1613 } 1614 } 1615 else 1616 skip("Do not have authority to access volumes. Tests skipped\n"); 1617 } 1618 else 1619 win_skip("GetVolumeNameForVolumeMountPointA not functioning\n"); 1620 } 1621 else 1622 win_skip("GetVolumeNameForVolumeMountPointA not found\n"); 1623} 1624 1625static void test_CreateFileW(void) 1626{ 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; 1634 1635 ret = GetTempPathW(MAX_PATH, temp_path); 1636 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 1637 { 1638 win_skip("GetTempPathW is not available\n"); 1639 return; 1640 } 1641 ok(ret != 0, "GetTempPathW error %ld\n", GetLastError()); 1642 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n"); 1643 1644 ret = GetTempFileNameW(temp_path, prefix, 0, filename); 1645 ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError()); 1646 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"); 1652 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()); 1658 1659 CloseHandle(hFile); 1660 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()); 1666 1667 CloseHandle(hFile); 1668 1669 ret = DeleteFileW(filename); 1670 ok(ret, "DeleteFileW: error %ld\n", GetLastError()); 1671 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()); 1677 1678 CloseHandle(hFile); 1679 1680 ret = DeleteFileW(filename); 1681 ok(ret, "DeleteFileW: error %ld\n", GetLastError()); 1682 1683 if (0) 1684 { 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()); 1690 } 1691 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()); 1696 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()); 1702 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()); 1712} 1713 1714static void test_CreateFile2(void) 1715{ 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; 1724 1725 if (!pCreateFile2) 1726 { 1727 win_skip("CreateFile2 is missing\n"); 1728 return; 1729 } 1730 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"); 1734 1735 ret = GetTempFileNameW(temp_path, prefix, 0, filename); 1736 ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError()); 1737 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"); 1748 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); 1754 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); 1760 1761 ret = DeleteFileW(filename); 1762 ok(ret, "DeleteFileW: error %ld\n", GetLastError()); 1763 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); 1769 1770 ret = DeleteFileW(filename); 1771 ok(ret, "DeleteFileW: error %ld\n", GetLastError()); 1772 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()); 1776 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()); 1782 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()); 1794 1795 for (i = 0; i < 2; ++i) 1796 { 1797 memset(&exparams, 0, sizeof(exparams)); 1798 exparams.dwSize = sizeof(exparams); 1799 if (i == 0) 1800 { 1801 exparams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; 1802 exparams.dwFileFlags = FILE_FLAG_OVERLAPPED | FILE_FLAG_DELETE_ON_CLOSE; 1803 } 1804 else 1805 { 1806 exparams.dwFileFlags = FILE_ATTRIBUTE_NORMAL; 1807 exparams.dwFileAttributes = FILE_FLAG_OVERLAPPED | FILE_FLAG_DELETE_ON_CLOSE; 1808 } 1809 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()); 1813 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()); 1817 1818 CloseHandle(iocp); 1819 CloseHandle(hFile); 1820 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()); 1824 } 1825} 1826 1827static void test_GetTempFileNameA(void) 1828{ 1829 UINT result; 1830 char out[MAX_PATH]; 1831 char expected[MAX_PATH + 10]; 1832 char windowsdir[MAX_PATH + 10]; 1833 char windowsdrive[3]; 1834 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()); 1838 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:\" */ 1841 { 1842 strcat(windowsdir, "\\"); 1843 } 1844 1845 windowsdrive[0] = windowsdir[0]; 1846 windowsdrive[1] = windowsdir[1]; 1847 windowsdrive[2] = '\0'; 1848 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); 1854 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); 1862} 1863 1864static void test_DeleteFileA( void ) 1865{ 1866 BOOL ret; 1867 char temp_path[MAX_PATH], temp_file[MAX_PATH]; 1868 HANDLE hfile, mapping; 1869 char **argv; 1870 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()); 1875 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()); 1880 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()); 1887 1888 ret = DeleteFileA("nonexist.txt"); 1889 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND, "DeleteFileA(\"nonexist.txt\") returned ret=%d error=%ld\n",ret,GetLastError()); 1890 1891 GetTempPathA(MAX_PATH, temp_path); 1892 GetTempFileNameA(temp_path, "tst", 0, temp_file); 1893 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()); 1897 1898 SetLastError(0xdeadbeef); 1899 ret = DeleteFileA(temp_file); 1900 ok(ret, "DeleteFile error %ld\n", GetLastError()); 1901 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"); 1907 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()); 1916 1917 winetest_get_mainargs(&argv); 1918 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()); 1923 1924 mapping = CreateFileMappingA(hfile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL); 1925 ok(!!mapping, "got error %lu\n", GetLastError()); 1926 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()); 1931 1932 CloseHandle(mapping); 1933 1934 ret = DeleteFileA(temp_file); 1935 ok(ret, "got error %lu\n", GetLastError()); 1936 1937 CloseHandle(hfile); 1938} 1939 1940static void test_DeleteFileW( void ) 1941{ 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'}; 1948 1949 ret = DeleteFileW(NULL); 1950 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 1951 { 1952 win_skip("DeleteFileW is not available\n"); 1953 return; 1954 } 1955 ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND, 1956 "DeleteFileW(NULL) returned ret=%d error=%ld\n",ret,GetLastError()); 1957 1958 ret = DeleteFileW(emptyW); 1959 ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND, 1960 "DeleteFileW(\"\") returned ret=%d error=%ld\n",ret,GetLastError()); 1961 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) 1965 { 1966 ok(0, "MAX_PATH exceeded in constructing paths\n"); 1967 return; 1968 } 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"); 1978 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"); 1990} 1991 1992#define IsDotDir(x) ((x[0] == '.') && ((x[1] == 0) || ((x[1] == '.') && (x[2] == 0)))) 1993 1994static void test_MoveFileA(void) 1995{ 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; 2004 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"); 2008 2009 ret = GetTempFileNameA(tempdir, prefix, 0, source); 2010 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError()); 2011 2012 ret = GetTempFileNameA(tempdir, prefix, 0, dest); 2013 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError()); 2014 2015 ret = MoveFileA(source, source); 2016 ok(ret, "MoveFileA: failed, error %ld\n", GetLastError()); 2017 2018 ret = MoveFileA(source, dest); 2019 ok(!ret && GetLastError() == ERROR_ALREADY_EXISTS, 2020 "MoveFileA: unexpected error %ld\n", GetLastError()); 2021 2022 ret = DeleteFileA(dest); 2023 ok(ret, "DeleteFileA: error %ld\n", GetLastError()); 2024 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"); 2027 2028 retok = WriteFile(hfile, prefix, sizeof(prefix), &ret, NULL ); 2029 ok( retok && ret == sizeof(prefix), 2030 "WriteFile error %ld\n", GetLastError()); 2031 2032 hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL); 2033 ok(hmapfile != NULL, "CreateFileMapping: error %ld\n", GetLastError()); 2034 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()); 2040 2041 CloseHandle(hmapfile); 2042 CloseHandle(hfile); 2043 2044 /* if MoveFile succeeded, move back to dest */ 2045 if (ret) MoveFileA(dest, source); 2046 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"); 2049 2050 hmapfile = CreateFileMappingW(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL); 2051 ok(hmapfile != NULL, "CreateFileMapping: error %ld\n", GetLastError()); 2052 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()); 2058 2059 CloseHandle(hmapfile); 2060 CloseHandle(hfile); 2061 2062 /* if MoveFile succeeded, move back to dest */ 2063 if (ret) MoveFileA(dest, source); 2064 2065 ret = MoveFileA(source, dest); 2066 ok(ret, "MoveFileA: failed, error %ld\n", GetLastError()); 2067 2068 lstrcatA(tempdir, "Remove Me"); 2069 2070 /* test renaming a file "Remove Me" to itself but in lowercase "me" */ 2071 lstrcpyA(source, tempdir); 2072 tempdir[lstrlenA(tempdir) - 2] = 'm'; 2073 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); 2077 2078 ret = MoveFileA(source, tempdir); 2079 ok(ret, "MoveFileA: failed, error %ld\n", GetLastError()); 2080 2081 hfile = FindFirstFileA(tempdir, &find_data); 2082 ok(hfile != INVALID_HANDLE_VALUE, "FindFirstFileA: failed, error %ld\n", GetLastError()); 2083 if (hfile != INVALID_HANDLE_VALUE) 2084 { 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); 2087 } 2088 CloseHandle(hfile); 2089 2090 /* test renaming another file "Remove Be" to "Remove Me", which replaces the existing "Remove me" */ 2091 tempdir[lstrlenA(tempdir) - 2] = 'B'; 2092 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); 2096 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()); 2102 2103 tempdir[lstrlenA(tempdir) - 2] = 'm'; 2104 2105 hfile = FindFirstFileA(tempdir, &find_data); 2106 ok(hfile != INVALID_HANDLE_VALUE, "FindFirstFileA: failed, error %ld\n", GetLastError()); 2107 if (hfile != INVALID_HANDLE_VALUE) 2108 { 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); 2111 } 2112 CloseHandle(hfile); 2113 2114 ret = DeleteFileA(tempdir); 2115 ok(ret, "DeleteFileA: error %ld\n", GetLastError()); 2116 2117 /* now test a directory from "Remove me" to uppercase "Me" */ 2118 ret = CreateDirectoryA(tempdir, NULL); 2119 ok(ret == TRUE, "CreateDirectoryA failed\n"); 2120 2121 lstrcpyA(source, tempdir); 2122 tempdir[lstrlenA(tempdir) - 2] = 'M'; 2123 ret = MoveFileA(source, tempdir); 2124 ok(ret, "MoveFileA: failed, error %ld\n", GetLastError()); 2125 2126 hfile = FindFirstFileA(tempdir, &find_data); 2127 ok(hfile != INVALID_HANDLE_VALUE, "FindFirstFileA: failed, error %ld\n", GetLastError()); 2128 if (hfile != INVALID_HANDLE_VALUE) 2129 { 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); 2132 } 2133 CloseHandle(hfile); 2134 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)) 2145 { 2146 WIN32_FIND_DATAA fd; 2147 char temppath[MAX_PATH]; 2148 HANDLE hFind; 2149 2150 lstrcpyA(temppath, tempdir); 2151 lstrcatA(temppath, "\\*.*"); 2152 hFind = FindFirstFileA(temppath, &fd); 2153 if (INVALID_HANDLE_VALUE != hFind) 2154 { 2155 LPSTR lpName; 2156 do 2157 { 2158 lpName = fd.cAlternateFileName; 2159 if (!lpName[0]) 2160 lpName = fd.cFileName; 2161 ok(IsDotDir(lpName), "MoveFileA: wildcards file created!\n"); 2162 } 2163 while (FindNextFileA(hFind, &fd)); 2164 FindClose(hFind); 2165 } 2166 } 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()); 2173} 2174 2175static void test_MoveFileW(void) 2176{ 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; 2181 2182 ret = GetTempPathW(MAX_PATH, temp_path); 2183 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 2184 { 2185 win_skip("GetTempPathW is not available\n"); 2186 return; 2187 } 2188 ok(ret != 0, "GetTempPathW error %ld\n", GetLastError()); 2189 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n"); 2190 2191 ret = GetTempFileNameW(temp_path, prefix, 0, source); 2192 ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError()); 2193 2194 ret = GetTempFileNameW(temp_path, prefix, 0, dest); 2195 ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError()); 2196 2197 ret = MoveFileW(source, dest); 2198 ok(!ret && GetLastError() == ERROR_ALREADY_EXISTS, 2199 "MoveFileW: unexpected error %ld\n", GetLastError()); 2200 2201 ret = DeleteFileW(source); 2202 ok(ret, "DeleteFileW: error %ld\n", GetLastError()); 2203 ret = DeleteFileW(dest); 2204 ok(ret, "DeleteFileW: error %ld\n", GetLastError()); 2205} 2206 2207#define PATTERN_OFFSET 0x10 2208 2209static void test_offset_in_overlapped_structure(void) 2210{ 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; 2219 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()); 2224 2225 /*** Write File *****************************************************/ 2226 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()); 2229 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); 2234 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); 2245 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); 2253 } 2254 2255 CloseHandle(hFile); 2256 2257 /*** Read File *****************************************************/ 2258 2259 hFile = CreateFileA(temp_fname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0); 2260 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA error %ld\n", GetLastError()); 2261 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"); 2274 } 2275 2276 CloseHandle(hFile); 2277 2278 ret = DeleteFileA(temp_fname); 2279 ok( ret, "DeleteFileA error %ld\n", GetLastError()); 2280} 2281 2282static void test_LockFile(void) 2283{ 2284 HANDLE handle, handle2; 2285 DWORD written; 2286 OVERLAPPED overlapped; 2287 int limited_LockFile; 2288 int limited_UnLockFile; 2289 BOOL ret; 2290 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) 2295 { 2296 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError()); 2297 return; 2298 } 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) 2303 { 2304 ok( 0, "couldn't open file \"%s\" (err=%ld)\n", filename, GetLastError() ); 2305 goto cleanup; 2306 } 2307 ok( WriteFile( handle, sillytext, strlen(sillytext), &written, NULL ), "write failed\n" ); 2308 2309 ok( LockFile( handle, 0, 0, 0, 0 ), "LockFile failed\n" ); 2310 ok( UnlockFile( handle, 0, 0, 0, 0 ), "UnlockFile failed\n" ); 2311 2312 limited_UnLockFile = 0; 2313 if (UnlockFile( handle, 0, 0, 0, 0 )) 2314 { 2315 limited_UnLockFile = 1; 2316 } 2317 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" ); 2324 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" ); 2329 2330 overlapped.Offset = 100; 2331 overlapped.OffsetHigh = 0; 2332 overlapped.hEvent = 0; 2333 2334 /* Test for broken LockFileEx a la Windows 95 OSR2. */ 2335 if (LockFileEx( handle, 0, 0, 100, 0, &overlapped )) 2336 { 2337 /* LockFileEx is probably OK, test it more. */ 2338 ok( LockFileEx( handle, 0, 0, 100, 0, &overlapped ), 2339 "LockFileEx 100,100 failed\n" ); 2340 } 2341 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" ); 2345 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" ); 2355 } 2356 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" ); 2372 2373 ret = LockFile( handle, 0, 0x10000000, 0, 0xf0000000 ); 2374 if (ret) 2375 { 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" ); 2379 } 2380 else /* win9x */ 2381 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong LockFile error %lu\n", GetLastError() ); 2382 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 ); 2386 2387 limited_LockFile = 0; 2388 if (!LockFile( handle, ~0, ~0, 1, 0 )) 2389 { 2390 limited_LockFile = 1; 2391 } 2392 2393 limited_UnLockFile || ok( UnlockFile( handle, ~0, ~0, 1, 0 ), "Unlockfile ~0,1 failed\n" ); 2394 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" ); 2400 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" ); 2403 2404 ok( UnlockFile( handle, 100, 0, 0, 0 ), "UnlockFile 100,0 failed\n" ); 2405 2406 CloseHandle( handle2 ); 2407cleanup: 2408 CloseHandle( handle ); 2409 DeleteFileA( filename ); 2410} 2411 2412static BOOL create_fake_dll( LPCSTR filename ) 2413{ 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; 2422 2423 HANDLE file = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 ); 2424 if (file == INVALID_HANDLE_VALUE) return FALSE; 2425 2426 buffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size ); 2427 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; 2439 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; 2473 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; 2481 2482 ret = WriteFile( file, buffer, size, &written, NULL ) && written == size; 2483 HeapFree( GetProcessHeap(), 0, buffer ); 2484 CloseHandle( file ); 2485 return ret; 2486} 2487 2488static unsigned int map_file_access( unsigned int access ) 2489{ 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); 2495} 2496 2497static BOOL is_sharing_compatible( DWORD access1, DWORD sharing1, DWORD access2, DWORD sharing2 ) 2498{ 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; 2503 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; 2506 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; 2514} 2515 2516static BOOL is_sharing_map_compatible( DWORD map_access, DWORD access2, DWORD sharing2 ) 2517{ 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; 2523} 2524 2525static void test_file_sharing(void) 2526{ 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; 2548 2549 /* make sure the file exists */ 2550 if (!create_fake_dll( filename )) 2551 { 2552 ok(0, "couldn't create file \"%s\" (err=%ld)\n", filename, GetLastError()); 2553 return; 2554 } 2555 2556 for (a1 = 0; a1 < ARRAY_SIZE(access_modes); a1++) 2557 { 2558 for (s1 = 0; s1 < ARRAY_SIZE(sharing_modes); s1++) 2559 { 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) 2564 { 2565 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError()); 2566 return; 2567 } 2568 for (a2 = 0; a2 < ARRAY_SIZE(access_modes); a2++) 2569 { 2570 for (s2 = 0; s2 < ARRAY_SIZE(sharing_modes); s2++) 2571 { 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 )) 2578 { 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 ); 2584 } 2585 else 2586 { 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 ); 2593 } 2594 if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 ); 2595 } 2596 } 2597 CloseHandle( h ); 2598 } 2599 } 2600 2601 for (a1 = 0; a1 < ARRAY_SIZE(mapping_modes); a1++) 2602 { 2603 HANDLE m; 2604 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) 2609 { 2610 ok(0,"couldn't create file \"%s\" (err=%ld)\n",filename,GetLastError()); 2611 return; 2612 } 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; 2617 2618 for (a2 = 0; a2 < ARRAY_SIZE(access_modes); a2++) 2619 { 2620 for (s2 = 0; s2 < ARRAY_SIZE(sharing_modes); s2++) 2621 { 2622 SetLastError(0xdeadbeef); 2623 h2 = CreateFileA( filename, access_modes[a2].dw, sharing_modes[s2].dw, 2624 NULL, OPEN_EXISTING, 0, 0 ); 2625 2626 ret = GetLastError(); 2627 if (h2 == INVALID_HANDLE_VALUE) 2628 { 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 ); 2634 } 2635 else 2636 { 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 ); 2645 } 2646 } 2647 } 2648 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) 2655 { 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 ); 2658 } 2659 else 2660 { 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 ); 2663 } 2664 if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 ); 2665 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) 2672 { 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 ); 2675 } 2676 else 2677 { 2678 ok( h2 != INVALID_HANDLE_VALUE, "open failed for map %s err %u\n", mapping_modes[a1].str, ret ); 2679 } 2680 if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 ); 2681 2682 CloseHandle( m ); 2683 } 2684 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() ); 2688 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() ); 2693 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() ); 2696 2697 CloseHandle(h); 2698 CloseHandle(h2); 2699 2700 DeleteFileA( filename ); 2701} 2702 2703static char get_windows_drive(void) 2704{ 2705 char windowsdir[MAX_PATH]; 2706 GetWindowsDirectoryA(windowsdir, sizeof(windowsdir)); 2707 return windowsdir[0]; 2708} 2709 2710static void test_FindFirstFileA(void) 2711{ 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; 2719 2720 /* try FindFirstFileA on "C:\" */ 2721 buffer[0] = get_windows_drive(); 2722 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 ); 2728 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 ); 2740 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 )) 2750 { 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)) 2755 { 2756 GetWindowsDirectoryA( buffer2, sizeof(buffer2) ); 2757 strcat(buffer2, "\\"); 2758 strcat(buffer2, data.cFileName); 2759 strcat(buffer2, "\\*"); 2760 found = TRUE; 2761 } 2762 } 2763 ok ( FindClose(handle) == TRUE, "Failed to close handle %s\n", buffer2 ); 2764 2765 ok ( found, "Windows dir should not be empty\n" ); 2766 if (found) 2767 { 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 ); 2773 } 2774 2775 /* try FindFirstFileA on "C:\foo\" */ 2776 SetLastError( 0xdeadbeaf ); 2777 if (!GetTempFileNameA( buffer, "foo", 0, nonexistent )) 2778 { 2779 char tmp[MAX_PATH]; 2780 GetTempPathA( sizeof(tmp), tmp ); 2781 GetTempFileNameA( tmp, "foo", 0, nonexistent ); 2782 } 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 ); 2791 } 2792 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 ); 2800 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 ); 2809 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 ); 2818 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 ); 2827 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) 2840 { 2841 ok( 0 == data.nFileSizeHigh, "wrong size %ld\n", data.nFileSizeHigh ); 2842 ok( 0 == data.nFileSizeLow, "wrong size %ld\n", data.nFileSizeLow ); 2843 } 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" ); 2848 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) 2860 { 2861 ok( 0 == data.nFileSizeHigh, "wrong size %ld\n", data.nFileSizeHigh ); 2862 ok( 0 == data.nFileSizeLow, "wrong size %ld\n", data.nFileSizeLow ); 2863 } 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" ); 2868 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 ); 2877 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 ); 2886 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 ); 2899 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 ); 2908} 2909 2910static void test_FindNextFileA(void) 2911{ 2912 HANDLE handle; 2913 WIN32_FIND_DATAA search_results; 2914 int err; 2915 char buffer[5] = "C:\\*"; 2916 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)) 2921 { 2922 /* get to the end of the files */ 2923 } 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"); 2927} 2928 2929static void test_FindFirstFileExA(FINDEX_INFO_LEVELS level, FINDEX_SEARCH_OPS search_ops, DWORD flags) 2930{ 2931 WIN32_FIND_DATAA search_results; 2932 HANDLE handle; 2933 BOOL ret; 2934 2935 if (!pFindFirstFileExA) 2936 { 2937 win_skip("FindFirstFileExA() is missing\n"); 2938 return; 2939 } 2940 2941 trace("Running FindFirstFileExA tests with level=%d, search_ops=%d, flags=%lu\n", 2942 level, search_ops, flags); 2943 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) 2951 { 2952 win_skip("FindFirstFileExA is not implemented\n"); 2953 goto cleanup; 2954 } 2955 if ((flags & FIND_FIRST_EX_LARGE_FETCH) && handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER) 2956 { 2957 win_skip("FindFirstFileExA flag FIND_FIRST_EX_LARGE_FETCH not supported, skipping test\n"); 2958 goto cleanup; 2959 } 2960 if ((level == FindExInfoBasic) && handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER) 2961 { 2962 win_skip("FindFirstFileExA level FindExInfoBasic not supported, skipping test\n"); 2963 goto cleanup; 2964 } 2965 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]) 2968 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"); 2972 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"); 2976 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"); 2980 2981 SetLastError(0xdeadbeef); 2982 ret = FindNextFileA(handle, &search_results); 2983 if (!ret && (GetLastError() == ERROR_NO_MORE_FILES) && (search_ops == FindExSearchLimitToDirectories)) 2984 { 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"); 2989 2990 } 2991 else 2992 { 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"); 2996 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"); 3000 3001 ok(FindNextFileA(handle, &search_results) == FALSE, "Fetching sixth file should fail\n"); 3002 } 3003 3004#undef CHECK_NAME 3005#undef CHECK_LEVEL 3006 3007 FindClose( handle ); 3008 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) 3014 { 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 " : ""); 3019 } 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 ); 3024 3025cleanup: 3026 DeleteFileA("test-dir\\file1"); 3027 DeleteFileA("test-dir\\file2"); 3028 RemoveDirectoryA("test-dir\\dir1"); 3029 RemoveDirectoryA("test-dir"); 3030} 3031 3032static void test_FindFirstFile_wildcards(void) 3033{ 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" 3040 }; 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'"}, 3068 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'"}, 3092 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'"}, 3118 3119 {"?", ", '.', '..', 'a'"}, 3120 {"?.", ", '.', '..', 'a'"}, 3121 {"?. ", ", '.', '..', 'a'"}, 3122 {"? .*", ""}, 3123 {"??.", ", '.', '..', 'a', 'aa'"}, 3124 {"??. ", ", '.', '..', 'a', 'aa'"}, 3125 {"???.", ", '.', '..', 'a', 'aa', 'aaa'"}, 3126 {"?.??.", ", '.', '..', '.a', 'a', 'a.a', ' .a'"}, 3127 {". ?", ""}, 3128 3129 {">", ", '.', '..', 'a'"}, 3130 {">.", ", '.', '..', 'a'"}, 3131 {">. ", ", '.', '..', 'a'"}, 3132 {">>.", ", '.', '..', 'a', 'aa'"}, 3133 {">>. ", ", '.', '..', 'a', 'aa'"}, 3134 {">>>.", ", '.', '..', 'a', 'aa', 'aaa'"}, 3135 {">.>>.", ", '.', '..', '.a', 'a.a', ' .a'"}, 3136 }; 3137 3138 CreateDirectoryA("test-dir", NULL); 3139 SetCurrentDirectoryA("test-dir"); 3140 for (i = 0; i < ARRAY_SIZE(files); ++i) 3141 _lclose(_lcreat(files[i], 0)); 3142 3143 for (i = 0; i < ARRAY_SIZE(tests); ++i) 3144 { 3145 char correct[512]; 3146 char incorrect[512]; 3147 char missing[512]; 3148 3149 strcpy(missing, tests[i].result); 3150 correct[0] = incorrect[0] = 0; 3151 3152 handle = FindFirstFileA(tests[i].pattern, &find_data); 3153 if (handle != INVALID_HANDLE_VALUE) 3154 { 3155 do { 3156 char *ptr; 3157 char quoted[16]; 3158 3159 sprintf(quoted, ", '%.10s'", find_data.cFileName); 3160 3161 if ((ptr = strstr(missing, quoted))) 3162 { 3163 int len = strlen(quoted); 3164 while ((ptr[0] = ptr[len]) != 0) 3165 ++ptr; 3166 strcat(correct, quoted); 3167 } 3168 else 3169 strcat(incorrect, quoted); 3170 } while (FindNextFileA(handle, &find_data)); 3171 FindClose(handle); 3172 } 3173 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"); 3180 } 3181 3182 for (i = 0; i < ARRAY_SIZE(files); ++i) 3183 DeleteFileA(files[i]); 3184 SetCurrentDirectoryA(".."); 3185 RemoveDirectoryA("test-dir"); 3186} 3187 3188static int test_Mapfile_createtemp(HANDLE *handle) 3189{ 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) { 3195 3196 return 1; 3197 } 3198 3199 return 0; 3200} 3201 3202static void test_MapFile(void) 3203{ 3204 HANDLE handle; 3205 HANDLE hmap; 3206 UINT err; 3207 3208 ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n"); 3209 3210 hmap = CreateFileMappingA( handle, NULL, PAGE_READWRITE, 0, 0x1000, "named_file_map" ); 3211 ok( hmap != NULL, "mapping should work, I named it!\n" ); 3212 3213 ok( CloseHandle( hmap ), "can't close mapping handle\n"); 3214 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; 3222 3223 ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n"); 3224 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 ); 3230 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 ); 3236 3237 /* On XP you can now map again, on Win 95 you cannot. */ 3238 3239 ok( CloseHandle( handle ), "can't close file handle\n"); 3240 ok( DeleteFileA( filename ), "DeleteFile failed after map\n" ); 3241} 3242 3243static void test_GetFileType(void) 3244{ 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); 3264 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 ); 3273 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 ); 3279 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 ); 3293 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 ); 3303 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 ok( type == FILE_TYPE_UNKNOWN, "expected type unknown got %ld\n", type ); 3309 todo_wine 3310 ok( GetLastError() == NO_ERROR, "expected ERROR_NO_ERROR got %lx\n", GetLastError() ); 3311 CloseHandle( h ); 3312 3313 SetLastError( 12345678 ); 3314 type = GetFileType( GetCurrentProcess() ); 3315 ok( type == FILE_TYPE_UNKNOWN, "expected type unknown got %ld\n", type ); 3316 ok( GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE got %lx\n", GetLastError() ); 3317 3318 SetLastError( 12345678 ); 3319 type = GetFileType( GetCurrentThread() ); 3320 ok( type == FILE_TYPE_UNKNOWN, "expected type unknown got %ld\n", type ); 3321 ok( GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE got %lx\n", GetLastError() ); 3322 3323 h = CreateMutexW( NULL, TRUE, NULL ); 3324 ok( h != NULL, "CreateMutex failed\n" ); 3325 SetLastError( 12345678 ); 3326 type = GetFileType( h ); 3327 ok( type == FILE_TYPE_UNKNOWN, "expected type unknown got %ld\n", type ); 3328 ok( GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE got %lx\n", GetLastError() ); 3329 CloseHandle( h ); 3330} 3331 3332static int completion_count; 3333 3334static void CALLBACK FileIOComplete(DWORD dwError, DWORD dwBytes, LPOVERLAPPED ovl) 3335{ 3336/* printf("(%ld, %ld, %p { %ld, %ld, %ld, %ld, %p })\n", dwError, dwBytes, ovl, ovl->Internal, ovl->InternalHigh, ovl->Offset, ovl->OffsetHigh, ovl->hEvent);*/ 3337 ReleaseSemaphore(ovl->hEvent, 1, NULL); 3338 completion_count++; 3339} 3340 3341static void test_async_file_errors(void) 3342{ 3343 char szFile[MAX_PATH]; 3344 HANDLE hSem = CreateSemaphoreW(NULL, 1, 1, NULL); 3345 HANDLE hFile; 3346 LPVOID lpBuffer = HeapAlloc(GetProcessHeap(), 0, 4096); 3347 OVERLAPPED ovl; 3348#ifdef __REACTOS__ 3349 if (is_reactos()) { 3350 ok(FALSE, "FIXME: test_async_file_errors() crashes on ReactOS!\n"); 3351 return; 3352 } 3353#endif 3354 ovl.Offset = 0; 3355 ovl.OffsetHigh = 0; 3356 ovl.hEvent = hSem; 3357 completion_count = 0; 3358 szFile[0] = '\0'; 3359 GetWindowsDirectoryA(szFile, ARRAY_SIZE(szFile)-1-strlen("\\win.ini")); 3360 strcat(szFile, "\\win.ini"); 3361 hFile = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 3362 NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL); 3363 if (hFile == INVALID_HANDLE_VALUE) /* win9x doesn't like FILE_SHARE_DELETE */ 3364 hFile = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 3365 NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL); 3366 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA(%s ...) failed\n", szFile); 3367 while (TRUE) 3368 { 3369 BOOL res; 3370 DWORD count; 3371 while (WaitForSingleObjectEx(hSem, INFINITE, TRUE) == WAIT_IO_COMPLETION) 3372 ; 3373 res = ReadFileEx(hFile, lpBuffer, 4096, &ovl, FileIOComplete); 3374 /*printf("Offset = %ld, result = %s\n", ovl.Offset, res ? "TRUE" : "FALSE");*/ 3375 if (!res) 3376 break; 3377 if (!GetOverlappedResult(hFile, &ovl, &count, FALSE)) 3378 break; 3379 ovl.Offset += count; 3380 /* i/o completion routine only called if ReadFileEx returned success. 3381 * we only care about violations of this rule so undo what should have 3382 * been done */ 3383 completion_count--; 3384 } 3385 ok(completion_count == 0, "completion routine should only be called when ReadFileEx succeeds (this rule was violated %d times)\n", completion_count); 3386 /*printf("Error = %ld\n", GetLastError());*/ 3387 HeapFree(GetProcessHeap(), 0, lpBuffer); 3388} 3389 3390static BOOL user_apc_ran; 3391static void CALLBACK user_apc(ULONG_PTR param) 3392{ 3393 user_apc_ran = TRUE; 3394} 3395 3396static void test_read_write(void) 3397{ 3398 DWORD bytes, ret, old_prot; 3399 HANDLE hFile; 3400 char temp_path[MAX_PATH]; 3401 char filename[MAX_PATH]; 3402 char *mem; 3403 static const char prefix[] = "pfx"; 3404 3405 ret = GetTempPathA(MAX_PATH, temp_path); 3406 ok(ret != 0, "GetTempPathA error %ld\n", GetLastError()); 3407 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n"); 3408 3409 ret = GetTempFileNameA(temp_path, prefix, 0, filename); 3410 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError()); 3411 3412 hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, 3413 CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0); 3414 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %ld\n", GetLastError()); 3415 3416 user_apc_ran = FALSE; 3417 ret = QueueUserAPC(&user_apc, GetCurrentThread(), 0); 3418 ok(ret, "QueueUserAPC failed: %ld\n", GetLastError()); 3419 3420 SetLastError(12345678); 3421 bytes = 12345678; 3422 ret = WriteFile(hFile, NULL, 0, &bytes, NULL); 3423 ok(ret && GetLastError() == 12345678, 3424 "ret = %ld, error %ld\n", ret, GetLastError()); 3425 ok(!bytes, "bytes = %ld\n", bytes); 3426 3427 SetLastError(12345678); 3428 bytes = 12345678; 3429 ret = WriteFile(hFile, NULL, 10, &bytes, NULL); 3430 ok((!ret && GetLastError() == ERROR_INVALID_USER_BUFFER) || /* Win2k */ 3431 (ret && GetLastError() == 12345678), /* Win9x */ 3432 "ret = %ld, error %ld\n", ret, GetLastError()); 3433 ok(!bytes || /* Win2k */ 3434 bytes == 10, /* Win9x */ 3435 "bytes = %ld\n", bytes); 3436 3437 /* make sure the file contains data */ 3438 WriteFile(hFile, "this is the test data", 21, &bytes, NULL); 3439 SetFilePointer(hFile, 0, NULL, FILE_BEGIN); 3440 3441 SetLastError(12345678); 3442 bytes = 12345678; 3443 ret = ReadFile(hFile, NULL, 0, &bytes, NULL); 3444 ok(ret && GetLastError() == 12345678, 3445 "ret = %ld, error %ld\n", ret, GetLastError()); 3446 ok(!bytes, "bytes = %ld\n", bytes); 3447 3448 SetLastError(12345678); 3449 bytes = 12345678; 3450 ret = ReadFile(hFile, NULL, 10, &bytes, NULL); 3451 ok(!ret && (GetLastError() == ERROR_NOACCESS || /* Win2k */ 3452 GetLastError() == ERROR_INVALID_PARAMETER), /* Win9x */ 3453 "ret = %ld, error %ld\n", ret, GetLastError()); 3454 ok(!bytes, "bytes = %ld\n", bytes); 3455 3456 ok(user_apc_ran == FALSE, "UserAPC ran, file using alertable io mode\n"); 3457 SleepEx(0, TRUE); /* get rid of apc */ 3458 3459 /* test passing protected memory as buffer */ 3460 3461 mem = VirtualAlloc( NULL, 0x4000, MEM_COMMIT, PAGE_READWRITE ); 3462 ok( mem != NULL, "failed to allocate virtual mem error %lu\n", GetLastError() ); 3463 3464 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL ); 3465 ok( ret, "WriteFile failed error %lu\n", GetLastError() ); 3466 ok( bytes == 0x4000, "only wrote %lx bytes\n", bytes ); 3467 3468 ret = VirtualProtect( mem + 0x2000, 0x2000, PAGE_NOACCESS, &old_prot ); 3469 ok( ret, "VirtualProtect failed error %lu\n", GetLastError() ); 3470 3471 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL ); 3472 ok( !ret, "WriteFile succeeded\n" ); 3473 ok( GetLastError() == ERROR_INVALID_USER_BUFFER || 3474 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */ 3475 "wrong error %lu\n", GetLastError() ); 3476 ok( bytes == 0, "wrote %lx bytes\n", bytes ); 3477 3478 ret = WriteFile( (HANDLE)0xdead, mem, 0x4000, &bytes, NULL ); 3479 ok( !ret, "WriteFile succeeded\n" ); 3480 ok( GetLastError() == ERROR_INVALID_HANDLE || /* handle is checked before buffer on NT */ 3481 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */ 3482 "wrong error %lu\n", GetLastError() ); 3483 ok( bytes == 0, "wrote %lx bytes\n", bytes ); 3484 3485 ret = VirtualProtect( mem, 0x2000, PAGE_NOACCESS, &old_prot ); 3486 ok( ret, "VirtualProtect failed error %lu\n", GetLastError() ); 3487 3488 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL ); 3489 ok( !ret, "WriteFile succeeded\n" ); 3490 ok( GetLastError() == ERROR_INVALID_USER_BUFFER || 3491 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */ 3492 "wrong error %lu\n", GetLastError() ); 3493 ok( bytes == 0, "wrote %lx bytes\n", bytes ); 3494 3495 SetFilePointer( hFile, 0, NULL, FILE_BEGIN ); 3496 3497 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL ); 3498 ok( !ret, "ReadFile succeeded\n" ); 3499 ok( GetLastError() == ERROR_NOACCESS || 3500 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */ 3501 "wrong error %lu\n", GetLastError() ); 3502 ok( bytes == 0, "read %lx bytes\n", bytes ); 3503 3504 ret = VirtualProtect( mem, 0x2000, PAGE_READONLY, &old_prot ); 3505 ok( ret, "VirtualProtect failed error %lu\n", GetLastError() ); 3506 3507 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL ); 3508 ok( !ret, "ReadFile succeeded\n" ); 3509 ok( GetLastError() == ERROR_NOACCESS || 3510 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */ 3511 "wrong error %lu\n", GetLastError() ); 3512 ok( bytes == 0, "read %lx bytes\n", bytes ); 3513 3514 ret = VirtualProtect( mem, 0x2000, PAGE_READWRITE, &old_prot ); 3515 ok( ret, "VirtualProtect failed error %lu\n", GetLastError() ); 3516 3517 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL ); 3518 ok( !ret, "ReadFile succeeded\n" ); 3519 ok( GetLastError() == ERROR_NOACCESS || 3520 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */ 3521 "wrong error %lu\n", GetLastError() ); 3522 ok( bytes == 0, "read %lx bytes\n", bytes ); 3523 3524 SetFilePointer( hFile, 0x1234, NULL, FILE_BEGIN ); 3525 SetEndOfFile( hFile ); 3526 SetFilePointer( hFile, 0, NULL, FILE_BEGIN ); 3527 3528 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL ); 3529 ok( !ret, "ReadFile succeeded\n" ); 3530 ok( GetLastError() == ERROR_NOACCESS || 3531 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */ 3532 "wrong error %lu\n", GetLastError() ); 3533 ok( bytes == 0, "read %lx bytes\n", bytes ); 3534 3535 ret = ReadFile( hFile, mem, 0x2000, &bytes, NULL ); 3536 ok( ret, "ReadFile failed error %lu\n", GetLastError() ); 3537 ok( bytes == 0x1234, "read %lx bytes\n", bytes ); 3538 3539 ret = ReadFile( hFile, NULL, 1, &bytes, NULL ); 3540 ok( !ret, "ReadFile succeeded\n" ); 3541 ok( GetLastError() == ERROR_NOACCESS || 3542 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */ 3543 "wrong error %lu\n", GetLastError() ); 3544 ok( bytes == 0, "read %lx bytes\n", bytes ); 3545 3546 VirtualFree( mem, 0, MEM_RELEASE ); 3547 3548 ret = CloseHandle(hFile); 3549 ok( ret, "CloseHandle: error %ld\n", GetLastError()); 3550 ret = DeleteFileA(filename); 3551 ok( ret, "DeleteFileA: error %ld\n", GetLastError()); 3552} 3553 3554static void test_OpenFile(void) 3555{ 3556 HFILE hFile; 3557 OFSTRUCT ofs; 3558 BOOL ret; 3559 DWORD retval; 3560 3561 static const char file[] = "regedit.exe"; 3562 static const char foo[] = ".\\foo-bar-foo.baz"; 3563 static const char *foo_too_long = ".\\foo-bar-foo.baz+++++++++++++++" 3564 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" 3565 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" 3566 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" 3567 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" 3568 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"; 3569 char buff[MAX_PATH]; 3570 char buff_long[4*MAX_PATH]; 3571 char filled_0xA5[OFS_MAXPATHNAME]; 3572 char *p; 3573 UINT length; 3574 3575 /* Check for existing file */ 3576 if (!pGetSystemWindowsDirectoryA) 3577 length = GetWindowsDirectoryA(buff, MAX_PATH); 3578 else 3579 length = pGetSystemWindowsDirectoryA(buff, MAX_PATH); 3580 3581 if (length + sizeof(file) < MAX_PATH) 3582 { 3583 p = buff + strlen(buff); 3584 if (p > buff && p[-1] != '\\') *p++ = '\\'; 3585 strcpy( p, file ); 3586 memset(&ofs, 0xA5, sizeof(ofs)); 3587 SetLastError(0xfaceabee); 3588 3589 hFile = OpenFile(buff, &ofs, OF_EXIST); 3590 ok( hFile == TRUE, "%s not found : %ld\n", buff, GetLastError() ); 3591 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 3592 "GetLastError() returns %ld\n", GetLastError() ); 3593 ok( ofs.cBytes == sizeof(ofs), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes ); 3594 ok( ofs.nErrCode == ERROR_SUCCESS, "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode ); 3595 ok( lstrcmpiA(ofs.szPathName, buff) == 0, 3596 "OpenFile returned '%s', but was expected to return '%s' or string filled with 0xA5\n", 3597 ofs.szPathName, buff ); 3598 } 3599 3600 memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME); 3601 length = GetCurrentDirectoryA(MAX_PATH, buff); 3602 3603 /* Check for nonexistent file */ 3604 if (length + sizeof(foo) < MAX_PATH) 3605 { 3606 p = buff + strlen(buff); 3607 if (p > buff && p[-1] != '\\') *p++ = '\\'; 3608 strcpy( p, foo + 2 ); 3609 memset(&ofs, 0xA5, sizeof(ofs)); 3610 SetLastError(0xfaceabee); 3611 3612 hFile = OpenFile(foo, &ofs, OF_EXIST); 3613 ok( hFile == HFILE_ERROR, "hFile != HFILE_ERROR : %ld\n", GetLastError()); 3614 ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError() returns %ld\n", GetLastError() ); 3615 todo_wine 3616 ok( ofs.cBytes == 0xA5, "OpenFile set ofs.cBytes to %d\n", ofs.cBytes ); 3617 ok( ofs.nErrCode == ERROR_FILE_NOT_FOUND, "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode ); 3618 ok( lstrcmpiA(ofs.szPathName, buff) == 0 || strncmp(ofs.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, 3619 "OpenFile returned '%s', but was expected to return '%s' or string filled with 0xA5\n", 3620 ofs.szPathName, buff ); 3621 } 3622 3623 length = GetCurrentDirectoryA(MAX_PATH, buff_long); 3624 length += lstrlenA(foo_too_long + 1); 3625 3626 /* Check for nonexistent file with too long filename */ 3627 if (length >= OFS_MAXPATHNAME && length < sizeof(buff_long)) 3628 { 3629 lstrcatA(buff_long, foo_too_long + 1); /* Avoid '.' during concatenation */ 3630 memset(&ofs, 0xA5, sizeof(ofs)); 3631 SetLastError(0xfaceabee); 3632 3633 hFile = OpenFile(foo_too_long, &ofs, OF_EXIST); 3634 ok( hFile == HFILE_ERROR, "hFile != HFILE_ERROR : %ld\n", GetLastError()); 3635 ok( GetLastError() == ERROR_INVALID_DATA || GetLastError() == ERROR_FILENAME_EXCED_RANGE, 3636 "GetLastError() returns %ld\n", GetLastError() ); 3637 todo_wine 3638 ok( ofs.cBytes == 0xA5, "OpenFile set ofs.cBytes to %d\n", ofs.cBytes ); 3639 ok( ofs.nErrCode == ERROR_INVALID_DATA || ofs.nErrCode == ERROR_FILENAME_EXCED_RANGE, 3640 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode ); 3641 ok( strncmp(ofs.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0, 3642 "OpenFile returned '%s', but was expected to return string filled with 0xA5\n", 3643 ofs.szPathName ); 3644 } 3645 3646 memset(&ofs, 0xA5, sizeof(ofs)); 3647 SetLastError(0xfaceabee); 3648 /* Create an empty file */ 3649 hFile = OpenFile(filename, &ofs, OF_CREATE); 3650 ok( hFile != HFILE_ERROR, "OpenFile failed to create nonexistent file\n" ); 3651 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 3652 "GetLastError() returns %ld\n", GetLastError() ); 3653 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes ); 3654 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */, 3655 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode ); 3656 ret = _lclose(hFile); 3657 ok( !ret, "_lclose() returns %d\n", ret ); 3658 retval = GetFileAttributesA(filename); 3659 ok( retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %ld\n", GetLastError() ); 3660 3661 memset(&ofs, 0xA5, sizeof(ofs)); 3662 SetLastError(0xfaceabee); 3663 /* Check various opening options: */ 3664 /* for reading only, */ 3665 hFile = OpenFile(filename, &ofs, OF_READ); 3666 ok( hFile != HFILE_ERROR, "OpenFile failed on read\n" ); 3667 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 3668 "GetLastError() returns %ld\n", GetLastError() ); 3669 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes ); 3670 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */, 3671 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode ); 3672 ok( lstrcmpiA(ofs.szPathName, filename) == 0, 3673 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, filename ); 3674 ret = _lclose(hFile); 3675 ok( !ret, "_lclose() returns %d\n", ret ); 3676 3677 memset(&ofs, 0xA5, sizeof(ofs)); 3678 SetLastError(0xfaceabee); 3679 /* for writing only, */ 3680 hFile = OpenFile(filename, &ofs, OF_WRITE); 3681 ok( hFile != HFILE_ERROR, "OpenFile failed on write\n" ); 3682 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 3683 "GetLastError() returns %ld\n", GetLastError() ); 3684 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes ); 3685 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */, 3686 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode ); 3687 ok( lstrcmpiA(ofs.szPathName, filename) == 0, 3688 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, filename ); 3689 ret = _lclose(hFile); 3690 ok( !ret, "_lclose() returns %d\n", ret ); 3691 3692 memset(&ofs, 0xA5, sizeof(ofs)); 3693 SetLastError(0xfaceabee); 3694 /* for reading and writing, */ 3695 hFile = OpenFile(filename, &ofs, OF_READWRITE); 3696 ok( hFile != HFILE_ERROR, "OpenFile failed on read/write\n" ); 3697 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 3698 "GetLastError() returns %ld\n", GetLastError() ); 3699 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes ); 3700 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */, 3701 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode ); 3702 ok( lstrcmpiA(ofs.szPathName, filename) == 0, 3703 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, filename ); 3704 ret = _lclose(hFile); 3705 ok( !ret, "_lclose() returns %d\n", ret ); 3706 3707 memset(&ofs, 0xA5, sizeof(ofs)); 3708 SetLastError(0xfaceabee); 3709 /* for checking file presence. */ 3710 hFile = OpenFile(filename, &ofs, OF_EXIST); 3711 ok( hFile == 1, "OpenFile failed on finding our created file\n" ); 3712 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 3713 "GetLastError() returns %ld\n", GetLastError() ); 3714 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes ); 3715 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */, 3716 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode ); 3717 ok( lstrcmpiA(ofs.szPathName, filename) == 0, 3718 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, filename ); 3719 3720 memset(&ofs, 0xA5, sizeof(ofs)); 3721 SetLastError(0xfaceabee); 3722 /* Delete the file and make sure it doesn't exist anymore */ 3723 hFile = OpenFile(filename, &ofs, OF_DELETE); 3724 ok( hFile == 1, "OpenFile failed on delete (%d)\n", hFile ); 3725 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS, 3726 "GetLastError() returns %ld\n", GetLastError() ); 3727 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes ); 3728 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */, 3729 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode ); 3730 ok( lstrcmpiA(ofs.szPathName, filename) == 0, 3731 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, filename ); 3732 3733 retval = GetFileAttributesA(filename); 3734 ok( retval == INVALID_FILE_ATTRIBUTES, "GetFileAttributesA succeeded on deleted file\n" ); 3735} 3736 3737static void test_overlapped(void) 3738{ 3739 OVERLAPPED ov; 3740 DWORD r, result; 3741 3742 /* GetOverlappedResult crashes if the 2nd or 3rd param are NULL */ 3743 if (0) /* tested: WinXP */ 3744 { 3745 GetOverlappedResult(0, NULL, &result, FALSE); 3746 GetOverlappedResult(0, &ov, NULL, FALSE); 3747 GetOverlappedResult(0, NULL, NULL, FALSE); 3748 } 3749 3750 memset( &ov, 0, sizeof ov ); 3751 result = 1; 3752 r = GetOverlappedResult(0, &ov, &result, 0); 3753 if (r) 3754 ok( result == 0, "wrong result %lu\n", result ); 3755 else /* win9x */ 3756 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %lu\n", GetLastError() ); 3757 3758 result = 0; 3759 ov.Internal = 0; 3760 ov.InternalHigh = 0xabcd; 3761 r = GetOverlappedResult(0, &ov, &result, 0); 3762 if (r) 3763 ok( result == 0xabcd, "wrong result %lu\n", result ); 3764 else /* win9x */ 3765 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %lu\n", GetLastError() ); 3766 3767 SetLastError( 0xb00 ); 3768 result = 0; 3769 ov.Internal = STATUS_INVALID_HANDLE; 3770 ov.InternalHigh = 0xabcd; 3771 r = GetOverlappedResult(0, &ov, &result, 0); 3772 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %lu\n", GetLastError() ); 3773 ok( r == FALSE, "should return false\n"); 3774 ok( result == 0xabcd || result == 0 /* win9x */, "wrong result %lu\n", result ); 3775 3776 SetLastError( 0xb00 ); 3777 result = 0; 3778 ov.Internal = STATUS_PENDING; 3779 ov.InternalHigh = 0xabcd; 3780 r = GetOverlappedResult(0, &ov, &result, 0); 3781 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */, 3782 "wrong error %lu\n", GetLastError() ); 3783 ok( r == FALSE, "should return false\n"); 3784 ok( result == 0, "wrong result %lu\n", result ); 3785 3786 SetLastError( 0xb00 ); 3787 ov.hEvent = CreateEventW( NULL, 1, 1, NULL ); 3788 ov.Internal = STATUS_PENDING; 3789 ov.InternalHigh = 0xabcd; 3790 r = GetOverlappedResult(0, &ov, &result, 0); 3791 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */, 3792 "wrong error %lu\n", GetLastError() ); 3793 ok( r == FALSE, "should return false\n"); 3794 3795 r = GetOverlappedResult( 0, &ov, &result, TRUE ); 3796 ok( r == TRUE, "should return TRUE\n" ); 3797 ok( result == 0xabcd, "wrong result %lu\n", result ); 3798 ok( ov.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %08Ix\n", ov.Internal ); 3799 3800 ResetEvent( ov.hEvent ); 3801 3802 SetLastError( 0xb00 ); 3803 ov.Internal = STATUS_PENDING; 3804 ov.InternalHigh = 0; 3805 r = GetOverlappedResult(0, &ov, &result, 0); 3806 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */, 3807 "wrong error %lu\n", GetLastError() ); 3808 ok( r == FALSE, "should return false\n"); 3809 3810 r = CloseHandle( ov.hEvent ); 3811 ok( r == TRUE, "close handle failed\n"); 3812} 3813 3814static void test_RemoveDirectory(void) 3815{ 3816 int rc; 3817 char directory[] = "removeme"; 3818 3819 rc = CreateDirectoryA(directory, NULL); 3820 ok( rc, "Createdirectory failed, gle=%ld\n", GetLastError() ); 3821 3822 rc = SetCurrentDirectoryA(directory); 3823 ok( rc, "SetCurrentDirectory failed, gle=%ld\n", GetLastError() ); 3824 3825 rc = RemoveDirectoryA("."); 3826 if (!rc) 3827 { 3828 rc = SetCurrentDirectoryA(".."); 3829 ok( rc, "SetCurrentDirectory failed, gle=%ld\n", GetLastError() ); 3830 3831 rc = RemoveDirectoryA(directory); 3832 ok( rc, "RemoveDirectory failed, gle=%ld\n", GetLastError() ); 3833 } 3834} 3835 3836static BOOL check_file_time( const FILETIME *ft1, const FILETIME *ft2, UINT tolerance ) 3837{ 3838 ULONGLONG t1 = ((ULONGLONG)ft1->dwHighDateTime << 32) | ft1->dwLowDateTime; 3839 ULONGLONG t2 = ((ULONGLONG)ft2->dwHighDateTime << 32) | ft2->dwLowDateTime; 3840 return (t1 > t2 ? t1 - t2 : t2 - t1) <= tolerance; 3841} 3842 3843static void test_ReplaceFileA(void) 3844{ 3845 char replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH]; 3846 HANDLE hReplacedFile, hReplacementFile, hBackupFile, mapping; 3847 static const char replacedData[] = "file-to-replace"; 3848 static const char replacementData[] = "new-file"; 3849 static const char backupData[] = "backup-file"; 3850 FILETIME ftReplaced, ftReplacement, ftBackup; 3851 static const char prefix[] = "pfx"; 3852 char temp_path[MAX_PATH]; 3853 DWORD ret; 3854 BOOL retok, removeBackup = FALSE; 3855 char **argv; 3856 3857 ret = GetTempPathA(MAX_PATH, temp_path); 3858 ok(ret != 0, "GetTempPathA error %ld\n", GetLastError()); 3859 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n"); 3860 3861 ret = GetTempFileNameA(temp_path, prefix, 0, replaced); 3862 ok(ret != 0, "GetTempFileNameA error (replaced) %ld\n", GetLastError()); 3863 3864 ret = GetTempFileNameA(temp_path, prefix, 0, replacement); 3865 ok(ret != 0, "GetTempFileNameA error (replacement) %ld\n", GetLastError()); 3866 3867 ret = GetTempFileNameA(temp_path, prefix, 0, backup); 3868 ok(ret != 0, "GetTempFileNameA error (backup) %ld\n", GetLastError()); 3869 3870 /* place predictable data in the file to be replaced */ 3871 hReplacedFile = CreateFileA(replaced, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 ); 3872 ok(hReplacedFile != INVALID_HANDLE_VALUE, 3873 "failed to open replaced file\n"); 3874 retok = WriteFile(hReplacedFile, replacedData, sizeof(replacedData), &ret, NULL ); 3875 ok( retok && ret == sizeof(replacedData), 3876 "WriteFile error (replaced) %ld\n", GetLastError()); 3877 ok(GetFileSize(hReplacedFile, NULL) == sizeof(replacedData), 3878 "replaced file has wrong size\n"); 3879 /* place predictable data in the file to be the replacement */ 3880 hReplacementFile = CreateFileA(replacement, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 ); 3881 ok(hReplacementFile != INVALID_HANDLE_VALUE, 3882 "failed to open replacement file\n"); 3883 retok = WriteFile(hReplacementFile, replacementData, sizeof(replacementData), &ret, NULL ); 3884 ok( retok && ret == sizeof(replacementData), 3885 "WriteFile error (replacement) %ld\n", GetLastError()); 3886 ok(GetFileSize(hReplacementFile, NULL) == sizeof(replacementData), 3887 "replacement file has wrong size\n"); 3888 /* place predictable data in the backup file (to be over-written) */ 3889 hBackupFile = CreateFileA(backup, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 ); 3890 ok(hBackupFile != INVALID_HANDLE_VALUE, 3891 "failed to open backup file\n"); 3892 retok = WriteFile(hBackupFile, backupData, sizeof(backupData), &ret, NULL ); 3893 ok( retok && ret == sizeof(backupData), 3894 "WriteFile error (replacement) %ld\n", GetLastError()); 3895 ok(GetFileSize(hBackupFile, NULL) == sizeof(backupData), 3896 "backup file has wrong size\n"); 3897 /* change the filetime on the "replaced" file to ensure that it changes */ 3898 ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced); 3899 ok( ret, "GetFileTime error (replaced) %ld\n", GetLastError()); 3900 ftReplaced.dwLowDateTime -= 600000000; /* 60 second */ 3901 ret = SetFileTime(hReplacedFile, NULL, NULL, &ftReplaced); 3902 ok( ret, "SetFileTime error (replaced) %ld\n", GetLastError()); 3903 GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced); /* get the actual time back */ 3904 CloseHandle(hReplacedFile); 3905 /* change the filetime on the backup to ensure that it changes */ 3906 ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup); 3907 ok( ret, "GetFileTime error (backup) %ld\n", GetLastError()); 3908 ftBackup.dwLowDateTime -= 1200000000; /* 120 second */ 3909 ret = SetFileTime(hBackupFile, NULL, NULL, &ftBackup); 3910 ok( ret, "SetFileTime error (backup) %ld\n", GetLastError()); 3911 GetFileTime(hBackupFile, NULL, NULL, &ftBackup); /* get the actual time back */ 3912 CloseHandle(hBackupFile); 3913 /* get the filetime on the replacement file to perform checks */ 3914 ret = GetFileTime(hReplacementFile, NULL, NULL, &ftReplacement); 3915 ok( ret, "GetFileTime error (replacement) %ld\n", GetLastError()); 3916 CloseHandle(hReplacementFile); 3917 3918 /* perform replacement w/ backup 3919 * TODO: flags are not implemented 3920 */ 3921 SetLastError(0xdeadbeef); 3922 ret = ReplaceFileA(replaced, replacement, backup, 0, 0, 0); 3923 ok(ret, "ReplaceFileA: unexpected error %ld\n", GetLastError()); 3924 /* make sure that the backup has the size of the old "replaced" file */ 3925 hBackupFile = CreateFileA(backup, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); 3926 ok(hBackupFile != INVALID_HANDLE_VALUE, 3927 "failed to open backup file\n"); 3928 ret = GetFileSize(hBackupFile, NULL); 3929 ok(ret == sizeof(replacedData), 3930 "backup file has wrong size %ld\n", ret); 3931 /* make sure that the "replaced" file has the size of the replacement file */ 3932 hReplacedFile = CreateFileA(replaced, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); 3933 ok(hReplacedFile != INVALID_HANDLE_VALUE, 3934 "failed to open replaced file: %ld\n", GetLastError()); 3935 if (hReplacedFile != INVALID_HANDLE_VALUE) 3936 { 3937 ret = GetFileSize(hReplacedFile, NULL); 3938 ok(ret == sizeof(replacementData), 3939 "replaced file has wrong size %ld\n", ret); 3940 /* make sure that the replacement file no-longer exists */ 3941 hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); 3942 ok(hReplacementFile == INVALID_HANDLE_VALUE, 3943 "unexpected error, replacement file should not exist %ld\n", GetLastError()); 3944 /* make sure that the backup has the old "replaced" filetime */ 3945 ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup); 3946 ok( ret, "GetFileTime error (backup %ld\n", GetLastError()); 3947 ok(check_file_time(&ftBackup, &ftReplaced, 20000000), "backup file has wrong filetime\n"); 3948 CloseHandle(hBackupFile); 3949 /* make sure that the "replaced" has the old replacement filetime */ 3950 ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced); 3951 ok( ret, "GetFileTime error (backup %ld\n", GetLastError()); 3952 ok(check_file_time(&ftReplaced, &ftReplacement, 20000000), 3953 "replaced file has wrong filetime %lx%08lx / %lx%08lx\n", 3954 ftReplaced.dwHighDateTime, ftReplaced.dwLowDateTime, 3955 ftReplacement.dwHighDateTime, ftReplacement.dwLowDateTime ); 3956 CloseHandle(hReplacedFile); 3957 } 3958 else 3959 skip("couldn't open replacement file, skipping tests\n"); 3960 3961 /* re-create replacement file for pass w/o backup (blank) */ 3962 ret = GetTempFileNameA(temp_path, prefix, 0, replacement); 3963 ok(ret != 0, "GetTempFileNameA error (replacement) %ld\n", GetLastError()); 3964 /* perform replacement w/o backup 3965 * TODO: flags are not implemented 3966 */ 3967 SetLastError(0xdeadbeef); 3968 ret = ReplaceFileA(replaced, replacement, NULL, 0, 0, 0); 3969 ok(ret || GetLastError() == ERROR_ACCESS_DENIED, 3970 "ReplaceFileA: unexpected error %ld\n", GetLastError()); 3971 3972 /* re-create replacement file for pass w/ backup (backup-file not existing) */ 3973 DeleteFileA(replacement); 3974 ret = GetTempFileNameA(temp_path, prefix, 0, replacement); 3975 ok(ret != 0, "GetTempFileNameA error (replacement) %ld\n", GetLastError()); 3976 ret = DeleteFileA(backup); 3977 ok(ret, "DeleteFileA: error (backup) %ld\n", GetLastError()); 3978 /* perform replacement w/ backup (no pre-existing backup) 3979 * TODO: flags are not implemented 3980 */ 3981 SetLastError(0xdeadbeef); 3982 ret = ReplaceFileA(replaced, replacement, backup, 0, 0, 0); 3983 ok(ret || GetLastError() == ERROR_ACCESS_DENIED, 3984 "ReplaceFileA: unexpected error %ld\n", GetLastError()); 3985 if (ret) 3986 removeBackup = TRUE; 3987 3988 /* re-create replacement file for pass w/ no permissions to "replaced" */ 3989 DeleteFileA(replacement); 3990 ret = GetTempFileNameA(temp_path, prefix, 0, replacement); 3991 ok(ret != 0, "GetTempFileNameA error (replacement) %ld\n", GetLastError()); 3992 ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_READONLY); 3993 ok(ret || GetLastError() == ERROR_ACCESS_DENIED, 3994 "SetFileAttributesA: error setting to read only %ld\n", GetLastError()); 3995 /* perform replacement w/ backup (no permission to "replaced") 3996 * TODO: flags are not implemented 3997 */ 3998 SetLastError(0xdeadbeef); 3999 ret = ReplaceFileA(replaced, replacement, backup, 0, 0, 0); 4000 ok(ret == 0 && GetLastError() == ERROR_ACCESS_DENIED, "ReplaceFileA: unexpected error %ld\n", GetLastError()); 4001 /* make sure that the replacement file still exists */ 4002 hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); 4003 ok(hReplacementFile != INVALID_HANDLE_VALUE || 4004 broken(GetLastError() == ERROR_FILE_NOT_FOUND), /* win2k */ 4005 "unexpected error, replacement file should still exist %ld\n", GetLastError()); 4006 CloseHandle(hReplacementFile); 4007 ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_NORMAL); 4008 ok(ret || GetLastError() == ERROR_ACCESS_DENIED, 4009 "SetFileAttributesA: error setting to normal %ld\n", GetLastError()); 4010 4011 /* replacement readonly */ 4012 DeleteFileA(replacement); 4013 ret = GetTempFileNameA(temp_path, prefix, 0, replacement); 4014 ok(ret != 0, "GetTempFileNameA error (replacement) %#lx\n", GetLastError()); 4015 ret = SetFileAttributesA(replacement, FILE_ATTRIBUTE_READONLY); 4016 ok(ret, "SetFileAttributesA: error setting to readonly %#lx\n", GetLastError()); 4017 ret = ReplaceFileA(replaced, replacement, NULL, 0, 0, 0); 4018 ok(GetLastError() == ERROR_ACCESS_DENIED, "ReplaceFileA: unexpected error %#lx\n", GetLastError()); 4019 ret = SetFileAttributesA(replacement, FILE_ATTRIBUTE_NORMAL); 4020 ok(ret, "SetFileAttributesA: error setting to normal %#lx\n", GetLastError()); 4021 4022 /* re-create replacement file for pass w/ replaced opened with 4023 * the same permissions as an exe (Replicating an exe trying to 4024 * replace itself) 4025 */ 4026 DeleteFileA(replacement); 4027 ret = GetTempFileNameA(temp_path, prefix, 0, replacement); 4028 ok(ret != 0, "GetTempFileNameA error (replacement) %ld\n", GetLastError()); 4029 4030 /* make sure that the replaced file is opened like an exe*/ 4031 hReplacedFile = CreateFileA(replaced, GENERIC_READ | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0); 4032 ok(hReplacedFile != INVALID_HANDLE_VALUE, 4033 "unexpected error, replaced file should be able to be opened %ld\n", GetLastError()); 4034 /*Calling ReplaceFileA on an exe should succeed*/ 4035 ret = ReplaceFileA(replaced, replacement, NULL, 0, 0, 0); 4036 ok(ret, "ReplaceFileA: unexpected error %ld\n", GetLastError()); 4037 CloseHandle(hReplacedFile); 4038 4039 /* replace file while replacement is opened */ 4040 ret = GetTempFileNameA(temp_path, prefix, 0, replacement); 4041 ok(ret != 0, "GetTempFileNameA error (replacement) %ld\n", GetLastError()); 4042 hReplacementFile = CreateFileA(replacement, GENERIC_READ | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0); 4043 ok(hReplacementFile != INVALID_HANDLE_VALUE, "unexpected error, replacement file should be able to be opened %ld\n", 4044 GetLastError()); 4045 ret = ReplaceFileA(replaced, replacement, NULL, 0, 0, 0); 4046 ok(!ret, "expect failure\n"); 4047 ok(GetLastError() == ERROR_SHARING_VIOLATION, "expect ERROR_SHARING_VIOLATION, got %#lx.\n", GetLastError()); 4048 CloseHandle(hReplacementFile); 4049 4050 /* replacement file still exists, make pass w/o "replaced" */ 4051 ret = DeleteFileA(replaced); 4052 ok(ret || GetLastError() == ERROR_ACCESS_DENIED, 4053 "DeleteFileA: error (replaced) %ld\n", GetLastError()); 4054 /* perform replacement w/ backup (no pre-existing backup or "replaced") 4055 * TODO: flags are not implemented 4056 */ 4057 SetLastError(0xdeadbeef); 4058 ret = ReplaceFileA(replaced, replacement, backup, 0, 0, 0); 4059 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND || 4060 GetLastError() == ERROR_ACCESS_DENIED), 4061 "ReplaceFileA: unexpected error %ld\n", GetLastError()); 4062 4063 /* perform replacement w/o existing "replacement" file 4064 * TODO: flags are not implemented 4065 */ 4066 SetLastError(0xdeadbeef); 4067 ret = ReplaceFileA(replaced, replacement, NULL, 0, 0, 0); 4068 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND || 4069 GetLastError() == ERROR_ACCESS_DENIED), 4070 "ReplaceFileA: unexpected error %ld\n", GetLastError()); 4071 DeleteFileA( replacement ); 4072 4073 /* 4074 * if the first round (w/ backup) worked then as long as there is no 4075 * failure then there is no need to check this round (w/ backup is the 4076 * more complete case) 4077 */ 4078 4079 /* delete temporary files, replacement and replaced are already deleted */ 4080 if (removeBackup) 4081 { 4082 ret = DeleteFileA(backup); 4083 ok(ret || 4084 broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */ 4085 "DeleteFileA: error (backup) %ld\n", GetLastError()); 4086 } 4087 4088 ret = GetTempFileNameA(temp_path, prefix, 0, replaced); 4089 ok(ret, "got error %lu\n", GetLastError()); 4090 hReplacedFile = CreateFileA(replaced, 0, 0, NULL, OPEN_EXISTING, 0, 0); 4091 ok(hReplacedFile != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError()); 4092 4093 ret = GetTempFileNameA(temp_path, prefix, 0, replacement); 4094 ok(ret, "got error %lu\n", GetLastError()); 4095 4096 ret = ReplaceFileA(replaced, replacement, NULL, 0, 0, 0); 4097 ok(ret, "got error %lu\n", GetLastError()); 4098 4099 CloseHandle(hReplacedFile); 4100 ret = DeleteFileA(replaced); 4101 ok(ret, "got error %lu\n", GetLastError()); 4102 4103 winetest_get_mainargs(&argv); 4104 4105 ret = CopyFileA(argv[0], replaced, FALSE); 4106 ok(ret, "got error %lu\n", GetLastError()); 4107 hReplacedFile = CreateFileA(replaced, GENERIC_READ, 4108 FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0); 4109 ok(hReplacedFile != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError()); 4110 4111 mapping = CreateFileMappingA(hReplacedFile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL); 4112 ok(!!mapping, "got error %lu\n", GetLastError()); 4113 4114 ret = GetTempFileNameA(temp_path, prefix, 0, replacement); 4115 ok(ret, "got error %lu\n", GetLastError()); 4116 4117 ret = ReplaceFileA(replaced, replacement, NULL, 0, 0, 0); 4118 ok(ret, "got error %lu\n", GetLastError()); 4119 4120 CloseHandle(mapping); 4121 CloseHandle(hReplacedFile); 4122 ret = DeleteFileA(replaced); 4123 ok(ret, "got error %lu\n", GetLastError()); 4124} 4125 4126/* 4127 * ReplaceFileW is a simpler case of ReplaceFileA, there is no 4128 * need to be as thorough. 4129 */ 4130static void test_ReplaceFileW(void) 4131{ 4132 WCHAR replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH]; 4133 static const WCHAR prefix[] = {'p','f','x',0}; 4134 WCHAR temp_path[MAX_PATH]; 4135 DWORD ret; 4136 BOOL removeBackup = FALSE; 4137 4138 if (!pReplaceFileW) 4139 { 4140 win_skip("ReplaceFileW() is missing\n"); 4141 return; 4142 } 4143 4144 ret = GetTempPathW(MAX_PATH, temp_path); 4145 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 4146 { 4147 win_skip("GetTempPathW is not available\n"); 4148 return; 4149 } 4150 ok(ret != 0, "GetTempPathW error %ld\n", GetLastError()); 4151 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n"); 4152 4153 ret = GetTempFileNameW(temp_path, prefix, 0, replaced); 4154 ok(ret != 0, "GetTempFileNameW error (replaced) %ld\n", GetLastError()); 4155 4156 ret = GetTempFileNameW(temp_path, prefix, 0, replacement); 4157 ok(ret != 0, "GetTempFileNameW error (replacement) %ld\n", GetLastError()); 4158 4159 ret = GetTempFileNameW(temp_path, prefix, 0, backup); 4160 ok(ret != 0, "GetTempFileNameW error (backup) %ld\n", GetLastError()); 4161 4162 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0); 4163 ok(ret, "ReplaceFileW: error %ld\n", GetLastError()); 4164 4165 ret = GetTempFileNameW(temp_path, prefix, 0, replacement); 4166 ok(ret != 0, "GetTempFileNameW error (replacement) %ld\n", GetLastError()); 4167 ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0); 4168 ok(ret || GetLastError() == ERROR_ACCESS_DENIED, 4169 "ReplaceFileW: error %ld\n", GetLastError()); 4170 4171 ret = GetTempFileNameW(temp_path, prefix, 0, replacement); 4172 ok(ret != 0, "GetTempFileNameW error (replacement) %ld\n", GetLastError()); 4173 ret = DeleteFileW(backup); 4174 ok(ret, "DeleteFileW: error (backup) %ld\n", GetLastError()); 4175 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0); 4176 ok(ret || GetLastError() == ERROR_ACCESS_DENIED, 4177 "ReplaceFileW: error %ld\n", GetLastError()); 4178 4179 ret = GetTempFileNameW(temp_path, prefix, 0, replacement); 4180 ok(ret != 0, "GetTempFileNameW error (replacement) %ld\n", GetLastError()); 4181 ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_READONLY); 4182 ok(ret || GetLastError() == ERROR_ACCESS_DENIED, 4183 "SetFileAttributesW: error setting to read only %ld\n", GetLastError()); 4184 4185 SetLastError(0xdeadbeef); 4186 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0); 4187 ok(!ret, "expected failure\n"); 4188 ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError()); 4189 ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_NORMAL); 4190 ok(ret || GetLastError() == ERROR_ACCESS_DENIED, 4191 "SetFileAttributesW: error setting to normal %ld\n", GetLastError()); 4192 if (ret) 4193 removeBackup = TRUE; 4194 4195 ret = DeleteFileW(replaced); 4196 ok(ret, "DeleteFileW: error (replaced) %ld\n", GetLastError()); 4197 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0); 4198 ok(!ret, "ReplaceFileW: error %ld\n", GetLastError()); 4199 4200 ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0); 4201 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND || 4202 GetLastError() == ERROR_ACCESS_DENIED), 4203 "ReplaceFileW: unexpected error %ld\n", GetLastError()); 4204 DeleteFileW( replacement ); 4205 4206 if (removeBackup) 4207 { 4208 ret = DeleteFileW(backup); 4209 ok(ret || 4210 broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */ 4211 "DeleteFileW: error (backup) %ld\n", GetLastError()); 4212 } 4213} 4214 4215static void test_CreateFile(void) 4216{ 4217 static const struct test_data 4218 { 4219 DWORD disposition, access, error, clean_up; 4220 } td[] = 4221 { 4222 /* 0 */ { 0, 0, ERROR_INVALID_PARAMETER, 0 }, 4223 /* 1 */ { 0, GENERIC_READ, ERROR_INVALID_PARAMETER, 0 }, 4224 /* 2 */ { 0, GENERIC_READ|GENERIC_WRITE, ERROR_INVALID_PARAMETER, 0 }, 4225 /* 3 */ { CREATE_NEW, 0, ERROR_FILE_EXISTS, 1 }, 4226 /* 4 */ { CREATE_NEW, 0, 0, 1 }, 4227 /* 5 */ { CREATE_NEW, GENERIC_READ, 0, 1 }, 4228 /* 6 */ { CREATE_NEW, GENERIC_WRITE, 0, 1 }, 4229 /* 7 */ { CREATE_NEW, GENERIC_READ|GENERIC_WRITE, 0, 0 }, 4230 /* 8 */ { CREATE_ALWAYS, 0, 0, 0 }, 4231 /* 9 */ { CREATE_ALWAYS, GENERIC_READ, 0, 0 }, 4232 /* 10*/ { CREATE_ALWAYS, GENERIC_WRITE, 0, 0 }, 4233 /* 11*/ { CREATE_ALWAYS, GENERIC_READ|GENERIC_WRITE, 0, 1 }, 4234 /* 12*/ { OPEN_EXISTING, 0, ERROR_FILE_NOT_FOUND, 0 }, 4235 /* 13*/ { CREATE_ALWAYS, 0, 0, 0 }, 4236 /* 14*/ { OPEN_EXISTING, 0, 0, 0 }, 4237 /* 15*/ { OPEN_EXISTING, GENERIC_READ, 0, 0 }, 4238 /* 16*/ { OPEN_EXISTING, GENERIC_WRITE, 0, 0 }, 4239 /* 17*/ { OPEN_EXISTING, GENERIC_READ|GENERIC_WRITE, 0, 1 }, 4240 /* 18*/ { OPEN_ALWAYS, 0, 0, 0 }, 4241 /* 19*/ { OPEN_ALWAYS, GENERIC_READ, 0, 0 }, 4242 /* 20*/ { OPEN_ALWAYS, GENERIC_WRITE, 0, 0 }, 4243 /* 21*/ { OPEN_ALWAYS, GENERIC_READ|GENERIC_WRITE, 0, 0 }, 4244 /* 22*/ { TRUNCATE_EXISTING, 0, ERROR_INVALID_PARAMETER, 0 }, 4245 /* 23*/ { TRUNCATE_EXISTING, GENERIC_READ, ERROR_INVALID_PARAMETER, 0 }, 4246 /* 24*/ { TRUNCATE_EXISTING, GENERIC_WRITE, 0, 0 }, 4247 /* 25*/ { TRUNCATE_EXISTING, GENERIC_READ|GENERIC_WRITE, 0, 0 }, 4248 /* 26*/ { TRUNCATE_EXISTING, FILE_WRITE_DATA, ERROR_INVALID_PARAMETER, 0 } 4249 }; 4250 char temp_path[MAX_PATH]; 4251 char file_name[MAX_PATH]; 4252 DWORD i, ret, written; 4253 HANDLE hfile; 4254 4255 GetTempPathA(MAX_PATH, temp_path); 4256 GetTempFileNameA(temp_path, "tmp", 0, file_name); 4257 4258 i = strlen(temp_path); 4259 if (i && temp_path[i - 1] == '\\') temp_path[i - 1] = 0; 4260 4261 for (i = 0; i <= 5; i++) 4262 { 4263 SetLastError(0xdeadbeef); 4264 hfile = CreateFileA(temp_path, GENERIC_READ, 0, NULL, i, 0, 0); 4265 ok(hfile == INVALID_HANDLE_VALUE, "CreateFile should fail\n"); 4266 if (i == 0 || i == 5) 4267 { 4268 /* FIXME: remove once Wine is fixed */ 4269 todo_wine_if (i == 5) 4270 ok(GetLastError() == ERROR_INVALID_PARAMETER, "%ld: expected ERROR_INVALID_PARAMETER, got %ld\n", i, GetLastError()); 4271 } 4272 else 4273 { 4274 /* FIXME: remove once Wine is fixed */ 4275 todo_wine_if (i == 1) 4276 ok(GetLastError() == ERROR_ACCESS_DENIED, "%ld: expected ERROR_ACCESS_DENIED, got %ld\n", i, GetLastError()); 4277 } 4278 4279 SetLastError(0xdeadbeef); 4280 hfile = CreateFileA(temp_path, GENERIC_WRITE, 0, NULL, i, 0, 0); 4281 ok(hfile == INVALID_HANDLE_VALUE, "CreateFile should fail\n"); 4282 if (i == 0) 4283 ok(GetLastError() == ERROR_INVALID_PARAMETER, "%ld: expected ERROR_INVALID_PARAMETER, got %ld\n", i, GetLastError()); 4284 else 4285 { 4286 /* FIXME: remove once Wine is fixed */ 4287 todo_wine_if (i == 1) 4288 ok(GetLastError() == ERROR_ACCESS_DENIED, "%ld: expected ERROR_ACCESS_DENIED, got %ld\n", i, GetLastError()); 4289 } 4290 } 4291 4292 for (i = 0; i < ARRAY_SIZE(td); i++) 4293 { 4294 SetLastError(0xdeadbeef); 4295 hfile = CreateFileA(file_name, td[i].access, 0, NULL, td[i].disposition, 0, 0); 4296 if (!td[i].error) 4297 { 4298 ok(hfile != INVALID_HANDLE_VALUE, "%ld: CreateFile error %ld\n", i, GetLastError()); 4299 written = 0xdeadbeef; 4300 SetLastError(0xdeadbeef); 4301 ret = WriteFile(hfile, &td[i].error, sizeof(td[i].error), &written, NULL); 4302 if (td[i].access & GENERIC_WRITE) 4303 ok(ret, "%ld: WriteFile error %ld\n", i, GetLastError()); 4304 else 4305 { 4306 ok(!ret, "%ld: WriteFile should fail\n", i); 4307 ok(GetLastError() == ERROR_ACCESS_DENIED, "%ld: expected ERROR_ACCESS_DENIED, got %ld\n", i, GetLastError()); 4308 } 4309 SetLastError(0xdeadbeef); 4310 ret = SetFileTime(hfile, NULL, NULL, NULL); 4311 if (td[i].access & GENERIC_WRITE) /* actually FILE_WRITE_ATTRIBUTES */ 4312 ok(ret, "%ld: SetFileTime error %ld\n", i, GetLastError()); 4313 else 4314 { 4315 todo_wine 4316 { 4317 ok(!ret, "%ld: SetFileTime should fail\n", i); 4318 ok(GetLastError() == ERROR_ACCESS_DENIED, "%ld: expected ERROR_ACCESS_DENIED, got %ld\n", i, GetLastError()); 4319 } 4320 } 4321 CloseHandle(hfile); 4322 } 4323 else 4324 { 4325 /* FIXME: remove the condition below once Wine is fixed */ 4326 if (td[i].disposition == TRUNCATE_EXISTING && !(td[i].access & GENERIC_WRITE)) 4327 { 4328 todo_wine 4329 { 4330 ok(hfile == INVALID_HANDLE_VALUE, "%ld: CreateFile should fail\n", i); 4331 ok(GetLastError() == td[i].error, "%ld: expected %ld, got %ld\n", i, td[i].error, GetLastError()); 4332 } 4333 CloseHandle(hfile); 4334 } 4335 else 4336 { 4337 ok(hfile == INVALID_HANDLE_VALUE, "%ld: CreateFile should fail\n", i); 4338 ok(GetLastError() == td[i].error, "%ld: expected %ld, got %ld\n", i, td[i].error, GetLastError()); 4339 } 4340 } 4341 4342 if (td[i].clean_up) DeleteFileA(file_name); 4343 } 4344 4345 DeleteFileA(file_name); 4346} 4347 4348static void test_GetFileInformationByHandleEx(void) 4349{ 4350 int i; 4351 char tempPath[MAX_PATH], tempFileName[MAX_PATH], buffer[1024], *strPtr; 4352 BOOL ret; 4353 DWORD ret2, written; 4354 HANDLE directory, file; 4355 FILE_ID_BOTH_DIR_INFO *bothDirInfo; 4356 FILE_BASIC_INFO *basicInfo; 4357 FILE_STANDARD_INFO *standardInfo; 4358 FILE_NAME_INFO *nameInfo; 4359 LARGE_INTEGER prevWrite; 4360 FILE_IO_PRIORITY_HINT_INFO priohintinfo; 4361 FILE_ALLOCATION_INFO allocinfo; 4362 FILE_DISPOSITION_INFO dispinfo; 4363 FILE_END_OF_FILE_INFO eofinfo; 4364 FILE_RENAME_INFO renameinfo; 4365 4366 struct { 4367 FILE_INFO_BY_HANDLE_CLASS handleClass; 4368 void *ptr; 4369 DWORD size; 4370 DWORD errorCode; 4371 } checks[] = { 4372 {0xdeadbeef, NULL, 0, ERROR_INVALID_PARAMETER}, 4373 {FileIdBothDirectoryInfo, NULL, 0, ERROR_BAD_LENGTH}, 4374 {FileIdBothDirectoryInfo, NULL, sizeof(buffer), ERROR_NOACCESS}, 4375 {FileIdBothDirectoryInfo, buffer, 0, ERROR_BAD_LENGTH}}; 4376 4377 if (!pGetFileInformationByHandleEx) 4378 { 4379 win_skip("GetFileInformationByHandleEx is missing.\n"); 4380 return; 4381 } 4382 4383 ret2 = GetTempPathA(sizeof(tempPath), tempPath); 4384 ok(ret2, "GetFileInformationByHandleEx: GetTempPathA failed, got error %lu.\n", GetLastError()); 4385 4386 /* ensure the existence of a file in the temp folder */ 4387 ret2 = GetTempFileNameA(tempPath, "abc", 0, tempFileName); 4388 ok(ret2, "GetFileInformationByHandleEx: GetTempFileNameA failed, got error %lu.\n", GetLastError()); 4389 ret2 = GetFileAttributesA(tempFileName); 4390 ok(ret2 != INVALID_FILE_ATTRIBUTES, "GetFileInformationByHandleEx: " 4391 "GetFileAttributesA failed to find the temp file, got error %lu.\n", GetLastError()); 4392 4393 directory = CreateFileA(tempPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 4394 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); 4395 ok(directory != INVALID_HANDLE_VALUE, "GetFileInformationByHandleEx: failed to open the temp folder, " 4396 "got error %lu.\n", GetLastError()); 4397 4398 for (i = 0; i < ARRAY_SIZE(checks); i += 1) 4399 { 4400 SetLastError(0xdeadbeef); 4401 ret = pGetFileInformationByHandleEx(directory, checks[i].handleClass, checks[i].ptr, checks[i].size); 4402 ok(!ret && GetLastError() == checks[i].errorCode, "GetFileInformationByHandleEx: expected error %lu, " 4403 "got %lu.\n", checks[i].errorCode, GetLastError()); 4404 } 4405 4406 while (TRUE) 4407 { 4408 memset(buffer, 0xff, sizeof(buffer)); 4409 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer)); 4410 if (!ret && GetLastError() == ERROR_NO_MORE_FILES) 4411 break; 4412 ok(ret, "GetFileInformationByHandleEx: failed to query for FileIdBothDirectoryInfo, got error %lu.\n", GetLastError()); 4413 if (!ret) 4414 break; 4415 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer; 4416 while (TRUE) 4417 { 4418 ok(bothDirInfo->FileAttributes != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file attributes.\n"); 4419 ok(bothDirInfo->FileId.u.LowPart != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file id.\n"); 4420 ok(bothDirInfo->FileNameLength != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file name length.\n"); 4421 if (!bothDirInfo->NextEntryOffset) 4422 break; 4423 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)(((char *)bothDirInfo) + bothDirInfo->NextEntryOffset); 4424 } 4425 } 4426 4427 CloseHandle(directory); 4428 4429 file = CreateFileA(tempFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 4430 NULL, OPEN_EXISTING, 0, NULL); 4431 ok(file != INVALID_HANDLE_VALUE, "GetFileInformationByHandleEx: failed to open the temp file, " 4432 "got error %lu.\n", GetLastError()); 4433 4434 /* Test FileBasicInfo; make sure the write time changes when a file is updated */ 4435 memset(buffer, 0xff, sizeof(buffer)); 4436 ret = pGetFileInformationByHandleEx(file, FileBasicInfo, buffer, sizeof(buffer)); 4437 ok(ret, "GetFileInformationByHandleEx: failed to get FileBasicInfo, %lu\n", GetLastError()); 4438 basicInfo = (FILE_BASIC_INFO *)buffer; 4439 prevWrite = basicInfo->LastWriteTime; 4440 CloseHandle(file); 4441 4442 Sleep(30); /* Make sure a new write time is different from the previous */ 4443 4444 /* Write something to the file, to make sure the write time has changed */ 4445 file = CreateFileA(tempFileName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 4446 NULL, OPEN_EXISTING, 0, NULL); 4447 ok(file != INVALID_HANDLE_VALUE, "GetFileInformationByHandleEx: failed to open the temp file, " 4448 "got error %lu.\n", GetLastError()); 4449 ret = WriteFile(file, tempFileName, strlen(tempFileName), &written, NULL); 4450 ok(ret, "GetFileInformationByHandleEx: Write failed\n"); 4451 CloseHandle(file); 4452 4453 file = CreateFileA(tempFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 4454 NULL, OPEN_EXISTING, 0, NULL); 4455 ok(file != INVALID_HANDLE_VALUE, "GetFileInformationByHandleEx: failed to open the temp file, " 4456 "got error %lu.\n", GetLastError()); 4457 4458 memset(buffer, 0xff, sizeof(buffer)); 4459 ret = pGetFileInformationByHandleEx(file, FileBasicInfo, buffer, sizeof(buffer)); 4460 ok(ret, "GetFileInformationByHandleEx: failed to get FileBasicInfo, %lu\n", GetLastError()); 4461 basicInfo = (FILE_BASIC_INFO *)buffer; 4462 /* Could also check that the creation time didn't change - on windows 4463 * it doesn't, but on wine, it does change even if it shouldn't. */ 4464 ok(basicInfo->LastWriteTime.QuadPart != prevWrite.QuadPart, 4465 "GetFileInformationByHandleEx: last write time didn't change\n"); 4466 4467 /* Test FileStandardInfo, check some basic parameters */ 4468 memset(buffer, 0xff, sizeof(buffer)); 4469 ret = pGetFileInformationByHandleEx(file, FileStandardInfo, buffer, sizeof(buffer)); 4470 ok(ret, "GetFileInformationByHandleEx: failed to get FileStandardInfo, %lu\n", GetLastError()); 4471 standardInfo = (FILE_STANDARD_INFO *)buffer; 4472 ok(standardInfo->NumberOfLinks == 1, "GetFileInformationByHandleEx: Unexpected number of links\n"); 4473 ok(standardInfo->DeletePending == FALSE, "GetFileInformationByHandleEx: Unexpected pending delete\n"); 4474 ok(standardInfo->Directory == FALSE, "GetFileInformationByHandleEx: Incorrect directory flag\n"); 4475 4476 /* Test FileNameInfo */ 4477 memset(buffer, 0xff, sizeof(buffer)); 4478 ret = pGetFileInformationByHandleEx(file, FileNameInfo, buffer, sizeof(buffer)); 4479 ok(ret, "GetFileInformationByHandleEx: failed to get FileNameInfo, %lu\n", GetLastError()); 4480 nameInfo = (FILE_NAME_INFO *)buffer; 4481 strPtr = strchr(tempFileName, '\\'); 4482 ok(strPtr != NULL, "GetFileInformationByHandleEx: Temp filename didn't contain backslash\n"); 4483 ok(nameInfo->FileNameLength == strlen(strPtr) * 2, 4484 "GetFileInformationByHandleEx: Incorrect file name length\n"); 4485 for (i = 0; i < nameInfo->FileNameLength/2; i++) 4486 ok(strPtr[i] == nameInfo->FileName[i], "Incorrect filename char %d: %c vs %c\n", 4487 i, strPtr[i], nameInfo->FileName[i]); 4488 4489 /* invalid classes */ 4490 SetLastError(0xdeadbeef); 4491 ret = pGetFileInformationByHandleEx(file, FileEndOfFileInfo, &eofinfo, sizeof(eofinfo)); 4492 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError()); 4493 4494 SetLastError(0xdeadbeef); 4495 ret = pGetFileInformationByHandleEx(file, FileIoPriorityHintInfo, &priohintinfo, sizeof(priohintinfo)); 4496 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError()); 4497 4498 SetLastError(0xdeadbeef); 4499 ret = pGetFileInformationByHandleEx(file, FileAllocationInfo, &allocinfo, sizeof(allocinfo)); 4500 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError()); 4501 4502 SetLastError(0xdeadbeef); 4503 ret = pGetFileInformationByHandleEx(file, FileDispositionInfo, &dispinfo, sizeof(dispinfo)); 4504 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError()); 4505 4506 SetLastError(0xdeadbeef); 4507 ret = pGetFileInformationByHandleEx(file, FileRenameInfo, &renameinfo, sizeof(renameinfo)); 4508 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError()); 4509 4510 CloseHandle(file); 4511 DeleteFileA(tempFileName); 4512} 4513 4514static void test_OpenFileById(void) 4515{ 4516 char tempPath[MAX_PATH], tempFileName[MAX_PATH], buffer[256], tickCount[256]; 4517 WCHAR tempFileNameW[MAX_PATH]; 4518 BOOL ret, found; 4519 DWORD ret2, count, tempFileNameLen; 4520 HANDLE directory, handle, tempFile; 4521 FILE_ID_BOTH_DIR_INFO *bothDirInfo; 4522 FILE_ID_DESCRIPTOR fileIdDescr; 4523 4524 if (!pGetFileInformationByHandleEx || !pOpenFileById) 4525 { 4526 win_skip("GetFileInformationByHandleEx or OpenFileById is missing.\n"); 4527 return; 4528 } 4529 4530 ret2 = GetTempPathA(sizeof(tempPath), tempPath); 4531 ok(ret2, "OpenFileById: GetTempPath failed, got error %lu.\n", GetLastError()); 4532 4533 /* ensure the existence of a file in the temp folder */ 4534 ret2 = GetTempFileNameA(tempPath, "abc", 0, tempFileName); 4535 ok(ret2, "OpenFileById: GetTempFileNameA failed, got error %lu.\n", GetLastError()); 4536 ret2 = GetFileAttributesA(tempFileName); 4537 ok(ret2 != INVALID_FILE_ATTRIBUTES, 4538 "OpenFileById: GetFileAttributesA failed to find the temp file, got error %lu\n", GetLastError()); 4539 4540 ret2 = MultiByteToWideChar(CP_ACP, 0, tempFileName + strlen(tempPath), -1, tempFileNameW, ARRAY_SIZE(tempFileNameW)); 4541 ok(ret2, "OpenFileById: MultiByteToWideChar failed to convert tempFileName, got error %lu.\n", GetLastError()); 4542 tempFileNameLen = ret2 - 1; 4543 4544 tempFile = CreateFileA(tempFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 4545 ok(tempFile != INVALID_HANDLE_VALUE, "OpenFileById: failed to create a temp file, " 4546 "got error %lu.\n", GetLastError()); 4547 ret2 = sprintf(tickCount, "%lu", GetTickCount()); 4548 ret = WriteFile(tempFile, tickCount, ret2, &count, NULL); 4549 ok(ret, "OpenFileById: WriteFile failed, got error %lu.\n", GetLastError()); 4550 CloseHandle(tempFile); 4551 4552 directory = CreateFileA(tempPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 4553 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); 4554 ok(directory != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the temp folder, " 4555 "got error %lu.\n", GetLastError()); 4556 4557 /* get info about the temp folder itself */ 4558 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer; 4559 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer)); 4560 ok(ret, "OpenFileById: failed to query for FileIdBothDirectoryInfo, got error %lu.\n", GetLastError()); 4561 ok(bothDirInfo->FileNameLength == sizeof(WCHAR) && bothDirInfo->FileName[0] == '.', 4562 "OpenFileById: failed to return the temp folder at the first entry, got error %lu.\n", GetLastError()); 4563 4564 /* open the temp folder itself */ 4565 fileIdDescr.dwSize = sizeof(fileIdDescr); 4566 fileIdDescr.Type = FileIdType; 4567 fileIdDescr.FileId = bothDirInfo->FileId; 4568 handle = pOpenFileById(directory, &fileIdDescr, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0); 4569 todo_wine 4570 ok(handle != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the temp folder itself, got error %lu.\n", GetLastError()); 4571 CloseHandle(handle); 4572 4573 /* find the temp file in the temp folder */ 4574 found = FALSE; 4575 while (!found) 4576 { 4577 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer)); 4578 ok(ret, "OpenFileById: failed to query for FileIdBothDirectoryInfo, got error %lu.\n", GetLastError()); 4579 if (!ret) 4580 break; 4581 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer; 4582 while (TRUE) 4583 { 4584 if (tempFileNameLen == bothDirInfo->FileNameLength / sizeof(WCHAR) && 4585 memcmp(tempFileNameW, bothDirInfo->FileName, bothDirInfo->FileNameLength) == 0) 4586 { 4587 found = TRUE; 4588 break; 4589 } 4590 if (!bothDirInfo->NextEntryOffset) 4591 break; 4592 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)(((char *)bothDirInfo) + bothDirInfo->NextEntryOffset); 4593 } 4594 } 4595 ok(found, "OpenFileById: failed to find the temp file in the temp folder.\n"); 4596 4597 SetLastError(0xdeadbeef); 4598 handle = pOpenFileById(directory, NULL, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0); 4599 ok(handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER, 4600 "OpenFileById: expected ERROR_INVALID_PARAMETER, got error %lu.\n", GetLastError()); 4601 4602 fileIdDescr.dwSize = sizeof(fileIdDescr); 4603 fileIdDescr.Type = FileIdType; 4604 fileIdDescr.FileId = bothDirInfo->FileId; 4605 handle = pOpenFileById(directory, &fileIdDescr, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0); 4606 ok(handle != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the file, got error %lu.\n", GetLastError()); 4607 4608 ret = ReadFile(handle, buffer, sizeof(buffer), &count, NULL); 4609 buffer[count] = 0; 4610 ok(ret, "OpenFileById: ReadFile failed, got error %lu.\n", GetLastError()); 4611 ok(strcmp(tickCount, buffer) == 0, "OpenFileById: invalid contents of the temp file.\n"); 4612 4613 CloseHandle(handle); 4614 CloseHandle(directory); 4615 DeleteFileA(tempFileName); 4616} 4617 4618static void test_SetFileValidData(void) 4619{ 4620 BOOL ret; 4621 HANDLE handle; 4622 DWORD error, count; 4623 char path[MAX_PATH], filename[MAX_PATH]; 4624 TOKEN_PRIVILEGES privs; 4625 HANDLE token = NULL; 4626 4627 if (!pSetFileValidData) 4628 { 4629 win_skip("SetFileValidData is missing\n"); 4630 return; 4631 } 4632 GetTempPathA(sizeof(path), path); 4633 GetTempFileNameA(path, "tst", 0, filename); 4634 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); 4635 WriteFile(handle, "test", sizeof("test") - 1, &count, NULL); 4636 CloseHandle(handle); 4637 4638 SetLastError(0xdeadbeef); 4639 ret = pSetFileValidData(INVALID_HANDLE_VALUE, 0); 4640 error = GetLastError(); 4641 ok(!ret, "SetFileValidData succeeded\n"); 4642 ok(error == ERROR_INVALID_HANDLE, "got %lu\n", error); 4643 4644 SetLastError(0xdeadbeef); 4645 ret = pSetFileValidData(INVALID_HANDLE_VALUE, -1); 4646 error = GetLastError(); 4647 ok(!ret, "SetFileValidData succeeded\n"); 4648 ok(error == ERROR_INVALID_HANDLE, "got %lu\n", error); 4649 4650 /* file opened for reading */ 4651 handle = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); 4652 4653 SetLastError(0xdeadbeef); 4654 ret = pSetFileValidData(handle, 0); 4655 ok(!ret, "SetFileValidData succeeded\n"); 4656 error = GetLastError(); 4657 ok(error == ERROR_ACCESS_DENIED, "got %lu\n", error); 4658 4659 SetLastError(0xdeadbeef); 4660 ret = pSetFileValidData(handle, -1); 4661 error = GetLastError(); 4662 ok(!ret, "SetFileValidData succeeded\n"); 4663 ok(error == ERROR_ACCESS_DENIED, "got %lu\n", error); 4664 CloseHandle(handle); 4665 4666 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); 4667 4668 SetLastError(0xdeadbeef); 4669 ret = pSetFileValidData(handle, 0); 4670 error = GetLastError(); 4671 ok(!ret, "SetFileValidData succeeded\n"); 4672 todo_wine ok(error == ERROR_PRIVILEGE_NOT_HELD, "got %lu\n", error); 4673 CloseHandle(handle); 4674 4675 privs.PrivilegeCount = 1; 4676 privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 4677 4678 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token) || 4679 !LookupPrivilegeValueA(NULL, SE_MANAGE_VOLUME_NAME, &privs.Privileges[0].Luid) || 4680 !AdjustTokenPrivileges(token, FALSE, &privs, sizeof(privs), NULL, NULL) || 4681 GetLastError() == ERROR_NOT_ALL_ASSIGNED) 4682 { 4683 win_skip("cannot enable SE_MANAGE_VOLUME_NAME privilege\n"); 4684 CloseHandle(token); 4685 DeleteFileA(filename); 4686 return; 4687 } 4688 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); 4689 4690 SetLastError(0xdeadbeef); 4691 ret = pSetFileValidData(handle, 0); 4692 error = GetLastError(); 4693 ok(!ret, "SetFileValidData succeeded\n"); 4694 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error); 4695 4696 SetLastError(0xdeadbeef); 4697 ret = pSetFileValidData(handle, -1); 4698 error = GetLastError(); 4699 ok(!ret, "SetFileValidData succeeded\n"); 4700 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error); 4701 4702 SetLastError(0xdeadbeef); 4703 ret = pSetFileValidData(handle, 2); 4704 error = GetLastError(); 4705 todo_wine ok(!ret, "SetFileValidData succeeded\n"); 4706 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error); 4707 4708 ret = pSetFileValidData(handle, 4); 4709 ok(ret, "SetFileValidData failed %lu\n", GetLastError()); 4710 4711 SetLastError(0xdeadbeef); 4712 ret = pSetFileValidData(handle, 8); 4713 error = GetLastError(); 4714 ok(!ret, "SetFileValidData succeeded\n"); 4715 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error); 4716 4717 count = SetFilePointer(handle, 1024, NULL, FILE_END); 4718 ok(count != INVALID_SET_FILE_POINTER, "SetFilePointer failed %lu\n", GetLastError()); 4719 ret = SetEndOfFile(handle); 4720 ok(ret, "SetEndOfFile failed %lu\n", GetLastError()); 4721 4722 SetLastError(0xdeadbeef); 4723 ret = pSetFileValidData(handle, 2); 4724 error = GetLastError(); 4725 todo_wine ok(!ret, "SetFileValidData succeeded\n"); 4726 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error); 4727 4728 ret = pSetFileValidData(handle, 4); 4729 ok(ret, "SetFileValidData failed %lu\n", GetLastError()); 4730 4731 ret = pSetFileValidData(handle, 8); 4732 ok(ret, "SetFileValidData failed %lu\n", GetLastError()); 4733 4734 ret = pSetFileValidData(handle, 4); 4735 error = GetLastError(); 4736 todo_wine ok(!ret, "SetFileValidData succeeded\n"); 4737 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error); 4738 4739 ret = pSetFileValidData(handle, 1024); 4740 ok(ret, "SetFileValidData failed %lu\n", GetLastError()); 4741 4742 ret = pSetFileValidData(handle, 2048); 4743 error = GetLastError(); 4744 ok(!ret, "SetFileValidData succeeded\n"); 4745 ok(error == ERROR_INVALID_PARAMETER, "got %lu\n", error); 4746 4747 privs.Privileges[0].Attributes = 0; 4748 AdjustTokenPrivileges(token, FALSE, &privs, sizeof(privs), NULL, NULL); 4749 4750 CloseHandle(token); 4751 CloseHandle(handle); 4752 DeleteFileA(filename); 4753} 4754 4755static void test_ReOpenFile(void) 4756{ 4757 char path[MAX_PATH], filename[MAX_PATH], buffer[4]; 4758 HANDLE file, new; 4759 unsigned int i; 4760 DWORD size; 4761 BOOL ret; 4762 4763 static const DWORD invalid_attributes[] = 4764 { 4765 FILE_ATTRIBUTE_ARCHIVE, 4766 FILE_ATTRIBUTE_ENCRYPTED, 4767 FILE_ATTRIBUTE_HIDDEN, 4768 FILE_ATTRIBUTE_NORMAL, 4769 FILE_ATTRIBUTE_OFFLINE, 4770 FILE_ATTRIBUTE_READONLY, 4771 FILE_ATTRIBUTE_SYSTEM, 4772 FILE_ATTRIBUTE_TEMPORARY, 4773 }; 4774 4775 static const DWORD valid_attributes[] = 4776 { 4777 FILE_FLAG_BACKUP_SEMANTICS, 4778 FILE_FLAG_NO_BUFFERING, 4779 FILE_FLAG_OVERLAPPED, 4780 FILE_FLAG_RANDOM_ACCESS, 4781 FILE_FLAG_SEQUENTIAL_SCAN, 4782 FILE_FLAG_WRITE_THROUGH, 4783 }; 4784 4785 if (!pReOpenFile) 4786 { 4787 win_skip("ReOpenFile() is not available\n"); 4788 return; 4789 } 4790 4791 GetTempPathA(sizeof(path), path); 4792 GetTempFileNameA(path, "tst", 0, filename); 4793 4794 file = CreateFileA(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, 4795 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); 4796 ok(file != INVALID_HANDLE_VALUE, "failed to create file, error %lu\n", GetLastError()); 4797 ret = WriteFile(file, "foo", 4, &size, NULL); 4798 ok(ret, "failed to write file, error %lu\n", GetLastError()); 4799 4800 for (i = 0; i < ARRAY_SIZE(invalid_attributes); ++i) 4801 { 4802 SetLastError(0xdeadbeef); 4803 new = pReOpenFile(file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, invalid_attributes[i]); 4804 ok(new == INVALID_HANDLE_VALUE, "got %p\n", new); 4805 ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError()); 4806 } 4807 4808 new = pReOpenFile(file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0); 4809 ok(new != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError()); 4810 4811 ret = ReadFile(new, buffer, sizeof(buffer), &size, NULL); 4812 ok(ret, "failed to read file, error %lu\n", GetLastError()); 4813 ok(size == 4, "got size %lu\n", size); 4814 ok(!strcmp(buffer, "foo"), "got wrong data\n"); 4815 CloseHandle(new); 4816 4817 for (i = 0; i < ARRAY_SIZE(valid_attributes); ++i) 4818 { 4819 new = pReOpenFile(file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, valid_attributes[i]); 4820 ok(new != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError()); 4821 CloseHandle(new); 4822 } 4823 4824 SetLastError(0xdeadbeef); 4825 new = pReOpenFile(file, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0); 4826 ok(new == INVALID_HANDLE_VALUE, "got %p\n", new); 4827 ok(GetLastError() == ERROR_SHARING_VIOLATION, "got error %lu\n", GetLastError()); 4828 4829 CloseHandle(file); 4830 ret = DeleteFileA(filename); 4831 ok(ret, "failed to delete file, error %lu\n", GetLastError()); 4832 4833 file = CreateNamedPipeA("\\\\.\\pipe\\test_pipe", PIPE_ACCESS_DUPLEX, 0, 1, 1000, 1000, 1000, NULL); 4834 ok(file != INVALID_HANDLE_VALUE, "failed to create pipe, error %lu\n", GetLastError()); 4835 4836 new = pReOpenFile(file, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0); 4837 ok(new != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError()); 4838 4839 ret = WriteFile(file, "foo", 4, &size, NULL); 4840 ok(ret, "failed to write file, error %lu\n", GetLastError()); 4841 ret = ReadFile(new, buffer, sizeof(buffer), &size, NULL); 4842 ok(ret, "failed to read file, error %lu\n", GetLastError()); 4843 ok(size == 4, "got size %lu\n", size); 4844 ok(!strcmp(buffer, "foo"), "got wrong data\n"); 4845 4846 CloseHandle(new); 4847 CloseHandle(file); 4848} 4849 4850static void test_WriteFileGather(void) 4851{ 4852 char temp_path[MAX_PATH], filename[MAX_PATH]; 4853 HANDLE hfile, hiocp1, hiocp2, evt; 4854 DWORD ret, size, tx; 4855 ULONG_PTR key; 4856 FILE_SEGMENT_ELEMENT fse[2]; 4857 OVERLAPPED ovl, *povl = NULL; 4858 SYSTEM_INFO si; 4859 char *wbuf = NULL, *rbuf1, *rbuf2; 4860 BOOL br; 4861 4862 evt = CreateEventW( NULL, TRUE, FALSE, NULL ); 4863 4864 ret = GetTempPathA( MAX_PATH, temp_path ); 4865 ok( ret != 0, "GetTempPathA error %ld\n", GetLastError() ); 4866 ok( ret < MAX_PATH, "temp path should fit into MAX_PATH\n" ); 4867 ret = GetTempFileNameA( temp_path, "wfg", 0, filename ); 4868 ok( ret != 0, "GetTempFileNameA error %ld\n", GetLastError() ); 4869 4870 hfile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 4871 FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL, 0 ); 4872 ok( hfile != INVALID_HANDLE_VALUE, "CreateFile failed err %lu\n", GetLastError() ); 4873 if (hfile == INVALID_HANDLE_VALUE) return; 4874 4875 hiocp1 = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 999, 0 ); 4876 hiocp2 = CreateIoCompletionPort( hfile, hiocp1, 999, 0 ); 4877 ok( hiocp2 != 0, "CreateIoCompletionPort failed err %lu\n", GetLastError() ); 4878 4879 GetSystemInfo( &si ); 4880 wbuf = VirtualAlloc( NULL, si.dwPageSize, MEM_COMMIT, PAGE_READWRITE ); 4881 ok( wbuf != NULL, "VirtualAlloc failed err %lu\n", GetLastError() ); 4882 4883 rbuf1 = VirtualAlloc( NULL, si.dwPageSize, MEM_COMMIT, PAGE_READWRITE ); 4884 ok( rbuf1 != NULL, "VirtualAlloc failed err %lu\n", GetLastError() ); 4885 4886 rbuf2 = VirtualAlloc( NULL, si.dwPageSize, MEM_COMMIT, PAGE_READWRITE ); 4887 ok( rbuf2 != NULL, "VirtualAlloc failed err %lu\n", GetLastError() ); 4888 4889 memset( &ovl, 0, sizeof(ovl) ); 4890 ovl.hEvent = evt; 4891 memset( fse, 0, sizeof(fse) ); 4892 fse[0].Buffer = wbuf; 4893 memset( wbuf, 0x42, si.dwPageSize ); 4894 SetLastError( 0xdeadbeef ); 4895 if (!WriteFileGather( hfile, fse, si.dwPageSize, NULL, &ovl )) 4896 ok( GetLastError() == ERROR_IO_PENDING, "WriteFileGather failed err %lu\n", GetLastError() ); 4897 4898 ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 1000 ); 4899 ok( ret, "GetQueuedCompletionStatus failed err %lu\n", GetLastError()); 4900 ok( povl == &ovl, "wrong ovl %p\n", povl ); 4901 4902#ifdef __REACTOS__ 4903 if (is_reactos()) { 4904 ok(FALSE, "FIXME: Calls to GetOverlappedResult hang on ReactOS!\n"); 4905 } else { 4906#endif 4907 tx = 0; 4908 br = GetOverlappedResult( hfile, &ovl, &tx, TRUE ); 4909 ok( br == TRUE, "GetOverlappedResult failed: %lu\n", GetLastError() ); 4910 ok( tx == si.dwPageSize, "got unexpected bytes transferred: %lu\n", tx ); 4911#ifdef __REACTOS__ 4912 } 4913#endif 4914 4915 ResetEvent( evt ); 4916 4917 /* read exact size */ 4918 memset( &ovl, 0, sizeof(ovl) ); 4919 ovl.hEvent = evt; 4920 memset( fse, 0, sizeof(fse) ); 4921 fse[0].Buffer = rbuf1; 4922 memset( rbuf1, 0, si.dwPageSize ); 4923 SetLastError( 0xdeadbeef ); 4924 br = ReadFileScatter( hfile, fse, si.dwPageSize, NULL, &ovl ); 4925 ok( br == FALSE, "ReadFileScatter should be asynchronous\n" ); 4926 ok( GetLastError() == ERROR_IO_PENDING, "ReadFileScatter failed err %lu\n", GetLastError() ); 4927 4928 ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 1000 ); 4929 ok( ret, "GetQueuedCompletionStatus failed err %lu\n", GetLastError()); 4930 ok( povl == &ovl, "wrong ovl %p\n", povl ); 4931 4932#ifdef __REACTOS__ 4933 if (is_reactos()) { 4934 ok(FALSE, "FIXME: Calls to GetOverlappedResult hang on ReactOS!\n"); 4935 } else { 4936#endif 4937 tx = 0; 4938 br = GetOverlappedResult( hfile, &ovl, &tx, TRUE ); 4939 ok( br == TRUE, "GetOverlappedResult failed: %lu\n", GetLastError() ); 4940 ok( tx == si.dwPageSize, "got unexpected bytes transferred: %lu\n", tx ); 4941#ifdef __REACTOS__ 4942 } 4943#endif 4944 4945 ok( memcmp( rbuf1, wbuf, si.dwPageSize ) == 0, 4946 "data was not read into buffer\n" ); 4947 4948 ResetEvent( evt ); 4949 4950 /* start read at EOF */ 4951 memset( &ovl, 0, sizeof(ovl) ); 4952 ovl.hEvent = evt; 4953 ovl.OffsetHigh = 0; 4954 ovl.Offset = si.dwPageSize; 4955 memset( fse, 0, sizeof(fse) ); 4956 fse[0].Buffer = rbuf1; 4957 SetLastError( 0xdeadbeef ); 4958 br = ReadFileScatter( hfile, fse, si.dwPageSize, NULL, &ovl ); 4959 ok( br == FALSE, "ReadFileScatter should have failed\n" ); 4960 ok( GetLastError() == ERROR_HANDLE_EOF || 4961 GetLastError() == ERROR_IO_PENDING, "ReadFileScatter gave wrong error %lu\n", GetLastError() ); 4962 if (GetLastError() == ERROR_IO_PENDING) 4963 { 4964 SetLastError( 0xdeadbeef ); 4965 ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 1000 ); 4966 ok( !ret, "GetQueuedCompletionStatus should have returned failure\n" ); 4967 ok( GetLastError() == ERROR_HANDLE_EOF, "Got wrong error: %lu\n", GetLastError() ); 4968 ok( povl == &ovl, "wrong ovl %p\n", povl ); 4969 4970 SetLastError( 0xdeadbeef ); 4971 br = GetOverlappedResult( hfile, &ovl, &tx, TRUE ); 4972 ok( br == FALSE, "GetOverlappedResult should have failed\n" ); 4973 ok( GetLastError() == ERROR_HANDLE_EOF, "Got wrong error: %lu\n", GetLastError() ); 4974 } 4975 else 4976 { 4977 SetLastError( 0xdeadbeef ); 4978 ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 100 ); 4979 ok( !ret, "GetQueuedCompletionStatus failed err %lu\n", GetLastError() ); 4980 ok( GetLastError() == WAIT_TIMEOUT, "GetQueuedCompletionStatus gave wrong error %lu\n", GetLastError() ); 4981 ok( povl == NULL, "wrong ovl %p\n", povl ); 4982 } 4983 4984 ResetEvent( evt ); 4985 4986 /* read past EOF */ 4987 memset( &ovl, 0, sizeof(ovl) ); 4988 ovl.hEvent = evt; 4989 memset( fse, 0, sizeof(fse) ); 4990 fse[0].Buffer = rbuf1; 4991 fse[1].Buffer = rbuf2; 4992 memset( rbuf1, 0, si.dwPageSize ); 4993 memset( rbuf2, 0x17, si.dwPageSize ); 4994 SetLastError( 0xdeadbeef ); 4995 br = ReadFileScatter( hfile, fse, si.dwPageSize * 2, NULL, &ovl ); 4996 ok( br == FALSE, "ReadFileScatter should be asynchronous\n" ); 4997 ok( GetLastError() == ERROR_IO_PENDING, "ReadFileScatter failed err %lu\n", GetLastError() ); 4998 4999 ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 1000 ); 5000 ok( ret, "GetQueuedCompletionStatus failed err %lu\n", GetLastError() ); 5001 ok( povl == &ovl, "wrong ovl %p\n", povl ); 5002 5003#ifdef __REACTOS__ 5004 if (is_reactos()) { 5005 ok(FALSE, "FIXME: Calls to GetOverlappedResult hang on ReactOS!\n"); 5006 } else { 5007#endif 5008 tx = 0; 5009 br = GetOverlappedResult( hfile, &ovl, &tx, TRUE ); 5010 ok( br == TRUE, "GetOverlappedResult failed: %lu\n", GetLastError() ); 5011 ok( tx == si.dwPageSize, "got unexpected bytes transferred: %lu\n", tx ); 5012#ifdef __REACTOS__ 5013 } 5014#endif 5015 5016 ok( memcmp( rbuf1, wbuf, si.dwPageSize ) == 0, 5017 "data was not read into buffer\n" ); 5018 memset( rbuf1, 0x17, si.dwPageSize ); 5019 ok( memcmp( rbuf2, rbuf1, si.dwPageSize ) == 0, 5020 "data should not have been read into buffer\n" ); 5021 5022 ResetEvent( evt ); 5023 5024 /* partial page read */ 5025 memset( &ovl, 0, sizeof(ovl) ); 5026 ovl.hEvent = evt; 5027 memset( fse, 0, sizeof(fse) ); 5028 fse[0].Buffer = rbuf1; 5029 memset( rbuf1, 0, si.dwPageSize ); 5030 SetLastError( 0xdeadbeef ); 5031 br = ReadFileScatter( hfile, fse, si.dwPageSize / 2, NULL, &ovl ); 5032 ok( br == FALSE, "ReadFileScatter should be asynchronous\n" ); 5033 ok( GetLastError() == ERROR_IO_PENDING, "ReadFileScatter failed err %lu\n", GetLastError() ); 5034 5035 ret = GetQueuedCompletionStatus( hiocp2, &size, &key, &povl, 1000 ); 5036 ok( ret, "GetQueuedCompletionStatus failed err %lu\n", GetLastError() ); 5037 ok( povl == &ovl, "wrong ovl %p\n", povl ); 5038 5039#ifdef __REACTOS__ 5040 if (is_reactos()) { 5041 ok(FALSE, "FIXME: Calls to GetOverlappedResult hang on ReactOS!\n"); 5042 } else { 5043#endif 5044 tx = 0; 5045 br = GetOverlappedResult( hfile, &ovl, &tx, TRUE ); 5046 ok( br == TRUE, "GetOverlappedResult failed: %lu\n", GetLastError() ); 5047 ok( tx == si.dwPageSize / 2, "got unexpected bytes transferred: %lu\n", tx ); 5048#ifdef __REACTOS__ 5049 } 5050#endif 5051 5052 ok( memcmp( rbuf1, wbuf, si.dwPageSize / 2 ) == 0, 5053 "invalid data was read into buffer\n" ); 5054 memset( rbuf2, 0, si.dwPageSize ); 5055 ok( memcmp( rbuf1 + si.dwPageSize / 2, rbuf2, si.dwPageSize - si.dwPageSize / 2 ) == 0, 5056 "invalid data was read into buffer\n" ); 5057 5058 if (pSetFileCompletionNotificationModes) 5059 { 5060 br = pSetFileCompletionNotificationModes(hfile, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS); 5061 ok(br, "SetFileCompletionNotificationModes failed, error %lu.\n", GetLastError()); 5062 5063 br = ReadFileScatter(hfile, fse, si.dwPageSize, NULL, &ovl); 5064 ok(br == FALSE, "ReadFileScatter should be asynchronous.\n"); 5065 ok(GetLastError() == ERROR_IO_PENDING, "ReadFileScatter failed, error %lu.\n", GetLastError()); 5066 5067 br = GetQueuedCompletionStatus(hiocp2, &size, &key, &povl, 1000); 5068 ok(br, "GetQueuedCompletionStatus failed, err %lu.\n", GetLastError()); 5069 ok(povl == &ovl, "Wrong ovl %p.\n", povl); 5070 5071#ifdef __REACTOS__ 5072 if (is_reactos()) { 5073 ok(FALSE, "FIXME: Calls to GetOverlappedResult hang on ReactOS!\n"); 5074 } else { 5075#endif 5076 br = GetOverlappedResult(hfile, &ovl, &tx, TRUE); 5077 ok(br, "GetOverlappedResult failed, err %lu.\n", GetLastError()); 5078 ok(tx == si.dwPageSize, "Got unexpected size %lu.\n", tx); 5079#ifdef __REACTOS__ 5080 } 5081#endif 5082 5083 ResetEvent(evt); 5084 } 5085 else 5086 win_skip("SetFileCompletionNotificationModes not available.\n"); 5087 5088 CloseHandle( hfile ); 5089 CloseHandle( hiocp1 ); 5090 CloseHandle( hiocp2 ); 5091 5092 /* file handle must be overlapped */ 5093 hfile = CreateFileA( filename, GENERIC_READ, 0, 0, OPEN_EXISTING, 5094 FILE_FLAG_NO_BUFFERING | FILE_ATTRIBUTE_NORMAL, 0 ); 5095 ok( hfile != INVALID_HANDLE_VALUE, "CreateFile failed err %lu\n", GetLastError() ); 5096 5097 memset( &ovl, 0, sizeof(ovl) ); 5098 memset( fse, 0, sizeof(fse) ); 5099 fse[0].Buffer = rbuf1; 5100 memset( rbuf1, 0, si.dwPageSize ); 5101 SetLastError( 0xdeadbeef ); 5102 br = ReadFileScatter( hfile, fse, si.dwPageSize, NULL, &ovl ); 5103 ok( br == FALSE, "ReadFileScatter should fail\n" ); 5104 ok( GetLastError() == ERROR_INVALID_PARAMETER, "ReadFileScatter failed err %lu\n", GetLastError() ); 5105 5106 VirtualFree( wbuf, 0, MEM_RELEASE ); 5107 VirtualFree( rbuf1, 0, MEM_RELEASE ); 5108 VirtualFree( rbuf2, 0, MEM_RELEASE ); 5109 CloseHandle( evt ); 5110 DeleteFileA( filename ); 5111} 5112 5113static unsigned file_map_access(unsigned access) 5114{ 5115 if (access & GENERIC_READ) access |= FILE_GENERIC_READ; 5116 if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE; 5117 if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE; 5118 if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS; 5119 return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL); 5120} 5121 5122static BOOL is_access_compatible(unsigned obj_access, unsigned desired_access) 5123{ 5124 obj_access = file_map_access(obj_access); 5125 desired_access = file_map_access(desired_access); 5126 return (obj_access & desired_access) == desired_access; 5127} 5128 5129static void test_file_access(void) 5130{ 5131 static const struct 5132 { 5133 unsigned access, create_error, write_error, read_error; 5134 } td[] = 5135 { 5136 { GENERIC_READ | GENERIC_WRITE, 0, 0, 0 }, 5137 { GENERIC_WRITE, 0, 0, ERROR_ACCESS_DENIED }, 5138 { GENERIC_READ, 0, ERROR_ACCESS_DENIED, 0 }, 5139 { FILE_READ_DATA | FILE_WRITE_DATA, 0, 0, 0 }, 5140 { FILE_WRITE_DATA, 0, 0, ERROR_ACCESS_DENIED }, 5141 { FILE_READ_DATA, 0, ERROR_ACCESS_DENIED, 0 }, 5142 { FILE_APPEND_DATA, 0, 0, ERROR_ACCESS_DENIED }, 5143 { FILE_READ_DATA | FILE_APPEND_DATA, 0, 0, 0 }, 5144 { FILE_WRITE_DATA | FILE_APPEND_DATA, 0, 0, ERROR_ACCESS_DENIED }, 5145 { 0, 0, ERROR_ACCESS_DENIED, ERROR_ACCESS_DENIED }, 5146 }; 5147 char path[MAX_PATH], fname[MAX_PATH]; 5148 unsigned char buf[16]; 5149 HANDLE hfile, hdup; 5150 DWORD i, j, ret, bytes; 5151 5152 GetTempPathA(MAX_PATH, path); 5153 GetTempFileNameA(path, "foo", 0, fname); 5154 5155 for (i = 0; i < ARRAY_SIZE(td); i++) 5156 { 5157 SetLastError(0xdeadbeef); 5158 hfile = CreateFileA(fname, td[i].access, 0, NULL, CREATE_ALWAYS, 5159 FILE_FLAG_DELETE_ON_CLOSE, 0); 5160 if (td[i].create_error) 5161 { 5162 ok(hfile == INVALID_HANDLE_VALUE, "%ld: CreateFile should fail\n", i); 5163 ok(td[i].create_error == GetLastError(), "%ld: expected %d, got %ld\n", i, td[i].create_error, GetLastError()); 5164 continue; 5165 } 5166 else 5167 ok(hfile != INVALID_HANDLE_VALUE, "%ld: CreateFile error %ld\n", i, GetLastError()); 5168 5169 for (j = 0; j < ARRAY_SIZE(td); j++) 5170 { 5171 SetLastError(0xdeadbeef); 5172 ret = DuplicateHandle(GetCurrentProcess(), hfile, GetCurrentProcess(), &hdup, 5173 td[j].access, 0, 0); 5174 if (is_access_compatible(td[i].access, td[j].access)) 5175 ok(ret, "DuplicateHandle(%#x => %#x) error %ld\n", td[i].access, td[j].access, GetLastError()); 5176 else 5177 { 5178 /* FIXME: Remove once Wine is fixed */ 5179 todo_wine_if((td[j].access & (GENERIC_READ | GENERIC_WRITE) || 5180 (!(td[i].access & (GENERIC_WRITE | FILE_WRITE_DATA)) && (td[j].access & FILE_WRITE_DATA)) || 5181 (!(td[i].access & (GENERIC_READ | FILE_READ_DATA)) && (td[j].access & FILE_READ_DATA)) || 5182 (!(td[i].access & (GENERIC_WRITE)) && (td[j].access & FILE_APPEND_DATA)))) 5183 { 5184 ok(!ret, "DuplicateHandle(%#x => %#x) should fail\n", td[i].access, td[j].access); 5185 ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError()); 5186 } 5187 } 5188 if (ret) CloseHandle(hdup); 5189 } 5190 5191 SetLastError(0xdeadbeef); 5192 bytes = 0xdeadbeef; 5193 ret = WriteFile(hfile, "\x5e\xa7", 2, &bytes, NULL); 5194 if (td[i].write_error) 5195 { 5196 ok(!ret, "%ld: WriteFile should fail\n", i); 5197 ok(td[i].write_error == GetLastError(), "%ld: expected %d, got %ld\n", i, td[i].write_error, GetLastError()); 5198 ok(bytes == 0, "%ld: expected 0, got %lu\n", i, bytes); 5199 } 5200 else 5201 { 5202 ok(ret, "%ld: WriteFile error %ld\n", i, GetLastError()); 5203 ok(bytes == 2, "%ld: expected 2, got %lu\n", i, bytes); 5204 } 5205 5206 SetLastError(0xdeadbeef); 5207 ret = SetFilePointer(hfile, 0, NULL, FILE_BEGIN); 5208 ok(ret != INVALID_SET_FILE_POINTER, "SetFilePointer error %ld\n", GetLastError()); 5209 5210 SetLastError(0xdeadbeef); 5211 bytes = 0xdeadbeef; 5212 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, NULL); 5213 if (td[i].read_error) 5214 { 5215 ok(!ret, "%ld: ReadFile should fail\n", i); 5216 ok(td[i].read_error == GetLastError(), "%ld: expected %d, got %ld\n", i, td[i].read_error, GetLastError()); 5217 ok(bytes == 0, "%ld: expected 0, got %lu\n", i, bytes); 5218 } 5219 else 5220 { 5221 ok(ret, "%ld: ReadFile error %ld\n", i, GetLastError()); 5222 if (td[i].write_error) 5223 ok(bytes == 0, "%ld: expected 0, got %lu\n", i, bytes); 5224 else 5225 { 5226 ok(bytes == 2, "%ld: expected 2, got %lu\n", i, bytes); 5227 ok(buf[0] == 0x5e && buf[1] == 0xa7, "%ld: expected 5ea7, got %02x%02x\n", i, buf[0], buf[1]); 5228 } 5229 } 5230 5231 CloseHandle(hfile); 5232 } 5233} 5234 5235static void test_GetFinalPathNameByHandleA(void) 5236{ 5237 static char prefix[] = "GetFinalPathNameByHandleA"; 5238 static char dos_prefix[] = "\\\\?\\"; 5239 char temp_path[MAX_PATH], test_path[MAX_PATH]; 5240 char long_path[MAX_PATH], result_path[MAX_PATH]; 5241 char dos_path[MAX_PATH + sizeof(dos_prefix)]; 5242 HANDLE file; 5243 DWORD count; 5244 UINT ret; 5245 5246 if (!pGetFinalPathNameByHandleA) 5247 { 5248 win_skip("GetFinalPathNameByHandleA is missing\n"); 5249 return; 5250 } 5251 5252 /* Test calling with INVALID_HANDLE_VALUE */ 5253 SetLastError(0xdeadbeaf); 5254 count = pGetFinalPathNameByHandleA(INVALID_HANDLE_VALUE, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 5255 ok(count == 0, "Expected length 0, got %lu\n", count); 5256 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %lu\n", GetLastError()); 5257 5258 count = GetTempPathA(MAX_PATH, temp_path); 5259 ok(count, "Failed to get temp path, error %lu\n", GetLastError()); 5260 ret = GetTempFileNameA(temp_path, prefix, 0, test_path); 5261 ok(ret != 0, "GetTempFileNameA error %lu\n", GetLastError()); 5262 ret = GetLongPathNameA(test_path, long_path, MAX_PATH); 5263 ok(ret != 0, "GetLongPathNameA error %lu\n", GetLastError()); 5264 strcpy(dos_path, dos_prefix); 5265 strcat(dos_path, long_path); 5266 5267 count = pGetFinalPathNameByHandleA(INVALID_HANDLE_VALUE, NULL, 0, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 5268 ok(count == 0, "Expected length 0, got %lu\n", count); 5269 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %lu\n", GetLastError()); 5270 5271 file = CreateFileA(test_path, GENERIC_READ | GENERIC_WRITE, 0, NULL, 5272 CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0); 5273 ok(file != INVALID_HANDLE_VALUE, "CreateFileA error %lu\n", GetLastError()); 5274 5275 if (0) { 5276 /* Windows crashes on NULL path */ 5277 count = pGetFinalPathNameByHandleA(file, NULL, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 5278 ok(count == 0, "Expected length 0, got %lu\n", count); 5279 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %lu\n", GetLastError()); 5280 } 5281 5282 /* Test 0-length path */ 5283 count = pGetFinalPathNameByHandleA(file, result_path, 0, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 5284 ok(count == strlen(dos_path), "Expected length %u, got %lu\n", lstrlenA(dos_path), count); 5285 5286 /* Test 0 and NULL path */ 5287 count = pGetFinalPathNameByHandleA(file, NULL, 0, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 5288 ok(count == strlen(dos_path), "Expected length %u, got %lu\n", lstrlenA(dos_path), count); 5289 5290 /* Test VOLUME_NAME_DOS with sufficient buffer size */ 5291 memset(result_path, 0x11, sizeof(result_path)); 5292 count = pGetFinalPathNameByHandleA(file, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 5293 ok(count == strlen(dos_path), "Expected length %lu, got %lu\n", (DWORD)strlen(dos_path), count); 5294 ok(lstrcmpiA(dos_path, result_path) == 0, "Expected %s, got %s\n", dos_path, result_path); 5295 5296 /* Test VOLUME_NAME_DOS with insufficient buffer size */ 5297 memset(result_path, 0x11, sizeof(result_path)); 5298 count = pGetFinalPathNameByHandleA(file, result_path, strlen(dos_path)-2, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 5299 ok(count == strlen(dos_path), "Expected length %lu, got %lu\n", (DWORD)strlen(dos_path), count); 5300 ok(result_path[0] == 0x11, "Result path was modified\n"); 5301 5302 memset(result_path, 0x11, sizeof(result_path)); 5303 count = pGetFinalPathNameByHandleA(file, result_path, strlen(dos_path)-1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 5304 ok(count == strlen(dos_path), "Expected length %lu, got %lu\n", (DWORD)strlen(dos_path), count); 5305 ok(result_path[0] == 0x11, "Result path was modified\n"); 5306 5307 memset(result_path, 0x11, sizeof(result_path)); 5308 count = pGetFinalPathNameByHandleA(file, result_path, strlen(dos_path), FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 5309 ok(count == strlen(dos_path), "Expected length %lu, got %lu\n", (DWORD)strlen(dos_path), count); 5310 ok(result_path[0] == 0x11, "Result path was modified\n"); 5311 5312 memset(result_path, 0x11, sizeof(result_path)); 5313 count = pGetFinalPathNameByHandleA(file, result_path, strlen(dos_path)+1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 5314 ok(count == strlen(dos_path), "Expected length %lu, got %lu\n", (DWORD)strlen(dos_path), count); 5315 ok(result_path[0] != 0x11, "Result path was not modified\n"); 5316 ok(!result_path[strlen(dos_path)], "Expected nullterminated string\n"); 5317 ok(result_path[strlen(dos_path)+1] == 0x11, "Buffer overflow\n"); 5318 5319 CloseHandle(file); 5320} 5321 5322static void test_GetFinalPathNameByHandleW(void) 5323{ 5324 static WCHAR prefix[] = {'G','e','t','F','i','n','a','l','P','a','t','h', 5325 'N','a','m','e','B','y','H','a','n','d','l','e','W','\0'}; 5326 static WCHAR dos_prefix[] = {'\\','\\','?','\\','\0'}; 5327 WCHAR temp_path[MAX_PATH], test_path[MAX_PATH]; 5328 WCHAR long_path[MAX_PATH], result_path[MAX_PATH]; 5329 WCHAR dos_path[MAX_PATH + sizeof(dos_prefix)]; 5330 WCHAR drive_part[MAX_PATH]; 5331 WCHAR *file_part; 5332 WCHAR volume_path[MAX_PATH + 50]; 5333 WCHAR nt_path[2 * MAX_PATH]; 5334 BOOL success; 5335 HANDLE file; 5336 DWORD count; 5337 UINT ret; 5338 5339 if (!pGetFinalPathNameByHandleW) 5340 { 5341 win_skip("GetFinalPathNameByHandleW is missing\n"); 5342 return; 5343 } 5344 5345 /* Test calling with INVALID_HANDLE_VALUE */ 5346 SetLastError(0xdeadbeaf); 5347 count = pGetFinalPathNameByHandleW(INVALID_HANDLE_VALUE, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 5348 ok(count == 0, "Expected length 0, got %lu\n", count); 5349 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %lu\n", GetLastError()); 5350 5351 count = pGetFinalPathNameByHandleW(INVALID_HANDLE_VALUE, NULL, 0, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 5352 ok(count == 0, "Expected length 0, got %lu\n", count); 5353 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %lu\n", GetLastError()); 5354 5355 count = GetTempPathW(MAX_PATH, temp_path); 5356 ok(count, "Failed to get temp path, error %lu\n", GetLastError()); 5357 ret = GetTempFileNameW(temp_path, prefix, 0, test_path); 5358 ok(ret != 0, "GetTempFileNameW error %lu\n", GetLastError()); 5359 ret = GetLongPathNameW(test_path, long_path, MAX_PATH); 5360 ok(ret != 0, "GetLongPathNameW error %lu\n", GetLastError()); 5361 lstrcpyW(dos_path, dos_prefix); 5362 lstrcatW(dos_path, long_path); 5363 5364 file = CreateFileW(test_path, GENERIC_READ | GENERIC_WRITE, 0, NULL, 5365 CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0); 5366 ok(file != INVALID_HANDLE_VALUE, "CreateFileW error %lu\n", GetLastError()); 5367 5368 if (0) { 5369 /* Windows crashes on NULL path */ 5370 count = pGetFinalPathNameByHandleW(file, NULL, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 5371 ok(count == 0, "Expected length 0, got %lu\n", count); 5372 ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %lu\n", GetLastError()); 5373 } 5374 5375 /* Test 0-length path */ 5376 count = pGetFinalPathNameByHandleW(file, result_path, 0, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 5377 ok(count == lstrlenW(dos_path) + 1 || 5378 broken(count == lstrlenW(dos_path) + 2), "Expected length %u, got %lu\n", lstrlenW(dos_path) + 1, count); 5379 5380 /* Test 0 and NULL path */ 5381 count = pGetFinalPathNameByHandleW(file, NULL, 0, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 5382 ok(count == lstrlenW(dos_path) + 1 || 5383 broken(count == lstrlenW(dos_path) + 2), "Expected length %u, got %lu\n", lstrlenW(dos_path) + 1, count); 5384 5385 /* Test VOLUME_NAME_DOS with sufficient buffer size */ 5386 memset(result_path, 0x11, sizeof(result_path)); 5387 count = pGetFinalPathNameByHandleW(file, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 5388 ok(count == lstrlenW(dos_path), "Expected length %u, got %lu\n", lstrlenW(dos_path), count); 5389 ok(lstrcmpiW(dos_path, result_path) == 0, "Expected %s, got %s\n", wine_dbgstr_w(dos_path), wine_dbgstr_w(result_path)); 5390 5391 /* Test VOLUME_NAME_DOS with insufficient buffer size */ 5392 memset(result_path, 0x11, sizeof(result_path)); 5393 count = pGetFinalPathNameByHandleW(file, result_path, lstrlenW(dos_path)-1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 5394 ok(count == lstrlenW(dos_path) + 1, "Expected length %u, got %lu\n", lstrlenW(dos_path) + 1, count); 5395 ok(result_path[0] == 0x1111, "Result path was modified\n"); 5396 5397 memset(result_path, 0x11, sizeof(result_path)); 5398 count = pGetFinalPathNameByHandleW(file, result_path, lstrlenW(dos_path), FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 5399 ok(count == lstrlenW(dos_path) + 1, "Expected length %u, got %lu\n", lstrlenW(dos_path) + 1, count); 5400 ok(result_path[0] == 0x1111, "Result path was modified\n"); 5401 5402 memset(result_path, 0x11, sizeof(result_path)); 5403 count = pGetFinalPathNameByHandleW(file, result_path, lstrlenW(dos_path)+1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); 5404 ok(count == lstrlenW(dos_path), "Expected length %u, got %lu\n", lstrlenW(dos_path), count); 5405 ok(result_path[0] != 0x1111, "Result path was not modified\n"); 5406 ok(!result_path[lstrlenW(dos_path)], "Expected nullterminated string\n"); 5407 ok(result_path[lstrlenW(dos_path)+1] == 0x1111, "Buffer overflow\n"); 5408 5409 success = GetVolumePathNameW(long_path, drive_part, MAX_PATH); 5410 ok(success, "GetVolumePathNameW error %lu\n", GetLastError()); 5411 success = GetVolumeNameForVolumeMountPointW(drive_part, volume_path, ARRAY_SIZE(volume_path)); 5412 ok(success, "GetVolumeNameForVolumeMountPointW error %lu\n", GetLastError()); 5413 5414 /* Test for VOLUME_NAME_GUID */ 5415 lstrcatW(volume_path, long_path + lstrlenW(drive_part)); 5416 memset(result_path, 0x11, sizeof(result_path)); 5417 count = pGetFinalPathNameByHandleW(file, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_GUID); 5418 ok(count == lstrlenW(volume_path), "Expected length %u, got %lu\n", lstrlenW(volume_path), count); 5419 ok(lstrcmpiW(volume_path, result_path) == 0, "Expected %s, got %s\n", 5420 wine_dbgstr_w(volume_path), wine_dbgstr_w(result_path)); 5421 5422 /* Test for VOLUME_NAME_NONE */ 5423 file_part = long_path + lstrlenW(drive_part) - 1; 5424 memset(result_path, 0x11, sizeof(result_path)); 5425 count = pGetFinalPathNameByHandleW(file, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_NONE); 5426 ok(count == lstrlenW(file_part), "Expected length %u, got %lu\n", lstrlenW(file_part), count); 5427 ok(lstrcmpiW(file_part, result_path) == 0, "Expected %s, got %s\n", 5428 wine_dbgstr_w(file_part), wine_dbgstr_w(result_path)); 5429 5430 drive_part[lstrlenW(drive_part)-1] = 0; 5431 success = QueryDosDeviceW(drive_part, nt_path, ARRAY_SIZE(nt_path)); 5432 ok(success, "QueryDosDeviceW error %lu\n", GetLastError()); 5433 5434 /* Test for VOLUME_NAME_NT */ 5435 lstrcatW(nt_path, file_part); 5436 memset(result_path, 0x11, sizeof(result_path)); 5437 count = pGetFinalPathNameByHandleW(file, result_path, MAX_PATH, FILE_NAME_NORMALIZED | VOLUME_NAME_NT); 5438 ok(count == lstrlenW(nt_path), "Expected length %u, got %lu\n", lstrlenW(nt_path), count); 5439 ok(lstrcmpiW(nt_path, result_path) == 0, "Expected %s, got %s\n", 5440 wine_dbgstr_w(nt_path), wine_dbgstr_w(result_path)); 5441 5442 CloseHandle(file); 5443} 5444 5445static void test_SetFileInformationByHandle(void) 5446{ 5447 FILE_ATTRIBUTE_TAG_INFO fileattrinfo = { 0 }; 5448 FILE_REMOTE_PROTOCOL_INFO protinfo = { 0 }; 5449 FILE_STANDARD_INFO stdinfo = { {{0}},{{0}},0,FALSE,FALSE }; 5450 FILE_COMPRESSION_INFO compressinfo; 5451 FILE_DISPOSITION_INFO dispinfo; 5452 DECLSPEC_ALIGN(8) FILE_IO_PRIORITY_HINT_INFO hintinfo; 5453 FILE_BASIC_INFO basicinfo = { {{0}} }; 5454 char tempFileName[MAX_PATH]; 5455 char tempPath[MAX_PATH]; 5456 LARGE_INTEGER atime; 5457 HANDLE file; 5458 BOOL ret; 5459 5460#if defined(__REACTOS__) && DLL_EXPORT_VERSION >= 0x600 5461 /* FIXME: SetFileInformationByHandle is a STUB on ReactOS. */ 5462 if (is_reactos() || !pSetFileInformationByHandle) 5463#else 5464 if (!pSetFileInformationByHandle) 5465#endif 5466 { 5467 win_skip("SetFileInformationByHandle is not supported\n"); 5468 return; 5469 } 5470 5471 ret = GetTempPathA(sizeof(tempPath), tempPath); 5472 ok(ret, "GetTempPathA failed, got error %lu.\n", GetLastError()); 5473 5474 /* ensure the existence of a file in the temp folder */ 5475 ret = GetTempFileNameA(tempPath, "abc", 0, tempFileName); 5476 ok(ret, "GetTempFileNameA failed, got error %lu.\n", GetLastError()); 5477 5478 file = CreateFileA(tempFileName, GENERIC_READ | FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 5479 NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL); 5480 ok(file != INVALID_HANDLE_VALUE, "failed to open the temp file, error %lu.\n", GetLastError()); 5481 5482 /* invalid classes */ 5483 SetLastError(0xdeadbeef); 5484 ret = pSetFileInformationByHandle(file, FileStandardInfo, &stdinfo, sizeof(stdinfo)); 5485 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError()); 5486 5487 memset(&compressinfo, 0, sizeof(compressinfo)); 5488 SetLastError(0xdeadbeef); 5489 ret = pSetFileInformationByHandle(file, FileCompressionInfo, &compressinfo, sizeof(compressinfo)); 5490 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError()); 5491 5492 SetLastError(0xdeadbeef); 5493 ret = pSetFileInformationByHandle(file, FileAttributeTagInfo, &fileattrinfo, sizeof(fileattrinfo)); 5494 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError()); 5495 5496 SetLastError(0xdeadbeef); 5497 hintinfo.PriorityHint = MaximumIoPriorityHintType; 5498 ret = pSetFileInformationByHandle(file, FileIoPriorityHintInfo, &hintinfo, sizeof(hintinfo)); 5499 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError()); 5500 5501 hintinfo.PriorityHint = IoPriorityHintNormal; 5502 ret = pSetFileInformationByHandle(file, FileIoPriorityHintInfo, &hintinfo, sizeof(hintinfo)); 5503 ok(ret, "setting FileIoPriorityHintInfo got %d, error %ld\n", ret, GetLastError()); 5504 5505 hintinfo.PriorityHint = IoPriorityHintVeryLow; 5506 ret = pSetFileInformationByHandle(file, FileIoPriorityHintInfo, &hintinfo, sizeof(hintinfo)); 5507 ok(ret, "setting FileIoPriorityHintInfo got %d, error %ld\n", ret, GetLastError()); 5508 5509 SetLastError(0xdeadbeef); 5510 ret = pSetFileInformationByHandle(file, FileIoPriorityHintInfo, &hintinfo, sizeof(hintinfo) - 1); 5511 ok(!ret && GetLastError() == ERROR_BAD_LENGTH, "got %d, error %ld\n", ret, GetLastError()); 5512 5513 SetLastError(0xdeadbeef); 5514 hintinfo.PriorityHint = IoPriorityHintVeryLow - 1; 5515 ret = pSetFileInformationByHandle(file, FileIoPriorityHintInfo, &hintinfo, sizeof(hintinfo)); 5516 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError()); 5517 5518 memset(&protinfo, 0, sizeof(protinfo)); 5519 protinfo.StructureVersion = 1; 5520 protinfo.StructureSize = sizeof(protinfo); 5521 SetLastError(0xdeadbeef); 5522 ret = pSetFileInformationByHandle(file, FileRemoteProtocolInfo, &protinfo, sizeof(protinfo)); 5523 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %ld\n", ret, GetLastError()); 5524 5525 /* test FileDispositionInfo, additional details already covered by ntdll tests */ 5526 SetLastError(0xdeadbeef); 5527 ret = pSetFileInformationByHandle(file, FileDispositionInfo, &dispinfo, 0); 5528 todo_wine 5529 ok(!ret && GetLastError() == ERROR_BAD_LENGTH, "got %d, error %ld\n", ret, GetLastError()); 5530 5531 SetLastError(0xdeadbeef); 5532 ret = pSetFileInformationByHandle(file, FileBasicInfo, &basicinfo, 0); 5533 todo_wine 5534 ok(!ret && GetLastError() == ERROR_BAD_LENGTH, "got %d, error %ld\n", ret, GetLastError()); 5535 5536 memset(&basicinfo, 0, sizeof(basicinfo)); 5537 ret = pGetFileInformationByHandleEx(file, FileBasicInfo, &basicinfo, sizeof(basicinfo)); 5538 ok(ret, "Failed to get basic info, error %ld.\n", GetLastError()); 5539 atime = basicinfo.LastAccessTime; 5540 5541 basicinfo.LastAccessTime.QuadPart++; 5542 ret = pSetFileInformationByHandle(file, FileBasicInfo, &basicinfo, sizeof(basicinfo)); 5543 ok(ret, "Failed to set basic info, error %ld.\n", GetLastError()); 5544 5545 memset(&basicinfo, 0, sizeof(basicinfo)); 5546 ret = pGetFileInformationByHandleEx(file, FileBasicInfo, &basicinfo, sizeof(basicinfo)); 5547 ok(ret, "Failed to get basic info, error %ld.\n", GetLastError()); 5548 ok(atime.QuadPart + 1 == basicinfo.LastAccessTime.QuadPart, "Unexpected access time.\n"); 5549 5550 memset(&basicinfo, 0, sizeof(basicinfo)); 5551 basicinfo.LastAccessTime.QuadPart = -1; 5552 ret = pSetFileInformationByHandle(file, FileBasicInfo, &basicinfo, sizeof(basicinfo)); 5553 ok(ret, "Failed to set basic info, error %ld.\n", GetLastError()); 5554 5555 memset(&basicinfo, 0, sizeof(basicinfo)); 5556 ret = pGetFileInformationByHandleEx(file, FileBasicInfo, &basicinfo, sizeof(basicinfo)); 5557 ok(ret, "Failed to get basic info, error %ld.\n", GetLastError()); 5558 ok(atime.QuadPart + 1 == basicinfo.LastAccessTime.QuadPart, "Unexpected access time.\n"); 5559 5560 dispinfo.DeleteFile = TRUE; 5561 ret = pSetFileInformationByHandle(file, FileDispositionInfo, &dispinfo, sizeof(dispinfo)); 5562 ok(ret, "setting FileDispositionInfo failed, error %ld\n", GetLastError()); 5563 5564 CloseHandle(file); 5565} 5566 5567static void test_SetFileRenameInfo(void) 5568{ 5569 WCHAR tempFileFrom[MAX_PATH], tempFileTo1[MAX_PATH], tempFileTo2[MAX_PATH]; 5570 WCHAR tempPath[MAX_PATH]; 5571 FILE_RENAME_INFORMATION *fri; 5572 HANDLE file; 5573 DWORD size; 5574 BOOL ret; 5575 5576#if defined(__REACTOS__) && DLL_EXPORT_VERSION >= 0x600 5577 /* FIXME: SetFileInformationByHandle is a STUB on ReactOS. */ 5578 if (is_reactos() || !pSetFileInformationByHandle) 5579#else 5580 if (!pSetFileInformationByHandle) 5581#endif 5582 { 5583 win_skip("SetFileInformationByHandle is not supported\n"); 5584 return; 5585 } 5586 5587 ret = GetTempPathW(MAX_PATH, tempPath); 5588 ok(ret, "GetTempPathW failed, got error %lu.\n", GetLastError()); 5589 5590 ret = GetTempFileNameW(tempPath, L"abc", 0, tempFileFrom); 5591 ok(ret, "GetTempFileNameW failed, got error %lu.\n", GetLastError()); 5592 5593 ret = GetTempFileNameW(tempPath, L"abc", 0, tempFileTo1); 5594 ok(ret, "GetTempFileNameW failed, got error %lu.\n", GetLastError()); 5595 5596 ret = GetTempFileNameW(tempPath, L"abc", 1, tempFileTo2); 5597 ok(ret, "GetTempFileNameW failed, got error %lu.\n", GetLastError()); 5598 5599 file = CreateFileW(tempFileFrom, GENERIC_READ | GENERIC_WRITE | DELETE, 0, 0, OPEN_EXISTING, 0, 0); 5600 ok(file != INVALID_HANDLE_VALUE, "failed to create temp file, error %lu.\n", GetLastError()); 5601 5602 size = sizeof(FILE_RENAME_INFORMATION) + MAX_PATH; 5603 fri = HeapAlloc(GetProcessHeap(), 0, size); 5604 5605 fri->ReplaceIfExists = FALSE; 5606 fri->RootDirectory = NULL; 5607 fri->FileNameLength = wcslen(tempFileTo1) * sizeof(WCHAR); 5608 memcpy(fri->FileName, tempFileTo1, fri->FileNameLength + sizeof(WCHAR)); 5609 ret = pSetFileInformationByHandle(file, FileRenameInfo, fri, size); 5610 ok(!ret && GetLastError() == ERROR_ALREADY_EXISTS, "FileRenameInfo unexpected result %ld\n", GetLastError()); 5611 5612 fri->ReplaceIfExists = TRUE; 5613 ret = pSetFileInformationByHandle(file, FileRenameInfo, fri, size); 5614 ok(ret, "FileRenameInfo failed, error %ld\n", GetLastError()); 5615 5616 fri->ReplaceIfExists = FALSE; 5617 fri->FileNameLength = wcslen(tempFileTo2) * sizeof(WCHAR); 5618 memcpy(fri->FileName, tempFileTo2, fri->FileNameLength + sizeof(WCHAR)); 5619 ret = pSetFileInformationByHandle(file, FileRenameInfo, fri, size); 5620 ok(ret, "FileRenameInfo failed, error %ld\n", GetLastError()); 5621 CloseHandle(file); 5622 5623 file = CreateFileW(tempFileTo2, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); 5624 ok(file != INVALID_HANDLE_VALUE, "file not renamed, error %ld\n", GetLastError()); 5625 5626 fri->FileNameLength = wcslen(tempFileTo1) * sizeof(WCHAR); 5627 memcpy(fri->FileName, tempFileTo1, fri->FileNameLength + sizeof(WCHAR)); 5628 ret = pSetFileInformationByHandle(file, FileRenameInfo, fri, size); 5629 todo_wine 5630 ok(!ret && GetLastError() == ERROR_ACCESS_DENIED, "FileRenameInfo unexpected result %ld\n", GetLastError()); 5631 CloseHandle(file); 5632 5633 HeapFree(GetProcessHeap(), 0, fri); 5634 DeleteFileW(tempFileFrom); 5635 DeleteFileW(tempFileTo1); 5636 DeleteFileW(tempFileTo2); 5637} 5638 5639static void test_GetFileAttributesExW(void) 5640{ 5641 static const struct 5642 { 5643 const WCHAR *path; 5644 DWORD expected_error; 5645 } 5646 tests[] = 5647 { 5648 {L"\\\\?\\", ERROR_INVALID_NAME}, 5649 {L"\\??\\", ERROR_INVALID_NAME}, 5650 {L"\\DosDevices\\", ERROR_FILE_NOT_FOUND}, 5651 {L"\\\\?\\C:\\windows\\system32\\..\\system32\\kernel32.dll", ERROR_INVALID_NAME}, 5652 }; 5653 WIN32_FILE_ATTRIBUTE_DATA info; 5654 DWORD error, test_idx; 5655 BOOL ret; 5656 5657 for (test_idx = 0; test_idx < ARRAY_SIZE(tests); ++test_idx) 5658 { 5659 winetest_push_context("Test %lu", test_idx); 5660 5661 SetLastError(0xdeadbeef); 5662 ret = GetFileAttributesExW(tests[test_idx].path, GetFileExInfoStandard, &info); 5663 error = GetLastError(); 5664 ok(!ret, "GetFileAttributesExW succeeded\n"); 5665 ok(error == tests[test_idx].expected_error, "Expected error %lu, got %lu\n", 5666 tests[test_idx].expected_error, error); 5667 5668 winetest_pop_context(); 5669 } 5670} 5671 5672static void test_post_completion(void) 5673{ 5674 OVERLAPPED ovl, ovl2, *povl; 5675 OVERLAPPED_ENTRY entries[2]; 5676 ULONG_PTR key; 5677 HANDLE port; 5678 ULONG count; 5679 DWORD size; 5680 BOOL ret; 5681 5682 port = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 999, 0 ); 5683 ok(port != NULL, "CreateIoCompletionPort failed: %lu\n", GetLastError()); 5684 5685 ret = GetQueuedCompletionStatus( port, &size, &key, &povl, 0 ); 5686 ok(!ret, "GetQueuedCompletionStatus succeeded\n"); 5687 ok(GetLastError() == WAIT_TIMEOUT, "wrong error %lu\n", GetLastError()); 5688 5689 ret = PostQueuedCompletionStatus( port, 123, 456, &ovl ); 5690 ok(ret, "PostQueuedCompletionStatus failed: %lu\n", GetLastError()); 5691 5692 ret = GetQueuedCompletionStatus( port, &size, &key, &povl, 0 ); 5693 ok(ret, "GetQueuedCompletionStatus failed: %lu\n", GetLastError()); 5694 ok(size == 123, "wrong size %lu\n", size); 5695 ok(key == 456, "wrong key %Iu\n", key); 5696 ok(povl == &ovl, "wrong ovl %p\n", povl); 5697 5698 ret = GetQueuedCompletionStatus( port, &size, &key, &povl, 0 ); 5699 ok(!ret, "GetQueuedCompletionStatus succeeded\n"); 5700 ok(GetLastError() == WAIT_TIMEOUT, "wrong error %lu\n", GetLastError()); 5701 5702#if defined(__REACTOS__) && DLL_EXPORT_VERSION >= 0x600 5703 /* FIXME: GetQueuedCompletionStatusEx is a STUB on ReactOS. */ 5704 if (is_reactos() || !pGetQueuedCompletionStatusEx) 5705#else 5706 if (!pGetQueuedCompletionStatusEx) 5707#endif 5708 { 5709 win_skip("GetQueuedCompletionStatusEx not available\n"); 5710 CloseHandle( port ); 5711 return; 5712 } 5713 5714 count = 0xdeadbeef; 5715 ret = pGetQueuedCompletionStatusEx( port, entries, 2, &count, 0, FALSE ); 5716 ok(!ret, "GetQueuedCompletionStatusEx succeeded\n"); 5717 ok(GetLastError() == WAIT_TIMEOUT, "wrong error %lu\n", GetLastError()); 5718 ok(count <= 1, "wrong count %lu\n", count); 5719 5720 ret = PostQueuedCompletionStatus( port, 123, 456, &ovl ); 5721 ok(ret, "PostQueuedCompletionStatus failed: %lu\n", GetLastError()); 5722 5723 count = 0xdeadbeef; 5724 memset( entries, 0xcc, sizeof(entries) ); 5725 ret = pGetQueuedCompletionStatusEx( port, entries, 2, &count, 0, FALSE ); 5726 ok(ret, "GetQueuedCompletionStatusEx failed\n"); 5727 ok(count == 1, "wrong count %lu\n", count); 5728 ok(entries[0].lpCompletionKey == 456, "wrong key %Iu\n", entries[0].lpCompletionKey); 5729 ok(entries[0].lpOverlapped == &ovl, "wrong ovl %p\n", entries[0].lpOverlapped); 5730 ok(!(ULONG)entries[0].Internal, "wrong internal %#lx\n", (ULONG)entries[0].Internal); 5731 ok(entries[0].dwNumberOfBytesTransferred == 123, "wrong size %lu\n", entries[0].dwNumberOfBytesTransferred); 5732 5733 ret = PostQueuedCompletionStatus( port, 123, 456, &ovl ); 5734 ok(ret, "PostQueuedCompletionStatus failed: %lu\n", GetLastError()); 5735 5736 ret = PostQueuedCompletionStatus( port, 654, 321, &ovl2 ); 5737 ok(ret, "PostQueuedCompletionStatus failed: %lu\n", GetLastError()); 5738 5739 count = 0xdeadbeef; 5740 memset( entries, 0xcc, sizeof(entries) ); 5741 ret = pGetQueuedCompletionStatusEx( port, entries, 2, &count, 0, FALSE ); 5742 ok(ret, "GetQueuedCompletionStatusEx failed\n"); 5743 ok(count == 2, "wrong count %lu\n", count); 5744 ok(entries[0].lpCompletionKey == 456, "wrong key %Iu\n", entries[0].lpCompletionKey); 5745 ok(entries[0].lpOverlapped == &ovl, "wrong ovl %p\n", entries[0].lpOverlapped); 5746 ok(!(ULONG)entries[0].Internal, "wrong internal %#lx\n", (ULONG)entries[0].Internal); 5747 ok(entries[0].dwNumberOfBytesTransferred == 123, "wrong size %lu\n", entries[0].dwNumberOfBytesTransferred); 5748 ok(entries[1].lpCompletionKey == 321, "wrong key %Iu\n", entries[1].lpCompletionKey); 5749 ok(entries[1].lpOverlapped == &ovl2, "wrong ovl %p\n", entries[1].lpOverlapped); 5750 ok(!(ULONG)entries[1].Internal, "wrong internal %#lx\n", (ULONG)entries[1].Internal); 5751 ok(entries[1].dwNumberOfBytesTransferred == 654, "wrong size %lu\n", entries[1].dwNumberOfBytesTransferred); 5752 5753 user_apc_ran = FALSE; 5754 QueueUserAPC( user_apc, GetCurrentThread(), 0 ); 5755 5756 ret = pGetQueuedCompletionStatusEx( port, entries, 2, &count, 0, FALSE ); 5757 ok(!ret, "GetQueuedCompletionStatusEx succeeded\n"); 5758 ok(GetLastError() == WAIT_TIMEOUT, "wrong error %lu\n", GetLastError()); 5759 ok(count <= 1, "wrong count %lu\n", count); 5760 ok(!user_apc_ran, "user APC should not have run\n"); 5761 5762 ret = pGetQueuedCompletionStatusEx( port, entries, 2, &count, 0, TRUE ); 5763 ok(!ret || broken(ret) /* Vista */, "GetQueuedCompletionStatusEx succeeded\n"); 5764 if (!ret) 5765 ok(GetLastError() == WAIT_IO_COMPLETION, "wrong error %lu\n", GetLastError()); 5766 ok(count <= 1, "wrong count %lu\n", count); 5767 ok(user_apc_ran, "user APC should have run\n"); 5768 5769 user_apc_ran = FALSE; 5770 QueueUserAPC( user_apc, GetCurrentThread(), 0 ); 5771 5772 ret = PostQueuedCompletionStatus( port, 123, 456, &ovl ); 5773 ok(ret, "PostQueuedCompletionStatus failed: %lu\n", GetLastError()); 5774 5775 ret = pGetQueuedCompletionStatusEx( port, entries, 2, &count, 0, TRUE ); 5776 ok(ret, "GetQueuedCompletionStatusEx failed\n"); 5777 ok(count == 1, "wrong count %lu\n", count); 5778 ok(!user_apc_ran, "user APC should not have run\n"); 5779 5780 SleepEx(0, TRUE); 5781 5782 CloseHandle( port ); 5783} 5784 5785#define TEST_OVERLAPPED_READ_SIZE 4096 5786 5787static void test_overlapped_read(void) 5788{ 5789 DECLSPEC_ALIGN(TEST_OVERLAPPED_READ_SIZE) static unsigned char buffer[TEST_OVERLAPPED_READ_SIZE]; 5790 static const char prefix[] = "pfx"; 5791 char temp_path[MAX_PATH]; 5792 char file_name[MAX_PATH]; 5793 DWORD bytes_count; 5794 OVERLAPPED ov; 5795 HANDLE hfile; 5796 DWORD err; 5797 DWORD ret; 5798 5799 ret = GetTempPathA(MAX_PATH, temp_path); 5800 ok(ret, "Unexpected error %lu.\n", GetLastError()); 5801 ret = GetTempFileNameA(temp_path, prefix, 0, file_name); 5802 ok(ret, "Unexpected error %lu.\n", GetLastError()); 5803 5804 hfile = CreateFileA(file_name, GENERIC_WRITE, 0, 5805 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL); 5806 ok(hfile != INVALID_HANDLE_VALUE, "Failed to create file, GetLastError() %lu.\n", GetLastError()); 5807 memset(buffer, 0x55, sizeof(buffer)); 5808 ret = WriteFile(hfile, buffer, TEST_OVERLAPPED_READ_SIZE, &bytes_count, NULL); 5809 ok(ret && bytes_count == TEST_OVERLAPPED_READ_SIZE, 5810 "Unexpected WriteFile result, ret %#lx, bytes_count %lu, GetLastError() %lu.\n", 5811 ret, bytes_count, GetLastError()); 5812 CloseHandle(hfile); 5813 5814 hfile = CreateFileA(file_name, GENERIC_READ, FILE_SHARE_READ, 5815 NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL); 5816 ok(hfile != INVALID_HANDLE_VALUE, "Failed to create file, GetLastError() %lu.\n", GetLastError()); 5817 5818 memset(&ov, 0, sizeof(ov)); 5819 5820 bytes_count = 0xffffffff; 5821 ret = ReadFile(hfile, buffer, TEST_OVERLAPPED_READ_SIZE, &bytes_count, &ov); 5822 ok(!ret && GetLastError() == ERROR_IO_PENDING, 5823 "Unexpected ReadFile result, ret %#lx, GetLastError() %lu.\n", ret, GetLastError()); 5824 ok(!bytes_count, "Unexpected read size %lu.\n", bytes_count); 5825 ret = GetOverlappedResult(hfile, &ov, &bytes_count, TRUE); 5826 ok(ret, "Unexpected error %lu.\n", GetLastError()); 5827 ok(bytes_count == TEST_OVERLAPPED_READ_SIZE, "Unexpected read size %lu.\n", bytes_count); 5828 5829 ov.Offset = bytes_count; 5830 ret = ReadFile(hfile, buffer, TEST_OVERLAPPED_READ_SIZE, &bytes_count, &ov); 5831 err = GetLastError(); 5832 /* Win8+ return ERROR_IO_PENDING like stated in MSDN, while older ones 5833 * return ERROR_HANDLE_EOF right away. */ 5834 ok(!ret && (err == ERROR_IO_PENDING || broken(err == ERROR_HANDLE_EOF)), 5835 "Unexpected ReadFile result, ret %#lx, GetLastError() %lu.\n", ret, GetLastError()); 5836 if (err == ERROR_IO_PENDING) 5837 { 5838 ret = GetOverlappedResult(hfile, &ov, &bytes_count, TRUE); 5839 ok(!ret && GetLastError() == ERROR_HANDLE_EOF, "Unexpected result %#lx, GetLasttError() %lu.\n", 5840 ret, GetLastError()); 5841 } 5842 ok(!bytes_count, "Unexpected read size %lu.\n", bytes_count); 5843 5844 CloseHandle(hfile); 5845 ret = DeleteFileA(file_name); 5846 ok(ret, "Unexpected error %lu.\n", GetLastError()); 5847} 5848 5849static void test_file_readonly_access(void) 5850{ 5851 static const DWORD default_sharing = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; 5852 static const CHAR prefix[] = "pfx"; 5853 CHAR file_name[MAX_PATH], file_name2[MAX_PATH]; 5854 CHAR temp_path[MAX_PATH]; 5855 HANDLE handle; 5856 DWORD error; 5857 DWORD ret; 5858 5859 /* Set up */ 5860 ret = GetTempPathA(MAX_PATH, temp_path); 5861 ok(ret != 0, "GetTempPathA error %ld\n", GetLastError()); 5862 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n"); 5863 5864 ret = GetTempFileNameA(temp_path, prefix, 0, file_name); 5865 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError()); 5866 ret = DeleteFileA(file_name); 5867 ok(ret, "expect success\n"); 5868 5869 ret = GetTempFileNameA(temp_path, prefix, 0, file_name2); 5870 ok(ret != 0, "GetTempFileNameA error %ld\n", GetLastError()); 5871 ret = DeleteFileA(file_name2); 5872 ok(ret, "expect success\n"); 5873 5874 handle = CreateFileA(file_name, 0, default_sharing, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_READONLY, 0); 5875 ok(handle != INVALID_HANDLE_VALUE, "CreateFileA: error %ld\n", GetLastError()); 5876 CloseHandle(handle); 5877 5878 /* CreateFile GENERIC_WRITE */ 5879 SetLastError(0xdeadbeef); 5880 handle = CreateFileA(file_name, GENERIC_WRITE, default_sharing, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 5881 error = GetLastError(); 5882 ok(handle == INVALID_HANDLE_VALUE, "expect failure\n"); 5883 ok(error == ERROR_ACCESS_DENIED, "wrong error code: %#lx\n", error); 5884 5885 /* CreateFile DELETE without FILE_FLAG_DELETE_ON_CLOSE */ 5886 handle = CreateFileA(file_name, DELETE, default_sharing, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 5887 ok(handle != INVALID_HANDLE_VALUE, "expect success\n"); 5888 CloseHandle(handle); 5889 5890 /* CreateFile DELETE with FILE_FLAG_DELETE_ON_CLOSE */ 5891 SetLastError(0xdeadbeef); 5892 handle = CreateFileA(file_name, DELETE, default_sharing, NULL, OPEN_EXISTING, 5893 FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_NORMAL, 0); 5894 error = GetLastError(); 5895 ok(handle == INVALID_HANDLE_VALUE, "expect failure\n"); 5896 ok(error == ERROR_ACCESS_DENIED, "wrong error code: %#lx\n", error); 5897 5898 ret = MoveFileA(file_name, file_name2); 5899 ok(ret, "expect success\n"); 5900 ret = MoveFileA(file_name2, file_name); 5901 ok(ret, "expect success\n"); 5902 5903 SetLastError(0xdeadbeef); 5904 ret = DeleteFileA(file_name); 5905 error = GetLastError(); 5906 ok(!ret, "expect failure\n"); 5907 ok(error == ERROR_ACCESS_DENIED, "wrong error code: %#lx\n", error); 5908 5909 ret = GetFileAttributesA(file_name); 5910 ok(ret & FILE_ATTRIBUTE_READONLY, "got wrong attribute: %#lx.\n", ret); 5911 5912 /* Clean up */ 5913 SetFileAttributesA(file_name, FILE_ATTRIBUTE_NORMAL); 5914 ret = DeleteFileA(file_name); 5915 ok(ret, "DeleteFileA: error %ld\n", GetLastError()); 5916} 5917 5918static void test_find_file_stream(void) 5919{ 5920#ifdef __REACTOS__ 5921 WCHAR path[MAX_PATH]; 5922#else 5923 WCHAR path[] = {'C',':','\\','w','i','n','d','o','w','s',0}; 5924#endif 5925 HANDLE handle; 5926 int error; 5927 WIN32_FIND_STREAM_DATA data; 5928 5929 if (!pFindFirstStreamW) 5930 { 5931 win_skip("FindFirstStreamW is missing\n"); 5932 return; 5933 } 5934 5935#ifdef __REACTOS__ 5936 GetWindowsDirectoryW(path, ARRAY_SIZE(path)); 5937#endif 5938 SetLastError(0xdeadbeef); 5939 handle = pFindFirstStreamW(path, FindStreamInfoStandard, &data, 0); 5940 error = GetLastError(); 5941 ok(handle == INVALID_HANDLE_VALUE, "Expected INVALID_HANDLE_VALUE, got %p\n", handle); 5942 ok(error == ERROR_HANDLE_EOF, "Expected ERROR_HANDLE_EOF, got %d\n", error); 5943} 5944 5945static void test_SetFileTime(void) 5946{ 5947 static const WCHAR prefix[] = {'p','f','x',0}; 5948 WCHAR path[MAX_PATH], temp_path[MAX_PATH]; 5949 FILETIME ft1, ft2; 5950 DWORD ret, len; 5951 HANDLE hfile; 5952 5953 ret = GetTempPathW(MAX_PATH, temp_path); 5954 ok(ret != 0, "GetTempPathW error %ld\n", GetLastError()); 5955 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n"); 5956 5957 ret = GetTempFileNameW(temp_path, prefix, 0, path); 5958 ok(ret != 0, "GetTempFileNameW error %ld\n", GetLastError()); 5959 5960 hfile = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0); 5961 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n"); 5962 ret = WriteFile(hfile, prefix, sizeof(prefix), &len, NULL ); 5963 ok(ret && len == sizeof(prefix), "WriteFile error %ld\n", GetLastError()); 5964 ok(GetFileSize(hfile, NULL) == sizeof(prefix), "source file has wrong size\n"); 5965 5966 ret = GetFileTime(hfile, NULL, NULL, &ft1); 5967 ok(ret, "GetFileTime error %ld\n", GetLastError()); 5968 ft2 = ft1; 5969 ft2.dwLowDateTime -= 600000000; /* 60 second */ 5970 ret = SetFileTime(hfile, NULL, NULL, &ft2); 5971 ok(ret, "SetFileTime error %ld\n", GetLastError()); 5972 memset(&ft2, 0, sizeof(ft2)); 5973 ret = GetFileTime(hfile, NULL, NULL, &ft2); /* get the actual time back */ 5974 ok(ret, "GetFileTime error %ld\n", GetLastError()); 5975 ok(memcmp(&ft1, &ft2, sizeof(ft1)), "Unexpected write time.\n"); 5976 5977 memset(&ft1, 0xff, sizeof(ft1)); 5978 ret = SetFileTime(hfile, NULL, NULL, &ft1); 5979 ok(ret, "SetFileTime error %ld\n", GetLastError()); 5980 memset(&ft1, 0, sizeof(ft1)); 5981 ret = GetFileTime(hfile, NULL, NULL, &ft1); /* get the actual time back */ 5982 ok(ret, "GetFileTime error %ld\n", GetLastError()); 5983 ok(!memcmp(&ft1, &ft2, sizeof(ft1)), "Unexpected write time.\n"); 5984 5985 CloseHandle(hfile); 5986} 5987 5988static void test_hard_link(void) 5989{ 5990 char cwd[MAX_PATH], temp_dir[MAX_PATH], name_buffer[200], buffer[20]; 5991 FILE_NAME_INFORMATION *name_info = (FILE_NAME_INFORMATION *)name_buffer; 5992 IO_STATUS_BLOCK io; 5993 NTSTATUS status; 5994 HANDLE file; 5995 DWORD size; 5996 BOOL ret; 5997 5998 GetCurrentDirectoryA( sizeof(cwd), cwd ); 5999 GetTempPathA( sizeof(temp_dir), temp_dir ); 6000 SetCurrentDirectoryA( temp_dir ); 6001 6002 ret = CreateDirectoryA( "winetest_dir1", NULL ); 6003 ok(ret, "failed to create directory, error %lu\n", GetLastError()); 6004 ret = CreateDirectoryA( "winetest_dir2", NULL ); 6005 ok(ret, "failed to create directory, error %lu\n", GetLastError()); 6006 create_file( "winetest_file1" ); 6007 create_file( "winetest_file2" ); 6008 6009 ret = CreateHardLinkA( "winetest_file3", "winetest_file1", NULL ); 6010 ok(ret, "got error %lu\n", GetLastError()); 6011 6012 file = CreateFileA( "winetest_file3", FILE_READ_DATA, 0, NULL, OPEN_EXISTING, 0, NULL ); 6013 ok(file != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError()); 6014 6015 status = NtQueryInformationFile( file, &io, name_buffer, sizeof(name_buffer), FileNameInformation ); 6016 ok(!status, "got status %#lx\n", status); 6017#ifdef __REACTOS__ 6018 if (!status) 6019#endif 6020 ok(!wcsncmp(name_info->FileName + (name_info->FileNameLength / sizeof(WCHAR)) - wcslen(L"\\winetest_file3"), 6021 L"\\winetest_file3", wcslen(L"\\winetest_file3")), "got name %s\n", 6022 debugstr_wn(name_info->FileName, name_info->FileNameLength / sizeof(WCHAR))); 6023 6024 ret = ReadFile( file, buffer, sizeof(buffer), &size, NULL ); 6025 ok(ret, "got error %lu\n", GetLastError()); 6026 ok(!memcmp( buffer, "winetest_file1", size ), "got file contents %s\n", debugstr_an( buffer, size )); 6027 6028 CloseHandle( file ); 6029 6030 ret = DeleteFileA( "winetest_file3" ); 6031 ok(ret, "failed to delete file, error %lu\n", GetLastError()); 6032 6033 SetLastError(0xdeadbeef); 6034 ret = CreateHardLinkA( "winetest_file2", "winetest_file1", NULL ); 6035 ok(!ret, "expected failure\n"); 6036 ok(GetLastError() == ERROR_ALREADY_EXISTS, "got error %lu\n", GetLastError()); 6037 6038 SetLastError(0xdeadbeef); 6039 ret = CreateHardLinkA( "WineTest_File1", "winetest_file1", NULL ); 6040 ok(!ret, "expected failure\n"); 6041 ok(GetLastError() == ERROR_ALREADY_EXISTS, "got error %lu\n", GetLastError()); 6042 6043 SetLastError(0xdeadbeef); 6044 ret = CreateHardLinkA( "winetest_file3", "winetest_dir1", NULL ); 6045 ok(!ret, "expected failure\n"); 6046 ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError()); 6047 6048 SetLastError(0xdeadbeef); 6049 ret = CreateHardLinkA( "winetest_dir2", "winetest_dir1", NULL ); 6050 ok(!ret, "expected failure\n"); 6051 ok(GetLastError() == ERROR_ACCESS_DENIED 6052 || GetLastError() == ERROR_ALREADY_EXISTS /* XP */, "got error %lu\n", GetLastError()); 6053 6054 SetLastError(0xdeadbeef); 6055 ret = CreateHardLinkA( "winetest_dir1", "winetest_file1", NULL ); 6056 ok(!ret, "expected failure\n"); 6057 ok(GetLastError() == ERROR_ALREADY_EXISTS, "got error %lu\n", GetLastError()); 6058 6059 ret = RemoveDirectoryA( "winetest_dir1" ); 6060 ok(ret, "failed to remove directory, error %lu\n", GetLastError()); 6061 ret = RemoveDirectoryA( "winetest_dir2" ); 6062 ok(ret, "failed to remove directory, error %lu\n", GetLastError()); 6063 ret = DeleteFileA( "winetest_file1" ); 6064 ok(ret, "failed to delete file, error %lu\n", GetLastError()); 6065 ret = DeleteFileA( "winetest_file2" ); 6066 ok(ret, "failed to delete file, error %lu\n", GetLastError()); 6067 SetCurrentDirectoryA( cwd ); 6068} 6069 6070static void test_move_file(void) 6071{ 6072 char cwd[MAX_PATH], temp_dir[MAX_PATH]; 6073 HANDLE file; 6074 BOOL ret; 6075 6076 GetCurrentDirectoryA( sizeof(cwd), cwd ); 6077 GetTempPathA( sizeof(temp_dir), temp_dir ); 6078 SetCurrentDirectoryA( temp_dir ); 6079 6080 ret = CreateDirectoryA( "winetest_dir1", NULL ); 6081 ok(ret, "failed to create directory, error %lu\n", GetLastError()); 6082 ret = CreateDirectoryA( "winetest_dir2", NULL ); 6083 ok(ret, "failed to create directory, error %lu\n", GetLastError()); 6084 create_file( "winetest_file1" ); 6085 create_file( "winetest_file2" ); 6086 6087 ret = MoveFileA( "winetest_file1", "winetest_file3" ); 6088 ok(ret, "failed to move file, error %lu\n", GetLastError()); 6089 ret = GetFileAttributesA( "winetest_file1" ); 6090 ok(ret == INVALID_FILE_ATTRIBUTES, "got %#x\n", ret); 6091 ret = GetFileAttributesA( "winetest_file3" ); 6092 ok(ret != INVALID_FILE_ATTRIBUTES, "got %#x\n", ret); 6093 6094 SetLastError(0xdeadbeef); 6095 ret = MoveFileA( "winetest_file3", "winetest_file2" ); 6096 ok(!ret, "expected failure\n"); 6097 ok(GetLastError() == ERROR_ALREADY_EXISTS, "got error %lu\n", GetLastError()); 6098 6099 SetLastError(0xdeadbeef); 6100 ret = MoveFileA( "winetest_file1", "winetest_file4" ); 6101 ok(!ret, "expected failure\n"); 6102 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "got error %lu\n", GetLastError()); 6103 6104 ret = MoveFileA( "winetest_dir1", "winetest_dir3" ); 6105 ok(ret, "failed to move file, error %lu\n", GetLastError()); 6106 6107 SetLastError(0xdeadbeef); 6108 ret = MoveFileA( "winetest_dir3", "winetest_dir2" ); 6109 ok(!ret, "expected failure\n"); 6110 ok(GetLastError() == ERROR_ALREADY_EXISTS, "got error %lu\n", GetLastError()); 6111 6112 file = CreateFileA( "winetest_file3", DELETE, 0, NULL, OPEN_EXISTING, 0, 0 ); 6113 ok(file != INVALID_HANDLE_VALUE, "failed to open file, error %lu\n", GetLastError()); 6114 ret = MoveFileA( "winetest_file3", "winetest_file1" ); 6115 ok(!ret, "expected failure\n"); 6116 ok(GetLastError() == ERROR_SHARING_VIOLATION, "got error %lu\n", GetLastError()); 6117 CloseHandle( file ); 6118 6119 file = CreateFileA( "winetest_file3", 0, 0, NULL, OPEN_EXISTING, 0, 0 ); 6120 ok(file != INVALID_HANDLE_VALUE, "failed to open file, error %lu\n", GetLastError()); 6121 ret = MoveFileA( "winetest_file3", "winetest_file1" ); 6122 ok(ret, "failed to move file, error %lu\n", GetLastError()); 6123 ret = GetFileAttributesA( "winetest_file1" ); 6124 ok(ret != INVALID_FILE_ATTRIBUTES, "got %#x\n", ret); 6125 ret = GetFileAttributesA( "winetest_file3" ); 6126 ok(ret == INVALID_FILE_ATTRIBUTES, "got %#x\n", ret); 6127 CloseHandle( file ); 6128 6129 ret = MoveFileExA( "winetest_file1", "winetest_file2", MOVEFILE_REPLACE_EXISTING ); 6130 ok(ret, "failed to move file, error %lu\n", GetLastError()); 6131 6132 file = CreateFileA( "winetest_file1", GENERIC_ALL, 6133 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, CREATE_NEW, 0, 0 ); 6134 ok(file != INVALID_HANDLE_VALUE, "failed to open file, error %lu\n", GetLastError()); 6135 SetLastError(0xdeadbeef); 6136 ret = MoveFileExA( "winetest_file2", "winetest_file1", MOVEFILE_REPLACE_EXISTING ); 6137 ok(!ret, "expected failure\n"); 6138 ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError()); 6139 CloseHandle( file ); 6140 6141 SetLastError(0xdeadbeef); 6142 ret = MoveFileExA( "winetest_file2", "winetest_dir2", MOVEFILE_REPLACE_EXISTING ); 6143 ok(!ret, "expected failure\n"); 6144 ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError()); 6145 6146 SetLastError(0xdeadbeef); 6147 ret = MoveFileExA( "winetest_dir3", "winetest_dir2", MOVEFILE_REPLACE_EXISTING ); 6148 ok(!ret, "expected failure\n"); 6149 ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError()); 6150 6151 ret = MoveFileExA( "winetest_dir2", "winetest_file2", MOVEFILE_REPLACE_EXISTING ); 6152 ok(ret, "failed to move file, error %lu\n", GetLastError()); 6153 6154 ret = RemoveDirectoryA( "winetest_dir3" ); 6155 ok(ret, "failed to remove directory, error %lu\n", GetLastError()); 6156 ret = RemoveDirectoryA( "winetest_file2" ); 6157 ok(ret, "failed to remove directory, error %lu\n", GetLastError()); 6158 ret = DeleteFileA( "winetest_file1" ); 6159 ok(ret, "failed to delete file, error %lu\n", GetLastError()); 6160 SetCurrentDirectoryA( cwd ); 6161} 6162 6163static void test_eof(void) 6164{ 6165 char temp_path[MAX_PATH], filename[MAX_PATH], buffer[20]; 6166 OVERLAPPED overlapped = {0}; 6167 LARGE_INTEGER file_size; 6168 HANDLE file, mapping; 6169 unsigned int i; 6170 void *view; 6171 DWORD size; 6172 BOOL ret; 6173 6174 static const struct 6175 { 6176 DWORD protection; 6177 DWORD view_access; 6178 } 6179 map_tests[] = 6180 { 6181 {PAGE_READONLY, FILE_MAP_READ}, 6182 {PAGE_READWRITE, FILE_MAP_WRITE}, 6183 }; 6184 6185 GetTempPathA(sizeof(temp_path), temp_path); 6186 GetTempFileNameA(temp_path, "eof", 0, filename); 6187 6188 file = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0); 6189 ok(file != INVALID_HANDLE_VALUE, "failed to create file, error %lu\n", GetLastError()); 6190 6191 ret = GetFileSizeEx(file, &file_size); 6192 ok(ret, "failed to get size, error %lu\n", GetLastError()); 6193 ok(!file_size.QuadPart, "got size %I64d\n", file_size.QuadPart); 6194 6195 SetFilePointer(file, 2, NULL, SEEK_SET); 6196 6197 ret = GetFileSizeEx(file, &file_size); 6198 ok(ret, "failed to get size, error %lu\n", GetLastError()); 6199 ok(!file_size.QuadPart, "got size %I64d\n", file_size.QuadPart); 6200 6201 SetLastError(0xdeadbeef); 6202 ret = ReadFile(file, buffer, sizeof(buffer), &size, NULL); 6203 ok(ret, "failed to read, error %lu\n", GetLastError()); 6204 ok(!size, "got size %lu\n", size); 6205 ok(GetLastError() == 0xdeadbeef, "got error %lu\n", GetLastError()); 6206 6207 SetFilePointer(file, 2, NULL, SEEK_SET); 6208 6209 SetLastError(0xdeadbeef); 6210 size = 0xdeadbeef; 6211 overlapped.Offset = 2; 6212 ret = ReadFile(file, buffer, sizeof(buffer), &size, &overlapped); 6213 ok(!ret, "expected failure\n"); 6214 ok(GetLastError() == ERROR_HANDLE_EOF, "got error %lu\n", GetLastError()); 6215 ok(!size, "got size %lu\n", size); 6216 ok((NTSTATUS)overlapped.Internal == STATUS_PENDING || (NTSTATUS)overlapped.Internal == STATUS_END_OF_FILE, 6217 "got status %#lx\n", (NTSTATUS)overlapped.Internal); 6218 ok(!overlapped.InternalHigh, "got size %Iu\n", overlapped.InternalHigh); 6219 6220 SetFilePointer(file, 2, NULL, SEEK_SET); 6221 6222 ret = SetEndOfFile(file); 6223 ok(ret, "failed to set EOF, error %lu\n", GetLastError()); 6224 6225 ret = GetFileSizeEx(file, &file_size); 6226 ok(ret, "failed to get size, error %lu\n", GetLastError()); 6227 ok(file_size.QuadPart == 2, "got size %I64d\n", file_size.QuadPart); 6228 6229 ret = WriteFile(file, "data", 4, &size, NULL); 6230 ok(ret, "failed to write, error %lu\n", GetLastError()); 6231 ok(size == 4, "got size %lu\n", size); 6232 6233 ret = GetFileSizeEx(file, &file_size); 6234 ok(ret, "failed to get size, error %lu\n", GetLastError()); 6235 ok(file_size.QuadPart == 6, "got size %I64d\n", file_size.QuadPart); 6236 6237 SetFilePointer(file, 4, NULL, SEEK_SET); 6238 ret = SetEndOfFile(file); 6239 ok(ret, "failed to set EOF, error %lu\n", GetLastError()); 6240 6241 ret = GetFileSizeEx(file, &file_size); 6242 ok(ret, "failed to get size, error %lu\n", GetLastError()); 6243 ok(file_size.QuadPart == 4, "got size %I64d\n", file_size.QuadPart); 6244 6245 SetFilePointer(file, 0, NULL, SEEK_SET); 6246 ret = ReadFile(file, buffer, sizeof(buffer), &size, NULL); 6247 ok(ret, "failed to read, error %lu\n", GetLastError()); 6248 ok(size == 4, "got size %lu\n", size); 6249 ok(!memcmp(buffer, "\0\0da", 4), "wrong data\n"); 6250 6251 SetFilePointer(file, 6, NULL, SEEK_SET); 6252 ret = SetEndOfFile(file); 6253 ok(ret, "failed to set EOF, error %lu\n", GetLastError()); 6254 6255 ret = GetFileSizeEx(file, &file_size); 6256 ok(ret, "failed to get size, error %lu\n", GetLastError()); 6257 ok(file_size.QuadPart == 6, "got size %I64d\n", file_size.QuadPart); 6258 6259 SetFilePointer(file, 0, NULL, SEEK_SET); 6260 ret = ReadFile(file, buffer, sizeof(buffer), &size, NULL); 6261 ok(ret, "failed to read, error %lu\n", GetLastError()); 6262 ok(size == 6, "got size %lu\n", size); 6263 ok(!memcmp(buffer, "\0\0da\0\0", 6), "wrong data\n"); 6264 6265 ret = SetEndOfFile(file); 6266 ok(ret, "failed to set EOF, error %lu\n", GetLastError()); 6267 6268 SetFilePointer(file, 2, NULL, SEEK_SET); 6269 ret = WriteFile(file, "data", 4, &size, NULL); 6270 ok(ret, "failed to write, error %lu\n", GetLastError()); 6271 ok(size == 4, "got size %lu\n", size); 6272 6273 ret = GetFileSizeEx(file, &file_size); 6274 ok(ret, "failed to get size, error %lu\n", GetLastError()); 6275 ok(file_size.QuadPart == 6, "got size %I64d\n", file_size.QuadPart); 6276 6277 SetFilePointer(file, 0, NULL, SEEK_SET); 6278 ret = ReadFile(file, buffer, sizeof(buffer), &size, NULL); 6279 ok(ret, "failed to read, error %lu\n", GetLastError()); 6280 ok(size == 6, "got size %lu\n", size); 6281 ok(!memcmp(buffer, "\0\0data", 6), "wrong data\n"); 6282 6283 for (i = 0; i < ARRAY_SIZE(map_tests); ++i) 6284 { 6285 mapping = CreateFileMappingA(file, NULL, map_tests[i].protection, 0, 4, NULL); 6286 ok(!!mapping, "failed to create mapping, error %lu\n", GetLastError()); 6287 6288 ret = GetFileSizeEx(file, &file_size); 6289 ok(ret, "failed to get size, error %lu\n", GetLastError()); 6290 ok(file_size.QuadPart == 6, "got size %I64d\n", file_size.QuadPart); 6291 6292 SetFilePointer(file, 6, NULL, SEEK_SET); 6293 ret = SetEndOfFile(file); 6294 ok(ret, "failed to set EOF, error %lu\n", GetLastError()); 6295 ret = GetFileSizeEx(file, &file_size); 6296 ok(ret, "failed to get size, error %lu\n", GetLastError()); 6297 ok(file_size.QuadPart == 6, "got size %I64d\n", file_size.QuadPart); 6298 6299 SetFilePointer(file, 8, NULL, SEEK_SET); 6300 ret = SetEndOfFile(file); 6301 ok(ret, "failed to set EOF, error %lu\n", GetLastError()); 6302 ret = GetFileSizeEx(file, &file_size); 6303 ok(ret, "failed to get size, error %lu\n", GetLastError()); 6304 ok(file_size.QuadPart == 8, "got size %I64d\n", file_size.QuadPart); 6305 6306 SetLastError(0xdeadbeef); 6307 SetFilePointer(file, 6, NULL, SEEK_SET); 6308 ret = SetEndOfFile(file); 6309 ok(!ret, "expected failure\n"); 6310 ok(GetLastError() == ERROR_USER_MAPPED_FILE, "got error %lu\n", GetLastError()); 6311 ret = GetFileSizeEx(file, &file_size); 6312 ok(ret, "failed to get size, error %lu\n", GetLastError()); 6313 ok(file_size.QuadPart == 8, "got size %I64d\n", file_size.QuadPart); 6314 6315 SetFilePointer(file, 8192, NULL, SEEK_SET); 6316 ret = SetEndOfFile(file); 6317 ok(ret, "failed to set EOF, error %lu\n", GetLastError()); 6318 ret = GetFileSizeEx(file, &file_size); 6319 ok(ret, "failed to get size, error %lu\n", GetLastError()); 6320 ok(file_size.QuadPart == 8192, "got size %I64d\n", file_size.QuadPart); 6321 6322 SetFilePointer(file, 8191, NULL, SEEK_SET); 6323 ret = SetEndOfFile(file); 6324 ok(!ret, "expected failure\n"); 6325 ok(GetLastError() == ERROR_USER_MAPPED_FILE, "got error %lu\n", GetLastError()); 6326 ret = GetFileSizeEx(file, &file_size); 6327 ok(ret, "failed to get size, error %lu\n", GetLastError()); 6328 ok(file_size.QuadPart == 8192, "got size %I64d\n", file_size.QuadPart); 6329 6330 view = MapViewOfFile(mapping, map_tests[i].view_access, 0, 0, 4); 6331 ok(!!view, "failed to map view, error %lu\n", GetLastError()); 6332 6333 CloseHandle(mapping); 6334 6335 SetFilePointer(file, 16384, NULL, SEEK_SET); 6336 ret = SetEndOfFile(file); 6337 ok(ret, "failed to set EOF, error %lu\n", GetLastError()); 6338 ret = GetFileSizeEx(file, &file_size); 6339 ok(ret, "failed to get size, error %lu\n", GetLastError()); 6340 ok(file_size.QuadPart == 16384, "got size %I64d\n", file_size.QuadPart); 6341 6342 SetFilePointer(file, 16383, NULL, SEEK_SET); 6343 ret = SetEndOfFile(file); 6344 ok(!ret, "expected failure\n"); 6345 ok(GetLastError() == ERROR_USER_MAPPED_FILE, "got error %lu\n", GetLastError()); 6346 ret = GetFileSizeEx(file, &file_size); 6347 ok(ret, "failed to get size, error %lu\n", GetLastError()); 6348 ok(file_size.QuadPart == 16384, "got size %I64d\n", file_size.QuadPart); 6349 6350 ret = UnmapViewOfFile(view); 6351 ok(ret, "failed to unmap view, error %lu\n", GetLastError()); 6352 6353 SetFilePointer(file, 6, NULL, SEEK_SET); 6354 ret = SetEndOfFile(file); 6355 ok(ret, "failed to set EOF, error %lu\n", GetLastError()); 6356 ret = GetFileSizeEx(file, &file_size); 6357 ok(ret, "failed to get size, error %lu\n", GetLastError()); 6358 ok(file_size.QuadPart == 6, "got size %I64d\n", file_size.QuadPart); 6359 } 6360 6361 CloseHandle(file); 6362 ret = DeleteFileA(filename); 6363 ok(ret, "failed to delete %s, error %lu\n", debugstr_a(filename), GetLastError()); 6364} 6365 6366START_TEST(file) 6367{ 6368 char temp_path[MAX_PATH]; 6369 DWORD ret; 6370 6371 InitFunctionPointers(); 6372 6373 ret = GetTempPathA(MAX_PATH, temp_path); 6374 ok(ret != 0, "GetTempPath error %lu\n", GetLastError()); 6375 ret = GetTempFileNameA(temp_path, "tmp", 0, filename); 6376 ok(ret != 0, "GetTempFileName error %lu\n", GetLastError()); 6377 ret = DeleteFileA(filename); 6378 ok(ret != 0, "DeleteFile error %lu\n", GetLastError()); 6379 6380 test__hread( ); 6381 test__hwrite( ); 6382 test__lclose( ); 6383 test__lcreat( ); 6384 test__llseek( ); 6385 test__llopen( ); 6386 test__lread( ); 6387 test__lwrite( ); 6388 test_GetTempFileNameA(); 6389 test_CopyFileA(); 6390 test_CopyFileW(); 6391 test_CopyFile2(); 6392 test_CopyFileEx(); 6393 test_CreateFile(); 6394 test_CreateFileA(); 6395 test_CreateFileW(); 6396 test_CreateFile2(); 6397 test_DeleteFileA(); 6398 test_DeleteFileW(); 6399 test_MoveFileA(); 6400 test_MoveFileW(); 6401 test_FindFirstFileA(); 6402 test_FindNextFileA(); 6403 test_FindFirstFile_wildcards(); 6404 test_FindFirstFileExA(FindExInfoStandard, 0, 0); 6405 test_FindFirstFileExA(FindExInfoStandard, 0, FIND_FIRST_EX_CASE_SENSITIVE); 6406 test_FindFirstFileExA(FindExInfoStandard, 0, FIND_FIRST_EX_LARGE_FETCH); 6407 test_FindFirstFileExA(FindExInfoBasic, 0, 0); 6408 /* FindExLimitToDirectories is ignored if the file system doesn't support directory filtering */ 6409 test_FindFirstFileExA(FindExInfoStandard, FindExSearchLimitToDirectories, 0); 6410 test_FindFirstFileExA(FindExInfoStandard, FindExSearchLimitToDirectories, FIND_FIRST_EX_CASE_SENSITIVE); 6411 test_FindFirstFileExA(FindExInfoStandard, FindExSearchLimitToDirectories, FIND_FIRST_EX_LARGE_FETCH); 6412 test_FindFirstFileExA(FindExInfoBasic, FindExSearchLimitToDirectories, 0); 6413 test_LockFile(); 6414 test_file_sharing(); 6415 test_offset_in_overlapped_structure(); 6416 test_MapFile(); 6417 test_GetFileType(); 6418 test_async_file_errors(); 6419 test_read_write(); 6420 test_OpenFile(); 6421 test_overlapped(); 6422 test_RemoveDirectory(); 6423 test_ReplaceFileA(); 6424 test_ReplaceFileW(); 6425 test_GetFileInformationByHandleEx(); 6426 test_OpenFileById(); 6427 test_SetFileValidData(); 6428 test_WriteFileGather(); 6429 test_file_access(); 6430 test_GetFinalPathNameByHandleA(); 6431 test_GetFinalPathNameByHandleW(); 6432 test_SetFileInformationByHandle(); 6433 test_SetFileRenameInfo(); 6434 test_GetFileAttributesExW(); 6435 test_post_completion(); 6436 test_overlapped_read(); 6437 test_file_readonly_access(); 6438 test_find_file_stream(); 6439 test_SetFileTime(); 6440 test_ReOpenFile(); 6441 test_hard_link(); 6442 test_move_file(); 6443 test_eof(); 6444}