2 * Unit tests for file functions in Wine
4 * Copyright (c) 2002, 2004 Jakob Eriksson
5 * Copyright (c) 2008 Jeff Zaroyko
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 /* ReplaceFile requires Windows 2000 or newer */
24 #define _WIN32_WINNT 0x0500
31 #include "wine/test.h"
37 static HANDLE (WINAPI *pFindFirstFileExA)(LPCSTR,FINDEX_INFO_LEVELS,LPVOID,FINDEX_SEARCH_OPS,LPVOID,DWORD);
38 static BOOL (WINAPI *pReplaceFileA)(LPCSTR, LPCSTR, LPCSTR, DWORD, LPVOID, LPVOID);
39 static BOOL (WINAPI *pReplaceFileW)(LPCWSTR, LPCWSTR, LPCWSTR, DWORD, LPVOID, LPVOID);
40 static UINT (WINAPI *pGetSystemWindowsDirectoryA)(LPSTR, UINT);
41 static BOOL (WINAPI *pGetVolumeNameForVolumeMountPointA)(LPCSTR, LPSTR, DWORD);
42 static DWORD (WINAPI *pQueueUserAPC)(PAPCFUNC pfnAPC, HANDLE hThread, ULONG_PTR dwData);
43 static BOOL (WINAPI *pGetFileInformationByHandleEx)(HANDLE, FILE_INFO_BY_HANDLE_CLASS, LPVOID, DWORD);
44 static HANDLE (WINAPI *pOpenFileById)(HANDLE, LPFILE_ID_DESCRIPTOR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD);
45 static BOOL (WINAPI *pSetFileValidData)(HANDLE, LONGLONG);
47 /* keep filename and filenameW the same */
48 static const char filename[] = "testfile.xxx";
49 static const WCHAR filenameW[] = { 't','e','s','t','f','i','l','e','.','x','x','x',0 };
50 static const char sillytext[] =
51 "en larvig liten text dx \033 gx hej 84 hej 4484 ! \001\033 bla bl\na.. bla bla."
52 "1234 43 4kljf lf &%%%&&&&&& 34 4 34 3############# 33 3 3 3 # 3## 3"
53 "1234 43 4kljf lf &%%%&&&&&& 34 4 34 3############# 33 3 3 3 # 3## 3"
54 "1234 43 4kljf lf &%%%&&&&&& 34 4 34 3############# 33 3 3 3 # 3## 3"
55 "1234 43 4kljf lf &%%%&&&&&& 34 4 34 3############# 33 3 3 3 # 3## 3"
56 "1234 43 4kljf lf &%%%&&&&&& 34 4 34 3############# 33 3 3 3 # 3## 3"
57 "1234 43 4kljf lf &%%%&&&&&& 34 4 34 3############# 33 3 3 3 # 3## 3"
58 "1234 43 4kljf lf &%%%&&&&&& 34 4 34 3############# 33 3 3 3 # 3## 3"
59 "1234 43 4kljf lf &%%%&&&&&& 34 4 34 3############# 33 3 3 3 # 3## 3"
60 "sdlkfjasdlkfj a dslkj adsklf \n \nasdklf askldfa sdlkf \nsadklf asdklf asdf ";
63 const char *file; /* file string to test */
64 const DWORD err; /* Win NT and further error code */
65 const LONG err2; /* Win 9x & ME error code or -1 */
66 const DWORD options; /* option flag to use for open */
67 const BOOL todo_flag; /* todo_wine indicator */
70 static void InitFunctionPointers(void)
72 HMODULE hkernel32 = GetModuleHandleA("kernel32");
74 pFindFirstFileExA=(void*)GetProcAddress(hkernel32, "FindFirstFileExA");
75 pReplaceFileA=(void*)GetProcAddress(hkernel32, "ReplaceFileA");
76 pReplaceFileW=(void*)GetProcAddress(hkernel32, "ReplaceFileW");
77 pGetSystemWindowsDirectoryA=(void*)GetProcAddress(hkernel32, "GetSystemWindowsDirectoryA");
78 pGetVolumeNameForVolumeMountPointA = (void *) GetProcAddress(hkernel32, "GetVolumeNameForVolumeMountPointA");
79 pQueueUserAPC = (void *) GetProcAddress(hkernel32, "QueueUserAPC");
80 pGetFileInformationByHandleEx = (void *) GetProcAddress(hkernel32, "GetFileInformationByHandleEx");
81 pOpenFileById = (void *) GetProcAddress(hkernel32, "OpenFileById");
82 pSetFileValidData = (void *) GetProcAddress(hkernel32, "SetFileValidData");
85 static void test__hread( void )
94 SetFileAttributesA(filename,FILE_ATTRIBUTE_NORMAL); /* be sure to remove stale files */
95 DeleteFileA( filename );
96 filehandle = _lcreat( filename, 0 );
97 if (filehandle == HFILE_ERROR)
99 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
103 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
105 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
107 filehandle = _lopen( filename, OF_READ );
109 ok( HFILE_ERROR != filehandle, "couldn't open file \"%s\" again (err=%d)\n", filename, GetLastError( ) );
111 bytes_read = _hread( filehandle, buffer, 2 * strlen( sillytext ) );
113 ok( lstrlenA( sillytext ) == bytes_read, "file read size error\n" );
115 for (bytes_wanted = 0; bytes_wanted < lstrlenA( sillytext ); bytes_wanted++)
117 ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
118 ok( _hread( filehandle, buffer, bytes_wanted ) == bytes_wanted, "erratic _hread return value\n" );
119 for (i = 0; i < bytes_wanted; i++)
121 ok( buffer[i] == sillytext[i], "that's not what's written\n" );
125 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
127 ret = DeleteFileA( filename );
128 ok( ret != 0, "DeleteFile failed (%d)\n", GetLastError( ) );
132 static void test__hwrite( void )
141 HLOCAL memory_object;
145 filehandle = _lcreat( filename, 0 );
146 if (filehandle == HFILE_ERROR)
148 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
152 ok( HFILE_ERROR != _hwrite( filehandle, "", 0 ), "_hwrite complains\n" );
154 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
156 filehandle = _lopen( filename, OF_READ );
158 bytes_read = _hread( filehandle, buffer, 1);
160 ok( 0 == bytes_read, "file read size error\n" );
162 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
164 filehandle = _lopen( filename, OF_READWRITE );
168 srand( (unsigned)time( NULL ) );
169 for (blocks = 0; blocks < 100; blocks++)
171 for (i = 0; i < (LONG)sizeof( buffer ); i++)
174 checksum[0] = checksum[0] + buffer[i];
176 ok( HFILE_ERROR != _hwrite( filehandle, buffer, sizeof( buffer ) ), "_hwrite complains\n" );
177 bytes_written = bytes_written + sizeof( buffer );
180 ok( HFILE_ERROR != _hwrite( filehandle, checksum, 1 ), "_hwrite complains\n" );
183 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
185 memory_object = LocalAlloc( LPTR, bytes_written );
187 ok( 0 != memory_object, "LocalAlloc fails. (Could be out of memory.)\n" );
189 contents = LocalLock( memory_object );
190 ok( NULL != contents, "LocalLock whines\n" );
192 filehandle = _lopen( filename, OF_READ );
194 contents = LocalLock( memory_object );
195 ok( NULL != contents, "LocalLock whines\n" );
197 ok( bytes_written == _hread( filehandle, contents, bytes_written), "read length differ from write length\n" );
203 checksum[0] = checksum[0] + contents[i];
206 while (i < bytes_written - 1);
208 ok( checksum[0] == contents[i], "stored checksum differ from computed checksum\n" );
210 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
212 ret = DeleteFileA( filename );
213 ok( ret != 0, "DeleteFile failed (%d)\n", GetLastError( ) );
215 LocalFree( contents );
219 static void test__lclose( void )
224 filehandle = _lcreat( filename, 0 );
225 if (filehandle == HFILE_ERROR)
227 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
231 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
233 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
235 ret = DeleteFileA( filename );
236 ok( ret != 0, "DeleteFile failed (%d)\n", GetLastError( ) );
240 static void test__lcreat( void )
244 WIN32_FIND_DATAA search_results;
245 char slashname[] = "testfi/";
250 filehandle = _lcreat( filename, 0 );
251 if (filehandle == HFILE_ERROR)
253 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
257 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
259 ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
261 ok( _hread( filehandle, buffer, strlen( sillytext ) ) == lstrlenA( sillytext ), "erratic _hread return value\n" );
263 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
265 find = FindFirstFileA( filename, &search_results );
266 ok( INVALID_HANDLE_VALUE != find, "should be able to find file\n" );
269 ret = DeleteFileA(filename);
270 ok( ret != 0, "DeleteFile failed (%d)\n", GetLastError());
272 filehandle = _lcreat( filename, 1 ); /* readonly */
273 ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%d)\n", filename, GetLastError( ) );
275 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite shouldn't be able to write never the less\n" );
277 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
279 find = FindFirstFileA( filename, &search_results );
280 ok( INVALID_HANDLE_VALUE != find, "should be able to find file\n" );
283 ok( 0 == DeleteFileA( filename ), "shouldn't be able to delete a readonly file\n" );
285 ok( SetFileAttributesA(filename, FILE_ATTRIBUTE_NORMAL ) != 0, "couldn't change attributes on file\n" );
287 ok( DeleteFileA( filename ) != 0, "now it should be possible to delete the file!\n" );
289 filehandle = _lcreat( filename, 2 );
290 ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%d)\n", filename, GetLastError( ) );
292 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
294 ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
296 ok( _hread( filehandle, buffer, strlen( sillytext ) ) == lstrlenA( sillytext ), "erratic _hread return value\n" );
298 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
300 find = FindFirstFileA( filename, &search_results );
301 ok( INVALID_HANDLE_VALUE != find, "should STILL be able to find file\n" );
304 ret = DeleteFileA( filename );
305 ok( ret, "DeleteFile failed (%d)\n", GetLastError( ) );
307 filehandle = _lcreat( filename, 4 ); /* SYSTEM file */
308 ok( HFILE_ERROR != filehandle, "couldn't create file \"%s\" (err=%d)\n", filename, GetLastError( ) );
310 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
312 ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
314 ok( _hread( filehandle, buffer, strlen( sillytext ) ) == lstrlenA( sillytext ), "erratic _hread return value\n" );
316 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
318 find = FindFirstFileA( filename, &search_results );
319 ok( INVALID_HANDLE_VALUE != find, "should STILL be able to find file\n" );
322 ret = DeleteFileA( filename );
323 ok( ret, "DeleteFile failed (%d)\n", GetLastError( ) );
325 filehandle=_lcreat (slashname, 0); /* illegal name */
326 if (HFILE_ERROR==filehandle) {
328 ok (err==ERROR_INVALID_NAME || err==ERROR_PATH_NOT_FOUND,
329 "creating file \"%s\" failed with error %d\n", slashname, err);
330 } else { /* only NT succeeds */
332 find=FindFirstFileA (slashname, &search_results);
333 if (INVALID_HANDLE_VALUE!=find)
335 ret = FindClose (find);
336 ok (0 != ret, "FindClose complains (%d)\n", GetLastError ());
337 slashname[strlen(slashname)-1]=0;
338 ok (!strcmp (slashname, search_results.cFileName),
339 "found unexpected name \"%s\"\n", search_results.cFileName);
340 ok (FILE_ATTRIBUTE_ARCHIVE==search_results.dwFileAttributes,
341 "attributes of file \"%s\" are 0x%04x\n", search_results.cFileName,
342 search_results.dwFileAttributes);
344 ret = DeleteFileA( slashname );
345 ok( ret, "DeleteFile failed (%d)\n", GetLastError( ) );
348 filehandle=_lcreat (filename, 8); /* illegal attribute */
349 if (HFILE_ERROR==filehandle)
350 ok (0, "couldn't create volume label \"%s\"\n", filename);
353 find=FindFirstFileA (filename, &search_results);
354 if (INVALID_HANDLE_VALUE==find)
355 ok (0, "file \"%s\" not found\n", filename);
357 ret = FindClose(find);
358 ok ( 0 != ret, "FindClose complains (%d)\n", GetLastError ());
359 ok (!strcmp (filename, search_results.cFileName),
360 "found unexpected name \"%s\"\n", search_results.cFileName);
361 search_results.dwFileAttributes &= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
362 ok (FILE_ATTRIBUTE_ARCHIVE==search_results.dwFileAttributes,
363 "attributes of file \"%s\" are 0x%04x\n", search_results.cFileName,
364 search_results.dwFileAttributes);
366 ret = DeleteFileA( filename );
367 ok( ret, "DeleteFile failed (%d)\n", GetLastError( ) );
372 static void test__llseek( void )
380 filehandle = _lcreat( filename, 0 );
381 if (filehandle == HFILE_ERROR)
383 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
387 for (i = 0; i < 400; i++)
389 ok( _hwrite( filehandle, sillytext, strlen( sillytext ) ) != -1, "_hwrite complains\n" );
391 ok( _llseek( filehandle, 400 * strlen( sillytext ), FILE_CURRENT ) != -1, "should be able to seek\n" );
392 ok( _llseek( filehandle, 27 + 35 * strlen( sillytext ), FILE_BEGIN ) != -1, "should be able to seek\n" );
394 bytes_read = _hread( filehandle, buffer, 1);
395 ok( 1 == bytes_read, "file read size error\n" );
396 ok( buffer[0] == sillytext[27], "_llseek error, it got lost seeking\n" );
397 ok( _llseek( filehandle, -400 * (LONG)strlen( sillytext ), FILE_END ) != -1, "should be able to seek\n" );
399 bytes_read = _hread( filehandle, buffer, 1);
400 ok( 1 == bytes_read, "file read size error\n" );
401 ok( buffer[0] == sillytext[0], "_llseek error, it got lost seeking\n" );
402 ok( _llseek( filehandle, 1000000, FILE_END ) != -1, "should be able to seek past file; poor, poor Windows programmers\n" );
403 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
405 ret = DeleteFileA( filename );
406 ok( ret, "DeleteFile failed (%d)\n", GetLastError( ) );
410 static void test__llopen( void )
417 filehandle = _lcreat( filename, 0 );
418 if (filehandle == HFILE_ERROR)
420 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
424 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
425 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
427 filehandle = _lopen( filename, OF_READ );
428 ok( HFILE_ERROR == _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite shouldn't be able to write!\n" );
429 bytes_read = _hread( filehandle, buffer, strlen( sillytext ) );
430 ok( strlen( sillytext ) == bytes_read, "file read size error\n" );
431 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
433 filehandle = _lopen( filename, OF_READWRITE );
434 bytes_read = _hread( filehandle, buffer, 2 * strlen( sillytext ) );
435 ok( strlen( sillytext ) == bytes_read, "file read size error\n" );
436 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite should write just fine\n" );
437 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
439 filehandle = _lopen( filename, OF_WRITE );
440 ok( HFILE_ERROR == _hread( filehandle, buffer, 1 ), "you should only be able to write this file\n" );
441 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite should write just fine\n" );
442 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
444 ret = DeleteFileA( filename );
445 ok( ret, "DeleteFile failed (%d)\n", GetLastError( ) );
446 /* TODO - add tests for the SHARE modes - use two processes to pull this one off */
450 static void test__lread( void )
459 filehandle = _lcreat( filename, 0 );
460 if (filehandle == HFILE_ERROR)
462 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
466 ok( HFILE_ERROR != _hwrite( filehandle, sillytext, strlen( sillytext ) ), "_hwrite complains\n" );
468 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
470 filehandle = _lopen( filename, OF_READ );
472 ok( HFILE_ERROR != filehandle, "couldn't open file \"%s\" again (err=%d)\n", filename, GetLastError());
474 bytes_read = _lread( filehandle, buffer, 2 * strlen( sillytext ) );
476 ok( lstrlenA( sillytext ) == bytes_read, "file read size error\n" );
478 for (bytes_wanted = 0; bytes_wanted < strlen( sillytext ); bytes_wanted++)
480 ok( 0 == _llseek( filehandle, 0, FILE_BEGIN ), "_llseek complains\n" );
481 ok( _lread( filehandle, buffer, bytes_wanted ) == bytes_wanted, "erratic _hread return value\n" );
482 for (i = 0; i < bytes_wanted; i++)
484 ok( buffer[i] == sillytext[i], "that's not what's written\n" );
488 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
490 ret = DeleteFileA( filename );
491 ok( ret, "DeleteFile failed (%d)\n", GetLastError( ) );
495 static void test__lwrite( void )
504 HLOCAL memory_object;
508 filehandle = _lcreat( filename, 0 );
509 if (filehandle == HFILE_ERROR)
511 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
515 ok( HFILE_ERROR != _lwrite( filehandle, "", 0 ), "_hwrite complains\n" );
517 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
519 filehandle = _lopen( filename, OF_READ );
521 bytes_read = _hread( filehandle, buffer, 1);
523 ok( 0 == bytes_read, "file read size error\n" );
525 ok( HFILE_ERROR != _lclose(filehandle), "_lclose complains\n" );
527 filehandle = _lopen( filename, OF_READWRITE );
531 srand( (unsigned)time( NULL ) );
532 for (blocks = 0; blocks < 100; blocks++)
534 for (i = 0; i < (INT)sizeof( buffer ); i++)
537 checksum[0] = checksum[0] + buffer[i];
539 ok( HFILE_ERROR != _lwrite( filehandle, buffer, sizeof( buffer ) ), "_hwrite complains\n" );
540 bytes_written = bytes_written + sizeof( buffer );
543 ok( HFILE_ERROR != _lwrite( filehandle, checksum, 1 ), "_hwrite complains\n" );
546 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
548 memory_object = LocalAlloc( LPTR, bytes_written );
550 ok( 0 != memory_object, "LocalAlloc fails, could be out of memory\n" );
552 contents = LocalLock( memory_object );
553 ok( NULL != contents, "LocalLock whines\n" );
555 filehandle = _lopen( filename, OF_READ );
557 contents = LocalLock( memory_object );
558 ok( NULL != contents, "LocalLock whines\n" );
560 ok( bytes_written == _hread( filehandle, contents, bytes_written), "read length differ from write length\n" );
566 checksum[0] += contents[i];
569 while (i < bytes_written - 1);
571 ok( checksum[0] == contents[i], "stored checksum differ from computed checksum\n" );
573 ok( HFILE_ERROR != _lclose( filehandle ), "_lclose complains\n" );
575 ret = DeleteFileA( filename );
576 ok( ret, "DeleteFile failed (%d)\n", GetLastError( ) );
578 LocalFree( contents );
581 static void test_CopyFileA(void)
583 char temp_path[MAX_PATH];
584 char source[MAX_PATH], dest[MAX_PATH];
585 static const char prefix[] = "pfx";
593 ret = GetTempPathA(MAX_PATH, temp_path);
594 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
595 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
597 ret = GetTempFileNameA(temp_path, prefix, 0, source);
598 ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
600 ret = MoveFileA(source, source);
601 todo_wine ok(ret, "MoveFileA: failed, error %d\n", GetLastError());
603 /* copying a file to itself must fail */
604 retok = CopyFileA(source, source, FALSE);
605 ok( !retok && (GetLastError() == ERROR_SHARING_VIOLATION || broken(GetLastError() == ERROR_FILE_EXISTS) /* Win 9x */),
606 "copying a file to itself didn't fail (ret=%d, err=%d)\n", retok, GetLastError());
608 /* make the source have not zero size */
609 hfile = CreateFileA(source, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
610 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
611 retok = WriteFile(hfile, prefix, sizeof(prefix), &ret, NULL );
612 ok( retok && ret == sizeof(prefix),
613 "WriteFile error %d\n", GetLastError());
614 ok(GetFileSize(hfile, NULL) == sizeof(prefix), "source file has wrong size\n");
615 /* get the file time and change it to prove the difference */
616 ret = GetFileTime(hfile, NULL, NULL, &ft1);
617 ok( ret, "GetFileTime error %d\n", GetLastError());
618 ft1.dwLowDateTime -= 600000000; /* 60 second */
619 ret = SetFileTime(hfile, NULL, NULL, &ft1);
620 ok( ret, "SetFileTime error %d\n", GetLastError());
621 GetFileTime(hfile, NULL, NULL, &ft1); /* get the actual time back */
624 ret = GetTempFileNameA(temp_path, prefix, 0, dest);
625 ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
627 SetLastError(0xdeadbeef);
628 ret = CopyFileA(source, dest, TRUE);
629 ok(!ret && GetLastError() == ERROR_FILE_EXISTS,
630 "CopyFileA: unexpected error %d\n", GetLastError());
632 ret = CopyFileA(source, dest, FALSE);
633 ok(ret, "CopyFileA: error %d\n", GetLastError());
635 /* copying from a read-locked source fails */
636 hfile = CreateFileA(source, GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
637 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %d\n", GetLastError());
638 retok = CopyFileA(source, dest, FALSE);
639 ok(!retok && GetLastError() == ERROR_SHARING_VIOLATION,
640 "copying from a read-locked file succeeded when it shouldn't have\n");
641 /* in addition, the source is opened before the destination */
642 retok = CopyFileA("25f99d3b-4ba4-4f66-88f5-2906886993cc", dest, FALSE);
643 ok(!retok && GetLastError() == ERROR_FILE_NOT_FOUND,
644 "copying from a file that doesn't exist failed in an unexpected way (ret=%d, err=%d)\n", retok, GetLastError());
647 /* copying from a r+w opened, r shared source succeeds */
648 hfile = CreateFileA(source, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
649 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %d\n", GetLastError());
650 retok = CopyFileA(source, dest, FALSE);
652 "copying from an r+w opened and r shared file failed (ret=%d, err=%d)\n", retok, GetLastError());
655 /* copying from a delete-locked source mostly succeeds */
656 hfile = CreateFileA(source, DELETE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
657 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file, error %d\n", GetLastError());
658 retok = CopyFileA(source, dest, FALSE);
659 ok(retok || broken(!retok && GetLastError() == ERROR_SHARING_VIOLATION) /* NT, 2000, XP */,
660 "copying from a delete-locked file failed (ret=%d, err=%d)\n", retok, GetLastError());
663 /* copying to a write-locked destination fails */
664 hfile = CreateFileA(dest, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
665 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError());
666 retok = CopyFileA(source, dest, FALSE);
667 ok(!retok && GetLastError() == ERROR_SHARING_VIOLATION,
668 "copying to a write-locked file didn't fail (ret=%d, err=%d)\n", retok, GetLastError());
671 /* copying to a r+w opened, w shared destination mostly succeeds */
672 hfile = CreateFileA(dest, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
673 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError());
674 retok = CopyFileA(source, dest, FALSE);
675 ok(retok || broken(!retok && GetLastError() == ERROR_SHARING_VIOLATION) /* Win 9x */,
676 "copying to a r+w opened and w shared file failed (ret=%d, err=%d)\n", retok, GetLastError());
679 /* copying to a delete-locked destination fails, even when the destination is delete-shared */
680 hfile = CreateFileA(dest, DELETE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0);
681 ok(hfile != INVALID_HANDLE_VALUE || broken(GetLastError() == ERROR_INVALID_PARAMETER) /* Win 9x */,
682 "failed to open destination file, error %d\n", GetLastError());
683 if (hfile != INVALID_HANDLE_VALUE)
685 retok = CopyFileA(source, dest, FALSE);
686 ok(!retok && GetLastError() == ERROR_SHARING_VIOLATION,
687 "copying to a delete-locked shared file didn't fail (ret=%d, err=%d)\n", retok, GetLastError());
691 /* copy to a file that's opened the way Wine opens the source */
692 hfile = CreateFileA(dest, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
693 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file, error %d\n", GetLastError());
694 retok = CopyFileA(source, dest, FALSE);
695 ok(retok || broken(GetLastError() == ERROR_SHARING_VIOLATION) /* Win 9x */,
696 "copying to a file opened the way Wine opens the source failed (ret=%d, err=%d)\n", retok, GetLastError());
699 /* make sure that destination has correct size */
700 hfile = CreateFileA(dest, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
701 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n");
702 ret = GetFileSize(hfile, NULL);
703 ok(ret == sizeof(prefix), "destination file has wrong size %d\n", ret);
705 /* make sure that destination has the same filetime */
706 ret = GetFileTime(hfile, NULL, NULL, &ft2);
707 ok( ret, "GetFileTime error %d\n", GetLastError());
708 ok(CompareFileTime(&ft1, &ft2) == 0, "destination file has wrong filetime\n");
710 SetLastError(0xdeadbeef);
711 ret = CopyFileA(source, dest, FALSE);
712 ok(!ret && GetLastError() == ERROR_SHARING_VIOLATION,
713 "CopyFileA: ret = %d, unexpected error %d\n", ret, GetLastError());
715 /* make sure that destination still has correct size */
716 ret = GetFileSize(hfile, NULL);
717 ok(ret == sizeof(prefix), "destination file has wrong size %d\n", ret);
718 retok = ReadFile(hfile, buf, sizeof(buf), &ret, NULL);
719 ok( retok && ret == sizeof(prefix),
720 "ReadFile: error %d\n", GetLastError());
721 ok(!memcmp(prefix, buf, sizeof(prefix)), "buffer contents mismatch\n");
723 /* check error on copying over a mapped file that was opened with FILE_SHARE_READ */
724 hmapfile = CreateFileMapping(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
725 ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError());
727 ret = CopyFileA(source, dest, FALSE);
728 ok(!ret && GetLastError() == ERROR_SHARING_VIOLATION,
729 "CopyFileA with mapped dest file: expected ERROR_SHARING_VIOLATION, got %d\n", GetLastError());
731 CloseHandle(hmapfile);
734 hfile = CreateFileA(dest, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
735 ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n");
737 /* check error on copying over a mapped file that was opened with FILE_SHARE_WRITE */
738 hmapfile = CreateFileMapping(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
739 ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError());
741 ret = CopyFileA(source, dest, FALSE);
742 ok(!ret, "CopyFileA: expected failure\n");
743 ok(GetLastError() == ERROR_USER_MAPPED_FILE ||
744 broken(GetLastError() == ERROR_SHARING_VIOLATION), /* Win9x */
745 "CopyFileA with mapped dest file: expected ERROR_USER_MAPPED_FILE, got %d\n", GetLastError());
747 CloseHandle(hmapfile);
750 ret = DeleteFileA(source);
751 ok(ret, "DeleteFileA: error %d\n", GetLastError());
752 ret = DeleteFileA(dest);
753 ok(ret, "DeleteFileA: error %d\n", GetLastError());
756 static void test_CopyFileW(void)
758 WCHAR temp_path[MAX_PATH];
759 WCHAR source[MAX_PATH], dest[MAX_PATH];
760 static const WCHAR prefix[] = {'p','f','x',0};
763 ret = GetTempPathW(MAX_PATH, temp_path);
764 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
766 win_skip("GetTempPathW is not available\n");
769 ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
770 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
772 ret = GetTempFileNameW(temp_path, prefix, 0, source);
773 ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
775 ret = GetTempFileNameW(temp_path, prefix, 0, dest);
776 ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
778 ret = CopyFileW(source, dest, TRUE);
779 ok(!ret && GetLastError() == ERROR_FILE_EXISTS,
780 "CopyFileW: unexpected error %d\n", GetLastError());
782 ret = CopyFileW(source, dest, FALSE);
783 ok(ret, "CopyFileW: error %d\n", GetLastError());
785 ret = DeleteFileW(source);
786 ok(ret, "DeleteFileW: error %d\n", GetLastError());
787 ret = DeleteFileW(dest);
788 ok(ret, "DeleteFileW: error %d\n", GetLastError());
793 * Debugging routine to dump a buffer in a hexdump-like fashion.
795 static void dumpmem(unsigned char *mem, int len)
806 p += sprintf(p, "%02x ", mem[x]);
807 *c++ = (mem[x] >= 32 && mem[x] <= 127) ? mem[x] : '.';
808 } while (++x % 16 && x < len);
810 trace("%04x: %-48s- %s\n", x, hex, txt);
814 static void test_CreateFileA(void)
817 char temp_path[MAX_PATH], dirname[MAX_PATH];
818 char filename[MAX_PATH];
819 static const char prefix[] = "pfx";
820 char windowsdir[MAX_PATH];
821 char Volume_1[MAX_PATH];
822 unsigned char buffer[512];
823 char directory[] = "removeme";
824 static const char nt_drive[] = "\\\\?\\A:";
826 struct test_list p[] = {
827 {"", ERROR_PATH_NOT_FOUND, -1, FILE_ATTRIBUTE_NORMAL, TRUE }, /* dir as file w \ */
828 {"", ERROR_SUCCESS, ERROR_PATH_NOT_FOUND, FILE_FLAG_BACKUP_SEMANTICS, FALSE }, /* dir as dir w \ */
829 {"a", ERROR_FILE_NOT_FOUND, -1, FILE_ATTRIBUTE_NORMAL, FALSE }, /* non-exist file */
830 {"a\\", ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND, FILE_ATTRIBUTE_NORMAL, FALSE }, /* non-exist dir */
831 {"removeme", ERROR_ACCESS_DENIED, -1, FILE_ATTRIBUTE_NORMAL, FALSE }, /* exist dir w/o \ */
832 {"removeme\\", ERROR_PATH_NOT_FOUND, -1, FILE_ATTRIBUTE_NORMAL, TRUE }, /* exst dir w \ */
833 {"c:", ERROR_ACCESS_DENIED, ERROR_PATH_NOT_FOUND, FILE_ATTRIBUTE_NORMAL, FALSE }, /* device in file namespace */
834 {"c:", ERROR_SUCCESS, ERROR_PATH_NOT_FOUND, FILE_FLAG_BACKUP_SEMANTICS, FALSE }, /* device in file namespace as dir */
835 {"c:\\", ERROR_PATH_NOT_FOUND, ERROR_ACCESS_DENIED, FILE_ATTRIBUTE_NORMAL, TRUE }, /* root dir w \ */
836 {"c:\\", ERROR_SUCCESS, ERROR_ACCESS_DENIED, FILE_FLAG_BACKUP_SEMANTICS, FALSE }, /* root dir w \ as dir */
837 {"\\\\?\\c:", ERROR_SUCCESS, ERROR_BAD_NETPATH, FILE_ATTRIBUTE_NORMAL,FALSE }, /* dev namespace drive */
838 {"\\\\?\\c:\\", ERROR_PATH_NOT_FOUND, ERROR_BAD_NETPATH, FILE_ATTRIBUTE_NORMAL, TRUE }, /* dev namespace drive w \ */
839 {NULL, 0, -1, 0, FALSE}
841 BY_HANDLE_FILE_INFORMATION Finfo;
843 ret = GetTempPathA(MAX_PATH, temp_path);
844 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
845 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
847 ret = GetTempFileNameA(temp_path, prefix, 0, filename);
848 ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
850 SetLastError(0xdeadbeef);
851 hFile = CreateFileA(filename, GENERIC_READ, 0, NULL,
852 CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
853 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS,
854 "CREATE_NEW should fail if file exists and last error value should be ERROR_FILE_EXISTS\n");
856 SetLastError(0xdeadbeef);
857 hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
858 CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
859 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
860 "hFile %p, last error %u\n", hFile, GetLastError());
864 SetLastError(0xdeadbeef);
865 hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
866 OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
867 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
868 "hFile %p, last error %u\n", hFile, GetLastError());
872 ret = DeleteFileA(filename);
873 ok(ret, "DeleteFileA: error %d\n", GetLastError());
875 SetLastError(0xdeadbeef);
876 hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
877 OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
878 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == 0,
879 "hFile %p, last error %u\n", hFile, GetLastError());
883 ret = DeleteFileA(filename);
884 ok(ret, "DeleteFileA: error %d\n", GetLastError());
886 SetLastError(0xdeadbeef);
887 hFile = CreateFileA("c:\\*.*", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
888 ok(hFile == INVALID_HANDLE_VALUE, "hFile should have been INVALID_HANDLE_VALUE\n");
889 ok(GetLastError() == ERROR_INVALID_NAME ||
890 broken(GetLastError() == ERROR_FILE_NOT_FOUND), /* Win98 */
891 "LastError should have been ERROR_INVALID_NAME or ERROR_FILE_NOT_FOUND but got %u\n", GetLastError());
893 /* get windows drive letter */
894 ret = GetWindowsDirectory(windowsdir, sizeof(windowsdir));
895 ok(ret < sizeof(windowsdir), "windowsdir is abnormally long!\n");
896 ok(ret != 0, "GetWindowsDirectory: error %d\n", GetLastError());
898 /* test error return codes from CreateFile for some cases */
899 ret = GetTempPathA(MAX_PATH, temp_path);
900 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
901 strcpy(dirname, temp_path);
902 strcat(dirname, directory);
903 ret = CreateDirectory(dirname, NULL);
904 ok( ret, "Createdirectory failed, gle=%d\n", GetLastError() );
905 /* set current drive & directory to known location */
906 SetCurrentDirectoryA( temp_path );
911 /* update the drive id in the table entry with the current one */
912 if (p[i].file[1] == ':')
914 strcpy(filename, p[i].file);
915 filename[0] = windowsdir[0];
917 else if (p[i].file[0] == '\\' && p[i].file[5] == ':')
919 strcpy(filename, p[i].file);
920 filename[4] = windowsdir[0];
924 /* prefix the table entry with the current temp directory */
925 strcpy(filename, temp_path);
926 strcat(filename, p[i].file);
928 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
929 FILE_SHARE_READ | FILE_SHARE_WRITE,
931 p[i].options, NULL );
932 /* if we get ACCESS_DENIED when we do not expect it, assume
933 * no access to the volume
935 if (hFile == INVALID_HANDLE_VALUE &&
936 GetLastError() == ERROR_ACCESS_DENIED &&
937 p[i].err != ERROR_ACCESS_DENIED)
940 skip("Either no authority to volume, or is todo_wine for %s err=%d should be %d\n", filename, GetLastError(), p[i].err);
942 skip("Do not have authority to access volumes. Test for %s skipped\n", filename);
944 /* otherwise validate results with expectations */
945 else if (p[i].todo_flag)
947 (hFile == INVALID_HANDLE_VALUE &&
948 (p[i].err == GetLastError() || p[i].err2 == GetLastError())) ||
949 (hFile != INVALID_HANDLE_VALUE && p[i].err == ERROR_SUCCESS),
950 "CreateFileA failed on %s, hFile %p, err=%u, should be %u\n",
951 filename, hFile, GetLastError(), p[i].err);
954 (hFile == INVALID_HANDLE_VALUE &&
955 (p[i].err == GetLastError() || p[i].err2 == GetLastError())) ||
956 (hFile != INVALID_HANDLE_VALUE && p[i].err == ERROR_SUCCESS),
957 "CreateFileA failed on %s, hFile %p, err=%u, should be %u\n",
958 filename, hFile, GetLastError(), p[i].err);
959 if (hFile != INVALID_HANDLE_VALUE)
960 CloseHandle( hFile );
963 ret = RemoveDirectoryA(dirname);
964 ok(ret, "RemoveDirectoryA: error %d\n", GetLastError());
967 /* test opening directory as a directory */
968 hFile = CreateFileA( temp_path, GENERIC_READ,
972 FILE_FLAG_BACKUP_SEMANTICS, NULL );
973 if (hFile != INVALID_HANDLE_VALUE && GetLastError() != ERROR_PATH_NOT_FOUND)
975 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_SUCCESS,
976 "CreateFileA did not work, last error %u on volume <%s>\n",
977 GetLastError(), temp_path );
979 if (hFile != INVALID_HANDLE_VALUE)
981 ret = GetFileInformationByHandle( hFile, &Finfo );
984 ok(Finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY,
985 "CreateFileA probably did not open temp directory %s correctly\n file information does not include FILE_ATTRIBUTE_DIRECTORY, actual=0x%08x\n",
986 temp_path, Finfo.dwFileAttributes);
988 CloseHandle( hFile );
992 skip("Probable Win9x, got ERROR_PATH_NOT_FOUND w/ FILE_FLAG_BACKUP_SEMANTICS or %s\n", temp_path);
995 /* *** Test opening volumes/devices using drive letter *** */
997 /* test using drive letter in non-rewrite format without trailing \ */
998 /* this should work */
999 strcpy(filename, nt_drive);
1000 filename[4] = windowsdir[0];
1001 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1002 FILE_SHARE_READ | FILE_SHARE_WRITE,
1003 NULL, OPEN_EXISTING,
1004 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
1005 if (hFile != INVALID_HANDLE_VALUE ||
1006 (GetLastError() != ERROR_ACCESS_DENIED && GetLastError() != ERROR_BAD_NETPATH))
1008 /* if we have adm rights to volume, then try rest of tests */
1009 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA did not open %s, last error=%u\n",
1010 filename, GetLastError());
1011 if (hFile != INVALID_HANDLE_VALUE)
1013 /* if we opened the volume/device, try to read it. Since it */
1014 /* opened, we should be able to read it. We don't care about*/
1015 /* what the data is at this time. */
1017 ret = ReadFile( hFile, buffer, len, &len, NULL );
1018 todo_wine ok(ret, "Failed to read volume, last error %u, %u, for %s\n",
1019 GetLastError(), ret, filename);
1022 trace("buffer is\n");
1023 dumpmem(buffer, 64);
1025 CloseHandle( hFile );
1028 /* test using drive letter with trailing \ and in non-rewrite */
1029 /* this should not work */
1030 strcpy(filename, nt_drive);
1031 filename[4] = windowsdir[0];
1032 strcat( filename, "\\" );
1033 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1034 FILE_SHARE_READ | FILE_SHARE_WRITE,
1035 NULL, OPEN_EXISTING,
1036 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
1038 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
1039 "CreateFileA should have returned ERROR_PATH_NOT_FOUND on %s, but got %u\n",
1040 filename, GetLastError());
1041 if (hFile != INVALID_HANDLE_VALUE)
1042 CloseHandle( hFile );
1044 /* test using temp path with trailing \ and in non-rewrite as dir */
1045 /* this should work */
1046 strcpy(filename, nt_drive);
1048 strcat( filename, temp_path );
1049 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1050 FILE_SHARE_READ | FILE_SHARE_WRITE,
1051 NULL, OPEN_EXISTING,
1052 FILE_FLAG_BACKUP_SEMANTICS, NULL );
1053 ok(hFile != INVALID_HANDLE_VALUE,
1054 "CreateFileA should have worked on %s, but got %u\n",
1055 filename, GetLastError());
1056 if (hFile != INVALID_HANDLE_VALUE)
1057 CloseHandle( hFile );
1059 /* test using drive letter without trailing \ and in device ns */
1060 /* this should work */
1061 strcpy(filename, nt_drive);
1062 filename[4] = windowsdir[0];
1064 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1065 FILE_SHARE_READ | FILE_SHARE_WRITE,
1066 NULL, OPEN_EXISTING,
1067 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
1068 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA did not open %s, last error=%u\n",
1069 filename, GetLastError());
1070 if (hFile != INVALID_HANDLE_VALUE)
1071 CloseHandle( hFile );
1073 /* If we see ERROR_BAD_NETPATH then on Win9x or WinME, so skip */
1074 else if (GetLastError() == ERROR_BAD_NETPATH)
1075 skip("Probable Win9x, got ERROR_BAD_NETPATH (53)\n");
1077 skip("Do not have authority to access volumes. Tests skipped\n");
1080 /* *** Test opening volumes/devices using GUID *** */
1082 if (pGetVolumeNameForVolumeMountPointA)
1084 strcpy(filename, "c:\\");
1085 filename[0] = windowsdir[0];
1086 ret = pGetVolumeNameForVolumeMountPointA( filename, Volume_1, MAX_PATH );
1087 ok(ret, "GetVolumeNameForVolumeMountPointA failed, for %s, last error=%d\n", filename, GetLastError());
1090 ok(strlen(Volume_1) == 49, "GetVolumeNameForVolumeMountPointA returned wrong length name <%s>\n", Volume_1);
1092 /* test the result of opening a unique volume name (GUID)
1093 * with the trailing \
1094 * this should error out
1096 strcpy(filename, Volume_1);
1097 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1098 FILE_SHARE_READ | FILE_SHARE_WRITE,
1099 NULL, OPEN_EXISTING,
1100 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
1102 ok(hFile == INVALID_HANDLE_VALUE,
1103 "CreateFileA should not have opened %s, hFile %p\n",
1106 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
1107 "CreateFileA should have returned ERROR_PATH_NOT_FOUND on %s, but got %u\n",
1108 filename, GetLastError());
1109 if (hFile != INVALID_HANDLE_VALUE)
1110 CloseHandle( hFile );
1112 /* test the result of opening a unique volume name (GUID)
1113 * with the temp path string as dir
1116 strcpy(filename, Volume_1);
1117 strcat(filename, temp_path+3);
1118 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1119 FILE_SHARE_READ | FILE_SHARE_WRITE,
1120 NULL, OPEN_EXISTING,
1121 FILE_FLAG_BACKUP_SEMANTICS, NULL );
1123 ok(hFile != INVALID_HANDLE_VALUE,
1124 "CreateFileA should have opened %s, but got %u\n",
1125 filename, GetLastError());
1126 if (hFile != INVALID_HANDLE_VALUE)
1127 CloseHandle( hFile );
1129 /* test the result of opening a unique volume name (GUID)
1130 * without the trailing \ and in device namespace
1133 strcpy(filename, Volume_1);
1136 hFile = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1137 FILE_SHARE_READ | FILE_SHARE_WRITE,
1138 NULL, OPEN_EXISTING,
1139 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING, NULL );
1140 if (hFile != INVALID_HANDLE_VALUE || GetLastError() != ERROR_ACCESS_DENIED)
1142 /* if we have adm rights to volume, then try rest of tests */
1143 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA did not open %s, last error=%u\n",
1144 filename, GetLastError());
1145 if (hFile != INVALID_HANDLE_VALUE)
1147 /* if we opened the volume/device, try to read it. Since it */
1148 /* opened, we should be able to read it. We don't care about*/
1149 /* what the data is at this time. */
1151 ret = ReadFile( hFile, buffer, len, &len, NULL );
1152 todo_wine ok(ret, "Failed to read volume, last error %u, %u, for %s\n",
1153 GetLastError(), ret, filename);
1156 trace("buffer is\n");
1157 dumpmem(buffer, 64);
1159 CloseHandle( hFile );
1163 skip("Do not have authority to access volumes. Tests skipped\n");
1166 win_skip("GetVolumeNameForVolumeMountPointA not functioning\n");
1169 win_skip("GetVolumeNameForVolumeMountPointA not found\n");
1172 static void test_CreateFileW(void)
1175 WCHAR temp_path[MAX_PATH];
1176 WCHAR filename[MAX_PATH];
1177 static const WCHAR emptyW[]={'\0'};
1178 static const WCHAR prefix[] = {'p','f','x',0};
1179 static const WCHAR bogus[] = { '\\', '\\', '.', '\\', 'B', 'O', 'G', 'U', 'S', 0 };
1182 ret = GetTempPathW(MAX_PATH, temp_path);
1183 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1185 win_skip("GetTempPathW is not available\n");
1188 ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
1189 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
1191 ret = GetTempFileNameW(temp_path, prefix, 0, filename);
1192 ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
1194 SetLastError(0xdeadbeef);
1195 hFile = CreateFileW(filename, GENERIC_READ, 0, NULL,
1196 CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
1197 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS,
1198 "CREATE_NEW should fail if file exists and last error value should be ERROR_FILE_EXISTS\n");
1200 SetLastError(0xdeadbeef);
1201 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
1202 CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
1203 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
1204 "hFile %p, last error %u\n", hFile, GetLastError());
1208 SetLastError(0xdeadbeef);
1209 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
1210 OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
1211 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == ERROR_ALREADY_EXISTS,
1212 "hFile %p, last error %u\n", hFile, GetLastError());
1216 ret = DeleteFileW(filename);
1217 ok(ret, "DeleteFileW: error %d\n", GetLastError());
1219 SetLastError(0xdeadbeef);
1220 hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
1221 OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
1222 ok(hFile != INVALID_HANDLE_VALUE && GetLastError() == 0,
1223 "hFile %p, last error %u\n", hFile, GetLastError());
1227 ret = DeleteFileW(filename);
1228 ok(ret, "DeleteFileW: error %d\n", GetLastError());
1232 /* this crashes on NT4.0 */
1233 hFile = CreateFileW(NULL, GENERIC_READ, 0, NULL,
1234 CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
1235 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
1236 "CreateFileW(NULL) returned ret=%p error=%u\n",hFile,GetLastError());
1239 hFile = CreateFileW(emptyW, GENERIC_READ, 0, NULL,
1240 CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0);
1241 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
1242 "CreateFileW(\"\") returned ret=%p error=%d\n",hFile,GetLastError());
1244 /* test the result of opening a nonexistent driver name */
1245 hFile = CreateFileW(bogus, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1246 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1247 ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND,
1248 "CreateFileW on invalid VxD name returned ret=%p error=%d\n",hFile,GetLastError());
1250 ret = CreateDirectoryW(filename, NULL);
1251 ok(ret == TRUE, "couldn't create temporary directory\n");
1252 hFile = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
1253 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL);
1254 ok(hFile != INVALID_HANDLE_VALUE,
1255 "expected CreateFile to succeed on existing directory, error: %d\n", GetLastError());
1257 ret = RemoveDirectoryW(filename);
1258 ok(ret, "DeleteFileW: error %d\n", GetLastError());
1261 static void test_GetTempFileNameA(void)
1265 char expected[MAX_PATH + 10];
1266 char windowsdir[MAX_PATH + 10];
1267 char windowsdrive[3];
1269 result = GetWindowsDirectory(windowsdir, sizeof(windowsdir));
1270 ok(result < sizeof(windowsdir), "windowsdir is abnormally long!\n");
1271 ok(result != 0, "GetWindowsDirectory: error %d\n", GetLastError());
1273 /* If the Windows directory is the root directory, it ends in backslash, not else. */
1274 if (strlen(windowsdir) != 3) /* As in "C:\" or "F:\" */
1276 strcat(windowsdir, "\\");
1279 windowsdrive[0] = windowsdir[0];
1280 windowsdrive[1] = windowsdir[1];
1281 windowsdrive[2] = '\0';
1283 result = GetTempFileNameA(windowsdrive, "abc", 1, out);
1284 ok(result != 0, "GetTempFileNameA: error %d\n", GetLastError());
1285 ok(((out[0] == windowsdrive[0]) && (out[1] == ':')) && (out[2] == '\\'),
1286 "GetTempFileNameA: first three characters should be %c:\\, string was actually %s\n",
1287 windowsdrive[0], out);
1289 result = GetTempFileNameA(windowsdir, "abc", 2, out);
1290 ok(result != 0, "GetTempFileNameA: error %d\n", GetLastError());
1292 strcat(expected, windowsdir);
1293 strcat(expected, "abc2.tmp");
1294 ok(lstrcmpiA(out, expected) == 0, "GetTempFileNameA: Unexpected output \"%s\" vs \"%s\"\n",
1298 static void test_DeleteFileA( void )
1301 char temp_path[MAX_PATH], temp_file[MAX_PATH];
1304 ret = DeleteFileA(NULL);
1305 ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER ||
1306 GetLastError() == ERROR_PATH_NOT_FOUND),
1307 "DeleteFileA(NULL) returned ret=%d error=%d\n",ret,GetLastError());
1309 ret = DeleteFileA("");
1310 ok(!ret && (GetLastError() == ERROR_PATH_NOT_FOUND ||
1311 GetLastError() == ERROR_BAD_PATHNAME),
1312 "DeleteFileA(\"\") returned ret=%d error=%d\n",ret,GetLastError());
1314 ret = DeleteFileA("nul");
1315 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
1316 GetLastError() == ERROR_INVALID_PARAMETER ||
1317 GetLastError() == ERROR_ACCESS_DENIED ||
1318 GetLastError() == ERROR_INVALID_FUNCTION),
1319 "DeleteFileA(\"nul\") returned ret=%d error=%d\n",ret,GetLastError());
1321 GetTempPathA(MAX_PATH, temp_path);
1322 GetTempFileName(temp_path, "tst", 0, temp_file);
1324 SetLastError(0xdeadbeef);
1325 hfile = CreateFile(temp_file, GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
1326 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
1328 SetLastError(0xdeadbeef);
1329 ret = DeleteFile(temp_file);
1331 ok(ret, "DeleteFile error %d\n", GetLastError());
1333 SetLastError(0xdeadbeef);
1334 ret = CloseHandle(hfile);
1335 ok(ret, "CloseHandle error %d\n", GetLastError());
1336 ret = DeleteFile(temp_file);
1338 ok(!ret, "DeleteFile should fail\n");
1341 static void test_DeleteFileW( void )
1344 WCHAR pathW[MAX_PATH];
1345 WCHAR pathsubW[MAX_PATH];
1346 static const WCHAR dirW[] = {'d','e','l','e','t','e','f','i','l','e',0};
1347 static const WCHAR subdirW[] = {'\\','s','u','b',0};
1348 static const WCHAR emptyW[]={'\0'};
1350 ret = DeleteFileW(NULL);
1351 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1353 win_skip("DeleteFileW is not available\n");
1356 ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND,
1357 "DeleteFileW(NULL) returned ret=%d error=%d\n",ret,GetLastError());
1359 ret = DeleteFileW(emptyW);
1360 ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND,
1361 "DeleteFileW(\"\") returned ret=%d error=%d\n",ret,GetLastError());
1363 /* test DeleteFile on empty directory */
1364 ret = GetTempPathW(MAX_PATH, pathW);
1365 if (ret + sizeof(dirW)/sizeof(WCHAR)-1 + sizeof(subdirW)/sizeof(WCHAR)-1 >= MAX_PATH)
1367 ok(0, "MAX_PATH exceeded in constructing paths\n");
1370 lstrcatW(pathW, dirW);
1371 lstrcpyW(pathsubW, pathW);
1372 lstrcatW(pathsubW, subdirW);
1373 ret = CreateDirectoryW(pathW, NULL);
1374 ok(ret == TRUE, "couldn't create directory deletefile\n");
1375 ret = DeleteFileW(pathW);
1376 ok(ret == FALSE, "DeleteFile should fail for empty directories\n");
1377 ret = RemoveDirectoryW(pathW);
1378 ok(ret == TRUE, "expected to remove directory deletefile\n");
1380 /* test DeleteFile on non-empty directory */
1381 ret = CreateDirectoryW(pathW, NULL);
1382 ok(ret == TRUE, "couldn't create directory deletefile\n");
1383 ret = CreateDirectoryW(pathsubW, NULL);
1384 ok(ret == TRUE, "couldn't create directory deletefile\\sub\n");
1385 ret = DeleteFileW(pathW);
1386 ok(ret == FALSE, "DeleteFile should fail for non-empty directories\n");
1387 ret = RemoveDirectoryW(pathsubW);
1388 ok(ret == TRUE, "expected to remove directory deletefile\\sub\n");
1389 ret = RemoveDirectoryW(pathW);
1390 ok(ret == TRUE, "expected to remove directory deletefile\n");
1393 #define IsDotDir(x) ((x[0] == '.') && ((x[1] == 0) || ((x[1] == '.') && (x[2] == 0))))
1395 static void test_MoveFileA(void)
1397 char tempdir[MAX_PATH];
1398 char source[MAX_PATH], dest[MAX_PATH];
1399 static const char prefix[] = "pfx";
1405 ret = GetTempPathA(MAX_PATH, tempdir);
1406 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
1407 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
1409 ret = GetTempFileNameA(tempdir, prefix, 0, source);
1410 ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
1412 ret = GetTempFileNameA(tempdir, prefix, 0, dest);
1413 ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
1415 ret = MoveFileA(source, dest);
1416 ok(!ret && GetLastError() == ERROR_ALREADY_EXISTS,
1417 "MoveFileA: unexpected error %d\n", GetLastError());
1419 ret = DeleteFileA(dest);
1420 ok(ret, "DeleteFileA: error %d\n", GetLastError());
1422 hfile = CreateFileA(source, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
1423 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
1425 retok = WriteFile(hfile, prefix, sizeof(prefix), &ret, NULL );
1426 ok( retok && ret == sizeof(prefix),
1427 "WriteFile error %d\n", GetLastError());
1429 hmapfile = CreateFileMapping(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
1430 ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError());
1432 ret = MoveFileA(source, dest);
1434 ok(!ret, "MoveFileA: expected failure\n");
1435 ok(GetLastError() == ERROR_SHARING_VIOLATION ||
1436 broken(GetLastError() == ERROR_ACCESS_DENIED), /* Win9x and WinMe */
1437 "MoveFileA: expected ERROR_SHARING_VIOLATION, got %d\n", GetLastError());
1440 CloseHandle(hmapfile);
1443 /* if MoveFile succeeded, move back to dest */
1444 if (ret) MoveFile(dest, source);
1446 hfile = CreateFileA(source, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
1447 ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
1449 hmapfile = CreateFileMapping(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL);
1450 ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError());
1452 ret = MoveFileA(source, dest);
1454 ok(!ret, "MoveFileA: expected failure\n");
1455 ok(GetLastError() == ERROR_SHARING_VIOLATION ||
1456 broken(GetLastError() == ERROR_ACCESS_DENIED), /* Win9x and WinMe */
1457 "MoveFileA: expected ERROR_SHARING_VIOLATION, got %d\n", GetLastError());
1460 CloseHandle(hmapfile);
1463 /* if MoveFile succeeded, move back to dest */
1464 if (ret) MoveFile(dest, source);
1466 ret = MoveFileA(source, dest);
1467 ok(ret, "MoveFileA: failed, error %d\n", GetLastError());
1469 lstrcatA(tempdir, "Remove Me");
1470 ret = CreateDirectoryA(tempdir, NULL);
1471 ok(ret == TRUE, "CreateDirectoryA failed\n");
1473 lstrcpyA(source, dest);
1474 lstrcpyA(dest, tempdir);
1475 lstrcatA(dest, "\\wild?.*");
1476 /* FIXME: if we create a file with wildcards we can't delete it now that DeleteFile works correctly */
1477 ret = MoveFileA(source, dest);
1478 ok(!ret, "MoveFileA: shouldn't move to wildcard file\n");
1479 ok(GetLastError() == ERROR_INVALID_NAME || /* NT */
1480 GetLastError() == ERROR_FILE_NOT_FOUND, /* Win9x */
1481 "MoveFileA: with wildcards, unexpected error %d\n", GetLastError());
1482 if (ret || (GetLastError() != ERROR_INVALID_NAME))
1484 WIN32_FIND_DATAA fd;
1485 char temppath[MAX_PATH];
1488 lstrcpyA(temppath, tempdir);
1489 lstrcatA(temppath, "\\*.*");
1490 hFind = FindFirstFileA(temppath, &fd);
1491 if (INVALID_HANDLE_VALUE != hFind)
1496 lpName = fd.cAlternateFileName;
1498 lpName = fd.cFileName;
1499 ok(IsDotDir(lpName), "MoveFileA: wildcards file created!\n");
1501 while (FindNextFileA(hFind, &fd));
1505 ret = DeleteFileA(source);
1506 ok(ret, "DeleteFileA: error %d\n", GetLastError());
1507 ret = DeleteFileA(dest);
1508 ok(!ret, "DeleteFileA: error %d\n", GetLastError());
1509 ret = RemoveDirectoryA(tempdir);
1510 ok(ret, "DeleteDirectoryA: error %d\n", GetLastError());
1513 static void test_MoveFileW(void)
1515 WCHAR temp_path[MAX_PATH];
1516 WCHAR source[MAX_PATH], dest[MAX_PATH];
1517 static const WCHAR prefix[] = {'p','f','x',0};
1520 ret = GetTempPathW(MAX_PATH, temp_path);
1521 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1523 win_skip("GetTempPathW is not available\n");
1526 ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
1527 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
1529 ret = GetTempFileNameW(temp_path, prefix, 0, source);
1530 ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
1532 ret = GetTempFileNameW(temp_path, prefix, 0, dest);
1533 ok(ret != 0, "GetTempFileNameW error %d\n", GetLastError());
1535 ret = MoveFileW(source, dest);
1536 ok(!ret && GetLastError() == ERROR_ALREADY_EXISTS,
1537 "CopyFileW: unexpected error %d\n", GetLastError());
1539 ret = DeleteFileW(source);
1540 ok(ret, "DeleteFileW: error %d\n", GetLastError());
1541 ret = DeleteFileW(dest);
1542 ok(ret, "DeleteFileW: error %d\n", GetLastError());
1545 #define PATTERN_OFFSET 0x10
1547 static void test_offset_in_overlapped_structure(void)
1553 BYTE buf[256], pattern[] = "TeSt";
1555 char temp_path[MAX_PATH], temp_fname[MAX_PATH];
1558 ret =GetTempPathA(MAX_PATH, temp_path);
1559 ok( ret, "GetTempPathA error %d\n", GetLastError());
1560 ret =GetTempFileNameA(temp_path, "pfx", 0, temp_fname);
1561 ok( ret, "GetTempFileNameA error %d\n", GetLastError());
1563 /*** Write File *****************************************************/
1565 hFile = CreateFileA(temp_fname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
1566 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError());
1568 for(i = 0; i < sizeof(buf); i++) buf[i] = i;
1569 ret = WriteFile(hFile, buf, sizeof(buf), &done, NULL);
1570 ok( ret, "WriteFile error %d\n", GetLastError());
1571 ok(done == sizeof(buf), "expected number of bytes written %u\n", done);
1573 memset(&ov, 0, sizeof(ov));
1574 S(U(ov)).Offset = PATTERN_OFFSET;
1575 S(U(ov)).OffsetHigh = 0;
1576 rc=WriteFile(hFile, pattern, sizeof(pattern), &done, &ov);
1577 /* Win 9x does not support the overlapped I/O on files */
1578 if (rc || GetLastError()!=ERROR_INVALID_PARAMETER) {
1579 ok(rc, "WriteFile error %d\n", GetLastError());
1580 ok(done == sizeof(pattern), "expected number of bytes written %u\n", done);
1581 offset = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
1582 ok(offset == PATTERN_OFFSET + sizeof(pattern), "wrong file offset %d\n", offset);
1584 S(U(ov)).Offset = sizeof(buf) * 2;
1585 S(U(ov)).OffsetHigh = 0;
1586 ret = WriteFile(hFile, pattern, sizeof(pattern), &done, &ov);
1587 ok( ret, "WriteFile error %d\n", GetLastError());
1588 ok(done == sizeof(pattern), "expected number of bytes written %u\n", done);
1589 offset = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
1590 ok(offset == sizeof(buf) * 2 + sizeof(pattern), "wrong file offset %d\n", offset);
1595 /*** Read File *****************************************************/
1597 hFile = CreateFileA(temp_fname, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
1598 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError());
1600 memset(buf, 0, sizeof(buf));
1601 memset(&ov, 0, sizeof(ov));
1602 S(U(ov)).Offset = PATTERN_OFFSET;
1603 S(U(ov)).OffsetHigh = 0;
1604 rc=ReadFile(hFile, buf, sizeof(pattern), &done, &ov);
1605 /* Win 9x does not support the overlapped I/O on files */
1606 if (rc || GetLastError()!=ERROR_INVALID_PARAMETER) {
1607 ok(rc, "ReadFile error %d\n", GetLastError());
1608 ok(done == sizeof(pattern), "expected number of bytes read %u\n", done);
1609 offset = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
1610 ok(offset == PATTERN_OFFSET + sizeof(pattern), "wrong file offset %d\n", offset);
1611 ok(!memcmp(buf, pattern, sizeof(pattern)), "pattern match failed\n");
1616 ret = DeleteFileA(temp_fname);
1617 ok( ret, "DeleteFileA error %d\n", GetLastError());
1620 static void test_LockFile(void)
1622 HANDLE handle, handle2;
1624 OVERLAPPED overlapped;
1625 int limited_LockFile;
1626 int limited_UnLockFile;
1629 handle = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1630 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1631 CREATE_ALWAYS, 0, 0 );
1632 if (handle == INVALID_HANDLE_VALUE)
1634 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
1637 handle2 = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE,
1638 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1639 OPEN_EXISTING, 0, 0 );
1640 if (handle2 == INVALID_HANDLE_VALUE)
1642 ok( 0, "couldn't open file \"%s\" (err=%d)\n", filename, GetLastError() );
1645 ok( WriteFile( handle, sillytext, strlen(sillytext), &written, NULL ), "write failed\n" );
1647 ok( LockFile( handle, 0, 0, 0, 0 ), "LockFile failed\n" );
1648 ok( UnlockFile( handle, 0, 0, 0, 0 ), "UnlockFile failed\n" );
1650 limited_UnLockFile = 0;
1651 if (UnlockFile( handle, 0, 0, 0, 0 ))
1653 limited_UnLockFile = 1;
1656 ok( LockFile( handle, 10, 0, 20, 0 ), "LockFile 10,20 failed\n" );
1657 /* overlapping locks must fail */
1658 ok( !LockFile( handle, 12, 0, 10, 0 ), "LockFile 12,10 succeeded\n" );
1659 ok( !LockFile( handle, 5, 0, 6, 0 ), "LockFile 5,6 succeeded\n" );
1660 /* non-overlapping locks must succeed */
1661 ok( LockFile( handle, 5, 0, 5, 0 ), "LockFile 5,5 failed\n" );
1663 ok( !UnlockFile( handle, 10, 0, 10, 0 ), "UnlockFile 10,10 succeeded\n" );
1664 ok( UnlockFile( handle, 10, 0, 20, 0 ), "UnlockFile 10,20 failed\n" );
1665 ok( !UnlockFile( handle, 10, 0, 20, 0 ), "UnlockFile 10,20 again succeeded\n" );
1666 ok( UnlockFile( handle, 5, 0, 5, 0 ), "UnlockFile 5,5 failed\n" );
1668 S(U(overlapped)).Offset = 100;
1669 S(U(overlapped)).OffsetHigh = 0;
1670 overlapped.hEvent = 0;
1672 /* Test for broken LockFileEx a la Windows 95 OSR2. */
1673 if (LockFileEx( handle, 0, 0, 100, 0, &overlapped ))
1675 /* LockFileEx is probably OK, test it more. */
1676 ok( LockFileEx( handle, 0, 0, 100, 0, &overlapped ),
1677 "LockFileEx 100,100 failed\n" );
1680 /* overlapping shared locks are OK */
1681 S(U(overlapped)).Offset = 150;
1682 limited_UnLockFile || ok( LockFileEx( handle, 0, 0, 100, 0, &overlapped ), "LockFileEx 150,100 failed\n" );
1684 /* but exclusive is not */
1685 ok( !LockFileEx( handle, LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,
1686 0, 50, 0, &overlapped ),
1687 "LockFileEx exclusive 150,50 succeeded\n" );
1688 if (!UnlockFileEx( handle, 0, 100, 0, &overlapped ))
1689 { /* UnLockFile is capable. */
1690 S(U(overlapped)).Offset = 100;
1691 ok( !UnlockFileEx( handle, 0, 100, 0, &overlapped ),
1692 "UnlockFileEx 150,100 again succeeded\n" );
1695 /* shared lock can overlap exclusive if handles are equal */
1696 S(U(overlapped)).Offset = 300;
1697 ok( LockFileEx( handle, LOCKFILE_EXCLUSIVE_LOCK, 0, 100, 0, &overlapped ),
1698 "LockFileEx exclusive 300,100 failed\n" );
1699 ok( !LockFileEx( handle2, LOCKFILE_FAIL_IMMEDIATELY, 0, 100, 0, &overlapped ),
1700 "LockFileEx handle2 300,100 succeeded\n" );
1701 ret = LockFileEx( handle, LOCKFILE_FAIL_IMMEDIATELY, 0, 100, 0, &overlapped );
1702 ok( ret, "LockFileEx 300,100 failed\n" );
1703 ok( UnlockFileEx( handle, 0, 100, 0, &overlapped ), "UnlockFileEx 300,100 failed\n" );
1704 /* exclusive lock is removed first */
1705 ok( LockFileEx( handle2, LOCKFILE_FAIL_IMMEDIATELY, 0, 100, 0, &overlapped ),
1706 "LockFileEx handle2 300,100 failed\n" );
1707 ok( UnlockFileEx( handle2, 0, 100, 0, &overlapped ), "UnlockFileEx 300,100 failed\n" );
1709 ok( UnlockFileEx( handle, 0, 100, 0, &overlapped ), "UnlockFileEx 300,100 failed\n" );
1711 ret = LockFile( handle, 0, 0x10000000, 0, 0xf0000000 );
1714 ok( !LockFile( handle, ~0, ~0, 1, 0 ), "LockFile ~0,1 succeeded\n" );
1715 ok( !LockFile( handle, 0, 0x20000000, 20, 0 ), "LockFile 0x20000000,20 succeeded\n" );
1716 ok( UnlockFile( handle, 0, 0x10000000, 0, 0xf0000000 ), "UnlockFile failed\n" );
1719 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong LockFile error %u\n", GetLastError() );
1721 /* wrap-around lock should not do anything */
1722 /* (but still succeeds on NT4 so we don't check result) */
1723 LockFile( handle, 0, 0x10000000, 0, 0xf0000001 );
1725 limited_LockFile = 0;
1726 if (!LockFile( handle, ~0, ~0, 1, 0 ))
1728 limited_LockFile = 1;
1731 limited_UnLockFile || ok( UnlockFile( handle, ~0, ~0, 1, 0 ), "Unlockfile ~0,1 failed\n" );
1733 /* zero-byte lock */
1734 ok( LockFile( handle, 100, 0, 0, 0 ), "LockFile 100,0 failed\n" );
1735 if (!limited_LockFile) ok( !LockFile( handle, 98, 0, 4, 0 ), "LockFile 98,4 succeeded\n" );
1736 ok( LockFile( handle, 90, 0, 10, 0 ), "LockFile 90,10 failed\n" );
1737 if (!limited_LockFile) ok( !LockFile( handle, 100, 0, 10, 0 ), "LockFile 100,10 failed\n" );
1739 ok( UnlockFile( handle, 90, 0, 10, 0 ), "UnlockFile 90,10 failed\n" );
1740 ok( !UnlockFile( handle, 100, 0, 10, 0 ), "UnlockFile 100,10 succeeded\n" );
1742 ok( UnlockFile( handle, 100, 0, 0, 0 ), "UnlockFile 100,0 failed\n" );
1744 CloseHandle( handle2 );
1746 CloseHandle( handle );
1747 DeleteFileA( filename );
1750 static BOOL create_fake_dll( LPCSTR filename )
1752 IMAGE_DOS_HEADER *dos;
1753 IMAGE_NT_HEADERS *nt;
1754 IMAGE_SECTION_HEADER *sec;
1756 DWORD lfanew = sizeof(*dos);
1757 DWORD size = lfanew + sizeof(*nt) + sizeof(*sec);
1761 HANDLE file = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1762 if (file == INVALID_HANDLE_VALUE) return FALSE;
1764 buffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size );
1766 dos = (IMAGE_DOS_HEADER *)buffer;
1767 dos->e_magic = IMAGE_DOS_SIGNATURE;
1768 dos->e_cblp = sizeof(*dos);
1770 dos->e_cparhdr = lfanew / 16;
1771 dos->e_minalloc = 0;
1772 dos->e_maxalloc = 0xffff;
1775 dos->e_lfarlc = lfanew;
1776 dos->e_lfanew = lfanew;
1778 nt = (IMAGE_NT_HEADERS *)(buffer + lfanew);
1779 nt->Signature = IMAGE_NT_SIGNATURE;
1780 #if defined __i386__
1781 nt->FileHeader.Machine = IMAGE_FILE_MACHINE_I386;
1782 #elif defined __x86_64__
1783 nt->FileHeader.Machine = IMAGE_FILE_MACHINE_AMD64;
1784 #elif defined __powerpc__
1785 nt->FileHeader.Machine = IMAGE_FILE_MACHINE_POWERPC;
1786 #elif defined __arm__
1787 nt->FileHeader.Machine = IMAGE_FILE_MACHINE_ARMNT;
1788 #elif defined __aarch64__
1789 nt->FileHeader.Machine = IMAGE_FILE_MACHINE_ARM64;
1791 # error You must specify the machine type
1793 nt->FileHeader.NumberOfSections = 1;
1794 nt->FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER);
1795 nt->FileHeader.Characteristics = IMAGE_FILE_DLL | IMAGE_FILE_EXECUTABLE_IMAGE;
1796 nt->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
1797 nt->OptionalHeader.MajorLinkerVersion = 1;
1798 nt->OptionalHeader.MinorLinkerVersion = 0;
1799 nt->OptionalHeader.ImageBase = 0x10000000;
1800 nt->OptionalHeader.SectionAlignment = 0x1000;
1801 nt->OptionalHeader.FileAlignment = 0x1000;
1802 nt->OptionalHeader.MajorOperatingSystemVersion = 1;
1803 nt->OptionalHeader.MinorOperatingSystemVersion = 0;
1804 nt->OptionalHeader.MajorImageVersion = 1;
1805 nt->OptionalHeader.MinorImageVersion = 0;
1806 nt->OptionalHeader.MajorSubsystemVersion = 4;
1807 nt->OptionalHeader.MinorSubsystemVersion = 0;
1808 nt->OptionalHeader.SizeOfImage = 0x2000;
1809 nt->OptionalHeader.SizeOfHeaders = size;
1810 nt->OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
1811 nt->OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
1813 sec = (IMAGE_SECTION_HEADER *)(nt + 1);
1814 memcpy( sec->Name, ".rodata", sizeof(".rodata") );
1815 sec->Misc.VirtualSize = 0x1000;
1816 sec->VirtualAddress = 0x1000;
1817 sec->SizeOfRawData = 0;
1818 sec->PointerToRawData = 0;
1819 sec->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
1821 ret = WriteFile( file, buffer, size, &written, NULL ) && written == size;
1822 HeapFree( GetProcessHeap(), 0, buffer );
1823 CloseHandle( file );
1827 static unsigned int map_file_access( unsigned int access )
1829 if (access & GENERIC_READ) access |= FILE_GENERIC_READ;
1830 if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE;
1831 if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE;
1832 if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS;
1833 return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
1836 static int is_sharing_compatible( DWORD access1, DWORD sharing1, DWORD access2, DWORD sharing2 )
1838 access1 = map_file_access( access1 );
1839 access2 = map_file_access( access2 );
1840 access1 &= FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_EXECUTE | DELETE;
1841 access2 &= FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_EXECUTE | DELETE;
1843 if (!access1) sharing1 = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
1844 if (!access2) sharing2 = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
1846 if ((access1 & (FILE_READ_DATA|FILE_EXECUTE)) && !(sharing2 & FILE_SHARE_READ)) return 0;
1847 if ((access1 & (FILE_WRITE_DATA|FILE_APPEND_DATA)) && !(sharing2 & FILE_SHARE_WRITE)) return 0;
1848 if ((access1 & DELETE) && !(sharing2 & FILE_SHARE_DELETE)) return 0;
1849 if ((access2 & (FILE_READ_DATA|FILE_EXECUTE)) && !(sharing1 & FILE_SHARE_READ)) return 0;
1850 if ((access2 & (FILE_WRITE_DATA|FILE_APPEND_DATA)) && !(sharing1 & FILE_SHARE_WRITE)) return 0;
1851 if ((access2 & DELETE) && !(sharing1 & FILE_SHARE_DELETE)) return 0;
1855 static int is_sharing_map_compatible( DWORD map_access, DWORD access2, DWORD sharing2 )
1857 if ((map_access == PAGE_READWRITE || map_access == PAGE_EXECUTE_READWRITE) &&
1858 !(sharing2 & FILE_SHARE_WRITE)) return 0;
1859 access2 = map_file_access( access2 );
1860 if ((map_access & SEC_IMAGE) && (access2 & FILE_WRITE_DATA)) return 0;
1864 static void test_file_sharing(void)
1866 static const DWORD access_modes[] =
1867 { 0, GENERIC_READ, GENERIC_WRITE, GENERIC_READ|GENERIC_WRITE,
1868 DELETE, GENERIC_READ|DELETE, GENERIC_WRITE|DELETE, GENERIC_READ|GENERIC_WRITE|DELETE,
1869 GENERIC_EXECUTE, GENERIC_EXECUTE | DELETE,
1870 FILE_READ_DATA, FILE_WRITE_DATA, FILE_APPEND_DATA, FILE_READ_EA, FILE_WRITE_EA,
1871 FILE_READ_DATA | FILE_EXECUTE, FILE_WRITE_DATA | FILE_EXECUTE, FILE_APPEND_DATA | FILE_EXECUTE,
1872 FILE_READ_EA | FILE_EXECUTE, FILE_WRITE_EA | FILE_EXECUTE, FILE_EXECUTE,
1873 FILE_DELETE_CHILD, FILE_READ_ATTRIBUTES, FILE_WRITE_ATTRIBUTES };
1874 static const DWORD sharing_modes[] =
1875 { 0, FILE_SHARE_READ,
1876 FILE_SHARE_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
1877 FILE_SHARE_DELETE, FILE_SHARE_READ|FILE_SHARE_DELETE,
1878 FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE };
1879 static const DWORD mapping_modes[] =
1880 { PAGE_READONLY, PAGE_WRITECOPY, PAGE_READWRITE, SEC_IMAGE | PAGE_WRITECOPY };
1885 /* make sure the file exists */
1886 if (!create_fake_dll( filename ))
1888 ok(0, "couldn't create file \"%s\" (err=%d)\n", filename, GetLastError());
1892 for (a1 = 0; a1 < sizeof(access_modes)/sizeof(access_modes[0]); a1++)
1894 for (s1 = 0; s1 < sizeof(sharing_modes)/sizeof(sharing_modes[0]); s1++)
1896 SetLastError(0xdeadbeef);
1897 h = CreateFileA( filename, access_modes[a1], sharing_modes[s1],
1898 NULL, OPEN_EXISTING, 0, 0 );
1899 if (h == INVALID_HANDLE_VALUE)
1901 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
1904 for (a2 = 0; a2 < sizeof(access_modes)/sizeof(access_modes[0]); a2++)
1906 for (s2 = 0; s2 < sizeof(sharing_modes)/sizeof(sharing_modes[0]); s2++)
1908 SetLastError(0xdeadbeef);
1909 h2 = CreateFileA( filename, access_modes[a2], sharing_modes[s2],
1910 NULL, OPEN_EXISTING, 0, 0 );
1911 ret = GetLastError();
1912 if (is_sharing_compatible( access_modes[a1], sharing_modes[s1],
1913 access_modes[a2], sharing_modes[s2] ))
1915 ok( h2 != INVALID_HANDLE_VALUE,
1916 "open failed for modes %x/%x/%x/%x\n",
1917 access_modes[a1], sharing_modes[s1],
1918 access_modes[a2], sharing_modes[s2] );
1919 ok( ret == 0, "wrong error code %d\n", ret );
1923 ok( h2 == INVALID_HANDLE_VALUE,
1924 "open succeeded for modes %x/%x/%x/%x\n",
1925 access_modes[a1], sharing_modes[s1],
1926 access_modes[a2], sharing_modes[s2] );
1927 ok( ret == ERROR_SHARING_VIOLATION,
1928 "wrong error code %d\n", ret );
1930 if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 );
1937 for (a1 = 0; a1 < sizeof(mapping_modes)/sizeof(mapping_modes[0]); a1++)
1941 create_fake_dll( filename );
1942 SetLastError(0xdeadbeef);
1943 h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
1944 if (h == INVALID_HANDLE_VALUE)
1946 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
1949 m = CreateFileMappingA( h, NULL, mapping_modes[a1], 0, 0, NULL );
1950 ok( m != 0, "failed to create mapping %x err %u\n", mapping_modes[a1], GetLastError() );
1954 for (a2 = 0; a2 < sizeof(access_modes)/sizeof(access_modes[0]); a2++)
1956 for (s2 = 0; s2 < sizeof(sharing_modes)/sizeof(sharing_modes[0]); s2++)
1958 SetLastError(0xdeadbeef);
1959 h2 = CreateFileA( filename, access_modes[a2], sharing_modes[s2],
1960 NULL, OPEN_EXISTING, 0, 0 );
1962 ret = GetLastError();
1963 if (h2 == INVALID_HANDLE_VALUE)
1965 ok( !is_sharing_map_compatible(mapping_modes[a1], access_modes[a2], sharing_modes[s2]),
1966 "open failed for modes map %x/%x/%x\n",
1967 mapping_modes[a1], access_modes[a2], sharing_modes[s2] );
1968 ok( ret == ERROR_SHARING_VIOLATION,
1969 "wrong error code %d\n", ret );
1973 if (!is_sharing_map_compatible(mapping_modes[a1], access_modes[a2], sharing_modes[s2]))
1974 ok( broken(1), /* no checking on nt4 */
1975 "open succeeded for modes map %x/%x/%x\n",
1976 mapping_modes[a1], access_modes[a2], sharing_modes[s2] );
1977 ok( ret == 0xdeadbeef /* Win9x */ ||
1979 "wrong error code %d\n", ret );
1985 /* try CREATE_ALWAYS over an existing mapping */
1986 SetLastError(0xdeadbeef);
1987 h2 = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
1988 NULL, CREATE_ALWAYS, 0, 0 );
1989 ret = GetLastError();
1990 if (mapping_modes[a1] & SEC_IMAGE)
1992 ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] );
1993 ok( ret == ERROR_SHARING_VIOLATION, "wrong error code %d for %x\n", ret, mapping_modes[a1] );
1997 ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] );
1998 ok( ret == ERROR_USER_MAPPED_FILE, "wrong error code %d for %x\n", ret, mapping_modes[a1] );
2000 if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 );
2002 /* try DELETE_ON_CLOSE over an existing mapping */
2003 SetLastError(0xdeadbeef);
2004 h2 = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
2005 NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0 );
2006 ret = GetLastError();
2007 if (mapping_modes[a1] & SEC_IMAGE)
2009 ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] );
2010 ok( ret == ERROR_ACCESS_DENIED, "wrong error code %d for %x\n", ret, mapping_modes[a1] );
2014 ok( h2 != INVALID_HANDLE_VALUE, "open failed for map %x err %u\n", mapping_modes[a1], ret );
2016 if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 );
2021 SetLastError(0xdeadbeef);
2022 h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, 0 );
2023 ok( h != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError() );
2025 SetLastError(0xdeadbeef);
2026 h2 = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
2027 ok( h2 == INVALID_HANDLE_VALUE, "CreateFileA should fail\n");
2028 ok( GetLastError() == ERROR_SHARING_VIOLATION, "wrong error code %d\n", GetLastError() );
2030 h2 = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
2031 ok( h2 != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError() );
2036 DeleteFileA( filename );
2039 static char get_windows_drive(void)
2041 char windowsdir[MAX_PATH];
2042 GetWindowsDirectory(windowsdir, sizeof(windowsdir));
2043 return windowsdir[0];
2046 static void test_FindFirstFileA(void)
2049 WIN32_FIND_DATAA data;
2051 char buffer[5] = "C:\\";
2053 char nonexistent[MAX_PATH];
2055 /* try FindFirstFileA on "C:\" */
2056 buffer[0] = get_windows_drive();
2058 SetLastError( 0xdeadbeaf );
2059 handle = FindFirstFileA(buffer, &data);
2060 err = GetLastError();
2061 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on root directory should fail\n" );
2062 ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err );
2064 /* try FindFirstFileA on "C:\*" */
2065 strcpy(buffer2, buffer);
2066 strcat(buffer2, "*");
2067 handle = FindFirstFileA(buffer2, &data);
2068 ok ( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s should succeed\n", buffer2 );
2069 ok ( strcmp( data.cFileName, "." ) && strcmp( data.cFileName, ".." ),
2070 "FindFirstFile shouldn't return '%s' in drive root\n", data.cFileName );
2071 if (FindNextFileA( handle, &data ))
2072 ok ( strcmp( data.cFileName, "." ) && strcmp( data.cFileName, ".." ),
2073 "FindNextFile shouldn't return '%s' in drive root\n", data.cFileName );
2074 ok ( FindClose(handle) == TRUE, "Failed to close handle %s\n", buffer2 );
2076 /* try FindFirstFileA on windows dir */
2077 GetWindowsDirectory( buffer2, sizeof(buffer2) );
2078 strcat(buffer2, "\\*");
2079 handle = FindFirstFileA(buffer2, &data);
2080 ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s should succeed\n", buffer2 );
2081 ok( !strcmp( data.cFileName, "." ), "FindFirstFile should return '.' first\n" );
2082 ok( FindNextFileA( handle, &data ), "FindNextFile failed\n" );
2083 ok( !strcmp( data.cFileName, ".." ), "FindNextFile should return '..' as second entry\n" );
2084 while (FindNextFileA( handle, &data ))
2085 ok ( strcmp( data.cFileName, "." ) && strcmp( data.cFileName, ".." ),
2086 "FindNextFile shouldn't return '%s'\n", data.cFileName );
2087 ok ( FindClose(handle) == TRUE, "Failed to close handle %s\n", buffer2 );
2089 /* try FindFirstFileA on "C:\foo\" */
2090 SetLastError( 0xdeadbeaf );
2091 if (!GetTempFileNameA( buffer, "foo", 0, nonexistent ) && GetLastError() == ERROR_ACCESS_DENIED)
2094 GetTempPathA( sizeof(tmp), tmp );
2095 GetTempFileNameA( tmp, "foo", 0, nonexistent );
2097 DeleteFileA( nonexistent );
2098 strcpy(buffer2, nonexistent);
2099 strcat(buffer2, "\\");
2100 handle = FindFirstFileA(buffer2, &data);
2101 err = GetLastError();
2102 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2104 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2107 /* try FindFirstFileA on "C:\foo\bar.txt" */
2108 SetLastError( 0xdeadbeaf );
2109 strcpy(buffer2, nonexistent);
2110 strcat(buffer2, "\\bar.txt");
2111 handle = FindFirstFileA(buffer2, &data);
2112 err = GetLastError();
2113 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2114 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2116 /* try FindFirstFileA on "C:\foo\*.*" */
2117 SetLastError( 0xdeadbeaf );
2118 strcpy(buffer2, nonexistent);
2119 strcat(buffer2, "\\*.*");
2120 handle = FindFirstFileA(buffer2, &data);
2121 err = GetLastError();
2122 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2123 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2125 /* try FindFirstFileA on "foo\bar.txt" */
2126 SetLastError( 0xdeadbeaf );
2127 strcpy(buffer2, nonexistent + 3);
2128 strcat(buffer2, "\\bar.txt");
2129 handle = FindFirstFileA(buffer2, &data);
2130 err = GetLastError();
2131 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2132 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2134 /* try FindFirstFileA on "c:\nul" */
2135 SetLastError( 0xdeadbeaf );
2136 strcpy(buffer2, buffer);
2137 strcat(buffer2, "nul");
2138 handle = FindFirstFileA(buffer2, &data);
2139 err = GetLastError();
2140 ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s failed: %d\n", buffer2, err );
2141 ok( 0 == lstrcmpiA(data.cFileName, "nul"), "wrong name %s\n", data.cFileName );
2142 ok( FILE_ATTRIBUTE_ARCHIVE == data.dwFileAttributes ||
2143 FILE_ATTRIBUTE_DEVICE == data.dwFileAttributes /* Win9x */,
2144 "wrong attributes %x\n", data.dwFileAttributes );
2145 if (data.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE)
2147 ok( 0 == data.nFileSizeHigh, "wrong size %d\n", data.nFileSizeHigh );
2148 ok( 0 == data.nFileSizeLow, "wrong size %d\n", data.nFileSizeLow );
2150 SetLastError( 0xdeadbeaf );
2151 ok( !FindNextFileA( handle, &data ), "FindNextFileA succeeded\n" );
2152 ok( GetLastError() == ERROR_NO_MORE_FILES, "bad error %d\n", GetLastError() );
2153 ok( FindClose( handle ), "failed to close handle\n" );
2155 /* try FindFirstFileA on "lpt1" */
2156 SetLastError( 0xdeadbeaf );
2157 strcpy(buffer2, "lpt1");
2158 handle = FindFirstFileA(buffer2, &data);
2159 err = GetLastError();
2160 ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s failed: %d\n", buffer2, err );
2161 ok( 0 == lstrcmpiA(data.cFileName, "lpt1"), "wrong name %s\n", data.cFileName );
2162 ok( FILE_ATTRIBUTE_ARCHIVE == data.dwFileAttributes ||
2163 FILE_ATTRIBUTE_DEVICE == data.dwFileAttributes /* Win9x */,
2164 "wrong attributes %x\n", data.dwFileAttributes );
2165 if (data.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE)
2167 ok( 0 == data.nFileSizeHigh, "wrong size %d\n", data.nFileSizeHigh );
2168 ok( 0 == data.nFileSizeLow, "wrong size %d\n", data.nFileSizeLow );
2170 SetLastError( 0xdeadbeaf );
2171 ok( !FindNextFileA( handle, &data ), "FindNextFileA succeeded\n" );
2172 ok( GetLastError() == ERROR_NO_MORE_FILES, "bad error %d\n", GetLastError() );
2173 ok( FindClose( handle ), "failed to close handle\n" );
2175 /* try FindFirstFileA on "c:\nul\*" */
2176 SetLastError( 0xdeadbeaf );
2177 strcpy(buffer2, buffer);
2178 strcat(buffer2, "nul\\*");
2179 handle = FindFirstFileA(buffer2, &data);
2180 err = GetLastError();
2181 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2182 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2184 /* try FindFirstFileA on "c:\nul*" */
2185 SetLastError( 0xdeadbeaf );
2186 strcpy(buffer2, buffer);
2187 strcat(buffer2, "nul*");
2188 handle = FindFirstFileA(buffer2, &data);
2189 err = GetLastError();
2190 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2191 ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err );
2193 /* try FindFirstFileA on "c:\foo\bar\nul" */
2194 SetLastError( 0xdeadbeaf );
2195 strcpy(buffer2, buffer);
2196 strcat(buffer2, "foo\\bar\\nul");
2197 handle = FindFirstFileA(buffer2, &data);
2198 err = GetLastError();
2199 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2200 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2202 /* try FindFirstFileA on "c:\foo\nul\bar" */
2203 SetLastError( 0xdeadbeaf );
2204 strcpy(buffer2, buffer);
2205 strcat(buffer2, "foo\\nul\\bar");
2206 handle = FindFirstFileA(buffer2, &data);
2207 err = GetLastError();
2208 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2209 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2212 static void test_FindNextFileA(void)
2215 WIN32_FIND_DATAA search_results;
2217 char buffer[5] = "C:\\*";
2219 buffer[0] = get_windows_drive();
2220 handle = FindFirstFileA(buffer,&search_results);
2221 ok ( handle != INVALID_HANDLE_VALUE, "FindFirstFile on C:\\* should succeed\n" );
2222 while (FindNextFile(handle, &search_results))
2224 /* get to the end of the files */
2226 ok ( FindClose(handle) == TRUE, "Failed to close handle\n");
2227 err = GetLastError();
2228 ok ( err == ERROR_NO_MORE_FILES, "GetLastError should return ERROR_NO_MORE_FILES\n");
2231 static void test_FindFirstFileExA(FINDEX_SEARCH_OPS search_ops)
2233 WIN32_FIND_DATAA search_results;
2237 if (!pFindFirstFileExA)
2239 win_skip("FindFirstFileExA() is missing\n");
2243 CreateDirectoryA("test-dir", NULL);
2244 _lclose(_lcreat("test-dir\\file1", 0));
2245 _lclose(_lcreat("test-dir\\file2", 0));
2246 CreateDirectoryA("test-dir\\dir1", NULL);
2247 SetLastError(0xdeadbeef);
2248 handle = pFindFirstFileExA("test-dir\\*", FindExInfoStandard, &search_results, search_ops, NULL, 0);
2249 if (handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
2251 win_skip("FindFirstFileExA is not implemented\n");
2254 ok(handle != INVALID_HANDLE_VALUE, "FindFirstFile failed (err=%u)\n", GetLastError());
2255 ok(strcmp(search_results.cFileName, ".") == 0, "First entry should be '.', is %s\n", search_results.cFileName);
2257 #define CHECK_NAME(fn) (strcmp((fn), "file1") == 0 || strcmp((fn), "file2") == 0 || strcmp((fn), "dir1") == 0)
2259 ok(FindNextFile(handle, &search_results), "Fetching second file failed\n");
2260 ok(strcmp(search_results.cFileName, "..") == 0, "Second entry should be '..' is %s\n", search_results.cFileName);
2262 ok(FindNextFile(handle, &search_results), "Fetching third file failed\n");
2263 ok(CHECK_NAME(search_results.cFileName), "Invalid third entry - %s\n", search_results.cFileName);
2265 SetLastError(0xdeadbeef);
2266 ret = FindNextFile(handle, &search_results);
2267 if (!ret && (GetLastError() == ERROR_NO_MORE_FILES) && (search_ops == FindExSearchLimitToDirectories))
2269 skip("File system supports directory filtering\n");
2270 /* Results from the previous call are not cleared */
2271 ok(strcmp(search_results.cFileName, "dir1") == 0, "Third entry should be 'dir1' is %s\n", search_results.cFileName);
2272 FindClose( handle );
2276 ok(ret, "Fetching fourth file failed\n");
2277 ok(CHECK_NAME(search_results.cFileName), "Invalid fourth entry - %s\n", search_results.cFileName);
2279 ok(FindNextFile(handle, &search_results), "Fetching fifth file failed\n");
2280 ok(CHECK_NAME(search_results.cFileName), "Invalid fifth entry - %s\n", search_results.cFileName);
2284 ok(FindNextFile(handle, &search_results) == FALSE, "Fetching sixth file should fail\n");
2286 FindClose( handle );
2289 DeleteFileA("test-dir\\file1");
2290 DeleteFileA("test-dir\\file2");
2291 RemoveDirectoryA("test-dir\\dir1");
2292 RemoveDirectoryA("test-dir");
2295 static int test_Mapfile_createtemp(HANDLE *handle)
2297 SetFileAttributesA(filename,FILE_ATTRIBUTE_NORMAL);
2298 DeleteFile(filename);
2299 *handle = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, 0,
2300 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2301 if (*handle != INVALID_HANDLE_VALUE) {
2309 static void test_MapFile(void)
2314 ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
2316 hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0x1000, "named_file_map" );
2317 ok( hmap != NULL, "mapping should work, I named it!\n" );
2319 ok( CloseHandle( hmap ), "can't close mapping handle\n");
2321 /* We have to close file before we try new stuff with mapping again.
2322 Else we would always succeed on XP or block descriptors on 95. */
2323 hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
2324 ok( hmap != NULL, "We should still be able to map!\n" );
2325 ok( CloseHandle( hmap ), "can't close mapping handle\n");
2326 ok( CloseHandle( handle ), "can't close file handle\n");
2329 ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
2331 hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
2332 ok( hmap == NULL, "mapped zero size file\n");
2333 ok( GetLastError() == ERROR_FILE_INVALID, "not ERROR_FILE_INVALID\n");
2335 hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0x80000000, 0, NULL );
2336 ok( hmap == NULL || broken(hmap != NULL) /* NT4 */, "mapping should fail\n");
2337 /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */
2339 CloseHandle( hmap );
2341 hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0x80000000, 0x10000, NULL );
2342 ok( hmap == NULL || broken(hmap != NULL) /* NT4 */, "mapping should fail\n");
2343 /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */
2345 CloseHandle( hmap );
2347 /* On XP you can now map again, on Win 95 you cannot. */
2349 ok( CloseHandle( handle ), "can't close file handle\n");
2350 ok( DeleteFileA( filename ), "DeleteFile failed after map\n" );
2353 static void test_GetFileType(void)
2356 HANDLE h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2357 ok( h != INVALID_HANDLE_VALUE, "open %s failed\n", filename );
2358 type = GetFileType(h);
2359 ok( type == FILE_TYPE_DISK, "expected type disk got %d\n", type );
2361 h = CreateFileA( "nul", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2362 ok( h != INVALID_HANDLE_VALUE, "open nul failed\n" );
2363 type = GetFileType(h);
2364 ok( type == FILE_TYPE_CHAR, "expected type char for nul got %d\n", type );
2366 DeleteFileA( filename );
2369 static int completion_count;
2371 static void CALLBACK FileIOComplete(DWORD dwError, DWORD dwBytes, LPOVERLAPPED ovl)
2373 /* printf("(%ld, %ld, %p { %ld, %ld, %ld, %ld, %p })\n", dwError, dwBytes, ovl, ovl->Internal, ovl->InternalHigh, ovl->Offset, ovl->OffsetHigh, ovl->hEvent);*/
2374 ReleaseSemaphore(ovl->hEvent, 1, NULL);
2378 static void test_async_file_errors(void)
2380 char szFile[MAX_PATH];
2381 HANDLE hSem = CreateSemaphoreW(NULL, 1, 1, NULL);
2383 LPVOID lpBuffer = HeapAlloc(GetProcessHeap(), 0, 4096);
2385 S(U(ovl)).Offset = 0;
2386 S(U(ovl)).OffsetHigh = 0;
2388 completion_count = 0;
2390 GetWindowsDirectoryA(szFile, sizeof(szFile)/sizeof(szFile[0])-1-strlen("\\win.ini"));
2391 strcat(szFile, "\\win.ini");
2392 hFile = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
2393 NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
2394 if (hFile == INVALID_HANDLE_VALUE) /* win9x doesn't like FILE_SHARE_DELETE */
2395 hFile = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
2396 NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
2397 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA(%s ...) failed\n", szFile);
2402 while (WaitForSingleObjectEx(hSem, INFINITE, TRUE) == WAIT_IO_COMPLETION)
2404 res = ReadFileEx(hFile, lpBuffer, 4096, &ovl, FileIOComplete);
2405 /*printf("Offset = %ld, result = %s\n", ovl.Offset, res ? "TRUE" : "FALSE");*/
2408 if (!GetOverlappedResult(hFile, &ovl, &count, FALSE))
2410 S(U(ovl)).Offset += count;
2411 /* i/o completion routine only called if ReadFileEx returned success.
2412 * we only care about violations of this rule so undo what should have
2416 ok(completion_count == 0, "completion routine should only be called when ReadFileEx succeeds (this rule was violated %d times)\n", completion_count);
2417 /*printf("Error = %ld\n", GetLastError());*/
2418 HeapFree(GetProcessHeap(), 0, lpBuffer);
2421 static BOOL user_apc_ran;
2422 static void CALLBACK user_apc(ULONG_PTR param)
2424 user_apc_ran = TRUE;
2427 static void test_read_write(void)
2429 DWORD bytes, ret, old_prot;
2431 char temp_path[MAX_PATH];
2432 char filename[MAX_PATH];
2434 static const char prefix[] = "pfx";
2436 ret = GetTempPathA(MAX_PATH, temp_path);
2437 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
2438 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
2440 ret = GetTempFileNameA(temp_path, prefix, 0, filename);
2441 ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
2443 hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
2444 CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
2445 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
2447 user_apc_ran = FALSE;
2448 if (pQueueUserAPC) {
2449 trace("Queueing an user APC\n"); /* verify the file is non alerable */
2450 ret = pQueueUserAPC(&user_apc, GetCurrentThread(), 0);
2451 ok(ret, "QueueUserAPC failed: %d\n", GetLastError());
2454 SetLastError(12345678);
2456 ret = WriteFile(hFile, NULL, 0, &bytes, NULL);
2457 ok(ret && GetLastError() == 12345678,
2458 "ret = %d, error %d\n", ret, GetLastError());
2459 ok(!bytes, "bytes = %d\n", bytes);
2461 SetLastError(12345678);
2463 ret = WriteFile(hFile, NULL, 10, &bytes, NULL);
2464 ok((!ret && GetLastError() == ERROR_INVALID_USER_BUFFER) || /* Win2k */
2465 (ret && GetLastError() == 12345678), /* Win9x */
2466 "ret = %d, error %d\n", ret, GetLastError());
2467 ok(!bytes || /* Win2k */
2468 bytes == 10, /* Win9x */
2469 "bytes = %d\n", bytes);
2471 /* make sure the file contains data */
2472 WriteFile(hFile, "this is the test data", 21, &bytes, NULL);
2473 SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
2475 SetLastError(12345678);
2477 ret = ReadFile(hFile, NULL, 0, &bytes, NULL);
2478 ok(ret && GetLastError() == 12345678,
2479 "ret = %d, error %d\n", ret, GetLastError());
2480 ok(!bytes, "bytes = %d\n", bytes);
2482 SetLastError(12345678);
2484 ret = ReadFile(hFile, NULL, 10, &bytes, NULL);
2485 ok(!ret && (GetLastError() == ERROR_NOACCESS || /* Win2k */
2486 GetLastError() == ERROR_INVALID_PARAMETER), /* Win9x */
2487 "ret = %d, error %d\n", ret, GetLastError());
2488 ok(!bytes, "bytes = %d\n", bytes);
2490 ok(user_apc_ran == FALSE, "UserAPC ran, file using alertable io mode\n");
2492 SleepEx(0, TRUE); /* get rid of apc */
2494 /* test passing protected memory as buffer */
2496 mem = VirtualAlloc( NULL, 0x4000, MEM_COMMIT, PAGE_READWRITE );
2497 ok( mem != NULL, "failed to allocate virtual mem error %u\n", GetLastError() );
2499 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
2500 ok( ret, "WriteFile failed error %u\n", GetLastError() );
2501 ok( bytes == 0x4000, "only wrote %x bytes\n", bytes );
2503 ret = VirtualProtect( mem + 0x2000, 0x2000, PAGE_NOACCESS, &old_prot );
2504 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2506 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
2507 ok( !ret, "WriteFile succeeded\n" );
2508 ok( GetLastError() == ERROR_INVALID_USER_BUFFER ||
2509 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2510 "wrong error %u\n", GetLastError() );
2511 ok( bytes == 0, "wrote %x bytes\n", bytes );
2513 ret = WriteFile( (HANDLE)0xdead, mem, 0x4000, &bytes, NULL );
2514 ok( !ret, "WriteFile succeeded\n" );
2515 ok( GetLastError() == ERROR_INVALID_HANDLE || /* handle is checked before buffer on NT */
2516 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2517 "wrong error %u\n", GetLastError() );
2518 ok( bytes == 0, "wrote %x bytes\n", bytes );
2520 ret = VirtualProtect( mem, 0x2000, PAGE_NOACCESS, &old_prot );
2521 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2523 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
2524 ok( !ret, "WriteFile succeeded\n" );
2525 ok( GetLastError() == ERROR_INVALID_USER_BUFFER ||
2526 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2527 "wrong error %u\n", GetLastError() );
2528 ok( bytes == 0, "wrote %x bytes\n", bytes );
2530 SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
2532 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2533 ok( !ret, "ReadFile succeeded\n" );
2534 ok( GetLastError() == ERROR_NOACCESS ||
2535 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2536 "wrong error %u\n", GetLastError() );
2537 ok( bytes == 0, "read %x bytes\n", bytes );
2539 ret = VirtualProtect( mem, 0x2000, PAGE_READONLY, &old_prot );
2540 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2542 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2543 ok( !ret, "ReadFile succeeded\n" );
2544 ok( GetLastError() == ERROR_NOACCESS ||
2545 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2546 "wrong error %u\n", GetLastError() );
2547 ok( bytes == 0, "read %x bytes\n", bytes );
2549 ret = VirtualProtect( mem, 0x2000, PAGE_READWRITE, &old_prot );
2550 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2552 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2553 ok( !ret, "ReadFile succeeded\n" );
2554 ok( GetLastError() == ERROR_NOACCESS ||
2555 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2556 "wrong error %u\n", GetLastError() );
2557 ok( bytes == 0, "read %x bytes\n", bytes );
2559 SetFilePointer( hFile, 0x1234, NULL, FILE_BEGIN );
2560 SetEndOfFile( hFile );
2561 SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
2563 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2564 ok( !ret, "ReadFile succeeded\n" );
2565 ok( GetLastError() == ERROR_NOACCESS ||
2566 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2567 "wrong error %u\n", GetLastError() );
2568 ok( bytes == 0, "read %x bytes\n", bytes );
2570 ret = ReadFile( hFile, mem, 0x2000, &bytes, NULL );
2571 ok( ret, "ReadFile failed error %u\n", GetLastError() );
2572 ok( bytes == 0x1234, "read %x bytes\n", bytes );
2574 ret = ReadFile( hFile, NULL, 1, &bytes, NULL );
2575 ok( !ret, "ReadFile succeeded\n" );
2576 ok( GetLastError() == ERROR_NOACCESS ||
2577 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2578 "wrong error %u\n", GetLastError() );
2579 ok( bytes == 0, "read %x bytes\n", bytes );
2581 VirtualFree( mem, 0, MEM_FREE );
2583 ret = CloseHandle(hFile);
2584 ok( ret, "CloseHandle: error %d\n", GetLastError());
2585 ret = DeleteFileA(filename);
2586 ok( ret, "DeleteFileA: error %d\n", GetLastError());
2589 static void test_OpenFile(void)
2596 static const char file[] = "regedit.exe";
2597 static const char foo[] = ".\\foo-bar-foo.baz";
2598 static const char *foo_too_long = ".\\foo-bar-foo.baz+++++++++++++++"
2599 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2600 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2601 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2602 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2603 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
2604 char buff[MAX_PATH];
2605 char buff_long[4*MAX_PATH];
2606 char filled_0xA5[OFS_MAXPATHNAME];
2610 /* Check for existing file */
2611 if (!pGetSystemWindowsDirectoryA)
2612 length = GetWindowsDirectoryA(buff, MAX_PATH);
2614 length = pGetSystemWindowsDirectoryA(buff, MAX_PATH);
2616 if (length + sizeof(file) < MAX_PATH)
2618 p = buff + strlen(buff);
2619 if (p > buff && p[-1] != '\\') *p++ = '\\';
2621 memset(&ofs, 0xA5, sizeof(ofs));
2622 SetLastError(0xfaceabee);
2624 hFile = OpenFile(buff, &ofs, OF_EXIST);
2625 ok( hFile == TRUE, "%s not found : %d\n", buff, GetLastError() );
2626 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
2627 "GetLastError() returns %d\n", GetLastError() );
2628 ok( ofs.cBytes == sizeof(ofs), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2629 ok( ofs.nErrCode == ERROR_SUCCESS, "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2630 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2631 "OpenFile returned '%s', but was expected to return '%s' or string filled with 0xA5\n",
2632 ofs.szPathName, buff );
2635 memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
2636 length = GetCurrentDirectoryA(MAX_PATH, buff);
2638 /* Check for nonexistent file */
2639 if (length + sizeof(foo) < MAX_PATH)
2641 p = buff + strlen(buff);
2642 if (p > buff && p[-1] != '\\') *p++ = '\\';
2643 strcpy( p, foo + 2 );
2644 memset(&ofs, 0xA5, sizeof(ofs));
2645 SetLastError(0xfaceabee);
2647 hFile = OpenFile(foo, &ofs, OF_EXIST);
2648 ok( hFile == HFILE_ERROR, "hFile != HFILE_ERROR : %d\n", GetLastError());
2649 ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError() returns %d\n", GetLastError() );
2651 ok( ofs.cBytes == 0xA5, "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2652 ok( ofs.nErrCode == ERROR_FILE_NOT_FOUND, "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2653 ok( lstrcmpiA(ofs.szPathName, buff) == 0 || strncmp(ofs.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0,
2654 "OpenFile returned '%s', but was expected to return '%s' or string filled with 0xA5\n",
2655 ofs.szPathName, buff );
2658 length = GetCurrentDirectoryA(MAX_PATH, buff_long);
2659 length += lstrlenA(foo_too_long + 1);
2661 /* Check for nonexistent file with too long filename */
2662 if (length >= OFS_MAXPATHNAME && length < sizeof(buff_long))
2664 lstrcatA(buff_long, foo_too_long + 1); /* Avoid '.' during concatenation */
2665 memset(&ofs, 0xA5, sizeof(ofs));
2666 SetLastError(0xfaceabee);
2668 hFile = OpenFile(foo_too_long, &ofs, OF_EXIST);
2669 ok( hFile == HFILE_ERROR, "hFile != HFILE_ERROR : %d\n", GetLastError());
2670 ok( GetLastError() == ERROR_INVALID_DATA || GetLastError() == ERROR_FILENAME_EXCED_RANGE,
2671 "GetLastError() returns %d\n", GetLastError() );
2673 ok( ofs.cBytes == 0xA5, "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2674 ok( ofs.nErrCode == ERROR_INVALID_DATA || ofs.nErrCode == ERROR_FILENAME_EXCED_RANGE,
2675 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2676 ok( strncmp(ofs.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0,
2677 "OpenFile returned '%s', but was expected to return string filled with 0xA5\n",
2681 length = GetCurrentDirectoryA(MAX_PATH, buff) + sizeof(filename);
2683 if (length >= MAX_PATH)
2685 trace("Buffer too small, requested length = %d, but MAX_PATH = %d. Skipping test.\n", length, MAX_PATH);
2688 p = buff + strlen(buff);
2689 if (p > buff && p[-1] != '\\') *p++ = '\\';
2690 strcpy( p, filename );
2692 memset(&ofs, 0xA5, sizeof(ofs));
2693 SetLastError(0xfaceabee);
2694 /* Create an empty file */
2695 hFile = OpenFile(filename, &ofs, OF_CREATE);
2696 ok( hFile != HFILE_ERROR, "OpenFile failed to create nonexistent file\n" );
2697 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
2698 "GetLastError() returns %d\n", GetLastError() );
2699 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2700 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
2701 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2702 ret = _lclose(hFile);
2703 ok( !ret, "_lclose() returns %d\n", ret );
2704 retval = GetFileAttributesA(filename);
2705 ok( retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %d\n", GetLastError() );
2707 memset(&ofs, 0xA5, sizeof(ofs));
2708 SetLastError(0xfaceabee);
2709 /* Check various opening options: */
2710 /* for reading only, */
2711 hFile = OpenFile(filename, &ofs, OF_READ);
2712 ok( hFile != HFILE_ERROR, "OpenFile failed on read\n" );
2713 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
2714 "GetLastError() returns %d\n", GetLastError() );
2715 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2716 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
2717 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2718 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2719 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
2720 ret = _lclose(hFile);
2721 ok( !ret, "_lclose() returns %d\n", ret );
2723 memset(&ofs, 0xA5, sizeof(ofs));
2724 SetLastError(0xfaceabee);
2725 /* for writing only, */
2726 hFile = OpenFile(filename, &ofs, OF_WRITE);
2727 ok( hFile != HFILE_ERROR, "OpenFile failed on write\n" );
2728 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
2729 "GetLastError() returns %d\n", GetLastError() );
2730 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2731 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
2732 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2733 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2734 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
2735 ret = _lclose(hFile);
2736 ok( !ret, "_lclose() returns %d\n", ret );
2738 memset(&ofs, 0xA5, sizeof(ofs));
2739 SetLastError(0xfaceabee);
2740 /* for reading and writing, */
2741 hFile = OpenFile(filename, &ofs, OF_READWRITE);
2742 ok( hFile != HFILE_ERROR, "OpenFile failed on read/write\n" );
2743 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
2744 "GetLastError() returns %d\n", GetLastError() );
2745 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2746 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
2747 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2748 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2749 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
2750 ret = _lclose(hFile);
2751 ok( !ret, "_lclose() returns %d\n", ret );
2753 memset(&ofs, 0xA5, sizeof(ofs));
2754 SetLastError(0xfaceabee);
2755 /* for checking file presence. */
2756 hFile = OpenFile(filename, &ofs, OF_EXIST);
2757 ok( hFile == 1, "OpenFile failed on finding our created file\n" );
2758 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
2759 "GetLastError() returns %d\n", GetLastError() );
2760 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2761 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
2762 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2763 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2764 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
2766 memset(&ofs, 0xA5, sizeof(ofs));
2767 SetLastError(0xfaceabee);
2768 /* Delete the file and make sure it doesn't exist anymore */
2769 hFile = OpenFile(filename, &ofs, OF_DELETE);
2770 ok( hFile == 1, "OpenFile failed on delete (%d)\n", hFile );
2771 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
2772 "GetLastError() returns %d\n", GetLastError() );
2773 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2774 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
2775 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2776 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2777 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
2779 retval = GetFileAttributesA(filename);
2780 ok( retval == INVALID_FILE_ATTRIBUTES, "GetFileAttributesA succeeded on deleted file\n" );
2783 static void test_overlapped(void)
2788 /* GetOverlappedResult crashes if the 2nd or 3rd param are NULL */
2789 if (0) /* tested: WinXP */
2791 GetOverlappedResult(0, NULL, &result, FALSE);
2792 GetOverlappedResult(0, &ov, NULL, FALSE);
2793 GetOverlappedResult(0, NULL, NULL, FALSE);
2796 memset( &ov, 0, sizeof ov );
2798 r = GetOverlappedResult(0, &ov, &result, 0);
2800 ok( result == 0, "wrong result %u\n", result );
2802 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
2806 ov.InternalHigh = 0xabcd;
2807 r = GetOverlappedResult(0, &ov, &result, 0);
2809 ok( result == 0xabcd, "wrong result %u\n", result );
2811 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
2813 SetLastError( 0xb00 );
2815 ov.Internal = STATUS_INVALID_HANDLE;
2816 ov.InternalHigh = 0xabcd;
2817 r = GetOverlappedResult(0, &ov, &result, 0);
2818 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
2819 ok( r == FALSE, "should return false\n");
2820 ok( result == 0xabcd || result == 0 /* win9x */, "wrong result %u\n", result );
2822 SetLastError( 0xb00 );
2824 ov.Internal = STATUS_PENDING;
2825 ov.InternalHigh = 0xabcd;
2826 r = GetOverlappedResult(0, &ov, &result, 0);
2827 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
2828 "wrong error %u\n", GetLastError() );
2829 ok( r == FALSE, "should return false\n");
2830 ok( result == 0, "wrong result %u\n", result );
2832 SetLastError( 0xb00 );
2833 ov.hEvent = CreateEvent( NULL, 1, 1, NULL );
2834 ov.Internal = STATUS_PENDING;
2835 ov.InternalHigh = 0xabcd;
2836 r = GetOverlappedResult(0, &ov, &result, 0);
2837 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
2838 "wrong error %u\n", GetLastError() );
2839 ok( r == FALSE, "should return false\n");
2841 ResetEvent( ov.hEvent );
2843 SetLastError( 0xb00 );
2844 ov.Internal = STATUS_PENDING;
2845 ov.InternalHigh = 0;
2846 r = GetOverlappedResult(0, &ov, &result, 0);
2847 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
2848 "wrong error %u\n", GetLastError() );
2849 ok( r == FALSE, "should return false\n");
2851 r = CloseHandle( ov.hEvent );
2852 ok( r == TRUE, "close handle failed\n");
2855 static void test_RemoveDirectory(void)
2858 char directory[] = "removeme";
2860 rc = CreateDirectory(directory, NULL);
2861 ok( rc, "Createdirectory failed, gle=%d\n", GetLastError() );
2863 rc = SetCurrentDirectory(directory);
2864 ok( rc, "SetCurrentDirectory failed, gle=%d\n", GetLastError() );
2866 rc = RemoveDirectory(".");
2869 rc = SetCurrentDirectory("..");
2870 ok( rc, "SetCurrentDirectory failed, gle=%d\n", GetLastError() );
2872 rc = RemoveDirectory(directory);
2873 ok( rc, "RemoveDirectory failed, gle=%d\n", GetLastError() );
2877 static BOOL check_file_time( const FILETIME *ft1, const FILETIME *ft2, UINT tolerance )
2879 ULONGLONG t1 = ((ULONGLONG)ft1->dwHighDateTime << 32) | ft1->dwLowDateTime;
2880 ULONGLONG t2 = ((ULONGLONG)ft2->dwHighDateTime << 32) | ft2->dwLowDateTime;
2881 return abs(t1 - t2) <= tolerance;
2884 static void test_ReplaceFileA(void)
2886 char replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH];
2887 HANDLE hReplacedFile, hReplacementFile, hBackupFile;
2888 static const char replacedData[] = "file-to-replace";
2889 static const char replacementData[] = "new-file";
2890 static const char backupData[] = "backup-file";
2891 FILETIME ftReplaced, ftReplacement, ftBackup;
2892 static const char prefix[] = "pfx";
2893 char temp_path[MAX_PATH];
2895 BOOL retok, removeBackup = FALSE;
2899 win_skip("ReplaceFileA() is missing\n");
2903 ret = GetTempPathA(MAX_PATH, temp_path);
2904 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
2905 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
2907 ret = GetTempFileNameA(temp_path, prefix, 0, replaced);
2908 ok(ret != 0, "GetTempFileNameA error (replaced) %d\n", GetLastError());
2910 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
2911 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
2913 ret = GetTempFileNameA(temp_path, prefix, 0, backup);
2914 ok(ret != 0, "GetTempFileNameA error (backup) %d\n", GetLastError());
2916 /* place predictable data in the file to be replaced */
2917 hReplacedFile = CreateFileA(replaced, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2918 ok(hReplacedFile != INVALID_HANDLE_VALUE,
2919 "failed to open replaced file\n");
2920 retok = WriteFile(hReplacedFile, replacedData, sizeof(replacedData), &ret, NULL );
2921 ok( retok && ret == sizeof(replacedData),
2922 "WriteFile error (replaced) %d\n", GetLastError());
2923 ok(GetFileSize(hReplacedFile, NULL) == sizeof(replacedData),
2924 "replaced file has wrong size\n");
2925 /* place predictable data in the file to be the replacement */
2926 hReplacementFile = CreateFileA(replacement, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2927 ok(hReplacementFile != INVALID_HANDLE_VALUE,
2928 "failed to open replacement file\n");
2929 retok = WriteFile(hReplacementFile, replacementData, sizeof(replacementData), &ret, NULL );
2930 ok( retok && ret == sizeof(replacementData),
2931 "WriteFile error (replacement) %d\n", GetLastError());
2932 ok(GetFileSize(hReplacementFile, NULL) == sizeof(replacementData),
2933 "replacement file has wrong size\n");
2934 /* place predictable data in the backup file (to be over-written) */
2935 hBackupFile = CreateFileA(backup, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2936 ok(hBackupFile != INVALID_HANDLE_VALUE,
2937 "failed to open backup file\n");
2938 retok = WriteFile(hBackupFile, backupData, sizeof(backupData), &ret, NULL );
2939 ok( retok && ret == sizeof(backupData),
2940 "WriteFile error (replacement) %d\n", GetLastError());
2941 ok(GetFileSize(hBackupFile, NULL) == sizeof(backupData),
2942 "backup file has wrong size\n");
2943 /* change the filetime on the "replaced" file to ensure that it changes */
2944 ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
2945 ok( ret, "GetFileTime error (replaced) %d\n", GetLastError());
2946 ftReplaced.dwLowDateTime -= 600000000; /* 60 second */
2947 ret = SetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
2948 ok( ret, "SetFileTime error (replaced) %d\n", GetLastError());
2949 GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced); /* get the actual time back */
2950 CloseHandle(hReplacedFile);
2951 /* change the filetime on the backup to ensure that it changes */
2952 ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
2953 ok( ret, "GetFileTime error (backup) %d\n", GetLastError());
2954 ftBackup.dwLowDateTime -= 1200000000; /* 120 second */
2955 ret = SetFileTime(hBackupFile, NULL, NULL, &ftBackup);
2956 ok( ret, "SetFileTime error (backup) %d\n", GetLastError());
2957 GetFileTime(hBackupFile, NULL, NULL, &ftBackup); /* get the actual time back */
2958 CloseHandle(hBackupFile);
2959 /* get the filetime on the replacement file to perform checks */
2960 ret = GetFileTime(hReplacementFile, NULL, NULL, &ftReplacement);
2961 ok( ret, "GetFileTime error (replacement) %d\n", GetLastError());
2962 CloseHandle(hReplacementFile);
2964 /* perform replacement w/ backup
2965 * TODO: flags are not implemented
2967 SetLastError(0xdeadbeef);
2968 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
2969 ok(ret, "ReplaceFileA: unexpected error %d\n", GetLastError());
2970 /* make sure that the backup has the size of the old "replaced" file */
2971 hBackupFile = CreateFileA(backup, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
2972 ok(hBackupFile != INVALID_HANDLE_VALUE,
2973 "failed to open backup file\n");
2974 ret = GetFileSize(hBackupFile, NULL);
2975 ok(ret == sizeof(replacedData),
2976 "backup file has wrong size %d\n", ret);
2977 /* make sure that the "replaced" file has the size of the replacement file */
2978 hReplacedFile = CreateFileA(replaced, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
2979 ok(hReplacedFile != INVALID_HANDLE_VALUE,
2980 "failed to open replaced file: %d\n", GetLastError());
2981 if (hReplacedFile != INVALID_HANDLE_VALUE)
2983 ret = GetFileSize(hReplacedFile, NULL);
2984 ok(ret == sizeof(replacementData),
2985 "replaced file has wrong size %d\n", ret);
2986 /* make sure that the replacement file no-longer exists */
2987 hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
2988 ok(hReplacementFile == INVALID_HANDLE_VALUE,
2989 "unexpected error, replacement file should not exist %d\n", GetLastError());
2990 /* make sure that the backup has the old "replaced" filetime */
2991 ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
2992 ok( ret, "GetFileTime error (backup %d\n", GetLastError());
2993 ok(check_file_time(&ftBackup, &ftReplaced, 20000000), "backup file has wrong filetime\n");
2994 CloseHandle(hBackupFile);
2995 /* make sure that the "replaced" has the old replacement filetime */
2996 ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
2997 ok( ret, "GetFileTime error (backup %d\n", GetLastError());
2998 ok(check_file_time(&ftReplaced, &ftReplacement, 20000000),
2999 "replaced file has wrong filetime %x%08x / %x%08x\n",
3000 ftReplaced.dwHighDateTime, ftReplaced.dwLowDateTime,
3001 ftReplacement.dwHighDateTime, ftReplacement.dwLowDateTime );
3002 CloseHandle(hReplacedFile);
3005 skip("couldn't open replacement file, skipping tests\n");
3007 /* re-create replacement file for pass w/o backup (blank) */
3008 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3009 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
3010 /* perform replacement w/o backup
3011 * TODO: flags are not implemented
3013 SetLastError(0xdeadbeef);
3014 ret = pReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
3015 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3016 "ReplaceFileA: unexpected error %d\n", GetLastError());
3018 /* re-create replacement file for pass w/ backup (backup-file not existing) */
3019 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3020 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
3021 ret = DeleteFileA(backup);
3022 ok(ret, "DeleteFileA: error (backup) %d\n", GetLastError());
3023 /* perform replacement w/ backup (no pre-existing backup)
3024 * TODO: flags are not implemented
3026 SetLastError(0xdeadbeef);
3027 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3028 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3029 "ReplaceFileA: unexpected error %d\n", GetLastError());
3031 removeBackup = TRUE;
3033 /* re-create replacement file for pass w/ no permissions to "replaced" */
3034 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3035 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
3036 ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_READONLY);
3037 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3038 "SetFileAttributesA: error setting to read only %d\n", GetLastError());
3039 /* perform replacement w/ backup (no permission to "replaced")
3040 * TODO: flags are not implemented
3042 SetLastError(0xdeadbeef);
3043 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3044 ok(ret != ERROR_UNABLE_TO_REMOVE_REPLACED, "ReplaceFileA: unexpected error %d\n", GetLastError());
3045 /* make sure that the replacement file still exists */
3046 hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
3047 ok(hReplacementFile != INVALID_HANDLE_VALUE ||
3048 broken(GetLastError() == ERROR_FILE_NOT_FOUND), /* win2k */
3049 "unexpected error, replacement file should still exist %d\n", GetLastError());
3050 CloseHandle(hReplacementFile);
3051 ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_NORMAL);
3052 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3053 "SetFileAttributesA: error setting to normal %d\n", GetLastError());
3055 /* replacement file still exists, make pass w/o "replaced" */
3056 ret = DeleteFileA(replaced);
3057 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3058 "DeleteFileA: error (replaced) %d\n", GetLastError());
3059 /* perform replacement w/ backup (no pre-existing backup or "replaced")
3060 * TODO: flags are not implemented
3062 SetLastError(0xdeadbeef);
3063 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3064 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
3065 GetLastError() == ERROR_ACCESS_DENIED),
3066 "ReplaceFileA: unexpected error %d\n", GetLastError());
3068 /* perform replacement w/o existing "replacement" file
3069 * TODO: flags are not implemented
3071 SetLastError(0xdeadbeef);
3072 ret = pReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
3073 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
3074 GetLastError() == ERROR_ACCESS_DENIED),
3075 "ReplaceFileA: unexpected error %d\n", GetLastError());
3076 DeleteFileA( replacement );
3079 * if the first round (w/ backup) worked then as long as there is no
3080 * failure then there is no need to check this round (w/ backup is the
3081 * more complete case)
3084 /* delete temporary files, replacement and replaced are already deleted */
3087 ret = DeleteFileA(backup);
3089 broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */
3090 "DeleteFileA: error (backup) %d\n", GetLastError());
3095 * ReplaceFileW is a simpler case of ReplaceFileA, there is no
3096 * need to be as thorough.
3098 static void test_ReplaceFileW(void)
3100 WCHAR replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH];
3101 static const WCHAR prefix[] = {'p','f','x',0};
3102 WCHAR temp_path[MAX_PATH];
3104 BOOL removeBackup = FALSE;
3108 win_skip("ReplaceFileW() is missing\n");
3112 ret = GetTempPathW(MAX_PATH, temp_path);
3113 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
3115 win_skip("GetTempPathW is not available\n");
3118 ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
3119 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
3121 ret = GetTempFileNameW(temp_path, prefix, 0, replaced);
3122 ok(ret != 0, "GetTempFileNameW error (replaced) %d\n", GetLastError());
3124 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3125 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3127 ret = GetTempFileNameW(temp_path, prefix, 0, backup);
3128 ok(ret != 0, "GetTempFileNameW error (backup) %d\n", GetLastError());
3130 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3131 ok(ret, "ReplaceFileW: error %d\n", GetLastError());
3133 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3134 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3135 ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0);
3136 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3137 "ReplaceFileW: error %d\n", GetLastError());
3139 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3140 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3141 ret = DeleteFileW(backup);
3142 ok(ret, "DeleteFileW: error (backup) %d\n", GetLastError());
3143 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3144 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3145 "ReplaceFileW: error %d\n", GetLastError());
3147 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3148 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3149 ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_READONLY);
3150 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3151 "SetFileAttributesW: error setting to read only %d\n", GetLastError());
3153 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3154 ok(ret != ERROR_UNABLE_TO_REMOVE_REPLACED,
3155 "ReplaceFileW: unexpected error %d\n", GetLastError());
3156 ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_NORMAL);
3157 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3158 "SetFileAttributesW: error setting to normal %d\n", GetLastError());
3160 removeBackup = TRUE;
3162 ret = DeleteFileW(replaced);
3163 ok(ret, "DeleteFileW: error (replaced) %d\n", GetLastError());
3164 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3165 ok(!ret, "ReplaceFileW: error %d\n", GetLastError());
3167 ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0);
3168 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
3169 GetLastError() == ERROR_ACCESS_DENIED),
3170 "ReplaceFileW: unexpected error %d\n", GetLastError());
3171 DeleteFileW( replacement );
3175 ret = DeleteFileW(backup);
3177 broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */
3178 "DeleteFileW: error (backup) %d\n", GetLastError());
3182 static void test_CreatFile(void)
3184 static const struct test_data
3186 DWORD disposition, access, error, clean_up;
3189 /* 0 */ { 0, 0, ERROR_INVALID_PARAMETER, 0 },
3190 /* 1 */ { 0, GENERIC_READ, ERROR_INVALID_PARAMETER, 0 },
3191 /* 2 */ { 0, GENERIC_READ|GENERIC_WRITE, ERROR_INVALID_PARAMETER, 0 },
3192 /* 3 */ { CREATE_NEW, 0, ERROR_FILE_EXISTS, 1 },
3193 /* 4 */ { CREATE_NEW, 0, 0, 1 },
3194 /* 5 */ { CREATE_NEW, GENERIC_READ, 0, 1 },
3195 /* 6 */ { CREATE_NEW, GENERIC_WRITE, 0, 1 },
3196 /* 7 */ { CREATE_NEW, GENERIC_READ|GENERIC_WRITE, 0, 0 },
3197 /* 8 */ { CREATE_ALWAYS, 0, 0, 0 },
3198 /* 9 */ { CREATE_ALWAYS, GENERIC_READ, 0, 0 },
3199 /* 10*/ { CREATE_ALWAYS, GENERIC_WRITE, 0, 0 },
3200 /* 11*/ { CREATE_ALWAYS, GENERIC_READ|GENERIC_WRITE, 0, 1 },
3201 /* 12*/ { OPEN_EXISTING, 0, ERROR_FILE_NOT_FOUND, 0 },
3202 /* 13*/ { CREATE_ALWAYS, 0, 0, 0 },
3203 /* 14*/ { OPEN_EXISTING, 0, 0, 0 },
3204 /* 15*/ { OPEN_EXISTING, GENERIC_READ, 0, 0 },
3205 /* 16*/ { OPEN_EXISTING, GENERIC_WRITE, 0, 0 },
3206 /* 17*/ { OPEN_EXISTING, GENERIC_READ|GENERIC_WRITE, 0, 1 },
3207 /* 18*/ { OPEN_ALWAYS, 0, 0, 0 },
3208 /* 19*/ { OPEN_ALWAYS, GENERIC_READ, 0, 0 },
3209 /* 20*/ { OPEN_ALWAYS, GENERIC_WRITE, 0, 0 },
3210 /* 21*/ { OPEN_ALWAYS, GENERIC_READ|GENERIC_WRITE, 0, 0 },
3211 /* 22*/ { TRUNCATE_EXISTING, 0, ERROR_INVALID_PARAMETER, 0 },
3212 /* 23*/ { TRUNCATE_EXISTING, GENERIC_READ, ERROR_INVALID_PARAMETER, 0 },
3213 /* 24*/ { TRUNCATE_EXISTING, GENERIC_WRITE, 0, 0 },
3214 /* 25*/ { TRUNCATE_EXISTING, GENERIC_READ|GENERIC_WRITE, 0, 0 }
3216 char temp_path[MAX_PATH];
3217 char file_name[MAX_PATH];
3218 DWORD i, ret, written;
3221 GetTempPath(MAX_PATH, temp_path);
3222 GetTempFileName(temp_path, "tmp", 0, file_name);
3224 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
3226 SetLastError(0xdeadbeef);
3227 hfile = CreateFile(file_name, td[i].access, 0, NULL, td[i].disposition, 0, 0);
3230 ok(hfile != INVALID_HANDLE_VALUE, "%d: CreateFile error %d\n", i, GetLastError());
3231 written = 0xdeadbeef;
3232 SetLastError(0xdeadbeef);
3233 ret = WriteFile(hfile, &td[i].error, sizeof(td[i].error), &written, NULL);
3234 if (td[i].access & GENERIC_WRITE)
3235 ok(ret, "%d: WriteFile error %d\n", i, GetLastError());
3238 ok(!ret, "%d: WriteFile should fail\n", i);
3239 ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
3245 /* FIXME: remove the condition below once Wine is fixed */
3246 if (td[i].disposition == TRUNCATE_EXISTING && !(td[i].access & GENERIC_WRITE))
3250 ok(hfile == INVALID_HANDLE_VALUE, "%d: CreateFile should fail\n", i);
3251 ok(GetLastError() == td[i].error, "%d: expected %d, got %d\n", i, td[i].error, GetLastError());
3257 ok(hfile == INVALID_HANDLE_VALUE, "%d: CreateFile should fail\n", i);
3258 ok(GetLastError() == td[i].error, "%d: expected %d, got %d\n", i, td[i].error, GetLastError());
3262 if (td[i].clean_up) DeleteFile(file_name);
3265 DeleteFile(file_name);
3268 static void test_GetFileInformationByHandleEx(void)
3271 char tempPath[MAX_PATH], tempFileName[MAX_PATH], buffer[1024];
3275 FILE_ID_BOTH_DIR_INFO *bothDirInfo;
3277 FILE_INFO_BY_HANDLE_CLASS handleClass;
3282 {0xdeadbeef, NULL, 0, ERROR_INVALID_PARAMETER},
3283 {FileIdBothDirectoryInfo, NULL, 0, ERROR_BAD_LENGTH},
3284 {FileIdBothDirectoryInfo, NULL, sizeof(buffer), ERROR_NOACCESS},
3285 {FileIdBothDirectoryInfo, buffer, 0, ERROR_BAD_LENGTH}};
3287 if (!pGetFileInformationByHandleEx)
3289 win_skip("GetFileInformationByHandleEx is missing.\n");
3293 ret2 = GetTempPathA(sizeof(tempPath), tempPath);
3294 ok(ret2, "GetFileInformationByHandleEx: GetTempPathA failed, got error %u.\n", GetLastError());
3296 /* ensure the existence of a file in the temp folder */
3297 ret2 = GetTempFileNameA(tempPath, "abc", 0, tempFileName);
3298 ok(ret2, "GetFileInformationByHandleEx: GetTempFileNameA failed, got error %u.\n", GetLastError());
3299 ret2 = GetFileAttributesA(tempFileName);
3300 ok(ret2 != INVALID_FILE_ATTRIBUTES, "GetFileInformationByHandleEx: "
3301 "GetFileAttributesA failed to find the temp file, got error %u.\n", GetLastError());
3303 directory = CreateFileA(tempPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
3304 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
3305 ok(directory != INVALID_HANDLE_VALUE, "GetFileInformationByHandleEx: failed to open the temp folder, "
3306 "got error %u.\n", GetLastError());
3308 for (i = 0; i < sizeof(checks) / sizeof(checks[0]); i += 1)
3310 SetLastError(0xdeadbeef);
3311 ret = pGetFileInformationByHandleEx(directory, checks[i].handleClass, checks[i].ptr, checks[i].size);
3312 ok(!ret && GetLastError() == checks[i].errorCode, "GetFileInformationByHandleEx: expected error %u, "
3313 "got %u.\n", checks[i].errorCode, GetLastError());
3318 memset(buffer, 0xff, sizeof(buffer));
3319 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer));
3320 if (!ret && GetLastError() == ERROR_NO_MORE_FILES)
3322 ok(ret, "GetFileInformationByHandleEx: failed to query for FileIdBothDirectoryInfo, got error %u.\n", GetLastError());
3325 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
3328 ok(bothDirInfo->FileAttributes != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file attributes.\n");
3329 ok(bothDirInfo->FileId.u.LowPart != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file id.\n");
3330 ok(bothDirInfo->FileNameLength != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file name length.\n");
3331 if (!bothDirInfo->NextEntryOffset)
3333 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)(((char *)bothDirInfo) + bothDirInfo->NextEntryOffset);
3337 CloseHandle(directory);
3338 DeleteFile(tempFileName);
3341 static void test_OpenFileById(void)
3343 char tempPath[MAX_PATH], tempFileName[MAX_PATH], buffer[256], tickCount[256];
3344 WCHAR tempFileNameW[MAX_PATH];
3346 DWORD ret2, count, tempFileNameLen;
3347 HANDLE directory, handle, tempFile;
3348 FILE_ID_BOTH_DIR_INFO *bothDirInfo;
3349 FILE_ID_DESCRIPTOR fileIdDescr;
3351 if (!pGetFileInformationByHandleEx || !pOpenFileById)
3353 win_skip("GetFileInformationByHandleEx or OpenFileById is missing.\n");
3357 ret2 = GetTempPathA(sizeof(tempPath), tempPath);
3358 ok(ret2, "OpenFileById: GetTempPath failed, got error %u.\n", GetLastError());
3360 /* ensure the existence of a file in the temp folder */
3361 ret2 = GetTempFileNameA(tempPath, "abc", 0, tempFileName);
3362 ok(ret2, "OpenFileById: GetTempFileNameA failed, got error %u.\n", GetLastError());
3363 ret2 = GetFileAttributesA(tempFileName);
3364 ok(ret2 != INVALID_FILE_ATTRIBUTES,
3365 "OpenFileById: GetFileAttributesA failed to find the temp file, got error %u\n", GetLastError());
3367 ret2 = MultiByteToWideChar(CP_ACP, 0, tempFileName + strlen(tempPath), -1, tempFileNameW, sizeof(tempFileNameW)/sizeof(tempFileNameW[0]));
3368 ok(ret2, "OpenFileById: MultiByteToWideChar failed to convert tempFileName, got error %u.\n", GetLastError());
3369 tempFileNameLen = ret2 - 1;
3371 tempFile = CreateFileA(tempFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
3372 ok(tempFile != INVALID_HANDLE_VALUE, "OpenFileById: failed to create a temp file, "
3373 "got error %u.\n", GetLastError());
3374 ret2 = sprintf(tickCount, "%u", GetTickCount());
3375 ret = WriteFile(tempFile, tickCount, ret2, &count, NULL);
3376 ok(ret, "OpenFileById: WriteFile failed, got error %u.\n", GetLastError());
3377 CloseHandle(tempFile);
3379 directory = CreateFileA(tempPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
3380 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
3381 ok(directory != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the temp folder, "
3382 "got error %u.\n", GetLastError());
3384 /* get info about the temp folder itself */
3385 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
3386 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer));
3387 ok(ret, "OpenFileById: failed to query for FileIdBothDirectoryInfo, got error %u.\n", GetLastError());
3388 ok(bothDirInfo->FileNameLength == sizeof(WCHAR) && bothDirInfo->FileName[0] == '.',
3389 "OpenFileById: failed to return the temp folder at the first entry, got error %u.\n", GetLastError());
3391 /* open the temp folder itself */
3392 fileIdDescr.dwSize = sizeof(fileIdDescr);
3393 fileIdDescr.Type = FileIdType;
3394 U(fileIdDescr).FileId = bothDirInfo->FileId;
3395 handle = pOpenFileById(directory, &fileIdDescr, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0);
3397 ok(handle != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the temp folder itself, got error %u.\n", GetLastError());
3398 CloseHandle(handle);
3400 /* find the temp file in the temp folder */
3404 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer));
3405 ok(ret, "OpenFileById: failed to query for FileIdBothDirectoryInfo, got error %u.\n", GetLastError());
3408 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
3411 if (tempFileNameLen == bothDirInfo->FileNameLength / sizeof(WCHAR) &&
3412 memcmp(tempFileNameW, bothDirInfo->FileName, bothDirInfo->FileNameLength) == 0)
3417 if (!bothDirInfo->NextEntryOffset)
3419 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)(((char *)bothDirInfo) + bothDirInfo->NextEntryOffset);
3422 ok(found, "OpenFileById: failed to find the temp file in the temp folder.\n");
3424 SetLastError(0xdeadbeef);
3425 handle = pOpenFileById(directory, NULL, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0);
3426 ok(handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER,
3427 "OpenFileById: expected ERROR_INVALID_PARAMETER, got error %u.\n", GetLastError());
3429 fileIdDescr.dwSize = sizeof(fileIdDescr);
3430 fileIdDescr.Type = FileIdType;
3431 U(fileIdDescr).FileId = bothDirInfo->FileId;
3432 handle = pOpenFileById(directory, &fileIdDescr, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0);
3433 ok(handle != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the file, got error %u.\n", GetLastError());
3435 ret = ReadFile(handle, buffer, sizeof(buffer), &count, NULL);
3437 ok(ret, "OpenFileById: ReadFile failed, got error %u.\n", GetLastError());
3438 ok(strcmp(tickCount, buffer) == 0, "OpenFileById: invalid contents of the temp file.\n");
3440 CloseHandle(handle);
3441 CloseHandle(directory);
3442 DeleteFile(tempFileName);
3445 static void test_SetFileValidData(void)
3450 char path[MAX_PATH], filename[MAX_PATH];
3451 TOKEN_PRIVILEGES privs;
3452 HANDLE token = NULL;
3454 if (!pSetFileValidData)
3456 win_skip("SetFileValidData is missing\n");
3459 GetTempPathA(sizeof(path), path);
3460 GetTempFileNameA(path, "tst", 0, filename);
3461 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
3462 WriteFile(handle, "test", sizeof("test") - 1, &count, NULL);
3463 CloseHandle(handle);
3465 SetLastError(0xdeadbeef);
3466 ret = pSetFileValidData(INVALID_HANDLE_VALUE, 0);
3467 error = GetLastError();
3468 ok(!ret, "SetFileValidData succeeded\n");
3469 ok(error == ERROR_INVALID_HANDLE, "got %u\n", error);
3471 SetLastError(0xdeadbeef);
3472 ret = pSetFileValidData(INVALID_HANDLE_VALUE, -1);
3473 error = GetLastError();
3474 ok(!ret, "SetFileValidData succeeded\n");
3475 ok(error == ERROR_INVALID_HANDLE, "got %u\n", error);
3477 /* file opened for reading */
3478 handle = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
3480 SetLastError(0xdeadbeef);
3481 ret = pSetFileValidData(handle, 0);
3482 ok(!ret, "SetFileValidData succeeded\n");
3483 error = GetLastError();
3484 ok(error == ERROR_ACCESS_DENIED, "got %u\n", error);
3486 SetLastError(0xdeadbeef);
3487 ret = pSetFileValidData(handle, -1);
3488 error = GetLastError();
3489 ok(!ret, "SetFileValidData succeeded\n");
3490 ok(error == ERROR_ACCESS_DENIED, "got %u\n", error);
3491 CloseHandle(handle);
3493 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
3495 SetLastError(0xdeadbeef);
3496 ret = pSetFileValidData(handle, 0);
3497 error = GetLastError();
3498 ok(!ret, "SetFileValidData succeeded\n");
3499 todo_wine ok(error == ERROR_PRIVILEGE_NOT_HELD, "got %u\n", error);
3500 CloseHandle(handle);
3502 privs.PrivilegeCount = 1;
3503 privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
3505 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token) ||
3506 !LookupPrivilegeValue(NULL, SE_MANAGE_VOLUME_NAME, &privs.Privileges[0].Luid) ||
3507 !AdjustTokenPrivileges(token, FALSE, &privs, sizeof(privs), NULL, NULL))
3509 win_skip("cannot enable SE_MANAGE_VOLUME_NAME privilege\n");
3513 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
3515 SetLastError(0xdeadbeef);
3516 ret = pSetFileValidData(handle, 0);
3517 error = GetLastError();
3518 ok(!ret, "SetFileValidData succeeded\n");
3519 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3521 SetLastError(0xdeadbeef);
3522 ret = pSetFileValidData(handle, -1);
3523 error = GetLastError();
3524 ok(!ret, "SetFileValidData succeeded\n");
3525 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3527 SetLastError(0xdeadbeef);
3528 ret = pSetFileValidData(handle, 2);
3529 error = GetLastError();
3530 todo_wine ok(!ret, "SetFileValidData succeeded\n");
3531 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3533 ret = pSetFileValidData(handle, 4);
3534 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3536 SetLastError(0xdeadbeef);
3537 ret = pSetFileValidData(handle, 8);
3538 error = GetLastError();
3539 ok(!ret, "SetFileValidData succeeded\n");
3540 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3542 count = SetFilePointer(handle, 1024, NULL, FILE_END);
3543 ok(count != INVALID_SET_FILE_POINTER, "SetFilePointer failed %u\n", GetLastError());
3544 ret = SetEndOfFile(handle);
3545 ok(ret, "SetEndOfFile failed %u\n", GetLastError());
3547 SetLastError(0xdeadbeef);
3548 ret = pSetFileValidData(handle, 2);
3549 error = GetLastError();
3550 todo_wine ok(!ret, "SetFileValidData succeeded\n");
3551 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3553 ret = pSetFileValidData(handle, 4);
3554 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3556 ret = pSetFileValidData(handle, 8);
3557 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3559 ret = pSetFileValidData(handle, 4);
3560 error = GetLastError();
3561 todo_wine ok(!ret, "SetFileValidData succeeded\n");
3562 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3564 ret = pSetFileValidData(handle, 1024);
3565 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3567 ret = pSetFileValidData(handle, 2048);
3568 error = GetLastError();
3569 ok(!ret, "SetFileValidData succeeded\n");
3570 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3572 privs.Privileges[0].Attributes = 0;
3573 AdjustTokenPrivileges(token, FALSE, &privs, sizeof(privs), NULL, NULL);
3575 DeleteFile(filename);
3580 InitFunctionPointers();
3590 test_GetTempFileNameA();
3600 test_FindFirstFileA();
3601 test_FindNextFileA();
3602 test_FindFirstFileExA(0);
3603 /* FindExLimitToDirectories is ignored if the file system doesn't support directory filtering */
3604 test_FindFirstFileExA(FindExSearchLimitToDirectories);
3606 test_file_sharing();
3607 test_offset_in_overlapped_structure();
3610 test_async_file_errors();
3614 test_RemoveDirectory();
3615 test_ReplaceFileA();
3616 test_ReplaceFileW();
3617 test_GetFileInformationByHandleEx();
3618 test_OpenFileById();
3619 test_SetFileValidData();