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