1 /* Unit test suite for Ntdll file functions
3 * Copyright 2007 Jeff Latimer
4 * Copyright 2007 Andrey Turkin
5 * Copyright 2008 Jeff Zaroyko
6 * Copyright 2011 Dmitry Timoshkov
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.
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.
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
23 * We use function pointers here as there is no import library for NTDLL on
31 /* Define WIN32_NO_STATUS so MSVC does not give us duplicate macro
32 * definition errors when we get to winnt.h
34 #define WIN32_NO_STATUS
36 #include "wine/test.h"
37 #include "wine/winternl.h"
39 #include "wine/winioctl.h"
42 typedef struct _REPARSE_DATA_BUFFER
{
44 USHORT ReparseDataLength
;
46 _ANONYMOUS_UNION
union {
48 USHORT SubstituteNameOffset
;
49 USHORT SubstituteNameLength
;
50 USHORT PrintNameOffset
;
51 USHORT PrintNameLength
;
54 } SymbolicLinkReparseBuffer
;
56 USHORT SubstituteNameOffset
;
57 USHORT SubstituteNameLength
;
58 USHORT PrintNameOffset
;
59 USHORT PrintNameLength
;
61 } MountPointReparseBuffer
;
64 } GenericReparseBuffer
;
66 } REPARSE_DATA_BUFFER
, *PREPARSE_DATA_BUFFER
;
68 #ifndef IO_COMPLETION_ALL_ACCESS
69 #define IO_COMPLETION_ALL_ACCESS 0x001F0003
72 static BOOL (WINAPI
* pGetVolumePathNameW
)(LPCWSTR
, LPWSTR
, DWORD
);
73 static UINT (WINAPI
*pGetSystemWow64DirectoryW
)( LPWSTR
, UINT
);
75 static VOID (WINAPI
*pRtlFreeUnicodeString
)( PUNICODE_STRING
);
76 static VOID (WINAPI
*pRtlInitUnicodeString
)( PUNICODE_STRING
, LPCWSTR
);
77 static BOOL (WINAPI
*pRtlDosPathNameToNtPathName_U
)( LPCWSTR
, PUNICODE_STRING
, PWSTR
*, CURDIR
* );
78 static NTSTATUS (WINAPI
*pRtlWow64EnableFsRedirectionEx
)( ULONG
, ULONG
* );
80 static NTSTATUS (WINAPI
*pNtCreateMailslotFile
)( PHANDLE
, ULONG
, POBJECT_ATTRIBUTES
, PIO_STATUS_BLOCK
,
81 ULONG
, ULONG
, ULONG
, PLARGE_INTEGER
);
82 static NTSTATUS (WINAPI
*pNtCreateFile
)(PHANDLE
,ACCESS_MASK
,POBJECT_ATTRIBUTES
,PIO_STATUS_BLOCK
,PLARGE_INTEGER
,ULONG
,ULONG
,ULONG
,ULONG
,PVOID
,ULONG
);
83 static NTSTATUS (WINAPI
*pNtOpenFile
)(PHANDLE
,ACCESS_MASK
,POBJECT_ATTRIBUTES
,PIO_STATUS_BLOCK
,ULONG
,ULONG
);
84 static NTSTATUS (WINAPI
*pNtDeleteFile
)(POBJECT_ATTRIBUTES ObjectAttributes
);
85 static NTSTATUS (WINAPI
*pNtReadFile
)(HANDLE hFile
, HANDLE hEvent
,
86 PIO_APC_ROUTINE apc
, void* apc_user
,
87 PIO_STATUS_BLOCK io_status
, void* buffer
, ULONG length
,
88 PLARGE_INTEGER offset
, PULONG key
);
89 static NTSTATUS (WINAPI
*pNtWriteFile
)(HANDLE hFile
, HANDLE hEvent
,
90 PIO_APC_ROUTINE apc
, void* apc_user
,
91 PIO_STATUS_BLOCK io_status
,
92 const void* buffer
, ULONG length
,
93 PLARGE_INTEGER offset
, PULONG key
);
94 static NTSTATUS (WINAPI
*pNtCancelIoFile
)(HANDLE hFile
, PIO_STATUS_BLOCK io_status
);
95 static NTSTATUS (WINAPI
*pNtCancelIoFileEx
)(HANDLE hFile
, PIO_STATUS_BLOCK iosb
, PIO_STATUS_BLOCK io_status
);
96 static NTSTATUS (WINAPI
*pNtClose
)( PHANDLE
);
98 static NTSTATUS (WINAPI
*pNtCreateIoCompletion
)(PHANDLE
, ACCESS_MASK
, POBJECT_ATTRIBUTES
, ULONG
);
99 static NTSTATUS (WINAPI
*pNtOpenIoCompletion
)(PHANDLE
, ACCESS_MASK
, POBJECT_ATTRIBUTES
);
100 static NTSTATUS (WINAPI
*pNtQueryIoCompletion
)(HANDLE
, IO_COMPLETION_INFORMATION_CLASS
, PVOID
, ULONG
, PULONG
);
101 static NTSTATUS (WINAPI
*pNtRemoveIoCompletion
)(HANDLE
, PULONG_PTR
, PULONG_PTR
, PIO_STATUS_BLOCK
, PLARGE_INTEGER
);
102 static NTSTATUS (WINAPI
*pNtSetIoCompletion
)(HANDLE
, ULONG_PTR
, ULONG_PTR
, NTSTATUS
, SIZE_T
);
103 static NTSTATUS (WINAPI
*pNtSetInformationFile
)(HANDLE
, PIO_STATUS_BLOCK
, PVOID
, ULONG
, FILE_INFORMATION_CLASS
);
104 static NTSTATUS (WINAPI
*pNtQueryInformationFile
)(HANDLE
, PIO_STATUS_BLOCK
, PVOID
, ULONG
, FILE_INFORMATION_CLASS
);
105 static NTSTATUS (WINAPI
*pNtQueryDirectoryFile
)(HANDLE
,HANDLE
,PIO_APC_ROUTINE
,PVOID
,PIO_STATUS_BLOCK
,
106 PVOID
,ULONG
,FILE_INFORMATION_CLASS
,BOOLEAN
,PUNICODE_STRING
,BOOLEAN
);
107 static NTSTATUS (WINAPI
*pNtQueryVolumeInformationFile
)(HANDLE
,PIO_STATUS_BLOCK
,PVOID
,ULONG
,FS_INFORMATION_CLASS
);
108 static NTSTATUS (WINAPI
*pNtQueryFullAttributesFile
)(const OBJECT_ATTRIBUTES
*, FILE_NETWORK_OPEN_INFORMATION
*);
109 static NTSTATUS (WINAPI
*pNtQueryEaFile
)(HANDLE
,PIO_STATUS_BLOCK
,PVOID
,ULONG
,BOOLEAN
,PVOID
,ULONG
,PULONG
,BOOLEAN
);
111 static inline BOOL
is_signaled( HANDLE obj
)
113 return WaitForSingleObject( obj
, 0 ) == WAIT_OBJECT_0
;
116 static const char* debugstr_longlong(ULONGLONG ll
)
119 if (sizeof(ll
) > sizeof(unsigned long) && ll
>> 32)
120 sprintf(str
, "%lx%08lx", (unsigned long)(ll
>> 32), (unsigned long)ll
);
122 sprintf(str
, "%lx", (unsigned long)ll
);
126 #define PIPENAME "\\\\.\\pipe\\ntdll_tests_file.c"
127 #define TEST_BUF_LEN 3
129 static BOOL
create_pipe( HANDLE
*read
, HANDLE
*write
, ULONG flags
, ULONG size
)
131 *read
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_INBOUND
| flags
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
132 1, size
, size
, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
133 ok(*read
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
135 *write
= CreateFileA(PIPENAME
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
136 ok(*write
!= INVALID_HANDLE_VALUE
, "CreateFile failed (%d)\n", GetLastError());
141 static HANDLE
create_temp_file( ULONG flags
)
143 char path
[MAX_PATH
], buffer
[MAX_PATH
];
146 GetTempPathA( MAX_PATH
, path
);
147 GetTempFileNameA( path
, "foo", 0, buffer
);
148 handle
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
149 flags
| FILE_FLAG_DELETE_ON_CLOSE
, 0);
150 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
151 return (handle
== INVALID_HANDLE_VALUE
) ? 0 : handle
;
154 #define CVALUE_FIRST 0xfffabbcc
155 #define CKEY_FIRST 0x1030341
156 #define CKEY_SECOND 0x132E46
158 static ULONG_PTR completionKey
;
159 static IO_STATUS_BLOCK ioSb
;
160 static ULONG_PTR completionValue
;
162 static ULONG
get_pending_msgs(HANDLE h
)
167 res
= pNtQueryIoCompletion( h
, IoCompletionBasicInformation
, &a
, sizeof(a
), &req
);
168 ok( res
== STATUS_SUCCESS
, "NtQueryIoCompletion failed: %x\n", res
);
169 if (res
!= STATUS_SUCCESS
) return -1;
170 ok( req
== sizeof(a
), "Unexpected response size: %x\n", req
);
174 static BOOL
get_msg(HANDLE h
)
176 LARGE_INTEGER timeout
= {{-10000000*3}};
177 DWORD res
= pNtRemoveIoCompletion( h
, &completionKey
, &completionValue
, &ioSb
, &timeout
);
178 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletion failed: %x\n", res
);
179 if (res
!= STATUS_SUCCESS
)
181 completionKey
= completionValue
= 0;
182 memset(&ioSb
, 0, sizeof(ioSb
));
189 static void WINAPI
apc( void *arg
, IO_STATUS_BLOCK
*iosb
, ULONG reserved
)
193 trace( "apc called block %p iosb.status %x iosb.info %lu\n",
194 iosb
, U(*iosb
).Status
, iosb
->Information
);
196 ok( !reserved
, "reserved is not 0: %x\n", reserved
);
199 static void create_file_test(void)
201 static const WCHAR systemrootW
[] = {'\\','S','y','s','t','e','m','R','o','o','t',
202 '\\','f','a','i','l','i','n','g',0};
203 static const WCHAR questionmarkInvalidNameW
[] = {'a','f','i','l','e','?',0};
204 static const WCHAR pipeInvalidNameW
[] = {'a','|','b',0};
205 static const WCHAR pathInvalidNtW
[] = {'\\','\\','?','\\',0};
206 static const WCHAR pathInvalidNt2W
[] = {'\\','?','?','\\',0};
207 static const WCHAR pathInvalidDosW
[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0};
208 static const char testdata
[] = "Hello World";
209 FILE_NETWORK_OPEN_INFORMATION info
;
212 WCHAR path
[MAX_PATH
];
213 OBJECT_ATTRIBUTES attr
;
215 UNICODE_STRING nameW
;
216 LARGE_INTEGER offset
;
220 GetCurrentDirectoryW( MAX_PATH
, path
);
221 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
222 attr
.Length
= sizeof(attr
);
223 attr
.RootDirectory
= 0;
224 attr
.ObjectName
= &nameW
;
225 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
226 attr
.SecurityDescriptor
= NULL
;
227 attr
.SecurityQualityOfService
= NULL
;
229 /* try various open modes and options on directories */
230 status
= pNtCreateFile( &dir
, GENERIC_READ
|GENERIC_WRITE
, &attr
, &io
, NULL
, 0,
231 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, FILE_DIRECTORY_FILE
, NULL
, 0 );
232 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
234 U(io
).Status
= 0xdeadbeef;
236 status
= pNtReadFile( dir
, NULL
, NULL
, NULL
, &io
, buf
, sizeof(buf
), &offset
, NULL
);
237 ok( status
== STATUS_INVALID_DEVICE_REQUEST
|| status
== STATUS_PENDING
, "NtReadFile error %08x\n", status
);
238 if (status
== STATUS_PENDING
)
240 ret
= WaitForSingleObject( dir
, 1000 );
241 ok( ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %u\n", ret
);
242 ok( U(io
).Status
== STATUS_INVALID_DEVICE_REQUEST
,
243 "expected STATUS_INVALID_DEVICE_REQUEST, got %08x\n", U(io
).Status
);
246 U(io
).Status
= 0xdeadbeef;
248 status
= pNtWriteFile( dir
, NULL
, NULL
, NULL
, &io
, testdata
, sizeof(testdata
), &offset
, NULL
);
250 ok( status
== STATUS_INVALID_DEVICE_REQUEST
|| status
== STATUS_PENDING
, "NtWriteFile error %08x\n", status
);
251 if (status
== STATUS_PENDING
)
253 ret
= WaitForSingleObject( dir
, 1000 );
254 ok( ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %u\n", ret
);
255 ok( U(io
).Status
== STATUS_INVALID_DEVICE_REQUEST
,
256 "expected STATUS_INVALID_DEVICE_REQUEST, got %08x\n", U(io
).Status
);
261 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
262 FILE_CREATE
, FILE_DIRECTORY_FILE
, NULL
, 0 );
263 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
264 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
266 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
267 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, NULL
, 0 );
268 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
271 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
272 FILE_SUPERSEDE
, FILE_DIRECTORY_FILE
, NULL
, 0 );
273 ok( status
== STATUS_INVALID_PARAMETER
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
275 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
276 FILE_OVERWRITE
, FILE_DIRECTORY_FILE
, NULL
, 0 );
277 ok( status
== STATUS_INVALID_PARAMETER
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
279 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
280 FILE_OVERWRITE_IF
, FILE_DIRECTORY_FILE
, NULL
, 0 );
281 ok( status
== STATUS_INVALID_PARAMETER
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
283 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
284 FILE_OPEN
, 0, NULL
, 0 );
285 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
288 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
289 FILE_CREATE
, 0, NULL
, 0 );
290 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
291 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
293 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
294 FILE_OPEN_IF
, 0, NULL
, 0 );
295 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
298 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
299 FILE_SUPERSEDE
, 0, NULL
, 0 );
300 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
301 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
303 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
304 FILE_OVERWRITE
, 0, NULL
, 0 );
305 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
306 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
308 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
309 FILE_OVERWRITE_IF
, 0, NULL
, 0 );
310 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
311 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
313 pRtlFreeUnicodeString( &nameW
);
315 pRtlInitUnicodeString( &nameW
, systemrootW
);
316 attr
.Length
= sizeof(attr
);
317 attr
.RootDirectory
= NULL
;
318 attr
.ObjectName
= &nameW
;
319 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
320 attr
.SecurityDescriptor
= NULL
;
321 attr
.SecurityQualityOfService
= NULL
;
323 status
= pNtCreateFile( &dir
, FILE_APPEND_DATA
, &attr
, &io
, NULL
, FILE_ATTRIBUTE_NORMAL
, 0,
324 FILE_OPEN_IF
, FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
326 ok( status
== STATUS_INVALID_PARAMETER
,
327 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
329 /* Invalid chars in file/dirnames */
330 pRtlDosPathNameToNtPathName_U(questionmarkInvalidNameW
, &nameW
, NULL
, NULL
);
331 attr
.ObjectName
= &nameW
;
332 status
= pNtCreateFile(&dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
333 FILE_SHARE_READ
, FILE_CREATE
,
334 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
335 ok(status
== STATUS_OBJECT_NAME_INVALID
,
336 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
338 status
= pNtCreateFile(&file
, GENERIC_WRITE
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
340 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
341 ok(status
== STATUS_OBJECT_NAME_INVALID
,
342 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
343 pRtlFreeUnicodeString(&nameW
);
345 pRtlDosPathNameToNtPathName_U(pipeInvalidNameW
, &nameW
, NULL
, NULL
);
346 attr
.ObjectName
= &nameW
;
347 status
= pNtCreateFile(&dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
348 FILE_SHARE_READ
, FILE_CREATE
,
349 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
350 ok(status
== STATUS_OBJECT_NAME_INVALID
,
351 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
353 status
= pNtCreateFile(&file
, GENERIC_WRITE
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
355 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
356 ok(status
== STATUS_OBJECT_NAME_INVALID
,
357 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
358 pRtlFreeUnicodeString(&nameW
);
360 pRtlInitUnicodeString( &nameW
, pathInvalidNtW
);
361 status
= pNtCreateFile( &dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
362 FILE_SHARE_READ
, FILE_CREATE
,
363 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
364 ok( status
== STATUS_OBJECT_NAME_INVALID
,
365 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
367 status
= pNtQueryFullAttributesFile( &attr
, &info
);
368 todo_wine
ok( status
== STATUS_OBJECT_NAME_INVALID
,
369 "query %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
371 pRtlInitUnicodeString( &nameW
, pathInvalidNt2W
);
372 status
= pNtCreateFile( &dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
373 FILE_SHARE_READ
, FILE_CREATE
,
374 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
375 ok( status
== STATUS_OBJECT_NAME_INVALID
,
376 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
378 status
= pNtQueryFullAttributesFile( &attr
, &info
);
379 ok( status
== STATUS_OBJECT_NAME_INVALID
,
380 "query %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
382 pRtlInitUnicodeString( &nameW
, pathInvalidDosW
);
383 status
= pNtCreateFile( &dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
384 FILE_SHARE_READ
, FILE_CREATE
,
385 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
386 ok( status
== STATUS_OBJECT_NAME_INVALID
,
387 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
389 status
= pNtQueryFullAttributesFile( &attr
, &info
);
390 ok( status
== STATUS_OBJECT_NAME_INVALID
,
391 "query %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
394 static void open_file_test(void)
396 static const char testdata
[] = "Hello World";
397 static WCHAR fooW
[] = {'f','o','o',0};
399 HANDLE dir
, root
, handle
, file
;
400 WCHAR path
[MAX_PATH
], tmpfile
[MAX_PATH
];
402 OBJECT_ATTRIBUTES attr
;
404 UNICODE_STRING nameW
;
406 BOOL ret
, restart
= TRUE
;
409 len
= GetWindowsDirectoryW( path
, MAX_PATH
);
410 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
411 attr
.Length
= sizeof(attr
);
412 attr
.RootDirectory
= 0;
413 attr
.ObjectName
= &nameW
;
414 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
415 attr
.SecurityDescriptor
= NULL
;
416 attr
.SecurityQualityOfService
= NULL
;
417 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
418 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
419 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
420 pRtlFreeUnicodeString( &nameW
);
422 path
[3] = 0; /* root of the drive */
423 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
424 status
= pNtOpenFile( &root
, GENERIC_READ
, &attr
, &io
,
425 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
426 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
427 pRtlFreeUnicodeString( &nameW
);
429 /* test opening system dir with RootDirectory set to windows dir */
430 GetSystemDirectoryW( path
, MAX_PATH
);
431 while (path
[len
] == '\\') len
++;
432 nameW
.Buffer
= path
+ len
;
433 nameW
.Length
= lstrlenW(path
+ len
) * sizeof(WCHAR
);
434 attr
.RootDirectory
= dir
;
435 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
436 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
437 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
438 CloseHandle( handle
);
440 /* try uppercase name */
441 for (i
= len
; path
[i
]; i
++) if (path
[i
] >= 'a' && path
[i
] <= 'z') path
[i
] -= 'a' - 'A';
442 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
443 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
444 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
445 CloseHandle( handle
);
447 /* try with leading backslash */
449 nameW
.Length
+= sizeof(WCHAR
);
450 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
451 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
452 ok( status
== STATUS_INVALID_PARAMETER
||
453 status
== STATUS_OBJECT_NAME_INVALID
||
454 status
== STATUS_OBJECT_PATH_SYNTAX_BAD
,
455 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
456 if (!status
) CloseHandle( handle
);
458 /* try with empty name */
460 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
461 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
462 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
463 CloseHandle( handle
);
465 /* try open by file id */
467 while (!pNtQueryDirectoryFile( dir
, NULL
, NULL
, NULL
, &io
, data
, sizeof(data
),
468 FileIdBothDirectoryInformation
, TRUE
, NULL
, restart
))
470 FILE_ID_BOTH_DIRECTORY_INFORMATION
*info
= (FILE_ID_BOTH_DIRECTORY_INFORMATION
*)data
;
474 if (!info
->FileId
.QuadPart
) continue;
476 nameW
.Buffer
= (WCHAR
*)&info
->FileId
;
477 nameW
.Length
= sizeof(info
->FileId
);
478 info
->FileName
[info
->FileNameLength
/sizeof(WCHAR
)] = 0;
479 attr
.RootDirectory
= dir
;
480 /* We skip 'open' files by not specifying FILE_SHARE_WRITE */
481 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
483 FILE_OPEN_BY_FILE_ID
|
484 ((info
->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) ? FILE_DIRECTORY_FILE
: 0) );
485 ok( status
== STATUS_SUCCESS
|| status
== STATUS_ACCESS_DENIED
|| status
== STATUS_NOT_IMPLEMENTED
|| status
== STATUS_SHARING_VIOLATION
,
486 "open %s failed %x\n", wine_dbgstr_w(info
->FileName
), status
);
487 if (status
== STATUS_NOT_IMPLEMENTED
)
489 win_skip( "FILE_OPEN_BY_FILE_ID not supported\n" );
492 if (status
== STATUS_SHARING_VIOLATION
)
493 trace( "%s is currently open\n", wine_dbgstr_w(info
->FileName
) );
496 BYTE buf
[sizeof(FILE_ALL_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
)];
498 if (!pNtQueryInformationFile( handle
, &io
, buf
, sizeof(buf
), FileAllInformation
))
500 FILE_ALL_INFORMATION
*fai
= (FILE_ALL_INFORMATION
*)buf
;
502 /* check that it's the same file/directory */
504 /* don't check the size for directories */
505 if (!(info
->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
506 ok( info
->EndOfFile
.QuadPart
== fai
->StandardInformation
.EndOfFile
.QuadPart
,
507 "mismatched file size for %s\n", wine_dbgstr_w(info
->FileName
));
509 ok( info
->CreationTime
.QuadPart
== fai
->BasicInformation
.CreationTime
.QuadPart
,
510 "mismatched creation time for %s\n", wine_dbgstr_w(info
->FileName
));
512 CloseHandle( handle
);
514 /* try same thing from drive root */
515 attr
.RootDirectory
= root
;
516 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
517 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
518 FILE_OPEN_BY_FILE_ID
|
519 ((info
->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) ? FILE_DIRECTORY_FILE
: 0) );
520 ok( status
== STATUS_SUCCESS
|| status
== STATUS_NOT_IMPLEMENTED
,
521 "open %s failed %x\n", wine_dbgstr_w(info
->FileName
), status
);
522 if (!status
) CloseHandle( handle
);
529 GetTempPathW( MAX_PATH
, path
);
530 GetTempFileNameW( path
, fooW
, 0, tmpfile
);
531 pRtlDosPathNameToNtPathName_U( tmpfile
, &nameW
, NULL
, NULL
);
533 file
= CreateFileW( tmpfile
, FILE_WRITE_DATA
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
534 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError() );
535 numbytes
= 0xdeadbeef;
536 ret
= WriteFile( file
, testdata
, sizeof(testdata
) - 1, &numbytes
, NULL
);
537 ok( ret
, "WriteFile failed with error %u\n", GetLastError() );
538 ok( numbytes
== sizeof(testdata
) - 1, "failed to write all data\n" );
541 attr
.Length
= sizeof(attr
);
542 attr
.RootDirectory
= 0;
543 attr
.ObjectName
= &nameW
;
544 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
545 attr
.SecurityDescriptor
= NULL
;
546 attr
.SecurityQualityOfService
= NULL
;
547 status
= pNtOpenFile( &file
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
548 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
);
549 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
550 pRtlFreeUnicodeString( &nameW
);
552 numbytes
= 0xdeadbeef;
553 memset( data
, 0, sizeof(data
) );
554 ret
= ReadFile( file
, data
, sizeof(data
), &numbytes
, NULL
);
555 ok( ret
, "ReadFile failed with error %u\n", GetLastError() );
556 ok( numbytes
== sizeof(testdata
) - 1, "failed to read all data\n" );
557 ok( !memcmp( data
, testdata
, sizeof(testdata
) - 1 ), "testdata doesn't match\n" );
559 nameW
.Length
= sizeof(fooW
) - sizeof(WCHAR
);
561 attr
.RootDirectory
= file
;
562 attr
.ObjectName
= &nameW
;
563 status
= pNtOpenFile( &root
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
564 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
);
565 ok( status
== STATUS_OBJECT_PATH_NOT_FOUND
,
566 "expected STATUS_OBJECT_PATH_NOT_FOUND, got %08x\n", status
);
570 attr
.RootDirectory
= file
;
571 attr
.ObjectName
= &nameW
;
572 status
= pNtOpenFile( &root
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
573 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
);
574 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(tmpfile
), status
);
576 numbytes
= SetFilePointer( file
, 0, 0, FILE_CURRENT
);
577 ok( numbytes
== sizeof(testdata
) - 1, "SetFilePointer returned %u\n", numbytes
);
578 numbytes
= SetFilePointer( root
, 0, 0, FILE_CURRENT
);
579 ok( numbytes
== 0, "SetFilePointer returned %u\n", numbytes
);
581 numbytes
= 0xdeadbeef;
582 memset( data
, 0, sizeof(data
) );
583 ret
= ReadFile( root
, data
, sizeof(data
), &numbytes
, NULL
);
584 ok( ret
, "ReadFile failed with error %u\n", GetLastError() );
585 ok( numbytes
== sizeof(testdata
) - 1, "failed to read all data\n" );
586 ok( !memcmp( data
, testdata
, sizeof(testdata
) - 1 ), "testdata doesn't match\n" );
588 numbytes
= SetFilePointer( file
, 0, 0, FILE_CURRENT
);
589 ok( numbytes
== sizeof(testdata
) - 1, "SetFilePointer returned %u\n", numbytes
);
590 numbytes
= SetFilePointer( root
, 0, 0, FILE_CURRENT
);
591 ok( numbytes
== sizeof(testdata
) - 1, "SetFilePointer returned %u\n", numbytes
);
595 DeleteFileW( tmpfile
);
598 static void delete_file_test(void)
601 OBJECT_ATTRIBUTES attr
;
602 UNICODE_STRING nameW
;
603 WCHAR pathW
[MAX_PATH
];
604 WCHAR pathsubW
[MAX_PATH
];
605 static const WCHAR testdirW
[] = {'n','t','d','e','l','e','t','e','f','i','l','e',0};
606 static const WCHAR subdirW
[] = {'\\','s','u','b',0};
608 ret
= GetTempPathW(MAX_PATH
, pathW
);
611 ok(0, "couldn't get temp dir\n");
614 if (ret
+ sizeof(testdirW
)/sizeof(WCHAR
)-1 + sizeof(subdirW
)/sizeof(WCHAR
)-1 >= MAX_PATH
)
616 ok(0, "MAX_PATH exceeded in constructing paths\n");
620 lstrcatW(pathW
, testdirW
);
621 lstrcpyW(pathsubW
, pathW
);
622 lstrcatW(pathsubW
, subdirW
);
624 ret
= CreateDirectoryW(pathW
, NULL
);
625 ok(ret
== TRUE
, "couldn't create directory ntdeletefile\n");
626 if (!pRtlDosPathNameToNtPathName_U(pathW
, &nameW
, NULL
, NULL
))
628 ok(0,"RtlDosPathNametoNtPathName_U failed\n");
632 attr
.Length
= sizeof(attr
);
633 attr
.RootDirectory
= 0;
634 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
635 attr
.ObjectName
= &nameW
;
636 attr
.SecurityDescriptor
= NULL
;
637 attr
.SecurityQualityOfService
= NULL
;
639 /* test NtDeleteFile on an empty directory */
640 ret
= pNtDeleteFile(&attr
);
641 ok(ret
== STATUS_SUCCESS
, "NtDeleteFile should succeed in removing an empty directory\n");
642 ret
= RemoveDirectoryW(pathW
);
643 ok(ret
== FALSE
, "expected to fail removing directory, NtDeleteFile should have removed it\n");
645 /* test NtDeleteFile on a non-empty directory */
646 ret
= CreateDirectoryW(pathW
, NULL
);
647 ok(ret
== TRUE
, "couldn't create directory ntdeletefile ?!\n");
648 ret
= CreateDirectoryW(pathsubW
, NULL
);
649 ok(ret
== TRUE
, "couldn't create directory subdir\n");
650 ret
= pNtDeleteFile(&attr
);
651 ok(ret
== STATUS_SUCCESS
, "expected NtDeleteFile to ret STATUS_SUCCESS\n");
652 ret
= RemoveDirectoryW(pathsubW
);
653 ok(ret
== TRUE
, "expected to remove directory ntdeletefile\\sub\n");
654 ret
= RemoveDirectoryW(pathW
);
655 ok(ret
== TRUE
, "expected to remove directory ntdeletefile, NtDeleteFile failed.\n");
657 pRtlFreeUnicodeString( &nameW
);
660 static void read_file_test(void)
662 const char text
[] = "foobar";
663 HANDLE handle
, read
, write
;
665 IO_STATUS_BLOCK iosb
, iosb2
;
669 LARGE_INTEGER offset
;
670 HANDLE event
= CreateEventA( NULL
, TRUE
, FALSE
, NULL
);
675 if (!create_pipe( &read
, &write
, FILE_FLAG_OVERLAPPED
, 4096 )) return;
677 /* try read with no data */
678 U(iosb
).Status
= 0xdeadbabe;
679 iosb
.Information
= 0xdeadbeef;
680 ok( is_signaled( read
), "read handle is not signaled\n" );
681 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 1, NULL
, NULL
);
682 ok( status
== STATUS_PENDING
, "wrong status %x\n", status
);
683 ok( !is_signaled( read
), "read handle is signaled\n" );
684 ok( !is_signaled( event
), "event is signaled\n" );
685 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
686 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
687 ok( !apc_count
, "apc was called\n" );
688 ret
= WriteFile( write
, buffer
, 1, &written
, NULL
);
689 ok(ret
&& written
== 1, "WriteFile error %d\n", GetLastError());
690 /* iosb updated here by async i/o */
691 Sleep(1); /* FIXME: needed for wine to run the i/o apc */
692 ok( U(iosb
).Status
== 0, "wrong status %x\n", U(iosb
).Status
);
693 ok( iosb
.Information
== 1, "wrong info %lu\n", iosb
.Information
);
694 ok( !is_signaled( read
), "read handle is signaled\n" );
695 ok( is_signaled( event
), "event is not signaled\n" );
696 ok( !apc_count
, "apc was called\n" );
698 SleepEx( 1, FALSE
); /* non-alertable sleep */
699 ok( !apc_count
, "apc was called\n" );
700 SleepEx( 1, TRUE
); /* alertable sleep */
701 ok( apc_count
== 1, "apc not called\n" );
703 /* with no event, the pipe handle itself gets signaled */
705 U(iosb
).Status
= 0xdeadbabe;
706 iosb
.Information
= 0xdeadbeef;
707 ok( !is_signaled( read
), "read handle is not signaled\n" );
708 status
= pNtReadFile( read
, 0, apc
, &apc_count
, &iosb
, buffer
, 1, NULL
, NULL
);
709 ok( status
== STATUS_PENDING
, "wrong status %x\n", status
);
710 ok( !is_signaled( read
), "read handle is signaled\n" );
711 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
712 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
713 ok( !apc_count
, "apc was called\n" );
714 ret
= WriteFile( write
, buffer
, 1, &written
, NULL
);
715 ok(ret
&& written
== 1, "WriteFile error %d\n", GetLastError());
716 /* iosb updated here by async i/o */
717 Sleep(1); /* FIXME: needed for wine to run the i/o apc */
718 ok( U(iosb
).Status
== 0, "wrong status %x\n", U(iosb
).Status
);
719 ok( iosb
.Information
== 1, "wrong info %lu\n", iosb
.Information
);
720 ok( is_signaled( read
), "read handle is signaled\n" );
721 ok( !apc_count
, "apc was called\n" );
723 SleepEx( 1, FALSE
); /* non-alertable sleep */
724 ok( !apc_count
, "apc was called\n" );
725 SleepEx( 1, TRUE
); /* alertable sleep */
726 ok( apc_count
== 1, "apc not called\n" );
728 /* now read with data ready */
730 U(iosb
).Status
= 0xdeadbabe;
731 iosb
.Information
= 0xdeadbeef;
733 ret
= WriteFile( write
, buffer
, 1, &written
, NULL
);
734 ok(ret
&& written
== 1, "WriteFile error %d\n", GetLastError());
735 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 1, NULL
, NULL
);
736 ok( status
== STATUS_SUCCESS
, "wrong status %x\n", status
);
737 ok( U(iosb
).Status
== 0, "wrong status %x\n", U(iosb
).Status
);
738 ok( iosb
.Information
== 1, "wrong info %lu\n", iosb
.Information
);
739 ok( is_signaled( event
), "event is not signaled\n" );
740 ok( !apc_count
, "apc was called\n" );
741 SleepEx( 1, FALSE
); /* non-alertable sleep */
742 ok( !apc_count
, "apc was called\n" );
743 SleepEx( 1, TRUE
); /* alertable sleep */
744 ok( apc_count
== 1, "apc not called\n" );
746 /* try read with no data */
748 U(iosb
).Status
= 0xdeadbabe;
749 iosb
.Information
= 0xdeadbeef;
750 ok( is_signaled( event
), "event is not signaled\n" ); /* check that read resets the event */
751 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, NULL
, NULL
);
752 ok( status
== STATUS_PENDING
, "wrong status %x\n", status
);
753 ok( !is_signaled( event
), "event is signaled\n" );
754 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
755 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
756 ok( !apc_count
, "apc was called\n" );
757 ret
= WriteFile( write
, buffer
, 1, &written
, NULL
);
758 ok(ret
&& written
== 1, "WriteFile error %d\n", GetLastError());
759 /* partial read is good enough */
760 Sleep(1); /* FIXME: needed for wine to run the i/o apc */
761 ok( is_signaled( event
), "event is signaled\n" );
762 ok( U(iosb
).Status
== 0, "wrong status %x\n", U(iosb
).Status
);
763 ok( iosb
.Information
== 1, "wrong info %lu\n", iosb
.Information
);
764 ok( !apc_count
, "apc was called\n" );
765 SleepEx( 1, TRUE
); /* alertable sleep */
766 ok( apc_count
== 1, "apc was not called\n" );
768 /* read from disconnected pipe */
770 U(iosb
).Status
= 0xdeadbabe;
771 iosb
.Information
= 0xdeadbeef;
772 CloseHandle( write
);
773 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 1, NULL
, NULL
);
774 ok( status
== STATUS_PIPE_BROKEN
, "wrong status %x\n", status
);
775 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
776 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
777 ok( !is_signaled( event
), "event is signaled\n" );
778 ok( !apc_count
, "apc was called\n" );
779 SleepEx( 1, TRUE
); /* alertable sleep */
780 ok( !apc_count
, "apc was called\n" );
783 /* read from closed handle */
785 U(iosb
).Status
= 0xdeadbabe;
786 iosb
.Information
= 0xdeadbeef;
788 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 1, NULL
, NULL
);
789 ok( status
== STATUS_INVALID_HANDLE
, "wrong status %x\n", status
);
790 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
791 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
792 ok( is_signaled( event
), "event is signaled\n" ); /* not reset on invalid handle */
793 ok( !apc_count
, "apc was called\n" );
794 SleepEx( 1, TRUE
); /* alertable sleep */
795 ok( !apc_count
, "apc was called\n" );
797 /* disconnect while async read is in progress */
798 if (!create_pipe( &read
, &write
, FILE_FLAG_OVERLAPPED
, 4096 )) return;
800 U(iosb
).Status
= 0xdeadbabe;
801 iosb
.Information
= 0xdeadbeef;
802 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, NULL
, NULL
);
803 ok( status
== STATUS_PENDING
, "wrong status %x\n", status
);
804 ok( !is_signaled( event
), "event is signaled\n" );
805 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
806 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
807 ok( !apc_count
, "apc was called\n" );
808 CloseHandle( write
);
809 Sleep(1); /* FIXME: needed for wine to run the i/o apc */
810 ok( U(iosb
).Status
== STATUS_PIPE_BROKEN
, "wrong status %x\n", U(iosb
).Status
);
811 ok( iosb
.Information
== 0, "wrong info %lu\n", iosb
.Information
);
812 ok( is_signaled( event
), "event is signaled\n" );
813 ok( !apc_count
, "apc was called\n" );
814 SleepEx( 1, TRUE
); /* alertable sleep */
815 ok( apc_count
== 1, "apc was not called\n" );
818 if (!create_pipe( &read
, &write
, FILE_FLAG_OVERLAPPED
, 4096 )) return;
819 ret
= DuplicateHandle(GetCurrentProcess(), read
, GetCurrentProcess(), &handle
, 0, TRUE
, DUPLICATE_SAME_ACCESS
);
820 ok(ret
, "Failed to duplicate handle: %d\n", GetLastError());
823 U(iosb
).Status
= 0xdeadbabe;
824 iosb
.Information
= 0xdeadbeef;
825 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, NULL
, NULL
);
826 ok( status
== STATUS_PENDING
, "wrong status %x\n", status
);
827 ok( !is_signaled( event
), "event is signaled\n" );
828 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
829 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
830 ok( !apc_count
, "apc was called\n" );
831 /* Cancel by other handle */
832 status
= pNtCancelIoFile( read
, &iosb2
);
833 ok(status
== STATUS_SUCCESS
, "failed to cancel by different handle: %x\n", status
);
834 Sleep(1); /* FIXME: needed for wine to run the i/o apc */
835 ok( U(iosb
).Status
== STATUS_CANCELLED
, "wrong status %x\n", U(iosb
).Status
);
836 ok( iosb
.Information
== 0, "wrong info %lu\n", iosb
.Information
);
837 ok( is_signaled( event
), "event is signaled\n" );
838 ok( !apc_count
, "apc was called\n" );
839 SleepEx( 1, TRUE
); /* alertable sleep */
840 ok( apc_count
== 1, "apc was not called\n" );
843 U(iosb
).Status
= 0xdeadbabe;
844 iosb
.Information
= 0xdeadbeef;
845 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, NULL
, NULL
);
846 ok( status
== STATUS_PENDING
, "wrong status %x\n", status
);
847 ok( !is_signaled( event
), "event is signaled\n" );
848 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
849 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
850 ok( !apc_count
, "apc was called\n" );
851 /* Close queued handle */
853 SleepEx( 1, TRUE
); /* alertable sleep */
854 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
855 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
856 status
= pNtCancelIoFile( read
, &iosb2
);
857 ok(status
== STATUS_INVALID_HANDLE
, "cancelled by closed handle?\n");
858 status
= pNtCancelIoFile( handle
, &iosb2
);
859 ok(status
== STATUS_SUCCESS
, "failed to cancel: %x\n", status
);
860 Sleep(1); /* FIXME: needed for wine to run the i/o apc */
861 ok( U(iosb
).Status
== STATUS_CANCELLED
, "wrong status %x\n", U(iosb
).Status
);
862 ok( iosb
.Information
== 0, "wrong info %lu\n", iosb
.Information
);
863 ok( is_signaled( event
), "event is signaled\n" );
864 ok( !apc_count
, "apc was called\n" );
865 SleepEx( 1, TRUE
); /* alertable sleep */
866 ok( apc_count
== 1, "apc was not called\n" );
867 CloseHandle( handle
);
868 CloseHandle( write
);
870 if (pNtCancelIoFileEx
)
872 /* Basic Cancel Ex */
873 if (!create_pipe( &read
, &write
, FILE_FLAG_OVERLAPPED
, 4096 )) return;
876 U(iosb
).Status
= 0xdeadbabe;
877 iosb
.Information
= 0xdeadbeef;
878 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, NULL
, NULL
);
879 ok( status
== STATUS_PENDING
, "wrong status %x\n", status
);
880 ok( !is_signaled( event
), "event is signaled\n" );
881 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
882 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
883 ok( !apc_count
, "apc was called\n" );
884 status
= pNtCancelIoFileEx( read
, &iosb
, &iosb2
);
885 ok(status
== STATUS_SUCCESS
, "Failed to cancel I/O\n");
886 Sleep(1); /* FIXME: needed for wine to run the i/o apc */
887 ok( U(iosb
).Status
== STATUS_CANCELLED
, "wrong status %x\n", U(iosb
).Status
);
888 ok( iosb
.Information
== 0, "wrong info %lu\n", iosb
.Information
);
889 ok( is_signaled( event
), "event is signaled\n" );
890 ok( !apc_count
, "apc was called\n" );
891 SleepEx( 1, TRUE
); /* alertable sleep */
892 ok( apc_count
== 1, "apc was not called\n" );
896 U(iosb
).Status
= 0xdeadbabe;
897 iosb
.Information
= 0xdeadbeef;
898 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, NULL
, NULL
);
899 ok( status
== STATUS_PENDING
, "wrong status %x\n", status
);
900 ok( !is_signaled( event
), "event is signaled\n" );
901 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
902 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
903 ok( !apc_count
, "apc was called\n" );
904 status
= pNtReadFile( read
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, NULL
, NULL
);
905 ok( status
== STATUS_PENDING
, "wrong status %x\n", status
);
906 ok( !is_signaled( event
), "event is signaled\n" );
907 ok( U(iosb
).Status
== 0xdeadbabe, "wrong status %x\n", U(iosb
).Status
);
908 ok( iosb
.Information
== 0xdeadbeef, "wrong info %lu\n", iosb
.Information
);
909 ok( !apc_count
, "apc was called\n" );
910 status
= pNtCancelIoFileEx( read
, &iosb
, &iosb2
);
911 ok(status
== STATUS_SUCCESS
, "Failed to cancel I/O\n");
912 Sleep(1); /* FIXME: needed for wine to run the i/o apc */
913 ok( U(iosb
).Status
== STATUS_CANCELLED
, "wrong status %x\n", U(iosb
).Status
);
914 ok( iosb
.Information
== 0, "wrong info %lu\n", iosb
.Information
);
915 ok( is_signaled( event
), "event is signaled\n" );
916 ok( !apc_count
, "apc was called\n" );
917 SleepEx( 1, TRUE
); /* alertable sleep */
918 ok( apc_count
== 2, "apc was not called\n" );
921 CloseHandle( write
);
924 /* now try a real file */
925 if (!(handle
= create_temp_file( FILE_FLAG_OVERLAPPED
))) return;
927 U(iosb
).Status
= 0xdeadbabe;
928 iosb
.Information
= 0xdeadbeef;
931 status
= pNtWriteFile( handle
, event
, apc
, &apc_count
, &iosb
, text
, strlen(text
), &offset
, NULL
);
932 ok( status
== STATUS_SUCCESS
|| status
== STATUS_PENDING
, "wrong status %x\n", status
);
933 if (status
== STATUS_PENDING
) WaitForSingleObject( event
, 1000 );
934 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
935 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
936 ok( is_signaled( event
), "event is signaled\n" );
937 ok( !apc_count
, "apc was called\n" );
938 SleepEx( 1, TRUE
); /* alertable sleep */
939 ok( apc_count
== 1, "apc was not called\n" );
942 U(iosb
).Status
= 0xdeadbabe;
943 iosb
.Information
= 0xdeadbeef;
946 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, strlen(text
) + 10, &offset
, NULL
);
947 ok( status
== STATUS_SUCCESS
||
948 status
== STATUS_PENDING
, /* vista */
949 "wrong status %x\n", status
);
950 if (status
== STATUS_PENDING
) WaitForSingleObject( event
, 1000 );
951 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
952 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
953 ok( is_signaled( event
), "event is signaled\n" );
954 ok( !apc_count
, "apc was called\n" );
955 SleepEx( 1, TRUE
); /* alertable sleep */
956 ok( apc_count
== 1, "apc was not called\n" );
958 /* read beyond eof */
960 U(iosb
).Status
= 0xdeadbabe;
961 iosb
.Information
= 0xdeadbeef;
962 offset
.QuadPart
= strlen(text
) + 2;
963 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, &offset
, NULL
);
964 ok(status
== STATUS_PENDING
|| status
== STATUS_END_OF_FILE
/* before Vista */, "expected STATUS_PENDING or STATUS_END_OF_FILE, got %#x\n", status
);
965 if (status
== STATUS_PENDING
) /* vista */
967 WaitForSingleObject( event
, 1000 );
968 ok( U(iosb
).Status
== STATUS_END_OF_FILE
, "wrong status %x\n", U(iosb
).Status
);
969 ok( iosb
.Information
== 0, "wrong info %lu\n", iosb
.Information
);
970 ok( is_signaled( event
), "event is signaled\n" );
971 ok( !apc_count
, "apc was called\n" );
972 SleepEx( 1, TRUE
); /* alertable sleep */
973 ok( apc_count
== 1, "apc was not called\n" );
975 CloseHandle( handle
);
977 /* now a non-overlapped file */
978 if (!(handle
= create_temp_file(0))) return;
980 U(iosb
).Status
= 0xdeadbabe;
981 iosb
.Information
= 0xdeadbeef;
983 status
= pNtWriteFile( handle
, event
, apc
, &apc_count
, &iosb
, text
, strlen(text
), &offset
, NULL
);
984 ok( status
== STATUS_END_OF_FILE
||
985 status
== STATUS_SUCCESS
||
986 status
== STATUS_PENDING
, /* vista */
987 "wrong status %x\n", status
);
988 if (status
== STATUS_PENDING
) WaitForSingleObject( event
, 1000 );
989 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
990 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
991 ok( is_signaled( event
), "event is signaled\n" );
992 ok( !apc_count
, "apc was called\n" );
993 SleepEx( 1, TRUE
); /* alertable sleep */
994 ok( apc_count
== 1, "apc was not called\n" );
997 U(iosb
).Status
= 0xdeadbabe;
998 iosb
.Information
= 0xdeadbeef;
1000 ResetEvent( event
);
1001 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, strlen(text
) + 10, &offset
, NULL
);
1002 ok( status
== STATUS_SUCCESS
, "wrong status %x\n", status
);
1003 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
1004 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
1005 ok( is_signaled( event
), "event is signaled\n" );
1006 ok( !apc_count
, "apc was called\n" );
1007 SleepEx( 1, TRUE
); /* alertable sleep */
1008 todo_wine
ok( !apc_count
, "apc was called\n" );
1010 /* read beyond eof */
1012 U(iosb
).Status
= 0xdeadbabe;
1013 iosb
.Information
= 0xdeadbeef;
1014 offset
.QuadPart
= strlen(text
) + 2;
1015 ResetEvent( event
);
1016 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, &offset
, NULL
);
1017 ok( status
== STATUS_END_OF_FILE
, "wrong status %x\n", status
);
1018 ok( U(iosb
).Status
== STATUS_END_OF_FILE
, "wrong status %x\n", U(iosb
).Status
);
1019 ok( iosb
.Information
== 0, "wrong info %lu\n", iosb
.Information
);
1020 ok( is_signaled( event
), "event is not signaled\n" );
1021 ok( !apc_count
, "apc was called\n" );
1022 SleepEx( 1, TRUE
); /* alertable sleep */
1023 ok( !apc_count
, "apc was called\n" );
1025 CloseHandle( handle
);
1027 CloseHandle( event
);
1030 static void append_file_test(void)
1032 static const char text
[6] = "foobar";
1035 IO_STATUS_BLOCK iosb
;
1036 LARGE_INTEGER offset
;
1037 char path
[MAX_PATH
], buffer
[MAX_PATH
], buf
[16];
1040 GetTempPathA( MAX_PATH
, path
);
1041 GetTempFileNameA( path
, "foo", 0, buffer
);
1043 handle
= CreateFileA(buffer
, FILE_WRITE_DATA
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
1044 ok(handle
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError());
1046 U(iosb
).Status
= -1;
1047 iosb
.Information
= -1;
1048 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
, 2, NULL
, NULL
);
1049 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
1050 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
1051 ok(iosb
.Information
== 2, "expected 2, got %lu\n", iosb
.Information
);
1053 CloseHandle(handle
);
1055 /* It is possible to open a file with only FILE_APPEND_DATA access flags.
1056 It matches the O_WRONLY|O_APPEND open() posix behavior */
1057 handle
= CreateFileA(buffer
, FILE_APPEND_DATA
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1058 ok(handle
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError());
1060 U(iosb
).Status
= -1;
1061 iosb
.Information
= -1;
1062 offset
.QuadPart
= 1;
1063 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
+ 2, 2, &offset
, NULL
);
1064 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
1065 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
1066 ok(iosb
.Information
== 2, "expected 2, got %lu\n", iosb
.Information
);
1068 ret
= SetFilePointer(handle
, 0, NULL
, FILE_CURRENT
);
1069 ok(ret
== 4, "expected 4, got %u\n", ret
);
1071 U(iosb
).Status
= -1;
1072 iosb
.Information
= -1;
1073 offset
.QuadPart
= 3;
1074 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
+ 4, 2, &offset
, NULL
);
1075 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
1076 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
1077 ok(iosb
.Information
== 2, "expected 2, got %lu\n", iosb
.Information
);
1079 ret
= SetFilePointer(handle
, 0, NULL
, FILE_CURRENT
);
1080 ok(ret
== 6, "expected 6, got %u\n", ret
);
1082 CloseHandle(handle
);
1084 handle
= CreateFileA(buffer
, FILE_READ_DATA
| FILE_WRITE_DATA
| FILE_APPEND_DATA
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1085 ok(handle
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError());
1087 memset(buf
, 0, sizeof(buf
));
1088 U(iosb
).Status
= -1;
1089 iosb
.Information
= -1;
1090 offset
.QuadPart
= 0;
1091 status
= pNtReadFile(handle
, 0, NULL
, NULL
, &iosb
, buf
, sizeof(buf
), &offset
, NULL
);
1092 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
1093 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
1094 ok(iosb
.Information
== 6, "expected 6, got %lu\n", iosb
.Information
);
1096 ok(memcmp(buf
, text
, 6) == 0, "wrong file contents: %s\n", buf
);
1098 U(iosb
).Status
= -1;
1099 iosb
.Information
= -1;
1100 offset
.QuadPart
= 0;
1101 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
+ 3, 3, &offset
, NULL
);
1102 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
1103 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
1104 ok(iosb
.Information
== 3, "expected 3, got %lu\n", iosb
.Information
);
1106 memset(buf
, 0, sizeof(buf
));
1107 U(iosb
).Status
= -1;
1108 iosb
.Information
= -1;
1109 offset
.QuadPart
= 0;
1110 status
= pNtReadFile(handle
, 0, NULL
, NULL
, &iosb
, buf
, sizeof(buf
), &offset
, NULL
);
1111 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
1112 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
1113 ok(iosb
.Information
== 6, "expected 6, got %lu\n", iosb
.Information
);
1115 ok(memcmp(buf
, "barbar", 6) == 0, "wrong file contents: %s\n", buf
);
1117 CloseHandle(handle
);
1118 DeleteFileA(buffer
);
1121 static void nt_mailslot_test(void)
1124 ACCESS_MASK DesiredAccess
;
1125 OBJECT_ATTRIBUTES attr
;
1127 ULONG CreateOptions
;
1128 ULONG MailslotQuota
;
1129 ULONG MaxMessageSize
;
1130 LARGE_INTEGER TimeOut
;
1131 IO_STATUS_BLOCK IoStatusBlock
;
1134 WCHAR buffer1
[] = { '\\','?','?','\\','M','A','I','L','S','L','O','T','\\',
1135 'R',':','\\','F','R','E','D','\0' };
1137 TimeOut
.QuadPart
= -1;
1139 pRtlInitUnicodeString(&str
, buffer1
);
1140 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
1141 CreateOptions
= MailslotQuota
= MaxMessageSize
= 0;
1142 DesiredAccess
= GENERIC_READ
;
1145 * Check for NULL pointer handling
1147 rc
= pNtCreateMailslotFile(NULL
, DesiredAccess
,
1148 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
1150 ok( rc
== STATUS_ACCESS_VIOLATION
||
1151 rc
== STATUS_INVALID_PARAMETER
, /* win2k3 */
1152 "rc = %x not STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER\n", rc
);
1155 * Test to see if the Timeout can be NULL
1157 hslot
= (HANDLE
)0xdeadbeef;
1158 rc
= pNtCreateMailslotFile(&hslot
, DesiredAccess
,
1159 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
1161 ok( rc
== STATUS_SUCCESS
||
1162 rc
== STATUS_INVALID_PARAMETER
, /* win2k3 */
1163 "rc = %x not STATUS_SUCCESS or STATUS_INVALID_PARAMETER\n", rc
);
1164 ok( hslot
!= 0, "Handle is invalid\n");
1166 if ( rc
== STATUS_SUCCESS
) pNtClose(hslot
);
1169 * Test that the length field is checked properly
1172 rc
= pNtCreateMailslotFile(&hslot
, DesiredAccess
,
1173 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
1175 todo_wine
ok( rc
== STATUS_INVALID_PARAMETER
, "rc = %x not c000000d STATUS_INVALID_PARAMETER\n", rc
);
1177 if (rc
== STATUS_SUCCESS
) pNtClose(hslot
);
1179 attr
.Length
= sizeof(OBJECT_ATTRIBUTES
)+1;
1180 rc
= pNtCreateMailslotFile(&hslot
, DesiredAccess
,
1181 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
1183 todo_wine
ok( rc
== STATUS_INVALID_PARAMETER
, "rc = %x not c000000d STATUS_INVALID_PARAMETER\n", rc
);
1185 if (rc
== STATUS_SUCCESS
) pNtClose(hslot
);
1188 * Test handling of a NULL unicode string in ObjectName
1190 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
1191 attr
.ObjectName
= NULL
;
1192 rc
= pNtCreateMailslotFile(&hslot
, DesiredAccess
,
1193 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
1195 ok( rc
== STATUS_OBJECT_PATH_SYNTAX_BAD
||
1196 rc
== STATUS_INVALID_PARAMETER
,
1197 "rc = %x not STATUS_OBJECT_PATH_SYNTAX_BAD or STATUS_INVALID_PARAMETER\n", rc
);
1199 if (rc
== STATUS_SUCCESS
) pNtClose(hslot
);
1204 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
1205 rc
= pNtCreateMailslotFile(&hslot
, DesiredAccess
,
1206 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
1208 ok( rc
== STATUS_SUCCESS
, "Create MailslotFile failed rc = %x\n", rc
);
1209 ok( hslot
!= 0, "Handle is invalid\n");
1211 rc
= pNtClose(hslot
);
1212 ok( rc
== STATUS_SUCCESS
, "NtClose failed\n");
1215 static void test_iocp_setcompletion(HANDLE h
)
1221 if (sizeof(size
) > 4) size
|= (ULONGLONG
)0x12345678 << 32;
1223 res
= pNtSetIoCompletion( h
, CKEY_FIRST
, CVALUE_FIRST
, STATUS_INVALID_DEVICE_REQUEST
, size
);
1224 ok( res
== STATUS_SUCCESS
, "NtSetIoCompletion failed: %x\n", res
);
1226 count
= get_pending_msgs(h
);
1227 ok( count
== 1, "Unexpected msg count: %d\n", count
);
1231 ok( completionKey
== CKEY_FIRST
, "Invalid completion key: %lx\n", completionKey
);
1232 ok( ioSb
.Information
== size
, "Invalid ioSb.Information: %lu\n", ioSb
.Information
);
1233 ok( U(ioSb
).Status
== STATUS_INVALID_DEVICE_REQUEST
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
1234 ok( completionValue
== CVALUE_FIRST
, "Invalid completion value: %lx\n", completionValue
);
1237 count
= get_pending_msgs(h
);
1238 ok( !count
, "Unexpected msg count: %d\n", count
);
1241 static void test_iocp_fileio(HANDLE h
)
1243 static const char pipe_name
[] = "\\\\.\\pipe\\iocompletiontestnamedpipe";
1245 IO_STATUS_BLOCK iosb
;
1246 FILE_COMPLETION_INFORMATION fci
= {h
, CKEY_SECOND
};
1247 HANDLE hPipeSrv
, hPipeClt
;
1250 hPipeSrv
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
, PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
, 4, 1024, 1024, 1000, NULL
);
1251 ok( hPipeSrv
!= INVALID_HANDLE_VALUE
, "Cannot create named pipe\n" );
1252 if (hPipeSrv
!= INVALID_HANDLE_VALUE
)
1254 hPipeClt
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
1255 ok( hPipeClt
!= INVALID_HANDLE_VALUE
, "Cannot connect to pipe\n" );
1256 if (hPipeClt
!= INVALID_HANDLE_VALUE
)
1258 U(iosb
).Status
= 0xdeadbeef;
1259 res
= pNtSetInformationFile( hPipeSrv
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
1260 ok( res
== STATUS_INVALID_PARAMETER
, "Unexpected NtSetInformationFile on non-overlapped handle: %x\n", res
);
1261 ok( U(iosb
).Status
== STATUS_INVALID_PARAMETER
/* 98 */ || U(iosb
).Status
== 0xdeadbeef /* NT4+ */,
1262 "Unexpected iosb.Status on non-overlapped handle: %x\n", U(iosb
).Status
);
1263 CloseHandle(hPipeClt
);
1265 CloseHandle( hPipeSrv
);
1268 hPipeSrv
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
| FILE_FLAG_OVERLAPPED
, PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
, 4, 1024, 1024, 1000, NULL
);
1269 ok( hPipeSrv
!= INVALID_HANDLE_VALUE
, "Cannot create named pipe\n" );
1270 if (hPipeSrv
== INVALID_HANDLE_VALUE
)
1273 hPipeClt
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
1274 ok( hPipeClt
!= INVALID_HANDLE_VALUE
, "Cannot connect to pipe\n" );
1275 if (hPipeClt
!= INVALID_HANDLE_VALUE
)
1277 OVERLAPPED o
= {0,};
1278 BYTE send_buf
[TEST_BUF_LEN
], recv_buf
[TEST_BUF_LEN
];
1282 U(iosb
).Status
= 0xdeadbeef;
1283 res
= pNtSetInformationFile( hPipeSrv
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
1284 ok( res
== STATUS_SUCCESS
, "NtSetInformationFile failed: %x\n", res
);
1285 ok( U(iosb
).Status
== STATUS_SUCCESS
, "iosb.Status invalid: %x\n", U(iosb
).Status
);
1287 memset( send_buf
, 0, TEST_BUF_LEN
);
1288 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1289 count
= get_pending_msgs(h
);
1290 ok( !count
, "Unexpected msg count: %ld\n", count
);
1291 ReadFile( hPipeSrv
, recv_buf
, TEST_BUF_LEN
, &read
, &o
);
1292 count
= get_pending_msgs(h
);
1293 ok( !count
, "Unexpected msg count: %ld\n", count
);
1294 WriteFile( hPipeClt
, send_buf
, TEST_BUF_LEN
, &read
, NULL
);
1298 ok( completionKey
== CKEY_SECOND
, "Invalid completion key: %lx\n", completionKey
);
1299 ok( ioSb
.Information
== 3, "Invalid ioSb.Information: %ld\n", ioSb
.Information
);
1300 ok( U(ioSb
).Status
== STATUS_SUCCESS
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
1301 ok( completionValue
== (ULONG_PTR
)&o
, "Invalid completion value: %lx\n", completionValue
);
1302 ok( !memcmp( send_buf
, recv_buf
, TEST_BUF_LEN
), "Receive buffer (%x %x %x) did not match send buffer (%x %x %x)\n", recv_buf
[0], recv_buf
[1], recv_buf
[2], send_buf
[0], send_buf
[1], send_buf
[2] );
1304 count
= get_pending_msgs(h
);
1305 ok( !count
, "Unexpected msg count: %ld\n", count
);
1307 memset( send_buf
, 0, TEST_BUF_LEN
);
1308 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1309 WriteFile( hPipeClt
, send_buf
, 2, &read
, NULL
);
1310 count
= get_pending_msgs(h
);
1311 ok( !count
, "Unexpected msg count: %ld\n", count
);
1312 ReadFile( hPipeSrv
, recv_buf
, 2, &read
, &o
);
1313 count
= get_pending_msgs(h
);
1314 ok( count
== 1, "Unexpected msg count: %ld\n", count
);
1317 ok( completionKey
== CKEY_SECOND
, "Invalid completion key: %lx\n", completionKey
);
1318 ok( ioSb
.Information
== 2, "Invalid ioSb.Information: %ld\n", ioSb
.Information
);
1319 ok( U(ioSb
).Status
== STATUS_SUCCESS
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
1320 ok( completionValue
== (ULONG_PTR
)&o
, "Invalid completion value: %lx\n", completionValue
);
1321 ok( !memcmp( send_buf
, recv_buf
, 2 ), "Receive buffer (%x %x) did not match send buffer (%x %x)\n", recv_buf
[0], recv_buf
[1], send_buf
[0], send_buf
[1] );
1324 ReadFile( hPipeSrv
, recv_buf
, TEST_BUF_LEN
, &read
, &o
);
1325 CloseHandle( hPipeSrv
);
1326 count
= get_pending_msgs(h
);
1327 ok( count
== 1, "Unexpected msg count: %ld\n", count
);
1330 ok( completionKey
== CKEY_SECOND
, "Invalid completion key: %lx\n", completionKey
);
1331 ok( ioSb
.Information
== 0, "Invalid ioSb.Information: %ld\n", ioSb
.Information
);
1332 /* wine sends wrong status here */
1333 todo_wine
ok( U(ioSb
).Status
== STATUS_PIPE_BROKEN
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
1334 ok( completionValue
== (ULONG_PTR
)&o
, "Invalid completion value: %lx\n", completionValue
);
1338 CloseHandle( hPipeClt
);
1340 /* test associating a completion port with a handle after an async is queued */
1341 hPipeSrv
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
| FILE_FLAG_OVERLAPPED
, PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
, 4, 1024, 1024, 1000, NULL
);
1342 ok( hPipeSrv
!= INVALID_HANDLE_VALUE
, "Cannot create named pipe\n" );
1343 if (hPipeSrv
== INVALID_HANDLE_VALUE
)
1345 hPipeClt
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
1346 ok( hPipeClt
!= INVALID_HANDLE_VALUE
, "Cannot connect to pipe\n" );
1347 if (hPipeClt
!= INVALID_HANDLE_VALUE
)
1349 OVERLAPPED o
= {0,};
1350 BYTE send_buf
[TEST_BUF_LEN
], recv_buf
[TEST_BUF_LEN
];
1354 memset( send_buf
, 0, TEST_BUF_LEN
);
1355 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1356 count
= get_pending_msgs(h
);
1357 ok( !count
, "Unexpected msg count: %ld\n", count
);
1358 ReadFile( hPipeSrv
, recv_buf
, TEST_BUF_LEN
, &read
, &o
);
1360 U(iosb
).Status
= 0xdeadbeef;
1361 res
= pNtSetInformationFile( hPipeSrv
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
1362 ok( res
== STATUS_SUCCESS
, "NtSetInformationFile failed: %x\n", res
);
1363 ok( U(iosb
).Status
== STATUS_SUCCESS
, "iosb.Status invalid: %x\n", U(iosb
).Status
);
1364 count
= get_pending_msgs(h
);
1365 ok( !count
, "Unexpected msg count: %ld\n", count
);
1367 WriteFile( hPipeClt
, send_buf
, TEST_BUF_LEN
, &read
, NULL
);
1371 ok( completionKey
== CKEY_SECOND
, "Invalid completion key: %lx\n", completionKey
);
1372 ok( ioSb
.Information
== 3, "Invalid ioSb.Information: %ld\n", ioSb
.Information
);
1373 ok( U(ioSb
).Status
== STATUS_SUCCESS
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
1374 ok( completionValue
== (ULONG_PTR
)&o
, "Invalid completion value: %lx\n", completionValue
);
1375 ok( !memcmp( send_buf
, recv_buf
, TEST_BUF_LEN
), "Receive buffer (%x %x %x) did not match send buffer (%x %x %x)\n", recv_buf
[0], recv_buf
[1], recv_buf
[2], send_buf
[0], send_buf
[1], send_buf
[2] );
1377 count
= get_pending_msgs(h
);
1378 ok( !count
, "Unexpected msg count: %ld\n", count
);
1381 CloseHandle( hPipeSrv
);
1382 CloseHandle( hPipeClt
);
1385 static void test_file_full_size_information(void)
1388 FILE_FS_FULL_SIZE_INFORMATION ffsi
;
1389 FILE_FS_SIZE_INFORMATION fsi
;
1393 if(!(h
= create_temp_file(0))) return ;
1395 memset(&ffsi
,0,sizeof(ffsi
));
1396 memset(&fsi
,0,sizeof(fsi
));
1398 /* Assume No Quota Settings configured on Wine Testbot */
1399 res
= pNtQueryVolumeInformationFile(h
, &io
, &ffsi
, sizeof ffsi
, FileFsFullSizeInformation
);
1400 ok(res
== STATUS_SUCCESS
, "cannot get attributes, res %x\n", res
);
1401 res
= pNtQueryVolumeInformationFile(h
, &io
, &fsi
, sizeof fsi
, FileFsSizeInformation
);
1402 ok(res
== STATUS_SUCCESS
, "cannot get attributes, res %x\n", res
);
1404 /* Test for FileFsSizeInformation */
1405 ok(fsi
.TotalAllocationUnits
.QuadPart
> 0,
1406 "[fsi] TotalAllocationUnits expected positive, got 0x%s\n",
1407 debugstr_longlong(fsi
.TotalAllocationUnits
.QuadPart
));
1408 ok(fsi
.AvailableAllocationUnits
.QuadPart
> 0,
1409 "[fsi] AvailableAllocationUnits expected positive, got 0x%s\n",
1410 debugstr_longlong(fsi
.AvailableAllocationUnits
.QuadPart
));
1412 /* Assume file system is NTFS */
1413 ok(fsi
.BytesPerSector
== 512, "[fsi] BytesPerSector expected 512, got %d\n",fsi
.BytesPerSector
);
1414 ok(fsi
.SectorsPerAllocationUnit
== 8, "[fsi] SectorsPerAllocationUnit expected 8, got %d\n",fsi
.SectorsPerAllocationUnit
);
1416 ok(ffsi
.TotalAllocationUnits
.QuadPart
> 0,
1417 "[ffsi] TotalAllocationUnits expected positive, got negative value 0x%s\n",
1418 debugstr_longlong(ffsi
.TotalAllocationUnits
.QuadPart
));
1419 ok(ffsi
.CallerAvailableAllocationUnits
.QuadPart
> 0,
1420 "[ffsi] CallerAvailableAllocationUnits expected positive, got negative value 0x%s\n",
1421 debugstr_longlong(ffsi
.CallerAvailableAllocationUnits
.QuadPart
));
1422 ok(ffsi
.ActualAvailableAllocationUnits
.QuadPart
> 0,
1423 "[ffsi] ActualAvailableAllocationUnits expected positive, got negative value 0x%s\n",
1424 debugstr_longlong(ffsi
.ActualAvailableAllocationUnits
.QuadPart
));
1425 ok(ffsi
.TotalAllocationUnits
.QuadPart
== fsi
.TotalAllocationUnits
.QuadPart
,
1426 "[ffsi] TotalAllocationUnits error fsi:0x%s, ffsi:0x%s\n",
1427 debugstr_longlong(fsi
.TotalAllocationUnits
.QuadPart
),
1428 debugstr_longlong(ffsi
.TotalAllocationUnits
.QuadPart
));
1429 ok(ffsi
.CallerAvailableAllocationUnits
.QuadPart
== fsi
.AvailableAllocationUnits
.QuadPart
,
1430 "[ffsi] CallerAvailableAllocationUnits error fsi:0x%s, ffsi: 0x%s\n",
1431 debugstr_longlong(fsi
.AvailableAllocationUnits
.QuadPart
),
1432 debugstr_longlong(ffsi
.CallerAvailableAllocationUnits
.QuadPart
));
1434 /* Assume file system is NTFS */
1435 ok(ffsi
.BytesPerSector
== 512, "[ffsi] BytesPerSector expected 512, got %d\n",ffsi
.BytesPerSector
);
1436 ok(ffsi
.SectorsPerAllocationUnit
== 8, "[ffsi] SectorsPerAllocationUnit expected 8, got %d\n",ffsi
.SectorsPerAllocationUnit
);
1441 static void test_file_basic_information(void)
1444 FILE_BASIC_INFORMATION fbi
;
1447 int attrib_mask
= FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_NORMAL
;
1449 if (!(h
= create_temp_file(0))) return;
1451 /* Check default first */
1452 memset(&fbi
, 0, sizeof(fbi
));
1453 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1454 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1455 ok ( (fbi
.FileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) == FILE_ATTRIBUTE_ARCHIVE
,
1456 "attribute %x not expected\n", fbi
.FileAttributes
);
1459 /* Clear fbi to avoid setting times */
1460 memset(&fbi
, 0, sizeof(fbi
));
1461 fbi
.FileAttributes
= FILE_ATTRIBUTE_SYSTEM
;
1462 U(io
).Status
= 0xdeadbeef;
1463 res
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1464 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, NtSetInformationFile returned %x\n", res
);
1465 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status is %x\n", U(io
).Status
);
1467 memset(&fbi
, 0, sizeof(fbi
));
1468 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1469 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1470 ok ( (fbi
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_SYSTEM
, "attribute %x not FILE_ATTRIBUTE_SYSTEM (ok in old linux without xattr)\n", fbi
.FileAttributes
);
1473 memset(&fbi
, 0, sizeof(fbi
));
1474 fbi
.FileAttributes
= FILE_ATTRIBUTE_HIDDEN
;
1475 U(io
).Status
= 0xdeadbeef;
1476 res
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1477 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, NtSetInformationFile returned %x\n", res
);
1478 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status is %x\n", U(io
).Status
);
1480 memset(&fbi
, 0, sizeof(fbi
));
1481 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1482 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1483 ok ( (fbi
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_HIDDEN
, "attribute %x not FILE_ATTRIBUTE_HIDDEN (ok in old linux without xattr)\n", fbi
.FileAttributes
);
1485 /* Check NORMAL last of all (to make sure we can clear attributes) */
1486 memset(&fbi
, 0, sizeof(fbi
));
1487 fbi
.FileAttributes
= FILE_ATTRIBUTE_NORMAL
;
1488 U(io
).Status
= 0xdeadbeef;
1489 res
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1490 ok ( res
== STATUS_SUCCESS
, "can't set normal attribute, NtSetInformationFile returned %x\n", res
);
1491 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set normal attribute, io.Status is %x\n", U(io
).Status
);
1493 memset(&fbi
, 0, sizeof(fbi
));
1494 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1495 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1496 todo_wine
ok ( (fbi
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_NORMAL
, "attribute %x not 0\n", fbi
.FileAttributes
);
1501 static void test_file_all_information(void)
1504 /* FileAllInformation, like FileNameInformation, has a variable-length pathname
1505 * buffer at the end. Vista objects with STATUS_BUFFER_OVERFLOW if you
1506 * don't leave enough room there.
1509 FILE_ALL_INFORMATION fai
;
1514 int attrib_mask
= FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_NORMAL
;
1516 if (!(h
= create_temp_file(0))) return;
1518 /* Check default first */
1519 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1520 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1521 ok ( (fai_buf
.fai
.BasicInformation
.FileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) == FILE_ATTRIBUTE_ARCHIVE
,
1522 "attribute %x not expected\n", fai_buf
.fai
.BasicInformation
.FileAttributes
);
1525 /* Clear fbi to avoid setting times */
1526 memset(&fai_buf
.fai
.BasicInformation
, 0, sizeof(fai_buf
.fai
.BasicInformation
));
1527 fai_buf
.fai
.BasicInformation
.FileAttributes
= FILE_ATTRIBUTE_SYSTEM
;
1528 U(io
).Status
= 0xdeadbeef;
1529 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1530 ok ( res
== STATUS_INVALID_INFO_CLASS
|| broken(res
== STATUS_NOT_IMPLEMENTED
), "shouldn't be able to set FileAllInformation, res %x\n", res
);
1531 todo_wine
ok ( U(io
).Status
== 0xdeadbeef, "shouldn't be able to set FileAllInformation, io.Status is %x\n", U(io
).Status
);
1532 U(io
).Status
= 0xdeadbeef;
1533 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
.BasicInformation
, sizeof fai_buf
.fai
.BasicInformation
, FileBasicInformation
);
1534 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, res: %x\n", res
);
1535 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status: %x\n", U(io
).Status
);
1537 memset(&fai_buf
.fai
, 0, sizeof(fai_buf
.fai
));
1538 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1539 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1540 ok ( (fai_buf
.fai
.BasicInformation
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_SYSTEM
, "attribute %x not FILE_ATTRIBUTE_SYSTEM (ok in old linux without xattr)\n", fai_buf
.fai
.BasicInformation
.FileAttributes
);
1543 memset(&fai_buf
.fai
.BasicInformation
, 0, sizeof(fai_buf
.fai
.BasicInformation
));
1544 fai_buf
.fai
.BasicInformation
.FileAttributes
= FILE_ATTRIBUTE_HIDDEN
;
1545 U(io
).Status
= 0xdeadbeef;
1546 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
.BasicInformation
, sizeof fai_buf
.fai
.BasicInformation
, FileBasicInformation
);
1547 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, res: %x\n", res
);
1548 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status: %x\n", U(io
).Status
);
1550 memset(&fai_buf
.fai
, 0, sizeof(fai_buf
.fai
));
1551 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1552 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1553 ok ( (fai_buf
.fai
.BasicInformation
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_HIDDEN
, "attribute %x not FILE_ATTRIBUTE_HIDDEN (ok in old linux without xattr)\n", fai_buf
.fai
.BasicInformation
.FileAttributes
);
1555 /* Check NORMAL last of all (to make sure we can clear attributes) */
1556 memset(&fai_buf
.fai
.BasicInformation
, 0, sizeof(fai_buf
.fai
.BasicInformation
));
1557 fai_buf
.fai
.BasicInformation
.FileAttributes
= FILE_ATTRIBUTE_NORMAL
;
1558 U(io
).Status
= 0xdeadbeef;
1559 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
.BasicInformation
, sizeof fai_buf
.fai
.BasicInformation
, FileBasicInformation
);
1560 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, res: %x\n", res
);
1561 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status: %x\n", U(io
).Status
);
1563 memset(&fai_buf
.fai
, 0, sizeof(fai_buf
.fai
));
1564 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1565 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1566 todo_wine
ok ( (fai_buf
.fai
.BasicInformation
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_NORMAL
, "attribute %x not FILE_ATTRIBUTE_NORMAL\n", fai_buf
.fai
.BasicInformation
.FileAttributes
);
1571 static void delete_object( WCHAR
*path
)
1573 BOOL ret
= DeleteFileW( path
);
1574 ok( ret
|| GetLastError() == ERROR_FILE_NOT_FOUND
|| GetLastError() == ERROR_ACCESS_DENIED
,
1575 "DeleteFileW failed with %u\n", GetLastError() );
1576 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1578 ret
= RemoveDirectoryW( path
);
1579 ok( ret
, "RemoveDirectoryW failed with %u\n", GetLastError() );
1583 static void test_file_rename_information(void)
1585 static const WCHAR foo_txtW
[] = {'\\','f','o','o','.','t','x','t',0};
1586 static const WCHAR fooW
[] = {'f','o','o',0};
1587 WCHAR tmp_path
[MAX_PATH
], oldpath
[MAX_PATH
+ 16], newpath
[MAX_PATH
+ 16], *filename
, *p
;
1588 FILE_RENAME_INFORMATION
*fri
;
1589 FILE_NAME_INFORMATION
*fni
;
1590 BOOL success
, fileDeleted
;
1591 UNICODE_STRING name_str
;
1592 HANDLE handle
, handle2
;
1596 GetTempPathW( MAX_PATH
, tmp_path
);
1598 /* oldpath is a file, newpath doesn't exist */
1599 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1600 ok( res
!= 0, "failed to create temp file\n" );
1601 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1602 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1604 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1605 ok( res
!= 0, "failed to create temp file\n" );
1606 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1607 DeleteFileW( newpath
);
1608 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1609 fri
->Replace
= FALSE
;
1610 fri
->RootDir
= NULL
;
1611 fri
->FileNameLength
= name_str
.Length
;
1612 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1613 pRtlFreeUnicodeString( &name_str
);
1615 U(io
).Status
= 0xdeadbeef;
1616 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1617 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1618 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1619 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1620 ok( fileDeleted
, "file should not exist\n" );
1621 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1622 ok( !fileDeleted
, "file should exist\n" );
1624 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
1625 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
1626 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1627 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
1628 ok( !lstrcmpW(fni
->FileName
, newpath
+ 2), "FileName expected %s, got %s\n",
1629 wine_dbgstr_w(newpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
1630 HeapFree( GetProcessHeap(), 0, fni
);
1632 CloseHandle( handle
);
1633 HeapFree( GetProcessHeap(), 0, fri
);
1634 delete_object( oldpath
);
1635 delete_object( newpath
);
1637 /* oldpath is a file, newpath is a file, Replace = FALSE */
1638 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1639 ok( res
!= 0, "failed to create temp file\n" );
1640 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1641 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1643 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1644 ok( res
!= 0, "failed to create temp file\n" );
1645 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1646 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1647 fri
->Replace
= FALSE
;
1648 fri
->RootDir
= NULL
;
1649 fri
->FileNameLength
= name_str
.Length
;
1650 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1651 pRtlFreeUnicodeString( &name_str
);
1653 U(io
).Status
= 0xdeadbeef;
1654 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1655 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1656 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1657 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1658 ok( !fileDeleted
, "file should exist\n" );
1659 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1660 ok( !fileDeleted
, "file should exist\n" );
1662 CloseHandle( handle
);
1663 HeapFree( GetProcessHeap(), 0, fri
);
1664 delete_object( oldpath
);
1665 delete_object( newpath
);
1667 /* oldpath is a file, newpath is a file, Replace = TRUE */
1668 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1669 ok( res
!= 0, "failed to create temp file\n" );
1670 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1671 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1673 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1674 ok( res
!= 0, "failed to create temp file\n" );
1675 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1676 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1677 fri
->Replace
= TRUE
;
1678 fri
->RootDir
= NULL
;
1679 fri
->FileNameLength
= name_str
.Length
;
1680 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1681 pRtlFreeUnicodeString( &name_str
);
1683 U(io
).Status
= 0xdeadbeef;
1684 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1685 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1686 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1687 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1688 ok( fileDeleted
, "file should not exist\n" );
1689 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1690 ok( !fileDeleted
, "file should exist\n" );
1692 CloseHandle( handle
);
1693 HeapFree( GetProcessHeap(), 0, fri
);
1694 delete_object( oldpath
);
1695 delete_object( newpath
);
1697 /* oldpath is a file, newpath is a file, Replace = FALSE, target file opened */
1698 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1699 ok( res
!= 0, "failed to create temp file\n" );
1700 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1701 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1703 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1704 ok( res
!= 0, "failed to create temp file\n" );
1705 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1706 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1708 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1709 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1710 fri
->Replace
= FALSE
;
1711 fri
->RootDir
= NULL
;
1712 fri
->FileNameLength
= name_str
.Length
;
1713 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1714 pRtlFreeUnicodeString( &name_str
);
1716 U(io
).Status
= 0xdeadbeef;
1717 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1718 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1719 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1720 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1721 ok( !fileDeleted
, "file should exist\n" );
1722 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1723 ok( !fileDeleted
, "file should exist\n" );
1725 CloseHandle( handle
);
1726 CloseHandle( handle2
);
1727 HeapFree( GetProcessHeap(), 0, fri
);
1728 delete_object( oldpath
);
1729 delete_object( newpath
);
1731 /* oldpath is a file, newpath is a file, Replace = TRUE, target file opened */
1732 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1733 ok( res
!= 0, "failed to create temp file\n" );
1734 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1735 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1737 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1738 ok( res
!= 0, "failed to create temp file\n" );
1739 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1740 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1742 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1743 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1744 fri
->Replace
= TRUE
;
1745 fri
->RootDir
= NULL
;
1746 fri
->FileNameLength
= name_str
.Length
;
1747 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1748 pRtlFreeUnicodeString( &name_str
);
1750 U(io
).Status
= 0xdeadbeef;
1751 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1752 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1753 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1754 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1755 ok( !fileDeleted
, "file should exist\n" );
1756 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1757 ok( !fileDeleted
, "file should exist\n" );
1759 CloseHandle( handle
);
1760 CloseHandle( handle2
);
1761 HeapFree( GetProcessHeap(), 0, fri
);
1762 delete_object( oldpath
);
1763 delete_object( newpath
);
1765 /* oldpath is a directory, newpath doesn't exist, Replace = FALSE */
1766 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1767 ok( res
!= 0, "failed to create temp file\n" );
1768 DeleteFileW( oldpath
);
1769 success
= CreateDirectoryW( oldpath
, NULL
);
1770 ok( success
!= 0, "failed to create temp directory\n" );
1771 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1772 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1774 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1775 ok( res
!= 0, "failed to create temp file\n" );
1776 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1777 DeleteFileW( newpath
);
1778 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1779 fri
->Replace
= FALSE
;
1780 fri
->RootDir
= NULL
;
1781 fri
->FileNameLength
= name_str
.Length
;
1782 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1783 pRtlFreeUnicodeString( &name_str
);
1785 U(io
).Status
= 0xdeadbeef;
1786 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1787 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1788 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1789 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1790 ok( fileDeleted
, "file should not exist\n" );
1791 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1792 ok( !fileDeleted
, "file should exist\n" );
1794 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
1795 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
1796 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1797 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
1798 ok( !lstrcmpW(fni
->FileName
, newpath
+ 2), "FileName expected %s, got %s\n",
1799 wine_dbgstr_w(newpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
1800 HeapFree( GetProcessHeap(), 0, fni
);
1802 CloseHandle( handle
);
1803 HeapFree( GetProcessHeap(), 0, fri
);
1804 delete_object( oldpath
);
1805 delete_object( newpath
);
1807 /* oldpath is a directory (but child object opened), newpath doesn't exist, Replace = FALSE */
1808 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1809 ok( res
!= 0, "failed to create temp file\n" );
1810 DeleteFileW( oldpath
);
1811 success
= CreateDirectoryW( oldpath
, NULL
);
1812 ok( success
!= 0, "failed to create temp directory\n" );
1813 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1814 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1816 lstrcpyW( newpath
, oldpath
);
1817 lstrcatW( newpath
, foo_txtW
);
1818 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0 );
1819 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1821 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1822 ok( res
!= 0, "failed to create temp file\n" );
1823 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1824 DeleteFileW( newpath
);
1825 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1826 fri
->Replace
= FALSE
;
1827 fri
->RootDir
= NULL
;
1828 fri
->FileNameLength
= name_str
.Length
;
1829 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1830 pRtlFreeUnicodeString( &name_str
);
1832 U(io
).Status
= 0xdeadbeef;
1833 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1834 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1835 todo_wine
ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1836 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1837 todo_wine
ok( !fileDeleted
, "file should exist\n" );
1838 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1839 todo_wine
ok( fileDeleted
, "file should not exist\n" );
1841 CloseHandle( handle
);
1842 CloseHandle( handle2
);
1843 HeapFree( GetProcessHeap(), 0, fri
);
1844 delete_object( oldpath
);
1845 if (res
== STATUS_SUCCESS
) /* remove when Wine is fixed */
1847 lstrcpyW( oldpath
, newpath
);
1848 lstrcatW( oldpath
, foo_txtW
);
1849 delete_object( oldpath
);
1851 delete_object( newpath
);
1853 /* oldpath is a directory, newpath is a file, Replace = FALSE */
1854 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1855 ok( res
!= 0, "failed to create temp file\n" );
1856 DeleteFileW( oldpath
);
1857 success
= CreateDirectoryW( oldpath
, NULL
);
1858 ok( success
!= 0, "failed to create temp directory\n" );
1859 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1860 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1862 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1863 ok( res
!= 0, "failed to create temp file\n" );
1864 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1865 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1866 fri
->Replace
= FALSE
;
1867 fri
->RootDir
= NULL
;
1868 fri
->FileNameLength
= name_str
.Length
;
1869 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1870 pRtlFreeUnicodeString( &name_str
);
1872 U(io
).Status
= 0xdeadbeef;
1873 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1874 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1875 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1876 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1877 ok( !fileDeleted
, "file should exist\n" );
1878 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1879 ok( !fileDeleted
, "file should exist\n" );
1881 CloseHandle( handle
);
1882 HeapFree( GetProcessHeap(), 0, fri
);
1883 delete_object( oldpath
);
1884 delete_object( newpath
);
1886 /* oldpath is a directory, newpath is a file, Replace = FALSE, target file opened */
1887 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1888 ok( res
!= 0, "failed to create temp file\n" );
1889 DeleteFileW( oldpath
);
1890 success
= CreateDirectoryW( oldpath
, NULL
);
1891 ok( success
!= 0, "failed to create temp directory\n" );
1892 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1893 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1895 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1896 ok( res
!= 0, "failed to create temp file\n" );
1897 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1898 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1900 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1901 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1902 fri
->Replace
= FALSE
;
1903 fri
->RootDir
= NULL
;
1904 fri
->FileNameLength
= name_str
.Length
;
1905 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1906 pRtlFreeUnicodeString( &name_str
);
1908 U(io
).Status
= 0xdeadbeef;
1909 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1910 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1911 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1912 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1913 ok( !fileDeleted
, "file should exist\n" );
1914 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1915 ok( !fileDeleted
, "file should exist\n" );
1917 CloseHandle( handle
);
1918 CloseHandle( handle2
);
1919 HeapFree( GetProcessHeap(), 0, fri
);
1920 delete_object( oldpath
);
1921 delete_object( newpath
);
1923 /* oldpath is a directory, newpath is a file, Replace = TRUE */
1924 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1925 ok( res
!= 0, "failed to create temp file\n" );
1926 DeleteFileW( oldpath
);
1927 success
= CreateDirectoryW( oldpath
, NULL
);
1928 ok( success
!= 0, "failed to create temp directory\n" );
1929 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1930 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1932 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1933 ok( res
!= 0, "failed to create temp file\n" );
1934 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1935 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1936 fri
->Replace
= TRUE
;
1937 fri
->RootDir
= NULL
;
1938 fri
->FileNameLength
= name_str
.Length
;
1939 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1940 pRtlFreeUnicodeString( &name_str
);
1942 U(io
).Status
= 0xdeadbeef;
1943 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1944 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1945 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1946 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1947 ok( fileDeleted
, "file should not exist\n" );
1948 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1949 ok( !fileDeleted
, "file should exist\n" );
1951 CloseHandle( handle
);
1952 HeapFree( GetProcessHeap(), 0, fri
);
1953 delete_object( oldpath
);
1954 delete_object( newpath
);
1956 /* oldpath is a directory, newpath is a file, Replace = TRUE, target file opened */
1957 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1958 ok( res
!= 0, "failed to create temp file\n" );
1959 DeleteFileW( oldpath
);
1960 success
= CreateDirectoryW( oldpath
, NULL
);
1961 ok( success
!= 0, "failed to create temp directory\n" );
1962 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1963 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1965 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1966 ok( res
!= 0, "failed to create temp file\n" );
1967 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1968 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1970 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1971 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1972 fri
->Replace
= TRUE
;
1973 fri
->RootDir
= NULL
;
1974 fri
->FileNameLength
= name_str
.Length
;
1975 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1976 pRtlFreeUnicodeString( &name_str
);
1978 U(io
).Status
= 0xdeadbeef;
1979 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1980 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1981 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1982 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1983 ok( !fileDeleted
, "file should exist\n" );
1984 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1985 ok( !fileDeleted
, "file should exist\n" );
1987 CloseHandle( handle
);
1988 CloseHandle( handle2
);
1989 HeapFree( GetProcessHeap(), 0, fri
);
1990 delete_object( oldpath
);
1991 delete_object( newpath
);
1993 /* oldpath is a directory, newpath is a directory, Replace = FALSE */
1994 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1995 ok( res
!= 0, "failed to create temp file\n" );
1996 DeleteFileW( oldpath
);
1997 success
= CreateDirectoryW( oldpath
, NULL
);
1998 ok( success
!= 0, "failed to create temp directory\n" );
1999 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2000 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2002 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2003 ok( res
!= 0, "failed to create temp file\n" );
2004 DeleteFileW( newpath
);
2005 success
= CreateDirectoryW( newpath
, NULL
);
2006 ok( success
!= 0, "failed to create temp directory\n" );
2007 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2008 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
2009 fri
->Replace
= FALSE
;
2010 fri
->RootDir
= NULL
;
2011 fri
->FileNameLength
= name_str
.Length
;
2012 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
2013 pRtlFreeUnicodeString( &name_str
);
2015 U(io
).Status
= 0xdeadbeef;
2016 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
2017 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2018 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
2019 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2020 ok( !fileDeleted
, "file should exist\n" );
2021 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2022 ok( !fileDeleted
, "file should exist\n" );
2024 CloseHandle( handle
);
2025 HeapFree( GetProcessHeap(), 0, fri
);
2026 delete_object( oldpath
);
2027 delete_object( newpath
);
2029 /* oldpath is a directory, newpath is a directory, Replace = TRUE */
2030 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2031 ok( res
!= 0, "failed to create temp file\n" );
2032 DeleteFileW( oldpath
);
2033 success
= CreateDirectoryW( oldpath
, NULL
);
2034 ok( success
!= 0, "failed to create temp directory\n" );
2035 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2036 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2038 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2039 ok( res
!= 0, "failed to create temp file\n" );
2040 DeleteFileW( newpath
);
2041 success
= CreateDirectoryW( newpath
, NULL
);
2042 ok( success
!= 0, "failed to create temp directory\n" );
2043 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2044 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
2045 fri
->Replace
= TRUE
;
2046 fri
->RootDir
= NULL
;
2047 fri
->FileNameLength
= name_str
.Length
;
2048 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
2049 pRtlFreeUnicodeString( &name_str
);
2051 U(io
).Status
= 0xdeadbeef;
2052 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
2053 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2054 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
2055 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2056 ok( !fileDeleted
, "file should exist\n" );
2057 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2058 ok( !fileDeleted
, "file should exist\n" );
2060 CloseHandle( handle
);
2061 HeapFree( GetProcessHeap(), 0, fri
);
2062 delete_object( oldpath
);
2063 delete_object( newpath
);
2065 /* oldpath is a directory, newpath is a directory, Replace = TRUE, target file opened */
2066 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2067 ok( res
!= 0, "failed to create temp file\n" );
2068 DeleteFileW( oldpath
);
2069 success
= CreateDirectoryW( oldpath
, NULL
);
2070 ok( success
!= 0, "failed to create temp directory\n" );
2071 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2072 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2074 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2075 ok( res
!= 0, "failed to create temp file\n" );
2076 DeleteFileW( newpath
);
2077 success
= CreateDirectoryW( newpath
, NULL
);
2078 ok( success
!= 0, "failed to create temp directory\n" );
2079 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2080 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2082 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2083 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
2084 fri
->Replace
= TRUE
;
2085 fri
->RootDir
= NULL
;
2086 fri
->FileNameLength
= name_str
.Length
;
2087 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
2088 pRtlFreeUnicodeString( &name_str
);
2090 U(io
).Status
= 0xdeadbeef;
2091 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
2092 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2093 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
2094 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2095 ok( !fileDeleted
, "file should exist\n" );
2096 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2097 ok( !fileDeleted
, "file should exist\n" );
2099 CloseHandle( handle
);
2100 CloseHandle( handle2
);
2101 HeapFree( GetProcessHeap(), 0, fri
);
2102 delete_object( oldpath
);
2103 delete_object( newpath
);
2105 /* oldpath is a file, newpath is a directory, Replace = FALSE */
2106 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2107 ok( res
!= 0, "failed to create temp file\n" );
2108 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2109 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2111 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2112 ok( res
!= 0, "failed to create temp file\n" );
2113 DeleteFileW( newpath
);
2114 success
= CreateDirectoryW( newpath
, NULL
);
2115 ok( success
!= 0, "failed to create temp directory\n" );
2116 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2117 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
2118 fri
->Replace
= FALSE
;
2119 fri
->RootDir
= NULL
;
2120 fri
->FileNameLength
= name_str
.Length
;
2121 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
2122 pRtlFreeUnicodeString( &name_str
);
2124 U(io
).Status
= 0xdeadbeef;
2125 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
2126 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2127 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
2128 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2129 ok( !fileDeleted
, "file should exist\n" );
2130 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2131 ok( !fileDeleted
, "file should exist\n" );
2133 CloseHandle( handle
);
2134 HeapFree( GetProcessHeap(), 0, fri
);
2135 delete_object( oldpath
);
2136 delete_object( newpath
);
2138 /* oldpath is a file, newpath is a directory, Replace = TRUE */
2139 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2140 ok( res
!= 0, "failed to create temp file\n" );
2141 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2142 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2144 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2145 ok( res
!= 0, "failed to create temp file\n" );
2146 DeleteFileW( newpath
);
2147 success
= CreateDirectoryW( newpath
, NULL
);
2148 ok( success
!= 0, "failed to create temp directory\n" );
2149 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2150 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
2151 fri
->Replace
= TRUE
;
2152 fri
->RootDir
= NULL
;
2153 fri
->FileNameLength
= name_str
.Length
;
2154 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
2155 pRtlFreeUnicodeString( &name_str
);
2157 U(io
).Status
= 0xdeadbeef;
2158 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
2159 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2160 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
2161 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2162 ok( !fileDeleted
, "file should exist\n" );
2163 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2164 ok( !fileDeleted
, "file should exist\n" );
2166 CloseHandle( handle
);
2167 HeapFree( GetProcessHeap(), 0, fri
);
2168 delete_object( oldpath
);
2169 delete_object( newpath
);
2171 /* oldpath is a file, newpath doesn't exist, test with RootDir != NULL */
2172 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2173 ok( res
!= 0, "failed to create temp file\n" );
2174 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2175 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2177 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2178 ok( res
!= 0, "failed to create temp file\n" );
2179 DeleteFileW( newpath
);
2180 for (filename
= newpath
, p
= newpath
; *p
; p
++)
2181 if (*p
== '\\') filename
= p
+ 1;
2182 handle2
= CreateFileW( tmp_path
, 0, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2183 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2185 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + lstrlenW(filename
) * sizeof(WCHAR
) );
2186 fri
->Replace
= FALSE
;
2187 fri
->RootDir
= handle2
;
2188 fri
->FileNameLength
= lstrlenW(filename
) * sizeof(WCHAR
);
2189 memcpy( fri
->FileName
, filename
, fri
->FileNameLength
);
2191 U(io
).Status
= 0xdeadbeef;
2192 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
2193 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
2194 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2195 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2196 ok( fileDeleted
, "file should not exist\n" );
2197 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2198 ok( !fileDeleted
, "file should exist\n" );
2200 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2201 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2202 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2203 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2204 ok( !lstrcmpW(fni
->FileName
, newpath
+ 2), "FileName expected %s, got %s\n",
2205 wine_dbgstr_w(newpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2206 HeapFree( GetProcessHeap(), 0, fni
);
2208 CloseHandle( handle
);
2209 CloseHandle( handle2
);
2210 HeapFree( GetProcessHeap(), 0, fri
);
2211 delete_object( oldpath
);
2212 delete_object( newpath
);
2215 static void test_file_link_information(void)
2217 static const WCHAR foo_txtW
[] = {'\\','f','o','o','.','t','x','t',0};
2218 static const WCHAR fooW
[] = {'f','o','o',0};
2219 WCHAR tmp_path
[MAX_PATH
], oldpath
[MAX_PATH
+ 16], newpath
[MAX_PATH
+ 16], *filename
, *p
;
2220 FILE_LINK_INFORMATION
*fli
;
2221 FILE_NAME_INFORMATION
*fni
;
2222 BOOL success
, fileDeleted
;
2223 UNICODE_STRING name_str
;
2224 HANDLE handle
, handle2
;
2228 GetTempPathW( MAX_PATH
, tmp_path
);
2230 /* oldpath is a file, newpath doesn't exist */
2231 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2232 ok( res
!= 0, "failed to create temp file\n" );
2233 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2234 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2236 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2237 ok( res
!= 0, "failed to create temp file\n" );
2238 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2239 DeleteFileW( newpath
);
2240 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2241 fli
->ReplaceIfExists
= FALSE
;
2242 fli
->RootDirectory
= NULL
;
2243 fli
->FileNameLength
= name_str
.Length
;
2244 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2245 pRtlFreeUnicodeString( &name_str
);
2247 U(io
).Status
= 0xdeadbeef;
2248 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2249 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
2250 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2251 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2252 ok( !fileDeleted
, "file should exist\n" );
2253 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2254 ok( !fileDeleted
, "file should exist\n" );
2256 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2257 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2258 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2259 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2260 ok( !lstrcmpW(fni
->FileName
, oldpath
+ 2), "FileName expected %s, got %s\n",
2261 wine_dbgstr_w(oldpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2262 HeapFree( GetProcessHeap(), 0, fni
);
2264 CloseHandle( handle
);
2265 HeapFree( GetProcessHeap(), 0, fli
);
2266 delete_object( oldpath
);
2267 delete_object( newpath
);
2269 /* oldpath is a file, newpath is a file, ReplaceIfExists = FALSE */
2270 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2271 ok( res
!= 0, "failed to create temp file\n" );
2272 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2273 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2275 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2276 ok( res
!= 0, "failed to create temp file\n" );
2277 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2278 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2279 fli
->ReplaceIfExists
= FALSE
;
2280 fli
->RootDirectory
= NULL
;
2281 fli
->FileNameLength
= name_str
.Length
;
2282 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2283 pRtlFreeUnicodeString( &name_str
);
2285 U(io
).Status
= 0xdeadbeef;
2286 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2287 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2288 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
2289 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2290 ok( !fileDeleted
, "file should exist\n" );
2291 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2292 ok( !fileDeleted
, "file should exist\n" );
2294 CloseHandle( handle
);
2295 HeapFree( GetProcessHeap(), 0, fli
);
2296 delete_object( oldpath
);
2297 delete_object( newpath
);
2299 /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE */
2300 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2301 ok( res
!= 0, "failed to create temp file\n" );
2302 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2303 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2305 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2306 ok( res
!= 0, "failed to create temp file\n" );
2307 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2308 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2309 fli
->ReplaceIfExists
= TRUE
;
2310 fli
->RootDirectory
= NULL
;
2311 fli
->FileNameLength
= name_str
.Length
;
2312 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2313 pRtlFreeUnicodeString( &name_str
);
2315 U(io
).Status
= 0xdeadbeef;
2316 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2317 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
2318 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2319 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2320 ok( !fileDeleted
, "file should exist\n" );
2321 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2322 ok( !fileDeleted
, "file should exist\n" );
2324 CloseHandle( handle
);
2325 HeapFree( GetProcessHeap(), 0, fli
);
2326 delete_object( oldpath
);
2327 delete_object( newpath
);
2329 /* oldpath is a file, newpath is a file, ReplaceIfExists = FALSE, target file opened */
2330 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2331 ok( res
!= 0, "failed to create temp file\n" );
2332 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2333 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2335 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2336 ok( res
!= 0, "failed to create temp file\n" );
2337 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2338 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2340 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2341 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2342 fli
->ReplaceIfExists
= FALSE
;
2343 fli
->RootDirectory
= NULL
;
2344 fli
->FileNameLength
= name_str
.Length
;
2345 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2346 pRtlFreeUnicodeString( &name_str
);
2348 U(io
).Status
= 0xdeadbeef;
2349 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2350 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2351 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
2352 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2353 ok( !fileDeleted
, "file should exist\n" );
2354 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2355 ok( !fileDeleted
, "file should exist\n" );
2357 CloseHandle( handle
);
2358 CloseHandle( handle2
);
2359 HeapFree( GetProcessHeap(), 0, fli
);
2360 delete_object( oldpath
);
2361 delete_object( newpath
);
2363 /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE, target file opened */
2364 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2365 ok( res
!= 0, "failed to create temp file\n" );
2366 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2367 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2369 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2370 ok( res
!= 0, "failed to create temp file\n" );
2371 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2372 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2374 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2375 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2376 fli
->ReplaceIfExists
= TRUE
;
2377 fli
->RootDirectory
= NULL
;
2378 fli
->FileNameLength
= name_str
.Length
;
2379 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2380 pRtlFreeUnicodeString( &name_str
);
2382 U(io
).Status
= 0xdeadbeef;
2383 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2384 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2385 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
2386 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2387 ok( !fileDeleted
, "file should exist\n" );
2388 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2389 ok( !fileDeleted
, "file should exist\n" );
2391 CloseHandle( handle
);
2392 CloseHandle( handle2
);
2393 HeapFree( GetProcessHeap(), 0, fli
);
2394 delete_object( oldpath
);
2395 delete_object( newpath
);
2397 /* oldpath is a directory, newpath doesn't exist, ReplaceIfExists = FALSE */
2398 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2399 ok( res
!= 0, "failed to create temp file\n" );
2400 DeleteFileW( oldpath
);
2401 success
= CreateDirectoryW( oldpath
, NULL
);
2402 ok( success
!= 0, "failed to create temp directory\n" );
2403 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2404 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2406 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2407 ok( res
!= 0, "failed to create temp file\n" );
2408 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2409 DeleteFileW( newpath
);
2410 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2411 fli
->ReplaceIfExists
= FALSE
;
2412 fli
->RootDirectory
= NULL
;
2413 fli
->FileNameLength
= name_str
.Length
;
2414 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2415 pRtlFreeUnicodeString( &name_str
);
2417 U(io
).Status
= 0xdeadbeef;
2418 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2419 todo_wine
ok( U(io
).Status
== 0xdeadbeef , "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2420 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2421 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2422 ok( !fileDeleted
, "file should exist\n" );
2423 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2424 ok( fileDeleted
, "file should not exist\n" );
2426 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2427 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2428 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2429 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2430 ok( !lstrcmpW(fni
->FileName
, oldpath
+ 2), "FileName expected %s, got %s\n",
2431 wine_dbgstr_w(oldpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2432 HeapFree( GetProcessHeap(), 0, fni
);
2434 CloseHandle( handle
);
2435 HeapFree( GetProcessHeap(), 0, fli
);
2436 delete_object( oldpath
);
2437 delete_object( newpath
);
2439 /* oldpath is a directory (but child object opened), newpath doesn't exist, ReplaceIfExists = FALSE */
2440 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2441 ok( res
!= 0, "failed to create temp file\n" );
2442 DeleteFileW( oldpath
);
2443 success
= CreateDirectoryW( oldpath
, NULL
);
2444 ok( success
!= 0, "failed to create temp directory\n" );
2445 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2446 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2448 lstrcpyW( newpath
, oldpath
);
2449 lstrcatW( newpath
, foo_txtW
);
2450 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0 );
2451 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2453 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2454 ok( res
!= 0, "failed to create temp file\n" );
2455 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2456 DeleteFileW( newpath
);
2457 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2458 fli
->ReplaceIfExists
= FALSE
;
2459 fli
->RootDirectory
= NULL
;
2460 fli
->FileNameLength
= name_str
.Length
;
2461 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2462 pRtlFreeUnicodeString( &name_str
);
2464 U(io
).Status
= 0xdeadbeef;
2465 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2466 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2467 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2468 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2469 ok( !fileDeleted
, "file should exist\n" );
2470 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2471 ok( fileDeleted
, "file should not exist\n" );
2473 CloseHandle( handle
);
2474 CloseHandle( handle2
);
2475 HeapFree( GetProcessHeap(), 0, fli
);
2476 delete_object( oldpath
);
2477 delete_object( newpath
);
2479 /* oldpath is a directory, newpath is a file, ReplaceIfExists = FALSE */
2480 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2481 ok( res
!= 0, "failed to create temp file\n" );
2482 DeleteFileW( oldpath
);
2483 success
= CreateDirectoryW( oldpath
, NULL
);
2484 ok( success
!= 0, "failed to create temp directory\n" );
2485 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2486 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2488 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2489 ok( res
!= 0, "failed to create temp file\n" );
2490 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2491 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2492 fli
->ReplaceIfExists
= FALSE
;
2493 fli
->RootDirectory
= NULL
;
2494 fli
->FileNameLength
= name_str
.Length
;
2495 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2496 pRtlFreeUnicodeString( &name_str
);
2498 U(io
).Status
= 0xdeadbeef;
2499 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2500 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2501 ok( res
== STATUS_OBJECT_NAME_COLLISION
|| res
== STATUS_FILE_IS_A_DIRECTORY
/* > Win XP */,
2502 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2503 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2504 ok( !fileDeleted
, "file should exist\n" );
2505 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2506 ok( !fileDeleted
, "file should exist\n" );
2508 CloseHandle( handle
);
2509 HeapFree( GetProcessHeap(), 0, fli
);
2510 delete_object( oldpath
);
2511 delete_object( newpath
);
2513 /* oldpath is a directory, newpath is a file, ReplaceIfExists = FALSE, target file opened */
2514 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2515 ok( res
!= 0, "failed to create temp file\n" );
2516 DeleteFileW( oldpath
);
2517 success
= CreateDirectoryW( oldpath
, NULL
);
2518 ok( success
!= 0, "failed to create temp directory\n" );
2519 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2520 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2522 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2523 ok( res
!= 0, "failed to create temp file\n" );
2524 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2525 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2527 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2528 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2529 fli
->ReplaceIfExists
= FALSE
;
2530 fli
->RootDirectory
= NULL
;
2531 fli
->FileNameLength
= name_str
.Length
;
2532 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2533 pRtlFreeUnicodeString( &name_str
);
2535 U(io
).Status
= 0xdeadbeef;
2536 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2537 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2538 ok( res
== STATUS_OBJECT_NAME_COLLISION
|| res
== STATUS_FILE_IS_A_DIRECTORY
/* > Win XP */,
2539 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2540 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2541 ok( !fileDeleted
, "file should exist\n" );
2542 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2543 ok( !fileDeleted
, "file should exist\n" );
2545 CloseHandle( handle
);
2546 CloseHandle( handle2
);
2547 HeapFree( GetProcessHeap(), 0, fli
);
2548 delete_object( oldpath
);
2549 delete_object( newpath
);
2551 /* oldpath is a directory, newpath is a file, ReplaceIfExists = TRUE */
2552 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2553 ok( res
!= 0, "failed to create temp file\n" );
2554 DeleteFileW( oldpath
);
2555 success
= CreateDirectoryW( oldpath
, NULL
);
2556 ok( success
!= 0, "failed to create temp directory\n" );
2557 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2558 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2560 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2561 ok( res
!= 0, "failed to create temp file\n" );
2562 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2563 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2564 fli
->ReplaceIfExists
= TRUE
;
2565 fli
->RootDirectory
= NULL
;
2566 fli
->FileNameLength
= name_str
.Length
;
2567 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2568 pRtlFreeUnicodeString( &name_str
);
2570 U(io
).Status
= 0xdeadbeef;
2571 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2572 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2573 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2574 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2575 ok( !fileDeleted
, "file should exist\n" );
2576 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2577 ok( !fileDeleted
, "file should exist\n" );
2579 CloseHandle( handle
);
2580 HeapFree( GetProcessHeap(), 0, fli
);
2581 delete_object( oldpath
);
2582 delete_object( newpath
);
2584 /* oldpath is a directory, newpath is a file, ReplaceIfExists = TRUE, target file opened */
2585 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2586 ok( res
!= 0, "failed to create temp file\n" );
2587 DeleteFileW( oldpath
);
2588 success
= CreateDirectoryW( oldpath
, NULL
);
2589 ok( success
!= 0, "failed to create temp directory\n" );
2590 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2591 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2593 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2594 ok( res
!= 0, "failed to create temp file\n" );
2595 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2596 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2598 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2599 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2600 fli
->ReplaceIfExists
= TRUE
;
2601 fli
->RootDirectory
= NULL
;
2602 fli
->FileNameLength
= name_str
.Length
;
2603 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2604 pRtlFreeUnicodeString( &name_str
);
2606 U(io
).Status
= 0xdeadbeef;
2607 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2608 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2609 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2610 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2611 ok( !fileDeleted
, "file should exist\n" );
2612 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2613 ok( !fileDeleted
, "file should exist\n" );
2615 CloseHandle( handle
);
2616 CloseHandle( handle2
);
2617 HeapFree( GetProcessHeap(), 0, fli
);
2618 delete_object( oldpath
);
2619 delete_object( newpath
);
2621 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = FALSE */
2622 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2623 ok( res
!= 0, "failed to create temp file\n" );
2624 DeleteFileW( oldpath
);
2625 success
= CreateDirectoryW( oldpath
, NULL
);
2626 ok( success
!= 0, "failed to create temp directory\n" );
2627 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2628 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2630 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2631 ok( res
!= 0, "failed to create temp file\n" );
2632 DeleteFileW( newpath
);
2633 success
= CreateDirectoryW( newpath
, NULL
);
2634 ok( success
!= 0, "failed to create temp directory\n" );
2635 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2636 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2637 fli
->ReplaceIfExists
= FALSE
;
2638 fli
->RootDirectory
= NULL
;
2639 fli
->FileNameLength
= name_str
.Length
;
2640 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2641 pRtlFreeUnicodeString( &name_str
);
2643 U(io
).Status
= 0xdeadbeef;
2644 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2645 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2646 ok( res
== STATUS_OBJECT_NAME_COLLISION
|| res
== STATUS_FILE_IS_A_DIRECTORY
/* > Win XP */,
2647 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2648 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2649 ok( !fileDeleted
, "file should exist\n" );
2650 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2651 ok( !fileDeleted
, "file should exist\n" );
2653 CloseHandle( handle
);
2654 HeapFree( GetProcessHeap(), 0, fli
);
2655 delete_object( oldpath
);
2656 delete_object( newpath
);
2658 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = TRUE */
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" );
2664 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2665 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2667 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2668 ok( res
!= 0, "failed to create temp file\n" );
2669 DeleteFileW( newpath
);
2670 success
= CreateDirectoryW( newpath
, NULL
);
2671 ok( success
!= 0, "failed to create temp directory\n" );
2672 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2673 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2674 fli
->ReplaceIfExists
= TRUE
;
2675 fli
->RootDirectory
= NULL
;
2676 fli
->FileNameLength
= name_str
.Length
;
2677 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2678 pRtlFreeUnicodeString( &name_str
);
2680 U(io
).Status
= 0xdeadbeef;
2681 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2682 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2683 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2684 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2685 ok( !fileDeleted
, "file should exist\n" );
2686 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2687 ok( !fileDeleted
, "file should exist\n" );
2689 CloseHandle( handle
);
2690 HeapFree( GetProcessHeap(), 0, fli
);
2691 delete_object( oldpath
);
2692 delete_object( newpath
);
2694 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = TRUE, target file opened */
2695 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2696 ok( res
!= 0, "failed to create temp file\n" );
2697 DeleteFileW( oldpath
);
2698 success
= CreateDirectoryW( oldpath
, NULL
);
2699 ok( success
!= 0, "failed to create temp directory\n" );
2700 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2701 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2703 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2704 ok( res
!= 0, "failed to create temp file\n" );
2705 DeleteFileW( newpath
);
2706 success
= CreateDirectoryW( newpath
, NULL
);
2707 ok( success
!= 0, "failed to create temp directory\n" );
2708 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2709 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2711 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2712 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2713 fli
->ReplaceIfExists
= TRUE
;
2714 fli
->RootDirectory
= NULL
;
2715 fli
->FileNameLength
= name_str
.Length
;
2716 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2717 pRtlFreeUnicodeString( &name_str
);
2719 U(io
).Status
= 0xdeadbeef;
2720 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2721 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2722 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2723 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2724 ok( !fileDeleted
, "file should exist\n" );
2725 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2726 ok( !fileDeleted
, "file should exist\n" );
2728 CloseHandle( handle
);
2729 CloseHandle( handle2
);
2730 HeapFree( GetProcessHeap(), 0, fli
);
2731 delete_object( oldpath
);
2732 delete_object( newpath
);
2734 /* oldpath is a file, newpath is a directory, ReplaceIfExists = FALSE */
2735 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2736 ok( res
!= 0, "failed to create temp file\n" );
2737 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2738 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2740 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2741 ok( res
!= 0, "failed to create temp file\n" );
2742 DeleteFileW( newpath
);
2743 success
= CreateDirectoryW( newpath
, NULL
);
2744 ok( success
!= 0, "failed to create temp directory\n" );
2745 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2746 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2747 fli
->ReplaceIfExists
= FALSE
;
2748 fli
->RootDirectory
= NULL
;
2749 fli
->FileNameLength
= name_str
.Length
;
2750 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2751 pRtlFreeUnicodeString( &name_str
);
2753 U(io
).Status
= 0xdeadbeef;
2754 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2755 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2756 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
2757 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2758 ok( !fileDeleted
, "file should exist\n" );
2759 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2760 ok( !fileDeleted
, "file should exist\n" );
2762 CloseHandle( handle
);
2763 HeapFree( GetProcessHeap(), 0, fli
);
2764 delete_object( oldpath
);
2765 delete_object( newpath
);
2767 /* oldpath is a file, newpath is a directory, ReplaceIfExists = TRUE */
2768 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2769 ok( res
!= 0, "failed to create temp file\n" );
2770 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2771 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2773 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2774 ok( res
!= 0, "failed to create temp file\n" );
2775 DeleteFileW( newpath
);
2776 success
= CreateDirectoryW( newpath
, NULL
);
2777 ok( success
!= 0, "failed to create temp directory\n" );
2778 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2779 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2780 fli
->ReplaceIfExists
= TRUE
;
2781 fli
->RootDirectory
= NULL
;
2782 fli
->FileNameLength
= name_str
.Length
;
2783 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2784 pRtlFreeUnicodeString( &name_str
);
2786 U(io
).Status
= 0xdeadbeef;
2787 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2788 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2789 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
2790 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2791 ok( !fileDeleted
, "file should exist\n" );
2792 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2793 ok( !fileDeleted
, "file should exist\n" );
2795 CloseHandle( handle
);
2796 HeapFree( GetProcessHeap(), 0, fli
);
2797 delete_object( oldpath
);
2798 delete_object( newpath
);
2800 /* oldpath is a file, newpath doesn't exist, test with RootDirectory != NULL */
2801 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2802 ok( res
!= 0, "failed to create temp file\n" );
2803 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2804 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2806 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2807 ok( res
!= 0, "failed to create temp file\n" );
2808 DeleteFileW( newpath
);
2809 for (filename
= newpath
, p
= newpath
; *p
; p
++)
2810 if (*p
== '\\') filename
= p
+ 1;
2811 handle2
= CreateFileW( tmp_path
, 0, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2812 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2814 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + lstrlenW(filename
) * sizeof(WCHAR
) );
2815 fli
->ReplaceIfExists
= FALSE
;
2816 fli
->RootDirectory
= handle2
;
2817 fli
->FileNameLength
= lstrlenW(filename
) * sizeof(WCHAR
);
2818 memcpy( fli
->FileName
, filename
, fli
->FileNameLength
);
2820 U(io
).Status
= 0xdeadbeef;
2821 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2822 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
2823 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2824 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2825 ok( !fileDeleted
, "file should exist\n" );
2826 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2827 ok( !fileDeleted
, "file should exist\n" );
2829 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2830 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2831 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2832 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2833 ok( !lstrcmpW(fni
->FileName
, oldpath
+ 2), "FileName expected %s, got %s\n",
2834 wine_dbgstr_w(oldpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2835 HeapFree( GetProcessHeap(), 0, fni
);
2837 CloseHandle( handle
);
2838 CloseHandle( handle2
);
2839 HeapFree( GetProcessHeap(), 0, fli
);
2840 delete_object( oldpath
);
2841 delete_object( newpath
);
2844 static void test_file_both_information(void)
2847 FILE_BOTH_DIR_INFORMATION fbi
;
2851 if (!(h
= create_temp_file(0))) return;
2853 memset(&fbi
, 0, sizeof(fbi
));
2854 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBothDirectoryInformation
);
2855 ok ( res
== STATUS_INVALID_INFO_CLASS
|| res
== STATUS_NOT_IMPLEMENTED
, "shouldn't be able to query FileBothDirectoryInformation, res %x\n", res
);
2860 static void test_file_disposition_information(void)
2862 char tmp_path
[MAX_PATH
], buffer
[MAX_PATH
+ 16];
2864 HANDLE handle
, handle2
, mapping
;
2867 FILE_DISPOSITION_INFORMATION fdi
;
2872 GetTempPathA( MAX_PATH
, tmp_path
);
2874 /* tests for info struct size */
2875 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2876 handle
= CreateFileA( buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2877 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2878 res
= pNtSetInformationFile( handle
, &io
, &fdi
, 0, FileDispositionInformation
);
2880 ok( res
== STATUS_INFO_LENGTH_MISMATCH
, "expected STATUS_INFO_LENGTH_MISMATCH, got %x\n", res
);
2882 res
= pNtSetInformationFile( handle
, &io
, &fdi2
, sizeof(fdi2
), FileDispositionInformation
);
2883 ok( res
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %x\n", res
);
2884 CloseHandle( handle
);
2885 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2886 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2887 DeleteFileA( buffer
);
2889 /* cannot set disposition on file not opened with delete access */
2890 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2891 handle
= CreateFileA(buffer
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2892 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2893 res
= pNtQueryInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2894 ok( res
== STATUS_INVALID_INFO_CLASS
|| res
== STATUS_NOT_IMPLEMENTED
, "Unexpected NtQueryInformationFile result (expected STATUS_INVALID_INFO_CLASS, got %x)\n", res
);
2895 fdi
.DoDeleteFile
= TRUE
;
2896 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2897 ok( res
== STATUS_ACCESS_DENIED
, "unexpected FileDispositionInformation result (expected STATUS_ACCESS_DENIED, got %x)\n", res
);
2898 CloseHandle( handle
);
2899 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2900 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2901 DeleteFileA( buffer
);
2903 /* can set disposition on file opened with proper access */
2904 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2905 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2906 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2907 fdi
.DoDeleteFile
= TRUE
;
2908 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2909 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2910 CloseHandle( handle
);
2911 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2912 ok( fileDeleted
, "File should have been deleted\n" );
2913 DeleteFileA( buffer
);
2915 /* cannot set disposition on readonly file */
2916 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2917 DeleteFileA( buffer
);
2918 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_READONLY
, 0);
2919 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2920 fdi
.DoDeleteFile
= TRUE
;
2921 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2922 ok( res
== STATUS_CANNOT_DELETE
, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res
);
2923 CloseHandle( handle
);
2924 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2925 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2926 SetFileAttributesA( buffer
, FILE_ATTRIBUTE_NORMAL
);
2927 DeleteFileA( buffer
);
2929 /* cannot set disposition on readonly file */
2930 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2931 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_READONLY
, 0);
2932 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2933 fdi
.DoDeleteFile
= TRUE
;
2934 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2936 ok( res
== STATUS_CANNOT_DELETE
, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res
);
2937 CloseHandle( handle
);
2938 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2940 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2941 SetFileAttributesA( buffer
, FILE_ATTRIBUTE_NORMAL
);
2942 DeleteFileA( buffer
);
2944 /* can set disposition on file and then reset it */
2945 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2946 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2947 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2948 fdi
.DoDeleteFile
= TRUE
;
2949 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2950 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2951 fdi
.DoDeleteFile
= FALSE
;
2952 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2953 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2954 CloseHandle( handle
);
2955 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2956 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2957 DeleteFileA( buffer
);
2959 /* Delete-on-close flag doesn't change file disposition until a handle is closed */
2960 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2961 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0);
2962 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2963 fdi
.DoDeleteFile
= FALSE
;
2964 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2965 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2966 CloseHandle( handle
);
2967 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2968 ok( fileDeleted
, "File should have been deleted\n" );
2969 DeleteFileA( buffer
);
2971 /* Delete-on-close flag sets disposition when a handle is closed and then it could be changed back */
2972 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2973 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0);
2974 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2975 ok( DuplicateHandle( GetCurrentProcess(), handle
, GetCurrentProcess(), &handle2
, 0, FALSE
, DUPLICATE_SAME_ACCESS
), "DuplicateHandle failed\n" );
2976 CloseHandle( handle
);
2977 fdi
.DoDeleteFile
= FALSE
;
2978 res
= pNtSetInformationFile( handle2
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2979 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2980 CloseHandle( handle2
);
2981 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2982 ok( fileDeleted
, "File should have been deleted\n" );
2983 DeleteFileA( buffer
);
2985 /* can set disposition on a directory opened with proper access */
2986 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2987 DeleteFileA( buffer
);
2988 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
2989 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2990 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
2991 fdi
.DoDeleteFile
= TRUE
;
2992 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2993 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2994 CloseHandle( handle
);
2995 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2996 ok( fileDeleted
, "Directory should have been deleted\n" );
2997 RemoveDirectoryA( buffer
);
2999 /* RemoveDirectory sets directory disposition and it can be undone */
3000 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3001 DeleteFileA( buffer
);
3002 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
3003 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
3004 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
3005 RemoveDirectoryA( buffer
);
3006 fdi
.DoDeleteFile
= FALSE
;
3007 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
3008 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
3009 CloseHandle( handle
);
3010 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3011 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
3012 RemoveDirectoryA( buffer
);
3014 /* cannot set disposition on a non-empty directory */
3015 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3016 DeleteFileA( buffer
);
3017 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
3018 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
3019 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
3020 dirpos
= lstrlenA( buffer
);
3021 lstrcpyA( buffer
+ dirpos
, "\\tst" );
3022 handle2
= CreateFileA(buffer
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
3023 CloseHandle( handle2
);
3024 fdi
.DoDeleteFile
= TRUE
;
3025 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
3027 ok( res
== STATUS_DIRECTORY_NOT_EMPTY
, "unexpected FileDispositionInformation result (expected STATUS_DIRECTORY_NOT_EMPTY, got %x)\n", res
);
3028 DeleteFileA( buffer
);
3029 buffer
[dirpos
] = '\0';
3030 CloseHandle( handle
);
3031 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3033 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
3034 RemoveDirectoryA( buffer
);
3036 /* cannot set disposition on file with file mapping opened */
3037 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3038 handle
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
3039 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
3040 mapping
= CreateFileMappingA( handle
, NULL
, PAGE_READWRITE
, 0, 64 * 1024, "DelFileTest" );
3041 ok( mapping
!= NULL
, "failed to create file mapping\n");
3042 fdi
.DoDeleteFile
= TRUE
;
3043 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
3044 ok( res
== STATUS_CANNOT_DELETE
, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res
);
3045 CloseHandle( handle
);
3046 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3047 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
3048 CloseHandle( mapping
);
3049 DeleteFileA( buffer
);
3051 /* can set disposition on file with file mapping closed */
3052 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3053 handle
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
3054 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
3055 mapping
= CreateFileMappingA( handle
, NULL
, PAGE_READWRITE
, 0, 64 * 1024, "DelFileTest" );
3056 ok( mapping
!= NULL
, "failed to create file mapping\n");
3057 CloseHandle( mapping
);
3058 fdi
.DoDeleteFile
= TRUE
;
3059 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
3060 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
3061 CloseHandle( handle
);
3062 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3063 ok( fileDeleted
, "File should have been deleted\n" );
3064 DeleteFileA( buffer
);
3066 /* cannot set disposition on file which is mapped to memory */
3067 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3068 handle
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
3069 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
3070 mapping
= CreateFileMappingA( handle
, NULL
, PAGE_READWRITE
, 0, 64 * 1024, "DelFileTest" );
3071 ok( mapping
!= NULL
, "failed to create file mapping\n");
3072 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
3073 ok( ptr
!= NULL
, "MapViewOfFile failed\n");
3074 CloseHandle( mapping
);
3075 fdi
.DoDeleteFile
= TRUE
;
3076 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
3077 ok( res
== STATUS_CANNOT_DELETE
, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res
);
3078 CloseHandle( handle
);
3079 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3080 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
3081 UnmapViewOfFile( ptr
);
3082 DeleteFileA( buffer
);
3084 /* can set disposition on file which is mapped to memory and unmapped again */
3085 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3086 handle
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
3087 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
3088 mapping
= CreateFileMappingA( handle
, NULL
, PAGE_READWRITE
, 0, 64 * 1024, "DelFileTest" );
3089 ok( mapping
!= NULL
, "failed to create file mapping\n");
3090 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
3091 ok( ptr
!= NULL
, "MapViewOfFile failed\n");
3092 CloseHandle( mapping
);
3093 UnmapViewOfFile( ptr
);
3094 fdi
.DoDeleteFile
= TRUE
;
3095 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
3096 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
3097 CloseHandle( handle
);
3098 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3099 ok( fileDeleted
, "File should have been deleted\n" );
3100 DeleteFileA( buffer
);
3103 static void test_iocompletion(void)
3105 HANDLE h
= INVALID_HANDLE_VALUE
;
3108 res
= pNtCreateIoCompletion( &h
, IO_COMPLETION_ALL_ACCESS
, NULL
, 0);
3110 ok( res
== 0, "NtCreateIoCompletion anonymous failed: %x\n", res
);
3111 ok( h
&& h
!= INVALID_HANDLE_VALUE
, "Invalid handle returned\n" );
3113 if ( h
&& h
!= INVALID_HANDLE_VALUE
)
3115 test_iocp_setcompletion(h
);
3116 test_iocp_fileio(h
);
3121 static void test_file_name_information(void)
3123 WCHAR
*file_name
, *volume_prefix
, *expected
;
3124 FILE_NAME_INFORMATION
*info
;
3125 ULONG old_redir
= 1, tmp
;
3126 UINT file_name_size
;
3133 /* GetVolumePathName is not present before w2k */
3134 if (!pGetVolumePathNameW
) {
3135 win_skip("GetVolumePathNameW not found\n");
3139 file_name_size
= GetSystemDirectoryW( NULL
, 0 );
3140 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3141 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3142 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3144 len
= GetSystemDirectoryW( file_name
, file_name_size
);
3145 ok(len
== file_name_size
- 1,
3146 "GetSystemDirectoryW returned %u, expected %u.\n",
3147 len
, file_name_size
- 1);
3149 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3150 ok(len
, "GetVolumePathNameW failed.\n");
3152 len
= lstrlenW( volume_prefix
);
3153 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3154 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3155 expected
[file_name_size
- len
- 1] = '\0';
3157 /* A bit more than we actually need, but it keeps the calculation simple. */
3158 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3159 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3161 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( TRUE
, &old_redir
);
3162 h
= CreateFileW( file_name
, GENERIC_READ
,
3163 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3164 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3165 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( old_redir
, &tmp
);
3166 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3168 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
) - 1, FileNameInformation
);
3169 ok(hr
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryInformationFile returned %#x.\n", hr
);
3171 memset( info
, 0xcc, info_size
);
3172 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
), FileNameInformation
);
3173 ok(hr
== STATUS_BUFFER_OVERFLOW
, "NtQueryInformationFile returned %#x, expected %#x.\n",
3174 hr
, STATUS_BUFFER_OVERFLOW
);
3175 ok(U(io
).Status
== STATUS_BUFFER_OVERFLOW
, "io.Status is %#x, expected %#x.\n",
3176 U(io
).Status
, STATUS_BUFFER_OVERFLOW
);
3177 ok(info
->FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
), "info->FileNameLength is %u\n", info
->FileNameLength
);
3178 ok(info
->FileName
[2] == 0xcccc, "info->FileName[2] is %#x, expected 0xcccc.\n", info
->FileName
[2]);
3179 ok(CharLowerW((LPWSTR
)(UINT_PTR
)info
->FileName
[1]) == CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]),
3180 "info->FileName[1] is %p, expected %p.\n",
3181 CharLowerW((LPWSTR
)(UINT_PTR
)info
->FileName
[1]), CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]));
3182 ok(io
.Information
== sizeof(*info
), "io.Information is %lu\n", io
.Information
);
3184 memset( info
, 0xcc, info_size
);
3185 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileNameInformation
);
3186 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
3187 ok(U(io
).Status
== STATUS_SUCCESS
, "io.Status is %#x, expected %#x.\n", U(io
).Status
, STATUS_SUCCESS
);
3188 ok(info
->FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
), "info->FileNameLength is %u\n", info
->FileNameLength
);
3189 ok(info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)] == 0xcccc, "info->FileName[len] is %#x, expected 0xcccc.\n",
3190 info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)]);
3191 info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)] = '\0';
3192 ok(!lstrcmpiW( info
->FileName
, expected
), "info->FileName is %s, expected %s.\n",
3193 wine_dbgstr_w( info
->FileName
), wine_dbgstr_w( expected
));
3194 ok(io
.Information
== FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
) + info
->FileNameLength
,
3195 "io.Information is %lu, expected %u.\n",
3196 io
.Information
, FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
) + info
->FileNameLength
);
3199 HeapFree( GetProcessHeap(), 0, info
);
3200 HeapFree( GetProcessHeap(), 0, expected
);
3201 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3203 if (old_redir
|| !pGetSystemWow64DirectoryW
|| !(file_name_size
= pGetSystemWow64DirectoryW( NULL
, 0 )))
3205 skip("Not running on WoW64, skipping test.\n");
3206 HeapFree( GetProcessHeap(), 0, file_name
);
3210 h
= CreateFileW( file_name
, GENERIC_READ
,
3211 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3212 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3213 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3214 HeapFree( GetProcessHeap(), 0, file_name
);
3216 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3217 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3218 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*expected
) );
3220 len
= pGetSystemWow64DirectoryW( file_name
, file_name_size
);
3221 ok(len
== file_name_size
- 1,
3222 "GetSystemWow64DirectoryW returned %u, expected %u.\n",
3223 len
, file_name_size
- 1);
3225 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3226 ok(len
, "GetVolumePathNameW failed.\n");
3228 len
= lstrlenW( volume_prefix
);
3229 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3230 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3231 expected
[file_name_size
- len
- 1] = '\0';
3233 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3234 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3236 memset( info
, 0xcc, info_size
);
3237 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileNameInformation
);
3238 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
3239 info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)] = '\0';
3240 ok(!lstrcmpiW( info
->FileName
, expected
), "info->FileName is %s, expected %s.\n",
3241 wine_dbgstr_w( info
->FileName
), wine_dbgstr_w( expected
));
3244 HeapFree( GetProcessHeap(), 0, info
);
3245 HeapFree( GetProcessHeap(), 0, expected
);
3246 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3247 HeapFree( GetProcessHeap(), 0, file_name
);
3250 static void test_file_all_name_information(void)
3252 WCHAR
*file_name
, *volume_prefix
, *expected
;
3253 FILE_ALL_INFORMATION
*info
;
3254 ULONG old_redir
= 1, tmp
;
3255 UINT file_name_size
;
3262 /* GetVolumePathName is not present before w2k */
3263 if (!pGetVolumePathNameW
) {
3264 win_skip("GetVolumePathNameW not found\n");
3268 file_name_size
= GetSystemDirectoryW( NULL
, 0 );
3269 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3270 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3271 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3273 len
= GetSystemDirectoryW( file_name
, file_name_size
);
3274 ok(len
== file_name_size
- 1,
3275 "GetSystemDirectoryW returned %u, expected %u.\n",
3276 len
, file_name_size
- 1);
3278 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3279 ok(len
, "GetVolumePathNameW failed.\n");
3281 len
= lstrlenW( volume_prefix
);
3282 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3283 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3284 expected
[file_name_size
- len
- 1] = '\0';
3286 /* A bit more than we actually need, but it keeps the calculation simple. */
3287 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3288 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3290 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( TRUE
, &old_redir
);
3291 h
= CreateFileW( file_name
, GENERIC_READ
,
3292 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3293 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3294 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( old_redir
, &tmp
);
3295 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3297 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
) - 1, FileAllInformation
);
3298 ok(hr
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryInformationFile returned %#x, expected %#x.\n",
3299 hr
, STATUS_INFO_LENGTH_MISMATCH
);
3301 memset( info
, 0xcc, info_size
);
3302 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
), FileAllInformation
);
3303 ok(hr
== STATUS_BUFFER_OVERFLOW
, "NtQueryInformationFile returned %#x, expected %#x.\n",
3304 hr
, STATUS_BUFFER_OVERFLOW
);
3305 ok(U(io
).Status
== STATUS_BUFFER_OVERFLOW
, "io.Status is %#x, expected %#x.\n",
3306 U(io
).Status
, STATUS_BUFFER_OVERFLOW
);
3307 ok(info
->NameInformation
.FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
),
3308 "info->NameInformation.FileNameLength is %u\n", info
->NameInformation
.FileNameLength
);
3309 ok(info
->NameInformation
.FileName
[2] == 0xcccc,
3310 "info->NameInformation.FileName[2] is %#x, expected 0xcccc.\n", info
->NameInformation
.FileName
[2]);
3311 ok(CharLowerW((LPWSTR
)(UINT_PTR
)info
->NameInformation
.FileName
[1]) == CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]),
3312 "info->NameInformation.FileName[1] is %p, expected %p.\n",
3313 CharLowerW((LPWSTR
)(UINT_PTR
)info
->NameInformation
.FileName
[1]), CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]));
3314 ok(io
.Information
== sizeof(*info
), "io.Information is %lu\n", io
.Information
);
3316 memset( info
, 0xcc, info_size
);
3317 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileAllInformation
);
3318 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
3319 ok(U(io
).Status
== STATUS_SUCCESS
, "io.Status is %#x, expected %#x.\n", U(io
).Status
, STATUS_SUCCESS
);
3320 ok(info
->NameInformation
.FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
),
3321 "info->NameInformation.FileNameLength is %u\n", info
->NameInformation
.FileNameLength
);
3322 ok(info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)] == 0xcccc,
3323 "info->NameInformation.FileName[len] is %#x, expected 0xcccc.\n",
3324 info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)]);
3325 info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)] = '\0';
3326 ok(!lstrcmpiW( info
->NameInformation
.FileName
, expected
),
3327 "info->NameInformation.FileName is %s, expected %s.\n",
3328 wine_dbgstr_w( info
->NameInformation
.FileName
), wine_dbgstr_w( expected
));
3329 ok(io
.Information
== FIELD_OFFSET(FILE_ALL_INFORMATION
, NameInformation
.FileName
)
3330 + info
->NameInformation
.FileNameLength
,
3331 "io.Information is %lu\n", io
.Information
);
3334 HeapFree( GetProcessHeap(), 0, info
);
3335 HeapFree( GetProcessHeap(), 0, expected
);
3336 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3338 if (old_redir
|| !pGetSystemWow64DirectoryW
|| !(file_name_size
= pGetSystemWow64DirectoryW( NULL
, 0 )))
3340 skip("Not running on WoW64, skipping test.\n");
3341 HeapFree( GetProcessHeap(), 0, file_name
);
3345 h
= CreateFileW( file_name
, GENERIC_READ
,
3346 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3347 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3348 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3349 HeapFree( GetProcessHeap(), 0, file_name
);
3351 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3352 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3353 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*expected
) );
3355 len
= pGetSystemWow64DirectoryW( file_name
, file_name_size
);
3356 ok(len
== file_name_size
- 1,
3357 "GetSystemWow64DirectoryW returned %u, expected %u.\n",
3358 len
, file_name_size
- 1);
3360 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3361 ok(len
, "GetVolumePathNameW failed.\n");
3363 len
= lstrlenW( volume_prefix
);
3364 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3365 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3366 expected
[file_name_size
- len
- 1] = '\0';
3368 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3369 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3371 memset( info
, 0xcc, info_size
);
3372 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileAllInformation
);
3373 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
3374 info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)] = '\0';
3375 ok(!lstrcmpiW( info
->NameInformation
.FileName
, expected
), "info->NameInformation.FileName is %s, expected %s.\n",
3376 wine_dbgstr_w( info
->NameInformation
.FileName
), wine_dbgstr_w( expected
));
3379 HeapFree( GetProcessHeap(), 0, info
);
3380 HeapFree( GetProcessHeap(), 0, expected
);
3381 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3382 HeapFree( GetProcessHeap(), 0, file_name
);
3385 static void test_query_volume_information_file(void)
3389 WCHAR path
[MAX_PATH
];
3390 OBJECT_ATTRIBUTES attr
;
3392 UNICODE_STRING nameW
;
3393 FILE_FS_VOLUME_INFORMATION
*ffvi
;
3394 BYTE buf
[sizeof(FILE_FS_VOLUME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
)];
3396 GetWindowsDirectoryW( path
, MAX_PATH
);
3397 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
3398 attr
.Length
= sizeof(attr
);
3399 attr
.RootDirectory
= 0;
3400 attr
.ObjectName
= &nameW
;
3401 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
3402 attr
.SecurityDescriptor
= NULL
;
3403 attr
.SecurityQualityOfService
= NULL
;
3405 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
3406 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
3407 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
3408 pRtlFreeUnicodeString( &nameW
);
3410 ZeroMemory( buf
, sizeof(buf
) );
3411 U(io
).Status
= 0xdadadada;
3412 io
.Information
= 0xcacacaca;
3414 status
= pNtQueryVolumeInformationFile( dir
, &io
, buf
, sizeof(buf
), FileFsVolumeInformation
);
3416 ffvi
= (FILE_FS_VOLUME_INFORMATION
*)buf
;
3418 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", status
);
3419 ok(U(io
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", U(io
).Status
);
3423 ok(io
.Information
== (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION
, VolumeLabel
) + ffvi
->VolumeLabelLength
),
3424 "expected %d, got %lu\n", (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION
, VolumeLabel
) + ffvi
->VolumeLabelLength
),
3427 ok(ffvi
->VolumeCreationTime
.QuadPart
!= 0, "Missing VolumeCreationTime\n");
3428 ok(ffvi
->VolumeSerialNumber
!= 0, "Missing VolumeSerialNumber\n");
3429 ok(ffvi
->SupportsObjects
== 1,"expected 1, got %d\n", ffvi
->SupportsObjects
);
3431 ok(ffvi
->VolumeLabelLength
== lstrlenW(ffvi
->VolumeLabel
) * sizeof(WCHAR
), "got %d\n", ffvi
->VolumeLabelLength
);
3433 trace("VolumeSerialNumber: %x VolumeLabelName: %s\n", ffvi
->VolumeSerialNumber
, wine_dbgstr_w(ffvi
->VolumeLabel
));
3438 static void test_query_attribute_information_file(void)
3442 WCHAR path
[MAX_PATH
];
3443 OBJECT_ATTRIBUTES attr
;
3445 UNICODE_STRING nameW
;
3446 FILE_FS_ATTRIBUTE_INFORMATION
*ffai
;
3447 BYTE buf
[sizeof(FILE_FS_ATTRIBUTE_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
)];
3449 GetWindowsDirectoryW( path
, MAX_PATH
);
3450 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
3451 attr
.Length
= sizeof(attr
);
3452 attr
.RootDirectory
= 0;
3453 attr
.ObjectName
= &nameW
;
3454 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
3455 attr
.SecurityDescriptor
= NULL
;
3456 attr
.SecurityQualityOfService
= NULL
;
3458 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
3459 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
3460 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
3461 pRtlFreeUnicodeString( &nameW
);
3463 ZeroMemory( buf
, sizeof(buf
) );
3464 U(io
).Status
= 0xdadadada;
3465 io
.Information
= 0xcacacaca;
3467 status
= pNtQueryVolumeInformationFile( dir
, &io
, buf
, sizeof(buf
), FileFsAttributeInformation
);
3469 ffai
= (FILE_FS_ATTRIBUTE_INFORMATION
*)buf
;
3471 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", status
);
3472 ok(U(io
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", U(io
).Status
);
3473 ok(ffai
->FileSystemAttribute
!= 0, "Missing FileSystemAttribute\n");
3474 ok(ffai
->MaximumComponentNameLength
!= 0, "Missing MaximumComponentNameLength\n");
3475 ok(ffai
->FileSystemNameLength
!= 0, "Missing FileSystemNameLength\n");
3477 trace("FileSystemAttribute: %x MaximumComponentNameLength: %x FileSystemName: %s\n",
3478 ffai
->FileSystemAttribute
, ffai
->MaximumComponentNameLength
,
3479 wine_dbgstr_wn(ffai
->FileSystemName
, ffai
->FileSystemNameLength
/ sizeof(WCHAR
)));
3484 static void test_NtCreateFile(void)
3486 static const struct test_data
3488 DWORD disposition
, attrib_in
, status
, result
, attrib_out
, needs_cleanup
;
3491 /* 0*/{ FILE_CREATE
, FILE_ATTRIBUTE_READONLY
, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3492 /* 1*/{ FILE_CREATE
, 0, STATUS_OBJECT_NAME_COLLISION
, 0, 0, TRUE
},
3493 /* 2*/{ FILE_CREATE
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3494 /* 3*/{ FILE_OPEN
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OPENED
, FILE_ATTRIBUTE_ARCHIVE
, TRUE
},
3495 /* 4*/{ FILE_OPEN
, FILE_ATTRIBUTE_READONLY
, STATUS_OBJECT_NAME_NOT_FOUND
, 0, 0, FALSE
},
3496 /* 5*/{ FILE_OPEN_IF
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3497 /* 6*/{ FILE_OPEN_IF
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OPENED
, FILE_ATTRIBUTE_ARCHIVE
, TRUE
},
3498 /* 7*/{ FILE_OPEN_IF
, FILE_ATTRIBUTE_READONLY
, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3499 /* 8*/{ FILE_OPEN_IF
, 0, 0, FILE_OPENED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3500 /* 9*/{ FILE_OVERWRITE
, 0, STATUS_ACCESS_DENIED
, 0, 0, TRUE
},
3501 /*10*/{ FILE_OVERWRITE
, 0, STATUS_OBJECT_NAME_NOT_FOUND
, 0, 0, FALSE
},
3502 /*11*/{ FILE_CREATE
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3503 /*12*/{ FILE_OVERWRITE
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OVERWRITTEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3504 /*13*/{ FILE_OVERWRITE_IF
, 0, STATUS_ACCESS_DENIED
, 0, 0, TRUE
},
3505 /*14*/{ FILE_OVERWRITE_IF
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3506 /*15*/{ FILE_OVERWRITE_IF
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OVERWRITTEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3507 /*16*/{ FILE_SUPERSEDE
, 0, 0, FILE_SUPERSEDED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3508 /*17*/{ FILE_SUPERSEDE
, FILE_ATTRIBUTE_READONLY
, 0, FILE_SUPERSEDED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, TRUE
},
3509 /*18*/{ FILE_SUPERSEDE
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, TRUE
}
3511 static const WCHAR fooW
[] = {'f','o','o',0};
3514 WCHAR path
[MAX_PATH
];
3515 OBJECT_ATTRIBUTES attr
;
3517 UNICODE_STRING nameW
;
3520 GetTempPathW(MAX_PATH
, path
);
3521 GetTempFileNameW(path
, fooW
, 0, path
);
3523 pRtlDosPathNameToNtPathName_U(path
, &nameW
, NULL
, NULL
);
3525 attr
.Length
= sizeof(attr
);
3526 attr
.RootDirectory
= NULL
;
3527 attr
.ObjectName
= &nameW
;
3528 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
3529 attr
.SecurityDescriptor
= NULL
;
3530 attr
.SecurityQualityOfService
= NULL
;
3532 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3534 status
= pNtCreateFile(&handle
, GENERIC_READ
, &attr
, &io
, NULL
,
3535 td
[i
].attrib_in
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
3536 td
[i
].disposition
, 0, NULL
, 0);
3538 ok(status
== td
[i
].status
, "%d: expected %#x got %#x\n", i
, td
[i
].status
, status
);
3542 ok(io
.Information
== td
[i
].result
,"%d: expected %#x got %#lx\n", i
, td
[i
].result
, io
.Information
);
3544 ret
= GetFileAttributesW(path
);
3545 ret
&= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
;
3546 /* FIXME: leave only 'else' case below once Wine is fixed */
3547 if (ret
!= td
[i
].attrib_out
)
3550 ok(ret
== td
[i
].attrib_out
, "%d: expected %#x got %#x\n", i
, td
[i
].attrib_out
, ret
);
3551 SetFileAttributesW(path
, td
[i
].attrib_out
);
3554 ok(ret
== td
[i
].attrib_out
, "%d: expected %#x got %#x\n", i
, td
[i
].attrib_out
, ret
);
3556 CloseHandle(handle
);
3559 if (td
[i
].needs_cleanup
)
3561 SetFileAttributesW(path
, FILE_ATTRIBUTE_ARCHIVE
);
3566 pRtlFreeUnicodeString( &nameW
);
3567 SetFileAttributesW(path
, FILE_ATTRIBUTE_ARCHIVE
);
3568 DeleteFileW( path
);
3571 static void test_readonly(void)
3573 static const WCHAR fooW
[] = {'f','o','o',0};
3576 WCHAR path
[MAX_PATH
];
3577 OBJECT_ATTRIBUTES attr
;
3579 UNICODE_STRING nameW
;
3581 GetTempPathW(MAX_PATH
, path
);
3582 GetTempFileNameW(path
, fooW
, 0, path
);
3584 pRtlDosPathNameToNtPathName_U(path
, &nameW
, NULL
, NULL
);
3586 attr
.Length
= sizeof(attr
);
3587 attr
.RootDirectory
= NULL
;
3588 attr
.ObjectName
= &nameW
;
3589 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
3590 attr
.SecurityDescriptor
= NULL
;
3591 attr
.SecurityQualityOfService
= NULL
;
3593 status
= pNtCreateFile(&handle
, GENERIC_READ
, &attr
, &io
, NULL
, FILE_ATTRIBUTE_READONLY
,
3594 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_CREATE
, 0, NULL
, 0);
3595 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3596 CloseHandle(handle
);
3598 status
= pNtOpenFile(&handle
, GENERIC_WRITE
, &attr
, &io
,
3599 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3600 ok(status
== STATUS_ACCESS_DENIED
, "got %#x\n", status
);
3601 CloseHandle(handle
);
3603 status
= pNtOpenFile(&handle
, GENERIC_READ
, &attr
, &io
,
3604 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3605 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3606 CloseHandle(handle
);
3608 status
= pNtOpenFile(&handle
, FILE_READ_ATTRIBUTES
, &attr
, &io
,
3609 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3610 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3611 CloseHandle(handle
);
3613 status
= pNtOpenFile(&handle
, FILE_WRITE_ATTRIBUTES
, &attr
, &io
,
3614 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3615 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3616 CloseHandle(handle
);
3618 status
= pNtOpenFile(&handle
, DELETE
, &attr
, &io
,
3619 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3620 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3621 CloseHandle(handle
);
3623 status
= pNtOpenFile(&handle
, READ_CONTROL
, &attr
, &io
,
3624 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3625 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3626 CloseHandle(handle
);
3628 status
= pNtOpenFile(&handle
, WRITE_DAC
, &attr
, &io
,
3629 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3630 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3631 CloseHandle(handle
);
3633 status
= pNtOpenFile(&handle
, WRITE_OWNER
, &attr
, &io
,
3634 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3635 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3636 CloseHandle(handle
);
3638 status
= pNtOpenFile(&handle
, SYNCHRONIZE
, &attr
, &io
,
3639 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3640 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3641 CloseHandle( handle
);
3643 pRtlFreeUnicodeString(&nameW
);
3644 SetFileAttributesW(path
, FILE_ATTRIBUTE_ARCHIVE
);
3648 static void test_read_write(void)
3650 static const char contents
[14] = "1234567890abcd";
3654 IO_STATUS_BLOCK iob
;
3655 DWORD ret
, bytes
, status
, off
;
3656 LARGE_INTEGER offset
;
3660 iob
.Information
= -1;
3661 offset
.QuadPart
= 0;
3662 status
= pNtReadFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3663 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status
);
3664 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3665 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3668 iob
.Information
= -1;
3669 offset
.QuadPart
= 0;
3670 status
= pNtWriteFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3671 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status
);
3672 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3673 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3675 hfile
= create_temp_file(0);
3679 iob
.Information
= -1;
3680 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
3681 ok(status
== STATUS_INVALID_USER_BUFFER
, "expected STATUS_INVALID_USER_BUFFER, got %#x\n", status
);
3682 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3683 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3686 iob
.Information
= -1;
3687 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
3688 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#x\n", status
);
3689 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3690 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3693 iob
.Information
= -1;
3694 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, 7, NULL
, NULL
);
3695 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
3696 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3697 ok(iob
.Information
== 7, "expected 7, got %lu\n", iob
.Information
);
3699 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3702 iob
.Information
= -1;
3703 offset
.QuadPart
= (LONGLONG
)-1 /* FILE_WRITE_TO_END_OF_FILE */;
3704 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
+ 7, sizeof(contents
) - 7, &offset
, NULL
);
3705 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
3706 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3707 ok(iob
.Information
== sizeof(contents
) - 7, "expected sizeof(contents)-7, got %lu\n", iob
.Information
);
3709 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3710 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3713 SetLastError(0xdeadbeef);
3714 ret
= ReadFile(INVALID_HANDLE_VALUE
, buf
, 0, &bytes
, NULL
);
3715 ok(!ret
, "ReadFile should fail\n");
3716 ok(GetLastError() == ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
3717 ok(bytes
== 0, "bytes %u\n", bytes
);
3720 SetLastError(0xdeadbeef);
3721 ret
= ReadFile(hfile
, buf
, 0, &bytes
, NULL
);
3722 ok(ret
, "ReadFile error %d\n", GetLastError());
3723 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3724 ok(bytes
== 0, "bytes %u\n", bytes
);
3727 SetLastError(0xdeadbeef);
3728 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3729 ok(ret
, "ReadFile error %d\n", GetLastError());
3730 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3731 ok(bytes
== 0, "bytes %u\n", bytes
);
3733 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3736 SetLastError(0xdeadbeef);
3737 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3738 ok(ret
, "ReadFile error %d\n", GetLastError());
3739 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3740 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
3742 for (i
= -20; i
< -1; i
++)
3744 if (i
== -2) continue;
3747 iob
.Information
= -1;
3748 offset
.QuadPart
= (LONGLONG
)i
;
3749 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), &offset
, NULL
);
3750 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
3751 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3752 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
3755 SetFilePointer(hfile
, sizeof(contents
) - 4, NULL
, FILE_BEGIN
);
3758 iob
.Information
= -1;
3759 offset
.QuadPart
= (LONGLONG
)-2 /* FILE_USE_FILE_POINTER_POSITION */;
3760 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, "DCBA", 4, &offset
, NULL
);
3761 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
3762 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3763 ok(iob
.Information
== 4, "expected 4, got %lu\n", iob
.Information
);
3765 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3766 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3769 iob
.Information
= -1;
3770 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), NULL
, NULL
);
3771 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3772 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3773 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3775 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3778 SetLastError(0xdeadbeef);
3779 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3780 ok(ret
, "ReadFile error %d\n", GetLastError());
3781 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3782 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
3783 ok(!memcmp(buf
+ sizeof(contents
) - 4, "DCBA", 4), "file contents mismatch\n");
3785 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3786 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3788 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3791 SetLastError(0xdeadbeef);
3792 ret
= WriteFile(hfile
, contents
, sizeof(contents
), &bytes
, NULL
);
3793 ok(ret
, "WriteFile error %d\n", GetLastError());
3794 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3796 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3797 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3799 /* test reading beyond EOF */
3801 SetLastError(0xdeadbeef);
3802 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3803 ok(ret
, "ReadFile error %d\n", GetLastError());
3804 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3805 ok(bytes
== 0, "bytes %u\n", bytes
);
3808 SetLastError(0xdeadbeef);
3809 ret
= ReadFile(hfile
, buf
, 0, &bytes
, NULL
);
3810 ok(ret
, "ReadFile error %d\n", GetLastError());
3811 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3812 ok(bytes
== 0, "bytes %u\n", bytes
);
3815 SetLastError(0xdeadbeef);
3816 ret
= ReadFile(hfile
, NULL
, 0, &bytes
, NULL
);
3817 ok(ret
, "ReadFile error %d\n", GetLastError());
3818 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3819 ok(bytes
== 0, "bytes %u\n", bytes
);
3821 S(U(ovl
)).Offset
= sizeof(contents
);
3822 S(U(ovl
)).OffsetHigh
= 0;
3824 ovl
.InternalHigh
= -1;
3827 SetLastError(0xdeadbeef);
3828 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
3829 ok(!ret
, "ReadFile should fail\n");
3830 ok(GetLastError() == ERROR_HANDLE_EOF
, "expected ERROR_HANDLE_EOF, got %d\n", GetLastError());
3831 ok(bytes
== 0, "bytes %u\n", bytes
);
3832 ok((NTSTATUS
)ovl
.Internal
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", ovl
.Internal
);
3833 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
3835 S(U(ovl
)).Offset
= sizeof(contents
);
3836 S(U(ovl
)).OffsetHigh
= 0;
3838 ovl
.InternalHigh
= -1;
3841 SetLastError(0xdeadbeef);
3842 ret
= ReadFile(hfile
, buf
, 0, &bytes
, &ovl
);
3843 ok(ret
, "ReadFile error %d\n", GetLastError());
3844 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3845 ok(bytes
== 0, "bytes %u\n", bytes
);
3846 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
3847 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
3850 iob
.Information
= -1;
3851 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), NULL
, NULL
);
3852 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3853 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3854 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3857 iob
.Information
= -1;
3858 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, NULL
, NULL
);
3859 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3860 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3861 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3864 iob
.Information
= -1;
3865 offset
.QuadPart
= sizeof(contents
);
3866 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3867 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3868 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3869 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3872 iob
.Information
= -1;
3873 offset
.QuadPart
= sizeof(contents
);
3874 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, &offset
, NULL
);
3875 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3876 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3877 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3880 iob
.Information
= -1;
3881 offset
.QuadPart
= (LONGLONG
)-2 /* FILE_USE_FILE_POINTER_POSITION */;
3882 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3883 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3884 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3885 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3888 iob
.Information
= -1;
3889 offset
.QuadPart
= (LONGLONG
)-2 /* FILE_USE_FILE_POINTER_POSITION */;
3890 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, &offset
, NULL
);
3891 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3892 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3893 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3895 for (i
= -20; i
< 0; i
++)
3897 if (i
== -2) continue;
3900 iob
.Information
= -1;
3901 offset
.QuadPart
= (LONGLONG
)i
;
3902 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3903 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
3904 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3905 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
3908 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3911 SetLastError(0xdeadbeef);
3912 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3913 ok(ret
, "ReadFile error %d\n", GetLastError());
3914 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3915 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
3917 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3918 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3921 iob
.Information
= -1;
3922 offset
.QuadPart
= 0;
3923 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3924 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3925 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3926 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %lu\n", iob
.Information
);
3927 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
3929 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3930 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3933 iob
.Information
= -1;
3934 offset
.QuadPart
= sizeof(contents
) - 4;
3935 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, "DCBA", 4, &offset
, NULL
);
3936 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
3937 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3938 ok(iob
.Information
== 4, "expected 4, got %lu\n", iob
.Information
);
3940 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3941 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3944 iob
.Information
= -1;
3945 offset
.QuadPart
= 0;
3946 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3947 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3948 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3949 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %lu\n", iob
.Information
);
3950 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
3951 ok(!memcmp(buf
+ sizeof(contents
) - 4, "DCBA", 4), "file contents mismatch\n");
3953 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3954 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3956 S(U(ovl
)).Offset
= sizeof(contents
) - 4;
3957 S(U(ovl
)).OffsetHigh
= 0;
3960 SetLastError(0xdeadbeef);
3961 ret
= WriteFile(hfile
, "ABCD", 4, &bytes
, &ovl
);
3962 ok(ret
, "WriteFile error %d\n", GetLastError());
3963 ok(bytes
== 4, "bytes %u\n", bytes
);
3965 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3966 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3968 S(U(ovl
)).Offset
= 0;
3969 S(U(ovl
)).OffsetHigh
= 0;
3971 ovl
.InternalHigh
= -1;
3974 SetLastError(0xdeadbeef);
3975 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
3976 ok(ret
, "ReadFile error %d\n", GetLastError());
3977 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3978 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
3979 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
3980 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
3981 ok(!memcmp(buf
+ sizeof(contents
) - 4, "ABCD", 4), "file contents mismatch\n");
3983 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3984 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3988 hfile
= create_temp_file(FILE_FLAG_OVERLAPPED
);
3992 SetLastError(0xdeadbeef);
3993 ret
= ReadFile(INVALID_HANDLE_VALUE
, buf
, 0, &bytes
, NULL
);
3994 ok(!ret
, "ReadFile should fail\n");
3995 ok(GetLastError() == ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
3996 ok(bytes
== 0, "bytes %u\n", bytes
);
3998 S(U(ovl
)).Offset
= 0;
3999 S(U(ovl
)).OffsetHigh
= 0;
4001 ovl
.InternalHigh
= -1;
4004 SetLastError(0xdeadbeef);
4005 /* ReadFile return value depends on Windows version and testing it is not practical */
4006 ReadFile(hfile
, buf
, 0, &bytes
, &ovl
);
4007 ok(bytes
== 0, "bytes %u\n", bytes
);
4008 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4009 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
4012 SetLastError(0xdeadbeef);
4013 ret
= WriteFile(hfile
, contents
, sizeof(contents
), &bytes
, NULL
);
4014 ok(!ret
, "WriteFile should fail\n");
4015 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
4016 ok(bytes
== 0, "bytes %u\n", bytes
);
4019 iob
.Information
= -1;
4020 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), NULL
, NULL
);
4021 ok(status
== STATUS_INVALID_PARAMETER
, "expected STATUS_INVALID_PARAMETER, got %#x\n", status
);
4022 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4023 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
4025 for (i
= -20; i
< -1; i
++)
4028 iob
.Information
= -1;
4029 offset
.QuadPart
= (LONGLONG
)i
;
4030 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), &offset
, NULL
);
4031 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
4032 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4033 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
4037 iob
.Information
= -1;
4038 offset
.QuadPart
= 0;
4039 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), &offset
, NULL
);
4040 ok(status
== STATUS_PENDING
|| status
== STATUS_SUCCESS
/* before Vista */, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status
);
4041 if (status
== STATUS_PENDING
)
4043 ret
= WaitForSingleObject(hfile
, 3000);
4044 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4046 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4047 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %lu\n", iob
.Information
);
4049 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4050 ok(off
== 0, "expected 0, got %u\n", off
);
4053 SetLastError(0xdeadbeef);
4054 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
4055 ok(!ret
, "ReadFile should fail\n");
4056 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
4057 ok(bytes
== 0, "bytes %u\n", bytes
);
4060 iob
.Information
= -1;
4061 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), NULL
, NULL
);
4062 ok(status
== STATUS_INVALID_PARAMETER
, "expected STATUS_INVALID_PARAMETER, got %#x\n", status
);
4063 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4064 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
4066 for (i
= -20; i
< 0; i
++)
4069 iob
.Information
= -1;
4070 offset
.QuadPart
= (LONGLONG
)i
;
4071 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4072 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
4073 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4074 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
4077 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4078 ok(off
== 0, "expected 0, got %u\n", off
);
4080 /* test reading beyond EOF */
4081 offset
.QuadPart
= sizeof(contents
);
4082 S(U(ovl
)).Offset
= offset
.u
.LowPart
;
4083 S(U(ovl
)).OffsetHigh
= offset
.u
.HighPart
;
4085 ovl
.InternalHigh
= -1;
4088 SetLastError(0xdeadbeef);
4089 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4090 ok(!ret
, "ReadFile should fail\n");
4091 ret
= GetLastError();
4092 ok(ret
== ERROR_IO_PENDING
|| ret
== ERROR_HANDLE_EOF
/* before Vista */, "expected ERROR_IO_PENDING or ERROR_HANDLE_EOF, got %d\n", ret
);
4093 ok(bytes
== 0, "bytes %u\n", bytes
);
4095 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4096 ok(off
== 0, "expected 0, got %u\n", off
);
4098 if (ret
== ERROR_IO_PENDING
)
4101 SetLastError(0xdeadbeef);
4102 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4103 ok(!ret
, "GetOverlappedResult should report FALSE\n");
4104 ok(GetLastError() == ERROR_HANDLE_EOF
, "expected ERROR_HANDLE_EOF, got %d\n", GetLastError());
4105 ok(bytes
== 0, "expected 0, read %u\n", bytes
);
4106 ok((NTSTATUS
)ovl
.Internal
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", ovl
.Internal
);
4107 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
4110 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4111 ok(off
== 0, "expected 0, got %u\n", off
);
4113 offset
.QuadPart
= sizeof(contents
);
4114 S(U(ovl
)).Offset
= offset
.u
.LowPart
;
4115 S(U(ovl
)).OffsetHigh
= offset
.u
.HighPart
;
4117 ovl
.InternalHigh
= -1;
4120 SetLastError(0xdeadbeef);
4121 ret
= ReadFile(hfile
, buf
, 0, &bytes
, &ovl
);
4122 /* ReadFile return value depends on Windows version and testing it is not practical */
4124 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4125 ret
= GetLastError();
4126 ok(bytes
== 0, "bytes %u\n", bytes
);
4128 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4129 ok(off
== 0, "expected 0, got %u\n", off
);
4131 if (ret
== ERROR_IO_PENDING
)
4134 SetLastError(0xdeadbeef);
4135 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4136 ok(ret
, "GetOverlappedResult should report TRUE\n");
4137 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
4138 ok(bytes
== 0, "expected 0, read %u\n", bytes
);
4139 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4140 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
4143 offset
.QuadPart
= sizeof(contents
);
4144 S(U(ovl
)).Offset
= offset
.u
.LowPart
;
4145 S(U(ovl
)).OffsetHigh
= offset
.u
.HighPart
;
4147 ovl
.InternalHigh
= -1;
4150 SetLastError(0xdeadbeef);
4151 ret
= ReadFile(hfile
, NULL
, 0, &bytes
, &ovl
);
4152 /* ReadFile return value depends on Windows version and testing it is not practical */
4154 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4155 ret
= GetLastError();
4156 ok(bytes
== 0, "bytes %u\n", bytes
);
4158 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4159 ok(off
== 0, "expected 0, got %u\n", off
);
4161 if (ret
== ERROR_IO_PENDING
)
4164 SetLastError(0xdeadbeef);
4165 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4166 ok(ret
, "GetOverlappedResult should report TRUE\n");
4167 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
4168 ok(bytes
== 0, "expected 0, read %u\n", bytes
);
4169 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4170 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
4174 iob
.Information
= -1;
4175 offset
.QuadPart
= sizeof(contents
);
4176 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4177 if (status
== STATUS_PENDING
)
4179 ret
= WaitForSingleObject(hfile
, 3000);
4180 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4181 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
4182 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
4186 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
4187 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4188 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
4191 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4192 ok(off
== 0, "expected 0, got %u\n", off
);
4195 iob
.Information
= -1;
4196 offset
.QuadPart
= sizeof(contents
);
4197 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, &offset
, NULL
);
4198 if (status
== STATUS_PENDING
)
4200 ret
= WaitForSingleObject(hfile
, 3000);
4201 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4202 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4203 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
4207 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", status
);
4208 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4209 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
4212 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4213 ok(off
== 0, "expected 0, got %u\n", off
);
4215 S(U(ovl
)).Offset
= 0;
4216 S(U(ovl
)).OffsetHigh
= 0;
4218 ovl
.InternalHigh
= -1;
4221 SetLastError(0xdeadbeef);
4222 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4223 /* ReadFile return value depends on Windows version and testing it is not practical */
4226 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4227 ok(bytes
== 0, "bytes %u\n", bytes
);
4229 else ok(bytes
== 14, "bytes %u\n", bytes
);
4230 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4231 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4233 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4234 ok(off
== 0, "expected 0, got %u\n", off
);
4237 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4238 ok(ret
, "GetOverlappedResult error %d\n", GetLastError());
4239 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
4240 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4241 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4242 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
4244 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4245 ok(off
== 0, "expected 0, got %u\n", off
);
4247 SetFilePointer(hfile
, sizeof(contents
) - 4, NULL
, FILE_BEGIN
);
4248 SetEndOfFile(hfile
);
4249 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
4252 iob
.Information
= -1;
4253 offset
.QuadPart
= (LONGLONG
)-1 /* FILE_WRITE_TO_END_OF_FILE */;
4254 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, "DCBA", 4, &offset
, NULL
);
4255 ok(status
== STATUS_PENDING
|| status
== STATUS_SUCCESS
/* before Vista */, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status
);
4256 if (status
== STATUS_PENDING
)
4258 ret
= WaitForSingleObject(hfile
, 3000);
4259 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4261 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4262 ok(iob
.Information
== 4, "expected 4, got %lu\n", iob
.Information
);
4264 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4265 ok(off
== 0, "expected 0, got %u\n", off
);
4268 iob
.Information
= -1;
4269 offset
.QuadPart
= 0;
4270 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4271 ok(status
== STATUS_PENDING
|| status
== STATUS_SUCCESS
, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status
);
4272 if (status
== STATUS_PENDING
)
4274 ret
= WaitForSingleObject(hfile
, 3000);
4275 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4277 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4278 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %lu\n", iob
.Information
);
4280 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4281 ok(off
== 0, "expected 0, got %u\n", off
);
4283 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
4284 ok(!memcmp(buf
+ sizeof(contents
) - 4, "DCBA", 4), "file contents mismatch\n");
4286 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4287 ok(off
== 0, "expected 0, got %u\n", off
);
4289 S(U(ovl
)).Offset
= sizeof(contents
) - 4;
4290 S(U(ovl
)).OffsetHigh
= 0;
4292 ovl
.InternalHigh
= -1;
4295 SetLastError(0xdeadbeef);
4296 ret
= WriteFile(hfile
, "ABCD", 4, &bytes
, &ovl
);
4297 /* WriteFile return value depends on Windows version and testing it is not practical */
4300 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4301 ok(bytes
== 0, "bytes %u\n", bytes
);
4302 ret
= WaitForSingleObject(hfile
, 3000);
4303 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4305 else ok(bytes
== 4, "bytes %u\n", bytes
);
4306 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4307 ok(ovl
.InternalHigh
== 4, "expected 4, got %lu\n", ovl
.InternalHigh
);
4309 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4310 ok(off
== 0, "expected 0, got %u\n", off
);
4313 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4314 ok(ret
, "GetOverlappedResult error %d\n", GetLastError());
4315 ok(bytes
== 4, "bytes %u\n", bytes
);
4316 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4317 ok(ovl
.InternalHigh
== 4, "expected 4, got %lu\n", ovl
.InternalHigh
);
4319 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4320 ok(off
== 0, "expected 0, got %u\n", off
);
4322 S(U(ovl
)).Offset
= 0;
4323 S(U(ovl
)).OffsetHigh
= 0;
4325 ovl
.InternalHigh
= -1;
4328 SetLastError(0xdeadbeef);
4329 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4330 /* ReadFile return value depends on Windows version and testing it is not practical */
4333 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4334 ok(bytes
== 0, "bytes %u\n", bytes
);
4335 ret
= WaitForSingleObject(hfile
, 3000);
4336 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4338 else ok(bytes
== 14, "bytes %u\n", bytes
);
4339 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4340 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4342 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4343 ok(off
== 0, "expected 0, got %u\n", off
);
4346 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4347 ok(ret
, "GetOverlappedResult error %d\n", GetLastError());
4348 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
4349 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4350 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4351 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
4352 ok(!memcmp(buf
+ sizeof(contents
) - 4, "ABCD", 4), "file contents mismatch\n");
4354 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4355 ok(off
== 0, "expected 0, got %u\n", off
);
4360 static void test_query_ea(void)
4362 #define EA_BUFFER_SIZE 4097
4363 unsigned char data
[EA_BUFFER_SIZE
+ 8];
4364 unsigned char *buffer
= (void *)(((DWORD_PTR
)data
+ 7) & ~7);
4365 DWORD buffer_len
, i
;
4370 if (!(handle
= create_temp_file(0))) return;
4372 /* test with INVALID_HANDLE_VALUE */
4373 U(io
).Status
= 0xdeadbeef;
4374 io
.Information
= 0xdeadbeef;
4375 memset(buffer
, 0xcc, EA_BUFFER_SIZE
);
4376 buffer_len
= EA_BUFFER_SIZE
- 1;
4377 status
= pNtQueryEaFile(INVALID_HANDLE_VALUE
, &io
, buffer
, buffer_len
, TRUE
, NULL
, 0, NULL
, FALSE
);
4378 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %x\n", status
);
4379 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io
).Status
);
4380 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io
.Information
);
4381 ok(buffer
[0] == 0xcc, "data at position 0 overwritten\n");
4383 /* test with 0xdeadbeef */
4384 U(io
).Status
= 0xdeadbeef;
4385 io
.Information
= 0xdeadbeef;
4386 memset(buffer
, 0xcc, EA_BUFFER_SIZE
);
4387 buffer_len
= EA_BUFFER_SIZE
- 1;
4388 status
= pNtQueryEaFile((void *)0xdeadbeef, &io
, buffer
, buffer_len
, TRUE
, NULL
, 0, NULL
, FALSE
);
4389 ok(status
== STATUS_INVALID_HANDLE
, "expected STATUS_INVALID_HANDLE, got %x\n", status
);
4390 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io
).Status
);
4391 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io
.Information
);
4392 ok(buffer
[0] == 0xcc, "data at position 0 overwritten\n");
4394 /* test without buffer */
4395 U(io
).Status
= 0xdeadbeef;
4396 io
.Information
= 0xdeadbeef;
4397 status
= pNtQueryEaFile(handle
, &io
, NULL
, 0, TRUE
, NULL
, 0, NULL
, FALSE
);
4398 ok(status
== STATUS_NO_EAS_ON_FILE
, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status
);
4399 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io
).Status
);
4400 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io
.Information
);
4402 /* test with zero buffer */
4403 U(io
).Status
= 0xdeadbeef;
4404 io
.Information
= 0xdeadbeef;
4405 status
= pNtQueryEaFile(handle
, &io
, buffer
, 0, TRUE
, NULL
, 0, NULL
, FALSE
);
4406 ok(status
== STATUS_NO_EAS_ON_FILE
, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status
);
4407 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io
).Status
);
4408 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io
.Information
);
4410 /* test with very small buffer */
4411 U(io
).Status
= 0xdeadbeef;
4412 io
.Information
= 0xdeadbeef;
4413 memset(buffer
, 0xcc, EA_BUFFER_SIZE
);
4415 status
= pNtQueryEaFile(handle
, &io
, buffer
, buffer_len
, TRUE
, NULL
, 0, NULL
, FALSE
);
4416 ok(status
== STATUS_NO_EAS_ON_FILE
, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status
);
4417 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io
).Status
);
4418 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io
.Information
);
4419 for (i
= 0; i
< buffer_len
&& !buffer
[i
]; i
++);
4420 ok(i
== buffer_len
, "expected %u bytes filled with 0x00, got %u bytes\n", buffer_len
, i
);
4421 ok(buffer
[i
] == 0xcc, "data at position %u overwritten\n", buffer
[i
]);
4423 /* test with very big buffer */
4424 U(io
).Status
= 0xdeadbeef;
4425 io
.Information
= 0xdeadbeef;
4426 memset(buffer
, 0xcc, EA_BUFFER_SIZE
);
4427 buffer_len
= EA_BUFFER_SIZE
- 1;
4428 status
= pNtQueryEaFile(handle
, &io
, buffer
, buffer_len
, TRUE
, NULL
, 0, NULL
, FALSE
);
4429 ok(status
== STATUS_NO_EAS_ON_FILE
, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status
);
4430 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io
).Status
);
4431 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io
.Information
);
4432 for (i
= 0; i
< buffer_len
&& !buffer
[i
]; i
++);
4433 ok(i
== buffer_len
, "expected %u bytes filled with 0x00, got %u bytes\n", buffer_len
, i
);
4434 ok(buffer
[i
] == 0xcc, "data at position %u overwritten\n", buffer
[i
]);
4436 CloseHandle(handle
);
4437 #undef EA_BUFFER_SIZE
4440 static INT
build_reparse_buffer(WCHAR
*filename
, REPARSE_DATA_BUFFER
**pbuffer
)
4442 REPARSE_DATA_BUFFER
*buffer
;
4443 INT buffer_len
, string_len
;
4446 string_len
= (lstrlenW(filename
)+1)*sizeof(WCHAR
);
4447 buffer_len
= FIELD_OFFSET(REPARSE_DATA_BUFFER
, MountPointReparseBuffer
.PathBuffer
[1]) + string_len
;
4448 buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, buffer_len
);
4449 buffer
->ReparseTag
= IO_REPARSE_TAG_MOUNT_POINT
;
4450 buffer
->ReparseDataLength
= sizeof(buffer
->MountPointReparseBuffer
) + string_len
;
4451 buffer
->MountPointReparseBuffer
.SubstituteNameLength
= string_len
- sizeof(WCHAR
);
4452 buffer
->MountPointReparseBuffer
.PrintNameOffset
= string_len
;
4453 dest
= &buffer
->MountPointReparseBuffer
.PathBuffer
[0];
4454 memcpy(dest
, filename
, string_len
);
4459 static void test_junction_points(void)
4461 static const WCHAR junctionW
[] = {'\\','j','u','n','c','t','i','o','n',0};
4462 WCHAR path
[MAX_PATH
], junction_path
[MAX_PATH
], target_path
[MAX_PATH
];
4463 static const WCHAR targetW
[] = {'\\','t','a','r','g','e','t',0};
4464 FILE_BASIC_INFORMATION old_attrib
, new_attrib
;
4465 static const WCHAR fooW
[] = {'f','o','o',0};
4466 static WCHAR volW
[] = {'c',':','\\',0};
4467 REPARSE_GUID_DATA_BUFFER guid_buffer
;
4468 static const WCHAR dotW
[] = {'.',0};
4469 REPARSE_DATA_BUFFER
*buffer
= NULL
;
4470 DWORD dwret
, dwLen
, dwFlags
, err
;
4471 INT buffer_len
, string_len
;
4472 IO_STATUS_BLOCK iosb
;
4473 UNICODE_STRING nameW
;
4478 /* Create a temporary folder for the junction point tests */
4479 GetTempFileNameW(dotW
, fooW
, 0, path
);
4481 if (!CreateDirectoryW(path
, NULL
))
4483 win_skip("Unable to create a temporary junction point directory.\n");
4487 /* Check that the volume this folder is located on supports junction points */
4488 pRtlDosPathNameToNtPathName_U(path
, &nameW
, NULL
, NULL
);
4489 volW
[0] = nameW
.Buffer
[4];
4490 pRtlFreeUnicodeString( &nameW
);
4491 GetVolumeInformationW(volW
, 0, 0, 0, &dwLen
, &dwFlags
, 0, 0);
4492 if (!(dwFlags
& FILE_SUPPORTS_REPARSE_POINTS
))
4494 skip("File system does not support junction points.\n");
4495 RemoveDirectoryW(path
);
4499 /* Create the folder to be replaced by a junction point */
4500 lstrcpyW(junction_path
, path
);
4501 lstrcatW(junction_path
, junctionW
);
4502 bret
= CreateDirectoryW(junction_path
, NULL
);
4503 ok(bret
, "Failed to create junction point directory.\n");
4505 /* Create a destination folder for the junction point to target */
4506 lstrcpyW(target_path
, path
);
4507 lstrcatW(target_path
, targetW
);
4508 bret
= CreateDirectoryW(target_path
, NULL
);
4509 ok(bret
, "Failed to create junction point target directory.\n");
4510 pRtlDosPathNameToNtPathName_U(target_path
, &nameW
, NULL
, NULL
);
4512 /* Create the junction point */
4513 hJunction
= CreateFileW(junction_path
, GENERIC_READ
| GENERIC_WRITE
, 0, 0, OPEN_EXISTING
,
4514 FILE_FLAG_BACKUP_SEMANTICS
| FILE_FLAG_OPEN_REPARSE_POINT
, 0);
4515 if (hJunction
== INVALID_HANDLE_VALUE
)
4517 win_skip("Failed to open junction point directory handle (0x%x).\n", GetLastError());
4520 dwret
= NtQueryInformationFile(hJunction
, &iosb
, &old_attrib
, sizeof(old_attrib
), FileBasicInformation
);
4521 ok(dwret
== STATUS_SUCCESS
, "Failed to get junction point folder's attributes (0x%x).\n", dwret
);
4522 buffer_len
= build_reparse_buffer(nameW
.Buffer
, &buffer
);
4523 bret
= DeviceIoControl(hJunction
, FSCTL_SET_REPARSE_POINT
, (LPVOID
)buffer
, buffer_len
, NULL
, 0, &dwret
, 0);
4524 ok(bret
, "Failed to create junction point! (0x%x)\n", GetLastError());
4526 /* Check the file attributes of the junction point */
4527 dwret
= GetFileAttributesW(junction_path
);
4528 ok(dwret
!= (DWORD
)~0, "Junction point doesn't exist (attributes: 0x%x)!\n", dwret
);
4529 ok(dwret
& FILE_ATTRIBUTE_REPARSE_POINT
, "File is not a junction point! (attributes: %d)\n", dwret
);
4531 /* Read back the junction point */
4532 HeapFree(GetProcessHeap(), 0, buffer
);
4533 buffer_len
= sizeof(*buffer
) + MAX_PATH
*sizeof(WCHAR
);
4534 buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, buffer_len
);
4535 bret
= DeviceIoControl(hJunction
, FSCTL_GET_REPARSE_POINT
, NULL
, 0, (LPVOID
)buffer
, buffer_len
, &dwret
, 0);
4536 string_len
= buffer
->MountPointReparseBuffer
.SubstituteNameLength
;
4537 dest
= &buffer
->MountPointReparseBuffer
.PathBuffer
[buffer
->MountPointReparseBuffer
.SubstituteNameOffset
/sizeof(WCHAR
)];
4538 ok(bret
, "Failed to read junction point!\n");
4539 ok((memcmp(dest
, nameW
.Buffer
, string_len
) == 0), "Junction point destination does not match ('%s' != '%s')!\n",
4540 wine_dbgstr_w(dest
), wine_dbgstr_w(nameW
.Buffer
));
4542 /* Delete the junction point */
4543 memset(&old_attrib
, 0x00, sizeof(old_attrib
));
4544 old_attrib
.LastAccessTime
.QuadPart
= 0x200deadcafebeef;
4545 dwret
= NtSetInformationFile(hJunction
, &iosb
, &old_attrib
, sizeof(old_attrib
), FileBasicInformation
);
4546 ok(dwret
== STATUS_SUCCESS
, "Failed to set junction point folder's attributes (0x%x).\n", dwret
);
4547 memset(&guid_buffer
, 0x00, sizeof(guid_buffer
));
4548 guid_buffer
.ReparseTag
= IO_REPARSE_TAG_MOUNT_POINT
;
4549 bret
= DeviceIoControl(hJunction
, FSCTL_DELETE_REPARSE_POINT
, (LPVOID
)&guid_buffer
,
4550 REPARSE_GUID_DATA_BUFFER_HEADER_SIZE
, NULL
, 0, &dwret
, 0);
4551 ok(bret
, "Failed to delete junction point! (0x%x)\n", GetLastError());
4552 memset(&new_attrib
, 0x00, sizeof(new_attrib
));
4553 dwret
= NtQueryInformationFile(hJunction
, &iosb
, &new_attrib
, sizeof(new_attrib
), FileBasicInformation
);
4554 ok(dwret
== STATUS_SUCCESS
, "Failed to get junction point folder's attributes (0x%x).\n", dwret
);
4555 ok(old_attrib
.LastAccessTime
.QuadPart
== new_attrib
.LastAccessTime
.QuadPart
,
4556 "Junction point folder's access time does not match (0x%llx != 0x%llx).\n",
4557 new_attrib
.LastAccessTime
.QuadPart
, old_attrib
.LastAccessTime
.QuadPart
);
4558 CloseHandle(hJunction
);
4560 /* Check deleting a junction point as if it were a directory */
4561 HeapFree(GetProcessHeap(), 0, buffer
);
4562 hJunction
= CreateFileW(junction_path
, GENERIC_READ
| GENERIC_WRITE
, 0, 0, OPEN_EXISTING
,
4563 FILE_FLAG_BACKUP_SEMANTICS
| FILE_FLAG_OPEN_REPARSE_POINT
, 0);
4564 buffer_len
= build_reparse_buffer(nameW
.Buffer
, &buffer
);
4565 bret
= DeviceIoControl(hJunction
, FSCTL_SET_REPARSE_POINT
, (LPVOID
)buffer
, buffer_len
, NULL
, 0, &dwret
, 0);
4566 ok(bret
, "Failed to create junction point! (0x%x)\n", GetLastError());
4567 CloseHandle(hJunction
);
4568 bret
= RemoveDirectoryW(junction_path
);
4569 ok(bret
, "Failed to delete junction point as directory!\n");
4570 dwret
= GetFileAttributesW(junction_path
);
4571 ok(dwret
== (DWORD
)~0, "Junction point still exists (attributes: 0x%x)!\n", dwret
);
4573 /* Check deleting a junction point as if it were a file */
4574 HeapFree(GetProcessHeap(), 0, buffer
);
4575 bret
= CreateDirectoryW(junction_path
, NULL
);
4576 ok(bret
, "Failed to create junction point target directory.\n");
4577 hJunction
= CreateFileW(junction_path
, GENERIC_READ
| GENERIC_WRITE
, 0, 0, OPEN_EXISTING
,
4578 FILE_FLAG_BACKUP_SEMANTICS
| FILE_FLAG_OPEN_REPARSE_POINT
, 0);
4579 buffer_len
= build_reparse_buffer(nameW
.Buffer
, &buffer
);
4580 bret
= DeviceIoControl(hJunction
, FSCTL_SET_REPARSE_POINT
, (LPVOID
)buffer
, buffer_len
, NULL
, 0, &dwret
, 0);
4581 ok(bret
, "Failed to create junction point! (0x%x)\n", GetLastError());
4582 CloseHandle(hJunction
);
4583 bret
= DeleteFileW(junction_path
);
4584 ok(!bret
, "Succeeded in deleting junction point as file!\n");
4585 err
= GetLastError();
4586 ok(err
== ERROR_ACCESS_DENIED
, "Expected last error 0x%x for DeleteFile on junction point (actually 0x%x)!\n",
4587 ERROR_ACCESS_DENIED
, err
);
4588 dwret
= GetFileAttributesW(junction_path
);
4589 ok(dwret
!= (DWORD
)~0, "Junction point doesn't exist (attributes: 0x%x)!\n", dwret
);
4590 ok(dwret
& FILE_ATTRIBUTE_REPARSE_POINT
, "File is not a junction point! (attributes: 0x%x)\n", dwret
);
4592 /* Test deleting a junction point's target */
4593 dwret
= GetFileAttributesW(junction_path
);
4594 ok(dwret
== 0x410 || broken(dwret
== 0x430) /* win2k */,
4595 "Unexpected junction point attributes (0x%x != 0x410)!\n", dwret
);
4596 bret
= RemoveDirectoryW(target_path
);
4597 ok(bret
, "Failed to delete junction point target!\n");
4598 bret
= CreateDirectoryW(target_path
, NULL
);
4599 ok(bret
, "Failed to create junction point target directory.\n");
4603 pRtlFreeUnicodeString( &nameW
);
4604 HeapFree(GetProcessHeap(), 0, buffer
);
4605 bret
= RemoveDirectoryW(junction_path
);
4606 ok(bret
, "Failed to remove temporary junction point directory!\n");
4607 bret
= RemoveDirectoryW(target_path
);
4608 ok(bret
, "Failed to remove temporary target directory!\n");
4609 RemoveDirectoryW(path
);
4614 HMODULE hkernel32
= GetModuleHandleA("kernel32.dll");
4615 HMODULE hntdll
= GetModuleHandleA("ntdll.dll");
4618 skip("not running on NT, skipping test\n");
4622 pGetVolumePathNameW
= (void *)GetProcAddress(hkernel32
, "GetVolumePathNameW");
4623 pGetSystemWow64DirectoryW
= (void *)GetProcAddress(hkernel32
, "GetSystemWow64DirectoryW");
4625 pRtlFreeUnicodeString
= (void *)GetProcAddress(hntdll
, "RtlFreeUnicodeString");
4626 pRtlInitUnicodeString
= (void *)GetProcAddress(hntdll
, "RtlInitUnicodeString");
4627 pRtlDosPathNameToNtPathName_U
= (void *)GetProcAddress(hntdll
, "RtlDosPathNameToNtPathName_U");
4628 pRtlWow64EnableFsRedirectionEx
= (void *)GetProcAddress(hntdll
, "RtlWow64EnableFsRedirectionEx");
4629 pNtCreateMailslotFile
= (void *)GetProcAddress(hntdll
, "NtCreateMailslotFile");
4630 pNtCreateFile
= (void *)GetProcAddress(hntdll
, "NtCreateFile");
4631 pNtOpenFile
= (void *)GetProcAddress(hntdll
, "NtOpenFile");
4632 pNtDeleteFile
= (void *)GetProcAddress(hntdll
, "NtDeleteFile");
4633 pNtReadFile
= (void *)GetProcAddress(hntdll
, "NtReadFile");
4634 pNtWriteFile
= (void *)GetProcAddress(hntdll
, "NtWriteFile");
4635 pNtCancelIoFile
= (void *)GetProcAddress(hntdll
, "NtCancelIoFile");
4636 pNtCancelIoFileEx
= (void *)GetProcAddress(hntdll
, "NtCancelIoFileEx");
4637 pNtClose
= (void *)GetProcAddress(hntdll
, "NtClose");
4638 pNtCreateIoCompletion
= (void *)GetProcAddress(hntdll
, "NtCreateIoCompletion");
4639 pNtOpenIoCompletion
= (void *)GetProcAddress(hntdll
, "NtOpenIoCompletion");
4640 pNtQueryIoCompletion
= (void *)GetProcAddress(hntdll
, "NtQueryIoCompletion");
4641 pNtRemoveIoCompletion
= (void *)GetProcAddress(hntdll
, "NtRemoveIoCompletion");
4642 pNtSetIoCompletion
= (void *)GetProcAddress(hntdll
, "NtSetIoCompletion");
4643 pNtSetInformationFile
= (void *)GetProcAddress(hntdll
, "NtSetInformationFile");
4644 pNtQueryInformationFile
= (void *)GetProcAddress(hntdll
, "NtQueryInformationFile");
4645 pNtQueryDirectoryFile
= (void *)GetProcAddress(hntdll
, "NtQueryDirectoryFile");
4646 pNtQueryVolumeInformationFile
= (void *)GetProcAddress(hntdll
, "NtQueryVolumeInformationFile");
4647 pNtQueryFullAttributesFile
= (void *)GetProcAddress(hntdll
, "NtQueryFullAttributesFile");
4648 pNtQueryEaFile
= (void *)GetProcAddress(hntdll
, "NtQueryEaFile");
4651 test_NtCreateFile();
4659 test_iocompletion();
4660 test_file_basic_information();
4661 test_file_all_information();
4662 test_file_both_information();
4663 test_file_name_information();
4664 test_file_full_size_information();
4665 test_file_all_name_information();
4666 test_file_rename_information();
4667 test_file_link_information();
4668 test_file_disposition_information();
4669 test_query_volume_information_file();
4670 test_query_attribute_information_file();
4672 test_junction_points();