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 __sparc__
1787 nt->FileHeader.Machine = IMAGE_FILE_MACHINE_SPARC;
1788 #elif defined __arm__
1789 nt->FileHeader.Machine = IMAGE_FILE_MACHINE_ARMNT;
1790 #elif defined __aarch64__
1791 nt->FileHeader.Machine = IMAGE_FILE_MACHINE_ARM64;
1793 # error You must specify the machine type
1795 nt->FileHeader.NumberOfSections = 1;
1796 nt->FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER);
1797 nt->FileHeader.Characteristics = IMAGE_FILE_DLL | IMAGE_FILE_EXECUTABLE_IMAGE;
1798 nt->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
1799 nt->OptionalHeader.MajorLinkerVersion = 1;
1800 nt->OptionalHeader.MinorLinkerVersion = 0;
1801 nt->OptionalHeader.ImageBase = 0x10000000;
1802 nt->OptionalHeader.SectionAlignment = 0x1000;
1803 nt->OptionalHeader.FileAlignment = 0x1000;
1804 nt->OptionalHeader.MajorOperatingSystemVersion = 1;
1805 nt->OptionalHeader.MinorOperatingSystemVersion = 0;
1806 nt->OptionalHeader.MajorImageVersion = 1;
1807 nt->OptionalHeader.MinorImageVersion = 0;
1808 nt->OptionalHeader.MajorSubsystemVersion = 4;
1809 nt->OptionalHeader.MinorSubsystemVersion = 0;
1810 nt->OptionalHeader.SizeOfImage = 0x2000;
1811 nt->OptionalHeader.SizeOfHeaders = size;
1812 nt->OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
1813 nt->OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
1815 sec = (IMAGE_SECTION_HEADER *)(nt + 1);
1816 memcpy( sec->Name, ".rodata", sizeof(".rodata") );
1817 sec->Misc.VirtualSize = 0x1000;
1818 sec->VirtualAddress = 0x1000;
1819 sec->SizeOfRawData = 0;
1820 sec->PointerToRawData = 0;
1821 sec->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
1823 ret = WriteFile( file, buffer, size, &written, NULL ) && written == size;
1824 HeapFree( GetProcessHeap(), 0, buffer );
1825 CloseHandle( file );
1829 static unsigned int map_file_access( unsigned int access )
1831 if (access & GENERIC_READ) access |= FILE_GENERIC_READ;
1832 if (access & GENERIC_WRITE) access |= FILE_GENERIC_WRITE;
1833 if (access & GENERIC_EXECUTE) access |= FILE_GENERIC_EXECUTE;
1834 if (access & GENERIC_ALL) access |= FILE_ALL_ACCESS;
1835 return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
1838 static int is_sharing_compatible( DWORD access1, DWORD sharing1, DWORD access2, DWORD sharing2 )
1840 access1 = map_file_access( access1 );
1841 access2 = map_file_access( access2 );
1842 access1 &= FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_EXECUTE | DELETE;
1843 access2 &= FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_EXECUTE | DELETE;
1845 if (!access1) sharing1 = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
1846 if (!access2) sharing2 = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
1848 if ((access1 & (FILE_READ_DATA|FILE_EXECUTE)) && !(sharing2 & FILE_SHARE_READ)) return 0;
1849 if ((access1 & (FILE_WRITE_DATA|FILE_APPEND_DATA)) && !(sharing2 & FILE_SHARE_WRITE)) return 0;
1850 if ((access1 & DELETE) && !(sharing2 & FILE_SHARE_DELETE)) return 0;
1851 if ((access2 & (FILE_READ_DATA|FILE_EXECUTE)) && !(sharing1 & FILE_SHARE_READ)) return 0;
1852 if ((access2 & (FILE_WRITE_DATA|FILE_APPEND_DATA)) && !(sharing1 & FILE_SHARE_WRITE)) return 0;
1853 if ((access2 & DELETE) && !(sharing1 & FILE_SHARE_DELETE)) return 0;
1857 static int is_sharing_map_compatible( DWORD map_access, DWORD access2, DWORD sharing2 )
1859 if ((map_access == PAGE_READWRITE || map_access == PAGE_EXECUTE_READWRITE) &&
1860 !(sharing2 & FILE_SHARE_WRITE)) return 0;
1861 access2 = map_file_access( access2 );
1862 if ((map_access & SEC_IMAGE) && (access2 & FILE_WRITE_DATA)) return 0;
1866 static void test_file_sharing(void)
1868 static const DWORD access_modes[] =
1869 { 0, GENERIC_READ, GENERIC_WRITE, GENERIC_READ|GENERIC_WRITE,
1870 DELETE, GENERIC_READ|DELETE, GENERIC_WRITE|DELETE, GENERIC_READ|GENERIC_WRITE|DELETE,
1871 GENERIC_EXECUTE, GENERIC_EXECUTE | DELETE,
1872 FILE_READ_DATA, FILE_WRITE_DATA, FILE_APPEND_DATA, FILE_READ_EA, FILE_WRITE_EA,
1873 FILE_READ_DATA | FILE_EXECUTE, FILE_WRITE_DATA | FILE_EXECUTE, FILE_APPEND_DATA | FILE_EXECUTE,
1874 FILE_READ_EA | FILE_EXECUTE, FILE_WRITE_EA | FILE_EXECUTE, FILE_EXECUTE,
1875 FILE_DELETE_CHILD, FILE_READ_ATTRIBUTES, FILE_WRITE_ATTRIBUTES };
1876 static const DWORD sharing_modes[] =
1877 { 0, FILE_SHARE_READ,
1878 FILE_SHARE_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
1879 FILE_SHARE_DELETE, FILE_SHARE_READ|FILE_SHARE_DELETE,
1880 FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE };
1881 static const DWORD mapping_modes[] =
1882 { PAGE_READONLY, PAGE_WRITECOPY, PAGE_READWRITE, SEC_IMAGE | PAGE_WRITECOPY };
1887 /* make sure the file exists */
1888 if (!create_fake_dll( filename ))
1890 ok(0, "couldn't create file \"%s\" (err=%d)\n", filename, GetLastError());
1894 for (a1 = 0; a1 < sizeof(access_modes)/sizeof(access_modes[0]); a1++)
1896 for (s1 = 0; s1 < sizeof(sharing_modes)/sizeof(sharing_modes[0]); s1++)
1898 SetLastError(0xdeadbeef);
1899 h = CreateFileA( filename, access_modes[a1], sharing_modes[s1],
1900 NULL, OPEN_EXISTING, 0, 0 );
1901 if (h == INVALID_HANDLE_VALUE)
1903 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
1906 for (a2 = 0; a2 < sizeof(access_modes)/sizeof(access_modes[0]); a2++)
1908 for (s2 = 0; s2 < sizeof(sharing_modes)/sizeof(sharing_modes[0]); s2++)
1910 SetLastError(0xdeadbeef);
1911 h2 = CreateFileA( filename, access_modes[a2], sharing_modes[s2],
1912 NULL, OPEN_EXISTING, 0, 0 );
1913 ret = GetLastError();
1914 if (is_sharing_compatible( access_modes[a1], sharing_modes[s1],
1915 access_modes[a2], sharing_modes[s2] ))
1917 ok( h2 != INVALID_HANDLE_VALUE,
1918 "open failed for modes %x/%x/%x/%x\n",
1919 access_modes[a1], sharing_modes[s1],
1920 access_modes[a2], sharing_modes[s2] );
1921 ok( ret == 0, "wrong error code %d\n", ret );
1925 ok( h2 == INVALID_HANDLE_VALUE,
1926 "open succeeded for modes %x/%x/%x/%x\n",
1927 access_modes[a1], sharing_modes[s1],
1928 access_modes[a2], sharing_modes[s2] );
1929 ok( ret == ERROR_SHARING_VIOLATION,
1930 "wrong error code %d\n", ret );
1932 if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 );
1939 for (a1 = 0; a1 < sizeof(mapping_modes)/sizeof(mapping_modes[0]); a1++)
1943 create_fake_dll( filename );
1944 SetLastError(0xdeadbeef);
1945 h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
1946 if (h == INVALID_HANDLE_VALUE)
1948 ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError());
1951 m = CreateFileMappingA( h, NULL, mapping_modes[a1], 0, 0, NULL );
1952 ok( m != 0, "failed to create mapping %x err %u\n", mapping_modes[a1], GetLastError() );
1956 for (a2 = 0; a2 < sizeof(access_modes)/sizeof(access_modes[0]); a2++)
1958 for (s2 = 0; s2 < sizeof(sharing_modes)/sizeof(sharing_modes[0]); s2++)
1960 SetLastError(0xdeadbeef);
1961 h2 = CreateFileA( filename, access_modes[a2], sharing_modes[s2],
1962 NULL, OPEN_EXISTING, 0, 0 );
1964 ret = GetLastError();
1965 if (h2 == INVALID_HANDLE_VALUE)
1967 ok( !is_sharing_map_compatible(mapping_modes[a1], access_modes[a2], sharing_modes[s2]),
1968 "open failed for modes map %x/%x/%x\n",
1969 mapping_modes[a1], access_modes[a2], sharing_modes[s2] );
1970 ok( ret == ERROR_SHARING_VIOLATION,
1971 "wrong error code %d\n", ret );
1975 if (!is_sharing_map_compatible(mapping_modes[a1], access_modes[a2], sharing_modes[s2]))
1976 ok( broken(1), /* no checking on nt4 */
1977 "open succeeded for modes map %x/%x/%x\n",
1978 mapping_modes[a1], access_modes[a2], sharing_modes[s2] );
1979 ok( ret == 0xdeadbeef /* Win9x */ ||
1981 "wrong error code %d\n", ret );
1987 /* try CREATE_ALWAYS over an existing mapping */
1988 SetLastError(0xdeadbeef);
1989 h2 = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
1990 NULL, CREATE_ALWAYS, 0, 0 );
1991 ret = GetLastError();
1992 if (mapping_modes[a1] & SEC_IMAGE)
1994 ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] );
1995 ok( ret == ERROR_SHARING_VIOLATION, "wrong error code %d for %x\n", ret, mapping_modes[a1] );
1999 ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] );
2000 ok( ret == ERROR_USER_MAPPED_FILE, "wrong error code %d for %x\n", ret, mapping_modes[a1] );
2002 if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 );
2004 /* try DELETE_ON_CLOSE over an existing mapping */
2005 SetLastError(0xdeadbeef);
2006 h2 = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
2007 NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0 );
2008 ret = GetLastError();
2009 if (mapping_modes[a1] & SEC_IMAGE)
2011 ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] );
2012 ok( ret == ERROR_ACCESS_DENIED, "wrong error code %d for %x\n", ret, mapping_modes[a1] );
2016 ok( h2 != INVALID_HANDLE_VALUE, "open failed for map %x err %u\n", mapping_modes[a1], ret );
2018 if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 );
2023 SetLastError(0xdeadbeef);
2024 h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, 0 );
2025 ok( h != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError() );
2027 SetLastError(0xdeadbeef);
2028 h2 = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
2029 ok( h2 == INVALID_HANDLE_VALUE, "CreateFileA should fail\n");
2030 ok( GetLastError() == ERROR_SHARING_VIOLATION, "wrong error code %d\n", GetLastError() );
2032 h2 = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
2033 ok( h2 != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError() );
2038 DeleteFileA( filename );
2041 static char get_windows_drive(void)
2043 char windowsdir[MAX_PATH];
2044 GetWindowsDirectory(windowsdir, sizeof(windowsdir));
2045 return windowsdir[0];
2048 static void test_FindFirstFileA(void)
2051 WIN32_FIND_DATAA data;
2053 char buffer[5] = "C:\\";
2055 char nonexistent[MAX_PATH];
2057 /* try FindFirstFileA on "C:\" */
2058 buffer[0] = get_windows_drive();
2060 SetLastError( 0xdeadbeaf );
2061 handle = FindFirstFileA(buffer, &data);
2062 err = GetLastError();
2063 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on root directory should fail\n" );
2064 ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err );
2066 /* try FindFirstFileA on "C:\*" */
2067 strcpy(buffer2, buffer);
2068 strcat(buffer2, "*");
2069 handle = FindFirstFileA(buffer2, &data);
2070 ok ( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s should succeed\n", buffer2 );
2071 ok ( strcmp( data.cFileName, "." ) && strcmp( data.cFileName, ".." ),
2072 "FindFirstFile shouldn't return '%s' in drive root\n", data.cFileName );
2073 if (FindNextFileA( handle, &data ))
2074 ok ( strcmp( data.cFileName, "." ) && strcmp( data.cFileName, ".." ),
2075 "FindNextFile shouldn't return '%s' in drive root\n", data.cFileName );
2076 ok ( FindClose(handle) == TRUE, "Failed to close handle %s\n", buffer2 );
2078 /* try FindFirstFileA on windows dir */
2079 GetWindowsDirectory( buffer2, sizeof(buffer2) );
2080 strcat(buffer2, "\\*");
2081 handle = FindFirstFileA(buffer2, &data);
2082 ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s should succeed\n", buffer2 );
2083 ok( !strcmp( data.cFileName, "." ), "FindFirstFile should return '.' first\n" );
2084 ok( FindNextFileA( handle, &data ), "FindNextFile failed\n" );
2085 ok( !strcmp( data.cFileName, ".." ), "FindNextFile should return '..' as second entry\n" );
2086 while (FindNextFileA( handle, &data ))
2087 ok ( strcmp( data.cFileName, "." ) && strcmp( data.cFileName, ".." ),
2088 "FindNextFile shouldn't return '%s'\n", data.cFileName );
2089 ok ( FindClose(handle) == TRUE, "Failed to close handle %s\n", buffer2 );
2091 /* try FindFirstFileA on "C:\foo\" */
2092 SetLastError( 0xdeadbeaf );
2093 if (!GetTempFileNameA( buffer, "foo", 0, nonexistent ) && GetLastError() == ERROR_ACCESS_DENIED)
2096 GetTempPathA( sizeof(tmp), tmp );
2097 GetTempFileNameA( tmp, "foo", 0, nonexistent );
2099 DeleteFileA( nonexistent );
2100 strcpy(buffer2, nonexistent);
2101 strcat(buffer2, "\\");
2102 handle = FindFirstFileA(buffer2, &data);
2103 err = GetLastError();
2104 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2106 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2109 /* try FindFirstFileA on "C:\foo\bar.txt" */
2110 SetLastError( 0xdeadbeaf );
2111 strcpy(buffer2, nonexistent);
2112 strcat(buffer2, "\\bar.txt");
2113 handle = FindFirstFileA(buffer2, &data);
2114 err = GetLastError();
2115 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2116 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2118 /* try FindFirstFileA on "C:\foo\*.*" */
2119 SetLastError( 0xdeadbeaf );
2120 strcpy(buffer2, nonexistent);
2121 strcat(buffer2, "\\*.*");
2122 handle = FindFirstFileA(buffer2, &data);
2123 err = GetLastError();
2124 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2125 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2127 /* try FindFirstFileA on "foo\bar.txt" */
2128 SetLastError( 0xdeadbeaf );
2129 strcpy(buffer2, nonexistent + 3);
2130 strcat(buffer2, "\\bar.txt");
2131 handle = FindFirstFileA(buffer2, &data);
2132 err = GetLastError();
2133 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2134 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2136 /* try FindFirstFileA on "c:\nul" */
2137 SetLastError( 0xdeadbeaf );
2138 strcpy(buffer2, buffer);
2139 strcat(buffer2, "nul");
2140 handle = FindFirstFileA(buffer2, &data);
2141 err = GetLastError();
2142 ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s failed: %d\n", buffer2, err );
2143 ok( 0 == lstrcmpiA(data.cFileName, "nul"), "wrong name %s\n", data.cFileName );
2144 ok( FILE_ATTRIBUTE_ARCHIVE == data.dwFileAttributes ||
2145 FILE_ATTRIBUTE_DEVICE == data.dwFileAttributes /* Win9x */,
2146 "wrong attributes %x\n", data.dwFileAttributes );
2147 if (data.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE)
2149 ok( 0 == data.nFileSizeHigh, "wrong size %d\n", data.nFileSizeHigh );
2150 ok( 0 == data.nFileSizeLow, "wrong size %d\n", data.nFileSizeLow );
2152 SetLastError( 0xdeadbeaf );
2153 ok( !FindNextFileA( handle, &data ), "FindNextFileA succeeded\n" );
2154 ok( GetLastError() == ERROR_NO_MORE_FILES, "bad error %d\n", GetLastError() );
2155 ok( FindClose( handle ), "failed to close handle\n" );
2157 /* try FindFirstFileA on "lpt1" */
2158 SetLastError( 0xdeadbeaf );
2159 strcpy(buffer2, "lpt1");
2160 handle = FindFirstFileA(buffer2, &data);
2161 err = GetLastError();
2162 ok( handle != INVALID_HANDLE_VALUE, "FindFirstFile on %s failed: %d\n", buffer2, err );
2163 ok( 0 == lstrcmpiA(data.cFileName, "lpt1"), "wrong name %s\n", data.cFileName );
2164 ok( FILE_ATTRIBUTE_ARCHIVE == data.dwFileAttributes ||
2165 FILE_ATTRIBUTE_DEVICE == data.dwFileAttributes /* Win9x */,
2166 "wrong attributes %x\n", data.dwFileAttributes );
2167 if (data.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE)
2169 ok( 0 == data.nFileSizeHigh, "wrong size %d\n", data.nFileSizeHigh );
2170 ok( 0 == data.nFileSizeLow, "wrong size %d\n", data.nFileSizeLow );
2172 SetLastError( 0xdeadbeaf );
2173 ok( !FindNextFileA( handle, &data ), "FindNextFileA succeeded\n" );
2174 ok( GetLastError() == ERROR_NO_MORE_FILES, "bad error %d\n", GetLastError() );
2175 ok( FindClose( handle ), "failed to close handle\n" );
2177 /* try FindFirstFileA on "c:\nul\*" */
2178 SetLastError( 0xdeadbeaf );
2179 strcpy(buffer2, buffer);
2180 strcat(buffer2, "nul\\*");
2181 handle = FindFirstFileA(buffer2, &data);
2182 err = GetLastError();
2183 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2184 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2186 /* try FindFirstFileA on "c:\nul*" */
2187 SetLastError( 0xdeadbeaf );
2188 strcpy(buffer2, buffer);
2189 strcat(buffer2, "nul*");
2190 handle = FindFirstFileA(buffer2, &data);
2191 err = GetLastError();
2192 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2193 ok ( err == ERROR_FILE_NOT_FOUND, "Bad Error number %d\n", err );
2195 /* try FindFirstFileA on "c:\foo\bar\nul" */
2196 SetLastError( 0xdeadbeaf );
2197 strcpy(buffer2, buffer);
2198 strcat(buffer2, "foo\\bar\\nul");
2199 handle = FindFirstFileA(buffer2, &data);
2200 err = GetLastError();
2201 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2202 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2204 /* try FindFirstFileA on "c:\foo\nul\bar" */
2205 SetLastError( 0xdeadbeaf );
2206 strcpy(buffer2, buffer);
2207 strcat(buffer2, "foo\\nul\\bar");
2208 handle = FindFirstFileA(buffer2, &data);
2209 err = GetLastError();
2210 ok ( handle == INVALID_HANDLE_VALUE, "FindFirstFile on %s should Fail\n", buffer2 );
2211 ok ( err == ERROR_PATH_NOT_FOUND, "Bad Error number %d\n", err );
2214 static void test_FindNextFileA(void)
2217 WIN32_FIND_DATAA search_results;
2219 char buffer[5] = "C:\\*";
2221 buffer[0] = get_windows_drive();
2222 handle = FindFirstFileA(buffer,&search_results);
2223 ok ( handle != INVALID_HANDLE_VALUE, "FindFirstFile on C:\\* should succeed\n" );
2224 while (FindNextFile(handle, &search_results))
2226 /* get to the end of the files */
2228 ok ( FindClose(handle) == TRUE, "Failed to close handle\n");
2229 err = GetLastError();
2230 ok ( err == ERROR_NO_MORE_FILES, "GetLastError should return ERROR_NO_MORE_FILES\n");
2233 static void test_FindFirstFileExA(FINDEX_SEARCH_OPS search_ops)
2235 WIN32_FIND_DATAA search_results;
2239 if (!pFindFirstFileExA)
2241 win_skip("FindFirstFileExA() is missing\n");
2245 CreateDirectoryA("test-dir", NULL);
2246 _lclose(_lcreat("test-dir\\file1", 0));
2247 _lclose(_lcreat("test-dir\\file2", 0));
2248 CreateDirectoryA("test-dir\\dir1", NULL);
2249 SetLastError(0xdeadbeef);
2250 handle = pFindFirstFileExA("test-dir\\*", FindExInfoStandard, &search_results, search_ops, NULL, 0);
2251 if (handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
2253 win_skip("FindFirstFileExA is not implemented\n");
2256 ok(handle != INVALID_HANDLE_VALUE, "FindFirstFile failed (err=%u)\n", GetLastError());
2257 ok(strcmp(search_results.cFileName, ".") == 0, "First entry should be '.', is %s\n", search_results.cFileName);
2259 #define CHECK_NAME(fn) (strcmp((fn), "file1") == 0 || strcmp((fn), "file2") == 0 || strcmp((fn), "dir1") == 0)
2261 ok(FindNextFile(handle, &search_results), "Fetching second file failed\n");
2262 ok(strcmp(search_results.cFileName, "..") == 0, "Second entry should be '..' is %s\n", search_results.cFileName);
2264 ok(FindNextFile(handle, &search_results), "Fetching third file failed\n");
2265 ok(CHECK_NAME(search_results.cFileName), "Invalid third entry - %s\n", search_results.cFileName);
2267 SetLastError(0xdeadbeef);
2268 ret = FindNextFile(handle, &search_results);
2269 if (!ret && (GetLastError() == ERROR_NO_MORE_FILES) && (search_ops == FindExSearchLimitToDirectories))
2271 skip("File system supports directory filtering\n");
2272 /* Results from the previous call are not cleared */
2273 ok(strcmp(search_results.cFileName, "dir1") == 0, "Third entry should be 'dir1' is %s\n", search_results.cFileName);
2274 FindClose( handle );
2278 ok(ret, "Fetching fourth file failed\n");
2279 ok(CHECK_NAME(search_results.cFileName), "Invalid fourth entry - %s\n", search_results.cFileName);
2281 ok(FindNextFile(handle, &search_results), "Fetching fifth file failed\n");
2282 ok(CHECK_NAME(search_results.cFileName), "Invalid fifth entry - %s\n", search_results.cFileName);
2286 ok(FindNextFile(handle, &search_results) == FALSE, "Fetching sixth file should fail\n");
2288 FindClose( handle );
2291 DeleteFileA("test-dir\\file1");
2292 DeleteFileA("test-dir\\file2");
2293 RemoveDirectoryA("test-dir\\dir1");
2294 RemoveDirectoryA("test-dir");
2297 static int test_Mapfile_createtemp(HANDLE *handle)
2299 SetFileAttributesA(filename,FILE_ATTRIBUTE_NORMAL);
2300 DeleteFile(filename);
2301 *handle = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, 0,
2302 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2303 if (*handle != INVALID_HANDLE_VALUE) {
2311 static void test_MapFile(void)
2316 ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
2318 hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0x1000, "named_file_map" );
2319 ok( hmap != NULL, "mapping should work, I named it!\n" );
2321 ok( CloseHandle( hmap ), "can't close mapping handle\n");
2323 /* We have to close file before we try new stuff with mapping again.
2324 Else we would always succeed on XP or block descriptors on 95. */
2325 hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
2326 ok( hmap != NULL, "We should still be able to map!\n" );
2327 ok( CloseHandle( hmap ), "can't close mapping handle\n");
2328 ok( CloseHandle( handle ), "can't close file handle\n");
2331 ok(test_Mapfile_createtemp(&handle), "Couldn't create test file.\n");
2333 hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0, 0, NULL );
2334 ok( hmap == NULL, "mapped zero size file\n");
2335 ok( GetLastError() == ERROR_FILE_INVALID, "not ERROR_FILE_INVALID\n");
2337 hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0x80000000, 0, NULL );
2338 ok( hmap == NULL || broken(hmap != NULL) /* NT4 */, "mapping should fail\n");
2339 /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */
2341 CloseHandle( hmap );
2343 hmap = CreateFileMapping( handle, NULL, PAGE_READWRITE, 0x80000000, 0x10000, NULL );
2344 ok( hmap == NULL || broken(hmap != NULL) /* NT4 */, "mapping should fail\n");
2345 /* GetLastError() varies between win9x and WinNT and also depends on the filesystem */
2347 CloseHandle( hmap );
2349 /* On XP you can now map again, on Win 95 you cannot. */
2351 ok( CloseHandle( handle ), "can't close file handle\n");
2352 ok( DeleteFileA( filename ), "DeleteFile failed after map\n" );
2355 static void test_GetFileType(void)
2358 HANDLE h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2359 ok( h != INVALID_HANDLE_VALUE, "open %s failed\n", filename );
2360 type = GetFileType(h);
2361 ok( type == FILE_TYPE_DISK, "expected type disk got %d\n", type );
2363 h = CreateFileA( "nul", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2364 ok( h != INVALID_HANDLE_VALUE, "open nul failed\n" );
2365 type = GetFileType(h);
2366 ok( type == FILE_TYPE_CHAR, "expected type char for nul got %d\n", type );
2368 DeleteFileA( filename );
2371 static int completion_count;
2373 static void CALLBACK FileIOComplete(DWORD dwError, DWORD dwBytes, LPOVERLAPPED ovl)
2375 /* printf("(%ld, %ld, %p { %ld, %ld, %ld, %ld, %p })\n", dwError, dwBytes, ovl, ovl->Internal, ovl->InternalHigh, ovl->Offset, ovl->OffsetHigh, ovl->hEvent);*/
2376 ReleaseSemaphore(ovl->hEvent, 1, NULL);
2380 static void test_async_file_errors(void)
2382 char szFile[MAX_PATH];
2383 HANDLE hSem = CreateSemaphoreW(NULL, 1, 1, NULL);
2385 LPVOID lpBuffer = HeapAlloc(GetProcessHeap(), 0, 4096);
2387 S(U(ovl)).Offset = 0;
2388 S(U(ovl)).OffsetHigh = 0;
2390 completion_count = 0;
2392 GetWindowsDirectoryA(szFile, sizeof(szFile)/sizeof(szFile[0])-1-strlen("\\win.ini"));
2393 strcat(szFile, "\\win.ini");
2394 hFile = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
2395 NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
2396 if (hFile == INVALID_HANDLE_VALUE) /* win9x doesn't like FILE_SHARE_DELETE */
2397 hFile = CreateFileA(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
2398 NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
2399 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA(%s ...) failed\n", szFile);
2404 while (WaitForSingleObjectEx(hSem, INFINITE, TRUE) == WAIT_IO_COMPLETION)
2406 res = ReadFileEx(hFile, lpBuffer, 4096, &ovl, FileIOComplete);
2407 /*printf("Offset = %ld, result = %s\n", ovl.Offset, res ? "TRUE" : "FALSE");*/
2410 if (!GetOverlappedResult(hFile, &ovl, &count, FALSE))
2412 S(U(ovl)).Offset += count;
2413 /* i/o completion routine only called if ReadFileEx returned success.
2414 * we only care about violations of this rule so undo what should have
2418 ok(completion_count == 0, "completion routine should only be called when ReadFileEx succeeds (this rule was violated %d times)\n", completion_count);
2419 /*printf("Error = %ld\n", GetLastError());*/
2420 HeapFree(GetProcessHeap(), 0, lpBuffer);
2423 static BOOL user_apc_ran;
2424 static void CALLBACK user_apc(ULONG_PTR param)
2426 user_apc_ran = TRUE;
2429 static void test_read_write(void)
2431 DWORD bytes, ret, old_prot;
2433 char temp_path[MAX_PATH];
2434 char filename[MAX_PATH];
2436 static const char prefix[] = "pfx";
2438 ret = GetTempPathA(MAX_PATH, temp_path);
2439 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
2440 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
2442 ret = GetTempFileNameA(temp_path, prefix, 0, filename);
2443 ok(ret != 0, "GetTempFileNameA error %d\n", GetLastError());
2445 hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
2446 CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS, 0);
2447 ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA: error %d\n", GetLastError());
2449 user_apc_ran = FALSE;
2450 if (pQueueUserAPC) {
2451 trace("Queueing an user APC\n"); /* verify the file is non alerable */
2452 ret = pQueueUserAPC(&user_apc, GetCurrentThread(), 0);
2453 ok(ret, "QueueUserAPC failed: %d\n", GetLastError());
2456 SetLastError(12345678);
2458 ret = WriteFile(hFile, NULL, 0, &bytes, NULL);
2459 ok(ret && GetLastError() == 12345678,
2460 "ret = %d, error %d\n", ret, GetLastError());
2461 ok(!bytes, "bytes = %d\n", bytes);
2463 SetLastError(12345678);
2465 ret = WriteFile(hFile, NULL, 10, &bytes, NULL);
2466 ok((!ret && GetLastError() == ERROR_INVALID_USER_BUFFER) || /* Win2k */
2467 (ret && GetLastError() == 12345678), /* Win9x */
2468 "ret = %d, error %d\n", ret, GetLastError());
2469 ok(!bytes || /* Win2k */
2470 bytes == 10, /* Win9x */
2471 "bytes = %d\n", bytes);
2473 /* make sure the file contains data */
2474 WriteFile(hFile, "this is the test data", 21, &bytes, NULL);
2475 SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
2477 SetLastError(12345678);
2479 ret = ReadFile(hFile, NULL, 0, &bytes, NULL);
2480 ok(ret && GetLastError() == 12345678,
2481 "ret = %d, error %d\n", ret, GetLastError());
2482 ok(!bytes, "bytes = %d\n", bytes);
2484 SetLastError(12345678);
2486 ret = ReadFile(hFile, NULL, 10, &bytes, NULL);
2487 ok(!ret && (GetLastError() == ERROR_NOACCESS || /* Win2k */
2488 GetLastError() == ERROR_INVALID_PARAMETER), /* Win9x */
2489 "ret = %d, error %d\n", ret, GetLastError());
2490 ok(!bytes, "bytes = %d\n", bytes);
2492 ok(user_apc_ran == FALSE, "UserAPC ran, file using alertable io mode\n");
2494 SleepEx(0, TRUE); /* get rid of apc */
2496 /* test passing protected memory as buffer */
2498 mem = VirtualAlloc( NULL, 0x4000, MEM_COMMIT, PAGE_READWRITE );
2499 ok( mem != NULL, "failed to allocate virtual mem error %u\n", GetLastError() );
2501 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
2502 ok( ret, "WriteFile failed error %u\n", GetLastError() );
2503 ok( bytes == 0x4000, "only wrote %x bytes\n", bytes );
2505 ret = VirtualProtect( mem + 0x2000, 0x2000, PAGE_NOACCESS, &old_prot );
2506 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2508 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
2509 ok( !ret, "WriteFile succeeded\n" );
2510 ok( GetLastError() == ERROR_INVALID_USER_BUFFER ||
2511 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2512 "wrong error %u\n", GetLastError() );
2513 ok( bytes == 0, "wrote %x bytes\n", bytes );
2515 ret = WriteFile( (HANDLE)0xdead, mem, 0x4000, &bytes, NULL );
2516 ok( !ret, "WriteFile succeeded\n" );
2517 ok( GetLastError() == ERROR_INVALID_HANDLE || /* handle is checked before buffer on NT */
2518 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2519 "wrong error %u\n", GetLastError() );
2520 ok( bytes == 0, "wrote %x bytes\n", bytes );
2522 ret = VirtualProtect( mem, 0x2000, PAGE_NOACCESS, &old_prot );
2523 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2525 ret = WriteFile( hFile, mem, 0x4000, &bytes, NULL );
2526 ok( !ret, "WriteFile succeeded\n" );
2527 ok( GetLastError() == ERROR_INVALID_USER_BUFFER ||
2528 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2529 "wrong error %u\n", GetLastError() );
2530 ok( bytes == 0, "wrote %x bytes\n", bytes );
2532 SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
2534 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2535 ok( !ret, "ReadFile succeeded\n" );
2536 ok( GetLastError() == ERROR_NOACCESS ||
2537 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2538 "wrong error %u\n", GetLastError() );
2539 ok( bytes == 0, "read %x bytes\n", bytes );
2541 ret = VirtualProtect( mem, 0x2000, PAGE_READONLY, &old_prot );
2542 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2544 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2545 ok( !ret, "ReadFile succeeded\n" );
2546 ok( GetLastError() == ERROR_NOACCESS ||
2547 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2548 "wrong error %u\n", GetLastError() );
2549 ok( bytes == 0, "read %x bytes\n", bytes );
2551 ret = VirtualProtect( mem, 0x2000, PAGE_READWRITE, &old_prot );
2552 ok( ret, "VirtualProtect failed error %u\n", GetLastError() );
2554 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2555 ok( !ret, "ReadFile succeeded\n" );
2556 ok( GetLastError() == ERROR_NOACCESS ||
2557 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2558 "wrong error %u\n", GetLastError() );
2559 ok( bytes == 0, "read %x bytes\n", bytes );
2561 SetFilePointer( hFile, 0x1234, NULL, FILE_BEGIN );
2562 SetEndOfFile( hFile );
2563 SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
2565 ret = ReadFile( hFile, mem, 0x4000, &bytes, NULL );
2566 ok( !ret, "ReadFile succeeded\n" );
2567 ok( GetLastError() == ERROR_NOACCESS ||
2568 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2569 "wrong error %u\n", GetLastError() );
2570 ok( bytes == 0, "read %x bytes\n", bytes );
2572 ret = ReadFile( hFile, mem, 0x2000, &bytes, NULL );
2573 ok( ret, "ReadFile failed error %u\n", GetLastError() );
2574 ok( bytes == 0x1234, "read %x bytes\n", bytes );
2576 ret = ReadFile( hFile, NULL, 1, &bytes, NULL );
2577 ok( !ret, "ReadFile succeeded\n" );
2578 ok( GetLastError() == ERROR_NOACCESS ||
2579 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
2580 "wrong error %u\n", GetLastError() );
2581 ok( bytes == 0, "read %x bytes\n", bytes );
2583 VirtualFree( mem, 0, MEM_FREE );
2585 ret = CloseHandle(hFile);
2586 ok( ret, "CloseHandle: error %d\n", GetLastError());
2587 ret = DeleteFileA(filename);
2588 ok( ret, "DeleteFileA: error %d\n", GetLastError());
2591 static void test_OpenFile(void)
2598 static const char file[] = "regedit.exe";
2599 static const char foo[] = ".\\foo-bar-foo.baz";
2600 static const char *foo_too_long = ".\\foo-bar-foo.baz+++++++++++++++"
2601 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2602 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2603 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2604 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
2605 "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
2606 char buff[MAX_PATH];
2607 char buff_long[4*MAX_PATH];
2608 char filled_0xA5[OFS_MAXPATHNAME];
2612 /* Check for existing file */
2613 if (!pGetSystemWindowsDirectoryA)
2614 length = GetWindowsDirectoryA(buff, MAX_PATH);
2616 length = pGetSystemWindowsDirectoryA(buff, MAX_PATH);
2618 if (length + sizeof(file) < MAX_PATH)
2620 p = buff + strlen(buff);
2621 if (p > buff && p[-1] != '\\') *p++ = '\\';
2623 memset(&ofs, 0xA5, sizeof(ofs));
2624 SetLastError(0xfaceabee);
2626 hFile = OpenFile(buff, &ofs, OF_EXIST);
2627 ok( hFile == TRUE, "%s not found : %d\n", buff, GetLastError() );
2628 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
2629 "GetLastError() returns %d\n", GetLastError() );
2630 ok( ofs.cBytes == sizeof(ofs), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2631 ok( ofs.nErrCode == ERROR_SUCCESS, "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2632 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2633 "OpenFile returned '%s', but was expected to return '%s' or string filled with 0xA5\n",
2634 ofs.szPathName, buff );
2637 memset(&filled_0xA5, 0xA5, OFS_MAXPATHNAME);
2638 length = GetCurrentDirectoryA(MAX_PATH, buff);
2640 /* Check for nonexistent file */
2641 if (length + sizeof(foo) < MAX_PATH)
2643 p = buff + strlen(buff);
2644 if (p > buff && p[-1] != '\\') *p++ = '\\';
2645 strcpy( p, foo + 2 );
2646 memset(&ofs, 0xA5, sizeof(ofs));
2647 SetLastError(0xfaceabee);
2649 hFile = OpenFile(foo, &ofs, OF_EXIST);
2650 ok( hFile == HFILE_ERROR, "hFile != HFILE_ERROR : %d\n", GetLastError());
2651 ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError() returns %d\n", GetLastError() );
2653 ok( ofs.cBytes == 0xA5, "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2654 ok( ofs.nErrCode == ERROR_FILE_NOT_FOUND, "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2655 ok( lstrcmpiA(ofs.szPathName, buff) == 0 || strncmp(ofs.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0,
2656 "OpenFile returned '%s', but was expected to return '%s' or string filled with 0xA5\n",
2657 ofs.szPathName, buff );
2660 length = GetCurrentDirectoryA(MAX_PATH, buff_long);
2661 length += lstrlenA(foo_too_long + 1);
2663 /* Check for nonexistent file with too long filename */
2664 if (length >= OFS_MAXPATHNAME && length < sizeof(buff_long))
2666 lstrcatA(buff_long, foo_too_long + 1); /* Avoid '.' during concatenation */
2667 memset(&ofs, 0xA5, sizeof(ofs));
2668 SetLastError(0xfaceabee);
2670 hFile = OpenFile(foo_too_long, &ofs, OF_EXIST);
2671 ok( hFile == HFILE_ERROR, "hFile != HFILE_ERROR : %d\n", GetLastError());
2672 ok( GetLastError() == ERROR_INVALID_DATA || GetLastError() == ERROR_FILENAME_EXCED_RANGE,
2673 "GetLastError() returns %d\n", GetLastError() );
2675 ok( ofs.cBytes == 0xA5, "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2676 ok( ofs.nErrCode == ERROR_INVALID_DATA || ofs.nErrCode == ERROR_FILENAME_EXCED_RANGE,
2677 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2678 ok( strncmp(ofs.szPathName, filled_0xA5, OFS_MAXPATHNAME) == 0,
2679 "OpenFile returned '%s', but was expected to return string filled with 0xA5\n",
2683 length = GetCurrentDirectoryA(MAX_PATH, buff) + sizeof(filename);
2685 if (length >= MAX_PATH)
2687 trace("Buffer too small, requested length = %d, but MAX_PATH = %d. Skipping test.\n", length, MAX_PATH);
2690 p = buff + strlen(buff);
2691 if (p > buff && p[-1] != '\\') *p++ = '\\';
2692 strcpy( p, filename );
2694 memset(&ofs, 0xA5, sizeof(ofs));
2695 SetLastError(0xfaceabee);
2696 /* Create an empty file */
2697 hFile = OpenFile(filename, &ofs, OF_CREATE);
2698 ok( hFile != HFILE_ERROR, "OpenFile failed to create nonexistent file\n" );
2699 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
2700 "GetLastError() returns %d\n", GetLastError() );
2701 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2702 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
2703 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2704 ret = _lclose(hFile);
2705 ok( !ret, "_lclose() returns %d\n", ret );
2706 retval = GetFileAttributesA(filename);
2707 ok( retval != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA: error %d\n", GetLastError() );
2709 memset(&ofs, 0xA5, sizeof(ofs));
2710 SetLastError(0xfaceabee);
2711 /* Check various opening options: */
2712 /* for reading only, */
2713 hFile = OpenFile(filename, &ofs, OF_READ);
2714 ok( hFile != HFILE_ERROR, "OpenFile failed on read\n" );
2715 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
2716 "GetLastError() returns %d\n", GetLastError() );
2717 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2718 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
2719 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2720 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2721 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
2722 ret = _lclose(hFile);
2723 ok( !ret, "_lclose() returns %d\n", ret );
2725 memset(&ofs, 0xA5, sizeof(ofs));
2726 SetLastError(0xfaceabee);
2727 /* for writing only, */
2728 hFile = OpenFile(filename, &ofs, OF_WRITE);
2729 ok( hFile != HFILE_ERROR, "OpenFile failed on write\n" );
2730 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
2731 "GetLastError() returns %d\n", GetLastError() );
2732 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2733 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
2734 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2735 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2736 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
2737 ret = _lclose(hFile);
2738 ok( !ret, "_lclose() returns %d\n", ret );
2740 memset(&ofs, 0xA5, sizeof(ofs));
2741 SetLastError(0xfaceabee);
2742 /* for reading and writing, */
2743 hFile = OpenFile(filename, &ofs, OF_READWRITE);
2744 ok( hFile != HFILE_ERROR, "OpenFile failed on read/write\n" );
2745 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
2746 "GetLastError() returns %d\n", GetLastError() );
2747 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2748 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
2749 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2750 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2751 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
2752 ret = _lclose(hFile);
2753 ok( !ret, "_lclose() returns %d\n", ret );
2755 memset(&ofs, 0xA5, sizeof(ofs));
2756 SetLastError(0xfaceabee);
2757 /* for checking file presence. */
2758 hFile = OpenFile(filename, &ofs, OF_EXIST);
2759 ok( hFile == 1, "OpenFile failed on finding our created file\n" );
2760 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
2761 "GetLastError() returns %d\n", GetLastError() );
2762 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2763 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
2764 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2765 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2766 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
2768 memset(&ofs, 0xA5, sizeof(ofs));
2769 SetLastError(0xfaceabee);
2770 /* Delete the file and make sure it doesn't exist anymore */
2771 hFile = OpenFile(filename, &ofs, OF_DELETE);
2772 ok( hFile == 1, "OpenFile failed on delete (%d)\n", hFile );
2773 ok( GetLastError() == 0xfaceabee || GetLastError() == ERROR_SUCCESS,
2774 "GetLastError() returns %d\n", GetLastError() );
2775 ok( ofs.cBytes == sizeof(OFSTRUCT), "OpenFile set ofs.cBytes to %d\n", ofs.cBytes );
2776 ok( ofs.nErrCode == ERROR_SUCCESS || broken(ofs.nErrCode != ERROR_SUCCESS) /* win9x */,
2777 "OpenFile set ofs.nErrCode to %d\n", ofs.nErrCode );
2778 ok( lstrcmpiA(ofs.szPathName, buff) == 0,
2779 "OpenFile returned '%s', but was expected to return '%s'\n", ofs.szPathName, buff );
2781 retval = GetFileAttributesA(filename);
2782 ok( retval == INVALID_FILE_ATTRIBUTES, "GetFileAttributesA succeeded on deleted file\n" );
2785 static void test_overlapped(void)
2790 /* GetOverlappedResult crashes if the 2nd or 3rd param are NULL */
2791 if (0) /* tested: WinXP */
2793 GetOverlappedResult(0, NULL, &result, FALSE);
2794 GetOverlappedResult(0, &ov, NULL, FALSE);
2795 GetOverlappedResult(0, NULL, NULL, FALSE);
2798 memset( &ov, 0, sizeof ov );
2800 r = GetOverlappedResult(0, &ov, &result, 0);
2802 ok( result == 0, "wrong result %u\n", result );
2804 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
2808 ov.InternalHigh = 0xabcd;
2809 r = GetOverlappedResult(0, &ov, &result, 0);
2811 ok( result == 0xabcd, "wrong result %u\n", result );
2813 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
2815 SetLastError( 0xb00 );
2817 ov.Internal = STATUS_INVALID_HANDLE;
2818 ov.InternalHigh = 0xabcd;
2819 r = GetOverlappedResult(0, &ov, &result, 0);
2820 ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
2821 ok( r == FALSE, "should return false\n");
2822 ok( result == 0xabcd || result == 0 /* win9x */, "wrong result %u\n", result );
2824 SetLastError( 0xb00 );
2826 ov.Internal = STATUS_PENDING;
2827 ov.InternalHigh = 0xabcd;
2828 r = GetOverlappedResult(0, &ov, &result, 0);
2829 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
2830 "wrong error %u\n", GetLastError() );
2831 ok( r == FALSE, "should return false\n");
2832 ok( result == 0, "wrong result %u\n", result );
2834 SetLastError( 0xb00 );
2835 ov.hEvent = CreateEvent( NULL, 1, 1, NULL );
2836 ov.Internal = STATUS_PENDING;
2837 ov.InternalHigh = 0xabcd;
2838 r = GetOverlappedResult(0, &ov, &result, 0);
2839 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
2840 "wrong error %u\n", GetLastError() );
2841 ok( r == FALSE, "should return false\n");
2843 ResetEvent( ov.hEvent );
2845 SetLastError( 0xb00 );
2846 ov.Internal = STATUS_PENDING;
2847 ov.InternalHigh = 0;
2848 r = GetOverlappedResult(0, &ov, &result, 0);
2849 ok( GetLastError() == ERROR_IO_INCOMPLETE || GetLastError() == ERROR_INVALID_HANDLE /* win9x */,
2850 "wrong error %u\n", GetLastError() );
2851 ok( r == FALSE, "should return false\n");
2853 r = CloseHandle( ov.hEvent );
2854 ok( r == TRUE, "close handle failed\n");
2857 static void test_RemoveDirectory(void)
2860 char directory[] = "removeme";
2862 rc = CreateDirectory(directory, NULL);
2863 ok( rc, "Createdirectory failed, gle=%d\n", GetLastError() );
2865 rc = SetCurrentDirectory(directory);
2866 ok( rc, "SetCurrentDirectory failed, gle=%d\n", GetLastError() );
2868 rc = RemoveDirectory(".");
2871 rc = SetCurrentDirectory("..");
2872 ok( rc, "SetCurrentDirectory failed, gle=%d\n", GetLastError() );
2874 rc = RemoveDirectory(directory);
2875 ok( rc, "RemoveDirectory failed, gle=%d\n", GetLastError() );
2879 static BOOL check_file_time( const FILETIME *ft1, const FILETIME *ft2, UINT tolerance )
2881 ULONGLONG t1 = ((ULONGLONG)ft1->dwHighDateTime << 32) | ft1->dwLowDateTime;
2882 ULONGLONG t2 = ((ULONGLONG)ft2->dwHighDateTime << 32) | ft2->dwLowDateTime;
2883 return abs(t1 - t2) <= tolerance;
2886 static void test_ReplaceFileA(void)
2888 char replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH];
2889 HANDLE hReplacedFile, hReplacementFile, hBackupFile;
2890 static const char replacedData[] = "file-to-replace";
2891 static const char replacementData[] = "new-file";
2892 static const char backupData[] = "backup-file";
2893 FILETIME ftReplaced, ftReplacement, ftBackup;
2894 static const char prefix[] = "pfx";
2895 char temp_path[MAX_PATH];
2897 BOOL retok, removeBackup = FALSE;
2901 win_skip("ReplaceFileA() is missing\n");
2905 ret = GetTempPathA(MAX_PATH, temp_path);
2906 ok(ret != 0, "GetTempPathA error %d\n", GetLastError());
2907 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
2909 ret = GetTempFileNameA(temp_path, prefix, 0, replaced);
2910 ok(ret != 0, "GetTempFileNameA error (replaced) %d\n", GetLastError());
2912 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
2913 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
2915 ret = GetTempFileNameA(temp_path, prefix, 0, backup);
2916 ok(ret != 0, "GetTempFileNameA error (backup) %d\n", GetLastError());
2918 /* place predictable data in the file to be replaced */
2919 hReplacedFile = CreateFileA(replaced, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2920 ok(hReplacedFile != INVALID_HANDLE_VALUE,
2921 "failed to open replaced file\n");
2922 retok = WriteFile(hReplacedFile, replacedData, sizeof(replacedData), &ret, NULL );
2923 ok( retok && ret == sizeof(replacedData),
2924 "WriteFile error (replaced) %d\n", GetLastError());
2925 ok(GetFileSize(hReplacedFile, NULL) == sizeof(replacedData),
2926 "replaced file has wrong size\n");
2927 /* place predictable data in the file to be the replacement */
2928 hReplacementFile = CreateFileA(replacement, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2929 ok(hReplacementFile != INVALID_HANDLE_VALUE,
2930 "failed to open replacement file\n");
2931 retok = WriteFile(hReplacementFile, replacementData, sizeof(replacementData), &ret, NULL );
2932 ok( retok && ret == sizeof(replacementData),
2933 "WriteFile error (replacement) %d\n", GetLastError());
2934 ok(GetFileSize(hReplacementFile, NULL) == sizeof(replacementData),
2935 "replacement file has wrong size\n");
2936 /* place predictable data in the backup file (to be over-written) */
2937 hBackupFile = CreateFileA(backup, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
2938 ok(hBackupFile != INVALID_HANDLE_VALUE,
2939 "failed to open backup file\n");
2940 retok = WriteFile(hBackupFile, backupData, sizeof(backupData), &ret, NULL );
2941 ok( retok && ret == sizeof(backupData),
2942 "WriteFile error (replacement) %d\n", GetLastError());
2943 ok(GetFileSize(hBackupFile, NULL) == sizeof(backupData),
2944 "backup file has wrong size\n");
2945 /* change the filetime on the "replaced" file to ensure that it changes */
2946 ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
2947 ok( ret, "GetFileTime error (replaced) %d\n", GetLastError());
2948 ftReplaced.dwLowDateTime -= 600000000; /* 60 second */
2949 ret = SetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
2950 ok( ret, "SetFileTime error (replaced) %d\n", GetLastError());
2951 GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced); /* get the actual time back */
2952 CloseHandle(hReplacedFile);
2953 /* change the filetime on the backup to ensure that it changes */
2954 ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
2955 ok( ret, "GetFileTime error (backup) %d\n", GetLastError());
2956 ftBackup.dwLowDateTime -= 1200000000; /* 120 second */
2957 ret = SetFileTime(hBackupFile, NULL, NULL, &ftBackup);
2958 ok( ret, "SetFileTime error (backup) %d\n", GetLastError());
2959 GetFileTime(hBackupFile, NULL, NULL, &ftBackup); /* get the actual time back */
2960 CloseHandle(hBackupFile);
2961 /* get the filetime on the replacement file to perform checks */
2962 ret = GetFileTime(hReplacementFile, NULL, NULL, &ftReplacement);
2963 ok( ret, "GetFileTime error (replacement) %d\n", GetLastError());
2964 CloseHandle(hReplacementFile);
2966 /* perform replacement w/ backup
2967 * TODO: flags are not implemented
2969 SetLastError(0xdeadbeef);
2970 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
2971 ok(ret, "ReplaceFileA: unexpected error %d\n", GetLastError());
2972 /* make sure that the backup has the size of the old "replaced" file */
2973 hBackupFile = CreateFileA(backup, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
2974 ok(hBackupFile != INVALID_HANDLE_VALUE,
2975 "failed to open backup file\n");
2976 ret = GetFileSize(hBackupFile, NULL);
2977 ok(ret == sizeof(replacedData),
2978 "backup file has wrong size %d\n", ret);
2979 /* make sure that the "replaced" file has the size of the replacement file */
2980 hReplacedFile = CreateFileA(replaced, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
2981 ok(hReplacedFile != INVALID_HANDLE_VALUE,
2982 "failed to open replaced file: %d\n", GetLastError());
2983 if (hReplacedFile != INVALID_HANDLE_VALUE)
2985 ret = GetFileSize(hReplacedFile, NULL);
2986 ok(ret == sizeof(replacementData),
2987 "replaced file has wrong size %d\n", ret);
2988 /* make sure that the replacement file no-longer exists */
2989 hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
2990 ok(hReplacementFile == INVALID_HANDLE_VALUE,
2991 "unexpected error, replacement file should not exist %d\n", GetLastError());
2992 /* make sure that the backup has the old "replaced" filetime */
2993 ret = GetFileTime(hBackupFile, NULL, NULL, &ftBackup);
2994 ok( ret, "GetFileTime error (backup %d\n", GetLastError());
2995 ok(check_file_time(&ftBackup, &ftReplaced, 20000000), "backup file has wrong filetime\n");
2996 CloseHandle(hBackupFile);
2997 /* make sure that the "replaced" has the old replacement filetime */
2998 ret = GetFileTime(hReplacedFile, NULL, NULL, &ftReplaced);
2999 ok( ret, "GetFileTime error (backup %d\n", GetLastError());
3000 ok(check_file_time(&ftReplaced, &ftReplacement, 20000000),
3001 "replaced file has wrong filetime %x%08x / %x%08x\n",
3002 ftReplaced.dwHighDateTime, ftReplaced.dwLowDateTime,
3003 ftReplacement.dwHighDateTime, ftReplacement.dwLowDateTime );
3004 CloseHandle(hReplacedFile);
3007 skip("couldn't open replacement file, skipping tests\n");
3009 /* re-create replacement file for pass w/o backup (blank) */
3010 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3011 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
3012 /* perform replacement w/o backup
3013 * TODO: flags are not implemented
3015 SetLastError(0xdeadbeef);
3016 ret = pReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
3017 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3018 "ReplaceFileA: unexpected error %d\n", GetLastError());
3020 /* re-create replacement file for pass w/ backup (backup-file not existing) */
3021 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3022 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
3023 ret = DeleteFileA(backup);
3024 ok(ret, "DeleteFileA: error (backup) %d\n", GetLastError());
3025 /* perform replacement w/ backup (no pre-existing backup)
3026 * TODO: flags are not implemented
3028 SetLastError(0xdeadbeef);
3029 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3030 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3031 "ReplaceFileA: unexpected error %d\n", GetLastError());
3033 removeBackup = TRUE;
3035 /* re-create replacement file for pass w/ no permissions to "replaced" */
3036 ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
3037 ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
3038 ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_READONLY);
3039 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3040 "SetFileAttributesA: error setting to read only %d\n", GetLastError());
3041 /* perform replacement w/ backup (no permission to "replaced")
3042 * TODO: flags are not implemented
3044 SetLastError(0xdeadbeef);
3045 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3046 ok(ret != ERROR_UNABLE_TO_REMOVE_REPLACED, "ReplaceFileA: unexpected error %d\n", GetLastError());
3047 /* make sure that the replacement file still exists */
3048 hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
3049 ok(hReplacementFile != INVALID_HANDLE_VALUE ||
3050 broken(GetLastError() == ERROR_FILE_NOT_FOUND), /* win2k */
3051 "unexpected error, replacement file should still exist %d\n", GetLastError());
3052 CloseHandle(hReplacementFile);
3053 ret = SetFileAttributesA(replaced, FILE_ATTRIBUTE_NORMAL);
3054 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3055 "SetFileAttributesA: error setting to normal %d\n", GetLastError());
3057 /* replacement file still exists, make pass w/o "replaced" */
3058 ret = DeleteFileA(replaced);
3059 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3060 "DeleteFileA: error (replaced) %d\n", GetLastError());
3061 /* perform replacement w/ backup (no pre-existing backup or "replaced")
3062 * TODO: flags are not implemented
3064 SetLastError(0xdeadbeef);
3065 ret = pReplaceFileA(replaced, replacement, backup, 0, 0, 0);
3066 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
3067 GetLastError() == ERROR_ACCESS_DENIED),
3068 "ReplaceFileA: unexpected error %d\n", GetLastError());
3070 /* perform replacement w/o existing "replacement" file
3071 * TODO: flags are not implemented
3073 SetLastError(0xdeadbeef);
3074 ret = pReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
3075 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
3076 GetLastError() == ERROR_ACCESS_DENIED),
3077 "ReplaceFileA: unexpected error %d\n", GetLastError());
3078 DeleteFileA( replacement );
3081 * if the first round (w/ backup) worked then as long as there is no
3082 * failure then there is no need to check this round (w/ backup is the
3083 * more complete case)
3086 /* delete temporary files, replacement and replaced are already deleted */
3089 ret = DeleteFileA(backup);
3091 broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */
3092 "DeleteFileA: error (backup) %d\n", GetLastError());
3097 * ReplaceFileW is a simpler case of ReplaceFileA, there is no
3098 * need to be as thorough.
3100 static void test_ReplaceFileW(void)
3102 WCHAR replaced[MAX_PATH], replacement[MAX_PATH], backup[MAX_PATH];
3103 static const WCHAR prefix[] = {'p','f','x',0};
3104 WCHAR temp_path[MAX_PATH];
3106 BOOL removeBackup = FALSE;
3110 win_skip("ReplaceFileW() is missing\n");
3114 ret = GetTempPathW(MAX_PATH, temp_path);
3115 if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
3117 win_skip("GetTempPathW is not available\n");
3120 ok(ret != 0, "GetTempPathW error %d\n", GetLastError());
3121 ok(ret < MAX_PATH, "temp path should fit into MAX_PATH\n");
3123 ret = GetTempFileNameW(temp_path, prefix, 0, replaced);
3124 ok(ret != 0, "GetTempFileNameW error (replaced) %d\n", GetLastError());
3126 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3127 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3129 ret = GetTempFileNameW(temp_path, prefix, 0, backup);
3130 ok(ret != 0, "GetTempFileNameW error (backup) %d\n", GetLastError());
3132 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3133 ok(ret, "ReplaceFileW: error %d\n", GetLastError());
3135 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3136 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3137 ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0);
3138 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3139 "ReplaceFileW: error %d\n", GetLastError());
3141 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3142 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3143 ret = DeleteFileW(backup);
3144 ok(ret, "DeleteFileW: error (backup) %d\n", GetLastError());
3145 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3146 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3147 "ReplaceFileW: error %d\n", GetLastError());
3149 ret = GetTempFileNameW(temp_path, prefix, 0, replacement);
3150 ok(ret != 0, "GetTempFileNameW error (replacement) %d\n", GetLastError());
3151 ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_READONLY);
3152 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3153 "SetFileAttributesW: error setting to read only %d\n", GetLastError());
3155 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3156 ok(ret != ERROR_UNABLE_TO_REMOVE_REPLACED,
3157 "ReplaceFileW: unexpected error %d\n", GetLastError());
3158 ret = SetFileAttributesW(replaced, FILE_ATTRIBUTE_NORMAL);
3159 ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
3160 "SetFileAttributesW: error setting to normal %d\n", GetLastError());
3162 removeBackup = TRUE;
3164 ret = DeleteFileW(replaced);
3165 ok(ret, "DeleteFileW: error (replaced) %d\n", GetLastError());
3166 ret = pReplaceFileW(replaced, replacement, backup, 0, 0, 0);
3167 ok(!ret, "ReplaceFileW: error %d\n", GetLastError());
3169 ret = pReplaceFileW(replaced, replacement, NULL, 0, 0, 0);
3170 ok(!ret && (GetLastError() == ERROR_FILE_NOT_FOUND ||
3171 GetLastError() == ERROR_ACCESS_DENIED),
3172 "ReplaceFileW: unexpected error %d\n", GetLastError());
3173 DeleteFileW( replacement );
3177 ret = DeleteFileW(backup);
3179 broken(GetLastError() == ERROR_ACCESS_DENIED), /* win2k */
3180 "DeleteFileW: error (backup) %d\n", GetLastError());
3184 static void test_CreatFile(void)
3186 static const struct test_data
3188 DWORD disposition, access, error, clean_up;
3191 /* 0 */ { 0, 0, ERROR_INVALID_PARAMETER, 0 },
3192 /* 1 */ { 0, GENERIC_READ, ERROR_INVALID_PARAMETER, 0 },
3193 /* 2 */ { 0, GENERIC_READ|GENERIC_WRITE, ERROR_INVALID_PARAMETER, 0 },
3194 /* 3 */ { CREATE_NEW, 0, ERROR_FILE_EXISTS, 1 },
3195 /* 4 */ { CREATE_NEW, 0, 0, 1 },
3196 /* 5 */ { CREATE_NEW, GENERIC_READ, 0, 1 },
3197 /* 6 */ { CREATE_NEW, GENERIC_WRITE, 0, 1 },
3198 /* 7 */ { CREATE_NEW, GENERIC_READ|GENERIC_WRITE, 0, 0 },
3199 /* 8 */ { CREATE_ALWAYS, 0, 0, 0 },
3200 /* 9 */ { CREATE_ALWAYS, GENERIC_READ, 0, 0 },
3201 /* 10*/ { CREATE_ALWAYS, GENERIC_WRITE, 0, 0 },
3202 /* 11*/ { CREATE_ALWAYS, GENERIC_READ|GENERIC_WRITE, 0, 1 },
3203 /* 12*/ { OPEN_EXISTING, 0, ERROR_FILE_NOT_FOUND, 0 },
3204 /* 13*/ { CREATE_ALWAYS, 0, 0, 0 },
3205 /* 14*/ { OPEN_EXISTING, 0, 0, 0 },
3206 /* 15*/ { OPEN_EXISTING, GENERIC_READ, 0, 0 },
3207 /* 16*/ { OPEN_EXISTING, GENERIC_WRITE, 0, 0 },
3208 /* 17*/ { OPEN_EXISTING, GENERIC_READ|GENERIC_WRITE, 0, 1 },
3209 /* 18*/ { OPEN_ALWAYS, 0, 0, 0 },
3210 /* 19*/ { OPEN_ALWAYS, GENERIC_READ, 0, 0 },
3211 /* 20*/ { OPEN_ALWAYS, GENERIC_WRITE, 0, 0 },
3212 /* 21*/ { OPEN_ALWAYS, GENERIC_READ|GENERIC_WRITE, 0, 0 },
3213 /* 22*/ { TRUNCATE_EXISTING, 0, ERROR_INVALID_PARAMETER, 0 },
3214 /* 23*/ { TRUNCATE_EXISTING, GENERIC_READ, ERROR_INVALID_PARAMETER, 0 },
3215 /* 24*/ { TRUNCATE_EXISTING, GENERIC_WRITE, 0, 0 },
3216 /* 25*/ { TRUNCATE_EXISTING, GENERIC_READ|GENERIC_WRITE, 0, 0 }
3218 char temp_path[MAX_PATH];
3219 char file_name[MAX_PATH];
3220 DWORD i, ret, written;
3223 GetTempPath(MAX_PATH, temp_path);
3224 GetTempFileName(temp_path, "tmp", 0, file_name);
3226 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
3228 SetLastError(0xdeadbeef);
3229 hfile = CreateFile(file_name, td[i].access, 0, NULL, td[i].disposition, 0, 0);
3232 ok(hfile != INVALID_HANDLE_VALUE, "%d: CreateFile error %d\n", i, GetLastError());
3233 written = 0xdeadbeef;
3234 SetLastError(0xdeadbeef);
3235 ret = WriteFile(hfile, &td[i].error, sizeof(td[i].error), &written, NULL);
3236 if (td[i].access & GENERIC_WRITE)
3237 ok(ret, "%d: WriteFile error %d\n", i, GetLastError());
3240 ok(!ret, "%d: WriteFile should fail\n", i);
3241 ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError());
3247 /* FIXME: remove the condition below once Wine is fixed */
3248 if (td[i].disposition == TRUNCATE_EXISTING && !(td[i].access & GENERIC_WRITE))
3252 ok(hfile == INVALID_HANDLE_VALUE, "%d: CreateFile should fail\n", i);
3253 ok(GetLastError() == td[i].error, "%d: expected %d, got %d\n", i, td[i].error, GetLastError());
3259 ok(hfile == INVALID_HANDLE_VALUE, "%d: CreateFile should fail\n", i);
3260 ok(GetLastError() == td[i].error, "%d: expected %d, got %d\n", i, td[i].error, GetLastError());
3264 if (td[i].clean_up) DeleteFile(file_name);
3267 DeleteFile(file_name);
3270 static void test_GetFileInformationByHandleEx(void)
3273 char tempPath[MAX_PATH], tempFileName[MAX_PATH], buffer[1024];
3277 FILE_ID_BOTH_DIR_INFO *bothDirInfo;
3279 FILE_INFO_BY_HANDLE_CLASS handleClass;
3284 {0xdeadbeef, NULL, 0, ERROR_INVALID_PARAMETER},
3285 {FileIdBothDirectoryInfo, NULL, 0, ERROR_BAD_LENGTH},
3286 {FileIdBothDirectoryInfo, NULL, sizeof(buffer), ERROR_NOACCESS},
3287 {FileIdBothDirectoryInfo, buffer, 0, ERROR_BAD_LENGTH}};
3289 if (!pGetFileInformationByHandleEx)
3291 win_skip("GetFileInformationByHandleEx is missing.\n");
3295 ret2 = GetTempPathA(sizeof(tempPath), tempPath);
3296 ok(ret2, "GetFileInformationByHandleEx: GetTempPathA failed, got error %u.\n", GetLastError());
3298 /* ensure the existence of a file in the temp folder */
3299 ret2 = GetTempFileNameA(tempPath, "abc", 0, tempFileName);
3300 ok(ret2, "GetFileInformationByHandleEx: GetTempFileNameA failed, got error %u.\n", GetLastError());
3301 ret2 = GetFileAttributesA(tempFileName);
3302 ok(ret2 != INVALID_FILE_ATTRIBUTES, "GetFileInformationByHandleEx: "
3303 "GetFileAttributesA failed to find the temp file, got error %u.\n", GetLastError());
3305 directory = CreateFileA(tempPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
3306 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
3307 ok(directory != INVALID_HANDLE_VALUE, "GetFileInformationByHandleEx: failed to open the temp folder, "
3308 "got error %u.\n", GetLastError());
3310 for (i = 0; i < sizeof(checks) / sizeof(checks[0]); i += 1)
3312 SetLastError(0xdeadbeef);
3313 ret = pGetFileInformationByHandleEx(directory, checks[i].handleClass, checks[i].ptr, checks[i].size);
3314 ok(!ret && GetLastError() == checks[i].errorCode, "GetFileInformationByHandleEx: expected error %u, "
3315 "got %u.\n", checks[i].errorCode, GetLastError());
3320 memset(buffer, 0xff, sizeof(buffer));
3321 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer));
3322 if (!ret && GetLastError() == ERROR_NO_MORE_FILES)
3324 ok(ret, "GetFileInformationByHandleEx: failed to query for FileIdBothDirectoryInfo, got error %u.\n", GetLastError());
3327 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
3330 ok(bothDirInfo->FileAttributes != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file attributes.\n");
3331 ok(bothDirInfo->FileId.u.LowPart != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file id.\n");
3332 ok(bothDirInfo->FileNameLength != 0xffffffff, "GetFileInformationByHandleEx: returned invalid file name length.\n");
3333 if (!bothDirInfo->NextEntryOffset)
3335 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)(((char *)bothDirInfo) + bothDirInfo->NextEntryOffset);
3339 CloseHandle(directory);
3340 DeleteFile(tempFileName);
3343 static void test_OpenFileById(void)
3345 char tempPath[MAX_PATH], tempFileName[MAX_PATH], buffer[256], tickCount[256];
3346 WCHAR tempFileNameW[MAX_PATH];
3348 DWORD ret2, count, tempFileNameLen;
3349 HANDLE directory, handle, tempFile;
3350 FILE_ID_BOTH_DIR_INFO *bothDirInfo;
3351 FILE_ID_DESCRIPTOR fileIdDescr;
3353 if (!pGetFileInformationByHandleEx || !pOpenFileById)
3355 win_skip("GetFileInformationByHandleEx or OpenFileById is missing.\n");
3359 ret2 = GetTempPathA(sizeof(tempPath), tempPath);
3360 ok(ret2, "OpenFileById: GetTempPath failed, got error %u.\n", GetLastError());
3362 /* ensure the existence of a file in the temp folder */
3363 ret2 = GetTempFileNameA(tempPath, "abc", 0, tempFileName);
3364 ok(ret2, "OpenFileById: GetTempFileNameA failed, got error %u.\n", GetLastError());
3365 ret2 = GetFileAttributesA(tempFileName);
3366 ok(ret2 != INVALID_FILE_ATTRIBUTES,
3367 "OpenFileById: GetFileAttributesA failed to find the temp file, got error %u\n", GetLastError());
3369 ret2 = MultiByteToWideChar(CP_ACP, 0, tempFileName + strlen(tempPath), -1, tempFileNameW, sizeof(tempFileNameW)/sizeof(tempFileNameW[0]));
3370 ok(ret2, "OpenFileById: MultiByteToWideChar failed to convert tempFileName, got error %u.\n", GetLastError());
3371 tempFileNameLen = ret2 - 1;
3373 tempFile = CreateFileA(tempFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
3374 ok(tempFile != INVALID_HANDLE_VALUE, "OpenFileById: failed to create a temp file, "
3375 "got error %u.\n", GetLastError());
3376 ret2 = sprintf(tickCount, "%u", GetTickCount());
3377 ret = WriteFile(tempFile, tickCount, ret2, &count, NULL);
3378 ok(ret, "OpenFileById: WriteFile failed, got error %u.\n", GetLastError());
3379 CloseHandle(tempFile);
3381 directory = CreateFileA(tempPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
3382 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
3383 ok(directory != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the temp folder, "
3384 "got error %u.\n", GetLastError());
3386 /* get info about the temp folder itself */
3387 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
3388 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer));
3389 ok(ret, "OpenFileById: failed to query for FileIdBothDirectoryInfo, got error %u.\n", GetLastError());
3390 ok(bothDirInfo->FileNameLength == sizeof(WCHAR) && bothDirInfo->FileName[0] == '.',
3391 "OpenFileById: failed to return the temp folder at the first entry, got error %u.\n", GetLastError());
3393 /* open the temp folder itself */
3394 fileIdDescr.dwSize = sizeof(fileIdDescr);
3395 fileIdDescr.Type = FileIdType;
3396 U(fileIdDescr).FileId = bothDirInfo->FileId;
3397 handle = pOpenFileById(directory, &fileIdDescr, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0);
3399 ok(handle != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the temp folder itself, got error %u.\n", GetLastError());
3400 CloseHandle(handle);
3402 /* find the temp file in the temp folder */
3406 ret = pGetFileInformationByHandleEx(directory, FileIdBothDirectoryInfo, buffer, sizeof(buffer));
3407 ok(ret, "OpenFileById: failed to query for FileIdBothDirectoryInfo, got error %u.\n", GetLastError());
3410 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)buffer;
3413 if (tempFileNameLen == bothDirInfo->FileNameLength / sizeof(WCHAR) &&
3414 memcmp(tempFileNameW, bothDirInfo->FileName, bothDirInfo->FileNameLength) == 0)
3419 if (!bothDirInfo->NextEntryOffset)
3421 bothDirInfo = (FILE_ID_BOTH_DIR_INFO *)(((char *)bothDirInfo) + bothDirInfo->NextEntryOffset);
3424 ok(found, "OpenFileById: failed to find the temp file in the temp folder.\n");
3426 SetLastError(0xdeadbeef);
3427 handle = pOpenFileById(directory, NULL, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0);
3428 ok(handle == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER,
3429 "OpenFileById: expected ERROR_INVALID_PARAMETER, got error %u.\n", GetLastError());
3431 fileIdDescr.dwSize = sizeof(fileIdDescr);
3432 fileIdDescr.Type = FileIdType;
3433 U(fileIdDescr).FileId = bothDirInfo->FileId;
3434 handle = pOpenFileById(directory, &fileIdDescr, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 0);
3435 ok(handle != INVALID_HANDLE_VALUE, "OpenFileById: failed to open the file, got error %u.\n", GetLastError());
3437 ret = ReadFile(handle, buffer, sizeof(buffer), &count, NULL);
3439 ok(ret, "OpenFileById: ReadFile failed, got error %u.\n", GetLastError());
3440 ok(strcmp(tickCount, buffer) == 0, "OpenFileById: invalid contents of the temp file.\n");
3442 CloseHandle(handle);
3443 CloseHandle(directory);
3444 DeleteFile(tempFileName);
3447 static void test_SetFileValidData(void)
3452 char path[MAX_PATH], filename[MAX_PATH];
3453 TOKEN_PRIVILEGES privs;
3454 HANDLE token = NULL;
3456 if (!pSetFileValidData)
3458 win_skip("SetFileValidData is missing\n");
3461 GetTempPathA(sizeof(path), path);
3462 GetTempFileNameA(path, "tst", 0, filename);
3463 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
3464 WriteFile(handle, "test", sizeof("test") - 1, &count, NULL);
3465 CloseHandle(handle);
3467 SetLastError(0xdeadbeef);
3468 ret = pSetFileValidData(INVALID_HANDLE_VALUE, 0);
3469 error = GetLastError();
3470 ok(!ret, "SetFileValidData succeeded\n");
3471 ok(error == ERROR_INVALID_HANDLE, "got %u\n", error);
3473 SetLastError(0xdeadbeef);
3474 ret = pSetFileValidData(INVALID_HANDLE_VALUE, -1);
3475 error = GetLastError();
3476 ok(!ret, "SetFileValidData succeeded\n");
3477 ok(error == ERROR_INVALID_HANDLE, "got %u\n", error);
3479 /* file opened for reading */
3480 handle = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
3482 SetLastError(0xdeadbeef);
3483 ret = pSetFileValidData(handle, 0);
3484 ok(!ret, "SetFileValidData succeeded\n");
3485 error = GetLastError();
3486 ok(error == ERROR_ACCESS_DENIED, "got %u\n", error);
3488 SetLastError(0xdeadbeef);
3489 ret = pSetFileValidData(handle, -1);
3490 error = GetLastError();
3491 ok(!ret, "SetFileValidData succeeded\n");
3492 ok(error == ERROR_ACCESS_DENIED, "got %u\n", error);
3493 CloseHandle(handle);
3495 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
3497 SetLastError(0xdeadbeef);
3498 ret = pSetFileValidData(handle, 0);
3499 error = GetLastError();
3500 ok(!ret, "SetFileValidData succeeded\n");
3501 todo_wine ok(error == ERROR_PRIVILEGE_NOT_HELD, "got %u\n", error);
3502 CloseHandle(handle);
3504 privs.PrivilegeCount = 1;
3505 privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
3507 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token) ||
3508 !LookupPrivilegeValue(NULL, SE_MANAGE_VOLUME_NAME, &privs.Privileges[0].Luid) ||
3509 !AdjustTokenPrivileges(token, FALSE, &privs, sizeof(privs), NULL, NULL))
3511 win_skip("cannot enable SE_MANAGE_VOLUME_NAME privilege\n");
3515 handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
3517 SetLastError(0xdeadbeef);
3518 ret = pSetFileValidData(handle, 0);
3519 error = GetLastError();
3520 ok(!ret, "SetFileValidData succeeded\n");
3521 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3523 SetLastError(0xdeadbeef);
3524 ret = pSetFileValidData(handle, -1);
3525 error = GetLastError();
3526 ok(!ret, "SetFileValidData succeeded\n");
3527 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3529 SetLastError(0xdeadbeef);
3530 ret = pSetFileValidData(handle, 2);
3531 error = GetLastError();
3532 todo_wine ok(!ret, "SetFileValidData succeeded\n");
3533 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3535 ret = pSetFileValidData(handle, 4);
3536 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3538 SetLastError(0xdeadbeef);
3539 ret = pSetFileValidData(handle, 8);
3540 error = GetLastError();
3541 ok(!ret, "SetFileValidData succeeded\n");
3542 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3544 count = SetFilePointer(handle, 1024, NULL, FILE_END);
3545 ok(count != INVALID_SET_FILE_POINTER, "SetFilePointer failed %u\n", GetLastError());
3546 ret = SetEndOfFile(handle);
3547 ok(ret, "SetEndOfFile failed %u\n", GetLastError());
3549 SetLastError(0xdeadbeef);
3550 ret = pSetFileValidData(handle, 2);
3551 error = GetLastError();
3552 todo_wine ok(!ret, "SetFileValidData succeeded\n");
3553 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3555 ret = pSetFileValidData(handle, 4);
3556 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3558 ret = pSetFileValidData(handle, 8);
3559 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3561 ret = pSetFileValidData(handle, 4);
3562 error = GetLastError();
3563 todo_wine ok(!ret, "SetFileValidData succeeded\n");
3564 todo_wine ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3566 ret = pSetFileValidData(handle, 1024);
3567 ok(ret, "SetFileValidData failed %u\n", GetLastError());
3569 ret = pSetFileValidData(handle, 2048);
3570 error = GetLastError();
3571 ok(!ret, "SetFileValidData succeeded\n");
3572 ok(error == ERROR_INVALID_PARAMETER, "got %u\n", error);
3574 privs.Privileges[0].Attributes = 0;
3575 AdjustTokenPrivileges(token, FALSE, &privs, sizeof(privs), NULL, NULL);
3577 DeleteFile(filename);
3582 InitFunctionPointers();
3592 test_GetTempFileNameA();
3602 test_FindFirstFileA();
3603 test_FindNextFileA();
3604 test_FindFirstFileExA(0);
3605 /* FindExLimitToDirectories is ignored if the file system doesn't support directory filtering */
3606 test_FindFirstFileExA(FindExSearchLimitToDirectories);
3608 test_file_sharing();
3609 test_offset_in_overlapped_structure();
3612 test_async_file_errors();
3616 test_RemoveDirectory();
3617 test_ReplaceFileA();
3618 test_ReplaceFileW();
3619 test_GetFileInformationByHandleEx();
3620 test_OpenFileById();
3621 test_SetFileValidData();