ReactOS 0.4.17-dev-116-ga4b6fe9
file.c
Go to the documentation of this file.
1/* Unit test suite for Ntdll file functions
2 *
3 * Copyright 2007 Jeff Latimer
4 * Copyright 2007 Andrey Turkin
5 * Copyright 2008 Jeff Zaroyko
6 * Copyright 2011 Dmitry Timoshkov
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 *
22 * NOTES
23 * We use function pointers here as there is no import library for NTDLL on
24 * windows.
25 */
26
27#include <stdio.h>
28#include <stdarg.h>
29
30#include "ntstatus.h"
31/* Define WIN32_NO_STATUS so MSVC does not give us duplicate macro
32 * definition errors when we get to winnt.h
33 */
34#define WIN32_NO_STATUS
35
36#include "wine/test.h"
37#include "winternl.h"
38#include "winuser.h"
39#include "winioctl.h"
40#include "winnls.h"
41
42#ifndef IO_COMPLETION_ALL_ACCESS
43#define IO_COMPLETION_ALL_ACCESS 0x001F0003
44#endif
45
46static BOOL (WINAPI * pGetVolumePathNameW)(LPCWSTR, LPWSTR, DWORD);
47static UINT (WINAPI *pGetSystemWow64DirectoryW)( LPWSTR, UINT );
48
49static VOID (WINAPI *pRtlFreeUnicodeString)( PUNICODE_STRING );
50static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR );
51static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)( LPCWSTR, PUNICODE_STRING, PWSTR*, CURDIR* );
52static NTSTATUS (WINAPI *pRtlWow64EnableFsRedirectionEx)( ULONG, ULONG * );
53
54static NTSTATUS (WINAPI *pNtAllocateReserveObject)( HANDLE *, const OBJECT_ATTRIBUTES *, MEMORY_RESERVE_OBJECT_TYPE );
55static NTSTATUS (WINAPI *pNtCreateMailslotFile)( PHANDLE, ULONG, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
59static NTSTATUS (WINAPI *pNtDeleteFile)(POBJECT_ATTRIBUTES ObjectAttributes);
60static NTSTATUS (WINAPI *pNtReadFile)(HANDLE hFile, HANDLE hEvent,
64static NTSTATUS (WINAPI *pNtWriteFile)(HANDLE hFile, HANDLE hEvent,
67 const void* buffer, ULONG length,
69static NTSTATUS (WINAPI *pNtCancelIoFile)(HANDLE hFile, PIO_STATUS_BLOCK io_status);
71static NTSTATUS (WINAPI *pNtClose)( PHANDLE );
73
74static NTSTATUS (WINAPI *pNtCreateIoCompletion)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG);
75static NTSTATUS (WINAPI *pNtOpenIoCompletion)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
79static NTSTATUS (WINAPI *pNtSetIoCompletion)(HANDLE, ULONG_PTR, ULONG_PTR, NTSTATUS, SIZE_T);
80static NTSTATUS (WINAPI *pNtSetIoCompletionEx)(HANDLE, HANDLE, ULONG_PTR, ULONG_PTR, NTSTATUS, SIZE_T);
82static NTSTATUS (WINAPI *pNtQueryAttributesFile)(const OBJECT_ATTRIBUTES*,FILE_BASIC_INFORMATION*);
83static NTSTATUS (WINAPI *pNtQueryInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS);
86static NTSTATUS (WINAPI *pNtQueryVolumeInformationFile)(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,FS_INFORMATION_CLASS);
87static NTSTATUS (WINAPI *pNtQueryFullAttributesFile)(const OBJECT_ATTRIBUTES*, FILE_NETWORK_OPEN_INFORMATION*);
88static NTSTATUS (WINAPI *pNtFlushBuffersFile)(HANDLE, IO_STATUS_BLOCK*);
90
91static WCHAR fooW[] = {'f','o','o',0};
92
93static inline BOOL is_signaled( HANDLE obj )
94{
96}
97
98#define TEST_BUF_LEN 3
99
101{
104
106 GetTempFileNameA( path, "foo", 0, buffer );
109 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
110 return (handle == INVALID_HANDLE_VALUE) ? 0 : handle;
111}
112
113#define CVALUE_FIRST 0xfffabbcc
114#define CKEY_FIRST 0x1030341
115#define CKEY_SECOND 0x132E46
116
118{
120 ULONG a, req;
121
122 res = pNtQueryIoCompletion( h, IoCompletionBasicInformation, &a, sizeof(a), &req );
123 ok( res == STATUS_SUCCESS, "NtQueryIoCompletion failed: %lx\n", res );
124 if (res != STATUS_SUCCESS) return -1;
125 ok( req == sizeof(a), "Unexpected response size: %lx\n", req );
126 return a;
127}
128
130{
131 int *count = arg;
132
133 trace( "apc called block %p iosb.status %lx iosb.info %Iu\n",
135 (*count)++;
136 ok( !reserved, "reserved is not 0: %lx\n", reserved );
137}
138
139static void create_file_test(void)
140{
141 static const WCHAR systemrootW[] = {'\\','S','y','s','t','e','m','R','o','o','t',
142 '\\','f','a','i','l','i','n','g',0};
143 static const WCHAR questionmarkInvalidNameW[] = {'a','f','i','l','e','?',0};
144 static const WCHAR pipeInvalidNameW[] = {'a','|','b',0};
145 static const WCHAR pathInvalidNtW[] = {'\\','\\','?','\\',0};
146 static const WCHAR pathInvalidNt2W[] = {'\\','?','?','\\',0};
147 static const WCHAR pathInvalidDosW[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0};
148 static const char testdata[] = "Hello World";
151 HANDLE dir, file;
157 char buf[32];
158 DWORD ret;
159
161 pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL );
162 attr.Length = sizeof(attr);
163 attr.RootDirectory = 0;
164 attr.ObjectName = &nameW;
165 attr.Attributes = OBJ_CASE_INSENSITIVE;
166 attr.SecurityDescriptor = NULL;
167 attr.SecurityQualityOfService = NULL;
168
169 /* try various open modes and options on directories */
170 status = pNtCreateFile( &dir, GENERIC_READ|GENERIC_WRITE, &attr, &io, NULL, 0,
172 ok( !status, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
173
174 io.Status = 0xdeadbeef;
175 offset.QuadPart = 0;
176 status = pNtReadFile( dir, NULL, NULL, NULL, &io, buf, sizeof(buf), &offset, NULL );
177 ok( status == STATUS_INVALID_DEVICE_REQUEST || status == STATUS_PENDING, "NtReadFile error %08lx\n", status );
178 if (status == STATUS_PENDING)
179 {
180 ret = WaitForSingleObject( dir, 1000 );
181 ok( ret == WAIT_OBJECT_0, "WaitForSingleObject error %lu\n", ret );
183 "expected STATUS_INVALID_DEVICE_REQUEST, got %08lx\n", io.Status );
184 }
185
186 io.Status = 0xdeadbeef;
187 offset.QuadPart = 0;
188 status = pNtWriteFile( dir, NULL, NULL, NULL, &io, testdata, sizeof(testdata), &offset, NULL);
190 ok( status == STATUS_INVALID_DEVICE_REQUEST || status == STATUS_PENDING, "NtWriteFile error %08lx\n", status );
191 if (status == STATUS_PENDING)
192 {
193 ret = WaitForSingleObject( dir, 1000 );
194 ok( ret == WAIT_OBJECT_0, "WaitForSingleObject error %lu\n", ret );
196 "expected STATUS_INVALID_DEVICE_REQUEST, got %08lx\n", io.Status );
197 }
198
199 CloseHandle( dir );
200
204 "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
205
208 ok( !status, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
209 CloseHandle( dir );
210
213 ok( status == STATUS_INVALID_PARAMETER, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
214
217 ok( status == STATUS_INVALID_PARAMETER, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
218
221 ok( status == STATUS_INVALID_PARAMETER, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
222
224 FILE_OPEN, 0, NULL, 0 );
225 ok( !status, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
226 CloseHandle( dir );
227
229 FILE_CREATE, 0, NULL, 0 );
231 "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
232
234 FILE_OPEN_IF, 0, NULL, 0 );
235 ok( !status, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
236 CloseHandle( dir );
237
239 FILE_SUPERSEDE, 0, NULL, 0 );
241 "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
242
244 FILE_OVERWRITE, 0, NULL, 0 );
246 "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
247
249 FILE_OVERWRITE_IF, 0, NULL, 0 );
251 "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
252
253 pRtlFreeUnicodeString( &nameW );
254
255 pRtlInitUnicodeString( &nameW, systemrootW );
256 attr.Length = sizeof(attr);
257 attr.RootDirectory = NULL;
258 attr.ObjectName = &nameW;
259 attr.Attributes = OBJ_CASE_INSENSITIVE;
260 attr.SecurityDescriptor = NULL;
261 attr.SecurityQualityOfService = NULL;
262 dir = NULL;
263 status = pNtCreateFile( &dir, FILE_APPEND_DATA, &attr, &io, NULL, FILE_ATTRIBUTE_NORMAL, 0,
267 "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
268
269 /* Invalid chars in file/dirnames */
270 pRtlDosPathNameToNtPathName_U(questionmarkInvalidNameW, &nameW, NULL, NULL);
271 attr.ObjectName = &nameW;
272 status = pNtCreateFile(&dir, GENERIC_READ|SYNCHRONIZE, &attr, &io, NULL, 0,
276 "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status);
277
278 status = pNtCreateFile(&file, GENERIC_WRITE|SYNCHRONIZE, &attr, &io, NULL, 0,
279 0, FILE_CREATE,
282 "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status);
283 pRtlFreeUnicodeString(&nameW);
284
285 pRtlDosPathNameToNtPathName_U(pipeInvalidNameW, &nameW, NULL, NULL);
286 attr.ObjectName = &nameW;
287 status = pNtCreateFile(&dir, GENERIC_READ|SYNCHRONIZE, &attr, &io, NULL, 0,
291 "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status);
292
293 status = pNtCreateFile(&file, GENERIC_WRITE|SYNCHRONIZE, &attr, &io, NULL, 0,
294 0, FILE_CREATE,
297 "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status);
298 pRtlFreeUnicodeString(&nameW);
299
300 pRtlInitUnicodeString( &nameW, pathInvalidNtW );
301 status = pNtCreateFile( &dir, GENERIC_READ|SYNCHRONIZE, &attr, &io, NULL, 0,
305 "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
306
307 status = pNtQueryFullAttributesFile( &attr, &info );
309 "query %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
310
311 pRtlInitUnicodeString( &nameW, pathInvalidNt2W );
312 status = pNtCreateFile( &dir, GENERIC_READ|SYNCHRONIZE, &attr, &io, NULL, 0,
316 "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
317
318 status = pNtQueryFullAttributesFile( &attr, &info );
320 "query %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
321
322 pRtlInitUnicodeString( &nameW, pathInvalidDosW );
323 status = pNtCreateFile( &dir, GENERIC_READ|SYNCHRONIZE, &attr, &io, NULL, 0,
327 "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
328
329 status = pNtQueryFullAttributesFile( &attr, &info );
331 "query %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
332}
333
334static void open_file_test(void)
335{
336 static const WCHAR testdirW[] = {'o','p','e','n','f','i','l','e','t','e','s','t',0};
337 static const char testdata[] = "Hello World";
341 BYTE data[1024];
345 UINT i, len;
346 BOOL ret, restart = TRUE;
347 DWORD numbytes;
348
350 pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL );
351 attr.Length = sizeof(attr);
352 attr.RootDirectory = 0;
353 attr.ObjectName = &nameW;
354 attr.Attributes = 0;
355 attr.SecurityDescriptor = NULL;
356 attr.SecurityQualityOfService = NULL;
357 status = pNtOpenFile( &dir, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io,
359 ok( !status, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
360 pRtlFreeUnicodeString( &nameW );
361
362 path[3] = 0; /* root of the drive */
363 pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL );
364 status = pNtOpenFile( &root, GENERIC_READ, &attr, &io,
366 ok( !status, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
367 pRtlFreeUnicodeString( &nameW );
368
369 /* test opening system dir with RootDirectory set to windows dir */
371 while (path[len] == '\\') len++;
372 nameW.Buffer = path + len;
373 nameW.Length = lstrlenW(path + len) * sizeof(WCHAR);
374 attr.RootDirectory = dir;
375 status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io,
377 ok( !status, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
379
380 /* try uppercase name */
381 for (i = len; path[i]; i++) if (path[i] >= 'a' && path[i] <= 'z') path[i] -= 'a' - 'A';
382 status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io,
384 ok( !status, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
386
387 /* try with leading backslash */
388 nameW.Buffer--;
389 nameW.Length += sizeof(WCHAR);
390 status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io,
395 "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
396 if (!status) CloseHandle( handle );
397
398 /* try with empty name */
399 nameW.Length = 0;
400 status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io,
402 ok( !status, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
404 CloseHandle( dir );
405
406 attr.RootDirectory = 0;
407 wcscat( path, L"\\cmd.exe" );
408 pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL );
409 status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io,
411 ok( status == STATUS_NOT_A_DIRECTORY, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
413 status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io,
415 ok( !status, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
417 pRtlFreeUnicodeString( &nameW );
418
419 wcscat( path, L"\\" );
420 pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL );
424 ok( status == STATUS_NOT_A_DIRECTORY, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
426 pRtlFreeUnicodeString( &nameW );
427
428 wcscat( path, L"\\cmd.exe" );
429 pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL );
430 status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io,
432 ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
433 status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io,
435 ok( status == STATUS_OBJECT_PATH_NOT_FOUND, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
436 pRtlFreeUnicodeString( &nameW );
437
439 lstrcatW( path, testdirW );
441
442 pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL );
443 attr.RootDirectory = NULL;
444 status = pNtOpenFile( &dir, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io,
446 ok( !status, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
447 pRtlFreeUnicodeString( &nameW );
448
451 ok( file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError() );
452 numbytes = 0xdeadbeef;
453 ret = WriteFile( file, testdata, sizeof(testdata) - 1, &numbytes, NULL );
454 ok( ret, "WriteFile failed with error %lu\n", GetLastError() );
455 ok( numbytes == sizeof(testdata) - 1, "failed to write all data\n" );
456 CloseHandle( file );
457
458 /* try open by file id */
459
460 while (!pNtQueryDirectoryFile( dir, NULL, NULL, NULL, &io, data, sizeof(data),
462 {
464
465 restart = FALSE;
466
467 if (!info->FileId.QuadPart) continue;
468
469 nameW.Buffer = (WCHAR *)&info->FileId;
470 nameW.Length = sizeof(info->FileId);
471 info->FileName[info->FileNameLength/sizeof(WCHAR)] = 0;
472 attr.RootDirectory = dir;
473 /* We skip 'open' files by not specifying FILE_SHARE_WRITE */
474 status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io,
477 ((info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? FILE_DIRECTORY_FILE : 0) );
478 ok( status == STATUS_SUCCESS, "open %s failed %lx\n", wine_dbgstr_w(info->FileName), status );
479 if (!status)
480 {
481 BYTE buf[sizeof(FILE_ALL_INFORMATION) + MAX_PATH * sizeof(WCHAR)];
482
483 if (!pNtQueryInformationFile( handle, &io, buf, sizeof(buf), FileAllInformation ))
484 {
486
487 /* check that it's the same file/directory */
488
489 /* don't check the size for directories */
490 if (!(info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY))
491 ok( info->EndOfFile.QuadPart == fai->StandardInformation.EndOfFile.QuadPart,
492 "mismatched file size for %s\n", wine_dbgstr_w(info->FileName));
493
494 ok( info->CreationTime.QuadPart == fai->BasicInformation.CreationTime.QuadPart,
495 "mismatched creation time for %s\n", wine_dbgstr_w(info->FileName));
496 }
498
499 /* try same thing from drive root */
500 attr.RootDirectory = root;
501 status = pNtOpenFile( &handle, GENERIC_READ, &attr, &io,
504 ((info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? FILE_DIRECTORY_FILE : 0) );
506 "open %s failed %lx\n", wine_dbgstr_w(info->FileName), status );
507 if (!status) CloseHandle( handle );
508 }
509 }
510
511 CloseHandle( dir );
512 CloseHandle( root );
513
514 pRtlDosPathNameToNtPathName_U( tmpfile, &nameW, NULL, NULL );
515 attr.Length = sizeof(attr);
516 attr.RootDirectory = 0;
517 attr.ObjectName = &nameW;
518 attr.Attributes = OBJ_CASE_INSENSITIVE;
519 attr.SecurityDescriptor = NULL;
520 attr.SecurityQualityOfService = NULL;
521 status = pNtOpenFile( &file, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io,
523 ok( !status, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
524 pRtlFreeUnicodeString( &nameW );
525
526 numbytes = 0xdeadbeef;
527 memset( data, 0, sizeof(data) );
528 ret = ReadFile( file, data, sizeof(data), &numbytes, NULL );
529 ok( ret, "ReadFile failed with error %lu\n", GetLastError() );
530 ok( numbytes == sizeof(testdata) - 1, "failed to read all data\n" );
531 ok( !memcmp( data, testdata, sizeof(testdata) - 1 ), "testdata doesn't match\n" );
532
533 nameW.Length = sizeof(fooW) - sizeof(WCHAR);
534 nameW.Buffer = fooW;
535 attr.RootDirectory = file;
536 attr.ObjectName = &nameW;
537 status = pNtOpenFile( &root, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io,
540 "expected STATUS_OBJECT_PATH_NOT_FOUND, got %08lx\n", status );
541
542 nameW.Length = 0;
543 nameW.Buffer = NULL;
544 attr.RootDirectory = file;
545 attr.ObjectName = &nameW;
546 status = pNtOpenFile( &root, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io,
548 ok( !status, "open %s failed %lx\n", wine_dbgstr_w(tmpfile), status );
549
550 numbytes = SetFilePointer( file, 0, 0, FILE_CURRENT );
551 ok( numbytes == sizeof(testdata) - 1, "SetFilePointer returned %lu\n", numbytes );
552 numbytes = SetFilePointer( root, 0, 0, FILE_CURRENT );
553 ok( numbytes == 0, "SetFilePointer returned %lu\n", numbytes );
554
555 numbytes = 0xdeadbeef;
556 memset( data, 0, sizeof(data) );
557 ret = ReadFile( root, data, sizeof(data), &numbytes, NULL );
558 ok( ret, "ReadFile failed with error %lu\n", GetLastError() );
559 ok( numbytes == sizeof(testdata) - 1, "failed to read all data\n" );
560 ok( !memcmp( data, testdata, sizeof(testdata) - 1 ), "testdata doesn't match\n" );
561
562 numbytes = SetFilePointer( file, 0, 0, FILE_CURRENT );
563 ok( numbytes == sizeof(testdata) - 1, "SetFilePointer returned %lu\n", numbytes );
564 numbytes = SetFilePointer( root, 0, 0, FILE_CURRENT );
565 ok( numbytes == sizeof(testdata) - 1, "SetFilePointer returned %lu\n", numbytes );
566
567 CloseHandle( file );
568 CloseHandle( root );
571}
572
573static void delete_file_test(void)
574{
579 WCHAR pathsubW[MAX_PATH];
580 static const WCHAR testdirW[] = {'n','t','d','e','l','e','t','e','f','i','l','e',0};
581 static const WCHAR subdirW[] = {'\\','s','u','b',0};
582
584 if (!ret)
585 {
586 ok(0, "couldn't get temp dir\n");
587 return;
588 }
589 if (ret + ARRAY_SIZE(testdirW)-1 + ARRAY_SIZE(subdirW)-1 >= MAX_PATH)
590 {
591 ok(0, "MAX_PATH exceeded in constructing paths\n");
592 return;
593 }
594
595 lstrcatW(pathW, testdirW);
596 lstrcpyW(pathsubW, pathW);
597 lstrcatW(pathsubW, subdirW);
598
600 ok(ret == TRUE, "couldn't create directory ntdeletefile\n");
601 if (!pRtlDosPathNameToNtPathName_U(pathW, &nameW, NULL, NULL))
602 {
603 ok(0,"RtlDosPathNametoNtPathName_U failed\n");
604 return;
605 }
606
607 attr.Length = sizeof(attr);
608 attr.RootDirectory = 0;
609 attr.Attributes = OBJ_CASE_INSENSITIVE;
610 attr.ObjectName = &nameW;
611 attr.SecurityDescriptor = NULL;
612 attr.SecurityQualityOfService = NULL;
613
614 /* test NtDeleteFile on an empty directory */
615 ret = pNtDeleteFile(&attr);
616 ok(ret == STATUS_SUCCESS, "NtDeleteFile should succeed in removing an empty directory\n");
618 ok(ret == FALSE, "expected to fail removing directory, NtDeleteFile should have removed it\n");
619
620 /* test NtDeleteFile on a non-empty directory */
622 ok(ret == TRUE, "couldn't create directory ntdeletefile ?!\n");
623 ret = CreateDirectoryW(pathsubW, NULL);
624 ok(ret == TRUE, "couldn't create directory subdir\n");
625 ret = pNtDeleteFile(&attr);
626 ok(ret == STATUS_SUCCESS, "expected NtDeleteFile to ret STATUS_SUCCESS\n");
627 ret = RemoveDirectoryW(pathsubW);
628 ok(ret == TRUE, "expected to remove directory ntdeletefile\\sub\n");
630 ok(ret == TRUE, "expected to remove directory ntdeletefile, NtDeleteFile failed.\n");
631
632 pRtlFreeUnicodeString( &nameW );
633}
634
635#define TEST_OVERLAPPED_READ_SIZE 4096
636
637static void read_file_test(void)
638{
639 DECLSPEC_ALIGN(TEST_OVERLAPPED_READ_SIZE) static unsigned char aligned_buffer[TEST_OVERLAPPED_READ_SIZE];
640 const char text[] = "foobar";
644 int apc_count = 0;
645 char buffer[128];
647 HANDLE event = CreateEventA( NULL, TRUE, FALSE, NULL );
648
649 if (!(handle = create_temp_file( FILE_FLAG_OVERLAPPED ))) return;
650 apc_count = 0;
651 iosb.Status = 0xdeadbabe;
652 iosb.Information = 0xdeadbeef;
653 offset.QuadPart = 0;
654 ResetEvent( event );
655 status = pNtWriteFile( handle, event, apc, &apc_count, &iosb, text, strlen(text), &offset, NULL );
656 ok( status == STATUS_PENDING || broken(status == STATUS_SUCCESS) /* before Vista */,
657 "wrong status %lx.\n", status );
659 ok( iosb.Status == STATUS_SUCCESS, "wrong status %lx\n", iosb.Status );
660 ok( iosb.Information == strlen(text), "wrong info %Iu\n", iosb.Information );
661 ok( is_signaled( event ), "event is not signaled\n" );
662 ok( !apc_count, "apc was called\n" );
663 SleepEx( 1, TRUE ); /* alertable sleep */
664 ok( apc_count == 1, "apc was not called\n" );
665
666 apc_count = 0;
667 iosb.Status = 0xdeadbabe;
668 iosb.Information = 0xdeadbeef;
669 offset.QuadPart = 0;
670 ResetEvent( event );
671 status = pNtReadFile( handle, event, apc, &apc_count, &iosb, buffer, strlen(text) + 10, &offset, NULL );
673 || broken(status == STATUS_SUCCESS) /* before Vista */,
674 "wrong status %lx.\n", status);
676 ok( iosb.Status == STATUS_SUCCESS, "wrong status %lx\n", iosb.Status );
677 ok( iosb.Information == strlen(text), "wrong info %Iu\n", iosb.Information );
678 ok( is_signaled( event ), "event is not signaled\n" );
679 ok( !apc_count, "apc was called\n" );
680 SleepEx( 1, TRUE ); /* alertable sleep */
681 ok( apc_count == 1, "apc was not called\n" );
682
683 /* read beyond eof */
684 apc_count = 0;
685 iosb.Status = 0xdeadbabe;
686 iosb.Information = 0xdeadbeef;
687 offset.QuadPart = strlen(text) + 2;
688 status = pNtReadFile( handle, event, apc, &apc_count, &iosb, buffer, 2, &offset, NULL );
689 ok(status == STATUS_PENDING || broken(status == STATUS_END_OF_FILE) /* before Vista */,
690 "expected STATUS_PENDING, got %#lx\n", status);
691 if (status == STATUS_PENDING) /* vista */
692 {
693 WaitForSingleObject( event, 1000 );
694 ok( iosb.Status == STATUS_END_OF_FILE, "wrong status %lx\n", iosb.Status );
695 ok( iosb.Information == 0, "wrong info %Iu\n", iosb.Information );
696 ok( is_signaled( event ), "event is not signaled\n" );
697 ok( !apc_count, "apc was called\n" );
698 SleepEx( 1, TRUE ); /* alertable sleep */
699 ok( apc_count == 1, "apc was not called\n" );
700 }
702
703 /* now a non-overlapped file */
704 if (!(handle = create_temp_file(0))) return;
705 apc_count = 0;
706 iosb.Status = 0xdeadbabe;
707 iosb.Information = 0xdeadbeef;
708 offset.QuadPart = 0;
709 status = pNtWriteFile( handle, event, apc, &apc_count, &iosb, text, strlen(text), &offset, NULL );
712 status == STATUS_PENDING, /* vista */
713 "wrong status %lx\n", status );
715 ok( iosb.Status == STATUS_SUCCESS, "wrong status %lx\n", iosb.Status );
716 ok( iosb.Information == strlen(text), "wrong info %Iu\n", iosb.Information );
717 ok( is_signaled( event ), "event is not signaled\n" );
718 ok( !apc_count, "apc was called\n" );
719 SleepEx( 1, TRUE ); /* alertable sleep */
720 ok( apc_count == 1, "apc was not called\n" );
721
722 apc_count = 0;
723 iosb.Status = 0xdeadbabe;
724 iosb.Information = 0xdeadbeef;
725 offset.QuadPart = 0;
726 ResetEvent( event );
727 status = pNtReadFile( handle, event, apc, &apc_count, &iosb, buffer, strlen(text) + 10, &offset, NULL );
728 ok( status == STATUS_SUCCESS, "wrong status %lx\n", status );
729 ok( iosb.Status == STATUS_SUCCESS, "wrong status %lx\n", iosb.Status );
730 ok( iosb.Information == strlen(text), "wrong info %Iu\n", iosb.Information );
731 ok( is_signaled( event ), "event is not signaled\n" );
732 ok( !apc_count, "apc was called\n" );
733 SleepEx( 1, TRUE ); /* alertable sleep */
734 todo_wine ok( !apc_count, "apc was called\n" );
735
736 /* read beyond eof */
737 apc_count = 0;
738 iosb.Status = 0xdeadbabe;
739 iosb.Information = 0xdeadbeef;
740 offset.QuadPart = strlen(text) + 2;
741 ResetEvent( event );
742 status = pNtReadFile( handle, event, apc, &apc_count, &iosb, buffer, 2, &offset, NULL );
743 ok( status == STATUS_END_OF_FILE, "wrong status %lx\n", status );
744 ok( iosb.Status == STATUS_END_OF_FILE, "wrong status %lx\n", iosb.Status );
745 ok( iosb.Information == 0, "wrong info %Iu\n", iosb.Information );
746 ok( is_signaled( event ), "event is not signaled\n" );
747 ok( !apc_count, "apc was called\n" );
748 SleepEx( 1, TRUE ); /* alertable sleep */
749 ok( !apc_count, "apc was called\n" );
750
752
754 return;
755
756 apc_count = 0;
757 offset.QuadPart = 0;
758 iosb.Status = 0xdeadbabe;
759 iosb.Information = 0xdeadbeef;
760 offset.QuadPart = 0;
762 status = pNtWriteFile(handle, event, apc, &apc_count, &iosb,
763 aligned_buffer, sizeof(aligned_buffer), &offset, NULL);
765 || broken(status == STATUS_SUCCESS) /* before Vista */,
766 "Wrong status %lx.\n", status);
767 ok(iosb.Status == STATUS_SUCCESS, "Wrong status %lx.\n", iosb.Status);
768 ok(iosb.Information == sizeof(aligned_buffer), "Wrong info %Iu.\n", iosb.Information);
769 ok(is_signaled(event), "event is not signaled.\n");
770 ok(!apc_count, "apc was called.\n");
771 SleepEx(1, TRUE); /* alertable sleep */
772 ok(apc_count == 1, "apc was not called.\n");
773
774 apc_count = 0;
775 offset.QuadPart = 0;
776 iosb.Status = 0xdeadbabe;
777 iosb.Information = 0xdeadbeef;
778 offset.QuadPart = 0;
780 status = pNtReadFile(handle, event, apc, &apc_count, &iosb,
781 aligned_buffer, sizeof(aligned_buffer), &offset, NULL);
782 ok(status == STATUS_PENDING, "Wrong status %lx.\n", status);
784 ok(iosb.Status == STATUS_SUCCESS, "Wrong status %lx.\n", iosb.Status);
785 ok(iosb.Information == sizeof(aligned_buffer), "Wrong info %Iu.\n", iosb.Information);
786 ok(is_signaled(event), "event is not signaled.\n");
787 ok(!apc_count, "apc was called.\n");
788 SleepEx(1, TRUE); /* alertable sleep */
789 ok(apc_count == 1, "apc was not called.\n");
790
793}
794
795static void append_file_test(void)
796{
797 static const char text[6] = "foobar";
802 char path[MAX_PATH], buffer[MAX_PATH], buf[16];
803 DWORD ret;
804
806 GetTempFileNameA( path, "foo", 0, buffer );
807
809 ok(handle != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
810
811 iosb.Status = -1;
812 iosb.Information = -1;
813 status = pNtWriteFile(handle, NULL, NULL, NULL, &iosb, text, 2, NULL, NULL);
814 ok(status == STATUS_SUCCESS, "NtWriteFile error %#lx\n", status);
815 ok(iosb.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iosb.Status);
816 ok(iosb.Information == 2, "expected 2, got %Iu\n", iosb.Information);
817
819
820 /* It is possible to open a file with only FILE_APPEND_DATA access flags.
821 It matches the O_WRONLY|O_APPEND open() posix behavior */
823 ok(handle != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
824
825 iosb.Status = -1;
826 iosb.Information = -1;
827 offset.QuadPart = 1;
828 status = pNtWriteFile(handle, NULL, NULL, NULL, &iosb, text + 2, 2, &offset, NULL);
829 ok(status == STATUS_SUCCESS, "NtWriteFile error %#lx\n", status);
830 ok(iosb.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iosb.Status);
831 ok(iosb.Information == 2, "expected 2, got %Iu\n", iosb.Information);
832
834 ok(ret == 4, "expected 4, got %lu\n", ret);
835
836 iosb.Status = -1;
837 iosb.Information = -1;
838 offset.QuadPart = 3;
839 status = pNtWriteFile(handle, NULL, NULL, NULL, &iosb, text + 4, 2, &offset, NULL);
840 ok(status == STATUS_SUCCESS, "NtWriteFile error %#lx\n", status);
841 ok(iosb.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iosb.Status);
842 ok(iosb.Information == 2, "expected 2, got %Iu\n", iosb.Information);
843
845 ok(ret == 6, "expected 6, got %lu\n", ret);
846
848
850 ok(handle != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
851
852 memset(buf, 0, sizeof(buf));
853 iosb.Status = -1;
854 iosb.Information = -1;
855 offset.QuadPart = 0;
856 status = pNtReadFile(handle, 0, NULL, NULL, &iosb, buf, sizeof(buf), &offset, NULL);
857 ok(status == STATUS_SUCCESS, "NtReadFile error %#lx\n", status);
858 ok(iosb.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iosb.Status);
859 ok(iosb.Information == 6, "expected 6, got %Iu\n", iosb.Information);
860 buf[6] = 0;
861 ok(memcmp(buf, text, 6) == 0, "wrong file contents: %s\n", buf);
862
863 iosb.Status = -1;
864 iosb.Information = -1;
865 offset.QuadPart = 0;
866 status = pNtWriteFile(handle, NULL, NULL, NULL, &iosb, text + 3, 3, &offset, NULL);
867 ok(status == STATUS_SUCCESS, "NtWriteFile error %#lx\n", status);
868 ok(iosb.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iosb.Status);
869 ok(iosb.Information == 3, "expected 3, got %Iu\n", iosb.Information);
870
871 memset(buf, 0, sizeof(buf));
872 iosb.Status = -1;
873 iosb.Information = -1;
874 offset.QuadPart = 0;
875 status = pNtReadFile(handle, 0, NULL, NULL, &iosb, buf, sizeof(buf), &offset, NULL);
876 ok(status == STATUS_SUCCESS, "NtReadFile error %#lx\n", status);
877 ok(iosb.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iosb.Status);
878 ok(iosb.Information == 6, "expected 6, got %Iu\n", iosb.Information);
879 buf[6] = 0;
880 ok(memcmp(buf, "barbar", 6) == 0, "wrong file contents: %s\n", buf);
881
884}
885
886static void nt_mailslot_test(void)
887{
888 HANDLE hslot;
891
893 ULONG MailslotQuota;
894 ULONG MaxMessageSize;
895 LARGE_INTEGER TimeOut;
897 NTSTATUS rc;
899 WCHAR buffer1[] = { '\\','?','?','\\','M','A','I','L','S','L','O','T','\\',
900 'R',':','\\','F','R','E','D','\0' };
901
902 TimeOut.QuadPart = -1;
903
904 pRtlInitUnicodeString(&str, buffer1);
906 CreateOptions = MailslotQuota = MaxMessageSize = 0;
908
909 /*
910 * Check for NULL pointer handling
911 */
912 rc = pNtCreateMailslotFile(NULL, DesiredAccess,
913 &attr, &IoStatusBlock, CreateOptions, MailslotQuota, MaxMessageSize,
914 &TimeOut);
916 rc == STATUS_INVALID_PARAMETER, /* win2k3 */
917 "rc = %lx not STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER\n", rc);
918
919 /*
920 * Test to see if the Timeout can be NULL
921 */
922 hslot = (HANDLE)0xdeadbeef;
923 rc = pNtCreateMailslotFile(&hslot, DesiredAccess,
924 &attr, &IoStatusBlock, CreateOptions, MailslotQuota, MaxMessageSize,
925 NULL);
926 ok( rc == STATUS_SUCCESS ||
927 rc == STATUS_INVALID_PARAMETER, /* win2k3 */
928 "rc = %lx not STATUS_SUCCESS or STATUS_INVALID_PARAMETER\n", rc);
929 ok( hslot != 0, "Handle is invalid\n");
930
931 if ( rc == STATUS_SUCCESS ) pNtClose(hslot);
932
933 /*
934 * Test a valid call
935 */
937 rc = pNtCreateMailslotFile(&hslot, DesiredAccess,
938 &attr, &IoStatusBlock, CreateOptions, MailslotQuota, MaxMessageSize,
939 &TimeOut);
940 ok( rc == STATUS_SUCCESS, "Create MailslotFile failed rc = %lx\n", rc);
941 ok( hslot != 0, "Handle is invalid\n");
942
943 rc = pNtClose(hslot);
944 ok( rc == STATUS_SUCCESS, "NtClose failed\n");
945}
946
948{
949 unsigned int *apc_count = (unsigned int *)arg;
950 ++*apc_count;
951}
952
953static void test_set_io_completion(void)
954{
956 LARGE_INTEGER timeout = {{0}};
957 unsigned int apc_count;
961 ULONG count;
962 SIZE_T size = 3;
963 HANDLE h, h2;
964
965#ifdef __REACTOS__
966 if (!pNtSetIoCompletionEx)
967 {
968 win_skip("NtSetIoCompletionEx() is unavailable.\n");
969 return;
970 }
971#endif
972
973 if (sizeof(size) > 4) size |= (ULONGLONG)0x12345678 << 32;
974
975 res = pNtCreateIoCompletion( &h2, IO_COMPLETION_ALL_ACCESS, NULL, 0 );
976 ok( res == STATUS_SUCCESS, "NtCreateIoCompletion failed: %#lx\n", res );
977 ok( h2 && h2 != INVALID_HANDLE_VALUE, "got invalid handle %p\n", h2 );
978 res = pNtSetIoCompletion( h2, 123, 456, 789, size );
979 ok( res == STATUS_SUCCESS, "NtSetIoCompletion failed: %#lx\n", res );
980 res = pNtRemoveIoCompletionEx( h2, info, 2, &count, &timeout, TRUE );
981 ok( res == STATUS_SUCCESS, "NtRemoveIoCompletionEx failed: %#lx\n", res );
982 ok( count == 1, "wrong count %lu\n", count );
983
984 res = pNtCreateIoCompletion( &h, IO_COMPLETION_ALL_ACCESS, NULL, 0 );
985 ok( res == STATUS_SUCCESS, "NtCreateIoCompletion failed: %#lx\n", res );
986 ok( h && h != INVALID_HANDLE_VALUE, "got invalid handle %p\n", h );
987
988 apc_count = 0;
990 res = pNtSetIoCompletion( h, 123, 456, 789, size );
991 ok( res == STATUS_SUCCESS, "NtSetIoCompletion failed: %#lx\n", res );
992 res = pNtRemoveIoCompletionEx( h, info, 2, &count, &timeout, TRUE );
993 /* APC goes first associated with completion port APC takes priority over pending completion.
994 * Even if the thread is associated with some other completion port. */
995 ok( res == STATUS_USER_APC, "NtRemoveIoCompletionEx unexpected status %#lx\n", res );
996 ok( apc_count == 1, "wrong apc count %u\n", apc_count );
997
998 CloseHandle( h2 );
999
1000 apc_count = 0;
1002 res = pNtRemoveIoCompletionEx( h, info, 2, &count, &timeout, TRUE );
1003 /* Previous call resulted in STATUS_USER_APC did not associate the thread with the port. */
1004 ok( res == STATUS_USER_APC, "NtRemoveIoCompletion unexpected status %#lx\n", res );
1005 ok( apc_count == 1, "wrong apc count %u\n", apc_count );
1006
1007 res = pNtRemoveIoCompletionEx( h, info, 2, &count, &timeout, TRUE );
1008 /* Now the thread is associated. */
1009 ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %#lx\n", res );
1010 ok( count == 1, "wrong count %lu\n", count );
1011
1012 apc_count = 0;
1014 res = pNtSetIoCompletion( h, 123, 456, 789, size );
1015 ok( res == STATUS_SUCCESS, "NtSetIoCompletion failed: %#lx\n", res );
1016 res = pNtRemoveIoCompletionEx( h, info, 2, &count, &timeout, TRUE );
1017 /* After a thread is associated with completion port existing completion is returned if APC is pending. */
1018 ok( res == STATUS_SUCCESS, "NtRemoveIoCompletionEx failed: %#lx\n", res );
1019 ok( count == 1, "wrong count %lu\n", count );
1020 ok( apc_count == 0, "wrong apc count %u\n", apc_count );
1021 SleepEx( 0, TRUE);
1022 ok( apc_count == 1, "wrong apc count %u\n", apc_count );
1023
1024 res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout );
1025 ok( res == STATUS_TIMEOUT, "NtRemoveIoCompletion failed: %#lx\n", res );
1026
1027 res = pNtSetIoCompletion( h, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size );
1028 ok( res == STATUS_SUCCESS, "NtSetIoCompletion failed: %lx\n", res );
1029
1031 ok( count == 1, "Unexpected msg count: %ld\n", count );
1032
1033 res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout );
1034 ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %#lx\n", res );
1035 ok( key == CKEY_FIRST, "Invalid completion key: %#Ix\n", key );
1036 ok( iosb.Information == size, "Invalid iosb.Information: %Iu\n", iosb.Information );
1037 ok( iosb.Status == STATUS_INVALID_DEVICE_REQUEST, "Invalid iosb.Status: %#lx\n", iosb.Status );
1038 ok( value == CVALUE_FIRST, "Invalid completion value: %#Ix\n", value );
1039
1041 ok( !count, "Unexpected msg count: %ld\n", count );
1042
1043 if (!pNtRemoveIoCompletionEx)
1044 {
1045 skip("NtRemoveIoCompletionEx() not present\n");
1046 pNtClose( h );
1047 return;
1048 }
1049
1050 count = 0xdeadbeef;
1051 res = pNtRemoveIoCompletionEx( h, info, 2, &count, &timeout, FALSE );
1052 ok( res == STATUS_TIMEOUT, "NtRemoveIoCompletionEx failed: %#lx\n", res );
1053 ok( count <= 1, "wrong count %lu\n", count );
1054
1055 res = pNtSetIoCompletion( h, 123, 456, 789, size );
1056 ok( res == STATUS_SUCCESS, "NtSetIoCompletion failed: %#lx\n", res );
1057
1058 count = 0xdeadbeef;
1059 res = pNtRemoveIoCompletionEx( h, info, 2, &count, &timeout, FALSE );
1060 ok( res == STATUS_SUCCESS, "NtRemoveIoCompletionEx failed: %#lx\n", res );
1061 ok( count == 1, "wrong count %lu\n", count );
1062 ok( info[0].CompletionKey == 123, "wrong key %#Ix\n", info[0].CompletionKey );
1063 ok( info[0].CompletionValue == 456, "wrong value %#Ix\n", info[0].CompletionValue );
1064 ok( info[0].IoStatusBlock.Information == size, "wrong information %#Ix\n",
1065 info[0].IoStatusBlock.Information );
1066 ok( info[0].IoStatusBlock.Status == 789, "wrong status %#lx\n", info[0].IoStatusBlock.Status);
1067
1068 res = pNtSetIoCompletion( h, 123, 456, 789, size );
1069 ok( res == STATUS_SUCCESS, "NtSetIoCompletion failed: %#lx\n", res );
1070
1071 res = pNtSetIoCompletion( h, 12, 34, 56, size );
1072 ok( res == STATUS_SUCCESS, "NtSetIoCompletion failed: %#lx\n", res );
1073
1074 count = 0xdeadbeef;
1075 res = pNtRemoveIoCompletionEx( h, info, 2, &count, &timeout, FALSE );
1076 ok( res == STATUS_SUCCESS, "NtRemoveIoCompletionEx failed: %#lx\n", res );
1077 ok( count == 2, "wrong count %lu\n", count );
1078 ok( info[0].CompletionKey == 123, "wrong key %#Ix\n", info[0].CompletionKey );
1079 ok( info[0].CompletionValue == 456, "wrong value %#Ix\n", info[0].CompletionValue );
1080 ok( info[0].IoStatusBlock.Information == size, "wrong information %#Ix\n",
1081 info[0].IoStatusBlock.Information );
1082 ok( info[0].IoStatusBlock.Status == 789, "wrong status %#lx\n", info[0].IoStatusBlock.Status);
1083 ok( info[1].CompletionKey == 12, "wrong key %#Ix\n", info[1].CompletionKey );
1084 ok( info[1].CompletionValue == 34, "wrong value %#Ix\n", info[1].CompletionValue );
1085 ok( info[1].IoStatusBlock.Information == size, "wrong information %#Ix\n",
1086 info[1].IoStatusBlock.Information );
1087 ok( info[1].IoStatusBlock.Status == 56, "wrong status %#lx\n", info[1].IoStatusBlock.Status);
1088
1089 res = pNtSetIoCompletion( h, 123, 456, 789, size );
1090 ok( res == STATUS_SUCCESS, "NtSetIoCompletion failed: %#lx\n", res );
1091
1092 res = pNtSetIoCompletion( h, 12, 34, 56, size );
1093 ok( res == STATUS_SUCCESS, "NtSetIoCompletion failed: %#lx\n", res );
1094
1095 count = 0xdeadbeef;
1096 res = pNtRemoveIoCompletionEx( h, info, 1, &count, NULL, FALSE );
1097 ok( res == STATUS_SUCCESS, "NtRemoveIoCompletionEx failed: %#lx\n", res );
1098 ok( count == 1, "wrong count %lu\n", count );
1099 ok( info[0].CompletionKey == 123, "wrong key %#Ix\n", info[0].CompletionKey );
1100 ok( info[0].CompletionValue == 456, "wrong value %#Ix\n", info[0].CompletionValue );
1101 ok( info[0].IoStatusBlock.Information == size, "wrong information %#Ix\n",
1102 info[0].IoStatusBlock.Information );
1103 ok( info[0].IoStatusBlock.Status == 789, "wrong status %#lx\n", info[0].IoStatusBlock.Status);
1104
1105 count = 0xdeadbeef;
1106 res = pNtRemoveIoCompletionEx( h, info, 1, &count, NULL, FALSE );
1107 ok( res == STATUS_SUCCESS, "NtRemoveIoCompletionEx failed: %#lx\n", res );
1108 ok( count == 1, "wrong count %lu\n", count );
1109 ok( info[0].CompletionKey == 12, "wrong key %#Ix\n", info[0].CompletionKey );
1110 ok( info[0].CompletionValue == 34, "wrong value %#Ix\n", info[0].CompletionValue );
1111 ok( info[0].IoStatusBlock.Information == size, "wrong information %#Ix\n",
1112 info[0].IoStatusBlock.Information );
1113 ok( info[0].IoStatusBlock.Status == 56, "wrong status %#lx\n", info[0].IoStatusBlock.Status);
1114
1115 apc_count = 0;
1117
1118 count = 0xdeadbeef;
1119 res = pNtRemoveIoCompletionEx( h, info, 2, &count, &timeout, FALSE );
1120 ok( res == STATUS_TIMEOUT, "NtRemoveIoCompletionEx failed: %#lx\n", res );
1121 ok( count <= 1, "wrong count %lu\n", count );
1122 ok( !apc_count, "wrong apc count %d\n", apc_count );
1123
1124 res = pNtRemoveIoCompletionEx( h, info, 2, &count, &timeout, TRUE );
1125 ok( res == STATUS_USER_APC, "NtRemoveIoCompletionEx failed: %#lx\n", res );
1126 ok( count <= 1, "wrong count %lu\n", count );
1127 ok( apc_count == 1, "wrong apc count %u\n", apc_count );
1128
1129 apc_count = 0;
1131
1132 res = pNtSetIoCompletion( h, 123, 456, 789, size );
1133 ok( res == STATUS_SUCCESS, "NtSetIoCompletion failed: %#lx\n", res );
1134
1135 res = pNtRemoveIoCompletionEx( h, info, 2, &count, &timeout, TRUE );
1136 ok( res == STATUS_SUCCESS, "NtRemoveIoCompletionEx failed: %#lx\n", res );
1137 ok( count == 1, "wrong count %lu\n", count );
1138 ok( !apc_count, "wrong apc count %u\n", apc_count );
1139
1140 SleepEx( 1, TRUE );
1141
1142 pNtClose( h );
1143}
1144
1146{
1147 static const char pipe_name[] = "\\\\.\\pipe\\iocompletiontestnamedpipe";
1148
1152 LARGE_INTEGER timeout = {{0}};
1155 OVERLAPPED o = {0};
1156 int apc_count = 0;
1157 NTSTATUS res;
1158 DWORD read;
1159 long count;
1160 HANDLE h;
1161
1162 res = pNtCreateIoCompletion( &h, IO_COMPLETION_ALL_ACCESS, NULL, 0 );
1163 ok( res == STATUS_SUCCESS, "NtCreateIoCompletion failed: %#lx\n", res );
1164 ok( h && h != INVALID_HANDLE_VALUE, "got invalid handle %p\n", h );
1165 fci.CompletionPort = h;
1167
1170 4, 1024, 1024, 1000, NULL );
1171 ok( server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %lu\n", GetLastError() );
1174 ok( client != INVALID_HANDLE_VALUE, "CreateFile failed: %lu\n", GetLastError() );
1175
1176 iosb.Status = 0xdeadbeef;
1177 res = pNtSetInformationFile( server, &iosb, &fci, sizeof(fci), FileCompletionInformation );
1178 ok( res == STATUS_INVALID_PARAMETER, "NtSetInformationFile failed: %#lx\n", res );
1179 todo_wine
1180 ok( iosb.Status == 0xdeadbeef, "wrong status %#lx\n", iosb.Status );
1183
1186 4, 1024, 1024, 1000, NULL );
1187 ok( server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %lu\n", GetLastError() );
1190 ok( client != INVALID_HANDLE_VALUE, "CreateFile failed: %lu\n", GetLastError() );
1191
1192 iosb.Status = 0xdeadbeef;
1193 res = pNtSetInformationFile( server, &iosb, &fci, sizeof(fci), FileCompletionInformation );
1194 ok( res == STATUS_SUCCESS, "NtSetInformationFile failed: %#lx\n", res );
1195 ok( iosb.Status == STATUS_SUCCESS, "wrong status %#lx\n", iosb.Status );
1196
1198 memset( recv_buf, 0xde, TEST_BUF_LEN );
1200 ok( !count, "Unexpected msg count: %ld\n", count );
1201 ReadFile( server, recv_buf, TEST_BUF_LEN, &read, &o);
1203 ok( !count, "Unexpected msg count: %ld\n", count );
1205
1206 res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout );
1207 ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %#lx\n", res );
1208 ok( key == CKEY_SECOND, "Invalid completion key: %#Ix\n", key );
1209 ok( iosb.Information == 3, "Invalid iosb.Information: %Id\n", iosb.Information );
1210 ok( iosb.Status == STATUS_SUCCESS, "Invalid iosb.Status: %#lx\n", iosb.Status );
1211 ok( value == (ULONG_PTR)&o, "Invalid completion value: %#Ix\n", value );
1212 ok( !memcmp( send_buf, recv_buf, TEST_BUF_LEN ),
1213 "Receive buffer (%02x %02x %02x) did not match send buffer (%02x %02x %02x)\n",
1214 recv_buf[0], recv_buf[1], recv_buf[2], send_buf[0], send_buf[1], send_buf[2] );
1216 ok( !count, "Unexpected msg count: %ld\n", count );
1217
1219 memset( recv_buf, 0xde, TEST_BUF_LEN );
1220 WriteFile( client, send_buf, 2, &read, NULL );
1222 ok( !count, "Unexpected msg count: %ld\n", count );
1223 ReadFile( server, recv_buf, 2, &read, &o);
1225 ok( count == 1, "Unexpected msg count: %ld\n", count );
1226
1227 res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout );
1228 ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %#lx\n", res );
1229 ok( key == CKEY_SECOND, "Invalid completion key: %#Ix\n", key );
1230 ok( iosb.Information == 2, "Invalid iosb.Information: %Id\n", iosb.Information );
1231 ok( iosb.Status == STATUS_SUCCESS, "Invalid iosb.Status: %#lx\n", iosb.Status );
1232 ok( value == (ULONG_PTR)&o, "Invalid completion value: %#Ix\n", value );
1233 ok( !memcmp( send_buf, recv_buf, 2 ),
1234 "Receive buffer (%02x %02x) did not match send buffer (%02x %02x)\n",
1235 recv_buf[0], recv_buf[1], send_buf[0], send_buf[1] );
1236
1237 ReadFile( server, recv_buf, TEST_BUF_LEN, &read, &o);
1240 ok( count == 1, "Unexpected msg count: %ld\n", count );
1241
1242 res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout );
1243 ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %#lx\n", res );
1244 ok( key == CKEY_SECOND, "Invalid completion key: %Ix\n", key );
1245 ok( iosb.Information == 0, "Invalid iosb.Information: %Id\n", iosb.Information );
1246 ok( iosb.Status == STATUS_PIPE_BROKEN, "Invalid iosb.Status: %lx\n", iosb.Status );
1247 ok( value == (ULONG_PTR)&o, "Invalid completion value: %Ix\n", value );
1248
1250
1251 /* test associating a completion port with a handle after an async is queued */
1254 4, 1024, 1024, 1000, NULL );
1255 ok( server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %lu\n", GetLastError() );
1258 ok( client != INVALID_HANDLE_VALUE, "CreateFile failed: %lu\n", GetLastError() );
1259
1261 memset( recv_buf, 0xde, TEST_BUF_LEN );
1263 ok( !count, "Unexpected msg count: %ld\n", count );
1264 ReadFile( server, recv_buf, TEST_BUF_LEN, &read, &o);
1265
1266 iosb.Status = 0xdeadbeef;
1267 res = pNtSetInformationFile( server, &iosb, &fci, sizeof(fci), FileCompletionInformation );
1268 ok( res == STATUS_SUCCESS, "NtSetInformationFile failed: %lx\n", res );
1269 ok( iosb.Status == STATUS_SUCCESS, "iosb.Status invalid: %lx\n", iosb.Status );
1271 ok( !count, "Unexpected msg count: %ld\n", count );
1272
1274
1275 res = pNtRemoveIoCompletion( h, &key, &value, &iosb, &timeout );
1276 ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %#lx\n", res );
1277 ok( key == CKEY_SECOND, "Invalid completion key: %#Ix\n", key );
1278 ok( iosb.Information == 3, "Invalid iosb.Information: %Id\n", iosb.Information );
1279 ok( iosb.Status == STATUS_SUCCESS, "Invalid iosb.Status: %#lx\n", iosb.Status );
1280 ok( value == (ULONG_PTR)&o, "Invalid completion value: %#Ix\n", value );
1281 ok( !memcmp( send_buf, recv_buf, TEST_BUF_LEN ),
1282 "Receive buffer (%02x %02x %02x) did not match send buffer (%02x %02x %02x)\n",
1283 recv_buf[0], recv_buf[1], recv_buf[2], send_buf[0], send_buf[1], send_buf[2] );
1284
1286 ok( !count, "Unexpected msg count: %ld\n", count );
1287
1288 /* using APCs on handle with associated completion port is not allowed */
1289 res = pNtReadFile( server, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL );
1290 ok(res == STATUS_INVALID_PARAMETER, "NtReadFile returned %lx\n", res);
1291
1294
1295 /* test associating a completion port with a handle after an async using APC is queued */
1298 4, 1024, 1024, 1000, NULL );
1299 ok( server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %lu\n", GetLastError() );
1302 ok( client != INVALID_HANDLE_VALUE, "CreateFile failed: %lu\n", GetLastError() );
1303
1304 apc_count = 0;
1306 memset( recv_buf, 0xde, TEST_BUF_LEN );
1308 ok( !count, "Unexpected msg count: %ld\n", count );
1309
1310 res = pNtReadFile( server, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL );
1311 ok(res == STATUS_PENDING, "NtReadFile returned %lx\n", res);
1312
1313 iosb.Status = 0xdeadbeef;
1314 res = pNtSetInformationFile( server, &iosb, &fci, sizeof(fci), FileCompletionInformation );
1315 ok( res == STATUS_SUCCESS, "NtSetInformationFile failed: %lx\n", res );
1316 ok( iosb.Status == STATUS_SUCCESS, "iosb.Status invalid: %lx\n", iosb.Status );
1318 ok( !count, "Unexpected msg count: %ld\n", count );
1319
1321
1322 ok(!apc_count, "apc_count = %u\n", apc_count);
1324 ok( !count, "Unexpected msg count: %ld\n", count );
1325
1326 SleepEx(1, TRUE); /* alertable sleep */
1327 ok(apc_count == 1, "apc was not called\n");
1329 ok( !count, "Unexpected msg count: %ld\n", count );
1330
1331 /* using APCs on handle with associated completion port is not allowed */
1332 res = pNtReadFile( server, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL );
1333 ok(res == STATUS_INVALID_PARAMETER, "NtReadFile returned %lx\n", res);
1334
1337 pNtClose( h );
1338}
1339
1341{
1345 HANDLE h;
1346 NTSTATUS res;
1347
1348 if(!(h = create_temp_file(0))) return ;
1349
1350 memset(&ffsi,0,sizeof(ffsi));
1351 memset(&fsi,0,sizeof(fsi));
1352
1353 /* Assume No Quota Settings configured on Wine Testbot */
1354 res = pNtQueryVolumeInformationFile(h, &io, &ffsi, sizeof ffsi, FileFsFullSizeInformation);
1355 ok(res == STATUS_SUCCESS, "cannot get attributes, res %lx\n", res);
1356 res = pNtQueryVolumeInformationFile(h, &io, &fsi, sizeof fsi, FileFsSizeInformation);
1357 ok(res == STATUS_SUCCESS, "cannot get attributes, res %lx\n", res);
1358
1359 /* Test for FileFsSizeInformation */
1361 "[fsi] TotalAllocationUnits expected positive, got 0x%s\n",
1364 "[fsi] AvailableAllocationUnits expected positive, got 0x%s\n",
1366
1367 /* Assume file system is NTFS */
1368 ok(fsi.BytesPerSector == 512, "[fsi] BytesPerSector expected 512, got %ld\n",fsi.BytesPerSector);
1369 ok(fsi.SectorsPerAllocationUnit == 8, "[fsi] SectorsPerAllocationUnit expected 8, got %ld\n",fsi.SectorsPerAllocationUnit);
1370
1372 "[ffsi] TotalAllocationUnits expected positive, got negative value 0x%s\n",
1375 "[ffsi] CallerAvailableAllocationUnits expected positive, got negative value 0x%s\n",
1378 "[ffsi] ActualAvailableAllocationUnits expected positive, got negative value 0x%s\n",
1381 "[ffsi] TotalAllocationUnits error fsi:0x%s, ffsi:0x%s\n",
1384
1385 /* Assume file system is NTFS */
1386 ok(ffsi.BytesPerSector == 512, "[ffsi] BytesPerSector expected 512, got %ld\n",ffsi.BytesPerSector);
1387 ok(ffsi.SectorsPerAllocationUnit == 8, "[ffsi] SectorsPerAllocationUnit expected 8, got %ld\n",ffsi.SectorsPerAllocationUnit);
1388
1389 CloseHandle( h );
1390}
1391
1393{
1394 FILE_BASIC_INFORMATION fbi, fbi2;
1396 HANDLE h;
1397 int res;
1399
1400 if (!(h = create_temp_file(0))) return;
1401
1402 /* Check default first */
1403 memset(&fbi, 0, sizeof(fbi));
1404 res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
1405 ok ( res == STATUS_SUCCESS, "can't get attributes, res %x\n", res);
1407 "attribute %lx not expected\n", fbi.FileAttributes );
1408
1409 memset(&fbi2, 0, sizeof(fbi2));
1410 fbi2.LastWriteTime.QuadPart = -1;
1411 io.Status = 0xdeadbeef;
1412 res = pNtSetInformationFile(h, &io, &fbi2, sizeof fbi2, FileBasicInformation);
1413 ok ( res == STATUS_SUCCESS, "can't set -1 write time, NtSetInformationFile returned %x\n", res );
1414 ok ( io.Status == STATUS_SUCCESS, "can't set -1 write time, io.Status is %lx\n", io.Status );
1415
1416 memset(&fbi2, 0, sizeof(fbi2));
1417 fbi2.LastAccessTime.QuadPart = 0x200deadcafebeef;
1418 io.Status = 0xdeadbeef;
1419 res = pNtSetInformationFile(h, &io, &fbi2, sizeof(fbi2), FileBasicInformation);
1420 ok ( res == STATUS_SUCCESS, "can't set access time, NtSetInformationFile returned %x\n", res );
1421 ok ( io.Status == STATUS_SUCCESS, "can't set access time, io.Status is %lx\n", io.Status );
1422 res = pNtQueryInformationFile(h, &io, &fbi, sizeof(fbi), FileBasicInformation);
1423 ok ( res == STATUS_SUCCESS, "can't get access time, NtQueryInformationFile returned %x\n", res );
1424 ok ( io.Status == STATUS_SUCCESS, "can't get access time, io.Status is %lx\n", io.Status );
1426 "access time mismatch, set: %s get: %s\n",
1429
1430 memset(&fbi2, 0, sizeof(fbi2));
1431 res = pNtQueryInformationFile(h, &io, &fbi2, sizeof fbi2, FileBasicInformation);
1432 ok ( res == STATUS_SUCCESS, "can't get write time 1, res %x\n", res);
1433 ok ( fbi2.LastWriteTime.QuadPart == fbi.LastWriteTime.QuadPart, "write time mismatch, %s != %s\n",
1436
1437 memset(&fbi2, 0, sizeof(fbi2));
1438 io.Status = 0xdeadbeef;
1439 res = pNtSetInformationFile(h, &io, &fbi2, sizeof fbi2, FileBasicInformation);
1440 ok ( res == STATUS_SUCCESS, "can't set nothing, NtSetInformationFile returned %x\n", res );
1441 ok ( io.Status == STATUS_SUCCESS, "can't set nothing, io.Status is %lx\n", io.Status );
1442
1443 memset(&fbi2, 0, sizeof(fbi2));
1444 res = pNtQueryInformationFile(h, &io, &fbi2, sizeof fbi2, FileBasicInformation);
1445 ok ( res == STATUS_SUCCESS, "can't get write time 2, res %x\n", res);
1446 ok ( fbi2.LastWriteTime.QuadPart == fbi.LastWriteTime.QuadPart, "write time changed, %s != %s\n",
1449
1450 /* Then SYSTEM */
1451 /* Clear fbi to avoid setting times */
1452 memset(&fbi, 0, sizeof(fbi));
1454 io.Status = 0xdeadbeef;
1455 res = pNtSetInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
1456 ok ( res == STATUS_SUCCESS, "can't set system attribute, NtSetInformationFile returned %x\n", res );
1457 ok ( io.Status == STATUS_SUCCESS, "can't set system attribute, io.Status is %lx\n", io.Status );
1458
1459 memset(&fbi, 0, sizeof(fbi));
1460 res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
1461 ok ( res == STATUS_SUCCESS, "can't get system attribute\n");
1462 ok ( (fbi.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_SYSTEM, "attribute %lx not FILE_ATTRIBUTE_SYSTEM\n", fbi.FileAttributes );
1463
1464 /* Then HIDDEN */
1465 memset(&fbi, 0, sizeof(fbi));
1467 io.Status = 0xdeadbeef;
1468 res = pNtSetInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
1469 ok ( res == STATUS_SUCCESS, "can't set hidden attribute, NtSetInformationFile returned %x\n", res );
1470 ok ( io.Status == STATUS_SUCCESS, "can't set hidden attribute, io.Status is %lx\n", io.Status );
1471
1472 memset(&fbi, 0, sizeof(fbi));
1473 res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
1474 ok ( res == STATUS_SUCCESS, "can't get hidden attribute\n");
1475 ok ( (fbi.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_HIDDEN, "attribute %lx not FILE_ATTRIBUTE_HIDDEN\n", fbi.FileAttributes );
1476
1477 /* Check NORMAL last of all (to make sure we can clear attributes) */
1478 memset(&fbi, 0, sizeof(fbi));
1480 io.Status = 0xdeadbeef;
1481 res = pNtSetInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
1482 ok ( res == STATUS_SUCCESS, "can't set normal attribute, NtSetInformationFile returned %x\n", res );
1483 ok ( io.Status == STATUS_SUCCESS, "can't set normal attribute, io.Status is %lx\n", io.Status );
1484
1485 memset(&fbi, 0, sizeof(fbi));
1486 res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
1487 ok ( res == STATUS_SUCCESS, "can't get normal attribute\n");
1488 todo_wine ok ( (fbi.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_NORMAL, "attribute %lx not 0\n", fbi.FileAttributes );
1489
1490 CloseHandle( h );
1491}
1492
1494{
1496 /* FileAllInformation, like FileNameInformation, has a variable-length pathname
1497 * buffer at the end. Vista objects with STATUS_BUFFER_OVERFLOW if you
1498 * don't leave enough room there.
1499 */
1500 struct {
1502 WCHAR buf[256];
1503 } fai_buf;
1504 HANDLE h;
1505 int res;
1507
1508 if (!(h = create_temp_file(0))) return;
1509
1510 /* Check default first */
1511 res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation);
1512 ok ( res == STATUS_SUCCESS, "can't get attributes, res %x\n", res);
1513 ok ( (fai_buf.fai.BasicInformation.FileAttributes & FILE_ATTRIBUTE_ARCHIVE) == FILE_ATTRIBUTE_ARCHIVE,
1514 "attribute %lx not expected\n", fai_buf.fai.BasicInformation.FileAttributes );
1515
1516 /* Then SYSTEM */
1517 /* Clear fbi to avoid setting times */
1518 memset(&fai_buf.fai.BasicInformation, 0, sizeof(fai_buf.fai.BasicInformation));
1519 fai_buf.fai.BasicInformation.FileAttributes = FILE_ATTRIBUTE_SYSTEM;
1520 io.Status = 0xdeadbeef;
1521 res = pNtSetInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation);
1522 ok ( res == STATUS_INVALID_INFO_CLASS || broken(res == STATUS_NOT_IMPLEMENTED), "shouldn't be able to set FileAllInformation, res %x\n", res);
1523 todo_wine ok ( io.Status == 0xdeadbeef, "shouldn't be able to set FileAllInformation, io.Status is %lx\n", io.Status);
1524 io.Status = 0xdeadbeef;
1525 res = pNtSetInformationFile(h, &io, &fai_buf.fai.BasicInformation, sizeof fai_buf.fai.BasicInformation, FileBasicInformation);
1526 ok ( res == STATUS_SUCCESS, "can't set system attribute, res: %x\n", res );
1527 ok ( io.Status == STATUS_SUCCESS, "can't set system attribute, io.Status: %lx\n", io.Status );
1528
1529 memset(&fai_buf.fai, 0, sizeof(fai_buf.fai));
1530 res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation);
1531 ok ( res == STATUS_SUCCESS, "can't get attributes, res %x\n", res);
1532 ok ( (fai_buf.fai.BasicInformation.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_SYSTEM, "attribute %lx not FILE_ATTRIBUTE_SYSTEM\n", fai_buf.fai.BasicInformation.FileAttributes );
1533
1534 /* Then HIDDEN */
1535 memset(&fai_buf.fai.BasicInformation, 0, sizeof(fai_buf.fai.BasicInformation));
1536 fai_buf.fai.BasicInformation.FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1537 io.Status = 0xdeadbeef;
1538 res = pNtSetInformationFile(h, &io, &fai_buf.fai.BasicInformation, sizeof fai_buf.fai.BasicInformation, FileBasicInformation);
1539 ok ( res == STATUS_SUCCESS, "can't set system attribute, res: %x\n", res );
1540 ok ( io.Status == STATUS_SUCCESS, "can't set system attribute, io.Status: %lx\n", io.Status );
1541
1542 memset(&fai_buf.fai, 0, sizeof(fai_buf.fai));
1543 res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation);
1544 ok ( res == STATUS_SUCCESS, "can't get attributes\n");
1545 ok ( (fai_buf.fai.BasicInformation.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_HIDDEN, "attribute %lx not FILE_ATTRIBUTE_HIDDEN\n", fai_buf.fai.BasicInformation.FileAttributes );
1546
1547 /* Check NORMAL last of all (to make sure we can clear attributes) */
1548 memset(&fai_buf.fai.BasicInformation, 0, sizeof(fai_buf.fai.BasicInformation));
1549 fai_buf.fai.BasicInformation.FileAttributes = FILE_ATTRIBUTE_NORMAL;
1550 io.Status = 0xdeadbeef;
1551 res = pNtSetInformationFile(h, &io, &fai_buf.fai.BasicInformation, sizeof fai_buf.fai.BasicInformation, FileBasicInformation);
1552 ok ( res == STATUS_SUCCESS, "can't set system attribute, res: %x\n", res );
1553 ok ( io.Status == STATUS_SUCCESS, "can't set system attribute, io.Status: %lx\n", io.Status );
1554
1555 memset(&fai_buf.fai, 0, sizeof(fai_buf.fai));
1556 res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation);
1557 ok ( res == STATUS_SUCCESS, "can't get attributes\n");
1558 todo_wine ok ( (fai_buf.fai.BasicInformation.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_NORMAL, "attribute %lx not FILE_ATTRIBUTE_NORMAL\n", fai_buf.fai.BasicInformation.FileAttributes );
1559
1560 CloseHandle( h );
1561}
1562
1563static void delete_object( WCHAR *path )
1564{
1566 ok( ret || GetLastError() == ERROR_FILE_NOT_FOUND, "SetFileAttribute failed with %lu\n", GetLastError() );
1567 ret = DeleteFileW( path );
1569 "DeleteFileW failed with %lu\n", GetLastError() );
1571 {
1573 ok( ret, "RemoveDirectoryW failed with %lu\n", GetLastError() );
1574 }
1575}
1576
1578{
1579 static const WCHAR foo_txtW[] = {'\\','f','o','o','.','t','x','t',0};
1580 static const WCHAR fooW[] = {'f','o','o',0};
1581 WCHAR tmp_path[MAX_PATH], oldpath[MAX_PATH + 16], newpath[MAX_PATH + 16], *filename, *p;
1584 BOOL success, fileDeleted;
1585 UNICODE_STRING name_str;
1586 HANDLE handle, handle2;
1588 NTSTATUS res;
1589
1590 GetTempPathW( MAX_PATH, tmp_path );
1591
1592 /* oldpath is a file, newpath doesn't exist */
1593 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1594 ok( res != 0, "failed to create temp file\n" );
1595 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1596 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1597
1598 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1599 ok( res != 0, "failed to create temp file\n" );
1600 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1601 DeleteFileW( newpath );
1602 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1603 fri->Flags = 0;
1604 fri->RootDirectory = NULL;
1605 fri->FileNameLength = name_str.Length;
1606 memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1607 pRtlFreeUnicodeString( &name_str );
1608
1609 io.Status = 0xdeadbeef;
1610 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, class );
1611
1613 {
1614 win_skip( "FileRenameInformationEx not supported\n" );
1616 HeapFree( GetProcessHeap(), 0, fri );
1617 delete_object( oldpath );
1618 return;
1619 }
1620
1621 ok( io.Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %lx\n", io.Status );
1622 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %lx\n", res );
1624 ok( fileDeleted, "file should not exist\n" );
1626 ok( !fileDeleted, "file should exist\n" );
1627
1628 fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) );
1629 res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation );
1630 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %lx\n", res );
1631 fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0;
1632 ok( !lstrcmpiW(fni->FileName, newpath + 2), "FileName expected %s, got %s\n",
1633 wine_dbgstr_w(newpath + 2), wine_dbgstr_w(fni->FileName) );
1634 HeapFree( GetProcessHeap(), 0, fni );
1635
1637 HeapFree( GetProcessHeap(), 0, fri );
1638 delete_object( oldpath );
1639 delete_object( newpath );
1640
1641 /* oldpath is a file, newpath is a file, Replace = FALSE */
1642 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1643 ok( res != 0, "failed to create temp file\n" );
1644 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1645 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1646
1647 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1648 ok( res != 0, "failed to create temp file\n" );
1649 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1650 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1651 fri->Flags = 0;
1652 fri->RootDirectory = NULL;
1653 fri->FileNameLength = name_str.Length;
1654 memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1655 pRtlFreeUnicodeString( &name_str );
1656
1657 io.Status = 0xdeadbeef;
1658 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, class );
1659 todo_wine ok( io.Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", io.Status );
1660 ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %lx\n", res );
1662 ok( !fileDeleted, "file should exist\n" );
1664 ok( !fileDeleted, "file should exist\n" );
1665
1667 HeapFree( GetProcessHeap(), 0, fri );
1668 delete_object( oldpath );
1669 delete_object( newpath );
1670
1671 /* oldpath is a file, newpath is a file, Replace = TRUE */
1672 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1673 ok( res != 0, "failed to create temp file\n" );
1674 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1675 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1676
1677 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1678 ok( res != 0, "failed to create temp file\n" );
1679 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1680 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1682 fri->RootDirectory = NULL;
1683 fri->FileNameLength = name_str.Length;
1684 memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1685 pRtlFreeUnicodeString( &name_str );
1686
1687 io.Status = 0xdeadbeef;
1688 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, class );
1689 ok( io.Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %lx\n", io.Status );
1690 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %lx\n", res );
1692 ok( fileDeleted, "file should not exist\n" );
1694 ok( !fileDeleted, "file should exist\n" );
1695
1697 HeapFree( GetProcessHeap(), 0, fri );
1698 delete_object( oldpath );
1699 delete_object( newpath );
1700
1701 /* oldpath is a file, newpath is a file, Replace = FALSE, target file opened */
1702 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1703 ok( res != 0, "failed to create temp file\n" );
1704 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1705 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1706
1707 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1708 ok( res != 0, "failed to create temp file\n" );
1709 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1710 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1711
1712 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1713 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1714 fri->Flags = 0;
1715 fri->RootDirectory = NULL;
1716 fri->FileNameLength = name_str.Length;
1717 memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1718 pRtlFreeUnicodeString( &name_str );
1719
1720 io.Status = 0xdeadbeef;
1721 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, class );
1722 todo_wine ok( io.Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", io.Status );
1723 ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %lx\n", res );
1725 ok( !fileDeleted, "file should exist\n" );
1727 ok( !fileDeleted, "file should exist\n" );
1728
1730 CloseHandle( handle2 );
1731 HeapFree( GetProcessHeap(), 0, fri );
1732 delete_object( oldpath );
1733 delete_object( newpath );
1734
1735 /* oldpath is a file, newpath is a file, Replace = TRUE, target file opened */
1736 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1737 ok( res != 0, "failed to create temp file\n" );
1738 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1739 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1740
1741 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1742 ok( res != 0, "failed to create temp file\n" );
1743 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1744 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1745
1746 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1747 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1749 fri->RootDirectory = NULL;
1750 fri->FileNameLength = name_str.Length;
1751 memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1752 pRtlFreeUnicodeString( &name_str );
1753
1754 io.Status = 0xdeadbeef;
1755 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, class );
1756 todo_wine ok( io.Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", io.Status );
1757 ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %lx\n", res );
1759 ok( !fileDeleted, "file should exist\n" );
1761 ok( !fileDeleted, "file should exist\n" );
1762
1764 CloseHandle( handle2 );
1765 HeapFree( GetProcessHeap(), 0, fri );
1766 delete_object( oldpath );
1767 delete_object( newpath );
1768
1769 /* oldpath is a directory, newpath doesn't exist, Replace = FALSE */
1770 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1771 ok( res != 0, "failed to create temp file\n" );
1772 DeleteFileW( oldpath );
1773 success = CreateDirectoryW( oldpath, NULL );
1774 ok( success != 0, "failed to create temp directory\n" );
1776 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1777
1778 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1779 ok( res != 0, "failed to create temp file\n" );
1780 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1781 DeleteFileW( newpath );
1782 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1783 fri->Flags = 0;
1784 fri->RootDirectory = NULL;
1785 fri->FileNameLength = name_str.Length;
1786 memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1787 pRtlFreeUnicodeString( &name_str );
1788
1789 io.Status = 0xdeadbeef;
1790 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, class );
1791 ok( io.Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %lx\n", io.Status );
1792 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %lx\n", res );
1794 ok( fileDeleted, "file should not exist\n" );
1796 ok( !fileDeleted, "file should exist\n" );
1797
1798 fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) );
1799 res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation );
1800 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %lx\n", res );
1801 fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0;
1802 ok( !lstrcmpiW(fni->FileName, newpath + 2), "FileName expected %s, got %s\n",
1803 wine_dbgstr_w(newpath + 2), wine_dbgstr_w(fni->FileName) );
1804 HeapFree( GetProcessHeap(), 0, fni );
1805
1807 HeapFree( GetProcessHeap(), 0, fri );
1808 delete_object( oldpath );
1809 delete_object( newpath );
1810
1811 /* oldpath is a directory (but child object opened), newpath doesn't exist, Replace = FALSE */
1812 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1813 ok( res != 0, "failed to create temp file\n" );
1814 DeleteFileW( oldpath );
1815 success = CreateDirectoryW( oldpath, NULL );
1816 ok( success != 0, "failed to create temp directory\n" );
1818 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1819
1820 lstrcpyW( newpath, oldpath );
1821 lstrcatW( newpath, foo_txtW );
1823 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1824
1825 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1826 ok( res != 0, "failed to create temp file\n" );
1827 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1828 DeleteFileW( newpath );
1829 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1830 fri->Flags = 0;
1831 fri->RootDirectory = NULL;
1832 fri->FileNameLength = name_str.Length;
1833 memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1834 pRtlFreeUnicodeString( &name_str );
1835
1836 io.Status = 0xdeadbeef;
1837 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, class );
1838 todo_wine ok( io.Status == 0xdeadbeef || io.Status == STATUS_ACCESS_DENIED, "io.Status got %lx\n", io.Status );
1839 todo_wine ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %lx\n", res );
1841 todo_wine ok( !fileDeleted, "file should exist\n" );
1843 todo_wine ok( fileDeleted, "file should not exist\n" );
1844
1846 CloseHandle( handle2 );
1847 HeapFree( GetProcessHeap(), 0, fri );
1848 delete_object( oldpath );
1849 if (res == STATUS_SUCCESS) /* remove when Wine is fixed */
1850 {
1851 lstrcpyW( oldpath, newpath );
1852 lstrcatW( oldpath, foo_txtW );
1853 delete_object( oldpath );
1854 }
1855 delete_object( newpath );
1856
1857 /* oldpath is a directory, newpath is a file, Replace = FALSE */
1858 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1859 ok( res != 0, "failed to create temp file\n" );
1860 DeleteFileW( oldpath );
1861 success = CreateDirectoryW( oldpath, NULL );
1862 ok( success != 0, "failed to create temp directory\n" );
1864 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1865
1866 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1867 ok( res != 0, "failed to create temp file\n" );
1868 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1869 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1870 fri->Flags = 0;
1871 fri->RootDirectory = NULL;
1872 fri->FileNameLength = name_str.Length;
1873 memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1874 pRtlFreeUnicodeString( &name_str );
1875
1876 io.Status = 0xdeadbeef;
1877 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, class );
1878 ok( io.Status == 0xdeadbeef || io.Status == STATUS_OBJECT_NAME_COLLISION, "io.Status got %lx\n", io.Status );
1879 ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %lx\n", res );
1881 ok( !fileDeleted, "file should exist\n" );
1883 ok( !fileDeleted, "file should exist\n" );
1884
1886 HeapFree( GetProcessHeap(), 0, fri );
1887 delete_object( oldpath );
1888 delete_object( newpath );
1889
1890 /* oldpath is a directory, newpath is a file, Replace = FALSE, target file opened */
1891 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1892 ok( res != 0, "failed to create temp file\n" );
1893 DeleteFileW( oldpath );
1894 success = CreateDirectoryW( oldpath, NULL );
1895 ok( success != 0, "failed to create temp directory\n" );
1897 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1898
1899 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1900 ok( res != 0, "failed to create temp file\n" );
1901 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1902 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1903
1904 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1905 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1906 fri->Flags = 0;
1907 fri->RootDirectory = NULL;
1908 fri->FileNameLength = name_str.Length;
1909 memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1910 pRtlFreeUnicodeString( &name_str );
1911
1912 io.Status = 0xdeadbeef;
1913 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, class );
1914 ok( io.Status == 0xdeadbeef || io.Status == STATUS_OBJECT_NAME_COLLISION, "io.Status got %lx\n", io.Status );
1915 ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %lx\n", res );
1917 ok( !fileDeleted, "file should exist\n" );
1919 ok( !fileDeleted, "file should exist\n" );
1920
1922 CloseHandle( handle2 );
1923 HeapFree( GetProcessHeap(), 0, fri );
1924 delete_object( oldpath );
1925 delete_object( newpath );
1926
1927 /* oldpath is a directory, newpath is a file, Replace = TRUE */
1928 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1929 ok( res != 0, "failed to create temp file\n" );
1930 DeleteFileW( oldpath );
1931 success = CreateDirectoryW( oldpath, NULL );
1932 ok( success != 0, "failed to create temp directory\n" );
1934 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1935
1936 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1937 ok( res != 0, "failed to create temp file\n" );
1938 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1939 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1941 fri->RootDirectory = NULL;
1942 fri->FileNameLength = name_str.Length;
1943 memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1944 pRtlFreeUnicodeString( &name_str );
1945
1946 io.Status = 0xdeadbeef;
1947 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, class );
1948 ok( io.Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %lx\n", io.Status );
1949 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %lx\n", res );
1951 ok( fileDeleted, "file should not exist\n" );
1953 ok( !fileDeleted, "file should exist\n" );
1954
1956 HeapFree( GetProcessHeap(), 0, fri );
1957 delete_object( oldpath );
1958 delete_object( newpath );
1959
1960 /* oldpath is a directory, newpath is a file, Replace = TRUE, target file opened */
1961 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1962 ok( res != 0, "failed to create temp file\n" );
1963 DeleteFileW( oldpath );
1964 success = CreateDirectoryW( oldpath, NULL );
1965 ok( success != 0, "failed to create temp directory\n" );
1967 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1968
1969 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
1970 ok( res != 0, "failed to create temp file\n" );
1971 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
1972 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
1973
1974 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
1975 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
1977 fri->RootDirectory = NULL;
1978 fri->FileNameLength = name_str.Length;
1979 memcpy( fri->FileName, name_str.Buffer, name_str.Length );
1980 pRtlFreeUnicodeString( &name_str );
1981
1982 io.Status = 0xdeadbeef;
1983 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, class );
1984 ok( io.Status == 0xdeadbeef || io.Status == STATUS_ACCESS_DENIED, "io.Status got %lx\n", io.Status );
1985 ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %lx\n", res );
1987 ok( !fileDeleted, "file should exist\n" );
1989 ok( !fileDeleted, "file should exist\n" );
1990
1992 CloseHandle( handle2 );
1993 HeapFree( GetProcessHeap(), 0, fri );
1994 delete_object( oldpath );
1995 delete_object( newpath );
1996
1997 /* oldpath is a directory, newpath is a directory, Replace = FALSE */
1998 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
1999 ok( res != 0, "failed to create temp file\n" );
2000 DeleteFileW( oldpath );
2001 success = CreateDirectoryW( oldpath, NULL );
2002 ok( success != 0, "failed to create temp directory\n" );
2004 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2005
2006 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2007 ok( res != 0, "failed to create temp file\n" );
2008 DeleteFileW( newpath );
2009 success = CreateDirectoryW( newpath, NULL );
2010 ok( success != 0, "failed to create temp directory\n" );
2011 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2012 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
2013 fri->Flags = 0;
2014 fri->RootDirectory = NULL;
2015 fri->FileNameLength = name_str.Length;
2016 memcpy( fri->FileName, name_str.Buffer, name_str.Length );
2017 pRtlFreeUnicodeString( &name_str );
2018
2019 io.Status = 0xdeadbeef;
2020 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, class );
2021 ok( io.Status == 0xdeadbeef || io.Status == STATUS_OBJECT_NAME_COLLISION, "io.Status got %lx\n", io.Status );
2022 ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %lx\n", res );
2024 ok( !fileDeleted, "file should exist\n" );
2026 ok( !fileDeleted, "file should exist\n" );
2027
2029 HeapFree( GetProcessHeap(), 0, fri );
2030 delete_object( oldpath );
2031 delete_object( newpath );
2032
2033 /* oldpath is a directory, newpath is a directory, Replace = TRUE */
2034 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2035 ok( res != 0, "failed to create temp file\n" );
2036 DeleteFileW( oldpath );
2037 success = CreateDirectoryW( oldpath, NULL );
2038 ok( success != 0, "failed to create temp directory\n" );
2040 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2041
2042 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2043 ok( res != 0, "failed to create temp file\n" );
2044 DeleteFileW( newpath );
2045 success = CreateDirectoryW( newpath, NULL );
2046 ok( success != 0, "failed to create temp directory\n" );
2047 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2048 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
2050 fri->RootDirectory = NULL;
2051 fri->FileNameLength = name_str.Length;
2052 memcpy( fri->FileName, name_str.Buffer, name_str.Length );
2053 pRtlFreeUnicodeString( &name_str );
2054
2055 io.Status = 0xdeadbeef;
2056 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, class );
2057 ok( io.Status == 0xdeadbeef || io.Status == STATUS_ACCESS_DENIED, "io.Status got %lx\n", io.Status );
2058 ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %lx\n", res );
2060 ok( !fileDeleted, "file should exist\n" );
2062 ok( !fileDeleted, "file should exist\n" );
2063
2065 HeapFree( GetProcessHeap(), 0, fri );
2066 delete_object( oldpath );
2067 delete_object( newpath );
2068
2069 /* oldpath is a directory, newpath is a directory, Replace = TRUE, target file opened */
2070 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2071 ok( res != 0, "failed to create temp file\n" );
2072 DeleteFileW( oldpath );
2073 success = CreateDirectoryW( oldpath, NULL );
2074 ok( success != 0, "failed to create temp directory\n" );
2076 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2077
2078 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2079 ok( res != 0, "failed to create temp file\n" );
2080 DeleteFileW( newpath );
2081 success = CreateDirectoryW( newpath, NULL );
2082 ok( success != 0, "failed to create temp directory\n" );
2084 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2085
2086 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2087 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
2089 fri->RootDirectory = NULL;
2090 fri->FileNameLength = name_str.Length;
2091 memcpy( fri->FileName, name_str.Buffer, name_str.Length );
2092 pRtlFreeUnicodeString( &name_str );
2093
2094 io.Status = 0xdeadbeef;
2095 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, class );
2096 ok( io.Status == 0xdeadbeef || io.Status == STATUS_ACCESS_DENIED, "io.Status got %lx\n", io.Status );
2097 ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %lx\n", res );
2099 ok( !fileDeleted, "file should exist\n" );
2101 ok( !fileDeleted, "file should exist\n" );
2102
2104 CloseHandle( handle2 );
2105 HeapFree( GetProcessHeap(), 0, fri );
2106 delete_object( oldpath );
2107 delete_object( newpath );
2108
2109 /* oldpath is a file, newpath is a directory, Replace = FALSE */
2110 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2111 ok( res != 0, "failed to create temp file\n" );
2112 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2113 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2114
2115 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2116 ok( res != 0, "failed to create temp file\n" );
2117 DeleteFileW( newpath );
2118 success = CreateDirectoryW( newpath, NULL );
2119 ok( success != 0, "failed to create temp directory\n" );
2120 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2121 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
2122 fri->Flags = 0;
2123 fri->RootDirectory = NULL;
2124 fri->FileNameLength = name_str.Length;
2125 memcpy( fri->FileName, name_str.Buffer, name_str.Length );
2126 pRtlFreeUnicodeString( &name_str );
2127
2128 io.Status = 0xdeadbeef;
2129 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, class );
2130 todo_wine ok( io.Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", io.Status );
2131 ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %lx\n", res );
2133 ok( !fileDeleted, "file should exist\n" );
2135 ok( !fileDeleted, "file should exist\n" );
2136
2138 HeapFree( GetProcessHeap(), 0, fri );
2139 delete_object( oldpath );
2140 delete_object( newpath );
2141
2142 /* oldpath is a file, newpath is a directory, Replace = TRUE */
2143 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2144 ok( res != 0, "failed to create temp file\n" );
2145 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2146 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2147
2148 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2149 ok( res != 0, "failed to create temp file\n" );
2150 DeleteFileW( newpath );
2151 success = CreateDirectoryW( newpath, NULL );
2152 ok( success != 0, "failed to create temp directory\n" );
2153 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2154 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
2156 fri->RootDirectory = NULL;
2157 fri->FileNameLength = name_str.Length;
2158 memcpy( fri->FileName, name_str.Buffer, name_str.Length );
2159 pRtlFreeUnicodeString( &name_str );
2160
2161 io.Status = 0xdeadbeef;
2162 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, class );
2163 todo_wine ok( io.Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", io.Status );
2164 ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %lx\n", res );
2166 ok( !fileDeleted, "file should exist\n" );
2168 ok( !fileDeleted, "file should exist\n" );
2169
2171 HeapFree( GetProcessHeap(), 0, fri );
2172 delete_object( oldpath );
2173 delete_object( newpath );
2174
2175 /* oldpath is a file, newpath doesn't exist, test with RootDir != NULL */
2176 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2177 ok( res != 0, "failed to create temp file\n" );
2178 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2179 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2180
2181 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2182 ok( res != 0, "failed to create temp file\n" );
2183 DeleteFileW( newpath );
2184 for (filename = newpath, p = newpath; *p; p++)
2185 if (*p == '\\') filename = p + 1;
2186 handle2 = CreateFileW( tmp_path, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
2187 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2188
2189 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + lstrlenW(filename) * sizeof(WCHAR) );
2190 fri->Flags = 0;
2191 fri->RootDirectory = handle2;
2192 fri->FileNameLength = lstrlenW(filename) * sizeof(WCHAR);
2193 memcpy( fri->FileName, filename, fri->FileNameLength );
2194
2195 io.Status = 0xdeadbeef;
2196 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, class );
2197 ok( io.Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %lx\n", io.Status );
2198 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %lx\n", res );
2200 ok( fileDeleted, "file should not exist\n" );
2202 ok( !fileDeleted, "file should exist\n" );
2203
2204 fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) );
2205 res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation );
2206 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %lx\n", res );
2207 fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0;
2208 ok( !lstrcmpiW(fni->FileName, newpath + 2), "FileName expected %s, got %s\n",
2209 wine_dbgstr_w(newpath + 2), wine_dbgstr_w(fni->FileName) );
2210 HeapFree( GetProcessHeap(), 0, fni );
2211
2213 CloseHandle( handle2 );
2214 HeapFree( GetProcessHeap(), 0, fri );
2215 delete_object( oldpath );
2216 delete_object( newpath );
2217
2218 /* oldpath == newpath */
2219 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2220 ok( res != 0, "failed to create temp file\n" );
2221 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2222 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2223
2224 pRtlDosPathNameToNtPathName_U( oldpath, &name_str, NULL, NULL );
2225 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
2226 fri->Flags = 0;
2227 fri->RootDirectory = NULL;
2228 fri->FileNameLength = name_str.Length;
2229 memcpy( fri->FileName, name_str.Buffer, name_str.Length );
2230 pRtlFreeUnicodeString( &name_str );
2231
2232 io.Status = 0xdeadbeef;
2233 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, class );
2234 ok( io.Status == STATUS_SUCCESS, "got io status %#lx\n", io.Status );
2235 ok( res == STATUS_SUCCESS, "got status %lx\n", res );
2236 ok( GetFileAttributesW( oldpath ) != INVALID_FILE_ATTRIBUTES, "file should exist\n" );
2237
2239 HeapFree( GetProcessHeap(), 0, fri );
2240 delete_object( oldpath );
2241}
2242
2244{
2245 static const WCHAR fooW[] = {'f','o','o',0};
2246 WCHAR tmp_path[MAX_PATH], oldpath[MAX_PATH + 16], newpath[MAX_PATH + 16];
2248 BOOL fileDeleted;
2249 UNICODE_STRING name_str;
2250 HANDLE handle, handle2;
2252 NTSTATUS res;
2253
2254 GetTempPathW( MAX_PATH, tmp_path );
2255
2256 /* oldpath is a file, newpath is a read-only file, with FILE_RENAME_REPLACE_IF_EXISTS */
2257 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2258 ok( res != 0, "failed to create temp file\n" );
2259 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2260 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2261
2262 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2263 ok( res != 0, "failed to create temp file\n" );
2264 DeleteFileW( newpath );
2266 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2267 CloseHandle( handle2 );
2268 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2269 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
2271 fri->RootDirectory = NULL;
2272 fri->FileNameLength = name_str.Length;
2273 memcpy( fri->FileName, name_str.Buffer, name_str.Length );
2274 pRtlFreeUnicodeString( &name_str );
2275
2276 io.Status = 0xdeadbeef;
2277 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformationEx );
2278
2280 {
2281 win_skip( "FileRenameInformationEx not supported\n" );
2283 HeapFree( GetProcessHeap(), 0, fri );
2284 delete_object( oldpath );
2285 return;
2286 }
2287
2288 todo_wine ok( io.Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", io.Status );
2289 ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %lx\n", res );
2291 ok( !fileDeleted, "file should exist\n" );
2293 ok( !fileDeleted, "file should exist\n" );
2294
2296 HeapFree( GetProcessHeap(), 0, fri );
2297 delete_object( oldpath );
2298 delete_object( newpath );
2299
2300 /* oldpath is a file, newpath is a read-only file, with FILE_RENAME_REPLACE_IF_EXISTS and FILE_RENAME_IGNORE_READONLY_ATTRIBUTE */
2301 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2302 ok( res != 0, "failed to create temp file\n" );
2303 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2304 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2305
2306 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2307 ok( res != 0, "failed to create temp file\n" );
2308 DeleteFileW( newpath );
2310 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2311 CloseHandle( handle2 );
2312 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2313 fri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
2315 fri->RootDirectory = NULL;
2316 fri->FileNameLength = name_str.Length;
2317 memcpy( fri->FileName, name_str.Buffer, name_str.Length );
2318 pRtlFreeUnicodeString( &name_str );
2319
2320 io.Status = 0xdeadbeef;
2321 res = pNtSetInformationFile( handle, &io, fri, sizeof(FILE_RENAME_INFORMATION) + fri->FileNameLength, FileRenameInformationEx );
2322 ok( io.Status == STATUS_SUCCESS || io.Status == 0xdeadbeef,
2323 "io.Status expected STATUS_SUCCESS or 0xdeadbeef, got %lx\n", io.Status );
2325 "res expected STATUS_SUCCESS or STATUS_NOT_SUPPORTED, got %lx\n", res );
2326
2327 if (res == STATUS_SUCCESS)
2328 {
2330 ok( fileDeleted, "file should not exist\n" );
2332 ok( !fileDeleted, "file should exist\n" );
2333 }
2334
2336 HeapFree( GetProcessHeap(), 0, fri );
2337 delete_object( oldpath );
2338 delete_object( newpath );
2339}
2340
2342{
2343 static const WCHAR foo_txtW[] = {'\\','f','o','o','.','t','x','t',0};
2344 static const WCHAR fooW[] = {'f','o','o',0};
2345 WCHAR tmp_path[MAX_PATH], oldpath[MAX_PATH + 16], newpath[MAX_PATH + 16], *filename, *p;
2349 BOOL success, fileDeleted;
2350 UNICODE_STRING name_str;
2351 HANDLE handle, handle2;
2353 NTSTATUS res;
2354
2355 GetTempPathW( MAX_PATH, tmp_path );
2356
2357 /* oldpath is a file, newpath doesn't exist */
2358 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2359 ok( res != 0, "failed to create temp file\n" );
2360 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2361 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2362
2363 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2364 ok( res != 0, "failed to create temp file\n" );
2365 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2366 DeleteFileW( newpath );
2367 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2368 fli->Flags = 0;
2369 fli->RootDirectory = NULL;
2370 fli->FileNameLength = name_str.Length;
2371 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2372 pRtlFreeUnicodeString( &name_str );
2373
2374 io.Status = 0xdeadbeef;
2375 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
2376
2378 {
2379 win_skip( "FileLinkInformationEx not supported\n" );
2381 HeapFree( GetProcessHeap(), 0, fli );
2382 delete_object( oldpath );
2383 return;
2384 }
2385
2386 ok( io.Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %lx\n", io.Status );
2387 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %lx\n", res );
2389 ok( !fileDeleted, "file should exist\n" );
2391 ok( !fileDeleted, "file should exist\n" );
2392
2393 fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) );
2394 res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation );
2395 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %lx\n", res );
2396 fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0;
2397 ok( !lstrcmpiW(fni->FileName, oldpath + 2), "FileName expected %s, got %s\n",
2398 wine_dbgstr_w(oldpath + 2), wine_dbgstr_w(fni->FileName) );
2399 HeapFree( GetProcessHeap(), 0, fni );
2400
2402 HeapFree( GetProcessHeap(), 0, fli );
2403 delete_object( oldpath );
2404 delete_object( newpath );
2405
2406 /* oldpath is a file, newpath is a file, ReplaceIfExists = FALSE */
2407 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2408 ok( res != 0, "failed to create temp file\n" );
2409 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2410 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2411
2412 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2413 ok( res != 0, "failed to create temp file\n" );
2414 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2415 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2416 fli->Flags = 0;
2417 fli->RootDirectory = NULL;
2418 fli->FileNameLength = name_str.Length;
2419 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2420 pRtlFreeUnicodeString( &name_str );
2421
2422 io.Status = 0xdeadbeef;
2423 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
2424 todo_wine ok( io.Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", io.Status );
2425 ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %lx\n", res );
2427 ok( !fileDeleted, "file should exist\n" );
2429 ok( !fileDeleted, "file should exist\n" );
2430
2432 HeapFree( GetProcessHeap(), 0, fli );
2433 delete_object( oldpath );
2434 delete_object( newpath );
2435
2436 /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE */
2437 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2438 ok( res != 0, "failed to create temp file\n" );
2439 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2440 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2441
2442 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2443 ok( res != 0, "failed to create temp file\n" );
2444 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2445 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2447 fli->RootDirectory = NULL;
2448 fli->FileNameLength = name_str.Length;
2449 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2450 pRtlFreeUnicodeString( &name_str );
2451
2452 io.Status = 0xdeadbeef;
2453 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
2454 ok( io.Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %lx\n", io.Status );
2455 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %lx\n", res );
2457 ok( !fileDeleted, "file should exist\n" );
2459 ok( !fileDeleted, "file should exist\n" );
2460
2462 HeapFree( GetProcessHeap(), 0, fli );
2463 delete_object( oldpath );
2464 delete_object( newpath );
2465
2466 /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE, different casing on link */
2467 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2468 ok( res != 0, "failed to create temp file\n" );
2469 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2470 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2471
2472 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2473 ok( res != 0, "failed to create temp file\n" );
2474 wcsrchr( newpath, '\\' )[1] = 'F';
2475 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2476 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2478 fli->RootDirectory = NULL;
2479 fli->FileNameLength = name_str.Length;
2480 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2481 pRtlFreeUnicodeString( &name_str );
2482
2483 io.Status = 0xdeadbeef;
2484 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
2485 ok( io.Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %lx\n", io.Status );
2486 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %lx\n", res );
2488 ok( !fileDeleted, "file should exist\n" );
2490 ok( !fileDeleted, "file should exist\n" );
2491
2493 handle = FindFirstFileW( newpath, &find_data );
2494 ok(handle != INVALID_HANDLE_VALUE, "FindFirstFileW: failed, error %ld\n", GetLastError());
2496 {
2497 todo_wine ok(!lstrcmpW(wcsrchr(newpath, '\\') + 1, find_data.cFileName),
2498 "Link did not change casing on existing target file: got %s\n", wine_dbgstr_w(find_data.cFileName));
2499 }
2500
2501 FindClose( handle );
2502 HeapFree( GetProcessHeap(), 0, fli );
2503 delete_object( oldpath );
2504 delete_object( newpath );
2505
2506 /* oldpath is a file, newpath is a file, ReplaceIfExists = FALSE, target file opened */
2507 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2508 ok( res != 0, "failed to create temp file\n" );
2509 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2510 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2511
2512 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2513 ok( res != 0, "failed to create temp file\n" );
2514 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2515 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2516
2517 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2518 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2519 fli->Flags = 0;
2520 fli->RootDirectory = NULL;
2521 fli->FileNameLength = name_str.Length;
2522 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2523 pRtlFreeUnicodeString( &name_str );
2524
2525 io.Status = 0xdeadbeef;
2526 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
2527 todo_wine ok( io.Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", io.Status );
2528 ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %lx\n", res );
2530 ok( !fileDeleted, "file should exist\n" );
2532 ok( !fileDeleted, "file should exist\n" );
2533
2535 CloseHandle( handle2 );
2536 HeapFree( GetProcessHeap(), 0, fli );
2537 delete_object( oldpath );
2538 delete_object( newpath );
2539
2540 /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE, target file opened */
2541 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2542 ok( res != 0, "failed to create temp file\n" );
2543 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2544 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2545
2546 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2547 ok( res != 0, "failed to create temp file\n" );
2548 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2549 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2550
2551 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2552 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2554 fli->RootDirectory = NULL;
2555 fli->FileNameLength = name_str.Length;
2556 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2557 pRtlFreeUnicodeString( &name_str );
2558
2559 io.Status = 0xdeadbeef;
2560 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
2561 todo_wine ok( io.Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", io.Status );
2562 ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %lx\n", res );
2564 ok( !fileDeleted, "file should exist\n" );
2566 ok( !fileDeleted, "file should exist\n" );
2567
2569 CloseHandle( handle2 );
2570 HeapFree( GetProcessHeap(), 0, fli );
2571 delete_object( oldpath );
2572 delete_object( newpath );
2573
2574 /* oldpath is a directory, newpath doesn't exist, ReplaceIfExists = FALSE */
2575 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2576 ok( res != 0, "failed to create temp file\n" );
2577 DeleteFileW( oldpath );
2578 success = CreateDirectoryW( oldpath, NULL );
2579 ok( success != 0, "failed to create temp directory\n" );
2581 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2582
2583 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2584 ok( res != 0, "failed to create temp file\n" );
2585 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2586 DeleteFileW( newpath );
2587 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2588 fli->Flags = 0;
2589 fli->RootDirectory = NULL;
2590 fli->FileNameLength = name_str.Length;
2591 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2592 pRtlFreeUnicodeString( &name_str );
2593
2594 io.Status = 0xdeadbeef;
2595 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
2596 ok( io.Status == 0xdeadbeef || io.Status == STATUS_FILE_IS_A_DIRECTORY ,
2597 "io.Status expected 0xdeadbeef or STATUS_FILE_IS_A_DIRECTORY, got %lx\n", io.Status );
2598 ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %lx\n", res );
2600 ok( !fileDeleted, "file should exist\n" );
2602 ok( fileDeleted, "file should not exist\n" );
2603
2604 fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) );
2605 res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation );
2606 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %lx\n", res );
2607 fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0;
2608 ok( !lstrcmpiW(fni->FileName, oldpath + 2), "FileName expected %s, got %s\n",
2609 wine_dbgstr_w(oldpath + 2), wine_dbgstr_w(fni->FileName) );
2610 HeapFree( GetProcessHeap(), 0, fni );
2611
2613 HeapFree( GetProcessHeap(), 0, fli );
2614 delete_object( oldpath );
2615 delete_object( newpath );
2616
2617 /* oldpath is a directory (but child object opened), newpath doesn't exist, ReplaceIfExists = FALSE */
2618 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2619 ok( res != 0, "failed to create temp file\n" );
2620 DeleteFileW( oldpath );
2621 success = CreateDirectoryW( oldpath, NULL );
2622 ok( success != 0, "failed to create temp directory\n" );
2624 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2625
2626 lstrcpyW( newpath, oldpath );
2627 lstrcatW( newpath, foo_txtW );
2629 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2630
2631 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2632 ok( res != 0, "failed to create temp file\n" );
2633 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2634 DeleteFileW( newpath );
2635 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2636 fli->Flags = 0;
2637 fli->RootDirectory = NULL;
2638 fli->FileNameLength = name_str.Length;
2639 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2640 pRtlFreeUnicodeString( &name_str );
2641
2642 io.Status = 0xdeadbeef;
2643 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
2644 ok( io.Status == 0xdeadbeef || io.Status == STATUS_FILE_IS_A_DIRECTORY,
2645 "io.Status expected 0xdeadbeef or STATUS_FILE_IS_A_DIRECTORY, got %lx\n", io.Status );
2646 ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %lx\n", res );
2648 ok( !fileDeleted, "file should exist\n" );
2650 ok( fileDeleted, "file should not exist\n" );
2651
2653 CloseHandle( handle2 );
2654 HeapFree( GetProcessHeap(), 0, fli );
2655 delete_object( oldpath );
2656 delete_object( newpath );
2657
2658 /* oldpath is a directory, newpath is a file, ReplaceIfExists = FALSE */
2659 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2660 ok( res != 0, "failed to create temp file\n" );
2661 DeleteFileW( oldpath );
2662 success = CreateDirectoryW( oldpath, NULL );
2663 ok( success != 0, "failed to create temp directory\n" );
2665 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2666
2667 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2668 ok( res != 0, "failed to create temp file\n" );
2669 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2670 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2671 fli->Flags = 0;
2672 fli->RootDirectory = NULL;
2673 fli->FileNameLength = name_str.Length;
2674 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2675 pRtlFreeUnicodeString( &name_str );
2676
2677 io.Status = 0xdeadbeef;
2678 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
2679 ok( io.Status == 0xdeadbeef || io.Status == STATUS_FILE_IS_A_DIRECTORY,
2680 "io.Status expected 0xdeadbeef or STATUS_FILE_IS_A_DIRECTORY, got %lx\n", io.Status );
2682 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %lx\n", res );
2684 ok( !fileDeleted, "file should exist\n" );
2686 ok( !fileDeleted, "file should exist\n" );
2687
2689 HeapFree( GetProcessHeap(), 0, fli );
2690 delete_object( oldpath );
2691 delete_object( newpath );
2692
2693 /* oldpath is a directory, newpath is a file, ReplaceIfExists = FALSE, target file opened */
2694 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2695 ok( res != 0, "failed to create temp file\n" );
2696 DeleteFileW( oldpath );
2697 success = CreateDirectoryW( oldpath, NULL );
2698 ok( success != 0, "failed to create temp directory\n" );
2700 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2701
2702 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2703 ok( res != 0, "failed to create temp file\n" );
2704 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2705 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2706
2707 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2708 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2709 fli->Flags = 0;
2710 fli->RootDirectory = NULL;
2711 fli->FileNameLength = name_str.Length;
2712 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2713 pRtlFreeUnicodeString( &name_str );
2714
2715 io.Status = 0xdeadbeef;
2716 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
2717 ok( io.Status == 0xdeadbeef || io.Status == STATUS_FILE_IS_A_DIRECTORY,
2718 "io.Status expected 0xdeadbeef or STATUS_FILE_IS_A_DIRECTORY, got %lx\n", io.Status );
2720 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %lx\n", res );
2722 ok( !fileDeleted, "file should exist\n" );
2724 ok( !fileDeleted, "file should exist\n" );
2725
2727 CloseHandle( handle2 );
2728 HeapFree( GetProcessHeap(), 0, fli );
2729 delete_object( oldpath );
2730 delete_object( newpath );
2731
2732 /* oldpath is a directory, newpath is a file, ReplaceIfExists = TRUE */
2733 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2734 ok( res != 0, "failed to create temp file\n" );
2735 DeleteFileW( oldpath );
2736 success = CreateDirectoryW( oldpath, NULL );
2737 ok( success != 0, "failed to create temp directory\n" );
2739 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2740
2741 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2742 ok( res != 0, "failed to create temp file\n" );
2743 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2744 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2746 fli->RootDirectory = NULL;
2747 fli->FileNameLength = name_str.Length;
2748 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2749 pRtlFreeUnicodeString( &name_str );
2750
2751 io.Status = 0xdeadbeef;
2752 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
2753 ok( io.Status == 0xdeadbeef || io.Status == STATUS_FILE_IS_A_DIRECTORY,
2754 "io.Status expected 0xdeadbeef or STATUS_FILE_IS_A_DIRECTORY, got %lx\n", io.Status );
2755 ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %lx\n", res );
2757 ok( !fileDeleted, "file should exist\n" );
2759 ok( !fileDeleted, "file should exist\n" );
2760
2762 HeapFree( GetProcessHeap(), 0, fli );
2763 delete_object( oldpath );
2764 delete_object( newpath );
2765
2766 /* oldpath is a directory, newpath is a file, ReplaceIfExists = TRUE, target file opened */
2767 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2768 ok( res != 0, "failed to create temp file\n" );
2769 DeleteFileW( oldpath );
2770 success = CreateDirectoryW( oldpath, NULL );
2771 ok( success != 0, "failed to create temp directory\n" );
2773 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2774
2775 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2776 ok( res != 0, "failed to create temp file\n" );
2777 handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2778 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2779
2780 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2781 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2783 fli->RootDirectory = NULL;
2784 fli->FileNameLength = name_str.Length;
2785 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2786 pRtlFreeUnicodeString( &name_str );
2787
2788 io.Status = 0xdeadbeef;
2789 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
2790 ok( io.Status == 0xdeadbeef || io.Status == STATUS_FILE_IS_A_DIRECTORY,
2791 "io.Status expected 0xdeadbeef or STATUS_FILE_IS_A_DIRECTORY, got %lx\n", io.Status );
2792 ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %lx\n", res );
2794 ok( !fileDeleted, "file should exist\n" );
2796 ok( !fileDeleted, "file should exist\n" );
2797
2799 CloseHandle( handle2 );
2800 HeapFree( GetProcessHeap(), 0, fli );
2801 delete_object( oldpath );
2802 delete_object( newpath );
2803
2804 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = FALSE */
2805 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2806 ok( res != 0, "failed to create temp file\n" );
2807 DeleteFileW( oldpath );
2808 success = CreateDirectoryW( oldpath, NULL );
2809 ok( success != 0, "failed to create temp directory\n" );
2811 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2812
2813 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2814 ok( res != 0, "failed to create temp file\n" );
2815 DeleteFileW( newpath );
2816 success = CreateDirectoryW( newpath, NULL );
2817 ok( success != 0, "failed to create temp directory\n" );
2818 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2819 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2820 fli->Flags = 0;
2821 fli->RootDirectory = NULL;
2822 fli->FileNameLength = name_str.Length;
2823 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2824 pRtlFreeUnicodeString( &name_str );
2825
2826 io.Status = 0xdeadbeef;
2827 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
2828 ok( io.Status == 0xdeadbeef || io.Status == STATUS_FILE_IS_A_DIRECTORY,
2829 "io.Status expected 0xdeadbeef or STATUS_FILE_IS_A_DIRECTORY, got %lx\n", io.Status );
2831 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %lx\n", res );
2833 ok( !fileDeleted, "file should exist\n" );
2835 ok( !fileDeleted, "file should exist\n" );
2836
2838 HeapFree( GetProcessHeap(), 0, fli );
2839 delete_object( oldpath );
2840 delete_object( newpath );
2841
2842 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = TRUE */
2843 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2844 ok( res != 0, "failed to create temp file\n" );
2845 DeleteFileW( oldpath );
2846 success = CreateDirectoryW( oldpath, NULL );
2847 ok( success != 0, "failed to create temp directory\n" );
2849 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2850
2851 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2852 ok( res != 0, "failed to create temp file\n" );
2853 DeleteFileW( newpath );
2854 success = CreateDirectoryW( newpath, NULL );
2855 ok( success != 0, "failed to create temp directory\n" );
2856 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2857 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2859 fli->RootDirectory = NULL;
2860 fli->FileNameLength = name_str.Length;
2861 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2862 pRtlFreeUnicodeString( &name_str );
2863
2864 io.Status = 0xdeadbeef;
2865 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
2866 ok( io.Status == 0xdeadbeef || io.Status == STATUS_FILE_IS_A_DIRECTORY,
2867 "io.Status expected 0xdeadbeef or STATUS_FILE_IS_A_DIRECTORY, got %lx\n", io.Status );
2868 ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %lx\n", res );
2870 ok( !fileDeleted, "file should exist\n" );
2872 ok( !fileDeleted, "file should exist\n" );
2873
2875 HeapFree( GetProcessHeap(), 0, fli );
2876 delete_object( oldpath );
2877 delete_object( newpath );
2878
2879 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = TRUE, target file opened */
2880 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2881 ok( res != 0, "failed to create temp file\n" );
2882 DeleteFileW( oldpath );
2883 success = CreateDirectoryW( oldpath, NULL );
2884 ok( success != 0, "failed to create temp directory\n" );
2886 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2887
2888 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2889 ok( res != 0, "failed to create temp file\n" );
2890 DeleteFileW( newpath );
2891 success = CreateDirectoryW( newpath, NULL );
2892 ok( success != 0, "failed to create temp directory\n" );
2894 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2895
2896 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2897 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2899 fli->RootDirectory = NULL;
2900 fli->FileNameLength = name_str.Length;
2901 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2902 pRtlFreeUnicodeString( &name_str );
2903
2904 io.Status = 0xdeadbeef;
2905 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
2906 ok( io.Status == 0xdeadbeef || io.Status == STATUS_FILE_IS_A_DIRECTORY,
2907 "io.Status expected 0xdeadbeef or STATUS_FILE_IS_A_DIRECTORY, got %lx\n", io.Status );
2908 ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %lx\n", res );
2910 ok( !fileDeleted, "file should exist\n" );
2912 ok( !fileDeleted, "file should exist\n" );
2913
2915 CloseHandle( handle2 );
2916 HeapFree( GetProcessHeap(), 0, fli );
2917 delete_object( oldpath );
2918 delete_object( newpath );
2919
2920 /* oldpath is a file, newpath is a directory, ReplaceIfExists = FALSE */
2921 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2922 ok( res != 0, "failed to create temp file\n" );
2923 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2924 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2925
2926 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2927 ok( res != 0, "failed to create temp file\n" );
2928 DeleteFileW( newpath );
2929 success = CreateDirectoryW( newpath, NULL );
2930 ok( success != 0, "failed to create temp directory\n" );
2931 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2932 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2933 fli->Flags = 0;
2934 fli->RootDirectory = NULL;
2935 fli->FileNameLength = name_str.Length;
2936 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2937 pRtlFreeUnicodeString( &name_str );
2938
2939 io.Status = 0xdeadbeef;
2940 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
2941 todo_wine ok( io.Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", io.Status );
2942 ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %lx\n", res );
2944 ok( !fileDeleted, "file should exist\n" );
2946 ok( !fileDeleted, "file should exist\n" );
2947
2949 HeapFree( GetProcessHeap(), 0, fli );
2950 delete_object( oldpath );
2951 delete_object( newpath );
2952
2953 /* oldpath is a file, newpath is a directory, ReplaceIfExists = TRUE */
2954 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2955 ok( res != 0, "failed to create temp file\n" );
2956 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2957 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2958
2959 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2960 ok( res != 0, "failed to create temp file\n" );
2961 DeleteFileW( newpath );
2962 success = CreateDirectoryW( newpath, NULL );
2963 ok( success != 0, "failed to create temp directory\n" );
2964 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
2965 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
2967 fli->RootDirectory = NULL;
2968 fli->FileNameLength = name_str.Length;
2969 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
2970 pRtlFreeUnicodeString( &name_str );
2971
2972 io.Status = 0xdeadbeef;
2973 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
2974 todo_wine ok( io.Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", io.Status );
2975 ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %lx\n", res );
2977 ok( !fileDeleted, "file should exist\n" );
2979 ok( !fileDeleted, "file should exist\n" );
2980
2982 HeapFree( GetProcessHeap(), 0, fli );
2983 delete_object( oldpath );
2984 delete_object( newpath );
2985
2986 /* oldpath is a file, newpath doesn't exist, test with RootDirectory != NULL */
2987 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
2988 ok( res != 0, "failed to create temp file\n" );
2989 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
2990 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2991
2992 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
2993 ok( res != 0, "failed to create temp file\n" );
2994 DeleteFileW( newpath );
2995 for (filename = newpath, p = newpath; *p; p++)
2996 if (*p == '\\') filename = p + 1;
2997 handle2 = CreateFileW( tmp_path, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
2998 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
2999
3000 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + lstrlenW(filename) * sizeof(WCHAR) );
3001 fli->Flags = 0;
3002 fli->RootDirectory = handle2;
3003 fli->FileNameLength = lstrlenW(filename) * sizeof(WCHAR);
3004 memcpy( fli->FileName, filename, fli->FileNameLength );
3005
3006 io.Status = 0xdeadbeef;
3007 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
3008 ok( io.Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %lx\n", io.Status );
3009 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %lx\n", res );
3011 ok( !fileDeleted, "file should exist\n" );
3013 ok( !fileDeleted, "file should exist\n" );
3014
3015 fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) );
3016 res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation );
3017 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %lx\n", res );
3018 fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0;
3019 ok( !lstrcmpiW(fni->FileName, oldpath + 2), "FileName expected %s, got %s\n",
3020 wine_dbgstr_w(oldpath + 2), wine_dbgstr_w(fni->FileName) );
3021 HeapFree( GetProcessHeap(), 0, fni );
3022
3024 CloseHandle( handle2 );
3025 HeapFree( GetProcessHeap(), 0, fli );
3026 delete_object( oldpath );
3027 delete_object( newpath );
3028
3029 /* oldpath == newpath */
3030 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
3031 ok( res != 0, "failed to create temp file\n" );
3032 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
3033 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
3034
3035 pRtlDosPathNameToNtPathName_U( oldpath, &name_str, NULL, NULL );
3036 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
3037 fli->Flags = 0;
3038 fli->RootDirectory = NULL;
3039 fli->FileNameLength = name_str.Length;
3040 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
3041 pRtlFreeUnicodeString( &name_str );
3042
3043 io.Status = 0xdeadbeef;
3044 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
3045 todo_wine ok( io.Status == 0xdeadbeef, "got io status %#lx\n", io.Status );
3046 ok( res == STATUS_OBJECT_NAME_COLLISION, "got status %lx\n", res );
3047
3049 io.Status = 0xdeadbeef;
3050 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
3051 ok( io.Status == STATUS_SUCCESS, "got io status %#lx\n", io.Status );
3052 ok( res == STATUS_SUCCESS, "got status %lx\n", res );
3053 ok( GetFileAttributesW( oldpath ) != INVALID_FILE_ATTRIBUTES, "file should exist\n" );
3054
3056 HeapFree( GetProcessHeap(), 0, fli );
3057 delete_object( oldpath );
3058
3059 /* oldpath == newpath, different casing on link */
3060 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
3061 ok( res != 0, "failed to create temp file\n" );
3062 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
3063 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
3064
3065 wcsrchr( oldpath, '\\' )[1] = 'F';
3066 pRtlDosPathNameToNtPathName_U( oldpath, &name_str, NULL, NULL );
3067 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
3068 fli->Flags = 0;
3069 fli->RootDirectory = NULL;
3070 fli->FileNameLength = name_str.Length;
3071 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
3072 pRtlFreeUnicodeString( &name_str );
3073
3074 io.Status = 0xdeadbeef;
3075 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
3076 todo_wine ok( io.Status == 0xdeadbeef, "got io status %#lx\n", io.Status );
3077 ok( res == STATUS_OBJECT_NAME_COLLISION, "got status %lx\n", res );
3078
3080 io.Status = 0xdeadbeef;
3081 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, class );
3082 ok( io.Status == STATUS_SUCCESS, "got io status %#lx\n", io.Status );
3083 ok( res == STATUS_SUCCESS, "got status %lx\n", res );
3084 ok( GetFileAttributesW( oldpath ) != INVALID_FILE_ATTRIBUTES, "file should exist\n" );
3085
3087 handle = FindFirstFileW( oldpath, &find_data );
3088 ok(handle != INVALID_HANDLE_VALUE, "FindFirstFileW: failed, error %ld\n", GetLastError());
3090 {
3091 todo_wine ok(!lstrcmpW(wcsrchr(oldpath, '\\') + 1, find_data.cFileName),
3092 "Link did not change casing on same file: got %s\n", wine_dbgstr_w(find_data.cFileName));
3093 }
3094
3095 FindClose( handle );
3096 HeapFree( GetProcessHeap(), 0, fli );
3097 delete_object( oldpath );
3098}
3099
3101{
3102 static const WCHAR fooW[] = {'f','o','o',0};
3103 WCHAR tmp_path[MAX_PATH], oldpath[MAX_PATH + 16], newpath[MAX_PATH + 16];
3105 BOOL fileDeleted;
3106 UNICODE_STRING name_str;
3107 HANDLE handle, handle2;
3109 NTSTATUS res;
3110
3111 GetTempPathW( MAX_PATH, tmp_path );
3112
3113 /* oldpath is a file, newpath is a read-only file, with FILE_LINK_REPLACE_IF_EXISTS */
3114 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
3115 ok( res != 0, "failed to create temp file\n" );
3116 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
3117 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
3118
3119 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
3120 ok( res != 0, "failed to create temp file\n" );
3121 DeleteFileW( newpath );
3123 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
3124 CloseHandle( handle2 );
3125 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
3126 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
3128 fli->RootDirectory = NULL;
3129 fli->FileNameLength = name_str.Length;
3130 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
3131 pRtlFreeUnicodeString( &name_str );
3132
3133 io.Status = 0xdeadbeef;
3134 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformationEx );
3135
3137 {
3138 win_skip( "FileLinkInformationEx not supported\n" );
3140 HeapFree( GetProcessHeap(), 0, fli );
3141 delete_object( oldpath );
3142 return;
3143 }
3144
3145 todo_wine ok( io.Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", io.Status );
3146 ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %lx\n", res );
3148 ok( !fileDeleted, "file should exist\n" );
3150 ok( !fileDeleted, "file should exist\n" );
3151
3153 HeapFree( GetProcessHeap(), 0, fli );
3154 delete_object( oldpath );
3155 delete_object( newpath );
3156
3157 /* oldpath is a file, newpath is a read-only file, with FILE_LINK_REPLACE_IF_EXISTS and FILE_LINK_IGNORE_READONLY_ATTRIBUTE */
3158 res = GetTempFileNameW( tmp_path, fooW, 0, oldpath );
3159 ok( res != 0, "failed to create temp file\n" );
3160 handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
3161 ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
3162
3163 res = GetTempFileNameW( tmp_path, fooW, 0, newpath );
3164 ok( res != 0, "failed to create temp file\n" );
3165 DeleteFileW( newpath );
3167 ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
3168 CloseHandle( handle2 );
3169 pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
3170 fli = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION) + name_str.Length );
3172 fli->RootDirectory = NULL;
3173 fli->FileNameLength = name_str.Length;
3174 memcpy( fli->FileName, name_str.Buffer, name_str.Length );
3175 pRtlFreeUnicodeString( &name_str );
3176
3177 io.Status = 0xdeadbeef;
3178 res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformationEx );
3179 ok( io.Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %lx\n", io.Status );
3180 ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %lx\n", res );
3182 ok( !fileDeleted, "file should exist\n" );
3184 ok( !fileDeleted, "file should exist\n" );
3185
3187 HeapFree( GetProcessHeap(), 0, fli );
3188 delete_object( oldpath );
3189 delete_object( newpath );
3190}
3191
3193{
3196 HANDLE h;
3197 int res;
3198
3199 if (!(h = create_temp_file(0))) return;
3200
3201 memset(&fbi, 0, sizeof(fbi));
3202 res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBothDirectoryInformation);
3203 ok ( res == STATUS_INVALID_INFO_CLASS || res == STATUS_NOT_IMPLEMENTED, "shouldn't be able to query FileBothDirectoryInformation, res %x\n", res);
3204
3205 CloseHandle( h );
3206}
3207
3208static NTSTATUS nt_get_file_attrs(const char *name, DWORD *attrs)
3209{
3212 UNICODE_STRING nt_name;
3215
3217
3218 *attrs = INVALID_FILE_ATTRIBUTES;
3219
3220 if (!pRtlDosPathNameToNtPathName_U( nameW, &nt_name, NULL, NULL ))
3221 return STATUS_UNSUCCESSFUL;
3222
3223 attr.Length = sizeof(attr);
3224 attr.RootDirectory = 0;
3225 attr.Attributes = OBJ_CASE_INSENSITIVE;
3226 attr.ObjectName = &nt_name;
3227 attr.SecurityDescriptor = NULL;
3228 attr.SecurityQualityOfService = NULL;
3229
3230 status = pNtQueryAttributesFile( &attr, &info );
3231 pRtlFreeUnicodeString( &nt_name );
3232
3233 if (status == STATUS_SUCCESS)
3234 *attrs = info.FileAttributes;
3235
3236 return status;
3237}
3238
3240{
3241 char tmp_path[MAX_PATH], buffer[MAX_PATH + 16];
3242 DWORD dirpos;
3243 HANDLE handle, handle2, handle3, mapping;
3244 NTSTATUS res;
3249 BOOL fileDeleted;
3250 DWORD fdi2, size;
3251 void *view;
3252
3253 GetTempPathA( MAX_PATH, tmp_path );
3254
3255 /* tests for info struct size */
3256 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3258 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3259 res = pNtSetInformationFile( handle, &io, &fdi, 0, FileDispositionInformation );
3260 todo_wine
3261 ok( res == STATUS_INFO_LENGTH_MISMATCH, "expected STATUS_INFO_LENGTH_MISMATCH, got %lx\n", res );
3262 fdi2 = 0x100;
3263 res = pNtSetInformationFile( handle, &io, &fdi2, sizeof(fdi2), FileDispositionInformation );
3264 ok( res == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %lx\n", res );
3267 ok( !fileDeleted, "File shouldn't have been deleted\n" );
3269
3270 /* cannot set disposition on file not opened with delete access */
3271 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3273 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3274 res = pNtQueryInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
3275 ok( res == STATUS_INVALID_INFO_CLASS || res == STATUS_NOT_IMPLEMENTED, "Unexpected NtQueryInformationFile result (expected STATUS_INVALID_INFO_CLASS, got %lx)\n", res );
3276 fdi.DoDeleteFile = TRUE;
3277 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
3278 ok( res == STATUS_ACCESS_DENIED, "unexpected FileDispositionInformation result (expected STATUS_ACCESS_DENIED, got %lx)\n", res );
3281 ok( !fileDeleted, "File shouldn't have been deleted\n" );
3283
3284 /* can set disposition on file opened with proper access */
3285 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3287 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3288 fdi.DoDeleteFile = TRUE;
3289 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
3290 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %lx)\n", res );
3292 ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res);
3293 todo_wine
3294 ok(fsi.DeletePending, "Handle should be marked for deletion\n");
3297 ok( fileDeleted, "File should have been deleted\n" );
3298
3299 /* file exists until all handles to it get closed */
3300 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3302 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3304 ok( handle2 != INVALID_HANDLE_VALUE, "failed to open temp file\n" );
3305 fdi.DoDeleteFile = TRUE;
3306 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
3307 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %lx)\n", res );
3308 res = nt_get_file_attrs( buffer, &fdi2 );
3309 todo_wine
3310 ok( res == STATUS_DELETE_PENDING, "got %#lx\n", res );
3311 /* can't open the deleted file */
3313 todo_wine
3314 ok( handle3 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
3315 if (handle3 != INVALID_HANDLE_VALUE)
3316 CloseHandle( handle3 );
3317 todo_wine
3318 ok(GetLastError() == ERROR_ACCESS_DENIED, "got %lu\n", GetLastError());
3319 /* can't open the deleted file (wrong sharing mode) */
3320 handle3 = CreateFileA(buffer, DELETE, 0, NULL, OPEN_EXISTING, 0, 0);
3321 ok( handle3 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
3322 todo_wine
3323 ok(GetLastError() == ERROR_ACCESS_DENIED, "got %lu\n", GetLastError());
3326 ok( !fileDeleted, "File shouldn't have been deleted\n" );
3327 CloseHandle( handle2 );
3329 ok( fileDeleted, "File should have been deleted\n" );
3330
3331 /* file exists until all handles to it get closed */
3332 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3334 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3335 /* can open the marked for delete file (proper sharing mode) */
3337 ok( handle2 != INVALID_HANDLE_VALUE, "failed to open temp file\n" );
3338 res = nt_get_file_attrs( buffer, &fdi2 );
3339 ok( res == STATUS_SUCCESS, "got %#lx\n", res );
3340 /* can't open the marked for delete file (wrong sharing mode) */
3341 handle3 = CreateFileA(buffer, DELETE, 0, NULL, OPEN_EXISTING, 0, 0);
3342 ok( handle3 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
3346 ok( !fileDeleted, "File shouldn't have been deleted\n" );
3347 CloseHandle( handle2 );
3349 ok( fileDeleted, "File should have been deleted\n" );
3350
3351 /* file is deleted after handle with FILE_DISPOSITION_POSIX_SEMANTICS is closed */
3352 /* FileDispositionInformationEx is only supported on Windows 10 build 1809 and later */
3353 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3355 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3357 ok( handle2 != INVALID_HANDLE_VALUE, "failed to open temp file\n" );
3359 res = pNtSetInformationFile( handle, &io, &fdie, sizeof fdie, FileDispositionInformationEx );
3361 "unexpected FileDispositionInformationEx result (expected STATUS_SUCCESS or SSTATUS_INVALID_INFO_CLASS, got %lx)\n", res );
3363 if ( res == STATUS_SUCCESS )
3364 {
3366 ok( fileDeleted, "File should have been deleted\n" );
3367 }
3368 CloseHandle( handle2 );
3369
3370 /* file is deleted after handle with FILE_DISPOSITION_POSIX_SEMANTICS is closed */
3371 /* FileDispositionInformationEx is only supported on Windows 10 build 1809 and later */
3372 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3374 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3376 ok( handle2 != INVALID_HANDLE_VALUE, "failed to open temp file\n" );
3378 res = pNtSetInformationFile( handle, &io, &fdie, sizeof fdie, FileDispositionInformationEx );
3380 "unexpected FileDispositionInformationEx result (expected STATUS_SUCCESS or SSTATUS_INVALID_INFO_CLASS, got %lx)\n", res );
3381 CloseHandle( handle2 );
3383 ok( !fileDeleted, "File shouldn't have been deleted\n" );
3385 if ( res == STATUS_SUCCESS )
3386 {
3388 ok( fileDeleted, "File should have been deleted\n" );
3389 }
3390
3391 /* cannot set disposition on readonly file */
3392 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3395 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3396 fdi.DoDeleteFile = TRUE;
3397 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
3398 ok( res == STATUS_CANNOT_DELETE, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %lx)\n", res );
3401 ok( !fileDeleted, "File shouldn't have been deleted\n" );
3404
3405 /* cannot set disposition on readonly file */
3406 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3408 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3409 fdi.DoDeleteFile = TRUE;
3410 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
3411 todo_wine
3412 ok( res == STATUS_CANNOT_DELETE, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %lx)\n", res );
3415 todo_wine
3416 ok( !fileDeleted, "File shouldn't have been deleted\n" );
3419
3420 /* set disposition on readonly file ignoring readonly attribute */
3421 /* FileDispositionInformationEx is only supported on Windows 10 build 1809 and later */
3422 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3425 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3427 res = pNtSetInformationFile( handle, &io, &fdie, sizeof fdie, FileDispositionInformationEx );
3429 || broken(res == STATUS_INVALID_INFO_CLASS) /* win10 1507 & 32-bit 1607 */
3430 || broken(res == STATUS_NOT_SUPPORTED), /* win10 1709 & 64-bit 1607 */
3431 "unexpected FileDispositionInformationEx result (expected STATUS_SUCCESS or SSTATUS_INVALID_INFO_CLASS, got %lx)\n", res );
3433 if ( res == STATUS_SUCCESS )
3434 {
3436 ok( fileDeleted, "File should have been deleted\n" );
3437 }
3440
3441 /* can set disposition on file and then reset it */
3442 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3444 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3445 fdi.DoDeleteFile = TRUE;
3446 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
3447 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %lx)\n", res );
3448 fdi.DoDeleteFile = FALSE;
3449 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
3450 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %lx)\n", res );
3453 ok( !fileDeleted, "File shouldn't have been deleted\n" );
3455
3456 /* can't reset disposition if delete-on-close flag is specified */
3457 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3459 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3460 fdi.DoDeleteFile = FALSE;
3461 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
3462 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %lx)\n", res );
3465 ok( fileDeleted, "File should have been deleted\n" );
3466
3467 /* can't reset disposition on duplicated handle if delete-on-close flag is specified */
3468 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3470 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3471 ok( DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(), &handle2, 0, FALSE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" );
3474 ok( !fileDeleted, "File shouldn't have been deleted\n" );
3475 fdi.DoDeleteFile = FALSE;
3476 res = pNtSetInformationFile( handle2, &io, &fdi, sizeof fdi, FileDispositionInformation );
3477 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %lx)\n", res );
3478 CloseHandle( handle2 );
3480 ok( fileDeleted, "File should have been deleted\n" );
3481
3482 /* can reset delete-on-close flag through FileDispositionInformationEx */
3483 /* FileDispositionInformationEx is only supported on Windows 10 build 1809 and later */
3484 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3486 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3488 res = pNtSetInformationFile( handle, &io, &fdie, sizeof fdie, FileDispositionInformationEx );
3490 "unexpected FileDispositionInformationEx result (expected STATUS_SUCCESS or SSTATUS_INVALID_INFO_CLASS, got %lx)\n", res );
3492 if ( res == STATUS_SUCCESS )
3493 {
3495 ok( !fileDeleted, "File shouldn't have been deleted\n" );
3497 }
3498
3499 /* DeleteFile fails for wrong sharing mode */
3500 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3502 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3503 fileDeleted = DeleteFileA( buffer );
3504 ok( !fileDeleted, "File shouldn't have been deleted\n" );
3508 ok( !fileDeleted, "File shouldn't have been deleted\n" );
3510
3511 /* DeleteFile succeeds for proper sharing mode */
3512 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3514 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3516 ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res);
3517 ok(!fsi.DeletePending, "Handle shouldn't be marked for deletion\n");
3518 fileDeleted = DeleteFileA( buffer );
3519 ok( fileDeleted, "File should have been deleted\n" );
3521 ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res);
3522 todo_wine
3523 ok(fsi.DeletePending, "Handle should be marked for deletion\n");
3524 res = nt_get_file_attrs( buffer, &fdi2 );
3525 todo_wine
3527 /* can't open the deleted file */
3529 todo_wine
3530 ok( handle2 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
3531 todo_wine
3533 if (handle2 != INVALID_HANDLE_VALUE)
3534 CloseHandle( handle2);
3537 ok( fileDeleted, "File should have been deleted\n" );
3538
3539 /* can set disposition on a directory opened with proper access */
3540 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3542 ok( CreateDirectoryA( buffer, NULL ), "CreateDirectory failed\n" );
3544 ok( handle != INVALID_HANDLE_VALUE, "failed to open a directory\n" );
3545 fdi.DoDeleteFile = TRUE;
3546 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
3547 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %lx)\n", res );
3550 ok( fileDeleted, "Directory should have been deleted\n" );
3551
3552 /* RemoveDirectory fails for wrong sharing mode */
3553 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3555 ok( CreateDirectoryA( buffer, NULL ), "CreateDirectory failed\n" );
3557 ok( handle != INVALID_HANDLE_VALUE, "failed to open a directory\n" );
3558 fileDeleted = RemoveDirectoryA( buffer );
3559 ok( !fileDeleted, "Directory shouldn't have been deleted\n" );
3563 ok( !fileDeleted, "Directory shouldn't have been deleted\n" );
3565
3566 /* RemoveDirectory succeeds for proper sharing mode */
3567 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3569 ok( CreateDirectoryA( buffer, NULL ), "CreateDirectory failed\n" );
3571 ok( handle != INVALID_HANDLE_VALUE, "failed to open a directory\n" );
3573 ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res);
3574 ok(!fsi.DeletePending, "Handle shouldn't be marked for deletion\n");
3575 fileDeleted = RemoveDirectoryA( buffer );
3576 ok( fileDeleted, "Directory should have been deleted\n" );
3578 ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res);
3579 todo_wine
3580 ok(fsi.DeletePending, "Handle should be marked for deletion\n");
3581 res = nt_get_file_attrs( buffer, &fdi2 );
3582 todo_wine
3584 /* can't open the deleted directory */
3586 todo_wine
3587 ok( handle2 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
3588 todo_wine
3590 if (handle2 != INVALID_HANDLE_VALUE) CloseHandle( handle2 );
3593 ok( fileDeleted, "Directory should have been deleted\n" );
3594
3595 /* directory exists until all handles to it get closed */
3596 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3598 ok( CreateDirectoryA( buffer, NULL ), "CreateDirectory failed\n" );
3600 ok( handle != INVALID_HANDLE_VALUE, "failed to open a directory\n" );
3602 ok( handle2 != INVALID_HANDLE_VALUE, "failed to open a directory\n" );
3603 fdi.DoDeleteFile = TRUE;
3604 res = pNtSetInformationFile( handle2, &io, &fdi, sizeof fdi, FileDispositionInformation );
3605 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %lx)\n", res );
3606 res = nt_get_file_attrs( buffer, &fdi2 );
3607 todo_wine
3608 ok( res == STATUS_DELETE_PENDING, "got %#lx\n", res );
3609 /* can't open the deleted directory */
3611 todo_wine
3612 ok( handle3 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
3613 if (handle3 != INVALID_HANDLE_VALUE)
3614 CloseHandle( handle3 );
3615 todo_wine
3616 ok(GetLastError() == ERROR_ACCESS_DENIED, "got %lu\n", GetLastError());
3617 /* can't open the deleted directory (wrong sharing mode) */
3619 ok( handle3 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
3620 todo_wine
3621 ok(GetLastError() == ERROR_ACCESS_DENIED, "got %lu\n", GetLastError());
3622 CloseHandle( handle2 );
3624 ok( !fileDeleted, "Directory shouldn't have been deleted\n" );
3627 ok( fileDeleted, "Directory should have been deleted\n" );
3628
3629 /* directory exists until all handles to it get closed */
3630 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3632 ok( CreateDirectoryA( buffer, NULL ), "CreateDirectory failed\n" );
3634 ok( handle != INVALID_HANDLE_VALUE, "failed to open a directory\n" );
3635 /* can open the marked for delete directory (proper sharing mode) */
3637 ok( handle2 != INVALID_HANDLE_VALUE, "failed to open a directory\n" );
3638 /* can't open the marked for delete file (wrong sharing mode) */
3640 ok( handle3 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
3644 ok( !fileDeleted, "Directory shouldn't have been deleted\n" );
3645 CloseHandle( handle2 );
3647 ok( fileDeleted, "Directory should have been deleted\n" );
3648
3649 /* can open a non-empty directory with FILE_FLAG_DELETE_ON_CLOSE */
3650 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3652 ok( CreateDirectoryA( buffer, NULL ), "CreateDirectory failed\n" );
3653 dirpos = lstrlenA( buffer );
3654 lstrcpyA( buffer + dirpos, "\\tst" );
3655 handle2 = CreateFileA(buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
3656 CloseHandle( handle2 );
3657 buffer[dirpos] = '\0';
3659 ok( handle != INVALID_HANDLE_VALUE, "failed to open a directory\n" );
3660 SetLastError(0xdeadbeef);
3662 ok(GetLastError() == 0xdeadbeef, "got %lu\n", GetLastError());
3664 ok( !fileDeleted, "Directory shouldn't have been deleted\n" );
3665 buffer[dirpos] = '\\';
3666 fileDeleted = DeleteFileA( buffer );
3667 ok( fileDeleted, "File should have been deleted\n" );
3668 buffer[dirpos] = '\0';
3669 fileDeleted = RemoveDirectoryA( buffer );
3670 ok( fileDeleted, "Directory should have been deleted\n" );
3671
3672 /* cannot set disposition on a non-empty directory */
3673 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3675 ok( CreateDirectoryA( buffer, NULL ), "CreateDirectory failed\n" );
3677 ok( handle != INVALID_HANDLE_VALUE, "failed to open a directory\n" );
3678 dirpos = lstrlenA( buffer );
3679 lstrcpyA( buffer + dirpos, "\\tst" );
3680 handle2 = CreateFileA(buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
3681 CloseHandle( handle2 );
3682 fdi.DoDeleteFile = TRUE;
3683 res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
3684 ok( res == STATUS_DIRECTORY_NOT_EMPTY, "unexpected FileDispositionInformation result (expected STATUS_DIRECTORY_NOT_EMPTY, got %lx)\n", res );
3685 fileDeleted = DeleteFileA( buffer );
3686 ok( fileDeleted, "File should have been deleted\n" );
3687 buffer[dirpos] = '\0';
3690 ok( !fileDeleted, "Directory shouldn't have been deleted\n" );
3691 fileDeleted = RemoveDirectoryA( buffer );
3692 ok( fileDeleted, "Directory should have been deleted\n" );
3693
3694 /* a file with an open mapping handle cannot be deleted */
3695
3696 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3698 ok( handle != INVALID_HANDLE_VALUE, "failed to create file, error %lu\n", GetLastError() );
3699 WriteFile(handle, "data", 4, &size, NULL);
3701 ok( !!mapping, "failed to create mapping, error %lu\n", GetLastError() );
3702
3703 fdi.DoDeleteFile = FALSE;
3704 res = pNtSetInformationFile( handle, &io, &fdi, sizeof(fdi), FileDispositionInformation );
3705 ok( !res, "got %#lx\n", res );
3706
3707 fdi.DoDeleteFile = TRUE;
3708 res = pNtSetInformationFile( handle, &io, &fdi, sizeof(fdi), FileDispositionInformation );
3709 ok( res == STATUS_CANNOT_DELETE, "got %#lx\n", res );
3711 ok( res != INVALID_FILE_ATTRIBUTES, "expected file to exist\n" );
3712
3715 res = DeleteFileA( buffer );
3716 ok( res, "got error %lu\n", GetLastError() );
3717
3718 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3720 ok( handle != INVALID_HANDLE_VALUE, "failed to create file, error %lu\n", GetLastError() );
3721 WriteFile(handle, "data", 4, &size, NULL);
3723 ok( !!mapping, "failed to create mapping, error %lu\n", GetLastError() );
3725
3726 fdi.DoDeleteFile = TRUE;
3727 res = pNtSetInformationFile( handle, &io, &fdi, sizeof(fdi), FileDispositionInformation );
3728 ok( !res, "got %#lx\n", res );
3729
3731 res = DeleteFileA( buffer );
3732 ok( !res, "expected failure\n" );
3733 ok( GetLastError() == ERROR_FILE_NOT_FOUND, "got error %lu\n", GetLastError() );
3734
3735 /* a file with an open view cannot be deleted */
3736
3737 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3739 ok( handle != INVALID_HANDLE_VALUE, "failed to create file, error %lu\n", GetLastError() );
3740 WriteFile(handle, "data", 4, &size, NULL);
3742 ok( !!mapping, "failed to create mapping, error %lu\n", GetLastError() );
3743 view = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4 );
3744 ok( !!view, "failed to map view, error %lu\n", GetLastError() );
3746
3747 fdi.DoDeleteFile = FALSE;
3748 res = pNtSetInformationFile( handle, &io, &fdi, sizeof(fdi), FileDispositionInformation );
3749 ok( !res, "got %#lx\n", res );
3750
3751 fdi.DoDeleteFile = TRUE;
3752 res = pNtSetInformationFile( handle, &io, &fdi, sizeof(fdi), FileDispositionInformation );
3753 ok( res == STATUS_CANNOT_DELETE, "got %#lx\n", res );
3755 ok( res != INVALID_FILE_ATTRIBUTES, "expected file to exist\n" );
3756
3759 res = DeleteFileA( buffer );
3760 ok( res, "got error %lu\n", GetLastError() );
3761
3762 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3764 ok( handle != INVALID_HANDLE_VALUE, "failed to create file, error %lu\n", GetLastError() );
3765 WriteFile(handle, "data", 4, &size, NULL);
3767 ok( !!mapping, "failed to create mapping, error %lu\n", GetLastError() );
3768 view = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 4 );
3769 ok( !!view, "failed to map view, error %lu\n", GetLastError() );
3772
3773 fdi.DoDeleteFile = TRUE;
3774 res = pNtSetInformationFile( handle, &io, &fdi, sizeof(fdi), FileDispositionInformation );
3775 ok( !res, "got %#lx\n", res );
3776
3778 res = DeleteFileA( buffer );
3779 ok( !res, "expected failure\n" );
3780 ok( GetLastError() == ERROR_FILE_NOT_FOUND, "got error %lu\n", GetLastError() );
3781
3782 /* pending delete flag is shared across handles */
3783 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3785 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3787 ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res);
3788 ok(!fsi.DeletePending, "Handle shouldn't be marked for deletion\n");
3790 ok( handle2 != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3791 res = NtQueryInformationFile(handle2, &io, &fsi, sizeof(fsi), FileStandardInformation);
3792 ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res);
3793 ok(!fsi.DeletePending, "Handle shouldn't be marked for deletion\n");
3794 fdi.DoDeleteFile = TRUE;
3796 ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res);
3797 res = NtQueryInformationFile(handle2, &io, &fsi, sizeof(fsi), FileStandardInformation);
3798 ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res);
3799 todo_wine
3800 ok(fsi.DeletePending, "Handle should be marked for deletion\n");
3801 fdi.DoDeleteFile = FALSE;
3802 res = NtSetInformationFile(handle2, &io, &fdi, sizeof(fdi), FileDispositionInformation);
3803 ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res);
3805 ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res);
3806 ok(!fsi.DeletePending, "Handle shouldn't be marked for deletion\n");
3808 CloseHandle(handle2);
3810 todo_wine
3811 ok( res != INVALID_FILE_ATTRIBUTES, "expected file to exist\n" );
3812
3813 /* pending delete flag is shared across handles (even after closing) */
3814 GetTempFileNameA( tmp_path, "dis", 0, buffer );
3816 ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3818 ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res);
3819 ok(!fsi.DeletePending, "Handle shouldn't be marked for deletion\n");
3821 ok( handle2 != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
3822 res = NtQueryInformationFile(handle2, &io, &fsi, sizeof(fsi), FileStandardInformation);
3823 ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res);
3824 ok(!fsi.DeletePending, "Handle shouldn't be marked for deletion\n");
3825 fdi.DoDeleteFile = TRUE;
3827 ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res);
3828 res = NtQueryInformationFile(handle2, &io, &fsi, sizeof(fsi), FileStandardInformation);
3829 ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res);
3830 todo_wine
3831 ok(fsi.DeletePending, "Handle should be marked for deletion\n");
3832 fdi.DoDeleteFile = FALSE;
3833 res = NtSetInformationFile(handle2, &io, &fdi, sizeof(fdi), FileDispositionInformation);
3834 ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res);
3835 CloseHandle(handle2);
3837 ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res);
3838 ok(!fsi.DeletePending, "Handle shouldn't be marked for deletion\n");
3841 todo_wine
3842 ok( res != INVALID_FILE_ATTRIBUTES, "expected file to exist\n" );
3843}
3844
3846{
3847 WCHAR *file_name, *volume_prefix, *expected;
3849 ULONG old_redir = 1, tmp;
3850 UINT file_name_size;
3852 UINT info_size;
3853 HRESULT hr;
3854 HANDLE h;
3855 UINT len;
3856
3857 /* GetVolumePathName is not present before w2k */
3858 if (!pGetVolumePathNameW) {
3859 win_skip("GetVolumePathNameW not found\n");
3860 return;
3861 }
3862
3863 file_name_size = GetSystemDirectoryW( NULL, 0 );
3864 file_name = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*file_name) );
3865 volume_prefix = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*volume_prefix) );
3866 expected = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*volume_prefix) );
3867
3868 len = GetSystemDirectoryW( file_name, file_name_size );
3869 ok(len == file_name_size - 1,
3870 "GetSystemDirectoryW returned %u, expected %u.\n",
3871 len, file_name_size - 1);
3872
3873 len = pGetVolumePathNameW( file_name, volume_prefix, file_name_size );
3874 ok(len, "GetVolumePathNameW failed.\n");
3875
3876 len = lstrlenW( volume_prefix );
3877 if (len && volume_prefix[len - 1] == '\\') --len;
3878 memcpy( expected, file_name + len, (file_name_size - len - 1) * sizeof(WCHAR) );
3879 expected[file_name_size - len - 1] = '\0';
3880
3881 /* A bit more than we actually need, but it keeps the calculation simple. */
3882 info_size = sizeof(*info) + (file_name_size * sizeof(WCHAR));
3883 info = HeapAlloc( GetProcessHeap(), 0, info_size );
3884
3885 if (pRtlWow64EnableFsRedirectionEx) pRtlWow64EnableFsRedirectionEx( TRUE, &old_redir );
3889 if (pRtlWow64EnableFsRedirectionEx) pRtlWow64EnableFsRedirectionEx( old_redir, &tmp );
3890 ok(h != INVALID_HANDLE_VALUE, "Failed to open file.\n");
3891
3892 hr = pNtQueryInformationFile( h, &io, info, sizeof(*info) - 1, FileNameInformation );
3893 ok(hr == STATUS_INFO_LENGTH_MISMATCH, "NtQueryInformationFile returned %#lx.\n", hr);
3894
3895 memset( info, 0xcc, info_size );
3896 hr = pNtQueryInformationFile( h, &io, info, sizeof(*info), FileNameInformation );
3897 ok(hr == STATUS_BUFFER_OVERFLOW, "NtQueryInformationFile returned %#lx, expected %#lx.\n",
3899 ok(io.Status == STATUS_BUFFER_OVERFLOW, "io.Status is %#lx, expected %#lx.\n",
3900 io.Status, STATUS_BUFFER_OVERFLOW);
3901 ok(info->FileNameLength == lstrlenW( expected ) * sizeof(WCHAR), "info->FileNameLength is %lu\n", info->FileNameLength);
3902 ok(info->FileName[2] == 0xcccc, "info->FileName[2] is %#x, expected 0xcccc.\n", info->FileName[2]);
3904 "info->FileName[1] is %p, expected %p.\n",
3906 ok(io.Information == sizeof(*info), "io.Information is %Iu\n", io.Information);
3907
3908 memset( info, 0xcc, info_size );
3909 hr = pNtQueryInformationFile( h, &io, info, info_size, FileNameInformation );
3910 ok(hr == STATUS_SUCCESS, "NtQueryInformationFile returned %#lx, expected %#lx.\n", hr, STATUS_SUCCESS);
3911 ok(io.Status == STATUS_SUCCESS, "io.Status is %#lx, expected %#lx.\n", io.Status, STATUS_SUCCESS);
3912 ok(info->FileNameLength == lstrlenW( expected ) * sizeof(WCHAR), "info->FileNameLength is %lu\n", info->FileNameLength);
3913 ok(info->FileName[info->FileNameLength / sizeof(WCHAR)] == 0xcccc, "info->FileName[len] is %#x, expected 0xcccc.\n",
3914 info->FileName[info->FileNameLength / sizeof(WCHAR)]);
3915 info->FileName[info->FileNameLength / sizeof(WCHAR)] = '\0';
3916 ok(!lstrcmpiW( info->FileName, expected ), "info->FileName is %s, expected %s.\n",
3917 wine_dbgstr_w( info->FileName ), wine_dbgstr_w( expected ));
3918 ok(io.Information == FIELD_OFFSET(FILE_NAME_INFORMATION, FileName) + info->FileNameLength,
3919 "io.Information is %Iu, expected %lu.\n",
3920 io.Information, FIELD_OFFSET(FILE_NAME_INFORMATION, FileName) + info->FileNameLength);
3921
3922 CloseHandle( h );
3923 HeapFree( GetProcessHeap(), 0, info );
3925 HeapFree( GetProcessHeap(), 0, volume_prefix );
3926
3927 if (old_redir || !pGetSystemWow64DirectoryW || !(file_name_size = pGetSystemWow64DirectoryW( NULL, 0 )))
3928 {
3929 skip("Not running on WoW64, skipping test.\n");
3931 return;
3932 }
3933
3937 ok(h != INVALID_HANDLE_VALUE, "Failed to open file.\n");
3939
3940 file_name = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*file_name) );
3941 volume_prefix = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*volume_prefix) );
3942 expected = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*expected) );
3943
3944 len = pGetSystemWow64DirectoryW( file_name, file_name_size );
3945 ok(len == file_name_size - 1,
3946 "GetSystemWow64DirectoryW returned %u, expected %u.\n",
3947 len, file_name_size - 1);
3948
3949 len = pGetVolumePathNameW( file_name, volume_prefix, file_name_size );
3950 ok(len, "GetVolumePathNameW failed.\n");
3951
3952 len = lstrlenW( volume_prefix );
3953 if (len && volume_prefix[len - 1] == '\\') --len;
3954 memcpy( expected, file_name + len, (file_name_size - len - 1) * sizeof(WCHAR) );
3955 expected[file_name_size - len - 1] = '\0';
3956
3957 info_size = sizeof(*info) + (file_name_size * sizeof(WCHAR));
3958 info = HeapAlloc( GetProcessHeap(), 0, info_size );
3959
3960 memset( info, 0xcc, info_size );
3961 hr = pNtQueryInformationFile( h, &io, info, info_size, FileNameInformation );
3962 ok(hr == STATUS_SUCCESS, "NtQueryInformationFile returned %#lx, expected %#lx.\n", hr, STATUS_SUCCESS);
3963 info->FileName[info->FileNameLength / sizeof(WCHAR)] = '\0';
3964 ok(!lstrcmpiW( info->FileName, expected ), "info->FileName is %s, expected %s.\n",
3965 wine_dbgstr_w( info->FileName ), wine_dbgstr_w( expected ));
3966
3967 CloseHandle( h );
3968 HeapFree( GetProcessHeap(), 0, info );
3970 HeapFree( GetProcessHeap(), 0, volume_prefix );
3972}
3973
3975{
3976 WCHAR *file_name, *volume_prefix, *expected;
3978 ULONG old_redir = 1, tmp;
3979 UINT file_name_size;
3981 UINT info_size;
3982 HRESULT hr;
3983 HANDLE h;
3984 UINT len;
3985
3986 /* GetVolumePathName is not present before w2k */
3987 if (!pGetVolumePathNameW) {
3988 win_skip("GetVolumePathNameW not found\n");
3989 return;
3990 }
3991
3992 file_name_size = GetSystemDirectoryW( NULL, 0 );
3993 file_name = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*file_name) );
3994 volume_prefix = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*volume_prefix) );
3995 expected = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*volume_prefix) );
3996
3997 len = GetSystemDirectoryW( file_name, file_name_size );
3998 ok(len == file_name_size - 1,
3999 "GetSystemDirectoryW returned %u, expected %u.\n",
4000 len, file_name_size - 1);
4001
4002 len = pGetVolumePathNameW( file_name, volume_prefix, file_name_size );
4003 ok(len, "GetVolumePathNameW failed.\n");
4004
4005 len = lstrlenW( volume_prefix );
4006 if (len && volume_prefix[len - 1] == '\\') --len;
4007 memcpy( expected, file_name + len, (file_name_size - len - 1) * sizeof(WCHAR) );
4008 expected[file_name_size - len - 1] = '\0';
4009
4010 /* A bit more than we actually need, but it keeps the calculation simple. */
4011 info_size = sizeof(*info) + (file_name_size * sizeof(WCHAR));
4012 info = HeapAlloc( GetProcessHeap(), 0, info_size );
4013
4014 if (pRtlWow64EnableFsRedirectionEx) pRtlWow64EnableFsRedirectionEx( TRUE, &old_redir );
4018 if (pRtlWow64EnableFsRedirectionEx) pRtlWow64EnableFsRedirectionEx( old_redir, &tmp );
4019 ok(h != INVALID_HANDLE_VALUE, "Failed to open file.\n");
4020
4021 hr = pNtQueryInformationFile( h, &io, info, sizeof(*info) - 1, FileAllInformation );
4022 ok(hr == STATUS_INFO_LENGTH_MISMATCH, "NtQueryInformationFile returned %#lx, expected %#lx.\n",
4024
4025 memset( info, 0xcc, info_size );
4026 hr = pNtQueryInformationFile( h, &io, info, sizeof(*info), FileAllInformation );
4027 ok(hr == STATUS_BUFFER_OVERFLOW, "NtQueryInformationFile returned %#lx, expected %#lx.\n",
4029 ok(io.Status == STATUS_BUFFER_OVERFLOW, "io.Status is %#lx, expected %#lx.\n",
4030 io.Status, STATUS_BUFFER_OVERFLOW);
4031 ok(info->NameInformation.FileNameLength == lstrlenW( expected ) * sizeof(WCHAR),
4032 "info->NameInformation.FileNameLength is %lu\n", info->NameInformation.FileNameLength );
4033 ok(info->NameInformation.FileName[2] == 0xcccc,
4034 "info->NameInformation.FileName[2] is %#x, expected 0xcccc.\n", info->NameInformation.FileName[2]);
4035 ok(CharLowerW((LPWSTR)(UINT_PTR)info->NameInformation.FileName[1]) == CharLowerW((LPWSTR)(UINT_PTR)expected[1]),
4036 "info->NameInformation.FileName[1] is %p, expected %p.\n",
4037 CharLowerW((LPWSTR)(UINT_PTR)info->NameInformation.FileName[1]), CharLowerW((LPWSTR)(UINT_PTR)expected[1]));
4038 ok(io.Information == sizeof(*info), "io.Information is %Iu\n", io.Information);
4039
4040 memset( info, 0xcc, info_size );
4041 hr = pNtQueryInformationFile( h, &io, info, info_size, FileAllInformation );
4042 ok(hr == STATUS_SUCCESS, "NtQueryInformationFile returned %#lx, expected %#lx.\n", hr, STATUS_SUCCESS);
4043 ok(io.Status == STATUS_SUCCESS, "io.Status is %#lx, expected %#lx.\n", io.Status, STATUS_SUCCESS);
4044 ok(info->NameInformation.FileNameLength == lstrlenW( expected ) * sizeof(WCHAR),
4045 "info->NameInformation.FileNameLength is %lu\n", info->NameInformation.FileNameLength );
4046 ok(info->NameInformation.FileName[info->NameInformation.FileNameLength / sizeof(WCHAR)] == 0xcccc,
4047 "info->NameInformation.FileName[len] is %#x, expected 0xcccc.\n",
4048 info->NameInformation.FileName[info->NameInformation.FileNameLength / sizeof(WCHAR)]);
4049 info->NameInformation.FileName[info->NameInformation.FileNameLength / sizeof(WCHAR)] = '\0';
4050 ok(!lstrcmpiW( info->NameInformation.FileName, expected ),
4051 "info->NameInformation.FileName is %s, expected %s.\n",
4052 wine_dbgstr_w( info->NameInformation.FileName ), wine_dbgstr_w( expected ));
4053 ok(io.Information == FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName)
4054 + info->NameInformation.FileNameLength,
4055 "io.Information is %Iu\n", io.Information );
4056
4057 CloseHandle( h );
4058 HeapFree( GetProcessHeap(), 0, info );
4060 HeapFree( GetProcessHeap(), 0, volume_prefix );
4061
4062 if (old_redir || !pGetSystemWow64DirectoryW || !(file_name_size = pGetSystemWow64DirectoryW( NULL, 0 )))
4063 {
4064 skip("Not running on WoW64, skipping test.\n");
4066 return;
4067 }
4068
4072 ok(h != INVALID_HANDLE_VALUE, "Failed to open file.\n");
4074
4075 file_name = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*file_name) );
4076 volume_prefix = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*volume_prefix) );
4077 expected = HeapAlloc( GetProcessHeap(), 0, file_name_size * sizeof(*expected) );
4078
4079 len = pGetSystemWow64DirectoryW( file_name, file_name_size );
4080 ok(len == file_name_size - 1,
4081 "GetSystemWow64DirectoryW returned %u, expected %u.\n",
4082 len, file_name_size - 1);
4083
4084 len = pGetVolumePathNameW( file_name, volume_prefix, file_name_size );
4085 ok(len, "GetVolumePathNameW failed.\n");
4086
4087 len = lstrlenW( volume_prefix );
4088 if (len && volume_prefix[len - 1] == '\\') --len;
4089 memcpy( expected, file_name + len, (file_name_size - len - 1) * sizeof(WCHAR) );
4090 expected[file_name_size - len - 1] = '\0';
4091
4092 info_size = sizeof(*info) + (file_name_size * sizeof(WCHAR));
4093 info = HeapAlloc( GetProcessHeap(), 0, info_size );
4094
4095 memset( info, 0xcc, info_size );
4096 hr = pNtQueryInformationFile( h, &io, info, info_size, FileAllInformation );
4097 ok(hr == STATUS_SUCCESS, "NtQueryInformationFile returned %#lx, expected %#lx.\n", hr, STATUS_SUCCESS);
4098 info->NameInformation.FileName[info->NameInformation.FileNameLength / sizeof(WCHAR)] = '\0';
4099 ok(!lstrcmpiW( info->NameInformation.FileName, expected ), "info->NameInformation.FileName is %s, expected %s.\n",
4100 wine_dbgstr_w( info->NameInformation.FileName ), wine_dbgstr_w( expected ));
4101
4102 CloseHandle( h );
4103 HeapFree( GetProcessHeap(), 0, info );
4105 HeapFree( GetProcessHeap(), 0, volume_prefix );
4107}
4108
4109#define test_completion_flags(a,b) _test_completion_flags(__LINE__,a,b)
4110static void _test_completion_flags(unsigned line, HANDLE handle, DWORD expected_flags)
4111{
4115
4116 info.Flags = 0xdeadbeef;
4117 status = pNtQueryInformationFile(handle, &io, &info, sizeof(info),
4119 ok_(__FILE__,line)(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08lx\n", status);
4120 ok_(__FILE__,line)(io.Status == STATUS_SUCCESS, "Status = %lx\n", io.Status);
4121 ok_(__FILE__,line)(io.Information == sizeof(info), "Information = %Iu\n", io.Information);
4122 ok_(__FILE__,line)((info.Flags & expected_flags) == expected_flags, "got %08lx\n", info.Flags);
4123}
4124
4126{
4127 DECLSPEC_ALIGN(TEST_OVERLAPPED_READ_SIZE) static unsigned char aligned_buf[TEST_OVERLAPPED_READ_SIZE];
4128 static const char pipe_name[] = "\\\\.\\pipe\\test_file_completion_information";
4129 static const char buf[] = "testdata";
4133 BYTE recv_buf[TEST_BUF_LEN];
4134 DWORD num_bytes, flag;
4135 OVERLAPPED ov, *pov;
4138 ULONG_PTR key;
4139 BOOL ret;
4140 int i;
4141
4142 if (!(h = create_temp_file(0))) return;
4143
4144 status = pNtSetInformationFile(h, &io, &info, sizeof(info) - 1, FileIoCompletionNotificationInformation);
4146 "expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status);
4148 {
4149 win_skip("FileIoCompletionNotificationInformation class not supported\n");
4150 CloseHandle(h);
4151 return;
4152 }
4153
4155 status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
4156 ok(status == STATUS_INVALID_PARAMETER, "expected STATUS_INVALID_PARAMETER, got %08lx\n", status);
4157
4158 CloseHandle(h);
4159 if (!(h = create_temp_file(FILE_FLAG_OVERLAPPED))) return;
4160
4162 status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
4163 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08lx\n", status);
4165
4167 status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
4168 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08lx\n", status);
4170
4171 info.Flags = 0;
4172 status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
4173 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08lx\n", status);
4175
4177 status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
4178 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08lx\n", status);
4180
4181 info.Flags = 0xdeadbeef;
4182 status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
4183 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08lx\n", status);
4185
4186 CloseHandle(h);
4187 if (!(h = create_temp_file(FILE_FLAG_OVERLAPPED))) return;
4189
4190 memset(&ov, 0, sizeof(ov));
4192 port = CreateIoCompletionPort(h, NULL, 0xdeadbeef, 0);
4193 ok(port != NULL, "CreateIoCompletionPort failed, error %lu\n", GetLastError());
4194
4195 for (i = 0; i < 10; i++)
4196 {
4197 SetLastError(0xdeadbeef);
4198 ret = WriteFile(h, buf, sizeof(buf), &num_bytes, &ov);
4199 ok((!ret && GetLastError() == ERROR_IO_PENDING) || broken(ret) /* Before Vista */,
4200 "Unexpected result %#x, GetLastError() %lu.\n", ret, GetLastError());
4201 if (ret || GetLastError() != ERROR_IO_PENDING) break;
4202 ret = GetOverlappedResult(h, &ov, &num_bytes, TRUE);
4203 ok(ret, "GetOverlappedResult failed, error %lu\n", GetLastError());
4204 ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 1000);
4205 ok(ret, "GetQueuedCompletionStatus failed, error %lu\n", GetLastError());
4206 ret = FALSE;
4207 }
4208 if (ret)
4209 {
4210 ok(num_bytes == sizeof(buf), "expected sizeof(buf), got %lu\n", num_bytes);
4211
4212 key = 0;
4213 pov = NULL;
4214 ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 1000);
4215 ok(ret, "GetQueuedCompletionStatus failed, error %lu\n", GetLastError());
4216 ok(key == 0xdeadbeef, "expected 0xdeadbeef, got %Ix\n", key);
4217 ok(pov == &ov, "expected %p, got %p\n", &ov, pov);
4218 }
4219
4221 status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
4222 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08lx\n", status);
4224
4225 for (i = 0; i < 10; i++)
4226 {
4227 SetLastError(0xdeadbeef);
4228 ret = WriteFile(h, buf, sizeof(buf), &num_bytes, &ov);
4229 ok((!ret && GetLastError() == ERROR_IO_PENDING) || broken(ret) /* Before Vista */,
4230 "Unexpected result %#x, GetLastError() %lu.\n", ret, GetLastError());
4231 if (ret || GetLastError() != ERROR_IO_PENDING) break;
4232 ret = GetOverlappedResult(h, &ov, &num_bytes, TRUE);
4233 ok(ret, "GetOverlappedResult failed, error %lu\n", GetLastError());
4234 ret = FALSE;
4235 }
4236 if (ret)
4237 {
4238 ok(num_bytes == sizeof(buf), "expected sizeof(buf), got %lu\n", num_bytes);
4239
4240 pov = (void *)0xdeadbeef;
4241 ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 500);
4242 ok(!ret, "GetQueuedCompletionStatus succeeded\n");
4243 ok(pov == NULL, "expected NULL, got %p\n", pov);
4244 }
4245
4246 info.Flags = 0;
4247 status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
4248 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08lx\n", status);
4250
4251 for (i = 0; i < 10; i++)
4252 {
4253 SetLastError(0xdeadbeef);
4254 ret = WriteFile(h, buf, sizeof(buf), &num_bytes, &ov);
4255 ok((!ret && GetLastError() == ERROR_IO_PENDING) || broken(ret) /* Before Vista */,
4256 "Unexpected result %#x, GetLastError() %lu.\n", ret, GetLastError());
4257 if (ret || GetLastError() != ERROR_IO_PENDING) break;
4258 ret = GetOverlappedResult(h, &ov, &num_bytes, TRUE);
4259 ok(ret, "GetOverlappedResult failed, error %lu\n", GetLastError());
4260 ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 1000);
4261 ok(ret, "GetQueuedCompletionStatus failed, error %lu\n", GetLastError());
4262 ret = FALSE;
4263 }
4264 if (ret)
4265 {
4266 ok(num_bytes == sizeof(buf), "expected sizeof(buf), got %lu\n", num_bytes);
4267
4268 pov = (void *)0xdeadbeef;
4269 ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 1000);
4270 ok(!ret, "GetQueuedCompletionStatus succeeded\n");
4271 ok(pov == NULL, "expected NULL, got %p\n", pov);
4272 }
4273
4275 CloseHandle(h);
4276
4278 return;
4279
4280 port = CreateIoCompletionPort(h, NULL, 0xdeadbeef, 0);
4281 ok(port != NULL, "CreateIoCompletionPort failed, error %lu.\n", GetLastError());
4282
4284 status = pNtSetInformationFile(h, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
4285 ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %#lx.\n", status);
4287
4288 ret = WriteFile(h, aligned_buf, sizeof(aligned_buf), &num_bytes, &ov);
4289 if (!ret && GetLastError() == ERROR_IO_PENDING)
4290 {
4291 ret = GetOverlappedResult(h, &ov, &num_bytes, TRUE);
4292 ok(ret, "GetOverlappedResult failed, error %lu.\n", GetLastError());
4293 ok(num_bytes == sizeof(aligned_buf), "expected sizeof(aligned_buf), got %lu.\n", num_bytes);
4294 ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 1000);
4295 ok(ret, "GetQueuedCompletionStatus failed, error %lu.\n", GetLastError());
4296 }
4297 ok(num_bytes == sizeof(aligned_buf), "expected sizeof(buf), got %lu.\n", num_bytes);
4298
4299 SetLastError(0xdeadbeef);
4300 ret = ReadFile(h, aligned_buf, sizeof(aligned_buf), &num_bytes, &ov);
4301 ok(!ret && GetLastError() == ERROR_IO_PENDING, "Unexpected result, ret %#x, error %lu.\n",
4302 ret, GetLastError());
4303 ret = GetOverlappedResult(h, &ov, &num_bytes, TRUE);
4304 ok(ret, "GetOverlappedResult failed, error %lu.\n", GetLastError());
4305 ret = GetQueuedCompletionStatus(port, &num_bytes, &key, &pov, 1000);
4306 ok(ret, "GetQueuedCompletionStatus failed, error %lu.\n", GetLastError());
4307
4308 CloseHandle(ov.hEvent);
4310 CloseHandle(h);
4311
4312 /* Test that setting FileCompletionInformation makes an overlapped file signaled unless FILE_SKIP_SET_EVENT_ON_HANDLE is set */
4313 for (flag = 0; flag <= FILE_SKIP_SET_USER_EVENT_ON_FAST_IO; flag = flag ? flag << 1 : 1)
4314 {
4315 winetest_push_context("%#lx", flag);
4316
4317 status = pNtCreateIoCompletion(&completion, IO_COMPLETION_ALL_ACCESS, NULL, 0);
4318 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
4319
4322 1000, NULL);
4323 ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed, error %lu.\n", GetLastError());
4326 ok(client != INVALID_HANDLE_VALUE, "CreateFile failed, error %lu.\n", GetLastError());
4327
4328 memset(&ov, 0, sizeof(ov));
4329 ReadFile(server, recv_buf, TEST_BUF_LEN, &num_bytes, &ov);
4330 ok(!is_signaled(server), "Expected not signaled.\n");
4331
4332 info.Flags = flag;
4333 status = pNtSetInformationFile(server, &io, &info, sizeof(info), FileIoCompletionNotificationInformation);
4334#ifdef __REACTOS__
4336 {
4337 ok(status == STATUS_ACCESS_DENIED, "Got unexpected status %#lx.\n", status);
4338 }
4339 else
4340 {
4341#endif
4342 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
4344#ifdef __REACTOS__
4345 }
4346#endif
4347
4350 io.Status = 0xdeadbeef;
4351 status = pNtSetInformationFile(server, &io, &fci, sizeof(fci), FileCompletionInformation);
4352 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
4353 ok(io.Status == STATUS_SUCCESS, "Got unexpected iosb.Status %#lx.\n", io.Status);
4354#ifdef __REACTOS__
4356#else
4358#endif
4359 ok(!is_signaled(server), "Expected not signaled.\n");
4360 else
4361 ok(is_signaled(server), "Expected signaled.\n");
4362
4363 status = pNtClose(client);
4364 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
4365 status = pNtClose(server);
4366 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
4367 status = pNtClose(completion);
4368 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
4370 }
4371}
4372
4374{
4379 DWORD *dwords;
4380 HANDLE h;
4381 BOOL ret;
4382
4383 if (!(h = create_temp_file(0))) return;
4384
4385 memset( &fid, 0x11, sizeof(fid) );
4386 status = pNtQueryInformationFile( h, &io, &fid, sizeof(fid), FileIdInformation );
4388 {
4389 win_skip( "FileIdInformation not supported\n" );
4390 CloseHandle( h );
4391 return;
4392 }
4393
4394 memset( &info, 0x22, sizeof(info) );
4396 ok( ret, "GetFileInformationByHandle failed\n" );
4397
4398 dwords = (DWORD *)&fid.VolumeSerialNumber;
4399 ok( dwords[0] == info.dwVolumeSerialNumber, "expected %08lx, got %08lx\n",
4400 info.dwVolumeSerialNumber, dwords[0] );
4401 ok( dwords[1] != 0x11111111, "expected != 0x11111111\n" );
4402
4403 dwords = (DWORD *)&fid.FileId;
4404 ok( dwords[0] == info.nFileIndexLow, "expected %08lx, got %08lx\n", info.nFileIndexLow, dwords[0] );
4405 ok( dwords[1] == info.nFileIndexHigh, "expected %08lx, got %08lx\n", info.nFileIndexHigh, dwords[1] );
4406 ok( dwords[2] == 0, "expected 0, got %08lx\n", dwords[2] );
4407 ok( dwords[3] == 0, "expected 0, got %08lx\n", dwords[3] );
4408
4409 CloseHandle( h );
4410}
4411
4413{
4417 HANDLE h;
4418
4419 if (!(h = create_temp_file(0))) return;
4420
4421 status = pNtQueryInformationFile( h, &io, &info, sizeof(info) - 1, FileAccessInformation );
4422 ok( status == STATUS_INFO_LENGTH_MISMATCH, "expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status );
4423
4424 status = pNtQueryInformationFile( (HANDLE)0xdeadbeef, &io, &info, sizeof(info), FileAccessInformation );
4425 ok( status == STATUS_INVALID_HANDLE, "expected STATUS_INVALID_HANDLE, got %08lx\n", status );
4426
4427 memset(&info, 0x11, sizeof(info));
4428 status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileAccessInformation );
4429 ok( status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08lx\n", status );
4430 ok( info.AccessFlags == 0x13019f, "got %08lx\n", info.AccessFlags );
4431
4432 CloseHandle( h );
4433}
4434
4436{
4438 FILE_BASIC_INFORMATION fbi = { 0 };
4441 HANDLE h;
4442
4443 if (!(h = create_temp_file(0))) return;
4444
4445 status = pNtQueryInformationFile( h, &io, &info, sizeof(info) - 1, FileAttributeTagInformation );
4446 ok( status == STATUS_INFO_LENGTH_MISMATCH, "got %#lx\n", status );
4447
4448 status = pNtQueryInformationFile( (HANDLE)0xdeadbeef, &io, &info, sizeof(info), FileAttributeTagInformation );
4449 ok( status == STATUS_INVALID_HANDLE, "got %#lx\n", status );
4450
4451 memset(&info, 0x11, sizeof(info));
4452 status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileAttributeTagInformation );
4453 ok( status == STATUS_SUCCESS, "got %#lx\n", status );
4454 info.FileAttributes &= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
4455 ok( info.FileAttributes == FILE_ATTRIBUTE_ARCHIVE, "got attributes %#lx\n", info.FileAttributes );
4456 ok( !info.ReparseTag, "got reparse tag %#lx\n", info.ReparseTag );
4457
4459 status = pNtSetInformationFile(h, &io, &fbi, sizeof(fbi), FileBasicInformation);
4460 ok( status == STATUS_SUCCESS, "got %#lx\n", status );
4461
4462 memset(&info, 0x11, sizeof(info));
4463 status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileAttributeTagInformation );
4464 ok( status == STATUS_SUCCESS, "got %#lx\n", status );
4465 todo_wine ok( info.FileAttributes == FILE_ATTRIBUTE_SYSTEM, "got attributes %#lx\n", info.FileAttributes );
4466 ok( !info.ReparseTag, "got reparse tag %#lx\n", info.ReparseTag );
4467
4469 status = pNtSetInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
4470 ok( status == STATUS_SUCCESS, "got %#lx\n", status );
4471
4472 memset(&info, 0x11, sizeof(info));
4473 status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileAttributeTagInformation );
4474 ok( status == STATUS_SUCCESS, "got %#lx\n", status );
4475 todo_wine ok( info.FileAttributes == FILE_ATTRIBUTE_HIDDEN, "got attributes %#lx\n", info.FileAttributes );
4476 ok( !info.ReparseTag, "got reparse tag %#lx\n", info.ReparseTag );
4477
4478 CloseHandle( h );
4479}
4480
4482{
4487 HANDLE h;
4488 BOOL ret;
4489
4490 if (!(h = create_temp_file(0))) return;
4491
4492 memset( &fsd, 0x11, sizeof(fsd) );
4493 status = pNtQueryInformationFile( h, &io, &fsd, sizeof(fsd), FileStatInformation );
4495 {
4496 win_skip( "FileStatInformation not supported\n" );
4497 CloseHandle( h );
4498 return;
4499 }
4500 ok( status == STATUS_SUCCESS, "query FileStatInformation returned %#lx\n", status );
4501
4502 memset( &info, 0x22, sizeof(info) );
4504 ok( ret, "GetFileInformationByHandle failed\n" );
4505
4506 ok( fsd.FileId.u.LowPart == info.nFileIndexLow, "expected %08lx, got %08lx\n", info.nFileIndexLow, fsd.FileId.u.LowPart );
4507 ok( fsd.FileId.u.HighPart == info.nFileIndexHigh, "expected %08lx, got %08lx\n", info.nFileIndexHigh, fsd.FileId.u.HighPart );
4508 ok( fsd.CreationTime.u.LowPart == info.ftCreationTime.dwLowDateTime, "expected %08lx, got %08lx\n",
4509 info.ftCreationTime.dwLowDateTime, fsd.CreationTime.u.LowPart );
4510 ok( fsd.CreationTime.u.HighPart == info.ftCreationTime.dwHighDateTime, "expected %08lx, got %08lx\n",
4511 info.ftCreationTime.dwHighDateTime, fsd.CreationTime.u.HighPart );
4512 ok( fsd.LastAccessTime.u.LowPart == info.ftLastAccessTime.dwLowDateTime, "expected %08lx, got %08lx\n",
4513 info.ftLastAccessTime.dwLowDateTime, fsd.LastAccessTime.u.LowPart );
4514 ok( fsd.LastAccessTime.u.HighPart == info.ftLastAccessTime.dwHighDateTime, "expected %08lx, got %08lx\n",
4515 info.ftLastAccessTime.dwHighDateTime, fsd.LastAccessTime.u.HighPart );
4516 ok( fsd.LastWriteTime.u.LowPart == info.ftLastWriteTime.dwLowDateTime, "expected %08lx, got %08lx\n",
4517 info.ftLastWriteTime.dwLowDateTime, fsd.LastWriteTime.u.LowPart );
4518 ok( fsd.LastWriteTime.u.HighPart == info.ftLastWriteTime.dwHighDateTime, "expected %08lx, got %08lx\n",
4519 info.ftLastWriteTime.dwHighDateTime, fsd.LastWriteTime.u.HighPart );
4520 /* TODO: ChangeTime */
4521 /* TODO: AllocationSize */
4522 ok( fsd.EndOfFile.u.LowPart == info.nFileSizeLow, "expected %08lx, got %08lx\n", info.nFileSizeLow, fsd.EndOfFile.u.LowPart );
4523 ok( fsd.EndOfFile.u.HighPart == info.nFileSizeHigh, "expected %08lx, got %08lx\n", info.nFileSizeHigh, fsd.EndOfFile.u.HighPart );
4524 ok( fsd.FileAttributes == info.dwFileAttributes, "expected %08lx, got %08lx\n", info.dwFileAttributes, fsd.FileAttributes );
4525 ok( !fsd.ReparseTag, "got reparse tag %#lx\n", fsd.ReparseTag );
4526 ok( fsd.NumberOfLinks == info.nNumberOfLinks, "expected %08lx, got %08lx\n", info.nNumberOfLinks, fsd.NumberOfLinks );
4527 ok( fsd.EffectiveAccess == FILE_ALL_ACCESS, "got %08lx\n", fsd.EffectiveAccess );
4528
4529 CloseHandle( h );
4530}
4531
4532static void rename_file( HANDLE h, const WCHAR *filename )
4533{
4535 UNICODE_STRING ntpath;
4538 BOOLEAN ret;
4539 ULONG size;
4540
4541 ret = pRtlDosPathNameToNtPathName_U( filename, &ntpath, NULL, NULL );
4542 ok( ret, "RtlDosPathNameToNtPathName_U failed\n" );
4543
4545 fri = HeapAlloc( GetProcessHeap(), 0, size );
4546 ok( fri != NULL, "HeapAlloc failed\n" );
4547 fri->ReplaceIfExists = TRUE;
4548 fri->RootDirectory = NULL;
4549 fri->FileNameLength = ntpath.Length;
4550 memcpy( fri->FileName, ntpath.Buffer, ntpath.Length );
4551 pRtlFreeUnicodeString( &ntpath );
4552
4553 status = pNtSetInformationFile( h, &io, fri, size, FileRenameInformation );
4554 HeapFree( GetProcessHeap(), 0, fri );
4555 ok( status == STATUS_SUCCESS, "got %#lx\n", status );
4556}
4557
4559{
4560 char temppath[MAX_PATH], filename[MAX_PATH];
4561 WCHAR temppathW[MAX_PATH], filenameW[MAX_PATH];
4565 DWORD attrs;
4566 HANDLE h;
4567
4568 GetTempPathA( MAX_PATH, temppath );
4569 GetTempFileNameA( temppath, ".foo", 0, filename );
4571 ok( h != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
4572
4574 ok( status == STATUS_SUCCESS, "got %#lx\n", status );
4575 ok( !(attrs & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", attrs );
4576
4577 status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileBasicInformation );
4578 ok( status == STATUS_SUCCESS, "got %#lx\n", status );
4579 ok( !(info.FileAttributes & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", info.FileAttributes );
4580
4581 info.FileAttributes = FILE_ATTRIBUTE_SYSTEM;
4582 status = pNtSetInformationFile( h, &io, &info, sizeof(info), FileBasicInformation );
4583 ok( status == STATUS_SUCCESS, "got %#lx\n", status );
4584
4586 ok( status == STATUS_SUCCESS, "got %#lx\n", status );
4587 ok( attrs & FILE_ATTRIBUTE_SYSTEM, "got attributes %#lx\n", attrs );
4588 ok( !(attrs & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", attrs );
4589
4590 status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileBasicInformation );
4591 ok( status == STATUS_SUCCESS, "got %#lx\n", status );
4592 ok( info.FileAttributes & FILE_ATTRIBUTE_SYSTEM, "got attributes %#lx\n", info.FileAttributes );
4593 ok( !(info.FileAttributes & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", info.FileAttributes );
4594
4595 CloseHandle( h );
4596
4597 GetTempPathW( MAX_PATH, temppathW );
4598 GetTempFileNameW( temppathW, L"foo", 0, filenameW );
4600 ok( h != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
4601
4602 GetTempFileNameW( temppathW, L".foo", 0, filenameW );
4603 winetest_push_context("foo -> .foo");
4606
4607 status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileBasicInformation );
4608 ok( status == STATUS_SUCCESS, "got %#lx\n", status );
4609 ok( !(info.FileAttributes & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", info.FileAttributes );
4610
4611 GetTempFileNameW( temppathW, L"foo", 0, filenameW );
4612 winetest_push_context(".foo -> foo");
4615
4616 status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileBasicInformation );
4617 ok( status == STATUS_SUCCESS, "got %#lx\n", status );
4618 ok( !(info.FileAttributes & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", info.FileAttributes );
4619
4620 CloseHandle( h );
4621}
4622
4623static void test_file_mode(void)
4624{
4625 UNICODE_STRING file_name, pipe_dev_name, mountmgr_dev_name, mailslot_dev_name;
4626 WCHAR tmp_path[MAX_PATH], dos_file_name[MAX_PATH];
4630 HANDLE file;
4631 unsigned i;
4632 DWORD res, access;
4634
4635 const struct {
4637 ULONG options;
4638 ULONG mode;
4639 } option_tests[] = {
4640 { &file_name, 0, 0 },
4649 { &pipe_dev_name, 0, 0 },
4651 { &mailslot_dev_name, 0, 0 },
4653 { &mountmgr_dev_name, 0, 0 },
4655 };
4656
4657 static WCHAR pipe_devW[] = {'\\','?','?','\\','P','I','P','E','\\'};
4658 static WCHAR mailslot_devW[] = {'\\','?','?','\\','M','A','I','L','S','L','O','T','\\'};
4659 static WCHAR mountmgr_devW[] =
4660 {'\\','?','?','\\','M','o','u','n','t','P','o','i','n','t','M','a','n','a','g','e','r'};
4661
4662 GetTempPathW(MAX_PATH, tmp_path);
4663 res = GetTempFileNameW(tmp_path, fooW, 0, dos_file_name);
4664 ok(res, "GetTempFileNameW failed: %lu\n", GetLastError());
4665 pRtlDosPathNameToNtPathName_U( dos_file_name, &file_name, NULL, NULL );
4666
4667 pipe_dev_name.Buffer = pipe_devW;
4668 pipe_dev_name.Length = sizeof(pipe_devW);
4669 pipe_dev_name.MaximumLength = sizeof(pipe_devW);
4670
4671 mailslot_dev_name.Buffer = mailslot_devW;
4672 mailslot_dev_name.Length = sizeof(mailslot_devW);
4673 mailslot_dev_name.MaximumLength = sizeof(mailslot_devW);
4674
4675 mountmgr_dev_name.Buffer = mountmgr_devW;
4676 mountmgr_dev_name.Length = sizeof(mountmgr_devW);
4677 mountmgr_dev_name.MaximumLength = sizeof(mountmgr_devW);
4678
4679 attr.Length = sizeof(attr);
4680 attr.RootDirectory = 0;
4681 attr.Attributes = OBJ_CASE_INSENSITIVE;
4682 attr.SecurityDescriptor = NULL;
4683 attr.SecurityQualityOfService = NULL;
4684
4685 for (i = 0; i < ARRAY_SIZE(option_tests); i++)
4686 {
4687 attr.ObjectName = option_tests[i].file_name;
4689
4690 if (option_tests[i].file_name == &file_name)
4691 {
4692 file = CreateFileW(dos_file_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
4693 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %lu\n", GetLastError());
4696 }
4697
4698 status = pNtOpenFile(&file, access, &attr, &io, 0, option_tests[i].options);
4699 ok(status == STATUS_SUCCESS, "[%u] NtOpenFile failed: %lx\n", i, status);
4700
4701 memset(&mode, 0xcc, sizeof(mode));
4702 status = pNtQueryInformationFile(file, &io, &mode, sizeof(mode), FileModeInformation);
4703 ok(status == STATUS_SUCCESS, "[%u] can't get FileModeInformation: %lx\n", i, status);
4704 ok(mode.Mode == option_tests[i].mode, "[%u] Mode = %lx, expected %lx\n",
4705 i, mode.Mode, option_tests[i].mode);
4706
4707 pNtClose(file);
4708 if (option_tests[i].file_name == &file_name)
4709 DeleteFileW(dos_file_name);
4710 }
4711
4712 pRtlFreeUnicodeString(&file_name);
4713}
4714
4716{
4718 HANDLE dir;
4724 BYTE buf[sizeof(FILE_FS_VOLUME_INFORMATION) + MAX_PATH * sizeof(WCHAR)];
4725
4727 pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL );
4728 attr.Length = sizeof(attr);
4729 attr.RootDirectory = 0;
4730 attr.ObjectName = &nameW;
4731 attr.Attributes = OBJ_CASE_INSENSITIVE;
4732 attr.SecurityDescriptor = NULL;
4733 attr.SecurityQualityOfService = NULL;
4734
4735 status = pNtOpenFile( &dir, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io,
4737 ok( !status, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
4738 pRtlFreeUnicodeString( &nameW );
4739
4740 ZeroMemory( buf, sizeof(buf) );
4741 io.Status = 0xdadadada;
4742 io.Information = 0xcacacaca;
4743
4744 status = pNtQueryVolumeInformationFile( dir, &io, buf, sizeof(buf), FileFsVolumeInformation );
4745
4747
4748 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %ld\n", status);
4749 ok(io.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %ld\n", io.Status);
4750
4751 ok(io.Information == (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel) + ffvi->VolumeLabelLength),
4752 "expected %ld, got %Iu\n", (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel) + ffvi->VolumeLabelLength),
4753 io.Information);
4754
4755 todo_wine ok(ffvi->VolumeCreationTime.QuadPart != 0, "Missing VolumeCreationTime\n");
4756 ok(ffvi->VolumeSerialNumber != 0, "Missing VolumeSerialNumber\n");
4757 ok(ffvi->SupportsObjects == 1,"expected 1, got %d\n", ffvi->SupportsObjects);
4758 ok(ffvi->VolumeLabelLength == lstrlenW(ffvi->VolumeLabel) * sizeof(WCHAR), "got %ld\n", ffvi->VolumeLabelLength);
4759
4760 trace("VolumeSerialNumber: %lx VolumeLabelName: %s\n", ffvi->VolumeSerialNumber, wine_dbgstr_w(ffvi->VolumeLabel));
4761
4762 CloseHandle( dir );
4763}
4764
4766{
4768 HANDLE dir;
4775
4777 pRtlDosPathNameToNtPathName_U( path, &nameW, NULL, NULL );
4778 attr.Length = sizeof(attr);
4779 attr.RootDirectory = 0;
4780 attr.ObjectName = &nameW;
4781 attr.Attributes = OBJ_CASE_INSENSITIVE;
4782 attr.SecurityDescriptor = NULL;
4783 attr.SecurityQualityOfService = NULL;
4784
4785 status = pNtOpenFile( &dir, SYNCHRONIZE|FILE_LIST_DIRECTORY, &attr, &io,
4787 ok( !status, "open %s failed %lx\n", wine_dbgstr_w(nameW.Buffer), status );
4788 pRtlFreeUnicodeString( &nameW );
4789
4790 ZeroMemory( buf, sizeof(buf) );
4791 io.Status = 0xdadadada;
4792 io.Information = 0xcacacaca;
4793
4794 status = pNtQueryVolumeInformationFile( dir, &io, buf, sizeof(buf), FileFsAttributeInformation );
4795
4797
4798 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %ld\n", status);
4799 ok(io.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %ld\n", io.Status);
4800 ok(ffai->FileSystemAttributes != 0, "Missing FileSystemAttributes\n");
4801 ok(ffai->MaximumComponentNameLength != 0, "Missing MaximumComponentNameLength\n");
4802 ok(ffai->FileSystemNameLength != 0, "Missing FileSystemNameLength\n");
4803
4804 trace("FileSystemAttributes: %lx MaximumComponentNameLength: %lx FileSystemName: %s\n",
4807
4808 CloseHandle( dir );
4809}
4810
4811static void test_NtCreateFile(void)
4812{
4813 static const struct test_data
4814 {
4815 DWORD disposition, attrib_in, status, result, attrib_out, needs_cleanup;
4816 } td[] =
4817 {
4819 /* 1*/{ FILE_CREATE, 0, STATUS_OBJECT_NAME_COLLISION, 0, 0, TRUE },
4827 /* 9*/{ FILE_OVERWRITE, 0, STATUS_ACCESS_DENIED, 0, 0, TRUE },
4831 /*13*/{ FILE_OVERWRITE_IF, 0, STATUS_ACCESS_DENIED, 0, 0, TRUE },
4837 };
4838 static const WCHAR fooW[] = {'f','o','o',0};
4840 HANDLE handle;
4845 DWORD ret, i;
4846
4850 pRtlDosPathNameToNtPathName_U(path, &nameW, NULL, NULL);
4851
4852 attr.Length = sizeof(attr);
4853 attr.RootDirectory = NULL;
4854 attr.ObjectName = &nameW;
4855 attr.Attributes = OBJ_CASE_INSENSITIVE;
4856 attr.SecurityDescriptor = NULL;
4857 attr.SecurityQualityOfService = NULL;
4858
4859 for (i = 0; i < ARRAY_SIZE(td); i++)
4860 {
4861 status = pNtCreateFile(&handle, GENERIC_READ, &attr, &io, NULL,
4862 td[i].attrib_in, FILE_SHARE_READ|FILE_SHARE_WRITE,
4863 td[i].disposition, 0, NULL, 0);
4864
4865 ok(status == td[i].status, "%ld: expected %#lx got %#lx\n", i, td[i].status, status);
4866
4867 if (!status)
4868 {
4869 ok(io.Information == td[i].result,"%ld: expected %#lx got %#Ix\n", i, td[i].result, io.Information);
4870
4872 ret &= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
4873 /* FIXME: leave only 'else' case below once Wine is fixed */
4874 if (ret != td[i].attrib_out)
4875 {
4876 todo_wine
4877 ok(ret == td[i].attrib_out, "%ld: expected %#lx got %#lx\n", i, td[i].attrib_out, ret);
4878 SetFileAttributesW(path, td[i].attrib_out);
4879 }
4880 else
4881 ok(ret == td[i].attrib_out, "%ld: expected %#lx got %#lx\n", i, td[i].attrib_out, ret);
4882
4884 }
4885
4886 if (td[i].needs_cleanup)
4887 {
4890 }
4891 }
4892
4893 pRtlFreeUnicodeString( &nameW );
4895 DeleteFileW( path );
4896
4897 wcscat( path, L"\\" );
4898 pRtlDosPathNameToNtPathName_U(path, &nameW, NULL, NULL);
4899
4900 status = pNtCreateFile( &handle, GENERIC_READ, &attr, &io, NULL,
4902 ok( status == STATUS_OBJECT_NAME_INVALID, "failed %s %lx\n", debugstr_w(nameW.Buffer), status );
4903 status = pNtCreateFile( &handle, GENERIC_READ, &attr, &io, NULL,
4906 ok( !status, "failed %s %lx\n", debugstr_w(nameW.Buffer), status );
4908}
4909
4910static void test_read_write(void)
4911{
4912 static const char contents[14] = "1234567890abcd";
4913 char buf[256];
4914 HANDLE hfile, event;
4915 OVERLAPPED ovl;
4916 IO_STATUS_BLOCK iob;
4917 DWORD ret, bytes, status, off;
4919 LONG i;
4920
4921 event = CreateEventA( NULL, TRUE, FALSE, NULL );
4922
4923 iob.Status = -1;
4924 iob.Information = -1;
4925 offset.QuadPart = 0;
4926 status = pNtReadFile(INVALID_HANDLE_VALUE, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL);
4927 ok(status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#lx\n", status);
4928 ok(iob.Status == -1, "expected -1, got %#lx\n", iob.Status);
4929 ok(iob.Information == -1, "expected -1, got %Iu\n", iob.Information);
4930
4931 iob.Status = -1;
4932 iob.Information = -1;
4933 offset.QuadPart = 0;
4934 status = pNtReadFile(INVALID_HANDLE_VALUE, 0, NULL, NULL, &iob, NULL, sizeof(buf), &offset, NULL);
4935 ok(status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#lx\n", status);
4936 ok(iob.Status == -1, "expected -1, got %#lx\n", iob.Status);
4937 ok(iob.Information == -1, "expected -1, got %Iu\n", iob.Information);
4938
4939 iob.Status = -1;
4940 iob.Information = -1;
4941 offset.QuadPart = 0;
4942 status = pNtWriteFile(INVALID_HANDLE_VALUE, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL);
4943 ok(status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#lx\n", status);
4944 ok(iob.Status == -1, "expected -1, got %#lx\n", iob.Status);
4945 ok(iob.Information == -1, "expected -1, got %Iu\n", iob.Information);
4946
4947 iob.Status = -1;
4948 iob.Information = -1;
4949 offset.QuadPart = 0;
4950 status = pNtWriteFile(INVALID_HANDLE_VALUE, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL);
4951 ok(status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#lx\n", status);
4952 ok(iob.Status == -1, "expected -1, got %#lx\n", iob.Status);
4953 ok(iob.Information == -1, "expected -1, got %Iu\n", iob.Information);
4954
4955 hfile = create_temp_file(0);
4956 if (!hfile) return;
4957
4958 iob.Status = -1;
4959 iob.Information = -1;
4960 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, NULL, sizeof(contents), NULL, NULL);
4961 ok(status == STATUS_INVALID_USER_BUFFER, "expected STATUS_INVALID_USER_BUFFER, got %#lx\n", status);
4962 ok(iob.Status == -1, "expected -1, got %#lx\n", iob.Status);
4963 ok(iob.Information == -1, "expected -1, got %Iu\n", iob.Information);
4964
4965 iob.Status = -1;
4966 iob.Information = -1;
4967 SetEvent(event);
4968 status = pNtWriteFile(hfile, event, NULL, NULL, &iob, NULL, sizeof(contents), NULL, NULL);
4969 ok(status == STATUS_INVALID_USER_BUFFER, "expected STATUS_INVALID_USER_BUFFER, got %#lx\n", status);
4970 ok(iob.Status == -1, "expected -1, got %#lx\n", iob.Status);
4971 ok(iob.Information == -1, "expected -1, got %Iu\n", iob.Information);
4972 ok(!is_signaled(event), "event is not signaled\n");
4973
4974 iob.Status = -1;
4975 iob.Information = -1;
4976 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, NULL, sizeof(contents), NULL, NULL);
4977 ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %#lx\n", status);
4978 ok(iob.Status == -1, "expected -1, got %#lx\n", iob.Status);
4979 ok(iob.Information == -1, "expected -1, got %Iu\n", iob.Information);
4980
4981 iob.Status = -1;
4982 iob.Information = -1;
4983 SetEvent(event);
4984 status = pNtReadFile(hfile, event, NULL, NULL, &iob, NULL, sizeof(contents), NULL, NULL);
4985 ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %#lx\n", status);
4986 ok(iob.Status == -1, "expected -1, got %#lx\n", iob.Status);
4987 ok(iob.Information == -1, "expected -1, got %Iu\n", iob.Information);
4988 ok(is_signaled(event), "event is not signaled\n");
4989
4990 iob.Status = -1;
4991 iob.Information = -1;
4992 SetEvent(event);
4993 status = pNtReadFile(hfile, event, NULL, NULL, &iob, (void*)0xdeadbeef, sizeof(contents), NULL, NULL);
4994 ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %#lx\n", status);
4995 ok(iob.Status == -1, "expected -1, got %#lx\n", iob.Status);
4996 ok(iob.Information == -1, "expected -1, got %Iu\n", iob.Information);
4997 ok(is_signaled(event), "event is not signaled\n");
4998
4999 iob.Status = -1;
5000 iob.Information = -1;
5001 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, contents, 7, NULL, NULL);
5002 ok(status == STATUS_SUCCESS, "NtWriteFile error %#lx\n", status);
5003 ok(iob.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iob.Status);
5004 ok(iob.Information == 7, "expected 7, got %Iu\n", iob.Information);
5005
5006 SetFilePointer(hfile, 0, NULL, FILE_BEGIN);
5007
5008 iob.Status = -1;
5009 iob.Information = -1;
5010 offset.QuadPart = (LONGLONG)-1 /* FILE_WRITE_TO_END_OF_FILE */;
5011 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, contents + 7, sizeof(contents) - 7, &offset, NULL);
5012 ok(status == STATUS_SUCCESS, "NtWriteFile error %#lx\n", status);
5013 ok(iob.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iob.Status);
5014 ok(iob.Information == sizeof(contents) - 7, "expected sizeof(contents)-7, got %Iu\n", iob.Information);
5015
5016 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5017 ok(off == sizeof(contents), "expected sizeof(contents), got %lu\n", off);
5018
5019 bytes = 0xdeadbeef;
5020 SetLastError(0xdeadbeef);
5022 ok(!ret, "ReadFile should fail\n");
5023 ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError());
5024 ok(bytes == 0, "bytes %lu\n", bytes);
5025
5026 bytes = 0xdeadbeef;
5027 SetLastError(0xdeadbeef);
5028 ret = ReadFile(hfile, buf, 0, &bytes, NULL);
5029 ok(ret, "ReadFile error %ld\n", GetLastError());
5030 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %ld\n", GetLastError());
5031 ok(bytes == 0, "bytes %lu\n", bytes);
5032
5033 bytes = 0xdeadbeef;
5034 SetLastError(0xdeadbeef);
5035 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, NULL);
5036 ok(ret, "ReadFile error %ld\n", GetLastError());
5037 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %ld\n", GetLastError());
5038 ok(bytes == 0, "bytes %lu\n", bytes);
5039
5040 SetFilePointer(hfile, 0, NULL, FILE_BEGIN);
5041
5042 bytes = 0;
5043 SetLastError(0xdeadbeef);
5044 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, NULL);
5045 ok(ret, "ReadFile error %ld\n", GetLastError());
5046 ok(bytes == sizeof(contents), "bytes %lu\n", bytes);
5047 ok(!memcmp(contents, buf, sizeof(contents)), "file contents mismatch\n");
5048
5049 for (i = -20; i < -1; i++)
5050 {
5051 if (i == -2) continue;
5052
5053 iob.Status = -1;
5054 iob.Information = -1;
5055 offset.QuadPart = (LONGLONG)i;
5056 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, contents, sizeof(contents), &offset, NULL);
5057 ok(status == STATUS_INVALID_PARAMETER, "%ld: expected STATUS_INVALID_PARAMETER, got %#lx\n", i, status);
5058 ok(iob.Status == -1, "expected -1, got %#lx\n", iob.Status);
5059 ok(iob.Information == -1, "expected -1, got %Id\n", iob.Information);
5060 }
5061
5062 SetFilePointer(hfile, sizeof(contents) - 4, NULL, FILE_BEGIN);
5063
5064 iob.Status = -1;
5065 iob.Information = -1;
5066 offset.QuadPart = (LONGLONG)-2 /* FILE_USE_FILE_POINTER_POSITION */;
5067 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, "DCBA", 4, &offset, NULL);
5068 ok(status == STATUS_SUCCESS, "NtWriteFile error %#lx\n", status);
5069 ok(iob.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iob.Status);
5070 ok(iob.Information == 4, "expected 4, got %Iu\n", iob.Information);
5071
5072 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5073 ok(off == sizeof(contents), "expected sizeof(contents), got %lu\n", off);
5074
5075 iob.Status = -1;
5076 iob.Information = -1;
5077 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), NULL, NULL);
5078 ok(status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#lx\n", status);
5079 ok(iob.Status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#lx\n", iob.Status);
5080 ok(iob.Information == 0, "expected 0, got %Iu\n", iob.Information);
5081
5082 SetFilePointer(hfile, 0, NULL, FILE_BEGIN);
5083
5084 bytes = 0;
5085 SetLastError(0xdeadbeef);
5086 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, NULL);
5087 ok(ret, "ReadFile error %ld\n", GetLastError());
5088 ok(bytes == sizeof(contents), "bytes %lu\n", bytes);
5089 ok(!memcmp(contents, buf, sizeof(contents) - 4), "file contents mismatch\n");
5090 ok(!memcmp(buf + sizeof(contents) - 4, "DCBA", 4), "file contents mismatch\n");
5091
5092 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5093 ok(off == sizeof(contents), "expected sizeof(contents), got %lu\n", off);
5094
5095 SetFilePointer(hfile, 0, NULL, FILE_BEGIN);
5096
5097 bytes = 0;
5098 SetLastError(0xdeadbeef);
5099 ret = WriteFile(hfile, contents, sizeof(contents), &bytes, NULL);
5100 ok(ret, "WriteFile error %ld\n", GetLastError());
5101 ok(bytes == sizeof(contents), "bytes %lu\n", bytes);
5102
5103 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5104 ok(off == sizeof(contents), "expected sizeof(contents), got %lu\n", off);
5105
5106 /* test reading beyond EOF */
5107 bytes = -1;
5108 SetLastError(0xdeadbeef);
5109 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, NULL);
5110 ok(ret, "ReadFile error %ld\n", GetLastError());
5111 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %ld\n", GetLastError());
5112 ok(bytes == 0, "bytes %lu\n", bytes);
5113
5114 bytes = -1;
5115 SetLastError(0xdeadbeef);
5116 ret = ReadFile(hfile, buf, 0, &bytes, NULL);
5117 ok(ret, "ReadFile error %ld\n", GetLastError());
5118 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %ld\n", GetLastError());
5119 ok(bytes == 0, "bytes %lu\n", bytes);
5120
5121 bytes = -1;
5122 SetLastError(0xdeadbeef);
5123 ret = ReadFile(hfile, NULL, 0, &bytes, NULL);
5124 ok(ret, "ReadFile error %ld\n", GetLastError());
5125 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %ld\n", GetLastError());
5126 ok(bytes == 0, "bytes %lu\n", bytes);
5127
5128 ovl.Offset = sizeof(contents);
5129 ovl.OffsetHigh = 0;
5130 ovl.Internal = -1;
5131 ovl.InternalHigh = -1;
5132 ovl.hEvent = 0;
5133 bytes = -1;
5134 SetLastError(0xdeadbeef);
5135 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, &ovl);
5136 ok(!ret, "ReadFile should fail\n");
5137 ok(GetLastError() == ERROR_HANDLE_EOF, "expected ERROR_HANDLE_EOF, got %ld\n", GetLastError());
5138 ok(bytes == 0, "bytes %lu\n", bytes);
5139 ok((NTSTATUS)ovl.Internal == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#Ix\n", ovl.Internal);
5140 ok(ovl.InternalHigh == 0, "expected 0, got %Iu\n", ovl.InternalHigh);
5141
5142 ovl.Offset = sizeof(contents);
5143 ovl.OffsetHigh = 0;
5144 ovl.Internal = -1;
5145 ovl.InternalHigh = -1;
5146 ovl.hEvent = 0;
5147 bytes = -1;
5148 SetLastError(0xdeadbeef);
5149 ret = ReadFile(hfile, buf, 0, &bytes, &ovl);
5150 ok(ret, "ReadFile error %ld\n", GetLastError());
5151 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %ld\n", GetLastError());
5152 ok(bytes == 0, "bytes %lu\n", bytes);
5153 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#Ix\n", ovl.Internal);
5154 ok(ovl.InternalHigh == 0, "expected 0, got %Iu\n", ovl.InternalHigh);
5155
5156 iob.Status = -1;
5157 iob.Information = -1;
5158 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), NULL, NULL);
5159 ok(status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#lx\n", status);
5160 ok(iob.Status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#lx\n", iob.Status);
5161 ok(iob.Information == 0, "expected 0, got %Iu\n", iob.Information);
5162
5163 iob.Status = -1;
5164 iob.Information = -1;
5165 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, 0, NULL, NULL);
5166 ok(status == STATUS_SUCCESS, "NtReadFile error %#lx\n", status);
5167 ok(iob.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iob.Status);
5168 ok(iob.Information == 0, "expected 0, got %Iu\n", iob.Information);
5169
5170 iob.Status = -1;
5171 iob.Information = -1;
5172 offset.QuadPart = sizeof(contents);
5173 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL);
5174 ok(status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#lx\n", status);
5175 ok(iob.Status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#lx\n", iob.Status);
5176 ok(iob.Information == 0, "expected 0, got %Iu\n", iob.Information);
5177
5178 iob.Status = -1;
5179 iob.Information = -1;
5180 offset.QuadPart = sizeof(contents);
5181 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, 0, &offset, NULL);
5182 ok(status == STATUS_SUCCESS, "NtReadFile error %#lx\n", status);
5183 ok(iob.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iob.Status);
5184 ok(iob.Information == 0, "expected 0, got %Iu\n", iob.Information);
5185
5186 iob.Status = -1;
5187 iob.Information = -1;
5188 offset.QuadPart = (LONGLONG)-2 /* FILE_USE_FILE_POINTER_POSITION */;
5189 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL);
5190 ok(status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#lx\n", status);
5191 ok(iob.Status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#lx\n", iob.Status);
5192 ok(iob.Information == 0, "expected 0, got %Iu\n", iob.Information);
5193
5194 iob.Status = -1;
5195 iob.Information = -1;
5196 offset.QuadPart = (LONGLONG)-2 /* FILE_USE_FILE_POINTER_POSITION */;
5197 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, 0, &offset, NULL);
5198 ok(status == STATUS_SUCCESS, "NtReadFile error %#lx\n", status);
5199 ok(iob.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iob.Status);
5200 ok(iob.Information == 0, "expected 0, got %Iu\n", iob.Information);
5201
5202 for (i = -20; i < 0; i++)
5203 {
5204 if (i == -2) continue;
5205
5206 iob.Status = -1;
5207 iob.Information = -1;
5208 offset.QuadPart = (LONGLONG)i;
5209 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL);
5210 ok(status == STATUS_INVALID_PARAMETER, "%ld: expected STATUS_INVALID_PARAMETER, got %#lx\n", i, status);
5211 ok(iob.Status == -1, "expected -1, got %#lx\n", iob.Status);
5212 ok(iob.Information == -1, "expected -1, got %Id\n", iob.Information);
5213 }
5214
5215 SetFilePointer(hfile, 0, NULL, FILE_BEGIN);
5216
5217 bytes = 0;
5218 SetLastError(0xdeadbeef);
5219 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, NULL);
5220 ok(ret, "ReadFile error %ld\n", GetLastError());
5221 ok(bytes == sizeof(contents), "bytes %lu\n", bytes);
5222 ok(!memcmp(contents, buf, sizeof(contents)), "file contents mismatch\n");
5223
5224 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5225 ok(off == sizeof(contents), "expected sizeof(contents), got %lu\n", off);
5226
5227 iob.Status = -1;
5228 iob.Information = -1;
5229 offset.QuadPart = 0;
5230 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL);
5231 ok(status == STATUS_SUCCESS, "NtReadFile error %#lx\n", status);
5232 ok(iob.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iob.Status);
5233 ok(iob.Information == sizeof(contents), "expected sizeof(contents), got %Iu\n", iob.Information);
5234 ok(!memcmp(contents, buf, sizeof(contents)), "file contents mismatch\n");
5235
5236 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5237 ok(off == sizeof(contents), "expected sizeof(contents), got %lu\n", off);
5238
5239 iob.Status = -1;
5240 iob.Information = -1;
5241 offset.QuadPart = sizeof(contents) - 4;
5242 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, "DCBA", 4, &offset, NULL);
5243 ok(status == STATUS_SUCCESS, "NtWriteFile error %#lx\n", status);
5244 ok(iob.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iob.Status);
5245 ok(iob.Information == 4, "expected 4, got %Iu\n", iob.Information);
5246
5247 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5248 ok(off == sizeof(contents), "expected sizeof(contents), got %lu\n", off);
5249
5250 iob.Status = -1;
5251 iob.Information = -1;
5252 offset.QuadPart = 0;
5253 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL);
5254 ok(status == STATUS_SUCCESS, "NtReadFile error %#lx\n", status);
5255 ok(iob.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iob.Status);
5256 ok(iob.Information == sizeof(contents), "expected sizeof(contents), got %Iu\n", iob.Information);
5257 ok(!memcmp(contents, buf, sizeof(contents) - 4), "file contents mismatch\n");
5258 ok(!memcmp(buf + sizeof(contents) - 4, "DCBA", 4), "file contents mismatch\n");
5259
5260 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5261 ok(off == sizeof(contents), "expected sizeof(contents), got %lu\n", off);
5262
5263 ovl.Offset = sizeof(contents) - 4;
5264 ovl.OffsetHigh = 0;
5265 ovl.hEvent = 0;
5266 bytes = 0;
5267 SetLastError(0xdeadbeef);
5268 ret = WriteFile(hfile, "ABCD", 4, &bytes, &ovl);
5269 ok(ret, "WriteFile error %ld\n", GetLastError());
5270 ok(bytes == 4, "bytes %lu\n", bytes);
5271
5272 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5273 ok(off == sizeof(contents), "expected sizeof(contents), got %lu\n", off);
5274
5275 ovl.Offset = 0;
5276 ovl.OffsetHigh = 0;
5277 ovl.Internal = -1;
5278 ovl.InternalHigh = -1;
5279 ovl.hEvent = 0;
5280 bytes = 0;
5281 SetLastError(0xdeadbeef);
5282 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, &ovl);
5283 ok(ret, "ReadFile error %ld\n", GetLastError());
5284 ok(bytes == sizeof(contents), "bytes %lu\n", bytes);
5285 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#Ix\n", ovl.Internal);
5286 ok(ovl.InternalHigh == sizeof(contents), "expected sizeof(contents), got %Iu\n", ovl.InternalHigh);
5287 ok(!memcmp(contents, buf, sizeof(contents) - 4), "file contents mismatch\n");
5288 ok(!memcmp(buf + sizeof(contents) - 4, "ABCD", 4), "file contents mismatch\n");
5289
5290 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5291 ok(off == sizeof(contents), "expected sizeof(contents), got %lu\n", off);
5292
5293 CloseHandle(hfile);
5294
5296 if (!hfile) return;
5297
5298 bytes = 0xdeadbeef;
5299 SetLastError(0xdeadbeef);
5301 ok(!ret, "ReadFile should fail\n");
5302 ok(GetLastError() == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError());
5303 ok(bytes == 0, "bytes %lu\n", bytes);
5304
5305 ovl.Offset = 0;
5306 ovl.OffsetHigh = 0;
5307 ovl.Internal = -1;
5308 ovl.InternalHigh = -1;
5309 ovl.hEvent = 0;
5310 bytes = 0xdeadbeef;
5311 SetLastError(0xdeadbeef);
5312 /* ReadFile return value depends on Windows version and testing it is not practical */
5313 ReadFile(hfile, buf, 0, &bytes, &ovl);
5314 ok(bytes == 0, "bytes %lu\n", bytes);
5315 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#Ix\n", ovl.Internal);
5316 ok(ovl.InternalHigh == 0, "expected 0, got %Iu\n", ovl.InternalHigh);
5317
5318 bytes = 0xdeadbeef;
5319 SetLastError(0xdeadbeef);
5320 ret = WriteFile(hfile, contents, sizeof(contents), &bytes, NULL);
5321 ok(!ret, "WriteFile should fail\n");
5322 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
5323 ok(bytes == 0, "bytes %lu\n", bytes);
5324
5325 iob.Status = -1;
5326 iob.Information = -1;
5327 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, contents, sizeof(contents), NULL, NULL);
5328 ok(status == STATUS_INVALID_PARAMETER, "expected STATUS_INVALID_PARAMETER, got %#lx\n", status);
5329 ok(iob.Status == -1, "expected -1, got %#lx\n", iob.Status);
5330 ok(iob.Information == -1, "expected -1, got %Id\n", iob.Information);
5331
5332 for (i = -20; i < -1; i++)
5333 {
5334 iob.Status = -1;
5335 iob.Information = -1;
5336 offset.QuadPart = (LONGLONG)i;
5337 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, contents, sizeof(contents), &offset, NULL);
5338 ok(status == STATUS_INVALID_PARAMETER, "%ld: expected STATUS_INVALID_PARAMETER, got %#lx\n", i, status);
5339 ok(iob.Status == -1, "expected -1, got %#lx\n", iob.Status);
5340 ok(iob.Information == -1, "expected -1, got %Id\n", iob.Information);
5341 }
5342
5343 iob.Status = -1;
5344 iob.Information = -1;
5345 offset.QuadPart = 0;
5346 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, contents, sizeof(contents), &offset, NULL);
5347 ok(status == STATUS_PENDING || broken(status == STATUS_SUCCESS) /* before Vista */,
5348 "expected STATUS_PENDING, got %#lx.\n", status);
5349 if (status == STATUS_PENDING)
5350 {
5351 ret = WaitForSingleObject(hfile, 3000);
5352 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject error %ld\n", ret);
5353 }
5354 ok(iob.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iob.Status);
5355 ok(iob.Information == sizeof(contents), "expected sizeof(contents), got %Iu\n", iob.Information);
5356
5357 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5358 ok(off == 0, "expected 0, got %lu\n", off);
5359
5360 bytes = 0xdeadbeef;
5361 SetLastError(0xdeadbeef);
5362 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, NULL);
5363 ok(!ret, "ReadFile should fail\n");
5364 ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
5365 ok(bytes == 0, "bytes %lu\n", bytes);
5366
5367 iob.Status = -1;
5368 iob.Information = -1;
5369 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), NULL, NULL);
5370 ok(status == STATUS_INVALID_PARAMETER, "expected STATUS_INVALID_PARAMETER, got %#lx\n", status);
5371 ok(iob.Status == -1, "expected -1, got %#lx\n", iob.Status);
5372 ok(iob.Information == -1, "expected -1, got %Id\n", iob.Information);
5373
5374 for (i = -20; i < 0; i++)
5375 {
5376 iob.Status = -1;
5377 iob.Information = -1;
5378 offset.QuadPart = (LONGLONG)i;
5379 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL);
5380 ok(status == STATUS_INVALID_PARAMETER, "%ld: expected STATUS_INVALID_PARAMETER, got %#lx\n", i, status);
5381 ok(iob.Status == -1, "expected -1, got %#lx\n", iob.Status);
5382 ok(iob.Information == -1, "expected -1, got %Id\n", iob.Information);
5383 }
5384
5385 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5386 ok(off == 0, "expected 0, got %lu\n", off);
5387
5388 /* test reading beyond EOF */
5389 offset.QuadPart = sizeof(contents);
5390 ovl.Offset = offset.u.LowPart;
5391 ovl.OffsetHigh = offset.u.HighPart;
5392 ovl.Internal = -1;
5393 ovl.InternalHigh = -1;
5394 ovl.hEvent = 0;
5395 bytes = 0xdeadbeef;
5396 SetLastError(0xdeadbeef);
5397 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, &ovl);
5398 ok(!ret, "ReadFile should fail\n");
5399 ret = GetLastError();
5400 ok(ret == ERROR_IO_PENDING || broken(ret == ERROR_HANDLE_EOF) /* before Vista */,
5401 "expected ERROR_IO_PENDING, got %ld\n", ret);
5402 ok(bytes == 0, "bytes %lu\n", bytes);
5403
5404 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5405 ok(off == 0, "expected 0, got %lu\n", off);
5406
5407 if (ret == ERROR_IO_PENDING)
5408 {
5409 bytes = 0xdeadbeef;
5410 SetLastError(0xdeadbeef);
5411 ret = GetOverlappedResult(hfile, &ovl, &bytes, TRUE);
5412 ok(!ret, "GetOverlappedResult should report FALSE\n");
5413 ok(GetLastError() == ERROR_HANDLE_EOF, "expected ERROR_HANDLE_EOF, got %ld\n", GetLastError());
5414 ok(bytes == 0, "expected 0, read %lu\n", bytes);
5415 ok((NTSTATUS)ovl.Internal == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#Ix\n", ovl.Internal);
5416 ok(ovl.InternalHigh == 0, "expected 0, got %Iu\n", ovl.InternalHigh);
5417 }
5418
5419 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5420 ok(off == 0, "expected 0, got %lu\n", off);
5421
5422 offset.QuadPart = sizeof(contents);
5423 ovl.Offset = offset.u.LowPart;
5424 ovl.OffsetHigh = offset.u.HighPart;
5425 ovl.Internal = -1;
5426 ovl.InternalHigh = -1;
5427 ovl.hEvent = 0;
5428 bytes = 0xdeadbeef;
5429 SetLastError(0xdeadbeef);
5430 ret = ReadFile(hfile, buf, 0, &bytes, &ovl);
5431 ok((!ret && GetLastError() == ERROR_IO_PENDING) || broken(ret) /* before Vista */,
5432 "Unexpected result, ret %#lx, GetLastError() %lu.\n", ret, GetLastError());
5433 ret = GetLastError();
5434 ok(bytes == 0, "bytes %lu\n", bytes);
5435
5436 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5437 ok(off == 0, "expected 0, got %lu\n", off);
5438
5439 if (ret == ERROR_IO_PENDING)
5440 {
5441 bytes = 0xdeadbeef;
5442 SetLastError(0xdeadbeef);
5443 ret = GetOverlappedResult(hfile, &ovl, &bytes, TRUE);
5444 ok(ret, "GetOverlappedResult returned FALSE with %lu (expected TRUE)\n", GetLastError());
5445 ok(bytes == 0, "expected 0, read %lu\n", bytes);
5446 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#Ix\n", ovl.Internal);
5447 ok(ovl.InternalHigh == 0, "expected 0, got %Iu\n", ovl.InternalHigh);
5448 }
5449
5450 offset.QuadPart = sizeof(contents);
5451 ovl.Offset = offset.u.LowPart;
5452 ovl.OffsetHigh = offset.u.HighPart;
5453 ovl.Internal = -1;
5454 ovl.InternalHigh = -1;
5455 ovl.hEvent = 0;
5456 bytes = 0xdeadbeef;
5457 SetLastError(0xdeadbeef);
5458 ret = ReadFile(hfile, NULL, 0, &bytes, &ovl);
5459 ok((!ret && GetLastError() == ERROR_IO_PENDING) || broken(ret) /* before Vista */,
5460 "Unexpected result, ret %#lx, GetLastError() %lu.\n", ret, GetLastError());
5461 ret = GetLastError();
5462 ok(bytes == 0, "bytes %lu\n", bytes);
5463
5464 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5465 ok(off == 0, "expected 0, got %lu\n", off);
5466
5467 if (ret == ERROR_IO_PENDING)
5468 {
5469 bytes = 0xdeadbeef;
5470 SetLastError(0xdeadbeef);
5471 ret = GetOverlappedResult(hfile, &ovl, &bytes, TRUE);
5472 ok(ret, "GetOverlappedResult returned FALSE with %lu (expected TRUE)\n", GetLastError());
5473 ok(bytes == 0, "expected 0, read %lu\n", bytes);
5474 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#Ix\n", ovl.Internal);
5475 ok(ovl.InternalHigh == 0, "expected 0, got %Iu\n", ovl.InternalHigh);
5476 }
5477
5478 iob.Status = -1;
5479 iob.Information = -1;
5480 offset.QuadPart = sizeof(contents);
5481 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL);
5482 if (status == STATUS_PENDING)
5483 {
5484 ret = WaitForSingleObject(hfile, 3000);
5485 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject error %ld\n", ret);
5486 ok(iob.Status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#lx\n", iob.Status);
5487 ok(iob.Information == 0, "expected 0, got %Iu\n", iob.Information);
5488 }
5489 else
5490 {
5491 ok(status == STATUS_END_OF_FILE, "expected STATUS_END_OF_FILE, got %#lx\n", status);
5492 ok(iob.Status == -1, "expected -1, got %#lx\n", iob.Status);
5493 ok(iob.Information == -1, "expected -1, got %Iu\n", iob.Information);
5494 }
5495
5496 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5497 ok(off == 0, "expected 0, got %lu\n", off);
5498
5499 iob.Status = -1;
5500 iob.Information = -1;
5501 offset.QuadPart = sizeof(contents);
5502 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, 0, &offset, NULL);
5503 ok(status == STATUS_PENDING || broken(status == STATUS_SUCCESS) /* before Vista */,
5504 "expected STATUS_PENDING, got %#lx.\n", status);
5505 if (status == STATUS_PENDING)
5506 {
5507 ret = WaitForSingleObject(hfile, 3000);
5508 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject error %ld\n", ret);
5509 ok(iob.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iob.Status);
5510 ok(iob.Information == 0, "expected 0, got %Iu\n", iob.Information);
5511 }
5512 else
5513 {
5514 ok(iob.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iob.Status);
5515 ok(iob.Information == 0, "expected 0, got %Iu\n", iob.Information);
5516 }
5517
5518 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5519 ok(off == 0, "expected 0, got %lu\n", off);
5520
5521 ovl.Offset = 0;
5522 ovl.OffsetHigh = 0;
5523 ovl.Internal = -1;
5524 ovl.InternalHigh = -1;
5525 ovl.hEvent = 0;
5526 bytes = 0;
5527 SetLastError(0xdeadbeef);
5528 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, &ovl);
5529 ok((!ret && GetLastError() == ERROR_IO_PENDING) || broken(ret) /* before Vista */,
5530 "Unexpected result, ret %#lx, GetLastError() %lu.\n", ret, GetLastError());
5531 if (!ret)
5532 ok(bytes == 0, "bytes %lu\n", bytes);
5533 else
5534 ok(bytes == 14, "bytes %lu\n", bytes);
5535 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#Ix\n", ovl.Internal);
5536 ok(ovl.InternalHigh == sizeof(contents), "expected sizeof(contents), got %Iu\n", ovl.InternalHigh);
5537
5538 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5539 ok(off == 0, "expected 0, got %lu\n", off);
5540
5541 bytes = 0xdeadbeef;
5542 ret = GetOverlappedResult(hfile, &ovl, &bytes, TRUE);
5543 ok(ret, "GetOverlappedResult error %ld\n", GetLastError());
5544 ok(bytes == sizeof(contents), "bytes %lu\n", bytes);
5545 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#Ix\n", ovl.Internal);
5546 ok(ovl.InternalHigh == sizeof(contents), "expected sizeof(contents), got %Iu\n", ovl.InternalHigh);
5547 ok(!memcmp(contents, buf, sizeof(contents)), "file contents mismatch\n");
5548
5549 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5550 ok(off == 0, "expected 0, got %lu\n", off);
5551
5552 SetFilePointer(hfile, sizeof(contents) - 4, NULL, FILE_BEGIN);
5553 SetEndOfFile(hfile);
5554 SetFilePointer(hfile, 0, NULL, FILE_BEGIN);
5555
5556 iob.Status = -1;
5557 iob.Information = -1;
5558 offset.QuadPart = (LONGLONG)-1 /* FILE_WRITE_TO_END_OF_FILE */;
5559 status = pNtWriteFile(hfile, 0, NULL, NULL, &iob, "DCBA", 4, &offset, NULL);
5560 ok(status == STATUS_PENDING || broken(status == STATUS_SUCCESS) /* before Vista */,
5561 "expected STATUS_PENDING, got %#lx.\n", status);
5562 if (status == STATUS_PENDING)
5563 {
5564 ret = WaitForSingleObject(hfile, 3000);
5565 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject error %ld\n", ret);
5566 }
5567 ok(iob.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iob.Status);
5568 ok(iob.Information == 4, "expected 4, got %Iu\n", iob.Information);
5569
5570 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5571 ok(off == 0, "expected 0, got %lu\n", off);
5572
5573 iob.Status = -1;
5574 iob.Information = -1;
5575 offset.QuadPart = 0;
5576 status = pNtReadFile(hfile, 0, NULL, NULL, &iob, buf, sizeof(buf), &offset, NULL);
5577 ok(status == STATUS_PENDING || broken(status == STATUS_SUCCESS) /* before Vista */,
5578 "expected STATUS_PENDING, got %#lx.\n", status);
5579 if (status == STATUS_PENDING)
5580 {
5581 ret = WaitForSingleObject(hfile, 3000);
5582 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject error %ld\n", ret);
5583 }
5584 ok(iob.Status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", iob.Status);
5585 ok(iob.Information == sizeof(contents), "expected sizeof(contents), got %Iu\n", iob.Information);
5586
5587 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5588 ok(off == 0, "expected 0, got %lu\n", off);
5589
5590 ok(!memcmp(contents, buf, sizeof(contents) - 4), "file contents mismatch\n");
5591 ok(!memcmp(buf + sizeof(contents) - 4, "DCBA", 4), "file contents mismatch\n");
5592
5593 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5594 ok(off == 0, "expected 0, got %lu\n", off);
5595
5596 ovl.Offset = sizeof(contents) - 4;
5597 ovl.OffsetHigh = 0;
5598 ovl.Internal = -1;
5599 ovl.InternalHigh = -1;
5600 ovl.hEvent = 0;
5601 bytes = 0;
5602 SetLastError(0xdeadbeef);
5603 ret = WriteFile(hfile, "ABCD", 4, &bytes, &ovl);
5604 ok((!ret && GetLastError() == ERROR_IO_PENDING) || broken(ret) /* before Vista */,
5605 "Unexpected result %#lx, GetLastError() %lu.\n", ret, GetLastError());
5606 if (!ret)
5607 {
5608 ok(bytes == 0, "bytes %lu\n", bytes);
5609 ret = WaitForSingleObject(hfile, 3000);
5610 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject error %ld\n", ret);
5611 }
5612 else ok(bytes == 4, "bytes %lu\n", bytes);
5613 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#Ix\n", ovl.Internal);
5614 ok(ovl.InternalHigh == 4, "expected 4, got %Iu\n", ovl.InternalHigh);
5615
5616 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5617 ok(off == 0, "expected 0, got %lu\n", off);
5618
5619 bytes = 0xdeadbeef;
5620 ret = GetOverlappedResult(hfile, &ovl, &bytes, TRUE);
5621 ok(ret, "GetOverlappedResult error %ld\n", GetLastError());
5622 ok(bytes == 4, "bytes %lu\n", bytes);
5623 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#Ix\n", ovl.Internal);
5624 ok(ovl.InternalHigh == 4, "expected 4, got %Iu\n", ovl.InternalHigh);
5625
5626 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5627 ok(off == 0, "expected 0, got %lu\n", off);
5628
5629 ovl.Offset = 0;
5630 ovl.OffsetHigh = 0;
5631 ovl.Internal = -1;
5632 ovl.InternalHigh = -1;
5633 ovl.hEvent = 0;
5634 bytes = 0;
5635 SetLastError(0xdeadbeef);
5636 ret = ReadFile(hfile, buf, sizeof(buf), &bytes, &ovl);
5637 ok((!ret && GetLastError() == ERROR_IO_PENDING) || broken(ret) /* before Vista */,
5638 "Unexpected result %#lx, GetLastError() %lu.\n", ret, GetLastError());
5639 if (!ret)
5640 {
5641 ok(bytes == 0, "bytes %lu\n", bytes);
5642 ret = WaitForSingleObject(hfile, 3000);
5643 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject error %ld\n", ret);
5644 }
5645 else ok(bytes == 14, "bytes %lu\n", bytes);
5646 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#Ix\n", ovl.Internal);
5647 ok(ovl.InternalHigh == sizeof(contents), "expected sizeof(contents), got %Iu\n", ovl.InternalHigh);
5648
5649 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5650 ok(off == 0, "expected 0, got %lu\n", off);
5651
5652 bytes = 0xdeadbeef;
5653 ret = GetOverlappedResult(hfile, &ovl, &bytes, TRUE);
5654 ok(ret, "GetOverlappedResult error %ld\n", GetLastError());
5655 ok(bytes == sizeof(contents), "bytes %lu\n", bytes);
5656 ok((NTSTATUS)ovl.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#Ix\n", ovl.Internal);
5657 ok(ovl.InternalHigh == sizeof(contents), "expected sizeof(contents), got %Iu\n", ovl.InternalHigh);
5658 ok(!memcmp(contents, buf, sizeof(contents) - 4), "file contents mismatch\n");
5659 ok(!memcmp(buf + sizeof(contents) - 4, "ABCD", 4), "file contents mismatch\n");
5660
5661 off = SetFilePointer(hfile, 0, NULL, FILE_CURRENT);
5662 ok(off == 0, "expected 0, got %lu\n", off);
5663
5665 CloseHandle(hfile);
5666}
5667
5668static void test_ioctl(void)
5669{
5670 HANDLE event = CreateEventA(NULL, TRUE, FALSE, NULL);
5671 FILE_PIPE_PEEK_BUFFER peek_buf;
5673 HANDLE file;
5675
5677 ok(file != INVALID_HANDLE_VALUE, "could not create temp file\n");
5678
5679 SetEvent(event);
5680 status = pNtFsControlFile(file, event, NULL, NULL, &iosb, 0xdeadbeef, 0, 0, 0, 0);
5681 todo_wine
5682 ok(status == STATUS_INVALID_DEVICE_REQUEST, "NtFsControlFile returned %lx\n", status);
5683 ok(!is_signaled(event), "event is signaled\n");
5684
5685 status = pNtFsControlFile(file, (HANDLE)0xdeadbeef, NULL, NULL, &iosb, 0xdeadbeef, 0, 0, 0, 0);
5686 ok(status == STATUS_INVALID_HANDLE, "NtFsControlFile returned %lx\n", status);
5687
5688 memset(&iosb, 0x55, sizeof(iosb));
5689 status = pNtFsControlFile(file, NULL, NULL, NULL, &iosb, FSCTL_PIPE_PEEK, NULL, 0,
5690 &peek_buf, sizeof(peek_buf));
5691 todo_wine
5692 ok(status == STATUS_INVALID_DEVICE_REQUEST, "NtFsControlFile failed: %lx\n", status);
5693 ok(iosb.Status == 0x55555555, "iosb.Status = %lx\n", iosb.Status);
5694
5697}
5698
5700{
5701 char path[MAX_PATH], buffer[MAX_PATH];
5702 HANDLE hfile, hfileread;
5704 IO_STATUS_BLOCK io_status_block;
5705
5707 GetTempFileNameA(path, "foo", 0, buffer);
5710 ok(hfile != INVALID_HANDLE_VALUE, "failed to create temp file.\n" );
5711
5713 OPEN_EXISTING, 0, NULL);
5714 ok(hfileread != INVALID_HANDLE_VALUE, "could not open temp file, error %ld.\n", GetLastError());
5715
5716 status = pNtFlushBuffersFile(hfile, NULL);
5718
5719 status = pNtFlushBuffersFile(hfile, (IO_STATUS_BLOCK *)0xdeadbeaf);
5720 ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %#lx.\n", status);
5721
5722 io_status_block.Information = 0xdeadbeef;
5723 io_status_block.Status = 0xdeadbeef;
5724 status = pNtFlushBuffersFile(hfile, &io_status_block);
5725 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx.\n", status);
5726 ok(io_status_block.Status == STATUS_SUCCESS, "Got unexpected io_status_block.Status %#lx.\n",
5727 io_status_block.Status);
5728 ok(!io_status_block.Information, "Got unexpected io_status_block.Information %#Ix.\n",
5729 io_status_block.Information);
5730
5731 status = pNtFlushBuffersFile(hfileread, &io_status_block);
5732 ok(status == STATUS_ACCESS_DENIED, "expected STATUS_ACCESS_DENIED, got %#lx.\n", status);
5733
5734 io_status_block.Information = 0xdeadbeef;
5735 io_status_block.Status = 0xdeadbeef;
5736 status = pNtFlushBuffersFile(NULL, &io_status_block);
5737 ok(status == STATUS_INVALID_HANDLE, "expected STATUS_INVALID_HANDLE, got %#lx.\n", status);
5738 ok(io_status_block.Status == 0xdeadbeef, "Got unexpected io_status_block.Status %#lx.\n",
5739 io_status_block.Status);
5740 ok(io_status_block.Information == 0xdeadbeef, "Got unexpected io_status_block.Information %#Ix.\n",
5741 io_status_block.Information);
5742
5743 CloseHandle(hfileread);
5744 CloseHandle(hfile);
5746 OPEN_EXISTING, 0, NULL);
5747 ok(hfile != INVALID_HANDLE_VALUE, "could not open temp file, error %ld.\n", GetLastError());
5748
5749 status = pNtFlushBuffersFile(hfile, &io_status_block);
5750 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx.\n", status);
5751
5752 io_status_block.Information = 0xdeadbeef;
5753 io_status_block.Status = 0xdeadbeef;
5754 status = pNtFlushBuffersFile((HANDLE)0xdeadbeef, &io_status_block);
5755 ok(status == STATUS_INVALID_HANDLE, "expected STATUS_INVALID_HANDLE, got %#lx.\n", status);
5756 ok(io_status_block.Status == 0xdeadbeef, "Got unexpected io_status_block.Status %#lx.\n",
5757 io_status_block.Status);
5758 ok(io_status_block.Information == 0xdeadbeef, "Got unexpected io_status_block.Information %#Ix.\n",
5759 io_status_block.Information);
5760
5761 CloseHandle(hfile);
5763}
5764
5765static void test_query_ea(void)
5766{
5767#define EA_BUFFER_SIZE 4097
5768 unsigned char data[EA_BUFFER_SIZE + 8];
5769 unsigned char *buffer = (void *)(((DWORD_PTR)data + 7) & ~7);
5770 DWORD buffer_len, i;
5773 HANDLE handle;
5774
5775 if (!(handle = create_temp_file(0))) return;
5776
5777 /* test with INVALID_HANDLE_VALUE */
5778 io.Status = 0xdeadbeef;
5779 io.Information = 0xdeadbeef;
5781 buffer_len = EA_BUFFER_SIZE - 1;
5782 status = pNtQueryEaFile(INVALID_HANDLE_VALUE, &io, buffer, buffer_len, TRUE, NULL, 0, NULL, FALSE);
5783 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#lx\n", status);
5784 ok(io.Status == 0xdeadbeef, "expected 0xdeadbeef, got %#lx\n", io.Status);
5785 ok(io.Information == 0xdeadbeef, "expected 0xdeadbeef, got %#Ix\n", io.Information);
5786 ok(buffer[0] == 0xcc, "data at position 0 overwritten\n");
5787
5788 /* test with 0xdeadbeef */
5789 io.Status = 0xdeadbeef;
5790 io.Information = 0xdeadbeef;
5792 buffer_len = EA_BUFFER_SIZE - 1;
5793 status = pNtQueryEaFile((void *)0xdeadbeef, &io, buffer, buffer_len, TRUE, NULL, 0, NULL, FALSE);
5794 ok(status == STATUS_INVALID_HANDLE, "expected STATUS_INVALID_HANDLE, got %#lx\n", status);
5795 ok(io.Status == 0xdeadbeef, "expected 0xdeadbeef, got %#lx\n", io.Status);
5796 ok(io.Information == 0xdeadbeef, "expected 0xdeadbeef, got %#Ix\n", io.Information);
5797 ok(buffer[0] == 0xcc, "data at position 0 overwritten\n");
5798
5799 /* test without buffer */
5800 io.Status = 0xdeadbeef;
5801 io.Information = 0xdeadbeef;
5802 status = pNtQueryEaFile(handle, &io, NULL, 0, TRUE, NULL, 0, NULL, FALSE);
5803 ok(status == STATUS_NO_EAS_ON_FILE, "expected STATUS_NO_EAS_ON_FILE, got %#lx\n", status);
5804 ok(io.Status == 0xdeadbeef, "expected 0xdeadbeef, got %#lx\n", io.Status);
5805 ok(io.Information == 0xdeadbeef, "expected 0xdeadbeef, got %#Ix\n", io.Information);
5806
5807 /* test with zero buffer */
5808 io.Status = 0xdeadbeef;
5809 io.Information = 0xdeadbeef;
5810 status = pNtQueryEaFile(handle, &io, buffer, 0, TRUE, NULL, 0, NULL, FALSE);
5811 ok(status == STATUS_NO_EAS_ON_FILE, "expected STATUS_NO_EAS_ON_FILE, got %#lx\n", status);
5812 ok(io.Status == 0xdeadbeef, "expected 0xdeadbeef, got %#lx\n", io.Status);
5813 ok(io.Information == 0xdeadbeef, "expected 0xdeadbeef, got %#Ix\n", io.Information);
5814
5815 /* test with very small buffer */
5816 io.Status = 0xdeadbeef;
5817 io.Information = 0xdeadbeef;
5819 buffer_len = 4;
5820 status = pNtQueryEaFile(handle, &io, buffer, buffer_len, TRUE, NULL, 0, NULL, FALSE);
5821 ok(status == STATUS_NO_EAS_ON_FILE, "expected STATUS_NO_EAS_ON_FILE, got %#lx\n", status);
5822 ok(io.Status == 0xdeadbeef, "expected 0xdeadbeef, got %#lx\n", io.Status);
5823 ok(io.Information == 0xdeadbeef, "expected 0xdeadbeef, got %#Ix\n", io.Information);
5824 for (i = 0; i < buffer_len && !buffer[i]; i++);
5825 ok(i == buffer_len, "expected %lu bytes filled with 0x00, got %lu bytes\n", buffer_len, i);
5826 ok(buffer[i] == 0xcc, "data at position %u overwritten\n", buffer[i]);
5827
5828 /* test with very big buffer */
5829 io.Status = 0xdeadbeef;
5830 io.Information = 0xdeadbeef;
5832 buffer_len = EA_BUFFER_SIZE - 1;
5833 status = pNtQueryEaFile(handle, &io, buffer, buffer_len, TRUE, NULL, 0, NULL, FALSE);
5834 ok(status == STATUS_NO_EAS_ON_FILE, "expected STATUS_NO_EAS_ON_FILE, got %#lx\n", status);
5835 ok(io.Status == 0xdeadbeef, "expected 0xdeadbeef, got %#lx\n", io.Status);
5836 ok(io.Information == 0xdeadbeef, "expected 0xdeadbeef, got %#Ix\n", io.Information);
5837 for (i = 0; i < buffer_len && !buffer[i]; i++);
5838 ok(i == buffer_len, "expected %lu bytes filled with 0x00, got %lu bytes\n", buffer_len, i);
5839 ok(buffer[i] == 0xcc, "data at position %u overwritten\n", buffer[i]);
5840
5842#undef EA_BUFFER_SIZE
5843}
5844
5846{
5847 static const DWORD default_sharing = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
5848 static const WCHAR fooW[] = {'f', 'o', 'o', 0};
5853 HANDLE handle;
5855 DWORD ret;
5856
5857 /* Set up */
5861 pRtlDosPathNameToNtPathName_U(path, &nameW, NULL, NULL);
5862
5863 attr.Length = sizeof(attr);
5864 attr.RootDirectory = NULL;
5865 attr.ObjectName = &nameW;
5866 attr.Attributes = OBJ_CASE_INSENSITIVE;
5867 attr.SecurityDescriptor = NULL;
5868 attr.SecurityQualityOfService = NULL;
5869
5870 status = pNtCreateFile(&handle, FILE_GENERIC_WRITE, &attr, &io, NULL, FILE_ATTRIBUTE_READONLY, default_sharing,
5871 FILE_CREATE, 0, NULL, 0);
5872 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx.\n", status);
5874
5875 /* NtCreateFile FILE_GENERIC_WRITE */
5876 status = pNtCreateFile(&handle, FILE_GENERIC_WRITE, &attr, &io, NULL, FILE_ATTRIBUTE_NORMAL, default_sharing,
5878 ok(status == STATUS_ACCESS_DENIED, "expected STATUS_ACCESS_DENIED, got %#lx.\n", status);
5879
5880 /* NtCreateFile DELETE without FILE_DELETE_ON_CLOSE */
5881 status = pNtCreateFile(&handle, DELETE, &attr, &io, NULL, FILE_ATTRIBUTE_NORMAL, default_sharing, FILE_OPEN,
5883 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx.\n", status);
5885
5886 /* NtCreateFile DELETE with FILE_DELETE_ON_CLOSE */
5887 status = pNtCreateFile(&handle, SYNCHRONIZE | DELETE, &attr, &io, NULL, FILE_ATTRIBUTE_NORMAL, default_sharing,
5889 ok(status == STATUS_CANNOT_DELETE, "expected STATUS_CANNOT_DELETE, got %#lx.\n", status);
5890
5891 /* NtOpenFile GENERIC_WRITE */
5892 status = pNtOpenFile(&handle, GENERIC_WRITE, &attr, &io, default_sharing, FILE_NON_DIRECTORY_FILE);
5893 ok(status == STATUS_ACCESS_DENIED, "expected STATUS_ACCESS_DENIED, got %#lx.\n", status);
5894
5895 /* NtOpenFile DELETE without FILE_DELETE_ON_CLOSE */
5896 status = pNtOpenFile(&handle, DELETE, &attr, &io, default_sharing, FILE_NON_DIRECTORY_FILE);
5897 ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx.\n", status);
5899
5900 /* NtOpenFile DELETE with FILE_DELETE_ON_CLOSE */
5901 status = pNtOpenFile(&handle, DELETE, &attr, &io, default_sharing, FILE_DELETE_ON_CLOSE | FILE_NON_DIRECTORY_FILE);
5902 ok(status == STATUS_CANNOT_DELETE, "expected STATUS_CANNOT_DELETE, got %#lx.\n", status);
5903
5905 ok(ret & FILE_ATTRIBUTE_READONLY, "got wrong attribute: %#lx.\n", ret);
5906
5907 /* Clean up */
5908 pRtlFreeUnicodeString(&nameW);
5911}
5912
5913static void test_mailslot_name(void)
5914{
5915 char buffer[1024] = {0};
5919 NTSTATUS ret;
5920
5921 server = CreateMailslotA( "\\\\.\\mailslot\\winetest", 100, 1000, NULL );
5922 ok(server != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError());
5923
5925 ok(ret == STATUS_INFO_LENGTH_MISMATCH, "got %#lx\n", ret);
5926
5927 memset(buffer, 0xcc, sizeof(buffer));
5930 todo_wine ok(ret == STATUS_BUFFER_OVERFLOW, "got %#lx\n", ret);
5932 {
5933 ok(name->FileNameLength == 18, "got length %lu\n", name->FileNameLength);
5934 ok(!memcmp(name->FileName, L"\\wine", 10), "got %s\n",
5935 debugstr_wn(name->FileName, name->FileNameLength / sizeof(WCHAR)));
5936 }
5937
5938 memset(buffer, 0xcc, sizeof(buffer));
5940 todo_wine ok(!ret, "got %#lx\n", ret);
5941 if (!ret)
5942 {
5943 ok(name->FileNameLength == 18, "got length %lu\n", name->FileNameLength);
5944 ok(!memcmp(name->FileName, L"\\winetest", 18), "got %s\n",
5945 debugstr_wn(name->FileName, name->FileNameLength / sizeof(WCHAR)));
5946 }
5947
5948 client = CreateFileA( "\\\\.\\mailslot\\winetest", 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
5949 ok(client != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError());
5950
5952 ok(ret == STATUS_INFO_LENGTH_MISMATCH, "got %#lx\n", ret);
5953
5955 todo_wine ok(ret == STATUS_INVALID_PARAMETER || !ret /* win8+ */, "got %#lx\n", ret);
5956 if (!ret)
5957 {
5958 ok(name->FileNameLength == 18, "got length %lu\n", name->FileNameLength);
5959 ok(!memcmp(name->FileName, L"\\winetest", 18), "got %s\n",
5960 debugstr_wn(name->FileName, name->FileNameLength / sizeof(WCHAR)));
5961 }
5962
5965
5966 device = CreateFileA("\\\\.\\mailslot", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
5967 ok(device != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError());
5968
5970 ok(ret == STATUS_INFO_LENGTH_MISMATCH, "got %#lx\n", ret);
5971
5973 todo_wine ok(ret == STATUS_INVALID_PARAMETER, "got %#lx\n", ret);
5974
5976}
5977
5978static void test_reparse_points(void)
5979{
5981 HANDLE handle;
5985 unsigned char reparse_data[1];
5986
5987 pRtlInitUnicodeString( &nameW, L"\\??\\C:\\" );
5989
5990 status = pNtOpenFile( &handle, READ_CONTROL, &attr, &io, 0, 0 );
5991 ok( !status, "open %s failed %#lx\n", wine_dbgstr_w(nameW.Buffer), status );
5992
5993 status = pNtFsControlFile( handle, NULL, NULL, NULL, &io, FSCTL_GET_REPARSE_POINT, NULL, 0, NULL, 0 );
5994 ok( status == STATUS_INVALID_USER_BUFFER, "expected %#lx, got %#lx\n", STATUS_INVALID_USER_BUFFER, status );
5995
5996 status = pNtFsControlFile( handle, NULL, NULL, NULL, &io, FSCTL_GET_REPARSE_POINT, NULL, 0, reparse_data, 0 );
5997 ok( status == STATUS_INVALID_USER_BUFFER, "expected %#lx, got %#lx\n", STATUS_INVALID_USER_BUFFER, status );
5998
5999 /* a volume cannot be a reparse point by definition */
6000 status = pNtFsControlFile( handle, NULL, NULL, NULL, &io, FSCTL_GET_REPARSE_POINT, NULL, 0, reparse_data, 1 );
6001 ok( status == STATUS_NOT_A_REPARSE_POINT, "expected %#lx, got %#lx\n", STATUS_NOT_A_REPARSE_POINT, status );
6002
6004}
6005
6007{
6008 HANDLE completion, completion_reserve, apc_reserve;
6009 LARGE_INTEGER timeout = {{0}};
6013 SIZE_T size = 3;
6014
6015 if (!pNtSetIoCompletionEx || !pNtAllocateReserveObject)
6016 {
6017 win_skip("NtSetIoCompletionEx() or NtAllocateReserveObject() is unavailable.\n");
6018 return;
6019 }
6020
6021 if (sizeof(size) > 4) size |= (ULONGLONG)0x12345678 << 32;
6022
6023 status = pNtCreateIoCompletion(&completion, IO_COMPLETION_ALL_ACCESS, NULL, 0);
6024 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
6025 status = pNtAllocateReserveObject(&completion_reserve, NULL, MemoryReserveObjectTypeIoCompletion);
6026 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
6027 status = pNtAllocateReserveObject(&apc_reserve, NULL, MemoryReserveObjectTypeUserApc);
6028 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
6029
6030 /* Parameter checks */
6031 status = pNtSetIoCompletionEx(NULL, completion_reserve, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
6032 ok(status == STATUS_INVALID_HANDLE, "Got unexpected status %#lx.\n", status);
6033
6034 status = pNtSetIoCompletionEx(INVALID_HANDLE_VALUE, completion_reserve, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
6035 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
6036
6038 ok(status == STATUS_INVALID_HANDLE, "Got unexpected status %#lx.\n", status);
6039
6041 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
6042
6043 status = pNtSetIoCompletionEx(completion, apc_reserve, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
6044 ok(status == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected status %#lx.\n", status);
6045
6046 /* Normal call */
6047 status = pNtSetIoCompletionEx(completion, completion_reserve, CKEY_FIRST, CVALUE_FIRST, STATUS_INVALID_DEVICE_REQUEST, size);
6048 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
6049
6050 status = pNtRemoveIoCompletion(completion, &key, &value, &iosb, &timeout);
6051 ok(status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status);
6052 ok(key == CKEY_FIRST, "Invalid completion key: %#Ix\n", key);
6053 ok(iosb.Information == size, "Invalid iosb.Information: %Iu\n", iosb.Information);
6054 ok(iosb.Status == STATUS_INVALID_DEVICE_REQUEST, "Invalid iosb.Status: %#lx\n", iosb.Status);
6055 ok(value == CVALUE_FIRST, "Invalid completion value: %#Ix\n", value);
6056
6057 CloseHandle(apc_reserve);
6058 CloseHandle(completion_reserve);
6060}
6061
6063{
6064 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
6065 HMODULE hntdll = GetModuleHandleA("ntdll.dll");
6066 if (!hntdll)
6067 {
6068 skip("not running on NT, skipping test\n");
6069 return;
6070 }
6071
6072 pGetVolumePathNameW = (void *)GetProcAddress(hkernel32, "GetVolumePathNameW");
6073 pGetSystemWow64DirectoryW = (void *)GetProcAddress(hkernel32, "GetSystemWow64DirectoryW");
6074
6075 pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString");
6076 pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
6077 pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U");
6078 pRtlWow64EnableFsRedirectionEx = (void *)GetProcAddress(hntdll, "RtlWow64EnableFsRedirectionEx");
6079 pNtAllocateReserveObject= (void *)GetProcAddress(hntdll, "NtAllocateReserveObject");
6080 pNtCreateMailslotFile = (void *)GetProcAddress(hntdll, "NtCreateMailslotFile");
6081 pNtCreateFile = (void *)GetProcAddress(hntdll, "NtCreateFile");
6082 pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile");
6083 pNtDeleteFile = (void *)GetProcAddress(hntdll, "NtDeleteFile");
6084 pNtReadFile = (void *)GetProcAddress(hntdll, "NtReadFile");
6085 pNtWriteFile = (void *)GetProcAddress(hntdll, "NtWriteFile");
6086 pNtCancelIoFile = (void *)GetProcAddress(hntdll, "NtCancelIoFile");
6087 pNtCancelIoFileEx = (void *)GetProcAddress(hntdll, "NtCancelIoFileEx");
6088 pNtClose = (void *)GetProcAddress(hntdll, "NtClose");
6089 pNtFsControlFile = (void *)GetProcAddress(hntdll, "NtFsControlFile");
6090 pNtCreateIoCompletion = (void *)GetProcAddress(hntdll, "NtCreateIoCompletion");
6091 pNtOpenIoCompletion = (void *)GetProcAddress(hntdll, "NtOpenIoCompletion");
6092 pNtQueryIoCompletion = (void *)GetProcAddress(hntdll, "NtQueryIoCompletion");
6093 pNtRemoveIoCompletion = (void *)GetProcAddress(hntdll, "NtRemoveIoCompletion");
6094 pNtRemoveIoCompletionEx = (void *)GetProcAddress(hntdll, "NtRemoveIoCompletionEx");
6095 pNtSetIoCompletion = (void *)GetProcAddress(hntdll, "NtSetIoCompletion");
6096 pNtSetIoCompletionEx = (void *)GetProcAddress(hntdll, "NtSetIoCompletionEx");
6097 pNtSetInformationFile = (void *)GetProcAddress(hntdll, "NtSetInformationFile");
6098 pNtQueryAttributesFile = (void *)GetProcAddress(hntdll, "NtQueryAttributesFile");
6099 pNtQueryInformationFile = (void *)GetProcAddress(hntdll, "NtQueryInformationFile");
6100 pNtQueryDirectoryFile = (void *)GetProcAddress(hntdll, "NtQueryDirectoryFile");
6101 pNtQueryVolumeInformationFile = (void *)GetProcAddress(hntdll, "NtQueryVolumeInformationFile");
6102 pNtQueryFullAttributesFile = (void *)GetProcAddress(hntdll, "NtQueryFullAttributesFile");
6103 pNtFlushBuffersFile = (void *)GetProcAddress(hntdll, "NtFlushBuffersFile");
6104 pNtQueryEaFile = (void *)GetProcAddress(hntdll, "NtQueryEaFile");
6105
6140 test_ioctl();
6141 test_query_ea();
6145}
void CALLBACK completion(DWORD dwError, DWORD cbTransferred, LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags)
Definition: WSARecv.c:16
#define VOID
Definition: acefi.h:82
unsigned char BOOLEAN
Definition: actypes.h:127
#define read
Definition: acwin.h:96
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
#define GetNTVersion()
Definition: apitest.h:17
unsigned int dir
Definition: maze.c:112
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
LONG NTSTATUS
Definition: precomp.h:26
static const WCHAR nameW[]
Definition: main.c:49
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
void restart(int argc, const char *argv[])
Definition: cmds.c:2115
#define ARRAY_SIZE(A)
Definition: main.h:20
struct _root root
return
Definition: dirsup.c:529
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define STATUS_TIMEOUT
Definition: d3dkmdt.h:49
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: d3dkmdt.h:46
#define ERROR_IO_PENDING
Definition: dderror.h:15
HRESULT hr
Definition: delayimp.cpp:573
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static int find_data(const struct Vector *v, const BYTE *pData, int size)
Definition: filtermapper.c:162
#define NTSTATUS
Definition: precomp.h:19
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define PAGE_READONLY
Definition: compat.h:138
#define FILE_BEGIN
Definition: compat.h:761
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:756
#define UnmapViewOfFile
Definition: compat.h:746
#define wcsrchr
Definition: compat.h:16
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetFilePointer
Definition: compat.h:743
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define GetCurrentProcess()
Definition: compat.h:759
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CreateFileW
Definition: compat.h:741
#define FILE_MAP_READ
Definition: compat.h:776
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define lstrcpyW
Definition: compat.h:749
#define MapViewOfFile
Definition: compat.h:745
#define MultiByteToWideChar
Definition: compat.h:110
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define FILE_SHARE_READ
Definition: compat.h:136
#define lstrlenW
Definition: compat.h:750
HANDLE WINAPI CreateMailslotA(IN LPCSTR lpName, IN DWORD nMaxMessageSize, IN DWORD lReadTimeout, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: mailslot.c:23
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
Definition: handle.c:149
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI QueueUserAPC(IN PAPCFUNC pfnAPC, IN HANDLE hThread, IN ULONG_PTR dwData)
Definition: thread.c:959
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4152
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4171
DWORD WINAPI DECLSPEC_HOTPATCH GetTempPathA(DWORD count, LPSTR path)
Definition: file.c:2420
UINT WINAPI DECLSPEC_HOTPATCH GetTempFileNameW(LPCWSTR path, LPCWSTR prefix, UINT unique, LPWSTR buffer)
Definition: file.c:2355
DWORD WINAPI DECLSPEC_HOTPATCH GetTempPathW(DWORD count, LPWSTR path)
Definition: file.c:2438
BOOL WINAPI DECLSPEC_HOTPATCH WriteFile(HANDLE file, LPCVOID buffer, DWORD count, LPDWORD result, LPOVERLAPPED overlapped)
Definition: file.c:3896
BOOL WINAPI DECLSPEC_HOTPATCH SetFileAttributesA(LPCSTR name, DWORD attributes)
Definition: file.c:2906
BOOL WINAPI DECLSPEC_HOTPATCH GetOverlappedResult(HANDLE file, LPOVERLAPPED overlapped, LPDWORD result, BOOL wait)
Definition: file.c:3255
BOOL WINAPI DECLSPEC_HOTPATCH GetFileInformationByHandle(HANDLE file, BY_HANDLE_FILE_INFORMATION *info)
Definition: file.c:3038
BOOL WINAPI DECLSPEC_HOTPATCH DeleteFileW(LPCWSTR path)
Definition: file.c:1003
BOOL WINAPI DECLSPEC_HOTPATCH DeleteFileA(LPCSTR path)
Definition: file.c:991
HANDLE WINAPI DECLSPEC_HOTPATCH FindFirstFileW(const WCHAR *filename, WIN32_FIND_DATAW *data)
Definition: file.c:1372
UINT WINAPI DECLSPEC_HOTPATCH GetTempFileNameA(LPCSTR path, LPCSTR prefix, UINT unique, LPSTR buffer)
Definition: file.c:2335
BOOL WINAPI DECLSPEC_HOTPATCH RemoveDirectoryA(LPCSTR path)
Definition: file.c:3607
DWORD WINAPI DECLSPEC_HOTPATCH GetFileAttributesA(LPCSTR name)
Definition: file.c:1659
UINT WINAPI DECLSPEC_HOTPATCH GetWindowsDirectoryW(LPWSTR path, UINT count)
Definition: file.c:2522
BOOL WINAPI DECLSPEC_HOTPATCH SetFileAttributesW(LPCWSTR name, DWORD attributes)
Definition: file.c:2918
UINT WINAPI DECLSPEC_HOTPATCH GetSystemDirectoryW(LPWSTR path, UINT count)
Definition: file.c:2258
BOOL WINAPI DECLSPEC_HOTPATCH CreateDirectoryW(LPCWSTR path, LPSECURITY_ATTRIBUTES sa)
Definition: file.c:653
BOOL WINAPI DECLSPEC_HOTPATCH CreateDirectoryA(LPCSTR path, LPSECURITY_ATTRIBUTES sa)
Definition: file.c:641
BOOL WINAPI DECLSPEC_HOTPATCH RemoveDirectoryW(LPCWSTR path)
Definition: file.c:3619
BOOL WINAPI DECLSPEC_HOTPATCH FindClose(HANDLE handle)
Definition: file.c:1525
BOOL WINAPI DECLSPEC_HOTPATCH SetEndOfFile(HANDLE file)
Definition: file.c:3651
DWORD WINAPI DECLSPEC_HOTPATCH GetFileAttributesW(LPCWSTR name)
Definition: file.c:1671
LPWSTR WINAPI CharLowerW(WCHAR *str)
Definition: string.c:1092
const WCHAR * text
Definition: package.c:1794
FILE *CDECL tmpfile(void)
Definition: file.c:5199
#define DECLSPEC_ALIGN(x)
Definition: corecrt.h:141
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
static const WCHAR systemrootW[]
Definition: path.c:4194
USHORT port
Definition: uri.c:228
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
r reserved
Definition: btrfs.c:3006
#define FileStatInformation
Definition: fileinfo.c:28
#define FILE_RENAME_IGNORE_READONLY_ATTRIBUTE
Definition: fileinfo.c:126
#define FILE_LINK_IGNORE_READONLY_ATTRIBUTE
Definition: fileinfo.c:140
#define FILE_DISPOSITION_POSIX_SEMANTICS
Definition: fileinfo.c:131
#define FILE_DISPOSITION_ON_CLOSE
Definition: fileinfo.c:133
#define FileIdInformation
Definition: fileinfo.c:24
#define FileRenameInformationEx
Definition: fileinfo.c:27
#define FileDispositionInformationEx
Definition: fileinfo.c:26
#define FILE_DISPOSITION_DELETE
Definition: fileinfo.c:130
#define FILE_RENAME_REPLACE_IF_EXISTS
Definition: fileinfo.c:120
#define FileLinkInformationEx
Definition: fileinfo.c:31
#define FILE_LINK_REPLACE_IF_EXISTS
Definition: fileinfo.c:135
#define ULONG_PTR
Definition: config.h:101
struct _IO_STATUS_BLOCK * PIO_STATUS_BLOCK
Definition: change.c:34
HANDLE NTAPI CreateFileMappingA(IN HANDLE hFile, IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes, IN DWORD flProtect, IN DWORD dwMaximumSizeHigh, IN DWORD dwMaximumSizeLow, IN LPCSTR lpName)
Definition: filemap.c:23
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define STATUS_ACCESS_VIOLATION
#define FILE_OPEN_BY_FILE_ID
Definition: from_kernel.h:41
@ FileRenameInformation
Definition: from_kernel.h:71
@ FileAllInformation
Definition: from_kernel.h:79
@ FileLinkInformation
Definition: from_kernel.h:72
@ FileAttributeTagInformation
Definition: from_kernel.h:96
@ FileIdBothDirectoryInformation
Definition: from_kernel.h:98
@ FileIoCompletionNotificationInformation
Definition: from_kernel.h:102
@ FileNameInformation
Definition: from_kernel.h:70
@ FileCompletionInformation
Definition: from_kernel.h:91
@ FileModeInformation
Definition: from_kernel.h:77
@ FileBasicInformation
Definition: from_kernel.h:65
@ FileDispositionInformation
Definition: from_kernel.h:74
@ FileBothDirectoryInformation
Definition: from_kernel.h:64
#define FILE_NO_COMPRESSION
Definition: from_kernel.h:43
#define FILE_OPEN
Definition: from_kernel.h:54
#define FILE_CREATE
Definition: from_kernel.h:55
enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS
Definition: directory.c:44
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
struct _FILE_FS_ATTRIBUTE_INFORMATION FILE_FS_ATTRIBUTE_INFORMATION
@ FileFsAttributeInformation
Definition: from_kernel.h:223
@ FileFsVolumeInformation
Definition: from_kernel.h:219
@ FileFsSizeInformation
Definition: from_kernel.h:221
#define FILE_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
#define FILE_RANDOM_ACCESS
Definition: from_kernel.h:38
#define FILE_OVERWRITE
Definition: from_kernel.h:57
#define FILE_WRITE_THROUGH
Definition: from_kernel.h:26
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define FILE_SEQUENTIAL_ONLY
Definition: from_kernel.h:27
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
struct _cl_event * event
Definition: glext.h:7739
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLenum mode
Definition: glext.h:6217
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
GLuint64EXT * result
Definition: glext.h:11304
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const char * filename
Definition: ioapi.h:137
HANDLE WINAPI CreateIoCompletionPort(IN HANDLE FileHandle, IN HANDLE ExistingCompletionPort, IN ULONG_PTR CompletionKey, IN DWORD NumberOfConcurrentThreads)
Definition: iocompl.c:65
#define FILE_SKIP_SET_EVENT_ON_HANDLE
Definition: iocompl.c:23
#define FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
Definition: iocompl.c:22
BOOL WINAPI GetQueuedCompletionStatus(IN HANDLE CompletionHandle, IN LPDWORD lpNumberOfBytesTransferred, OUT PULONG_PTR lpCompletionKey, OUT LPOVERLAPPED *lpOverlapped, IN DWORD dwMilliseconds)
Definition: iocompl.c:131
#define a
Definition: ke_i.h:78
#define debugstr_wn
Definition: kernel32.h:33
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define win_skip
Definition: minitest.h:67
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
Definition: test.h:537
#define todo_wine
Definition: minitest.h:80
#define ZeroMemory
Definition: minwinbase.h:31
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define CREATE_ALWAYS
Definition: disk.h:72
#define FILE_FLAG_OVERLAPPED
Definition: disk.h:46
#define FILE_FLAG_NO_BUFFERING
Definition: disk.h:45
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
#define FILE_FLAG_DELETE_ON_CLOSE
Definition: disk.h:42
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static const WCHAR filenameW[]
Definition: amstream.c:41
BOOL expected
Definition: store.c:2000
static HANDLE PIO_APC_ROUTINE void PIO_STATUS_BLOCK io_status
Definition: comm.c:56
static HANDLE PIO_APC_ROUTINE void * apc_user
Definition: comm.c:55
static ACCESS_MASK
Definition: file.c:51
static POBJECT_ATTRIBUTES
Definition: file.c:51
static char filename[MAX_PATH]
Definition: file.c:63
#define TEST_OVERLAPPED_READ_SIZE
Definition: file.c:5785
static void test_file_readonly_access(void)
Definition: file.c:5849
static LPWSTR
Definition: file.c:50
static PWSTR CURDIR *static BOOLEAN
Definition: file.c:54
static PLARGE_INTEGER
Definition: file.c:52
static PUNICODE_STRING
Definition: file.c:53
static OVERLAPPED_ENTRY ULONG BOOL
Definition: file.c:56
static void test_read_write(void)
Definition: file.c:3396
static LONGLONG
Definition: file.c:46
static UINT
Definition: file.c:42
static const WCHAR pathW[]
Definition: path.c:2368
static HINSTANCE hkernel32
Definition: process.c:68
static HINSTANCE hntdll
Definition: process.c:68
static int apc_count
Definition: sync.c:2950
static void append_file_test(void)
Definition: file.c:795
static void test_file_both_information(void)
Definition: file.c:3192
#define EA_BUFFER_SIZE
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG PVOID ULONG out_size
Definition: file.c:72
#define CKEY_FIRST
Definition: file.c:114
static void test_file_mode(void)
Definition: file.c:4623
static void test_file_all_name_information(void)
Definition: file.c:3974
static void test_file_stat_information(void)
Definition: file.c:4481
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG PVOID out_buffer
Definition: file.c:72
static void test_query_ea(void)
Definition: file.c:5765
static void test_file_basic_information(void)
Definition: file.c:1392
#define IO_COMPLETION_ALL_ACCESS
Definition: file.c:43
static HANDLE PIO_APC_ROUTINE PVOID apc_context
Definition: file.c:72
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK io
Definition: file.c:72
static void _test_completion_flags(unsigned line, HANDLE handle, DWORD expected_flags)
Definition: file.c:4110
static void test_set_io_completion_ex(void)
Definition: file.c:6006
#define TEST_BUF_LEN
Definition: file.c:98
#define CVALUE_FIRST
Definition: file.c:113
static void test_file_link_information(FILE_INFORMATION_CLASS class)
Definition: file.c:2341
static NTSTATUS nt_get_file_attrs(const char *name, DWORD *attrs)
Definition: file.c:3208
static FS_INFORMATION_CLASS
Definition: file.c:86
static HANDLE event
Definition: file.c:72
static WCHAR fooW[]
Definition: file.c:91
static HANDLE PIO_APC_ROUTINE apc
Definition: file.c:61
static void test_reparse_points(void)
Definition: file.c:5978
static void test_file_access_information(void)
Definition: file.c:4412
static HANDLE hEvent
Definition: file.c:60
static void test_NtCreateFile(void)
Definition: file.c:4811
static void open_file_test(void)
Definition: file.c:334
#define CKEY_SECOND
Definition: file.c:115
static PWSTR CURDIR *static ULONG *static const OBJECT_ATTRIBUTES MEMORY_RESERVE_OBJECT_TYPE
Definition: file.c:54
#define test_completion_flags(a, b)
Definition: file.c:4109
static HANDLE create_temp_file(ULONG flags)
Definition: file.c:100
static void test_query_volume_information_file(void)
Definition: file.c:4715
static void test_query_attribute_information_file(void)
Definition: file.c:4765
static void create_file_test(void)
Definition: file.c:139
static IO_COMPLETION_INFORMATION_CLASS
Definition: file.c:76
static void test_file_name_information(void)
Definition: file.c:3845
static BOOL is_signaled(HANDLE obj)
Definition: file.c:93
static PULONG
Definition: file.c:76
static void test_mailslot_name(void)
Definition: file.c:5913
static void test_file_io_completion(void)
Definition: file.c:1145
static void test_file_rename_information_ex(void)
Definition: file.c:2243
static void test_file_link_information_ex(void)
Definition: file.c:3100
static void test_file_disposition_information(void)
Definition: file.c:3239
static void test_set_io_completion(void)
Definition: file.c:953
static SIZE_T
Definition: file.c:79
static PIO_APC_ROUTINE
Definition: file.c:84
static void delete_object(WCHAR *path)
Definition: file.c:1563
static PIO_STATUS_BLOCK iosb
Definition: file.c:70
static void test_file_completion_information(void)
Definition: file.c:4125
static ULONG get_pending_msgs(HANDLE h)
Definition: file.c:117
static void test_file_full_size_information(void)
Definition: file.c:1340
static void test_flush_buffers_file(void)
Definition: file.c:5699
static void test_file_attribute_tag_information(void)
Definition: file.c:4435
static void test_file_id_information(void)
Definition: file.c:4373
static void test_ioctl(void)
Definition: file.c:5668
static FILE_INFORMATION_CLASS
Definition: file.c:81
static void test_file_rename_information(FILE_INFORMATION_CLASS class)
Definition: file.c:1577
static void delete_file_test(void)
Definition: file.c:573
static void test_dotfile_file_attributes(void)
Definition: file.c:4558
static void rename_file(HANDLE h, const WCHAR *filename)
Definition: file.c:4532
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID in_buffer
Definition: file.c:72
static PULONG_PTR
Definition: file.c:77
static void test_file_all_information(void)
Definition: file.c:1493
static void WINAPI user_apc_proc(ULONG_PTR arg)
Definition: file.c:947
static void read_file_test(void)
Definition: file.c:637
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG in_size
Definition: file.c:72
static void nt_mailslot_test(void)
Definition: file.c:886
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
static const char * contents
Definition: parser.c:511
static LPCWSTR file_name
Definition: protocol.c:147
static int send_buf(SOCKET s, const char *buf, size_t length)
Definition: send.c:74
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
_In_ HANDLE hFile
Definition: mswsock.h:90
unsigned int UINT
Definition: ndis.h:50
@ IoCompletionBasicInformation
Definition: iotypes.h:234
HANDLE WINAPI CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: npipe.c:220
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3950
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define FILE_READ_DATA
Definition: nt_native.h:628
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define FILE_CREATED
Definition: nt_native.h:770
NTSYSAPI NTSTATUS NTAPI NtSetInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
Definition: iofunc.c:3096
NTSYSAPI NTSTATUS NTAPI NtQueryInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
#define FILE_OVERWRITTEN
Definition: nt_native.h:771
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_SUPERSEDED
Definition: nt_native.h:768
#define FILE_APPEND_DATA
Definition: nt_native.h:634
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define DELETE
Definition: nt_native.h:57
#define READ_CONTROL
Definition: nt_native.h:58
#define FILE_ALL_ACCESS
Definition: nt_native.h:651
#define FILE_OPENED
Definition: nt_native.h:769
#define DWORD
Definition: nt_native.h:44
#define GENERIC_WRITE
Definition: nt_native.h:90
#define FILE_GENERIC_WRITE
Definition: nt_native.h:660
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:100
#define FileFsFullSizeInformation
Definition: ntifs_ex.h:389
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_USER_APC
Definition: ntstatus.h:130
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:416
#define STATUS_OBJECT_PATH_SYNTAX_BAD
Definition: ntstatus.h:389
#define STATUS_NO_EAS_ON_FILE
Definition: ntstatus.h:412
#define STATUS_PIPE_BROKEN
Definition: ntstatus.h:661
#define STATUS_NOT_A_REPARSE_POINT
Definition: ntstatus.h:875
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:333
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
#define FSCTL_GET_REPARSE_POINT
Definition: winioctl.h:753
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define wine_dbgstr_wn
Definition: testlist.c:2
const WCHAR * str
#define offsetof(TYPE, MEMBER)
wcscat
#define memset(x, y, z)
Definition: compat.h:39
static FILE * client
Definition: client.c:37
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25
#define FileAccessInformation
Definition: propsheet.cpp:51
#define FileStandardInformation
Definition: propsheet.cpp:61
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
FILE_STANDARD_INFORMATION StandardInformation
Definition: winternl.h:1791
FILE_BASIC_INFORMATION BasicInformation
Definition: winternl.h:1790
LARGE_INTEGER LastWriteTime
Definition: nt_native.h:944
LARGE_INTEGER CreationTime
Definition: nt_native.h:942
LARGE_INTEGER LastAccessTime
Definition: nt_native.h:943
LARGE_INTEGER ActualAvailableAllocationUnits
Definition: from_kernel.h:272
LARGE_INTEGER CallerAvailableAllocationUnits
Definition: from_kernel.h:271
LARGE_INTEGER TotalAllocationUnits
Definition: from_kernel.h:270
LARGE_INTEGER TotalAllocationUnits
Definition: from_kernel.h:263
LARGE_INTEGER AvailableAllocationUnits
Definition: from_kernel.h:264
LARGE_INTEGER VolumeCreationTime
Definition: winioctl.h:608
FILE_ID_128 FileId
Definition: fileinfo.c:36
ULONGLONG VolumeSerialNumber
Definition: fileinfo.c:35
LARGE_INTEGER LastAccessTime
Definition: fileinfo.c:42
ACCESS_MASK EffectiveAccess
Definition: fileinfo.c:50
LARGE_INTEGER FileId
Definition: fileinfo.c:40
LARGE_INTEGER EndOfFile
Definition: fileinfo.c:46
LARGE_INTEGER LastWriteTime
Definition: fileinfo.c:43
LARGE_INTEGER CreationTime
Definition: fileinfo.c:41
DWORD OffsetHigh
Definition: minwinbase.h:226
DWORD Offset
Definition: minwinbase.h:225
HANDLE hEvent
Definition: minwinbase.h:230
ULONG_PTR Internal
Definition: minwinbase.h:219
ULONG_PTR InternalHigh
Definition: minwinbase.h:220
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: cookie.c:202
Definition: inflate.c:139
Definition: devices.h:37
Definition: fci.c:127
Definition: copy.c:22
Definition: parser.c:49
Definition: name.c:39
Definition: ps.c:97
Definition: dhcpd.h:248
DWORD WINAPI SleepEx(IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:738
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:573
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:650
#define STATUS_PENDING
Definition: telnetd.h:14
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * LPCWSTR
Definition: typedefs.h:57
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint16_t * LPWSTR
Definition: typedefs.h:56
void * PVOID
Definition: typedefs.h:50
PVOID HANDLE
Definition: typedefs.h:73
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint64_t ULONGLONG
Definition: typedefs.h:67
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_DIRECTORY_NOT_EMPTY
Definition: udferr_usr.h:167
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_FILE_IS_A_DIRECTORY
Definition: udferr_usr.h:164
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
struct _LARGE_INTEGER::@2500 u
LONGLONG QuadPart
Definition: typedefs.h:114
Definition: pdh_main.c:96
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
static rfbScreenInfoPtr server
Definition: vnc.c:74
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2664
_Must_inspect_result_ _In_opt_ WDFKEY _In_ PCUNICODE_STRING _In_ ACCESS_MASK _In_ ULONG CreateOptions
Definition: wdfregistry.h:118
#define success(from, fromstr, to, tostr)
#define PIPE_ACCESS_INBOUND
Definition: winbase.h:167
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1146
#define FILE_CURRENT
Definition: winbase.h:115
#define PIPE_WAIT
Definition: winbase.h:173
#define PIPE_READMODE_MESSAGE
Definition: winbase.h:172
#define WAIT_OBJECT_0
Definition: winbase.h:383
#define PIPE_TYPE_MESSAGE
Definition: winbase.h:170
void * arg
Definition: msvc.h:10
#define WINAPI
Definition: msvc.h:6
#define FSCTL_PIPE_PEEK
Definition: winioctl.h:321
struct _FILE_FS_VOLUME_INFORMATION FILE_FS_VOLUME_INFORMATION
@ MemoryReserveObjectTypeIoCompletion
Definition: winternl.h:2658
@ MemoryReserveObjectTypeUserApc
Definition: winternl.h:2657
#define FILE_SKIP_SET_USER_EVENT_ON_FAST_IO
Definition: winternl.h:1821
#define FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE
Definition: winternl.h:1656
struct _FILE_ALL_INFORMATION FILE_ALL_INFORMATION
#define ERROR_SHARING_VIOLATION
Definition: winerror.h:257
#define ERROR_HANDLE_EOF
Definition: winerror.h:262
#define DUPLICATE_SAME_ACCESS
unsigned char BYTE
Definition: xxhash.c:193