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"
42 #ifndef IO_COMPLETION_ALL_ACCESS
43 #define IO_COMPLETION_ALL_ACCESS 0x001F0003
46 static BOOL (WINAPI
* pGetVolumePathNameW
)(LPCWSTR
, LPWSTR
, DWORD
);
47 static UINT (WINAPI
*pGetSystemWow64DirectoryW
)( LPWSTR
, UINT
);
49 static VOID (WINAPI
*pRtlFreeUnicodeString
)( PUNICODE_STRING
);
50 static VOID (WINAPI
*pRtlInitUnicodeString
)( PUNICODE_STRING
, LPCWSTR
);
51 static BOOL (WINAPI
*pRtlDosPathNameToNtPathName_U
)( LPCWSTR
, PUNICODE_STRING
, PWSTR
*, CURDIR
* );
52 static NTSTATUS (WINAPI
*pRtlWow64EnableFsRedirectionEx
)( ULONG
, ULONG
* );
54 static NTSTATUS (WINAPI
*pNtCreateMailslotFile
)( PHANDLE
, ULONG
, POBJECT_ATTRIBUTES
, PIO_STATUS_BLOCK
,
55 ULONG
, ULONG
, ULONG
, PLARGE_INTEGER
);
56 static NTSTATUS (WINAPI
*pNtCreateFile
)(PHANDLE
,ACCESS_MASK
,POBJECT_ATTRIBUTES
,PIO_STATUS_BLOCK
,PLARGE_INTEGER
,ULONG
,ULONG
,ULONG
,ULONG
,PVOID
,ULONG
);
57 static NTSTATUS (WINAPI
*pNtOpenFile
)(PHANDLE
,ACCESS_MASK
,POBJECT_ATTRIBUTES
,PIO_STATUS_BLOCK
,ULONG
,ULONG
);
58 static NTSTATUS (WINAPI
*pNtDeleteFile
)(POBJECT_ATTRIBUTES ObjectAttributes
);
59 static NTSTATUS (WINAPI
*pNtReadFile
)(HANDLE hFile
, HANDLE hEvent
,
60 PIO_APC_ROUTINE apc
, void* apc_user
,
61 PIO_STATUS_BLOCK io_status
, void* buffer
, ULONG length
,
62 PLARGE_INTEGER offset
, PULONG key
);
63 static NTSTATUS (WINAPI
*pNtWriteFile
)(HANDLE hFile
, HANDLE hEvent
,
64 PIO_APC_ROUTINE apc
, void* apc_user
,
65 PIO_STATUS_BLOCK io_status
,
66 const void* buffer
, ULONG length
,
67 PLARGE_INTEGER offset
, PULONG key
);
68 static NTSTATUS (WINAPI
*pNtCancelIoFile
)(HANDLE hFile
, PIO_STATUS_BLOCK io_status
);
69 static NTSTATUS (WINAPI
*pNtCancelIoFileEx
)(HANDLE hFile
, PIO_STATUS_BLOCK iosb
, PIO_STATUS_BLOCK io_status
);
70 static NTSTATUS (WINAPI
*pNtClose
)( PHANDLE
);
71 static NTSTATUS (WINAPI
*pNtFsControlFile
) (HANDLE handle
, HANDLE event
, PIO_APC_ROUTINE apc
, PVOID apc_context
, PIO_STATUS_BLOCK io
, ULONG code
, PVOID in_buffer
, ULONG in_size
, PVOID out_buffer
, ULONG out_size
);
73 static NTSTATUS (WINAPI
*pNtCreateIoCompletion
)(PHANDLE
, ACCESS_MASK
, POBJECT_ATTRIBUTES
, ULONG
);
74 static NTSTATUS (WINAPI
*pNtOpenIoCompletion
)(PHANDLE
, ACCESS_MASK
, POBJECT_ATTRIBUTES
);
75 static NTSTATUS (WINAPI
*pNtQueryIoCompletion
)(HANDLE
, IO_COMPLETION_INFORMATION_CLASS
, PVOID
, ULONG
, PULONG
);
76 static NTSTATUS (WINAPI
*pNtRemoveIoCompletion
)(HANDLE
, PULONG_PTR
, PULONG_PTR
, PIO_STATUS_BLOCK
, PLARGE_INTEGER
);
77 static NTSTATUS (WINAPI
*pNtRemoveIoCompletionEx
)(HANDLE
,FILE_IO_COMPLETION_INFORMATION
*,ULONG
,ULONG
*,LARGE_INTEGER
*,BOOLEAN
);
78 static NTSTATUS (WINAPI
*pNtSetIoCompletion
)(HANDLE
, ULONG_PTR
, ULONG_PTR
, NTSTATUS
, SIZE_T
);
79 static NTSTATUS (WINAPI
*pNtSetInformationFile
)(HANDLE
, PIO_STATUS_BLOCK
, PVOID
, ULONG
, FILE_INFORMATION_CLASS
);
80 static NTSTATUS (WINAPI
*pNtQueryAttributesFile
)(const OBJECT_ATTRIBUTES
*,FILE_BASIC_INFORMATION
*);
81 static NTSTATUS (WINAPI
*pNtQueryInformationFile
)(HANDLE
, PIO_STATUS_BLOCK
, PVOID
, ULONG
, FILE_INFORMATION_CLASS
);
82 static NTSTATUS (WINAPI
*pNtQueryDirectoryFile
)(HANDLE
,HANDLE
,PIO_APC_ROUTINE
,PVOID
,PIO_STATUS_BLOCK
,
83 PVOID
,ULONG
,FILE_INFORMATION_CLASS
,BOOLEAN
,PUNICODE_STRING
,BOOLEAN
);
84 static NTSTATUS (WINAPI
*pNtQueryVolumeInformationFile
)(HANDLE
,PIO_STATUS_BLOCK
,PVOID
,ULONG
,FS_INFORMATION_CLASS
);
85 static NTSTATUS (WINAPI
*pNtQueryFullAttributesFile
)(const OBJECT_ATTRIBUTES
*, FILE_NETWORK_OPEN_INFORMATION
*);
86 static NTSTATUS (WINAPI
*pNtFlushBuffersFile
)(HANDLE
, IO_STATUS_BLOCK
*);
87 static NTSTATUS (WINAPI
*pNtQueryEaFile
)(HANDLE
,PIO_STATUS_BLOCK
,PVOID
,ULONG
,BOOLEAN
,PVOID
,ULONG
,PULONG
,BOOLEAN
);
89 static WCHAR fooW
[] = {'f','o','o',0};
91 static inline BOOL
is_signaled( HANDLE obj
)
93 return WaitForSingleObject( obj
, 0 ) == WAIT_OBJECT_0
;
96 #define TEST_BUF_LEN 3
98 static HANDLE
create_temp_file( ULONG flags
)
100 char path
[MAX_PATH
], buffer
[MAX_PATH
];
103 GetTempPathA( MAX_PATH
, path
);
104 GetTempFileNameA( path
, "foo", 0, buffer
);
105 handle
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
106 flags
| FILE_FLAG_DELETE_ON_CLOSE
, 0);
107 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
108 return (handle
== INVALID_HANDLE_VALUE
) ? 0 : handle
;
111 #define CVALUE_FIRST 0xfffabbcc
112 #define CKEY_FIRST 0x1030341
113 #define CKEY_SECOND 0x132E46
115 static ULONG
get_pending_msgs(HANDLE h
)
120 res
= pNtQueryIoCompletion( h
, IoCompletionBasicInformation
, &a
, sizeof(a
), &req
);
121 ok( res
== STATUS_SUCCESS
, "NtQueryIoCompletion failed: %lx\n", res
);
122 if (res
!= STATUS_SUCCESS
) return -1;
123 ok( req
== sizeof(a
), "Unexpected response size: %lx\n", req
);
127 static void WINAPI
apc( void *arg
, IO_STATUS_BLOCK
*iosb
, ULONG reserved
)
131 trace( "apc called block %p iosb.status %lx iosb.info %Iu\n",
132 iosb
, U(*iosb
).Status
, iosb
->Information
);
134 ok( !reserved
, "reserved is not 0: %lx\n", reserved
);
137 static void create_file_test(void)
139 static const WCHAR systemrootW
[] = {'\\','S','y','s','t','e','m','R','o','o','t',
140 '\\','f','a','i','l','i','n','g',0};
141 static const WCHAR questionmarkInvalidNameW
[] = {'a','f','i','l','e','?',0};
142 static const WCHAR pipeInvalidNameW
[] = {'a','|','b',0};
143 static const WCHAR pathInvalidNtW
[] = {'\\','\\','?','\\',0};
144 static const WCHAR pathInvalidNt2W
[] = {'\\','?','?','\\',0};
145 static const WCHAR pathInvalidDosW
[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0};
146 static const char testdata
[] = "Hello World";
147 FILE_NETWORK_OPEN_INFORMATION info
;
150 WCHAR path
[MAX_PATH
];
151 OBJECT_ATTRIBUTES attr
;
153 UNICODE_STRING nameW
;
154 LARGE_INTEGER offset
;
158 GetCurrentDirectoryW( MAX_PATH
, path
);
159 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
160 attr
.Length
= sizeof(attr
);
161 attr
.RootDirectory
= 0;
162 attr
.ObjectName
= &nameW
;
163 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
164 attr
.SecurityDescriptor
= NULL
;
165 attr
.SecurityQualityOfService
= NULL
;
167 /* try various open modes and options on directories */
168 status
= pNtCreateFile( &dir
, GENERIC_READ
|GENERIC_WRITE
, &attr
, &io
, NULL
, 0,
169 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, FILE_DIRECTORY_FILE
, NULL
, 0 );
170 ok( !status
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
172 U(io
).Status
= 0xdeadbeef;
174 status
= pNtReadFile( dir
, NULL
, NULL
, NULL
, &io
, buf
, sizeof(buf
), &offset
, NULL
);
175 ok( status
== STATUS_INVALID_DEVICE_REQUEST
|| status
== STATUS_PENDING
, "NtReadFile error %08lx\n", status
);
176 if (status
== STATUS_PENDING
)
178 ret
= WaitForSingleObject( dir
, 1000 );
179 ok( ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %lu\n", ret
);
180 ok( U(io
).Status
== STATUS_INVALID_DEVICE_REQUEST
,
181 "expected STATUS_INVALID_DEVICE_REQUEST, got %08lx\n", U(io
).Status
);
184 U(io
).Status
= 0xdeadbeef;
186 status
= pNtWriteFile( dir
, NULL
, NULL
, NULL
, &io
, testdata
, sizeof(testdata
), &offset
, NULL
);
188 ok( status
== STATUS_INVALID_DEVICE_REQUEST
|| status
== STATUS_PENDING
, "NtWriteFile error %08lx\n", status
);
189 if (status
== STATUS_PENDING
)
191 ret
= WaitForSingleObject( dir
, 1000 );
192 ok( ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %lu\n", ret
);
193 ok( U(io
).Status
== STATUS_INVALID_DEVICE_REQUEST
,
194 "expected STATUS_INVALID_DEVICE_REQUEST, got %08lx\n", U(io
).Status
);
199 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
200 FILE_CREATE
, FILE_DIRECTORY_FILE
, NULL
, 0 );
201 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
202 "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
204 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
205 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, NULL
, 0 );
206 ok( !status
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
209 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
210 FILE_SUPERSEDE
, FILE_DIRECTORY_FILE
, NULL
, 0 );
211 ok( status
== STATUS_INVALID_PARAMETER
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
213 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
214 FILE_OVERWRITE
, FILE_DIRECTORY_FILE
, NULL
, 0 );
215 ok( status
== STATUS_INVALID_PARAMETER
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
217 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
218 FILE_OVERWRITE_IF
, FILE_DIRECTORY_FILE
, NULL
, 0 );
219 ok( status
== STATUS_INVALID_PARAMETER
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
221 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
222 FILE_OPEN
, 0, NULL
, 0 );
223 ok( !status
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
226 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
227 FILE_CREATE
, 0, NULL
, 0 );
228 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
229 "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
231 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
232 FILE_OPEN_IF
, 0, NULL
, 0 );
233 ok( !status
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
236 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
237 FILE_SUPERSEDE
, 0, NULL
, 0 );
238 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
239 "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
241 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
242 FILE_OVERWRITE
, 0, NULL
, 0 );
243 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
244 "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
246 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
247 FILE_OVERWRITE_IF
, 0, NULL
, 0 );
248 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
249 "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
251 pRtlFreeUnicodeString( &nameW
);
253 pRtlInitUnicodeString( &nameW
, systemrootW
);
254 attr
.Length
= sizeof(attr
);
255 attr
.RootDirectory
= NULL
;
256 attr
.ObjectName
= &nameW
;
257 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
258 attr
.SecurityDescriptor
= NULL
;
259 attr
.SecurityQualityOfService
= NULL
;
261 status
= pNtCreateFile( &dir
, FILE_APPEND_DATA
, &attr
, &io
, NULL
, FILE_ATTRIBUTE_NORMAL
, 0,
262 FILE_OPEN_IF
, FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
264 ok( status
== STATUS_INVALID_PARAMETER
,
265 "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
267 /* Invalid chars in file/dirnames */
268 pRtlDosPathNameToNtPathName_U(questionmarkInvalidNameW
, &nameW
, NULL
, NULL
);
269 attr
.ObjectName
= &nameW
;
270 status
= pNtCreateFile(&dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
271 FILE_SHARE_READ
, FILE_CREATE
,
272 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
273 ok(status
== STATUS_OBJECT_NAME_INVALID
,
274 "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
276 status
= pNtCreateFile(&file
, GENERIC_WRITE
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
278 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
279 ok(status
== STATUS_OBJECT_NAME_INVALID
,
280 "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
281 pRtlFreeUnicodeString(&nameW
);
283 pRtlDosPathNameToNtPathName_U(pipeInvalidNameW
, &nameW
, NULL
, NULL
);
284 attr
.ObjectName
= &nameW
;
285 status
= pNtCreateFile(&dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
286 FILE_SHARE_READ
, FILE_CREATE
,
287 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
288 ok(status
== STATUS_OBJECT_NAME_INVALID
,
289 "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
291 status
= pNtCreateFile(&file
, GENERIC_WRITE
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
293 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
294 ok(status
== STATUS_OBJECT_NAME_INVALID
,
295 "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
296 pRtlFreeUnicodeString(&nameW
);
298 pRtlInitUnicodeString( &nameW
, pathInvalidNtW
);
299 status
= pNtCreateFile( &dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
300 FILE_SHARE_READ
, FILE_CREATE
,
301 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
302 ok( status
== STATUS_OBJECT_NAME_INVALID
,
303 "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
305 status
= pNtQueryFullAttributesFile( &attr
, &info
);
306 todo_wine
ok( status
== STATUS_OBJECT_NAME_INVALID
,
307 "query %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
309 pRtlInitUnicodeString( &nameW
, pathInvalidNt2W
);
310 status
= pNtCreateFile( &dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
311 FILE_SHARE_READ
, FILE_CREATE
,
312 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
313 ok( status
== STATUS_OBJECT_NAME_INVALID
,
314 "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
316 status
= pNtQueryFullAttributesFile( &attr
, &info
);
317 ok( status
== STATUS_OBJECT_NAME_INVALID
,
318 "query %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
320 pRtlInitUnicodeString( &nameW
, pathInvalidDosW
);
321 status
= pNtCreateFile( &dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
322 FILE_SHARE_READ
, FILE_CREATE
,
323 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
324 ok( status
== STATUS_OBJECT_NAME_INVALID
,
325 "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
327 status
= pNtQueryFullAttributesFile( &attr
, &info
);
328 ok( status
== STATUS_OBJECT_NAME_INVALID
,
329 "query %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
332 static void open_file_test(void)
334 static const WCHAR testdirW
[] = {'o','p','e','n','f','i','l','e','t','e','s','t',0};
335 static const char testdata
[] = "Hello World";
337 HANDLE dir
, root
, handle
, file
;
338 WCHAR path
[MAX_PATH
], tmpfile
[MAX_PATH
];
340 OBJECT_ATTRIBUTES attr
;
342 UNICODE_STRING nameW
;
344 BOOL ret
, restart
= TRUE
;
347 len
= GetWindowsDirectoryW( path
, MAX_PATH
);
348 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
349 attr
.Length
= sizeof(attr
);
350 attr
.RootDirectory
= 0;
351 attr
.ObjectName
= &nameW
;
353 attr
.SecurityDescriptor
= NULL
;
354 attr
.SecurityQualityOfService
= NULL
;
355 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
356 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
357 ok( !status
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
358 pRtlFreeUnicodeString( &nameW
);
360 path
[3] = 0; /* root of the drive */
361 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
362 status
= pNtOpenFile( &root
, GENERIC_READ
, &attr
, &io
,
363 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
364 ok( !status
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
365 pRtlFreeUnicodeString( &nameW
);
367 /* test opening system dir with RootDirectory set to windows dir */
368 GetSystemDirectoryW( path
, MAX_PATH
);
369 while (path
[len
] == '\\') len
++;
370 nameW
.Buffer
= path
+ len
;
371 nameW
.Length
= lstrlenW(path
+ len
) * sizeof(WCHAR
);
372 attr
.RootDirectory
= dir
;
373 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
374 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
375 ok( !status
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
376 CloseHandle( handle
);
378 /* try uppercase name */
379 for (i
= len
; path
[i
]; i
++) if (path
[i
] >= 'a' && path
[i
] <= 'z') path
[i
] -= 'a' - 'A';
380 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
381 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
382 ok( !status
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
383 CloseHandle( handle
);
385 /* try with leading backslash */
387 nameW
.Length
+= sizeof(WCHAR
);
388 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
389 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
390 ok( status
== STATUS_INVALID_PARAMETER
||
391 status
== STATUS_OBJECT_NAME_INVALID
||
392 status
== STATUS_OBJECT_PATH_SYNTAX_BAD
,
393 "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
394 if (!status
) CloseHandle( handle
);
396 /* try with empty name */
398 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
399 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
400 ok( !status
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
401 CloseHandle( handle
);
404 attr
.RootDirectory
= 0;
405 wcscat( path
, L
"\\cmd.exe" );
406 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
407 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
408 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
409 ok( status
== STATUS_NOT_A_DIRECTORY
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
410 CloseHandle( handle
);
411 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
412 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_NON_DIRECTORY_FILE
);
413 ok( !status
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
414 CloseHandle( handle
);
415 pRtlFreeUnicodeString( &nameW
);
417 wcscat( path
, L
"\\cmd.exe" );
418 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
419 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
420 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
421 ok( status
== STATUS_OBJECT_PATH_NOT_FOUND
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
422 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
423 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_NON_DIRECTORY_FILE
);
424 ok( status
== STATUS_OBJECT_PATH_NOT_FOUND
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
425 pRtlFreeUnicodeString( &nameW
);
427 GetTempPathW( MAX_PATH
, path
);
428 lstrcatW( path
, testdirW
);
429 CreateDirectoryW( path
, NULL
);
431 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
432 attr
.RootDirectory
= NULL
;
433 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
434 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
435 ok( !status
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
436 pRtlFreeUnicodeString( &nameW
);
438 GetTempFileNameW( path
, fooW
, 0, tmpfile
);
439 file
= CreateFileW( tmpfile
, FILE_WRITE_DATA
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
440 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %ld\n", GetLastError() );
441 numbytes
= 0xdeadbeef;
442 ret
= WriteFile( file
, testdata
, sizeof(testdata
) - 1, &numbytes
, NULL
);
443 ok( ret
, "WriteFile failed with error %lu\n", GetLastError() );
444 ok( numbytes
== sizeof(testdata
) - 1, "failed to write all data\n" );
447 /* try open by file id */
449 while (!pNtQueryDirectoryFile( dir
, NULL
, NULL
, NULL
, &io
, data
, sizeof(data
),
450 FileIdBothDirectoryInformation
, TRUE
, NULL
, restart
))
452 FILE_ID_BOTH_DIRECTORY_INFORMATION
*info
= (FILE_ID_BOTH_DIRECTORY_INFORMATION
*)data
;
456 if (!info
->FileId
.QuadPart
) continue;
458 nameW
.Buffer
= (WCHAR
*)&info
->FileId
;
459 nameW
.Length
= sizeof(info
->FileId
);
460 info
->FileName
[info
->FileNameLength
/sizeof(WCHAR
)] = 0;
461 attr
.RootDirectory
= dir
;
462 /* We skip 'open' files by not specifying FILE_SHARE_WRITE */
463 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
465 FILE_OPEN_BY_FILE_ID
|
466 ((info
->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) ? FILE_DIRECTORY_FILE
: 0) );
467 ok( status
== STATUS_SUCCESS
, "open %s failed %lx\n", wine_dbgstr_w(info
->FileName
), status
);
470 BYTE buf
[sizeof(FILE_ALL_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
)];
472 if (!pNtQueryInformationFile( handle
, &io
, buf
, sizeof(buf
), FileAllInformation
))
474 FILE_ALL_INFORMATION
*fai
= (FILE_ALL_INFORMATION
*)buf
;
476 /* check that it's the same file/directory */
478 /* don't check the size for directories */
479 if (!(info
->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
480 ok( info
->EndOfFile
.QuadPart
== fai
->StandardInformation
.EndOfFile
.QuadPart
,
481 "mismatched file size for %s\n", wine_dbgstr_w(info
->FileName
));
483 ok( info
->CreationTime
.QuadPart
== fai
->BasicInformation
.CreationTime
.QuadPart
,
484 "mismatched creation time for %s\n", wine_dbgstr_w(info
->FileName
));
486 CloseHandle( handle
);
488 /* try same thing from drive root */
489 attr
.RootDirectory
= root
;
490 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
491 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
492 FILE_OPEN_BY_FILE_ID
|
493 ((info
->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) ? FILE_DIRECTORY_FILE
: 0) );
494 ok( status
== STATUS_SUCCESS
|| status
== STATUS_NOT_IMPLEMENTED
,
495 "open %s failed %lx\n", wine_dbgstr_w(info
->FileName
), status
);
496 if (!status
) CloseHandle( handle
);
503 pRtlDosPathNameToNtPathName_U( tmpfile
, &nameW
, NULL
, NULL
);
504 attr
.Length
= sizeof(attr
);
505 attr
.RootDirectory
= 0;
506 attr
.ObjectName
= &nameW
;
507 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
508 attr
.SecurityDescriptor
= NULL
;
509 attr
.SecurityQualityOfService
= NULL
;
510 status
= pNtOpenFile( &file
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
511 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
);
512 ok( !status
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
513 pRtlFreeUnicodeString( &nameW
);
515 numbytes
= 0xdeadbeef;
516 memset( data
, 0, sizeof(data
) );
517 ret
= ReadFile( file
, data
, sizeof(data
), &numbytes
, NULL
);
518 ok( ret
, "ReadFile failed with error %lu\n", GetLastError() );
519 ok( numbytes
== sizeof(testdata
) - 1, "failed to read all data\n" );
520 ok( !memcmp( data
, testdata
, sizeof(testdata
) - 1 ), "testdata doesn't match\n" );
522 nameW
.Length
= sizeof(fooW
) - sizeof(WCHAR
);
524 attr
.RootDirectory
= file
;
525 attr
.ObjectName
= &nameW
;
526 status
= pNtOpenFile( &root
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
527 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
);
528 ok( status
== STATUS_OBJECT_PATH_NOT_FOUND
,
529 "expected STATUS_OBJECT_PATH_NOT_FOUND, got %08lx\n", status
);
533 attr
.RootDirectory
= file
;
534 attr
.ObjectName
= &nameW
;
535 status
= pNtOpenFile( &root
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
536 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
);
537 ok( !status
, "open %s failed %lx\n", wine_dbgstr_w(tmpfile
), status
);
539 numbytes
= SetFilePointer( file
, 0, 0, FILE_CURRENT
);
540 ok( numbytes
== sizeof(testdata
) - 1, "SetFilePointer returned %lu\n", numbytes
);
541 numbytes
= SetFilePointer( root
, 0, 0, FILE_CURRENT
);
542 ok( numbytes
== 0, "SetFilePointer returned %lu\n", numbytes
);
544 numbytes
= 0xdeadbeef;
545 memset( data
, 0, sizeof(data
) );
546 ret
= ReadFile( root
, data
, sizeof(data
), &numbytes
, NULL
);
547 ok( ret
, "ReadFile failed with error %lu\n", GetLastError() );
548 ok( numbytes
== sizeof(testdata
) - 1, "failed to read all data\n" );
549 ok( !memcmp( data
, testdata
, sizeof(testdata
) - 1 ), "testdata doesn't match\n" );
551 numbytes
= SetFilePointer( file
, 0, 0, FILE_CURRENT
);
552 ok( numbytes
== sizeof(testdata
) - 1, "SetFilePointer returned %lu\n", numbytes
);
553 numbytes
= SetFilePointer( root
, 0, 0, FILE_CURRENT
);
554 ok( numbytes
== sizeof(testdata
) - 1, "SetFilePointer returned %lu\n", numbytes
);
558 DeleteFileW( tmpfile
);
559 RemoveDirectoryW( path
);
562 static void delete_file_test(void)
565 OBJECT_ATTRIBUTES attr
;
566 UNICODE_STRING nameW
;
567 WCHAR pathW
[MAX_PATH
];
568 WCHAR pathsubW
[MAX_PATH
];
569 static const WCHAR testdirW
[] = {'n','t','d','e','l','e','t','e','f','i','l','e',0};
570 static const WCHAR subdirW
[] = {'\\','s','u','b',0};
572 ret
= GetTempPathW(MAX_PATH
, pathW
);
575 ok(0, "couldn't get temp dir\n");
578 if (ret
+ ARRAY_SIZE(testdirW
)-1 + ARRAY_SIZE(subdirW
)-1 >= MAX_PATH
)
580 ok(0, "MAX_PATH exceeded in constructing paths\n");
584 lstrcatW(pathW
, testdirW
);
585 lstrcpyW(pathsubW
, pathW
);
586 lstrcatW(pathsubW
, subdirW
);
588 ret
= CreateDirectoryW(pathW
, NULL
);
589 ok(ret
== TRUE
, "couldn't create directory ntdeletefile\n");
590 if (!pRtlDosPathNameToNtPathName_U(pathW
, &nameW
, NULL
, NULL
))
592 ok(0,"RtlDosPathNametoNtPathName_U failed\n");
596 attr
.Length
= sizeof(attr
);
597 attr
.RootDirectory
= 0;
598 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
599 attr
.ObjectName
= &nameW
;
600 attr
.SecurityDescriptor
= NULL
;
601 attr
.SecurityQualityOfService
= NULL
;
603 /* test NtDeleteFile on an empty directory */
604 ret
= pNtDeleteFile(&attr
);
605 ok(ret
== STATUS_SUCCESS
, "NtDeleteFile should succeed in removing an empty directory\n");
606 ret
= RemoveDirectoryW(pathW
);
607 ok(ret
== FALSE
, "expected to fail removing directory, NtDeleteFile should have removed it\n");
609 /* test NtDeleteFile on a non-empty directory */
610 ret
= CreateDirectoryW(pathW
, NULL
);
611 ok(ret
== TRUE
, "couldn't create directory ntdeletefile ?!\n");
612 ret
= CreateDirectoryW(pathsubW
, NULL
);
613 ok(ret
== TRUE
, "couldn't create directory subdir\n");
614 ret
= pNtDeleteFile(&attr
);
615 ok(ret
== STATUS_SUCCESS
, "expected NtDeleteFile to ret STATUS_SUCCESS\n");
616 ret
= RemoveDirectoryW(pathsubW
);
617 ok(ret
== TRUE
, "expected to remove directory ntdeletefile\\sub\n");
618 ret
= RemoveDirectoryW(pathW
);
619 ok(ret
== TRUE
, "expected to remove directory ntdeletefile, NtDeleteFile failed.\n");
621 pRtlFreeUnicodeString( &nameW
);
624 #define TEST_OVERLAPPED_READ_SIZE 4096
626 static void read_file_test(void)
628 DECLSPEC_ALIGN(TEST_OVERLAPPED_READ_SIZE
) static unsigned char aligned_buffer
[TEST_OVERLAPPED_READ_SIZE
];
629 const char text
[] = "foobar";
631 IO_STATUS_BLOCK iosb
;
635 LARGE_INTEGER offset
;
636 HANDLE event
= CreateEventA( NULL
, TRUE
, FALSE
, NULL
);
638 if (!(handle
= create_temp_file( FILE_FLAG_OVERLAPPED
))) return;
640 U(iosb
).Status
= 0xdeadbabe;
641 iosb
.Information
= 0xdeadbeef;
644 status
= pNtWriteFile( handle
, event
, apc
, &apc_count
, &iosb
, text
, strlen(text
), &offset
, NULL
);
645 ok( status
== STATUS_PENDING
|| broken(status
== STATUS_SUCCESS
) /* before Vista */,
646 "wrong status %lx.\n", status
);
647 if (status
== STATUS_PENDING
) WaitForSingleObject( event
, 1000 );
648 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %lx\n", U(iosb
).Status
);
649 ok( iosb
.Information
== strlen(text
), "wrong info %Iu\n", iosb
.Information
);
650 ok( is_signaled( event
), "event is not signaled\n" );
651 ok( !apc_count
, "apc was called\n" );
652 SleepEx( 1, TRUE
); /* alertable sleep */
653 ok( apc_count
== 1, "apc was not called\n" );
656 U(iosb
).Status
= 0xdeadbabe;
657 iosb
.Information
= 0xdeadbeef;
660 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, strlen(text
) + 10, &offset
, NULL
);
661 ok(status
== STATUS_PENDING
662 || broken(status
== STATUS_SUCCESS
) /* before Vista */,
663 "wrong status %lx.\n", status
);
664 if (status
== STATUS_PENDING
) WaitForSingleObject( event
, 1000 );
665 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %lx\n", U(iosb
).Status
);
666 ok( iosb
.Information
== strlen(text
), "wrong info %Iu\n", iosb
.Information
);
667 ok( is_signaled( event
), "event is not signaled\n" );
668 ok( !apc_count
, "apc was called\n" );
669 SleepEx( 1, TRUE
); /* alertable sleep */
670 ok( apc_count
== 1, "apc was not called\n" );
672 /* read beyond eof */
674 U(iosb
).Status
= 0xdeadbabe;
675 iosb
.Information
= 0xdeadbeef;
676 offset
.QuadPart
= strlen(text
) + 2;
677 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, &offset
, NULL
);
678 ok(status
== STATUS_PENDING
|| broken(status
== STATUS_END_OF_FILE
) /* before Vista */,
679 "expected STATUS_PENDING, got %#lx\n", status
);
680 if (status
== STATUS_PENDING
) /* vista */
682 WaitForSingleObject( event
, 1000 );
683 ok( U(iosb
).Status
== STATUS_END_OF_FILE
, "wrong status %lx\n", U(iosb
).Status
);
684 ok( iosb
.Information
== 0, "wrong info %Iu\n", iosb
.Information
);
685 ok( is_signaled( event
), "event is not signaled\n" );
686 ok( !apc_count
, "apc was called\n" );
687 SleepEx( 1, TRUE
); /* alertable sleep */
688 ok( apc_count
== 1, "apc was not called\n" );
690 CloseHandle( handle
);
692 /* now a non-overlapped file */
693 if (!(handle
= create_temp_file(0))) return;
695 U(iosb
).Status
= 0xdeadbabe;
696 iosb
.Information
= 0xdeadbeef;
698 status
= pNtWriteFile( handle
, event
, apc
, &apc_count
, &iosb
, text
, strlen(text
), &offset
, NULL
);
699 ok( status
== STATUS_END_OF_FILE
||
700 status
== STATUS_SUCCESS
||
701 status
== STATUS_PENDING
, /* vista */
702 "wrong status %lx\n", status
);
703 if (status
== STATUS_PENDING
) WaitForSingleObject( event
, 1000 );
704 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %lx\n", U(iosb
).Status
);
705 ok( iosb
.Information
== strlen(text
), "wrong info %Iu\n", iosb
.Information
);
706 ok( is_signaled( event
), "event is not signaled\n" );
707 ok( !apc_count
, "apc was called\n" );
708 SleepEx( 1, TRUE
); /* alertable sleep */
709 ok( apc_count
== 1, "apc was not called\n" );
712 U(iosb
).Status
= 0xdeadbabe;
713 iosb
.Information
= 0xdeadbeef;
716 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, strlen(text
) + 10, &offset
, NULL
);
717 ok( status
== STATUS_SUCCESS
, "wrong status %lx\n", status
);
718 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %lx\n", U(iosb
).Status
);
719 ok( iosb
.Information
== strlen(text
), "wrong info %Iu\n", iosb
.Information
);
720 ok( is_signaled( event
), "event is not signaled\n" );
721 ok( !apc_count
, "apc was called\n" );
722 SleepEx( 1, TRUE
); /* alertable sleep */
723 todo_wine
ok( !apc_count
, "apc was called\n" );
725 /* read beyond eof */
727 U(iosb
).Status
= 0xdeadbabe;
728 iosb
.Information
= 0xdeadbeef;
729 offset
.QuadPart
= strlen(text
) + 2;
731 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, &offset
, NULL
);
732 ok( status
== STATUS_END_OF_FILE
, "wrong status %lx\n", status
);
733 ok( U(iosb
).Status
== STATUS_END_OF_FILE
, "wrong status %lx\n", U(iosb
).Status
);
734 ok( iosb
.Information
== 0, "wrong info %Iu\n", iosb
.Information
);
735 ok( is_signaled( event
), "event is not signaled\n" );
736 ok( !apc_count
, "apc was called\n" );
737 SleepEx( 1, TRUE
); /* alertable sleep */
738 ok( !apc_count
, "apc was called\n" );
740 CloseHandle( handle
);
742 if (!(handle
= create_temp_file(FILE_FLAG_OVERLAPPED
| FILE_FLAG_NO_BUFFERING
)))
747 U(iosb
).Status
= 0xdeadbabe;
748 iosb
.Information
= 0xdeadbeef;
751 status
= pNtWriteFile(handle
, event
, apc
, &apc_count
, &iosb
,
752 aligned_buffer
, sizeof(aligned_buffer
), &offset
, NULL
);
753 ok(status
== STATUS_END_OF_FILE
|| status
== STATUS_PENDING
754 || broken(status
== STATUS_SUCCESS
) /* before Vista */,
755 "Wrong status %lx.\n", status
);
756 ok(U(iosb
).Status
== STATUS_SUCCESS
, "Wrong status %lx.\n", U(iosb
).Status
);
757 ok(iosb
.Information
== sizeof(aligned_buffer
), "Wrong info %Iu.\n", iosb
.Information
);
758 ok(is_signaled(event
), "event is not signaled.\n");
759 ok(!apc_count
, "apc was called.\n");
760 SleepEx(1, TRUE
); /* alertable sleep */
761 ok(apc_count
== 1, "apc was not called.\n");
765 U(iosb
).Status
= 0xdeadbabe;
766 iosb
.Information
= 0xdeadbeef;
769 status
= pNtReadFile(handle
, event
, apc
, &apc_count
, &iosb
,
770 aligned_buffer
, sizeof(aligned_buffer
), &offset
, NULL
);
771 ok(status
== STATUS_PENDING
, "Wrong status %lx.\n", status
);
772 WaitForSingleObject(event
, 1000);
773 ok(U(iosb
).Status
== STATUS_SUCCESS
, "Wrong status %lx.\n", U(iosb
).Status
);
774 ok(iosb
.Information
== sizeof(aligned_buffer
), "Wrong info %Iu.\n", iosb
.Information
);
775 ok(is_signaled(event
), "event is not signaled.\n");
776 ok(!apc_count
, "apc was called.\n");
777 SleepEx(1, TRUE
); /* alertable sleep */
778 ok(apc_count
== 1, "apc was not called.\n");
784 static void append_file_test(void)
786 static const char text
[6] = "foobar";
789 IO_STATUS_BLOCK iosb
;
790 LARGE_INTEGER offset
;
791 char path
[MAX_PATH
], buffer
[MAX_PATH
], buf
[16];
794 GetTempPathA( MAX_PATH
, path
);
795 GetTempFileNameA( path
, "foo", 0, buffer
);
797 handle
= CreateFileA(buffer
, FILE_WRITE_DATA
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
798 ok(handle
!= INVALID_HANDLE_VALUE
, "CreateFile error %ld\n", GetLastError());
801 iosb
.Information
= -1;
802 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
, 2, NULL
, NULL
);
803 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#lx\n", status
);
804 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iosb
).Status
);
805 ok(iosb
.Information
== 2, "expected 2, got %Iu\n", iosb
.Information
);
809 /* It is possible to open a file with only FILE_APPEND_DATA access flags.
810 It matches the O_WRONLY|O_APPEND open() posix behavior */
811 handle
= CreateFileA(buffer
, FILE_APPEND_DATA
, 0, NULL
, OPEN_EXISTING
, 0, 0);
812 ok(handle
!= INVALID_HANDLE_VALUE
, "CreateFile error %ld\n", GetLastError());
815 iosb
.Information
= -1;
817 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
+ 2, 2, &offset
, NULL
);
818 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#lx\n", status
);
819 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iosb
).Status
);
820 ok(iosb
.Information
== 2, "expected 2, got %Iu\n", iosb
.Information
);
822 ret
= SetFilePointer(handle
, 0, NULL
, FILE_CURRENT
);
823 ok(ret
== 4, "expected 4, got %lu\n", ret
);
826 iosb
.Information
= -1;
828 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
+ 4, 2, &offset
, NULL
);
829 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#lx\n", status
);
830 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iosb
).Status
);
831 ok(iosb
.Information
== 2, "expected 2, got %Iu\n", iosb
.Information
);
833 ret
= SetFilePointer(handle
, 0, NULL
, FILE_CURRENT
);
834 ok(ret
== 6, "expected 6, got %lu\n", ret
);
838 handle
= CreateFileA(buffer
, FILE_READ_DATA
| FILE_WRITE_DATA
| FILE_APPEND_DATA
, 0, NULL
, OPEN_EXISTING
, 0, 0);
839 ok(handle
!= INVALID_HANDLE_VALUE
, "CreateFile error %ld\n", GetLastError());
841 memset(buf
, 0, sizeof(buf
));
843 iosb
.Information
= -1;
845 status
= pNtReadFile(handle
, 0, NULL
, NULL
, &iosb
, buf
, sizeof(buf
), &offset
, NULL
);
846 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#lx\n", status
);
847 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iosb
).Status
);
848 ok(iosb
.Information
== 6, "expected 6, got %Iu\n", iosb
.Information
);
850 ok(memcmp(buf
, text
, 6) == 0, "wrong file contents: %s\n", buf
);
853 iosb
.Information
= -1;
855 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
+ 3, 3, &offset
, NULL
);
856 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#lx\n", status
);
857 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iosb
).Status
);
858 ok(iosb
.Information
== 3, "expected 3, got %Iu\n", iosb
.Information
);
860 memset(buf
, 0, sizeof(buf
));
862 iosb
.Information
= -1;
864 status
= pNtReadFile(handle
, 0, NULL
, NULL
, &iosb
, buf
, sizeof(buf
), &offset
, NULL
);
865 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#lx\n", status
);
866 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iosb
).Status
);
867 ok(iosb
.Information
== 6, "expected 6, got %Iu\n", iosb
.Information
);
869 ok(memcmp(buf
, "barbar", 6) == 0, "wrong file contents: %s\n", buf
);
875 static void nt_mailslot_test(void)
878 ACCESS_MASK DesiredAccess
;
879 OBJECT_ATTRIBUTES attr
;
883 ULONG MaxMessageSize
;
884 LARGE_INTEGER TimeOut
;
885 IO_STATUS_BLOCK IoStatusBlock
;
888 WCHAR buffer1
[] = { '\\','?','?','\\','M','A','I','L','S','L','O','T','\\',
889 'R',':','\\','F','R','E','D','\0' };
891 TimeOut
.QuadPart
= -1;
893 pRtlInitUnicodeString(&str
, buffer1
);
894 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
895 CreateOptions
= MailslotQuota
= MaxMessageSize
= 0;
896 DesiredAccess
= GENERIC_READ
;
899 * Check for NULL pointer handling
901 rc
= pNtCreateMailslotFile(NULL
, DesiredAccess
,
902 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
904 ok( rc
== STATUS_ACCESS_VIOLATION
||
905 rc
== STATUS_INVALID_PARAMETER
, /* win2k3 */
906 "rc = %lx not STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER\n", rc
);
909 * Test to see if the Timeout can be NULL
911 hslot
= (HANDLE
)0xdeadbeef;
912 rc
= pNtCreateMailslotFile(&hslot
, DesiredAccess
,
913 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
915 ok( rc
== STATUS_SUCCESS
||
916 rc
== STATUS_INVALID_PARAMETER
, /* win2k3 */
917 "rc = %lx not STATUS_SUCCESS or STATUS_INVALID_PARAMETER\n", rc
);
918 ok( hslot
!= 0, "Handle is invalid\n");
920 if ( rc
== STATUS_SUCCESS
) pNtClose(hslot
);
925 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
926 rc
= pNtCreateMailslotFile(&hslot
, DesiredAccess
,
927 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
929 ok( rc
== STATUS_SUCCESS
, "Create MailslotFile failed rc = %lx\n", rc
);
930 ok( hslot
!= 0, "Handle is invalid\n");
932 rc
= pNtClose(hslot
);
933 ok( rc
== STATUS_SUCCESS
, "NtClose failed\n");
936 static void WINAPI
user_apc_proc(ULONG_PTR arg
)
938 unsigned int *apc_count
= (unsigned int *)arg
;
942 static void test_set_io_completion(void)
944 FILE_IO_COMPLETION_INFORMATION info
[2] = {{0}};
945 LARGE_INTEGER timeout
= {{0}};
946 unsigned int apc_count
;
947 IO_STATUS_BLOCK iosb
;
948 ULONG_PTR key
, value
;
954 if (sizeof(size
) > 4) size
|= (ULONGLONG
)0x12345678 << 32;
956 res
= pNtCreateIoCompletion( &h
, IO_COMPLETION_ALL_ACCESS
, NULL
, 0 );
957 ok( res
== STATUS_SUCCESS
, "NtCreateIoCompletion failed: %#lx\n", res
);
958 ok( h
&& h
!= INVALID_HANDLE_VALUE
, "got invalid handle %p\n", h
);
960 res
= pNtRemoveIoCompletion( h
, &key
, &value
, &iosb
, &timeout
);
961 ok( res
== STATUS_TIMEOUT
, "NtRemoveIoCompletion failed: %#lx\n", res
);
963 res
= pNtSetIoCompletion( h
, CKEY_FIRST
, CVALUE_FIRST
, STATUS_INVALID_DEVICE_REQUEST
, size
);
964 ok( res
== STATUS_SUCCESS
, "NtSetIoCompletion failed: %lx\n", res
);
966 count
= get_pending_msgs(h
);
967 ok( count
== 1, "Unexpected msg count: %ld\n", count
);
969 res
= pNtRemoveIoCompletion( h
, &key
, &value
, &iosb
, &timeout
);
970 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletion failed: %#lx\n", res
);
971 ok( key
== CKEY_FIRST
, "Invalid completion key: %#Ix\n", key
);
972 ok( iosb
.Information
== size
, "Invalid iosb.Information: %Iu\n", iosb
.Information
);
973 ok( U(iosb
).Status
== STATUS_INVALID_DEVICE_REQUEST
, "Invalid iosb.Status: %#lx\n", U(iosb
).Status
);
974 ok( value
== CVALUE_FIRST
, "Invalid completion value: %#Ix\n", value
);
976 count
= get_pending_msgs(h
);
977 ok( !count
, "Unexpected msg count: %ld\n", count
);
979 if (!pNtRemoveIoCompletionEx
)
981 skip("NtRemoveIoCompletionEx() not present\n");
987 res
= pNtRemoveIoCompletionEx( h
, info
, 2, &count
, &timeout
, FALSE
);
988 ok( res
== STATUS_TIMEOUT
, "NtRemoveIoCompletionEx failed: %#lx\n", res
);
989 ok( count
== 1, "wrong count %lu\n", count
);
991 res
= pNtSetIoCompletion( h
, 123, 456, 789, size
);
992 ok( res
== STATUS_SUCCESS
, "NtSetIoCompletion failed: %#lx\n", res
);
995 res
= pNtRemoveIoCompletionEx( h
, info
, 2, &count
, &timeout
, FALSE
);
996 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletionEx failed: %#lx\n", res
);
997 ok( count
== 1, "wrong count %lu\n", count
);
998 ok( info
[0].CompletionKey
== 123, "wrong key %#Ix\n", info
[0].CompletionKey
);
999 ok( info
[0].CompletionValue
== 456, "wrong value %#Ix\n", info
[0].CompletionValue
);
1000 ok( info
[0].IoStatusBlock
.Information
== size
, "wrong information %#Ix\n",
1001 info
[0].IoStatusBlock
.Information
);
1002 ok( U(info
[0].IoStatusBlock
).Status
== 789, "wrong status %#lx\n", U(info
[0].IoStatusBlock
).Status
);
1004 res
= pNtSetIoCompletion( h
, 123, 456, 789, size
);
1005 ok( res
== STATUS_SUCCESS
, "NtSetIoCompletion failed: %#lx\n", res
);
1007 res
= pNtSetIoCompletion( h
, 12, 34, 56, size
);
1008 ok( res
== STATUS_SUCCESS
, "NtSetIoCompletion failed: %#lx\n", res
);
1011 res
= pNtRemoveIoCompletionEx( h
, info
, 2, &count
, &timeout
, FALSE
);
1012 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletionEx failed: %#lx\n", res
);
1013 ok( count
== 2, "wrong count %lu\n", count
);
1014 ok( info
[0].CompletionKey
== 123, "wrong key %#Ix\n", info
[0].CompletionKey
);
1015 ok( info
[0].CompletionValue
== 456, "wrong value %#Ix\n", info
[0].CompletionValue
);
1016 ok( info
[0].IoStatusBlock
.Information
== size
, "wrong information %#Ix\n",
1017 info
[0].IoStatusBlock
.Information
);
1018 ok( U(info
[0].IoStatusBlock
).Status
== 789, "wrong status %#lx\n", U(info
[0].IoStatusBlock
).Status
);
1019 ok( info
[1].CompletionKey
== 12, "wrong key %#Ix\n", info
[1].CompletionKey
);
1020 ok( info
[1].CompletionValue
== 34, "wrong value %#Ix\n", info
[1].CompletionValue
);
1021 ok( info
[1].IoStatusBlock
.Information
== size
, "wrong information %#Ix\n",
1022 info
[1].IoStatusBlock
.Information
);
1023 ok( U(info
[1].IoStatusBlock
).Status
== 56, "wrong status %#lx\n", U(info
[1].IoStatusBlock
).Status
);
1025 res
= pNtSetIoCompletion( h
, 123, 456, 789, size
);
1026 ok( res
== STATUS_SUCCESS
, "NtSetIoCompletion failed: %#lx\n", res
);
1028 res
= pNtSetIoCompletion( h
, 12, 34, 56, size
);
1029 ok( res
== STATUS_SUCCESS
, "NtSetIoCompletion failed: %#lx\n", res
);
1032 res
= pNtRemoveIoCompletionEx( h
, info
, 1, &count
, NULL
, FALSE
);
1033 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletionEx failed: %#lx\n", res
);
1034 ok( count
== 1, "wrong count %lu\n", count
);
1035 ok( info
[0].CompletionKey
== 123, "wrong key %#Ix\n", info
[0].CompletionKey
);
1036 ok( info
[0].CompletionValue
== 456, "wrong value %#Ix\n", info
[0].CompletionValue
);
1037 ok( info
[0].IoStatusBlock
.Information
== size
, "wrong information %#Ix\n",
1038 info
[0].IoStatusBlock
.Information
);
1039 ok( U(info
[0].IoStatusBlock
).Status
== 789, "wrong status %#lx\n", U(info
[0].IoStatusBlock
).Status
);
1042 res
= pNtRemoveIoCompletionEx( h
, info
, 1, &count
, NULL
, FALSE
);
1043 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletionEx failed: %#lx\n", res
);
1044 ok( count
== 1, "wrong count %lu\n", count
);
1045 ok( info
[0].CompletionKey
== 12, "wrong key %#Ix\n", info
[0].CompletionKey
);
1046 ok( info
[0].CompletionValue
== 34, "wrong value %#Ix\n", info
[0].CompletionValue
);
1047 ok( info
[0].IoStatusBlock
.Information
== size
, "wrong information %#Ix\n",
1048 info
[0].IoStatusBlock
.Information
);
1049 ok( U(info
[0].IoStatusBlock
).Status
== 56, "wrong status %#lx\n", U(info
[0].IoStatusBlock
).Status
);
1052 QueueUserAPC( user_apc_proc
, GetCurrentThread(), (ULONG_PTR
)&apc_count
);
1055 res
= pNtRemoveIoCompletionEx( h
, info
, 2, &count
, &timeout
, FALSE
);
1056 ok( res
== STATUS_TIMEOUT
, "NtRemoveIoCompletionEx failed: %#lx\n", res
);
1057 ok( count
== 1, "wrong count %lu\n", count
);
1058 ok( !apc_count
, "wrong apc count %d\n", apc_count
);
1060 res
= pNtRemoveIoCompletionEx( h
, info
, 2, &count
, &timeout
, TRUE
);
1061 ok( res
== STATUS_USER_APC
, "NtRemoveIoCompletionEx failed: %#lx\n", res
);
1062 ok( count
== 1, "wrong count %lu\n", count
);
1063 ok( apc_count
== 1, "wrong apc count %u\n", apc_count
);
1066 QueueUserAPC( user_apc_proc
, GetCurrentThread(), (ULONG_PTR
)&apc_count
);
1068 res
= pNtSetIoCompletion( h
, 123, 456, 789, size
);
1069 ok( res
== STATUS_SUCCESS
, "NtSetIoCompletion failed: %#lx\n", res
);
1071 res
= pNtRemoveIoCompletionEx( h
, info
, 2, &count
, &timeout
, TRUE
);
1072 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletionEx failed: %#lx\n", res
);
1073 ok( count
== 1, "wrong count %lu\n", count
);
1074 ok( !apc_count
, "wrong apc count %u\n", apc_count
);
1081 static void test_file_io_completion(void)
1083 static const char pipe_name
[] = "\\\\.\\pipe\\iocompletiontestnamedpipe";
1085 IO_STATUS_BLOCK iosb
;
1086 BYTE send_buf
[TEST_BUF_LEN
], recv_buf
[TEST_BUF_LEN
];
1087 FILE_COMPLETION_INFORMATION fci
;
1088 LARGE_INTEGER timeout
= {{0}};
1089 HANDLE server
, client
;
1090 ULONG_PTR key
, value
;
1098 res
= pNtCreateIoCompletion( &h
, IO_COMPLETION_ALL_ACCESS
, NULL
, 0 );
1099 ok( res
== STATUS_SUCCESS
, "NtCreateIoCompletion failed: %#lx\n", res
);
1100 ok( h
&& h
!= INVALID_HANDLE_VALUE
, "got invalid handle %p\n", h
);
1101 fci
.CompletionPort
= h
;
1102 fci
.CompletionKey
= CKEY_SECOND
;
1104 server
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
,
1105 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1106 4, 1024, 1024, 1000, NULL
);
1107 ok( server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed: %lu\n", GetLastError() );
1108 client
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
,
1109 FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
1110 ok( client
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %lu\n", GetLastError() );
1112 U(iosb
).Status
= 0xdeadbeef;
1113 res
= pNtSetInformationFile( server
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
1114 ok( res
== STATUS_INVALID_PARAMETER
, "NtSetInformationFile failed: %#lx\n", res
);
1116 ok( U(iosb
).Status
== 0xdeadbeef, "wrong status %#lx\n", U(iosb
).Status
);
1117 CloseHandle( client
);
1118 CloseHandle( server
);
1120 server
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
| FILE_FLAG_OVERLAPPED
,
1121 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1122 4, 1024, 1024, 1000, NULL
);
1123 ok( server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed: %lu\n", GetLastError() );
1124 client
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
,
1125 FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
1126 ok( client
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %lu\n", GetLastError() );
1128 U(iosb
).Status
= 0xdeadbeef;
1129 res
= pNtSetInformationFile( server
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
1130 ok( res
== STATUS_SUCCESS
, "NtSetInformationFile failed: %#lx\n", res
);
1131 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %#lx\n", U(iosb
).Status
);
1133 memset( send_buf
, 0, TEST_BUF_LEN
);
1134 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1135 count
= get_pending_msgs(h
);
1136 ok( !count
, "Unexpected msg count: %ld\n", count
);
1137 ReadFile( server
, recv_buf
, TEST_BUF_LEN
, &read
, &o
);
1138 count
= get_pending_msgs(h
);
1139 ok( !count
, "Unexpected msg count: %ld\n", count
);
1140 WriteFile( client
, send_buf
, TEST_BUF_LEN
, &read
, NULL
);
1142 res
= pNtRemoveIoCompletion( h
, &key
, &value
, &iosb
, &timeout
);
1143 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletion failed: %#lx\n", res
);
1144 ok( key
== CKEY_SECOND
, "Invalid completion key: %#Ix\n", key
);
1145 ok( iosb
.Information
== 3, "Invalid iosb.Information: %Id\n", iosb
.Information
);
1146 ok( U(iosb
).Status
== STATUS_SUCCESS
, "Invalid iosb.Status: %#lx\n", U(iosb
).Status
);
1147 ok( value
== (ULONG_PTR
)&o
, "Invalid completion value: %#Ix\n", value
);
1148 ok( !memcmp( send_buf
, recv_buf
, TEST_BUF_LEN
),
1149 "Receive buffer (%02x %02x %02x) did not match send buffer (%02x %02x %02x)\n",
1150 recv_buf
[0], recv_buf
[1], recv_buf
[2], send_buf
[0], send_buf
[1], send_buf
[2] );
1151 count
= get_pending_msgs(h
);
1152 ok( !count
, "Unexpected msg count: %ld\n", count
);
1154 memset( send_buf
, 0, TEST_BUF_LEN
);
1155 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1156 WriteFile( client
, send_buf
, 2, &read
, NULL
);
1157 count
= get_pending_msgs(h
);
1158 ok( !count
, "Unexpected msg count: %ld\n", count
);
1159 ReadFile( server
, recv_buf
, 2, &read
, &o
);
1160 count
= get_pending_msgs(h
);
1161 ok( count
== 1, "Unexpected msg count: %ld\n", count
);
1163 res
= pNtRemoveIoCompletion( h
, &key
, &value
, &iosb
, &timeout
);
1164 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletion failed: %#lx\n", res
);
1165 ok( key
== CKEY_SECOND
, "Invalid completion key: %#Ix\n", key
);
1166 ok( iosb
.Information
== 2, "Invalid iosb.Information: %Id\n", iosb
.Information
);
1167 ok( U(iosb
).Status
== STATUS_SUCCESS
, "Invalid iosb.Status: %#lx\n", U(iosb
).Status
);
1168 ok( value
== (ULONG_PTR
)&o
, "Invalid completion value: %#Ix\n", value
);
1169 ok( !memcmp( send_buf
, recv_buf
, 2 ),
1170 "Receive buffer (%02x %02x) did not match send buffer (%02x %02x)\n",
1171 recv_buf
[0], recv_buf
[1], send_buf
[0], send_buf
[1] );
1173 ReadFile( server
, recv_buf
, TEST_BUF_LEN
, &read
, &o
);
1174 CloseHandle( server
);
1175 count
= get_pending_msgs(h
);
1176 ok( count
== 1, "Unexpected msg count: %ld\n", count
);
1178 res
= pNtRemoveIoCompletion( h
, &key
, &value
, &iosb
, &timeout
);
1179 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletion failed: %#lx\n", res
);
1180 ok( key
== CKEY_SECOND
, "Invalid completion key: %Ix\n", key
);
1181 ok( iosb
.Information
== 0, "Invalid iosb.Information: %Id\n", iosb
.Information
);
1182 ok( U(iosb
).Status
== STATUS_PIPE_BROKEN
, "Invalid iosb.Status: %lx\n", U(iosb
).Status
);
1183 ok( value
== (ULONG_PTR
)&o
, "Invalid completion value: %Ix\n", value
);
1185 CloseHandle( client
);
1187 /* test associating a completion port with a handle after an async is queued */
1188 server
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
| FILE_FLAG_OVERLAPPED
,
1189 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1190 4, 1024, 1024, 1000, NULL
);
1191 ok( server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed: %lu\n", GetLastError() );
1192 client
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
,
1193 FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
1194 ok( client
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %lu\n", GetLastError() );
1196 memset( send_buf
, 0, TEST_BUF_LEN
);
1197 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1198 count
= get_pending_msgs(h
);
1199 ok( !count
, "Unexpected msg count: %ld\n", count
);
1200 ReadFile( server
, recv_buf
, TEST_BUF_LEN
, &read
, &o
);
1202 U(iosb
).Status
= 0xdeadbeef;
1203 res
= pNtSetInformationFile( server
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
1204 ok( res
== STATUS_SUCCESS
, "NtSetInformationFile failed: %lx\n", res
);
1205 ok( U(iosb
).Status
== STATUS_SUCCESS
, "iosb.Status invalid: %lx\n", U(iosb
).Status
);
1206 count
= get_pending_msgs(h
);
1207 ok( !count
, "Unexpected msg count: %ld\n", count
);
1209 WriteFile( client
, send_buf
, TEST_BUF_LEN
, &read
, NULL
);
1211 res
= pNtRemoveIoCompletion( h
, &key
, &value
, &iosb
, &timeout
);
1212 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletion failed: %#lx\n", res
);
1213 ok( key
== CKEY_SECOND
, "Invalid completion key: %#Ix\n", key
);
1214 ok( iosb
.Information
== 3, "Invalid iosb.Information: %Id\n", iosb
.Information
);
1215 ok( U(iosb
).Status
== STATUS_SUCCESS
, "Invalid iosb.Status: %#lx\n", U(iosb
).Status
);
1216 ok( value
== (ULONG_PTR
)&o
, "Invalid completion value: %#Ix\n", value
);
1217 ok( !memcmp( send_buf
, recv_buf
, TEST_BUF_LEN
),
1218 "Receive buffer (%02x %02x %02x) did not match send buffer (%02x %02x %02x)\n",
1219 recv_buf
[0], recv_buf
[1], recv_buf
[2], send_buf
[0], send_buf
[1], send_buf
[2] );
1221 count
= get_pending_msgs(h
);
1222 ok( !count
, "Unexpected msg count: %ld\n", count
);
1224 /* using APCs on handle with associated completion port is not allowed */
1225 res
= pNtReadFile( server
, NULL
, apc
, &apc_count
, &iosb
, recv_buf
, sizeof(recv_buf
), NULL
, NULL
);
1226 ok(res
== STATUS_INVALID_PARAMETER
, "NtReadFile returned %lx\n", res
);
1228 CloseHandle( server
);
1229 CloseHandle( client
);
1231 /* test associating a completion port with a handle after an async using APC is queued */
1232 server
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
| FILE_FLAG_OVERLAPPED
,
1233 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1234 4, 1024, 1024, 1000, NULL
);
1235 ok( server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed: %lu\n", GetLastError() );
1236 client
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
,
1237 FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
1238 ok( client
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %lu\n", GetLastError() );
1241 memset( send_buf
, 0, TEST_BUF_LEN
);
1242 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1243 count
= get_pending_msgs(h
);
1244 ok( !count
, "Unexpected msg count: %ld\n", count
);
1246 res
= pNtReadFile( server
, NULL
, apc
, &apc_count
, &iosb
, recv_buf
, sizeof(recv_buf
), NULL
, NULL
);
1247 ok(res
== STATUS_PENDING
, "NtReadFile returned %lx\n", res
);
1249 U(iosb
).Status
= 0xdeadbeef;
1250 res
= pNtSetInformationFile( server
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
1251 ok( res
== STATUS_SUCCESS
, "NtSetInformationFile failed: %lx\n", res
);
1252 ok( U(iosb
).Status
== STATUS_SUCCESS
, "iosb.Status invalid: %lx\n", U(iosb
).Status
);
1253 count
= get_pending_msgs(h
);
1254 ok( !count
, "Unexpected msg count: %ld\n", count
);
1256 WriteFile( client
, send_buf
, TEST_BUF_LEN
, &read
, NULL
);
1258 ok(!apc_count
, "apc_count = %u\n", apc_count
);
1259 count
= get_pending_msgs(h
);
1260 ok( !count
, "Unexpected msg count: %ld\n", count
);
1262 SleepEx(1, TRUE
); /* alertable sleep */
1263 ok(apc_count
== 1, "apc was not called\n");
1264 count
= get_pending_msgs(h
);
1265 ok( !count
, "Unexpected msg count: %ld\n", count
);
1267 /* using APCs on handle with associated completion port is not allowed */
1268 res
= pNtReadFile( server
, NULL
, apc
, &apc_count
, &iosb
, recv_buf
, sizeof(recv_buf
), NULL
, NULL
);
1269 ok(res
== STATUS_INVALID_PARAMETER
, "NtReadFile returned %lx\n", res
);
1271 CloseHandle( server
);
1272 CloseHandle( client
);
1276 static void test_file_full_size_information(void)
1279 FILE_FS_FULL_SIZE_INFORMATION ffsi
;
1280 FILE_FS_SIZE_INFORMATION fsi
;
1284 if(!(h
= create_temp_file(0))) return ;
1286 memset(&ffsi
,0,sizeof(ffsi
));
1287 memset(&fsi
,0,sizeof(fsi
));
1289 /* Assume No Quota Settings configured on Wine Testbot */
1290 res
= pNtQueryVolumeInformationFile(h
, &io
, &ffsi
, sizeof ffsi
, FileFsFullSizeInformation
);
1291 ok(res
== STATUS_SUCCESS
, "cannot get attributes, res %lx\n", res
);
1292 res
= pNtQueryVolumeInformationFile(h
, &io
, &fsi
, sizeof fsi
, FileFsSizeInformation
);
1293 ok(res
== STATUS_SUCCESS
, "cannot get attributes, res %lx\n", res
);
1295 /* Test for FileFsSizeInformation */
1296 ok(fsi
.TotalAllocationUnits
.QuadPart
> 0,
1297 "[fsi] TotalAllocationUnits expected positive, got 0x%s\n",
1298 wine_dbgstr_longlong(fsi
.TotalAllocationUnits
.QuadPart
));
1299 ok(fsi
.AvailableAllocationUnits
.QuadPart
> 0,
1300 "[fsi] AvailableAllocationUnits expected positive, got 0x%s\n",
1301 wine_dbgstr_longlong(fsi
.AvailableAllocationUnits
.QuadPart
));
1303 /* Assume file system is NTFS */
1304 ok(fsi
.BytesPerSector
== 512, "[fsi] BytesPerSector expected 512, got %ld\n",fsi
.BytesPerSector
);
1305 ok(fsi
.SectorsPerAllocationUnit
== 8, "[fsi] SectorsPerAllocationUnit expected 8, got %ld\n",fsi
.SectorsPerAllocationUnit
);
1307 ok(ffsi
.TotalAllocationUnits
.QuadPart
> 0,
1308 "[ffsi] TotalAllocationUnits expected positive, got negative value 0x%s\n",
1309 wine_dbgstr_longlong(ffsi
.TotalAllocationUnits
.QuadPart
));
1310 ok(ffsi
.CallerAvailableAllocationUnits
.QuadPart
> 0,
1311 "[ffsi] CallerAvailableAllocationUnits expected positive, got negative value 0x%s\n",
1312 wine_dbgstr_longlong(ffsi
.CallerAvailableAllocationUnits
.QuadPart
));
1313 ok(ffsi
.ActualAvailableAllocationUnits
.QuadPart
> 0,
1314 "[ffsi] ActualAvailableAllocationUnits expected positive, got negative value 0x%s\n",
1315 wine_dbgstr_longlong(ffsi
.ActualAvailableAllocationUnits
.QuadPart
));
1316 ok(ffsi
.TotalAllocationUnits
.QuadPart
== fsi
.TotalAllocationUnits
.QuadPart
,
1317 "[ffsi] TotalAllocationUnits error fsi:0x%s, ffsi:0x%s\n",
1318 wine_dbgstr_longlong(fsi
.TotalAllocationUnits
.QuadPart
),
1319 wine_dbgstr_longlong(ffsi
.TotalAllocationUnits
.QuadPart
));
1320 ok(ffsi
.CallerAvailableAllocationUnits
.QuadPart
== fsi
.AvailableAllocationUnits
.QuadPart
,
1321 "[ffsi] CallerAvailableAllocationUnits error fsi:0x%s, ffsi: 0x%s\n",
1322 wine_dbgstr_longlong(fsi
.AvailableAllocationUnits
.QuadPart
),
1323 wine_dbgstr_longlong(ffsi
.CallerAvailableAllocationUnits
.QuadPart
));
1325 /* Assume file system is NTFS */
1326 ok(ffsi
.BytesPerSector
== 512, "[ffsi] BytesPerSector expected 512, got %ld\n",ffsi
.BytesPerSector
);
1327 ok(ffsi
.SectorsPerAllocationUnit
== 8, "[ffsi] SectorsPerAllocationUnit expected 8, got %ld\n",ffsi
.SectorsPerAllocationUnit
);
1332 static void test_file_basic_information(void)
1334 FILE_BASIC_INFORMATION fbi
, fbi2
;
1338 int attrib_mask
= FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_NORMAL
;
1340 if (!(h
= create_temp_file(0))) return;
1342 /* Check default first */
1343 memset(&fbi
, 0, sizeof(fbi
));
1344 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1345 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1346 ok ( (fbi
.FileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) == FILE_ATTRIBUTE_ARCHIVE
,
1347 "attribute %lx not expected\n", fbi
.FileAttributes
);
1349 memset(&fbi2
, 0, sizeof(fbi2
));
1350 fbi2
.LastWriteTime
.QuadPart
= -1;
1351 U(io
).Status
= 0xdeadbeef;
1352 res
= pNtSetInformationFile(h
, &io
, &fbi2
, sizeof fbi2
, FileBasicInformation
);
1353 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, NtSetInformationFile returned %x\n", res
);
1354 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status is %lx\n", U(io
).Status
);
1356 memset(&fbi2
, 0, sizeof(fbi2
));
1357 fbi2
.LastAccessTime
.QuadPart
= 0x200deadcafebeef;
1358 U(io
).Status
= 0xdeadbeef;
1359 res
= pNtSetInformationFile(h
, &io
, &fbi2
, sizeof(fbi2
), FileBasicInformation
);
1360 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, NtSetInformationFile returned %x\n", res
);
1361 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status is %lx\n", U(io
).Status
);
1362 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof(fbi
), FileBasicInformation
);
1363 ok ( res
== STATUS_SUCCESS
, "can't get system attribute, NtQueryInformationFile returned %x\n", res
);
1364 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't get system attribute, io.Status is %lx\n", U(io
).Status
);
1365 ok ( fbi2
.LastAccessTime
.QuadPart
== fbi
.LastAccessTime
.QuadPart
,
1366 "large access time set/get does not match.\n" );
1368 memset(&fbi2
, 0, sizeof(fbi2
));
1369 res
= pNtQueryInformationFile(h
, &io
, &fbi2
, sizeof fbi2
, FileBasicInformation
);
1370 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1371 ok ( fbi2
.LastWriteTime
.QuadPart
== fbi
.LastWriteTime
.QuadPart
, "unexpected write time.\n");
1373 memset(&fbi2
, 0, sizeof(fbi2
));
1374 U(io
).Status
= 0xdeadbeef;
1375 res
= pNtSetInformationFile(h
, &io
, &fbi2
, sizeof fbi2
, FileBasicInformation
);
1376 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, NtSetInformationFile returned %x\n", res
);
1377 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status is %lx\n", U(io
).Status
);
1379 memset(&fbi2
, 0, sizeof(fbi2
));
1380 res
= pNtQueryInformationFile(h
, &io
, &fbi2
, sizeof fbi2
, FileBasicInformation
);
1381 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1382 ok ( fbi2
.LastWriteTime
.QuadPart
== fbi
.LastWriteTime
.QuadPart
, "unexpected write time.\n");
1385 /* Clear fbi to avoid setting times */
1386 memset(&fbi
, 0, sizeof(fbi
));
1387 fbi
.FileAttributes
= FILE_ATTRIBUTE_SYSTEM
;
1388 U(io
).Status
= 0xdeadbeef;
1389 res
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1390 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, NtSetInformationFile returned %x\n", res
);
1391 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status is %lx\n", U(io
).Status
);
1393 memset(&fbi
, 0, sizeof(fbi
));
1394 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1395 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1396 ok ( (fbi
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_SYSTEM
, "attribute %lx not FILE_ATTRIBUTE_SYSTEM\n", fbi
.FileAttributes
);
1399 memset(&fbi
, 0, sizeof(fbi
));
1400 fbi
.FileAttributes
= FILE_ATTRIBUTE_HIDDEN
;
1401 U(io
).Status
= 0xdeadbeef;
1402 res
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1403 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, NtSetInformationFile returned %x\n", res
);
1404 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status is %lx\n", U(io
).Status
);
1406 memset(&fbi
, 0, sizeof(fbi
));
1407 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1408 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1409 ok ( (fbi
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_HIDDEN
, "attribute %lx not FILE_ATTRIBUTE_HIDDEN\n", fbi
.FileAttributes
);
1411 /* Check NORMAL last of all (to make sure we can clear attributes) */
1412 memset(&fbi
, 0, sizeof(fbi
));
1413 fbi
.FileAttributes
= FILE_ATTRIBUTE_NORMAL
;
1414 U(io
).Status
= 0xdeadbeef;
1415 res
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1416 ok ( res
== STATUS_SUCCESS
, "can't set normal attribute, NtSetInformationFile returned %x\n", res
);
1417 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set normal attribute, io.Status is %lx\n", U(io
).Status
);
1419 memset(&fbi
, 0, sizeof(fbi
));
1420 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1421 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1422 todo_wine
ok ( (fbi
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_NORMAL
, "attribute %lx not 0\n", fbi
.FileAttributes
);
1427 static void test_file_all_information(void)
1430 /* FileAllInformation, like FileNameInformation, has a variable-length pathname
1431 * buffer at the end. Vista objects with STATUS_BUFFER_OVERFLOW if you
1432 * don't leave enough room there.
1435 FILE_ALL_INFORMATION fai
;
1440 int attrib_mask
= FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_NORMAL
;
1442 if (!(h
= create_temp_file(0))) return;
1444 /* Check default first */
1445 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1446 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1447 ok ( (fai_buf
.fai
.BasicInformation
.FileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) == FILE_ATTRIBUTE_ARCHIVE
,
1448 "attribute %lx not expected\n", fai_buf
.fai
.BasicInformation
.FileAttributes
);
1451 /* Clear fbi to avoid setting times */
1452 memset(&fai_buf
.fai
.BasicInformation
, 0, sizeof(fai_buf
.fai
.BasicInformation
));
1453 fai_buf
.fai
.BasicInformation
.FileAttributes
= FILE_ATTRIBUTE_SYSTEM
;
1454 U(io
).Status
= 0xdeadbeef;
1455 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1456 ok ( res
== STATUS_INVALID_INFO_CLASS
|| broken(res
== STATUS_NOT_IMPLEMENTED
), "shouldn't be able to set FileAllInformation, res %x\n", res
);
1457 todo_wine
ok ( U(io
).Status
== 0xdeadbeef, "shouldn't be able to set FileAllInformation, io.Status is %lx\n", U(io
).Status
);
1458 U(io
).Status
= 0xdeadbeef;
1459 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
.BasicInformation
, sizeof fai_buf
.fai
.BasicInformation
, FileBasicInformation
);
1460 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, res: %x\n", res
);
1461 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status: %lx\n", U(io
).Status
);
1463 memset(&fai_buf
.fai
, 0, sizeof(fai_buf
.fai
));
1464 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1465 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1466 ok ( (fai_buf
.fai
.BasicInformation
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_SYSTEM
, "attribute %lx not FILE_ATTRIBUTE_SYSTEM\n", fai_buf
.fai
.BasicInformation
.FileAttributes
);
1469 memset(&fai_buf
.fai
.BasicInformation
, 0, sizeof(fai_buf
.fai
.BasicInformation
));
1470 fai_buf
.fai
.BasicInformation
.FileAttributes
= FILE_ATTRIBUTE_HIDDEN
;
1471 U(io
).Status
= 0xdeadbeef;
1472 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
.BasicInformation
, sizeof fai_buf
.fai
.BasicInformation
, FileBasicInformation
);
1473 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, res: %x\n", res
);
1474 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status: %lx\n", U(io
).Status
);
1476 memset(&fai_buf
.fai
, 0, sizeof(fai_buf
.fai
));
1477 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1478 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1479 ok ( (fai_buf
.fai
.BasicInformation
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_HIDDEN
, "attribute %lx not FILE_ATTRIBUTE_HIDDEN\n", fai_buf
.fai
.BasicInformation
.FileAttributes
);
1481 /* Check NORMAL last of all (to make sure we can clear attributes) */
1482 memset(&fai_buf
.fai
.BasicInformation
, 0, sizeof(fai_buf
.fai
.BasicInformation
));
1483 fai_buf
.fai
.BasicInformation
.FileAttributes
= FILE_ATTRIBUTE_NORMAL
;
1484 U(io
).Status
= 0xdeadbeef;
1485 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
.BasicInformation
, sizeof fai_buf
.fai
.BasicInformation
, FileBasicInformation
);
1486 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, res: %x\n", res
);
1487 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status: %lx\n", U(io
).Status
);
1489 memset(&fai_buf
.fai
, 0, sizeof(fai_buf
.fai
));
1490 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1491 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1492 todo_wine
ok ( (fai_buf
.fai
.BasicInformation
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_NORMAL
, "attribute %lx not FILE_ATTRIBUTE_NORMAL\n", fai_buf
.fai
.BasicInformation
.FileAttributes
);
1497 static void delete_object( WCHAR
*path
)
1499 BOOL ret
= DeleteFileW( path
);
1500 ok( ret
|| GetLastError() == ERROR_FILE_NOT_FOUND
|| GetLastError() == ERROR_ACCESS_DENIED
,
1501 "DeleteFileW failed with %lu\n", GetLastError() );
1502 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1504 ret
= RemoveDirectoryW( path
);
1505 ok( ret
, "RemoveDirectoryW failed with %lu\n", GetLastError() );
1509 static void test_file_rename_information(void)
1511 static const WCHAR foo_txtW
[] = {'\\','f','o','o','.','t','x','t',0};
1512 static const WCHAR fooW
[] = {'f','o','o',0};
1513 WCHAR tmp_path
[MAX_PATH
], oldpath
[MAX_PATH
+ 16], newpath
[MAX_PATH
+ 16], *filename
, *p
;
1514 FILE_RENAME_INFORMATION
*fri
;
1515 FILE_NAME_INFORMATION
*fni
;
1516 BOOL success
, fileDeleted
;
1517 UNICODE_STRING name_str
;
1518 HANDLE handle
, handle2
;
1522 GetTempPathW( MAX_PATH
, tmp_path
);
1524 /* oldpath is a file, newpath doesn't exist */
1525 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1526 ok( res
!= 0, "failed to create temp file\n" );
1527 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1528 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1530 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1531 ok( res
!= 0, "failed to create temp file\n" );
1532 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1533 DeleteFileW( newpath
);
1534 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1535 fri
->ReplaceIfExists
= FALSE
;
1536 fri
->RootDirectory
= NULL
;
1537 fri
->FileNameLength
= name_str
.Length
;
1538 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1539 pRtlFreeUnicodeString( &name_str
);
1541 U(io
).Status
= 0xdeadbeef;
1542 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1543 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %lx\n", U(io
).Status
);
1544 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %lx\n", res
);
1545 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1546 ok( fileDeleted
, "file should not exist\n" );
1547 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1548 ok( !fileDeleted
, "file should exist\n" );
1550 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
1551 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
1552 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %lx\n", res
);
1553 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
1554 ok( !lstrcmpiW(fni
->FileName
, newpath
+ 2), "FileName expected %s, got %s\n",
1555 wine_dbgstr_w(newpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
1556 HeapFree( GetProcessHeap(), 0, fni
);
1558 CloseHandle( handle
);
1559 HeapFree( GetProcessHeap(), 0, fri
);
1560 delete_object( oldpath
);
1561 delete_object( newpath
);
1563 /* oldpath is a file, newpath is a file, Replace = FALSE */
1564 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1565 ok( res
!= 0, "failed to create temp file\n" );
1566 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1567 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1569 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1570 ok( res
!= 0, "failed to create temp file\n" );
1571 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1572 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1573 fri
->ReplaceIfExists
= FALSE
;
1574 fri
->RootDirectory
= NULL
;
1575 fri
->FileNameLength
= name_str
.Length
;
1576 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1577 pRtlFreeUnicodeString( &name_str
);
1579 U(io
).Status
= 0xdeadbeef;
1580 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1581 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
1582 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %lx\n", res
);
1583 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1584 ok( !fileDeleted
, "file should exist\n" );
1585 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1586 ok( !fileDeleted
, "file should exist\n" );
1588 CloseHandle( handle
);
1589 HeapFree( GetProcessHeap(), 0, fri
);
1590 delete_object( oldpath
);
1591 delete_object( newpath
);
1593 /* oldpath is a file, newpath is a file, Replace = TRUE */
1594 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1595 ok( res
!= 0, "failed to create temp file\n" );
1596 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1597 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1599 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1600 ok( res
!= 0, "failed to create temp file\n" );
1601 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1602 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1603 fri
->ReplaceIfExists
= TRUE
;
1604 fri
->RootDirectory
= NULL
;
1605 fri
->FileNameLength
= name_str
.Length
;
1606 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1607 pRtlFreeUnicodeString( &name_str
);
1609 U(io
).Status
= 0xdeadbeef;
1610 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1611 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %lx\n", U(io
).Status
);
1612 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %lx\n", res
);
1613 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1614 ok( fileDeleted
, "file should not exist\n" );
1615 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1616 ok( !fileDeleted
, "file should exist\n" );
1618 CloseHandle( handle
);
1619 HeapFree( GetProcessHeap(), 0, fri
);
1620 delete_object( oldpath
);
1621 delete_object( newpath
);
1623 /* oldpath is a file, newpath is a file, Replace = FALSE, target file opened */
1624 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1625 ok( res
!= 0, "failed to create temp file\n" );
1626 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1627 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1629 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1630 ok( res
!= 0, "failed to create temp file\n" );
1631 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1632 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1634 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1635 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1636 fri
->ReplaceIfExists
= FALSE
;
1637 fri
->RootDirectory
= NULL
;
1638 fri
->FileNameLength
= name_str
.Length
;
1639 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1640 pRtlFreeUnicodeString( &name_str
);
1642 U(io
).Status
= 0xdeadbeef;
1643 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1644 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
1645 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %lx\n", res
);
1646 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1647 ok( !fileDeleted
, "file should exist\n" );
1648 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1649 ok( !fileDeleted
, "file should exist\n" );
1651 CloseHandle( handle
);
1652 CloseHandle( handle2
);
1653 HeapFree( GetProcessHeap(), 0, fri
);
1654 delete_object( oldpath
);
1655 delete_object( newpath
);
1657 /* oldpath is a file, newpath is a file, Replace = TRUE, target file opened */
1658 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1659 ok( res
!= 0, "failed to create temp file\n" );
1660 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1661 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1663 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1664 ok( res
!= 0, "failed to create temp file\n" );
1665 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1666 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1668 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1669 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1670 fri
->ReplaceIfExists
= TRUE
;
1671 fri
->RootDirectory
= NULL
;
1672 fri
->FileNameLength
= name_str
.Length
;
1673 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1674 pRtlFreeUnicodeString( &name_str
);
1676 U(io
).Status
= 0xdeadbeef;
1677 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1678 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
1679 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %lx\n", res
);
1680 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1681 ok( !fileDeleted
, "file should exist\n" );
1682 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1683 ok( !fileDeleted
, "file should exist\n" );
1685 CloseHandle( handle
);
1686 CloseHandle( handle2
);
1687 HeapFree( GetProcessHeap(), 0, fri
);
1688 delete_object( oldpath
);
1689 delete_object( newpath
);
1691 /* oldpath is a directory, newpath doesn't exist, Replace = FALSE */
1692 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1693 ok( res
!= 0, "failed to create temp file\n" );
1694 DeleteFileW( oldpath
);
1695 success
= CreateDirectoryW( oldpath
, NULL
);
1696 ok( success
!= 0, "failed to create temp directory\n" );
1697 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1698 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1700 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1701 ok( res
!= 0, "failed to create temp file\n" );
1702 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1703 DeleteFileW( newpath
);
1704 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1705 fri
->ReplaceIfExists
= FALSE
;
1706 fri
->RootDirectory
= NULL
;
1707 fri
->FileNameLength
= name_str
.Length
;
1708 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1709 pRtlFreeUnicodeString( &name_str
);
1711 U(io
).Status
= 0xdeadbeef;
1712 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1713 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %lx\n", U(io
).Status
);
1714 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %lx\n", res
);
1715 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1716 ok( fileDeleted
, "file should not exist\n" );
1717 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1718 ok( !fileDeleted
, "file should exist\n" );
1720 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
1721 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
1722 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %lx\n", res
);
1723 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
1724 ok( !lstrcmpiW(fni
->FileName
, newpath
+ 2), "FileName expected %s, got %s\n",
1725 wine_dbgstr_w(newpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
1726 HeapFree( GetProcessHeap(), 0, fni
);
1728 CloseHandle( handle
);
1729 HeapFree( GetProcessHeap(), 0, fri
);
1730 delete_object( oldpath
);
1731 delete_object( newpath
);
1733 /* oldpath is a directory (but child object opened), newpath doesn't exist, Replace = FALSE */
1734 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1735 ok( res
!= 0, "failed to create temp file\n" );
1736 DeleteFileW( oldpath
);
1737 success
= CreateDirectoryW( oldpath
, NULL
);
1738 ok( success
!= 0, "failed to create temp directory\n" );
1739 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1740 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1742 lstrcpyW( newpath
, oldpath
);
1743 lstrcatW( newpath
, foo_txtW
);
1744 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0 );
1745 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1747 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1748 ok( res
!= 0, "failed to create temp file\n" );
1749 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1750 DeleteFileW( newpath
);
1751 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1752 fri
->ReplaceIfExists
= FALSE
;
1753 fri
->RootDirectory
= NULL
;
1754 fri
->FileNameLength
= name_str
.Length
;
1755 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1756 pRtlFreeUnicodeString( &name_str
);
1758 U(io
).Status
= 0xdeadbeef;
1759 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1760 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
1761 todo_wine
ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %lx\n", res
);
1762 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1763 todo_wine
ok( !fileDeleted
, "file should exist\n" );
1764 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1765 todo_wine
ok( fileDeleted
, "file should not exist\n" );
1767 CloseHandle( handle
);
1768 CloseHandle( handle2
);
1769 HeapFree( GetProcessHeap(), 0, fri
);
1770 delete_object( oldpath
);
1771 if (res
== STATUS_SUCCESS
) /* remove when Wine is fixed */
1773 lstrcpyW( oldpath
, newpath
);
1774 lstrcatW( oldpath
, foo_txtW
);
1775 delete_object( oldpath
);
1777 delete_object( newpath
);
1779 /* oldpath is a directory, newpath is a file, Replace = FALSE */
1780 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1781 ok( res
!= 0, "failed to create temp file\n" );
1782 DeleteFileW( oldpath
);
1783 success
= CreateDirectoryW( oldpath
, NULL
);
1784 ok( success
!= 0, "failed to create temp directory\n" );
1785 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1786 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1788 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1789 ok( res
!= 0, "failed to create temp file\n" );
1790 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1791 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1792 fri
->ReplaceIfExists
= FALSE
;
1793 fri
->RootDirectory
= NULL
;
1794 fri
->FileNameLength
= name_str
.Length
;
1795 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1796 pRtlFreeUnicodeString( &name_str
);
1798 U(io
).Status
= 0xdeadbeef;
1799 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1800 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
1801 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %lx\n", res
);
1802 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1803 ok( !fileDeleted
, "file should exist\n" );
1804 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1805 ok( !fileDeleted
, "file should exist\n" );
1807 CloseHandle( handle
);
1808 HeapFree( GetProcessHeap(), 0, fri
);
1809 delete_object( oldpath
);
1810 delete_object( newpath
);
1812 /* oldpath is a directory, newpath is a file, Replace = FALSE, target file opened */
1813 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1814 ok( res
!= 0, "failed to create temp file\n" );
1815 DeleteFileW( oldpath
);
1816 success
= CreateDirectoryW( oldpath
, NULL
);
1817 ok( success
!= 0, "failed to create temp directory\n" );
1818 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1819 ok( handle
!= 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 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1824 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1826 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1827 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1828 fri
->ReplaceIfExists
= FALSE
;
1829 fri
->RootDirectory
= NULL
;
1830 fri
->FileNameLength
= name_str
.Length
;
1831 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1832 pRtlFreeUnicodeString( &name_str
);
1834 U(io
).Status
= 0xdeadbeef;
1835 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1836 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
1837 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %lx\n", res
);
1838 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1839 ok( !fileDeleted
, "file should exist\n" );
1840 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1841 ok( !fileDeleted
, "file should exist\n" );
1843 CloseHandle( handle
);
1844 CloseHandle( handle2
);
1845 HeapFree( GetProcessHeap(), 0, fri
);
1846 delete_object( oldpath
);
1847 delete_object( newpath
);
1849 /* oldpath is a directory, newpath is a file, Replace = TRUE */
1850 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1851 ok( res
!= 0, "failed to create temp file\n" );
1852 DeleteFileW( oldpath
);
1853 success
= CreateDirectoryW( oldpath
, NULL
);
1854 ok( success
!= 0, "failed to create temp directory\n" );
1855 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1856 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1858 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1859 ok( res
!= 0, "failed to create temp file\n" );
1860 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1861 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1862 fri
->ReplaceIfExists
= TRUE
;
1863 fri
->RootDirectory
= NULL
;
1864 fri
->FileNameLength
= name_str
.Length
;
1865 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1866 pRtlFreeUnicodeString( &name_str
);
1868 U(io
).Status
= 0xdeadbeef;
1869 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1870 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %lx\n", U(io
).Status
);
1871 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %lx\n", res
);
1872 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1873 ok( fileDeleted
, "file should not exist\n" );
1874 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1875 ok( !fileDeleted
, "file should exist\n" );
1877 CloseHandle( handle
);
1878 HeapFree( GetProcessHeap(), 0, fri
);
1879 delete_object( oldpath
);
1880 delete_object( newpath
);
1882 /* oldpath is a directory, newpath is a file, Replace = TRUE, target file opened */
1883 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1884 ok( res
!= 0, "failed to create temp file\n" );
1885 DeleteFileW( oldpath
);
1886 success
= CreateDirectoryW( oldpath
, NULL
);
1887 ok( success
!= 0, "failed to create temp directory\n" );
1888 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1889 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1891 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1892 ok( res
!= 0, "failed to create temp file\n" );
1893 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1894 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1896 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1897 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1898 fri
->ReplaceIfExists
= TRUE
;
1899 fri
->RootDirectory
= NULL
;
1900 fri
->FileNameLength
= name_str
.Length
;
1901 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1902 pRtlFreeUnicodeString( &name_str
);
1904 U(io
).Status
= 0xdeadbeef;
1905 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1906 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
1907 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %lx\n", res
);
1908 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1909 ok( !fileDeleted
, "file should exist\n" );
1910 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1911 ok( !fileDeleted
, "file should exist\n" );
1913 CloseHandle( handle
);
1914 CloseHandle( handle2
);
1915 HeapFree( GetProcessHeap(), 0, fri
);
1916 delete_object( oldpath
);
1917 delete_object( newpath
);
1919 /* oldpath is a directory, newpath is a directory, Replace = FALSE */
1920 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1921 ok( res
!= 0, "failed to create temp file\n" );
1922 DeleteFileW( oldpath
);
1923 success
= CreateDirectoryW( oldpath
, NULL
);
1924 ok( success
!= 0, "failed to create temp directory\n" );
1925 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1926 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1928 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1929 ok( res
!= 0, "failed to create temp file\n" );
1930 DeleteFileW( newpath
);
1931 success
= CreateDirectoryW( newpath
, NULL
);
1932 ok( success
!= 0, "failed to create temp directory\n" );
1933 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1934 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1935 fri
->ReplaceIfExists
= FALSE
;
1936 fri
->RootDirectory
= NULL
;
1937 fri
->FileNameLength
= name_str
.Length
;
1938 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1939 pRtlFreeUnicodeString( &name_str
);
1941 U(io
).Status
= 0xdeadbeef;
1942 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1943 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
1944 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %lx\n", res
);
1945 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1946 ok( !fileDeleted
, "file should exist\n" );
1947 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1948 ok( !fileDeleted
, "file should exist\n" );
1950 CloseHandle( handle
);
1951 HeapFree( GetProcessHeap(), 0, fri
);
1952 delete_object( oldpath
);
1953 delete_object( newpath
);
1955 /* oldpath is a directory, newpath is a directory, Replace = TRUE */
1956 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1957 ok( res
!= 0, "failed to create temp file\n" );
1958 DeleteFileW( oldpath
);
1959 success
= CreateDirectoryW( oldpath
, NULL
);
1960 ok( success
!= 0, "failed to create temp directory\n" );
1961 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1962 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1964 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1965 ok( res
!= 0, "failed to create temp file\n" );
1966 DeleteFileW( newpath
);
1967 success
= CreateDirectoryW( newpath
, NULL
);
1968 ok( success
!= 0, "failed to create temp directory\n" );
1969 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1970 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1971 fri
->ReplaceIfExists
= TRUE
;
1972 fri
->RootDirectory
= NULL
;
1973 fri
->FileNameLength
= name_str
.Length
;
1974 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1975 pRtlFreeUnicodeString( &name_str
);
1977 U(io
).Status
= 0xdeadbeef;
1978 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1979 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
1980 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %lx\n", res
);
1981 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1982 ok( !fileDeleted
, "file should exist\n" );
1983 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1984 ok( !fileDeleted
, "file should exist\n" );
1986 CloseHandle( handle
);
1987 HeapFree( GetProcessHeap(), 0, fri
);
1988 delete_object( oldpath
);
1989 delete_object( newpath
);
1991 /* oldpath is a directory, newpath is a directory, Replace = TRUE, target file opened */
1992 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1993 ok( res
!= 0, "failed to create temp file\n" );
1994 DeleteFileW( oldpath
);
1995 success
= CreateDirectoryW( oldpath
, NULL
);
1996 ok( success
!= 0, "failed to create temp directory\n" );
1997 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1998 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2000 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2001 ok( res
!= 0, "failed to create temp file\n" );
2002 DeleteFileW( newpath
);
2003 success
= CreateDirectoryW( newpath
, NULL
);
2004 ok( success
!= 0, "failed to create temp directory\n" );
2005 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2006 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2008 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2009 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
2010 fri
->ReplaceIfExists
= TRUE
;
2011 fri
->RootDirectory
= NULL
;
2012 fri
->FileNameLength
= name_str
.Length
;
2013 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
2014 pRtlFreeUnicodeString( &name_str
);
2016 U(io
).Status
= 0xdeadbeef;
2017 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
2018 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
2019 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %lx\n", res
);
2020 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2021 ok( !fileDeleted
, "file should exist\n" );
2022 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2023 ok( !fileDeleted
, "file should exist\n" );
2025 CloseHandle( handle
);
2026 CloseHandle( handle2
);
2027 HeapFree( GetProcessHeap(), 0, fri
);
2028 delete_object( oldpath
);
2029 delete_object( newpath
);
2031 /* oldpath is a file, newpath is a directory, Replace = FALSE */
2032 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2033 ok( res
!= 0, "failed to create temp file\n" );
2034 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2035 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2037 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2038 ok( res
!= 0, "failed to create temp file\n" );
2039 DeleteFileW( newpath
);
2040 success
= CreateDirectoryW( newpath
, NULL
);
2041 ok( success
!= 0, "failed to create temp directory\n" );
2042 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2043 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
2044 fri
->ReplaceIfExists
= FALSE
;
2045 fri
->RootDirectory
= NULL
;
2046 fri
->FileNameLength
= name_str
.Length
;
2047 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
2048 pRtlFreeUnicodeString( &name_str
);
2050 U(io
).Status
= 0xdeadbeef;
2051 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
2052 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
2053 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %lx\n", res
);
2054 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2055 ok( !fileDeleted
, "file should exist\n" );
2056 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2057 ok( !fileDeleted
, "file should exist\n" );
2059 CloseHandle( handle
);
2060 HeapFree( GetProcessHeap(), 0, fri
);
2061 delete_object( oldpath
);
2062 delete_object( newpath
);
2064 /* oldpath is a file, newpath is a directory, Replace = TRUE */
2065 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2066 ok( res
!= 0, "failed to create temp file\n" );
2067 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2068 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2070 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2071 ok( res
!= 0, "failed to create temp file\n" );
2072 DeleteFileW( newpath
);
2073 success
= CreateDirectoryW( newpath
, NULL
);
2074 ok( success
!= 0, "failed to create temp directory\n" );
2075 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2076 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
2077 fri
->ReplaceIfExists
= TRUE
;
2078 fri
->RootDirectory
= NULL
;
2079 fri
->FileNameLength
= name_str
.Length
;
2080 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
2081 pRtlFreeUnicodeString( &name_str
);
2083 U(io
).Status
= 0xdeadbeef;
2084 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
2085 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
2086 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %lx\n", res
);
2087 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2088 ok( !fileDeleted
, "file should exist\n" );
2089 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2090 ok( !fileDeleted
, "file should exist\n" );
2092 CloseHandle( handle
);
2093 HeapFree( GetProcessHeap(), 0, fri
);
2094 delete_object( oldpath
);
2095 delete_object( newpath
);
2097 /* oldpath is a file, newpath doesn't exist, test with RootDir != NULL */
2098 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2099 ok( res
!= 0, "failed to create temp file\n" );
2100 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2101 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2103 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2104 ok( res
!= 0, "failed to create temp file\n" );
2105 DeleteFileW( newpath
);
2106 for (filename
= newpath
, p
= newpath
; *p
; p
++)
2107 if (*p
== '\\') filename
= p
+ 1;
2108 handle2
= CreateFileW( tmp_path
, 0, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2109 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2111 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + lstrlenW(filename
) * sizeof(WCHAR
) );
2112 fri
->ReplaceIfExists
= FALSE
;
2113 fri
->RootDirectory
= handle2
;
2114 fri
->FileNameLength
= lstrlenW(filename
) * sizeof(WCHAR
);
2115 memcpy( fri
->FileName
, filename
, fri
->FileNameLength
);
2117 U(io
).Status
= 0xdeadbeef;
2118 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
2119 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %lx\n", U(io
).Status
);
2120 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %lx\n", res
);
2121 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2122 ok( fileDeleted
, "file should not exist\n" );
2123 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2124 ok( !fileDeleted
, "file should exist\n" );
2126 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2127 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2128 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %lx\n", res
);
2129 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2130 ok( !lstrcmpiW(fni
->FileName
, newpath
+ 2), "FileName expected %s, got %s\n",
2131 wine_dbgstr_w(newpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2132 HeapFree( GetProcessHeap(), 0, fni
);
2134 CloseHandle( handle
);
2135 CloseHandle( handle2
);
2136 HeapFree( GetProcessHeap(), 0, fri
);
2137 delete_object( oldpath
);
2138 delete_object( newpath
);
2140 /* oldpath == newpath */
2141 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2142 ok( res
!= 0, "failed to create temp file\n" );
2143 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2144 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2146 pRtlDosPathNameToNtPathName_U( oldpath
, &name_str
, NULL
, NULL
);
2147 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
2148 fri
->ReplaceIfExists
= FALSE
;
2149 fri
->RootDirectory
= NULL
;
2150 fri
->FileNameLength
= name_str
.Length
;
2151 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
2152 pRtlFreeUnicodeString( &name_str
);
2154 U(io
).Status
= 0xdeadbeef;
2155 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
2156 ok( U(io
).Status
== STATUS_SUCCESS
, "got io status %#lx\n", U(io
).Status
);
2157 ok( res
== STATUS_SUCCESS
, "got status %lx\n", res
);
2158 ok( GetFileAttributesW( oldpath
) != INVALID_FILE_ATTRIBUTES
, "file should exist\n" );
2160 CloseHandle( handle
);
2161 HeapFree( GetProcessHeap(), 0, fri
);
2162 delete_object( oldpath
);
2165 static void test_file_link_information(void)
2167 static const WCHAR foo_txtW
[] = {'\\','f','o','o','.','t','x','t',0};
2168 static const WCHAR fooW
[] = {'f','o','o',0};
2169 WCHAR tmp_path
[MAX_PATH
], oldpath
[MAX_PATH
+ 16], newpath
[MAX_PATH
+ 16], *filename
, *p
;
2170 FILE_LINK_INFORMATION
*fli
;
2171 FILE_NAME_INFORMATION
*fni
;
2172 WIN32_FIND_DATAW find_data
;
2173 BOOL success
, fileDeleted
;
2174 UNICODE_STRING name_str
;
2175 HANDLE handle
, handle2
;
2179 GetTempPathW( MAX_PATH
, tmp_path
);
2181 /* oldpath is a file, newpath doesn't exist */
2182 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2183 ok( res
!= 0, "failed to create temp file\n" );
2184 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2185 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2187 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2188 ok( res
!= 0, "failed to create temp file\n" );
2189 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2190 DeleteFileW( newpath
);
2191 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2192 fli
->ReplaceIfExists
= FALSE
;
2193 fli
->RootDirectory
= NULL
;
2194 fli
->FileNameLength
= name_str
.Length
;
2195 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2196 pRtlFreeUnicodeString( &name_str
);
2198 U(io
).Status
= 0xdeadbeef;
2199 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2200 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %lx\n", U(io
).Status
);
2201 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %lx\n", res
);
2202 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2203 ok( !fileDeleted
, "file should exist\n" );
2204 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2205 ok( !fileDeleted
, "file should exist\n" );
2207 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2208 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2209 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %lx\n", res
);
2210 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2211 ok( !lstrcmpiW(fni
->FileName
, oldpath
+ 2), "FileName expected %s, got %s\n",
2212 wine_dbgstr_w(oldpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2213 HeapFree( GetProcessHeap(), 0, fni
);
2215 CloseHandle( handle
);
2216 HeapFree( GetProcessHeap(), 0, fli
);
2217 delete_object( oldpath
);
2218 delete_object( newpath
);
2220 /* oldpath is a file, newpath is a file, ReplaceIfExists = FALSE */
2221 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2222 ok( res
!= 0, "failed to create temp file\n" );
2223 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2224 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2226 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2227 ok( res
!= 0, "failed to create temp file\n" );
2228 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2229 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2230 fli
->ReplaceIfExists
= FALSE
;
2231 fli
->RootDirectory
= NULL
;
2232 fli
->FileNameLength
= name_str
.Length
;
2233 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2234 pRtlFreeUnicodeString( &name_str
);
2236 U(io
).Status
= 0xdeadbeef;
2237 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2238 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
2239 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %lx\n", res
);
2240 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2241 ok( !fileDeleted
, "file should exist\n" );
2242 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2243 ok( !fileDeleted
, "file should exist\n" );
2245 CloseHandle( handle
);
2246 HeapFree( GetProcessHeap(), 0, fli
);
2247 delete_object( oldpath
);
2248 delete_object( newpath
);
2250 /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE */
2251 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2252 ok( res
!= 0, "failed to create temp file\n" );
2253 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2254 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2256 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2257 ok( res
!= 0, "failed to create temp file\n" );
2258 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2259 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2260 fli
->ReplaceIfExists
= TRUE
;
2261 fli
->RootDirectory
= NULL
;
2262 fli
->FileNameLength
= name_str
.Length
;
2263 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2264 pRtlFreeUnicodeString( &name_str
);
2266 U(io
).Status
= 0xdeadbeef;
2267 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2268 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %lx\n", U(io
).Status
);
2269 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %lx\n", res
);
2270 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2271 ok( !fileDeleted
, "file should exist\n" );
2272 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2273 ok( !fileDeleted
, "file should exist\n" );
2275 CloseHandle( handle
);
2276 HeapFree( GetProcessHeap(), 0, fli
);
2277 delete_object( oldpath
);
2278 delete_object( newpath
);
2280 /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE, different casing on link */
2281 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2282 ok( res
!= 0, "failed to create temp file\n" );
2283 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2284 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2286 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2287 ok( res
!= 0, "failed to create temp file\n" );
2288 wcsrchr( newpath
, '\\' )[1] = 'F';
2289 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2290 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2291 fli
->ReplaceIfExists
= TRUE
;
2292 fli
->RootDirectory
= NULL
;
2293 fli
->FileNameLength
= name_str
.Length
;
2294 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2295 pRtlFreeUnicodeString( &name_str
);
2297 U(io
).Status
= 0xdeadbeef;
2298 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2299 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %lx\n", U(io
).Status
);
2300 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %lx\n", res
);
2301 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2302 ok( !fileDeleted
, "file should exist\n" );
2303 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2304 ok( !fileDeleted
, "file should exist\n" );
2306 CloseHandle( handle
);
2307 handle
= FindFirstFileW( newpath
, &find_data
);
2308 ok(handle
!= INVALID_HANDLE_VALUE
, "FindFirstFileW: failed, error %ld\n", GetLastError());
2309 if (handle
!= INVALID_HANDLE_VALUE
)
2311 todo_wine
ok(!lstrcmpW(wcsrchr(newpath
, '\\') + 1, find_data
.cFileName
),
2312 "Link did not change casing on existing target file: got %s\n", wine_dbgstr_w(find_data
.cFileName
));
2315 FindClose( handle
);
2316 HeapFree( GetProcessHeap(), 0, fli
);
2317 delete_object( oldpath
);
2318 delete_object( newpath
);
2320 /* oldpath is a file, newpath is a file, ReplaceIfExists = FALSE, target file opened */
2321 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2322 ok( res
!= 0, "failed to create temp file\n" );
2323 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2324 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2326 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2327 ok( res
!= 0, "failed to create temp file\n" );
2328 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2329 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2331 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2332 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2333 fli
->ReplaceIfExists
= FALSE
;
2334 fli
->RootDirectory
= NULL
;
2335 fli
->FileNameLength
= name_str
.Length
;
2336 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2337 pRtlFreeUnicodeString( &name_str
);
2339 U(io
).Status
= 0xdeadbeef;
2340 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2341 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
2342 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %lx\n", res
);
2343 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2344 ok( !fileDeleted
, "file should exist\n" );
2345 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2346 ok( !fileDeleted
, "file should exist\n" );
2348 CloseHandle( handle
);
2349 CloseHandle( handle2
);
2350 HeapFree( GetProcessHeap(), 0, fli
);
2351 delete_object( oldpath
);
2352 delete_object( newpath
);
2354 /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE, target file opened */
2355 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2356 ok( res
!= 0, "failed to create temp file\n" );
2357 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2358 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2360 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2361 ok( res
!= 0, "failed to create temp file\n" );
2362 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2363 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2365 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2366 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2367 fli
->ReplaceIfExists
= TRUE
;
2368 fli
->RootDirectory
= NULL
;
2369 fli
->FileNameLength
= name_str
.Length
;
2370 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2371 pRtlFreeUnicodeString( &name_str
);
2373 U(io
).Status
= 0xdeadbeef;
2374 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2375 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
2376 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %lx\n", res
);
2377 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2378 ok( !fileDeleted
, "file should exist\n" );
2379 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2380 ok( !fileDeleted
, "file should exist\n" );
2382 CloseHandle( handle
);
2383 CloseHandle( handle2
);
2384 HeapFree( GetProcessHeap(), 0, fli
);
2385 delete_object( oldpath
);
2386 delete_object( newpath
);
2388 /* oldpath is a directory, newpath doesn't exist, ReplaceIfExists = FALSE */
2389 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2390 ok( res
!= 0, "failed to create temp file\n" );
2391 DeleteFileW( oldpath
);
2392 success
= CreateDirectoryW( oldpath
, NULL
);
2393 ok( success
!= 0, "failed to create temp directory\n" );
2394 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2395 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2397 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2398 ok( res
!= 0, "failed to create temp file\n" );
2399 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2400 DeleteFileW( newpath
);
2401 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2402 fli
->ReplaceIfExists
= FALSE
;
2403 fli
->RootDirectory
= NULL
;
2404 fli
->FileNameLength
= name_str
.Length
;
2405 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2406 pRtlFreeUnicodeString( &name_str
);
2408 U(io
).Status
= 0xdeadbeef;
2409 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2410 todo_wine
ok( U(io
).Status
== 0xdeadbeef , "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
2411 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %lx\n", res
);
2412 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2413 ok( !fileDeleted
, "file should exist\n" );
2414 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2415 ok( fileDeleted
, "file should not exist\n" );
2417 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2418 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2419 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %lx\n", res
);
2420 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2421 ok( !lstrcmpiW(fni
->FileName
, oldpath
+ 2), "FileName expected %s, got %s\n",
2422 wine_dbgstr_w(oldpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2423 HeapFree( GetProcessHeap(), 0, fni
);
2425 CloseHandle( handle
);
2426 HeapFree( GetProcessHeap(), 0, fli
);
2427 delete_object( oldpath
);
2428 delete_object( newpath
);
2430 /* oldpath is a directory (but child object opened), newpath doesn't exist, ReplaceIfExists = FALSE */
2431 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2432 ok( res
!= 0, "failed to create temp file\n" );
2433 DeleteFileW( oldpath
);
2434 success
= CreateDirectoryW( oldpath
, NULL
);
2435 ok( success
!= 0, "failed to create temp directory\n" );
2436 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2437 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2439 lstrcpyW( newpath
, oldpath
);
2440 lstrcatW( newpath
, foo_txtW
);
2441 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0 );
2442 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2444 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2445 ok( res
!= 0, "failed to create temp file\n" );
2446 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2447 DeleteFileW( newpath
);
2448 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2449 fli
->ReplaceIfExists
= FALSE
;
2450 fli
->RootDirectory
= NULL
;
2451 fli
->FileNameLength
= name_str
.Length
;
2452 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2453 pRtlFreeUnicodeString( &name_str
);
2455 U(io
).Status
= 0xdeadbeef;
2456 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2457 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
2458 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %lx\n", res
);
2459 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2460 ok( !fileDeleted
, "file should exist\n" );
2461 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2462 ok( fileDeleted
, "file should not exist\n" );
2464 CloseHandle( handle
);
2465 CloseHandle( handle2
);
2466 HeapFree( GetProcessHeap(), 0, fli
);
2467 delete_object( oldpath
);
2468 delete_object( newpath
);
2470 /* oldpath is a directory, newpath is a file, ReplaceIfExists = FALSE */
2471 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2472 ok( res
!= 0, "failed to create temp file\n" );
2473 DeleteFileW( oldpath
);
2474 success
= CreateDirectoryW( oldpath
, NULL
);
2475 ok( success
!= 0, "failed to create temp directory\n" );
2476 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2477 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2479 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2480 ok( res
!= 0, "failed to create temp file\n" );
2481 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2482 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2483 fli
->ReplaceIfExists
= FALSE
;
2484 fli
->RootDirectory
= NULL
;
2485 fli
->FileNameLength
= name_str
.Length
;
2486 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2487 pRtlFreeUnicodeString( &name_str
);
2489 U(io
).Status
= 0xdeadbeef;
2490 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2491 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
2492 ok( res
== STATUS_OBJECT_NAME_COLLISION
|| res
== STATUS_FILE_IS_A_DIRECTORY
/* > Win XP */,
2493 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %lx\n", res
);
2494 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2495 ok( !fileDeleted
, "file should exist\n" );
2496 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2497 ok( !fileDeleted
, "file should exist\n" );
2499 CloseHandle( handle
);
2500 HeapFree( GetProcessHeap(), 0, fli
);
2501 delete_object( oldpath
);
2502 delete_object( newpath
);
2504 /* oldpath is a directory, newpath is a file, ReplaceIfExists = FALSE, target file opened */
2505 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2506 ok( res
!= 0, "failed to create temp file\n" );
2507 DeleteFileW( oldpath
);
2508 success
= CreateDirectoryW( oldpath
, NULL
);
2509 ok( success
!= 0, "failed to create temp directory\n" );
2510 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2511 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2513 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2514 ok( res
!= 0, "failed to create temp file\n" );
2515 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2516 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2518 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2519 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2520 fli
->ReplaceIfExists
= FALSE
;
2521 fli
->RootDirectory
= NULL
;
2522 fli
->FileNameLength
= name_str
.Length
;
2523 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2524 pRtlFreeUnicodeString( &name_str
);
2526 U(io
).Status
= 0xdeadbeef;
2527 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2528 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
2529 ok( res
== STATUS_OBJECT_NAME_COLLISION
|| res
== STATUS_FILE_IS_A_DIRECTORY
/* > Win XP */,
2530 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %lx\n", res
);
2531 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2532 ok( !fileDeleted
, "file should exist\n" );
2533 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2534 ok( !fileDeleted
, "file should exist\n" );
2536 CloseHandle( handle
);
2537 CloseHandle( handle2
);
2538 HeapFree( GetProcessHeap(), 0, fli
);
2539 delete_object( oldpath
);
2540 delete_object( newpath
);
2542 /* oldpath is a directory, newpath is a file, ReplaceIfExists = TRUE */
2543 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2544 ok( res
!= 0, "failed to create temp file\n" );
2545 DeleteFileW( oldpath
);
2546 success
= CreateDirectoryW( oldpath
, NULL
);
2547 ok( success
!= 0, "failed to create temp directory\n" );
2548 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2549 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2551 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2552 ok( res
!= 0, "failed to create temp file\n" );
2553 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2554 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2555 fli
->ReplaceIfExists
= TRUE
;
2556 fli
->RootDirectory
= NULL
;
2557 fli
->FileNameLength
= name_str
.Length
;
2558 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2559 pRtlFreeUnicodeString( &name_str
);
2561 U(io
).Status
= 0xdeadbeef;
2562 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2563 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
2564 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %lx\n", res
);
2565 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2566 ok( !fileDeleted
, "file should exist\n" );
2567 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2568 ok( !fileDeleted
, "file should exist\n" );
2570 CloseHandle( handle
);
2571 HeapFree( GetProcessHeap(), 0, fli
);
2572 delete_object( oldpath
);
2573 delete_object( newpath
);
2575 /* oldpath is a directory, newpath is a file, ReplaceIfExists = TRUE, target file opened */
2576 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2577 ok( res
!= 0, "failed to create temp file\n" );
2578 DeleteFileW( oldpath
);
2579 success
= CreateDirectoryW( oldpath
, NULL
);
2580 ok( success
!= 0, "failed to create temp directory\n" );
2581 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2582 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2584 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2585 ok( res
!= 0, "failed to create temp file\n" );
2586 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2587 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2589 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2590 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2591 fli
->ReplaceIfExists
= TRUE
;
2592 fli
->RootDirectory
= NULL
;
2593 fli
->FileNameLength
= name_str
.Length
;
2594 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2595 pRtlFreeUnicodeString( &name_str
);
2597 U(io
).Status
= 0xdeadbeef;
2598 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2599 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
2600 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %lx\n", res
);
2601 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2602 ok( !fileDeleted
, "file should exist\n" );
2603 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2604 ok( !fileDeleted
, "file should exist\n" );
2606 CloseHandle( handle
);
2607 CloseHandle( handle2
);
2608 HeapFree( GetProcessHeap(), 0, fli
);
2609 delete_object( oldpath
);
2610 delete_object( newpath
);
2612 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = FALSE */
2613 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2614 ok( res
!= 0, "failed to create temp file\n" );
2615 DeleteFileW( oldpath
);
2616 success
= CreateDirectoryW( oldpath
, NULL
);
2617 ok( success
!= 0, "failed to create temp directory\n" );
2618 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2619 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2621 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2622 ok( res
!= 0, "failed to create temp file\n" );
2623 DeleteFileW( newpath
);
2624 success
= CreateDirectoryW( newpath
, NULL
);
2625 ok( success
!= 0, "failed to create temp directory\n" );
2626 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2627 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2628 fli
->ReplaceIfExists
= FALSE
;
2629 fli
->RootDirectory
= NULL
;
2630 fli
->FileNameLength
= name_str
.Length
;
2631 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2632 pRtlFreeUnicodeString( &name_str
);
2634 U(io
).Status
= 0xdeadbeef;
2635 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2636 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
2637 ok( res
== STATUS_OBJECT_NAME_COLLISION
|| res
== STATUS_FILE_IS_A_DIRECTORY
/* > Win XP */,
2638 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %lx\n", res
);
2639 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2640 ok( !fileDeleted
, "file should exist\n" );
2641 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2642 ok( !fileDeleted
, "file should exist\n" );
2644 CloseHandle( handle
);
2645 HeapFree( GetProcessHeap(), 0, fli
);
2646 delete_object( oldpath
);
2647 delete_object( newpath
);
2649 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = TRUE */
2650 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2651 ok( res
!= 0, "failed to create temp file\n" );
2652 DeleteFileW( oldpath
);
2653 success
= CreateDirectoryW( oldpath
, NULL
);
2654 ok( success
!= 0, "failed to create temp directory\n" );
2655 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2656 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2658 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2659 ok( res
!= 0, "failed to create temp file\n" );
2660 DeleteFileW( newpath
);
2661 success
= CreateDirectoryW( newpath
, NULL
);
2662 ok( success
!= 0, "failed to create temp directory\n" );
2663 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2664 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2665 fli
->ReplaceIfExists
= TRUE
;
2666 fli
->RootDirectory
= NULL
;
2667 fli
->FileNameLength
= name_str
.Length
;
2668 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2669 pRtlFreeUnicodeString( &name_str
);
2671 U(io
).Status
= 0xdeadbeef;
2672 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2673 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
2674 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %lx\n", res
);
2675 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2676 ok( !fileDeleted
, "file should exist\n" );
2677 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2678 ok( !fileDeleted
, "file should exist\n" );
2680 CloseHandle( handle
);
2681 HeapFree( GetProcessHeap(), 0, fli
);
2682 delete_object( oldpath
);
2683 delete_object( newpath
);
2685 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = TRUE, target file opened */
2686 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2687 ok( res
!= 0, "failed to create temp file\n" );
2688 DeleteFileW( oldpath
);
2689 success
= CreateDirectoryW( oldpath
, NULL
);
2690 ok( success
!= 0, "failed to create temp directory\n" );
2691 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2692 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2694 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2695 ok( res
!= 0, "failed to create temp file\n" );
2696 DeleteFileW( newpath
);
2697 success
= CreateDirectoryW( newpath
, NULL
);
2698 ok( success
!= 0, "failed to create temp directory\n" );
2699 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2700 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2702 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2703 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2704 fli
->ReplaceIfExists
= TRUE
;
2705 fli
->RootDirectory
= NULL
;
2706 fli
->FileNameLength
= name_str
.Length
;
2707 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2708 pRtlFreeUnicodeString( &name_str
);
2710 U(io
).Status
= 0xdeadbeef;
2711 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2712 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
2713 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %lx\n", res
);
2714 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2715 ok( !fileDeleted
, "file should exist\n" );
2716 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2717 ok( !fileDeleted
, "file should exist\n" );
2719 CloseHandle( handle
);
2720 CloseHandle( handle2
);
2721 HeapFree( GetProcessHeap(), 0, fli
);
2722 delete_object( oldpath
);
2723 delete_object( newpath
);
2725 /* oldpath is a file, newpath is a directory, ReplaceIfExists = FALSE */
2726 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2727 ok( res
!= 0, "failed to create temp file\n" );
2728 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2729 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2731 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2732 ok( res
!= 0, "failed to create temp file\n" );
2733 DeleteFileW( newpath
);
2734 success
= CreateDirectoryW( newpath
, NULL
);
2735 ok( success
!= 0, "failed to create temp directory\n" );
2736 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2737 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2738 fli
->ReplaceIfExists
= FALSE
;
2739 fli
->RootDirectory
= NULL
;
2740 fli
->FileNameLength
= name_str
.Length
;
2741 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2742 pRtlFreeUnicodeString( &name_str
);
2744 U(io
).Status
= 0xdeadbeef;
2745 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2746 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
2747 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %lx\n", res
);
2748 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2749 ok( !fileDeleted
, "file should exist\n" );
2750 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2751 ok( !fileDeleted
, "file should exist\n" );
2753 CloseHandle( handle
);
2754 HeapFree( GetProcessHeap(), 0, fli
);
2755 delete_object( oldpath
);
2756 delete_object( newpath
);
2758 /* oldpath is a file, newpath is a directory, ReplaceIfExists = TRUE */
2759 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2760 ok( res
!= 0, "failed to create temp file\n" );
2761 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2762 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2764 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2765 ok( res
!= 0, "failed to create temp file\n" );
2766 DeleteFileW( newpath
);
2767 success
= CreateDirectoryW( newpath
, NULL
);
2768 ok( success
!= 0, "failed to create temp directory\n" );
2769 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2770 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2771 fli
->ReplaceIfExists
= TRUE
;
2772 fli
->RootDirectory
= NULL
;
2773 fli
->FileNameLength
= name_str
.Length
;
2774 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2775 pRtlFreeUnicodeString( &name_str
);
2777 U(io
).Status
= 0xdeadbeef;
2778 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2779 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %lx\n", U(io
).Status
);
2780 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %lx\n", res
);
2781 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2782 ok( !fileDeleted
, "file should exist\n" );
2783 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2784 ok( !fileDeleted
, "file should exist\n" );
2786 CloseHandle( handle
);
2787 HeapFree( GetProcessHeap(), 0, fli
);
2788 delete_object( oldpath
);
2789 delete_object( newpath
);
2791 /* oldpath is a file, newpath doesn't exist, test with RootDirectory != NULL */
2792 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2793 ok( res
!= 0, "failed to create temp file\n" );
2794 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2795 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2797 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2798 ok( res
!= 0, "failed to create temp file\n" );
2799 DeleteFileW( newpath
);
2800 for (filename
= newpath
, p
= newpath
; *p
; p
++)
2801 if (*p
== '\\') filename
= p
+ 1;
2802 handle2
= CreateFileW( tmp_path
, 0, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2803 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2805 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + lstrlenW(filename
) * sizeof(WCHAR
) );
2806 fli
->ReplaceIfExists
= FALSE
;
2807 fli
->RootDirectory
= handle2
;
2808 fli
->FileNameLength
= lstrlenW(filename
) * sizeof(WCHAR
);
2809 memcpy( fli
->FileName
, filename
, fli
->FileNameLength
);
2811 U(io
).Status
= 0xdeadbeef;
2812 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2813 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %lx\n", U(io
).Status
);
2814 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %lx\n", res
);
2815 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2816 ok( !fileDeleted
, "file should exist\n" );
2817 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2818 ok( !fileDeleted
, "file should exist\n" );
2820 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2821 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2822 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %lx\n", res
);
2823 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2824 ok( !lstrcmpiW(fni
->FileName
, oldpath
+ 2), "FileName expected %s, got %s\n",
2825 wine_dbgstr_w(oldpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2826 HeapFree( GetProcessHeap(), 0, fni
);
2828 CloseHandle( handle
);
2829 CloseHandle( handle2
);
2830 HeapFree( GetProcessHeap(), 0, fli
);
2831 delete_object( oldpath
);
2832 delete_object( newpath
);
2834 /* oldpath == newpath */
2835 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2836 ok( res
!= 0, "failed to create temp file\n" );
2837 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2838 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2840 pRtlDosPathNameToNtPathName_U( oldpath
, &name_str
, NULL
, NULL
);
2841 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
2842 fli
->ReplaceIfExists
= FALSE
;
2843 fli
->RootDirectory
= NULL
;
2844 fli
->FileNameLength
= name_str
.Length
;
2845 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2846 pRtlFreeUnicodeString( &name_str
);
2848 U(io
).Status
= 0xdeadbeef;
2849 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2850 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "got io status %#lx\n", U(io
).Status
);
2851 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "got status %lx\n", res
);
2853 fli
->ReplaceIfExists
= TRUE
;
2854 U(io
).Status
= 0xdeadbeef;
2855 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2856 ok( U(io
).Status
== STATUS_SUCCESS
, "got io status %#lx\n", U(io
).Status
);
2857 ok( res
== STATUS_SUCCESS
, "got status %lx\n", res
);
2858 ok( GetFileAttributesW( oldpath
) != INVALID_FILE_ATTRIBUTES
, "file should exist\n" );
2860 CloseHandle( handle
);
2861 HeapFree( GetProcessHeap(), 0, fli
);
2862 delete_object( oldpath
);
2864 /* oldpath == newpath, different casing on link */
2865 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2866 ok( res
!= 0, "failed to create temp file\n" );
2867 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2868 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2870 wcsrchr( oldpath
, '\\' )[1] = 'F';
2871 pRtlDosPathNameToNtPathName_U( oldpath
, &name_str
, NULL
, NULL
);
2872 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
2873 fli
->ReplaceIfExists
= FALSE
;
2874 fli
->RootDirectory
= NULL
;
2875 fli
->FileNameLength
= name_str
.Length
;
2876 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2877 pRtlFreeUnicodeString( &name_str
);
2879 U(io
).Status
= 0xdeadbeef;
2880 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2881 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "got io status %#lx\n", U(io
).Status
);
2882 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "got status %lx\n", res
);
2884 fli
->ReplaceIfExists
= TRUE
;
2885 U(io
).Status
= 0xdeadbeef;
2886 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2887 ok( U(io
).Status
== STATUS_SUCCESS
, "got io status %#lx\n", U(io
).Status
);
2888 ok( res
== STATUS_SUCCESS
, "got status %lx\n", res
);
2889 ok( GetFileAttributesW( oldpath
) != INVALID_FILE_ATTRIBUTES
, "file should exist\n" );
2891 CloseHandle( handle
);
2892 handle
= FindFirstFileW( oldpath
, &find_data
);
2893 ok(handle
!= INVALID_HANDLE_VALUE
, "FindFirstFileW: failed, error %ld\n", GetLastError());
2894 if (handle
!= INVALID_HANDLE_VALUE
)
2896 todo_wine
ok(!lstrcmpW(wcsrchr(oldpath
, '\\') + 1, find_data
.cFileName
),
2897 "Link did not change casing on same file: got %s\n", wine_dbgstr_w(find_data
.cFileName
));
2900 FindClose( handle
);
2901 HeapFree( GetProcessHeap(), 0, fli
);
2902 delete_object( oldpath
);
2905 static void test_file_both_information(void)
2908 FILE_BOTH_DIR_INFORMATION fbi
;
2912 if (!(h
= create_temp_file(0))) return;
2914 memset(&fbi
, 0, sizeof(fbi
));
2915 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBothDirectoryInformation
);
2916 ok ( res
== STATUS_INVALID_INFO_CLASS
|| res
== STATUS_NOT_IMPLEMENTED
, "shouldn't be able to query FileBothDirectoryInformation, res %x\n", res
);
2921 static NTSTATUS
nt_get_file_attrs(const char *name
, DWORD
*attrs
)
2923 WCHAR nameW
[MAX_PATH
];
2924 FILE_BASIC_INFORMATION info
;
2925 UNICODE_STRING nt_name
;
2926 OBJECT_ATTRIBUTES attr
;
2929 MultiByteToWideChar( CP_ACP
, 0, name
, -1, nameW
, MAX_PATH
);
2931 *attrs
= INVALID_FILE_ATTRIBUTES
;
2933 if (!pRtlDosPathNameToNtPathName_U( nameW
, &nt_name
, NULL
, NULL
))
2934 return STATUS_UNSUCCESSFUL
;
2936 attr
.Length
= sizeof(attr
);
2937 attr
.RootDirectory
= 0;
2938 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
2939 attr
.ObjectName
= &nt_name
;
2940 attr
.SecurityDescriptor
= NULL
;
2941 attr
.SecurityQualityOfService
= NULL
;
2943 status
= pNtQueryAttributesFile( &attr
, &info
);
2944 pRtlFreeUnicodeString( &nt_name
);
2946 if (status
== STATUS_SUCCESS
)
2947 *attrs
= info
.FileAttributes
;
2952 static void test_file_disposition_information(void)
2954 char tmp_path
[MAX_PATH
], buffer
[MAX_PATH
+ 16];
2956 HANDLE handle
, handle2
, handle3
, mapping
;
2959 FILE_DISPOSITION_INFORMATION fdi
;
2964 GetTempPathA( MAX_PATH
, tmp_path
);
2966 /* tests for info struct size */
2967 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2968 handle
= CreateFileA( buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2969 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2970 res
= pNtSetInformationFile( handle
, &io
, &fdi
, 0, FileDispositionInformation
);
2972 ok( res
== STATUS_INFO_LENGTH_MISMATCH
, "expected STATUS_INFO_LENGTH_MISMATCH, got %lx\n", res
);
2974 res
= pNtSetInformationFile( handle
, &io
, &fdi2
, sizeof(fdi2
), FileDispositionInformation
);
2975 ok( res
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %lx\n", res
);
2976 CloseHandle( handle
);
2977 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2978 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2979 DeleteFileA( buffer
);
2981 /* cannot set disposition on file not opened with delete access */
2982 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2983 handle
= CreateFileA(buffer
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2984 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2985 res
= pNtQueryInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2986 ok( res
== STATUS_INVALID_INFO_CLASS
|| res
== STATUS_NOT_IMPLEMENTED
, "Unexpected NtQueryInformationFile result (expected STATUS_INVALID_INFO_CLASS, got %lx)\n", res
);
2987 fdi
.DoDeleteFile
= TRUE
;
2988 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2989 ok( res
== STATUS_ACCESS_DENIED
, "unexpected FileDispositionInformation result (expected STATUS_ACCESS_DENIED, got %lx)\n", res
);
2990 CloseHandle( handle
);
2991 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2992 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2993 DeleteFileA( buffer
);
2995 /* can set disposition on file opened with proper access */
2996 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2997 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2998 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2999 fdi
.DoDeleteFile
= TRUE
;
3000 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
3001 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %lx)\n", res
);
3002 CloseHandle( handle
);
3003 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3004 ok( fileDeleted
, "File should have been deleted\n" );
3006 /* file exists until all handles to it get closed */
3007 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3008 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, FILE_SHARE_DELETE
, NULL
, CREATE_ALWAYS
, 0, 0);
3009 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
3010 handle2
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0);
3011 ok( handle2
!= INVALID_HANDLE_VALUE
, "failed to open temp file\n" );
3012 fdi
.DoDeleteFile
= TRUE
;
3013 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
3014 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %lx)\n", res
);
3015 res
= nt_get_file_attrs( buffer
, &fdi2
);
3017 ok( res
== STATUS_DELETE_PENDING
, "got %#lx\n", res
);
3018 /* can't open the deleted file */
3019 handle3
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0);
3021 ok( handle3
== INVALID_HANDLE_VALUE
, "CreateFile should fail\n" );
3022 if (handle3
!= INVALID_HANDLE_VALUE
)
3023 CloseHandle( handle3
);
3025 ok(GetLastError() == ERROR_ACCESS_DENIED
, "got %lu\n", GetLastError());
3026 /* can't open the deleted file (wrong sharing mode) */
3027 handle3
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3028 ok( handle3
== INVALID_HANDLE_VALUE
, "CreateFile should fail\n" );
3030 ok(GetLastError() == ERROR_ACCESS_DENIED
, "got %lu\n", GetLastError());
3031 CloseHandle( handle
);
3032 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3033 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
3034 CloseHandle( handle2
);
3035 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3036 ok( fileDeleted
, "File should have been deleted\n" );
3038 /* file exists until all handles to it get closed */
3039 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3040 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, FILE_SHARE_DELETE
, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0);
3041 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
3042 /* can open the marked for delete file (proper sharing mode) */
3043 handle2
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0);
3044 ok( handle2
!= INVALID_HANDLE_VALUE
, "failed to open temp file\n" );
3045 res
= nt_get_file_attrs( buffer
, &fdi2
);
3046 ok( res
== STATUS_SUCCESS
, "got %#lx\n", res
);
3047 /* can't open the marked for delete file (wrong sharing mode) */
3048 handle3
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3049 ok( handle3
== INVALID_HANDLE_VALUE
, "CreateFile should fail\n" );
3050 ok(GetLastError() == ERROR_SHARING_VIOLATION
, "got %lu\n", GetLastError());
3051 CloseHandle( handle
);
3052 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3053 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
3054 CloseHandle( handle2
);
3055 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3056 ok( fileDeleted
, "File should have been deleted\n" );
3058 /* cannot set disposition on readonly file */
3059 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3060 DeleteFileA( buffer
);
3061 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_READONLY
, 0);
3062 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
3063 fdi
.DoDeleteFile
= TRUE
;
3064 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
3065 ok( res
== STATUS_CANNOT_DELETE
, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %lx)\n", res
);
3066 CloseHandle( handle
);
3067 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3068 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
3069 SetFileAttributesA( buffer
, FILE_ATTRIBUTE_NORMAL
);
3070 DeleteFileA( buffer
);
3072 /* cannot set disposition on readonly file */
3073 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3074 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_READONLY
, 0);
3075 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
3076 fdi
.DoDeleteFile
= TRUE
;
3077 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
3079 ok( res
== STATUS_CANNOT_DELETE
, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %lx)\n", res
);
3080 CloseHandle( handle
);
3081 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3083 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
3084 SetFileAttributesA( buffer
, FILE_ATTRIBUTE_NORMAL
);
3085 DeleteFileA( buffer
);
3087 /* can set disposition on file and then reset it */
3088 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3089 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
3090 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
3091 fdi
.DoDeleteFile
= TRUE
;
3092 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
3093 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %lx)\n", res
);
3094 fdi
.DoDeleteFile
= FALSE
;
3095 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
3096 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %lx)\n", res
);
3097 CloseHandle( handle
);
3098 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3099 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
3100 DeleteFileA( buffer
);
3102 /* can't reset disposition if delete-on-close flag is specified */
3103 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3104 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0);
3105 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
3106 fdi
.DoDeleteFile
= FALSE
;
3107 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
3108 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %lx)\n", res
);
3109 CloseHandle( handle
);
3110 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3111 ok( fileDeleted
, "File should have been deleted\n" );
3113 /* can't reset disposition on duplicated handle if delete-on-close flag is specified */
3114 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3115 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0);
3116 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
3117 ok( DuplicateHandle( GetCurrentProcess(), handle
, GetCurrentProcess(), &handle2
, 0, FALSE
, DUPLICATE_SAME_ACCESS
), "DuplicateHandle failed\n" );
3118 CloseHandle( handle
);
3119 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3120 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
3121 fdi
.DoDeleteFile
= FALSE
;
3122 res
= pNtSetInformationFile( handle2
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
3123 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %lx)\n", res
);
3124 CloseHandle( handle2
);
3125 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3126 ok( fileDeleted
, "File should have been deleted\n" );
3128 /* DeleteFile fails for wrong sharing mode */
3129 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3130 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
3131 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
3132 fileDeleted
= DeleteFileA( buffer
);
3133 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
3134 ok(GetLastError() == ERROR_SHARING_VIOLATION
, "got %lu\n", GetLastError());
3135 CloseHandle( handle
);
3136 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3137 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
3138 DeleteFileA( buffer
);
3140 /* DeleteFile succeeds for proper sharing mode */
3141 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3142 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, FILE_SHARE_DELETE
, NULL
, CREATE_ALWAYS
, 0, 0);
3143 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
3144 fileDeleted
= DeleteFileA( buffer
);
3145 ok( fileDeleted
, "File should have been deleted\n" );
3146 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3147 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
3148 res
= nt_get_file_attrs( buffer
, &fdi2
);
3150 ok( res
== STATUS_DELETE_PENDING
, "got %#lx\n", res
);
3151 /* can't open the deleted file */
3152 handle2
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
, NULL
, OPEN_EXISTING
, 0, 0);
3153 ok( handle2
== INVALID_HANDLE_VALUE
, "CreateFile should fail\n" );
3155 ok(GetLastError() == ERROR_ACCESS_DENIED
, "got %lu\n", GetLastError());
3156 CloseHandle( handle
);
3157 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3158 ok( fileDeleted
, "File should have been deleted\n" );
3160 /* can set disposition on a directory opened with proper access */
3161 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3162 DeleteFileA( buffer
);
3163 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
3164 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
3165 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
3166 fdi
.DoDeleteFile
= TRUE
;
3167 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
3168 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %lx)\n", res
);
3169 CloseHandle( handle
);
3170 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3171 ok( fileDeleted
, "Directory should have been deleted\n" );
3173 /* RemoveDirectory fails for wrong sharing mode */
3174 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3175 DeleteFileA( buffer
);
3176 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
3177 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
3178 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
3179 fileDeleted
= RemoveDirectoryA( buffer
);
3180 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
3181 ok(GetLastError() == ERROR_SHARING_VIOLATION
, "got %lu\n", GetLastError());
3182 CloseHandle( handle
);
3183 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3184 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
3185 RemoveDirectoryA( buffer
);
3187 /* RemoveDirectory succeeds for proper sharing mode */
3188 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3189 DeleteFileA( buffer
);
3190 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
3191 handle
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
3192 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
3193 fileDeleted
= RemoveDirectoryA( buffer
);
3194 ok( fileDeleted
, "Directory should have been deleted\n" );
3195 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3196 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
3197 res
= nt_get_file_attrs( buffer
, &fdi2
);
3199 ok( res
== STATUS_DELETE_PENDING
, "got %#lx\n", res
);
3200 /* can't open the deleted directory */
3201 handle2
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
3203 ok( handle2
== INVALID_HANDLE_VALUE
, "CreateFile should fail\n" );
3205 ok(GetLastError() == ERROR_ACCESS_DENIED
, "got %lu\n", GetLastError());
3206 if (handle2
!= INVALID_HANDLE_VALUE
) CloseHandle( handle2
);
3207 CloseHandle( handle
);
3208 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3209 ok( fileDeleted
, "Directory should have been deleted\n" );
3211 /* directory exists until all handles to it get closed */
3212 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3213 DeleteFileA( buffer
);
3214 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
3215 handle
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
3216 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
3217 handle2
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
3218 ok( handle2
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
3219 fdi
.DoDeleteFile
= TRUE
;
3220 res
= pNtSetInformationFile( handle2
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
3221 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %lx)\n", res
);
3222 res
= nt_get_file_attrs( buffer
, &fdi2
);
3224 ok( res
== STATUS_DELETE_PENDING
, "got %#lx\n", res
);
3225 /* can't open the deleted directory */
3226 handle3
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
3228 ok( handle3
== INVALID_HANDLE_VALUE
, "CreateFile should fail\n" );
3229 if (handle3
!= INVALID_HANDLE_VALUE
)
3230 CloseHandle( handle3
);
3232 ok(GetLastError() == ERROR_ACCESS_DENIED
, "got %lu\n", GetLastError());
3233 /* can't open the deleted directory (wrong sharing mode) */
3234 handle3
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
3235 ok( handle3
== INVALID_HANDLE_VALUE
, "CreateFile should fail\n" );
3237 ok(GetLastError() == ERROR_ACCESS_DENIED
, "got %lu\n", GetLastError());
3238 CloseHandle( handle2
);
3239 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3240 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
3241 CloseHandle( handle
);
3242 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3243 ok( fileDeleted
, "Directory should have been deleted\n" );
3245 /* directory exists until all handles to it get closed */
3246 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3247 DeleteFileA( buffer
);
3248 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
3249 handle
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
| FILE_FLAG_DELETE_ON_CLOSE
, 0);
3250 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
3251 /* can open the marked for delete directory (proper sharing mode) */
3252 handle2
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
3253 ok( handle2
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
3254 /* can't open the marked for delete file (wrong sharing mode) */
3255 handle3
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
3256 ok( handle3
== INVALID_HANDLE_VALUE
, "CreateFile should fail\n" );
3257 ok(GetLastError() == ERROR_SHARING_VIOLATION
, "got %lu\n", GetLastError());
3258 CloseHandle( handle
);
3259 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3260 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
3261 CloseHandle( handle2
);
3262 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3263 ok( fileDeleted
, "Directory should have been deleted\n" );
3265 /* can open a non-empty directory with FILE_FLAG_DELETE_ON_CLOSE */
3266 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3267 DeleteFileA( buffer
);
3268 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
3269 dirpos
= lstrlenA( buffer
);
3270 lstrcpyA( buffer
+ dirpos
, "\\tst" );
3271 handle2
= CreateFileA(buffer
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
3272 CloseHandle( handle2
);
3273 buffer
[dirpos
] = '\0';
3274 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
| FILE_FLAG_DELETE_ON_CLOSE
, 0);
3275 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
3276 SetLastError(0xdeadbeef);
3277 CloseHandle( handle
);
3278 ok(GetLastError() == 0xdeadbeef, "got %lu\n", GetLastError());
3279 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3280 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
3281 buffer
[dirpos
] = '\\';
3282 fileDeleted
= DeleteFileA( buffer
);
3283 ok( fileDeleted
, "File should have been deleted\n" );
3284 buffer
[dirpos
] = '\0';
3285 fileDeleted
= RemoveDirectoryA( buffer
);
3286 ok( fileDeleted
, "Directory should have been deleted\n" );
3288 /* cannot set disposition on a non-empty directory */
3289 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3290 DeleteFileA( buffer
);
3291 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
3292 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
3293 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
3294 dirpos
= lstrlenA( buffer
);
3295 lstrcpyA( buffer
+ dirpos
, "\\tst" );
3296 handle2
= CreateFileA(buffer
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
3297 CloseHandle( handle2
);
3298 fdi
.DoDeleteFile
= TRUE
;
3299 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
3300 ok( res
== STATUS_DIRECTORY_NOT_EMPTY
, "unexpected FileDispositionInformation result (expected STATUS_DIRECTORY_NOT_EMPTY, got %lx)\n", res
);
3301 fileDeleted
= DeleteFileA( buffer
);
3302 ok( fileDeleted
, "File should have been deleted\n" );
3303 buffer
[dirpos
] = '\0';
3304 CloseHandle( handle
);
3305 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3306 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
3307 fileDeleted
= RemoveDirectoryA( buffer
);
3308 ok( fileDeleted
, "Directory should have been deleted\n" );
3310 /* a file with an open mapping handle cannot be deleted */
3312 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3313 handle
= CreateFileA( buffer
, GENERIC_READ
| GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
3314 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create file, error %lu\n", GetLastError() );
3315 WriteFile(handle
, "data", 4, &size
, NULL
);
3316 mapping
= CreateFileMappingA( handle
, NULL
, PAGE_READONLY
, 0, 4, NULL
);
3317 ok( !!mapping
, "failed to create mapping, error %lu\n", GetLastError() );
3319 fdi
.DoDeleteFile
= FALSE
;
3320 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof(fdi
), FileDispositionInformation
);
3321 ok( !res
, "got %#lx\n", res
);
3323 fdi
.DoDeleteFile
= TRUE
;
3324 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof(fdi
), FileDispositionInformation
);
3325 ok( res
== STATUS_CANNOT_DELETE
, "got %#lx\n", res
);
3326 res
= GetFileAttributesA( buffer
);
3327 ok( res
!= INVALID_FILE_ATTRIBUTES
, "expected file to exist\n" );
3329 CloseHandle( mapping
);
3330 CloseHandle( handle
);
3331 res
= DeleteFileA( buffer
);
3332 ok( res
, "got error %lu\n", GetLastError() );
3334 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3335 handle
= CreateFileA( buffer
, GENERIC_READ
| GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
3336 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create file, error %lu\n", GetLastError() );
3337 WriteFile(handle
, "data", 4, &size
, NULL
);
3338 mapping
= CreateFileMappingA( handle
, NULL
, PAGE_READONLY
, 0, 4, NULL
);
3339 ok( !!mapping
, "failed to create mapping, error %lu\n", GetLastError() );
3340 CloseHandle( mapping
);
3342 fdi
.DoDeleteFile
= TRUE
;
3343 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof(fdi
), FileDispositionInformation
);
3344 ok( !res
, "got %#lx\n", res
);
3346 CloseHandle( handle
);
3347 res
= DeleteFileA( buffer
);
3348 ok( !res
, "expected failure\n" );
3349 ok( GetLastError() == ERROR_FILE_NOT_FOUND
, "got error %lu\n", GetLastError() );
3351 /* a file with an open view cannot be deleted */
3353 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3354 handle
= CreateFileA( buffer
, GENERIC_READ
| GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
3355 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create file, error %lu\n", GetLastError() );
3356 WriteFile(handle
, "data", 4, &size
, NULL
);
3357 mapping
= CreateFileMappingA( handle
, NULL
, PAGE_READONLY
, 0, 4, NULL
);
3358 ok( !!mapping
, "failed to create mapping, error %lu\n", GetLastError() );
3359 view
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4 );
3360 ok( !!view
, "failed to map view, error %lu\n", GetLastError() );
3361 CloseHandle( mapping
);
3363 fdi
.DoDeleteFile
= FALSE
;
3364 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof(fdi
), FileDispositionInformation
);
3365 ok( !res
, "got %#lx\n", res
);
3367 fdi
.DoDeleteFile
= TRUE
;
3368 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof(fdi
), FileDispositionInformation
);
3369 ok( res
== STATUS_CANNOT_DELETE
, "got %#lx\n", res
);
3370 res
= GetFileAttributesA( buffer
);
3371 ok( res
!= INVALID_FILE_ATTRIBUTES
, "expected file to exist\n" );
3373 UnmapViewOfFile( view
);
3374 CloseHandle( handle
);
3375 res
= DeleteFileA( buffer
);
3376 ok( res
, "got error %lu\n", GetLastError() );
3378 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3379 handle
= CreateFileA( buffer
, GENERIC_READ
| GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
3380 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create file, error %lu\n", GetLastError() );
3381 WriteFile(handle
, "data", 4, &size
, NULL
);
3382 mapping
= CreateFileMappingA( handle
, NULL
, PAGE_READONLY
, 0, 4, NULL
);
3383 ok( !!mapping
, "failed to create mapping, error %lu\n", GetLastError() );
3384 view
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4 );
3385 ok( !!view
, "failed to map view, error %lu\n", GetLastError() );
3386 CloseHandle( mapping
);
3387 UnmapViewOfFile( view
);
3389 fdi
.DoDeleteFile
= TRUE
;
3390 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof(fdi
), FileDispositionInformation
);
3391 ok( !res
, "got %#lx\n", res
);
3393 CloseHandle( handle
);
3394 res
= DeleteFileA( buffer
);
3395 ok( !res
, "expected failure\n" );
3396 ok( GetLastError() == ERROR_FILE_NOT_FOUND
, "got error %lu\n", GetLastError() );
3399 static void test_file_name_information(void)
3401 WCHAR
*file_name
, *volume_prefix
, *expected
;
3402 FILE_NAME_INFORMATION
*info
;
3403 ULONG old_redir
= 1, tmp
;
3404 UINT file_name_size
;
3411 /* GetVolumePathName is not present before w2k */
3412 if (!pGetVolumePathNameW
) {
3413 win_skip("GetVolumePathNameW not found\n");
3417 file_name_size
= GetSystemDirectoryW( NULL
, 0 );
3418 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3419 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3420 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3422 len
= GetSystemDirectoryW( file_name
, file_name_size
);
3423 ok(len
== file_name_size
- 1,
3424 "GetSystemDirectoryW returned %u, expected %u.\n",
3425 len
, file_name_size
- 1);
3427 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3428 ok(len
, "GetVolumePathNameW failed.\n");
3430 len
= lstrlenW( volume_prefix
);
3431 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3432 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3433 expected
[file_name_size
- len
- 1] = '\0';
3435 /* A bit more than we actually need, but it keeps the calculation simple. */
3436 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3437 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3439 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( TRUE
, &old_redir
);
3440 h
= CreateFileW( file_name
, GENERIC_READ
,
3441 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3442 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3443 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( old_redir
, &tmp
);
3444 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3446 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
) - 1, FileNameInformation
);
3447 ok(hr
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryInformationFile returned %#lx.\n", hr
);
3449 memset( info
, 0xcc, info_size
);
3450 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
), FileNameInformation
);
3451 ok(hr
== STATUS_BUFFER_OVERFLOW
, "NtQueryInformationFile returned %#lx, expected %#lx.\n",
3452 hr
, STATUS_BUFFER_OVERFLOW
);
3453 ok(U(io
).Status
== STATUS_BUFFER_OVERFLOW
, "io.Status is %#lx, expected %#lx.\n",
3454 U(io
).Status
, STATUS_BUFFER_OVERFLOW
);
3455 ok(info
->FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
), "info->FileNameLength is %lu\n", info
->FileNameLength
);
3456 ok(info
->FileName
[2] == 0xcccc, "info->FileName[2] is %#x, expected 0xcccc.\n", info
->FileName
[2]);
3457 ok(CharLowerW((LPWSTR
)(UINT_PTR
)info
->FileName
[1]) == CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]),
3458 "info->FileName[1] is %p, expected %p.\n",
3459 CharLowerW((LPWSTR
)(UINT_PTR
)info
->FileName
[1]), CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]));
3460 ok(io
.Information
== sizeof(*info
), "io.Information is %Iu\n", io
.Information
);
3462 memset( info
, 0xcc, info_size
);
3463 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileNameInformation
);
3464 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#lx, expected %#lx.\n", hr
, STATUS_SUCCESS
);
3465 ok(U(io
).Status
== STATUS_SUCCESS
, "io.Status is %#lx, expected %#lx.\n", U(io
).Status
, STATUS_SUCCESS
);
3466 ok(info
->FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
), "info->FileNameLength is %lu\n", info
->FileNameLength
);
3467 ok(info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)] == 0xcccc, "info->FileName[len] is %#x, expected 0xcccc.\n",
3468 info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)]);
3469 info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)] = '\0';
3470 ok(!lstrcmpiW( info
->FileName
, expected
), "info->FileName is %s, expected %s.\n",
3471 wine_dbgstr_w( info
->FileName
), wine_dbgstr_w( expected
));
3472 ok(io
.Information
== FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
) + info
->FileNameLength
,
3473 "io.Information is %Iu, expected %lu.\n",
3474 io
.Information
, FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
) + info
->FileNameLength
);
3477 HeapFree( GetProcessHeap(), 0, info
);
3478 HeapFree( GetProcessHeap(), 0, expected
);
3479 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3481 if (old_redir
|| !pGetSystemWow64DirectoryW
|| !(file_name_size
= pGetSystemWow64DirectoryW( NULL
, 0 )))
3483 skip("Not running on WoW64, skipping test.\n");
3484 HeapFree( GetProcessHeap(), 0, file_name
);
3488 h
= CreateFileW( file_name
, GENERIC_READ
,
3489 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3490 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3491 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3492 HeapFree( GetProcessHeap(), 0, file_name
);
3494 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3495 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3496 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*expected
) );
3498 len
= pGetSystemWow64DirectoryW( file_name
, file_name_size
);
3499 ok(len
== file_name_size
- 1,
3500 "GetSystemWow64DirectoryW returned %u, expected %u.\n",
3501 len
, file_name_size
- 1);
3503 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3504 ok(len
, "GetVolumePathNameW failed.\n");
3506 len
= lstrlenW( volume_prefix
);
3507 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3508 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3509 expected
[file_name_size
- len
- 1] = '\0';
3511 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3512 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3514 memset( info
, 0xcc, info_size
);
3515 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileNameInformation
);
3516 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#lx, expected %#lx.\n", hr
, STATUS_SUCCESS
);
3517 info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)] = '\0';
3518 ok(!lstrcmpiW( info
->FileName
, expected
), "info->FileName is %s, expected %s.\n",
3519 wine_dbgstr_w( info
->FileName
), wine_dbgstr_w( expected
));
3522 HeapFree( GetProcessHeap(), 0, info
);
3523 HeapFree( GetProcessHeap(), 0, expected
);
3524 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3525 HeapFree( GetProcessHeap(), 0, file_name
);
3528 static void test_file_all_name_information(void)
3530 WCHAR
*file_name
, *volume_prefix
, *expected
;
3531 FILE_ALL_INFORMATION
*info
;
3532 ULONG old_redir
= 1, tmp
;
3533 UINT file_name_size
;
3540 /* GetVolumePathName is not present before w2k */
3541 if (!pGetVolumePathNameW
) {
3542 win_skip("GetVolumePathNameW not found\n");
3546 file_name_size
= GetSystemDirectoryW( NULL
, 0 );
3547 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3548 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3549 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3551 len
= GetSystemDirectoryW( file_name
, file_name_size
);
3552 ok(len
== file_name_size
- 1,
3553 "GetSystemDirectoryW returned %u, expected %u.\n",
3554 len
, file_name_size
- 1);
3556 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3557 ok(len
, "GetVolumePathNameW failed.\n");
3559 len
= lstrlenW( volume_prefix
);
3560 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3561 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3562 expected
[file_name_size
- len
- 1] = '\0';
3564 /* A bit more than we actually need, but it keeps the calculation simple. */
3565 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3566 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3568 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( TRUE
, &old_redir
);
3569 h
= CreateFileW( file_name
, GENERIC_READ
,
3570 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3571 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3572 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( old_redir
, &tmp
);
3573 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3575 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
) - 1, FileAllInformation
);
3576 ok(hr
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryInformationFile returned %#lx, expected %#lx.\n",
3577 hr
, STATUS_INFO_LENGTH_MISMATCH
);
3579 memset( info
, 0xcc, info_size
);
3580 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
), FileAllInformation
);
3581 ok(hr
== STATUS_BUFFER_OVERFLOW
, "NtQueryInformationFile returned %#lx, expected %#lx.\n",
3582 hr
, STATUS_BUFFER_OVERFLOW
);
3583 ok(U(io
).Status
== STATUS_BUFFER_OVERFLOW
, "io.Status is %#lx, expected %#lx.\n",
3584 U(io
).Status
, STATUS_BUFFER_OVERFLOW
);
3585 ok(info
->NameInformation
.FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
),
3586 "info->NameInformation.FileNameLength is %lu\n", info
->NameInformation
.FileNameLength
);
3587 ok(info
->NameInformation
.FileName
[2] == 0xcccc,
3588 "info->NameInformation.FileName[2] is %#x, expected 0xcccc.\n", info
->NameInformation
.FileName
[2]);
3589 ok(CharLowerW((LPWSTR
)(UINT_PTR
)info
->NameInformation
.FileName
[1]) == CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]),
3590 "info->NameInformation.FileName[1] is %p, expected %p.\n",
3591 CharLowerW((LPWSTR
)(UINT_PTR
)info
->NameInformation
.FileName
[1]), CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]));
3592 ok(io
.Information
== sizeof(*info
), "io.Information is %Iu\n", io
.Information
);
3594 memset( info
, 0xcc, info_size
);
3595 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileAllInformation
);
3596 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#lx, expected %#lx.\n", hr
, STATUS_SUCCESS
);
3597 ok(U(io
).Status
== STATUS_SUCCESS
, "io.Status is %#lx, expected %#lx.\n", U(io
).Status
, STATUS_SUCCESS
);
3598 ok(info
->NameInformation
.FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
),
3599 "info->NameInformation.FileNameLength is %lu\n", info
->NameInformation
.FileNameLength
);
3600 ok(info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)] == 0xcccc,
3601 "info->NameInformation.FileName[len] is %#x, expected 0xcccc.\n",
3602 info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)]);
3603 info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)] = '\0';
3604 ok(!lstrcmpiW( info
->NameInformation
.FileName
, expected
),
3605 "info->NameInformation.FileName is %s, expected %s.\n",
3606 wine_dbgstr_w( info
->NameInformation
.FileName
), wine_dbgstr_w( expected
));
3607 ok(io
.Information
== FIELD_OFFSET(FILE_ALL_INFORMATION
, NameInformation
.FileName
)
3608 + info
->NameInformation
.FileNameLength
,
3609 "io.Information is %Iu\n", io
.Information
);
3612 HeapFree( GetProcessHeap(), 0, info
);
3613 HeapFree( GetProcessHeap(), 0, expected
);
3614 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3616 if (old_redir
|| !pGetSystemWow64DirectoryW
|| !(file_name_size
= pGetSystemWow64DirectoryW( NULL
, 0 )))
3618 skip("Not running on WoW64, skipping test.\n");
3619 HeapFree( GetProcessHeap(), 0, file_name
);
3623 h
= CreateFileW( file_name
, GENERIC_READ
,
3624 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3625 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3626 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3627 HeapFree( GetProcessHeap(), 0, file_name
);
3629 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3630 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3631 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*expected
) );
3633 len
= pGetSystemWow64DirectoryW( file_name
, file_name_size
);
3634 ok(len
== file_name_size
- 1,
3635 "GetSystemWow64DirectoryW returned %u, expected %u.\n",
3636 len
, file_name_size
- 1);
3638 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3639 ok(len
, "GetVolumePathNameW failed.\n");
3641 len
= lstrlenW( volume_prefix
);
3642 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3643 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3644 expected
[file_name_size
- len
- 1] = '\0';
3646 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3647 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3649 memset( info
, 0xcc, info_size
);
3650 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileAllInformation
);
3651 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#lx, expected %#lx.\n", hr
, STATUS_SUCCESS
);
3652 info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)] = '\0';
3653 ok(!lstrcmpiW( info
->NameInformation
.FileName
, expected
), "info->NameInformation.FileName is %s, expected %s.\n",
3654 wine_dbgstr_w( info
->NameInformation
.FileName
), wine_dbgstr_w( expected
));
3657 HeapFree( GetProcessHeap(), 0, info
);
3658 HeapFree( GetProcessHeap(), 0, expected
);
3659 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3660 HeapFree( GetProcessHeap(), 0, file_name
);
3663 #define test_completion_flags(a,b) _test_completion_flags(__LINE__,a,b)
3664 static void _test_completion_flags(unsigned line
, HANDLE handle
, DWORD expected_flags
)
3666 FILE_IO_COMPLETION_NOTIFICATION_INFORMATION info
;
3670 info
.Flags
= 0xdeadbeef;
3671 status
= pNtQueryInformationFile(handle
, &io
, &info
, sizeof(info
),
3672 FileIoCompletionNotificationInformation
);
3673 ok_(__FILE__
,line
)(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08lx\n", status
);
3674 ok_(__FILE__
,line
)(io
.Status
== STATUS_SUCCESS
, "Status = %lx\n", io
.Status
);
3675 ok_(__FILE__
,line
)(io
.Information
== sizeof(info
), "Information = %Iu\n", io
.Information
);
3676 /* FILE_SKIP_SET_USER_EVENT_ON_FAST_IO is not supported on win2k3 */
3677 ok_(__FILE__
,line
)((info
.Flags
& ~FILE_SKIP_SET_USER_EVENT_ON_FAST_IO
) == expected_flags
,
3678 "got %08lx\n", info
.Flags
);
3681 static void test_file_completion_information(void)
3683 DECLSPEC_ALIGN(TEST_OVERLAPPED_READ_SIZE
) static unsigned char aligned_buf
[TEST_OVERLAPPED_READ_SIZE
];
3684 static const char buf
[] = "testdata";
3685 FILE_IO_COMPLETION_NOTIFICATION_INFORMATION info
;
3686 OVERLAPPED ov
, *pov
;
3695 if (!(h
= create_temp_file(0))) return;
3697 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
) - 1, FileIoCompletionNotificationInformation
);
3698 ok(status
== STATUS_INFO_LENGTH_MISMATCH
|| broken(status
== STATUS_INVALID_INFO_CLASS
/* XP */),
3699 "expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
3700 if (status
!= STATUS_INFO_LENGTH_MISMATCH
)
3702 win_skip("FileIoCompletionNotificationInformation class not supported\n");
3707 info
.Flags
= FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
;
3708 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3709 ok(status
== STATUS_INVALID_PARAMETER
, "expected STATUS_INVALID_PARAMETER, got %08lx\n", status
);
3712 if (!(h
= create_temp_file(FILE_FLAG_OVERLAPPED
))) return;
3714 info
.Flags
= FILE_SKIP_SET_EVENT_ON_HANDLE
;
3715 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3716 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08lx\n", status
);
3717 test_completion_flags(h
, FILE_SKIP_SET_EVENT_ON_HANDLE
);
3719 info
.Flags
= FILE_SKIP_SET_USER_EVENT_ON_FAST_IO
;
3720 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3721 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08lx\n", status
);
3722 test_completion_flags(h
, FILE_SKIP_SET_EVENT_ON_HANDLE
);
3725 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3726 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08lx\n", status
);
3727 test_completion_flags(h
, FILE_SKIP_SET_EVENT_ON_HANDLE
);
3729 info
.Flags
= FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
;
3730 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3731 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08lx\n", status
);
3732 test_completion_flags(h
, FILE_SKIP_SET_EVENT_ON_HANDLE
| FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
);
3734 info
.Flags
= 0xdeadbeef;
3735 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3736 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08lx\n", status
);
3737 test_completion_flags(h
, FILE_SKIP_SET_EVENT_ON_HANDLE
| FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
);
3740 if (!(h
= create_temp_file(FILE_FLAG_OVERLAPPED
))) return;
3741 test_completion_flags(h
, 0);
3743 memset(&ov
, 0, sizeof(ov
));
3744 ov
.hEvent
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
3745 port
= CreateIoCompletionPort(h
, NULL
, 0xdeadbeef, 0);
3746 ok(port
!= NULL
, "CreateIoCompletionPort failed, error %lu\n", GetLastError());
3748 for (i
= 0; i
< 10; i
++)
3750 SetLastError(0xdeadbeef);
3751 ret
= WriteFile(h
, buf
, sizeof(buf
), &num_bytes
, &ov
);
3752 ok((!ret
&& GetLastError() == ERROR_IO_PENDING
) || broken(ret
) /* Before Vista */,
3753 "Unexpected result %#x, GetLastError() %lu.\n", ret
, GetLastError());
3754 if (ret
|| GetLastError() != ERROR_IO_PENDING
) break;
3755 ret
= GetOverlappedResult(h
, &ov
, &num_bytes
, TRUE
);
3756 ok(ret
, "GetOverlappedResult failed, error %lu\n", GetLastError());
3757 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 1000);
3758 ok(ret
, "GetQueuedCompletionStatus failed, error %lu\n", GetLastError());
3763 ok(num_bytes
== sizeof(buf
), "expected sizeof(buf), got %lu\n", num_bytes
);
3767 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 1000);
3768 ok(ret
, "GetQueuedCompletionStatus failed, error %lu\n", GetLastError());
3769 ok(key
== 0xdeadbeef, "expected 0xdeadbeef, got %Ix\n", key
);
3770 ok(pov
== &ov
, "expected %p, got %p\n", &ov
, pov
);
3773 info
.Flags
= FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
;
3774 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3775 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08lx\n", status
);
3776 test_completion_flags(h
, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
);
3778 for (i
= 0; i
< 10; i
++)
3780 SetLastError(0xdeadbeef);
3781 ret
= WriteFile(h
, buf
, sizeof(buf
), &num_bytes
, &ov
);
3782 ok((!ret
&& GetLastError() == ERROR_IO_PENDING
) || broken(ret
) /* Before Vista */,
3783 "Unexpected result %#x, GetLastError() %lu.\n", ret
, GetLastError());
3784 if (ret
|| GetLastError() != ERROR_IO_PENDING
) break;
3785 ret
= GetOverlappedResult(h
, &ov
, &num_bytes
, TRUE
);
3786 ok(ret
, "GetOverlappedResult failed, error %lu\n", GetLastError());
3791 ok(num_bytes
== sizeof(buf
), "expected sizeof(buf), got %lu\n", num_bytes
);
3793 pov
= (void *)0xdeadbeef;
3794 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 500);
3795 ok(!ret
, "GetQueuedCompletionStatus succeeded\n");
3796 ok(pov
== NULL
, "expected NULL, got %p\n", pov
);
3800 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3801 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08lx\n", status
);
3802 test_completion_flags(h
, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
);
3804 for (i
= 0; i
< 10; i
++)
3806 SetLastError(0xdeadbeef);
3807 ret
= WriteFile(h
, buf
, sizeof(buf
), &num_bytes
, &ov
);
3808 ok((!ret
&& GetLastError() == ERROR_IO_PENDING
) || broken(ret
) /* Before Vista */,
3809 "Unexpected result %#x, GetLastError() %lu.\n", ret
, GetLastError());
3810 if (ret
|| GetLastError() != ERROR_IO_PENDING
) break;
3811 ret
= GetOverlappedResult(h
, &ov
, &num_bytes
, TRUE
);
3812 ok(ret
, "GetOverlappedResult failed, error %lu\n", GetLastError());
3813 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 1000);
3814 ok(ret
, "GetQueuedCompletionStatus failed, error %lu\n", GetLastError());
3819 ok(num_bytes
== sizeof(buf
), "expected sizeof(buf), got %lu\n", num_bytes
);
3821 pov
= (void *)0xdeadbeef;
3822 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 1000);
3823 ok(!ret
, "GetQueuedCompletionStatus succeeded\n");
3824 ok(pov
== NULL
, "expected NULL, got %p\n", pov
);
3830 if (!(h
= create_temp_file(FILE_FLAG_OVERLAPPED
| FILE_FLAG_NO_BUFFERING
)))
3833 port
= CreateIoCompletionPort(h
, NULL
, 0xdeadbeef, 0);
3834 ok(port
!= NULL
, "CreateIoCompletionPort failed, error %lu.\n", GetLastError());
3836 info
.Flags
= FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
;
3837 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3838 ok(status
== STATUS_SUCCESS
, "Expected STATUS_SUCCESS, got %#lx.\n", status
);
3839 test_completion_flags(h
, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
);
3841 ret
= WriteFile(h
, aligned_buf
, sizeof(aligned_buf
), &num_bytes
, &ov
);
3842 if (!ret
&& GetLastError() == ERROR_IO_PENDING
)
3844 ret
= GetOverlappedResult(h
, &ov
, &num_bytes
, TRUE
);
3845 ok(ret
, "GetOverlappedResult failed, error %lu.\n", GetLastError());
3846 ok(num_bytes
== sizeof(aligned_buf
), "expected sizeof(aligned_buf), got %lu.\n", num_bytes
);
3847 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 1000);
3848 ok(ret
, "GetQueuedCompletionStatus failed, error %lu.\n", GetLastError());
3850 ok(num_bytes
== sizeof(aligned_buf
), "expected sizeof(buf), got %lu.\n", num_bytes
);
3852 SetLastError(0xdeadbeef);
3853 ret
= ReadFile(h
, aligned_buf
, sizeof(aligned_buf
), &num_bytes
, &ov
);
3854 ok(!ret
&& GetLastError() == ERROR_IO_PENDING
, "Unexpected result, ret %#x, error %lu.\n",
3855 ret
, GetLastError());
3856 ret
= GetOverlappedResult(h
, &ov
, &num_bytes
, TRUE
);
3857 ok(ret
, "GetOverlappedResult failed, error %lu.\n", GetLastError());
3858 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 1000);
3859 ok(ret
, "GetQueuedCompletionStatus failed, error %lu.\n", GetLastError());
3861 CloseHandle(ov
.hEvent
);
3866 static void test_file_id_information(void)
3868 BY_HANDLE_FILE_INFORMATION info
;
3869 FILE_ID_INFORMATION fid
;
3876 if (!(h
= create_temp_file(0))) return;
3878 memset( &fid
, 0x11, sizeof(fid
) );
3879 status
= pNtQueryInformationFile( h
, &io
, &fid
, sizeof(fid
), FileIdInformation
);
3880 if (status
== STATUS_NOT_IMPLEMENTED
|| status
== STATUS_INVALID_INFO_CLASS
)
3882 win_skip( "FileIdInformation not supported\n" );
3887 memset( &info
, 0x22, sizeof(info
) );
3888 ret
= GetFileInformationByHandle( h
, &info
);
3889 ok( ret
, "GetFileInformationByHandle failed\n" );
3891 dwords
= (DWORD
*)&fid
.VolumeSerialNumber
;
3892 ok( dwords
[0] == info
.dwVolumeSerialNumber
, "expected %08lx, got %08lx\n",
3893 info
.dwVolumeSerialNumber
, dwords
[0] );
3894 ok( dwords
[1] != 0x11111111, "expected != 0x11111111\n" );
3896 dwords
= (DWORD
*)&fid
.FileId
;
3897 ok( dwords
[0] == info
.nFileIndexLow
, "expected %08lx, got %08lx\n", info
.nFileIndexLow
, dwords
[0] );
3898 ok( dwords
[1] == info
.nFileIndexHigh
, "expected %08lx, got %08lx\n", info
.nFileIndexHigh
, dwords
[1] );
3899 ok( dwords
[2] == 0, "expected 0, got %08lx\n", dwords
[2] );
3900 ok( dwords
[3] == 0, "expected 0, got %08lx\n", dwords
[3] );
3905 static void test_file_access_information(void)
3907 FILE_ACCESS_INFORMATION info
;
3912 if (!(h
= create_temp_file(0))) return;
3914 status
= pNtQueryInformationFile( h
, &io
, &info
, sizeof(info
) - 1, FileAccessInformation
);
3915 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status
);
3917 status
= pNtQueryInformationFile( (HANDLE
)0xdeadbeef, &io
, &info
, sizeof(info
), FileAccessInformation
);
3918 ok( status
== STATUS_INVALID_HANDLE
, "expected STATUS_INVALID_HANDLE, got %08lx\n", status
);
3920 memset(&info
, 0x11, sizeof(info
));
3921 status
= pNtQueryInformationFile( h
, &io
, &info
, sizeof(info
), FileAccessInformation
);
3922 ok( status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08lx\n", status
);
3923 ok( info
.AccessFlags
== 0x13019f, "got %08lx\n", info
.AccessFlags
);
3928 static void test_file_attribute_tag_information(void)
3930 FILE_ATTRIBUTE_TAG_INFORMATION info
;
3931 FILE_BASIC_INFORMATION fbi
= {};
3936 if (!(h
= create_temp_file(0))) return;
3938 status
= pNtQueryInformationFile( h
, &io
, &info
, sizeof(info
) - 1, FileAttributeTagInformation
);
3939 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "got %#lx\n", status
);
3941 status
= pNtQueryInformationFile( (HANDLE
)0xdeadbeef, &io
, &info
, sizeof(info
), FileAttributeTagInformation
);
3942 ok( status
== STATUS_INVALID_HANDLE
, "got %#lx\n", status
);
3944 memset(&info
, 0x11, sizeof(info
));
3945 status
= pNtQueryInformationFile( h
, &io
, &info
, sizeof(info
), FileAttributeTagInformation
);
3946 ok( status
== STATUS_SUCCESS
, "got %#lx\n", status
);
3947 info
.FileAttributes
&= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
;
3948 ok( info
.FileAttributes
== FILE_ATTRIBUTE_ARCHIVE
, "got attributes %#lx\n", info
.FileAttributes
);
3949 ok( !info
.ReparseTag
, "got reparse tag %#lx\n", info
.ReparseTag
);
3951 fbi
.FileAttributes
= FILE_ATTRIBUTE_SYSTEM
;
3952 status
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof(fbi
), FileBasicInformation
);
3953 ok( status
== STATUS_SUCCESS
, "got %#lx\n", status
);
3955 memset(&info
, 0x11, sizeof(info
));
3956 status
= pNtQueryInformationFile( h
, &io
, &info
, sizeof(info
), FileAttributeTagInformation
);
3957 ok( status
== STATUS_SUCCESS
, "got %#lx\n", status
);
3958 todo_wine
ok( info
.FileAttributes
== FILE_ATTRIBUTE_SYSTEM
, "got attributes %#lx\n", info
.FileAttributes
);
3959 ok( !info
.ReparseTag
, "got reparse tag %#lx\n", info
.ReparseTag
);
3961 fbi
.FileAttributes
= FILE_ATTRIBUTE_HIDDEN
;
3962 status
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
3963 ok( status
== STATUS_SUCCESS
, "got %#lx\n", status
);
3965 memset(&info
, 0x11, sizeof(info
));
3966 status
= pNtQueryInformationFile( h
, &io
, &info
, sizeof(info
), FileAttributeTagInformation
);
3967 ok( status
== STATUS_SUCCESS
, "got %#lx\n", status
);
3968 todo_wine
ok( info
.FileAttributes
== FILE_ATTRIBUTE_HIDDEN
, "got attributes %#lx\n", info
.FileAttributes
);
3969 ok( !info
.ReparseTag
, "got reparse tag %#lx\n", info
.ReparseTag
);
3974 static void test_file_mode(void)
3976 UNICODE_STRING file_name
, pipe_dev_name
, mountmgr_dev_name
, mailslot_dev_name
;
3977 WCHAR tmp_path
[MAX_PATH
], dos_file_name
[MAX_PATH
];
3978 FILE_MODE_INFORMATION mode
;
3979 OBJECT_ATTRIBUTES attr
;
3987 UNICODE_STRING
*file_name
;
3990 } option_tests
[] = {
3991 { &file_name
, 0, 0 },
3992 { &file_name
, FILE_NON_DIRECTORY_FILE
, 0 },
3993 { &file_name
, FILE_NON_DIRECTORY_FILE
| FILE_SEQUENTIAL_ONLY
, FILE_SEQUENTIAL_ONLY
},
3994 { &file_name
, FILE_WRITE_THROUGH
, FILE_WRITE_THROUGH
},
3995 { &file_name
, FILE_SYNCHRONOUS_IO_ALERT
, FILE_SYNCHRONOUS_IO_ALERT
},
3996 { &file_name
, FILE_NO_INTERMEDIATE_BUFFERING
, FILE_NO_INTERMEDIATE_BUFFERING
},
3997 { &file_name
, FILE_SYNCHRONOUS_IO_NONALERT
| FILE_NON_DIRECTORY_FILE
, FILE_SYNCHRONOUS_IO_NONALERT
},
3998 { &file_name
, FILE_DELETE_ON_CLOSE
, 0 },
3999 { &file_name
, FILE_RANDOM_ACCESS
| FILE_NO_COMPRESSION
, 0 },
4000 { &pipe_dev_name
, 0, 0 },
4001 { &pipe_dev_name
, FILE_SYNCHRONOUS_IO_ALERT
, FILE_SYNCHRONOUS_IO_ALERT
},
4002 { &mailslot_dev_name
, 0, 0 },
4003 { &mailslot_dev_name
, FILE_SYNCHRONOUS_IO_ALERT
, FILE_SYNCHRONOUS_IO_ALERT
},
4004 { &mountmgr_dev_name
, 0, 0 },
4005 { &mountmgr_dev_name
, FILE_SYNCHRONOUS_IO_ALERT
, FILE_SYNCHRONOUS_IO_ALERT
}
4008 static WCHAR pipe_devW
[] = {'\\','?','?','\\','P','I','P','E','\\'};
4009 static WCHAR mailslot_devW
[] = {'\\','?','?','\\','M','A','I','L','S','L','O','T','\\'};
4010 static WCHAR mountmgr_devW
[] =
4011 {'\\','?','?','\\','M','o','u','n','t','P','o','i','n','t','M','a','n','a','g','e','r'};
4013 GetTempPathW(MAX_PATH
, tmp_path
);
4014 res
= GetTempFileNameW(tmp_path
, fooW
, 0, dos_file_name
);
4015 ok(res
, "GetTempFileNameW failed: %lu\n", GetLastError());
4016 pRtlDosPathNameToNtPathName_U( dos_file_name
, &file_name
, NULL
, NULL
);
4018 pipe_dev_name
.Buffer
= pipe_devW
;
4019 pipe_dev_name
.Length
= sizeof(pipe_devW
);
4020 pipe_dev_name
.MaximumLength
= sizeof(pipe_devW
);
4022 mailslot_dev_name
.Buffer
= mailslot_devW
;
4023 mailslot_dev_name
.Length
= sizeof(mailslot_devW
);
4024 mailslot_dev_name
.MaximumLength
= sizeof(mailslot_devW
);
4026 mountmgr_dev_name
.Buffer
= mountmgr_devW
;
4027 mountmgr_dev_name
.Length
= sizeof(mountmgr_devW
);
4028 mountmgr_dev_name
.MaximumLength
= sizeof(mountmgr_devW
);
4030 attr
.Length
= sizeof(attr
);
4031 attr
.RootDirectory
= 0;
4032 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
4033 attr
.SecurityDescriptor
= NULL
;
4034 attr
.SecurityQualityOfService
= NULL
;
4036 for (i
= 0; i
< ARRAY_SIZE(option_tests
); i
++)
4038 attr
.ObjectName
= option_tests
[i
].file_name
;
4039 access
= SYNCHRONIZE
;
4041 if (option_tests
[i
].file_name
== &file_name
)
4043 file
= CreateFileW(dos_file_name
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
4044 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %lu\n", GetLastError());
4046 access
|= GENERIC_WRITE
| DELETE
;
4049 status
= pNtOpenFile(&file
, access
, &attr
, &io
, 0, option_tests
[i
].options
);
4050 ok(status
== STATUS_SUCCESS
, "[%u] NtOpenFile failed: %lx\n", i
, status
);
4052 memset(&mode
, 0xcc, sizeof(mode
));
4053 status
= pNtQueryInformationFile(file
, &io
, &mode
, sizeof(mode
), FileModeInformation
);
4054 ok(status
== STATUS_SUCCESS
, "[%u] can't get FileModeInformation: %lx\n", i
, status
);
4055 ok(mode
.Mode
== option_tests
[i
].mode
, "[%u] Mode = %lx, expected %lx\n",
4056 i
, mode
.Mode
, option_tests
[i
].mode
);
4059 if (option_tests
[i
].file_name
== &file_name
)
4060 DeleteFileW(dos_file_name
);
4063 pRtlFreeUnicodeString(&file_name
);
4066 static void test_query_volume_information_file(void)
4070 WCHAR path
[MAX_PATH
];
4071 OBJECT_ATTRIBUTES attr
;
4073 UNICODE_STRING nameW
;
4074 FILE_FS_VOLUME_INFORMATION
*ffvi
;
4075 BYTE buf
[sizeof(FILE_FS_VOLUME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
)];
4077 GetWindowsDirectoryW( path
, MAX_PATH
);
4078 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
4079 attr
.Length
= sizeof(attr
);
4080 attr
.RootDirectory
= 0;
4081 attr
.ObjectName
= &nameW
;
4082 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
4083 attr
.SecurityDescriptor
= NULL
;
4084 attr
.SecurityQualityOfService
= NULL
;
4086 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
4087 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
4088 ok( !status
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
4089 pRtlFreeUnicodeString( &nameW
);
4091 ZeroMemory( buf
, sizeof(buf
) );
4092 U(io
).Status
= 0xdadadada;
4093 io
.Information
= 0xcacacaca;
4095 status
= pNtQueryVolumeInformationFile( dir
, &io
, buf
, sizeof(buf
), FileFsVolumeInformation
);
4097 ffvi
= (FILE_FS_VOLUME_INFORMATION
*)buf
;
4099 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %ld\n", status
);
4100 ok(U(io
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %ld\n", U(io
).Status
);
4102 ok(io
.Information
== (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION
, VolumeLabel
) + ffvi
->VolumeLabelLength
),
4103 "expected %ld, got %Iu\n", (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION
, VolumeLabel
) + ffvi
->VolumeLabelLength
),
4106 todo_wine
ok(ffvi
->VolumeCreationTime
.QuadPart
!= 0, "Missing VolumeCreationTime\n");
4107 ok(ffvi
->VolumeSerialNumber
!= 0, "Missing VolumeSerialNumber\n");
4108 ok(ffvi
->SupportsObjects
== 1,"expected 1, got %d\n", ffvi
->SupportsObjects
);
4109 ok(ffvi
->VolumeLabelLength
== lstrlenW(ffvi
->VolumeLabel
) * sizeof(WCHAR
), "got %ld\n", ffvi
->VolumeLabelLength
);
4111 trace("VolumeSerialNumber: %lx VolumeLabelName: %s\n", ffvi
->VolumeSerialNumber
, wine_dbgstr_w(ffvi
->VolumeLabel
));
4116 static void test_query_attribute_information_file(void)
4120 WCHAR path
[MAX_PATH
];
4121 OBJECT_ATTRIBUTES attr
;
4123 UNICODE_STRING nameW
;
4124 FILE_FS_ATTRIBUTE_INFORMATION
*ffai
;
4125 BYTE buf
[sizeof(FILE_FS_ATTRIBUTE_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
)];
4127 GetWindowsDirectoryW( path
, MAX_PATH
);
4128 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
4129 attr
.Length
= sizeof(attr
);
4130 attr
.RootDirectory
= 0;
4131 attr
.ObjectName
= &nameW
;
4132 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
4133 attr
.SecurityDescriptor
= NULL
;
4134 attr
.SecurityQualityOfService
= NULL
;
4136 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
4137 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
4138 ok( !status
, "open %s failed %lx\n", wine_dbgstr_w(nameW
.Buffer
), status
);
4139 pRtlFreeUnicodeString( &nameW
);
4141 ZeroMemory( buf
, sizeof(buf
) );
4142 U(io
).Status
= 0xdadadada;
4143 io
.Information
= 0xcacacaca;
4145 status
= pNtQueryVolumeInformationFile( dir
, &io
, buf
, sizeof(buf
), FileFsAttributeInformation
);
4147 ffai
= (FILE_FS_ATTRIBUTE_INFORMATION
*)buf
;
4149 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %ld\n", status
);
4150 ok(U(io
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %ld\n", U(io
).Status
);
4151 ok(ffai
->FileSystemAttributes
!= 0, "Missing FileSystemAttributes\n");
4152 ok(ffai
->MaximumComponentNameLength
!= 0, "Missing MaximumComponentNameLength\n");
4153 ok(ffai
->FileSystemNameLength
!= 0, "Missing FileSystemNameLength\n");
4155 trace("FileSystemAttributes: %lx MaximumComponentNameLength: %lx FileSystemName: %s\n",
4156 ffai
->FileSystemAttributes
, ffai
->MaximumComponentNameLength
,
4157 wine_dbgstr_wn(ffai
->FileSystemName
, ffai
->FileSystemNameLength
/ sizeof(WCHAR
)));
4162 static void test_NtCreateFile(void)
4164 static const struct test_data
4166 DWORD disposition
, attrib_in
, status
, result
, attrib_out
, needs_cleanup
;
4169 /* 0*/{ FILE_CREATE
, FILE_ATTRIBUTE_READONLY
, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
4170 /* 1*/{ FILE_CREATE
, 0, STATUS_OBJECT_NAME_COLLISION
, 0, 0, TRUE
},
4171 /* 2*/{ FILE_CREATE
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
4172 /* 3*/{ FILE_OPEN
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OPENED
, FILE_ATTRIBUTE_ARCHIVE
, TRUE
},
4173 /* 4*/{ FILE_OPEN
, FILE_ATTRIBUTE_READONLY
, STATUS_OBJECT_NAME_NOT_FOUND
, 0, 0, FALSE
},
4174 /* 5*/{ FILE_OPEN_IF
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
4175 /* 6*/{ FILE_OPEN_IF
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OPENED
, FILE_ATTRIBUTE_ARCHIVE
, TRUE
},
4176 /* 7*/{ FILE_OPEN_IF
, FILE_ATTRIBUTE_READONLY
, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
4177 /* 8*/{ FILE_OPEN_IF
, 0, 0, FILE_OPENED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
4178 /* 9*/{ FILE_OVERWRITE
, 0, STATUS_ACCESS_DENIED
, 0, 0, TRUE
},
4179 /*10*/{ FILE_OVERWRITE
, 0, STATUS_OBJECT_NAME_NOT_FOUND
, 0, 0, FALSE
},
4180 /*11*/{ FILE_CREATE
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
4181 /*12*/{ FILE_OVERWRITE
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OVERWRITTEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
4182 /*13*/{ FILE_OVERWRITE_IF
, 0, STATUS_ACCESS_DENIED
, 0, 0, TRUE
},
4183 /*14*/{ FILE_OVERWRITE_IF
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
4184 /*15*/{ FILE_OVERWRITE_IF
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OVERWRITTEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
4185 /*16*/{ FILE_SUPERSEDE
, 0, 0, FILE_SUPERSEDED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
4186 /*17*/{ FILE_SUPERSEDE
, FILE_ATTRIBUTE_READONLY
, 0, FILE_SUPERSEDED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, TRUE
},
4187 /*18*/{ FILE_SUPERSEDE
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, TRUE
}
4189 static const WCHAR fooW
[] = {'f','o','o',0};
4192 WCHAR path
[MAX_PATH
];
4193 OBJECT_ATTRIBUTES attr
;
4195 UNICODE_STRING nameW
;
4198 GetTempPathW(MAX_PATH
, path
);
4199 GetTempFileNameW(path
, fooW
, 0, path
);
4201 pRtlDosPathNameToNtPathName_U(path
, &nameW
, NULL
, NULL
);
4203 attr
.Length
= sizeof(attr
);
4204 attr
.RootDirectory
= NULL
;
4205 attr
.ObjectName
= &nameW
;
4206 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
4207 attr
.SecurityDescriptor
= NULL
;
4208 attr
.SecurityQualityOfService
= NULL
;
4210 for (i
= 0; i
< ARRAY_SIZE(td
); i
++)
4212 status
= pNtCreateFile(&handle
, GENERIC_READ
, &attr
, &io
, NULL
,
4213 td
[i
].attrib_in
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
4214 td
[i
].disposition
, 0, NULL
, 0);
4216 ok(status
== td
[i
].status
, "%ld: expected %#lx got %#lx\n", i
, td
[i
].status
, status
);
4220 ok(io
.Information
== td
[i
].result
,"%ld: expected %#lx got %#Ix\n", i
, td
[i
].result
, io
.Information
);
4222 ret
= GetFileAttributesW(path
);
4223 ret
&= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
;
4224 /* FIXME: leave only 'else' case below once Wine is fixed */
4225 if (ret
!= td
[i
].attrib_out
)
4228 ok(ret
== td
[i
].attrib_out
, "%ld: expected %#lx got %#lx\n", i
, td
[i
].attrib_out
, ret
);
4229 SetFileAttributesW(path
, td
[i
].attrib_out
);
4232 ok(ret
== td
[i
].attrib_out
, "%ld: expected %#lx got %#lx\n", i
, td
[i
].attrib_out
, ret
);
4234 CloseHandle(handle
);
4237 if (td
[i
].needs_cleanup
)
4239 SetFileAttributesW(path
, FILE_ATTRIBUTE_ARCHIVE
);
4244 pRtlFreeUnicodeString( &nameW
);
4245 SetFileAttributesW(path
, FILE_ATTRIBUTE_ARCHIVE
);
4246 DeleteFileW( path
);
4248 wcscat( path
, L
"\\" );
4249 pRtlDosPathNameToNtPathName_U(path
, &nameW
, NULL
, NULL
);
4251 status
= pNtCreateFile( &handle
, GENERIC_READ
, &attr
, &io
, NULL
,
4252 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_CREATE
, 0, NULL
, 0);
4253 ok( status
== STATUS_OBJECT_NAME_INVALID
, "failed %s %lx\n", debugstr_w(nameW
.Buffer
), status
);
4254 status
= pNtCreateFile( &handle
, GENERIC_READ
, &attr
, &io
, NULL
,
4255 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_CREATE
,
4256 FILE_DIRECTORY_FILE
, NULL
, 0);
4257 ok( !status
, "failed %s %lx\n", debugstr_w(nameW
.Buffer
), status
);
4258 RemoveDirectoryW( path
);
4261 static void test_read_write(void)
4263 static const char contents
[14] = "1234567890abcd";
4265 HANDLE hfile
, event
;
4267 IO_STATUS_BLOCK iob
;
4268 DWORD ret
, bytes
, status
, off
;
4269 LARGE_INTEGER offset
;
4272 event
= CreateEventA( NULL
, TRUE
, FALSE
, NULL
);
4275 iob
.Information
= -1;
4276 offset
.QuadPart
= 0;
4277 status
= pNtReadFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4278 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#lx\n", status
);
4279 ok(U(iob
).Status
== -1, "expected -1, got %#lx\n", U(iob
).Status
);
4280 ok(iob
.Information
== -1, "expected -1, got %Iu\n", iob
.Information
);
4283 iob
.Information
= -1;
4284 offset
.QuadPart
= 0;
4285 status
= pNtReadFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, NULL
, sizeof(buf
), &offset
, NULL
);
4286 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#lx\n", status
);
4287 ok(U(iob
).Status
== -1, "expected -1, got %#lx\n", U(iob
).Status
);
4288 ok(iob
.Information
== -1, "expected -1, got %Iu\n", iob
.Information
);
4291 iob
.Information
= -1;
4292 offset
.QuadPart
= 0;
4293 status
= pNtWriteFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4294 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#lx\n", status
);
4295 ok(U(iob
).Status
== -1, "expected -1, got %#lx\n", U(iob
).Status
);
4296 ok(iob
.Information
== -1, "expected -1, got %Iu\n", iob
.Information
);
4299 iob
.Information
= -1;
4300 offset
.QuadPart
= 0;
4301 status
= pNtWriteFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4302 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#lx\n", status
);
4303 ok(U(iob
).Status
== -1, "expected -1, got %#lx\n", U(iob
).Status
);
4304 ok(iob
.Information
== -1, "expected -1, got %Iu\n", iob
.Information
);
4306 hfile
= create_temp_file(0);
4310 iob
.Information
= -1;
4311 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
4312 ok(status
== STATUS_INVALID_USER_BUFFER
, "expected STATUS_INVALID_USER_BUFFER, got %#lx\n", status
);
4313 ok(U(iob
).Status
== -1, "expected -1, got %#lx\n", U(iob
).Status
);
4314 ok(iob
.Information
== -1, "expected -1, got %Iu\n", iob
.Information
);
4317 iob
.Information
= -1;
4319 status
= pNtWriteFile(hfile
, event
, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
4320 ok(status
== STATUS_INVALID_USER_BUFFER
, "expected STATUS_INVALID_USER_BUFFER, got %#lx\n", status
);
4321 ok(U(iob
).Status
== -1, "expected -1, got %#lx\n", U(iob
).Status
);
4322 ok(iob
.Information
== -1, "expected -1, got %Iu\n", iob
.Information
);
4323 ok(!is_signaled(event
), "event is not signaled\n");
4326 iob
.Information
= -1;
4327 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
4328 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#lx\n", status
);
4329 ok(U(iob
).Status
== -1, "expected -1, got %#lx\n", U(iob
).Status
);
4330 ok(iob
.Information
== -1, "expected -1, got %Iu\n", iob
.Information
);
4333 iob
.Information
= -1;
4335 status
= pNtReadFile(hfile
, event
, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
4336 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#lx\n", status
);
4337 ok(U(iob
).Status
== -1, "expected -1, got %#lx\n", U(iob
).Status
);
4338 ok(iob
.Information
== -1, "expected -1, got %Iu\n", iob
.Information
);
4339 ok(is_signaled(event
), "event is not signaled\n");
4342 iob
.Information
= -1;
4344 status
= pNtReadFile(hfile
, event
, NULL
, NULL
, &iob
, (void*)0xdeadbeef, sizeof(contents
), NULL
, NULL
);
4345 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#lx\n", status
);
4346 ok(U(iob
).Status
== -1, "expected -1, got %#lx\n", U(iob
).Status
);
4347 ok(iob
.Information
== -1, "expected -1, got %Iu\n", iob
.Information
);
4348 ok(is_signaled(event
), "event is not signaled\n");
4351 iob
.Information
= -1;
4352 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, 7, NULL
, NULL
);
4353 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#lx\n", status
);
4354 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iob
).Status
);
4355 ok(iob
.Information
== 7, "expected 7, got %Iu\n", iob
.Information
);
4357 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
4360 iob
.Information
= -1;
4361 offset
.QuadPart
= (LONGLONG
)-1 /* FILE_WRITE_TO_END_OF_FILE */;
4362 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
+ 7, sizeof(contents
) - 7, &offset
, NULL
);
4363 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#lx\n", status
);
4364 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iob
).Status
);
4365 ok(iob
.Information
== sizeof(contents
) - 7, "expected sizeof(contents)-7, got %Iu\n", iob
.Information
);
4367 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4368 ok(off
== sizeof(contents
), "expected sizeof(contents), got %lu\n", off
);
4371 SetLastError(0xdeadbeef);
4372 ret
= ReadFile(INVALID_HANDLE_VALUE
, buf
, 0, &bytes
, NULL
);
4373 ok(!ret
, "ReadFile should fail\n");
4374 ok(GetLastError() == ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError());
4375 ok(bytes
== 0, "bytes %lu\n", bytes
);
4378 SetLastError(0xdeadbeef);
4379 ret
= ReadFile(hfile
, buf
, 0, &bytes
, NULL
);
4380 ok(ret
, "ReadFile error %ld\n", GetLastError());
4381 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %ld\n", GetLastError());
4382 ok(bytes
== 0, "bytes %lu\n", bytes
);
4385 SetLastError(0xdeadbeef);
4386 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
4387 ok(ret
, "ReadFile error %ld\n", GetLastError());
4388 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %ld\n", GetLastError());
4389 ok(bytes
== 0, "bytes %lu\n", bytes
);
4391 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
4394 SetLastError(0xdeadbeef);
4395 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
4396 ok(ret
, "ReadFile error %ld\n", GetLastError());
4397 ok(bytes
== sizeof(contents
), "bytes %lu\n", bytes
);
4398 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
4400 for (i
= -20; i
< -1; i
++)
4402 if (i
== -2) continue;
4405 iob
.Information
= -1;
4406 offset
.QuadPart
= (LONGLONG
)i
;
4407 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), &offset
, NULL
);
4408 ok(status
== STATUS_INVALID_PARAMETER
, "%ld: expected STATUS_INVALID_PARAMETER, got %#lx\n", i
, status
);
4409 ok(U(iob
).Status
== -1, "expected -1, got %#lx\n", U(iob
).Status
);
4410 ok(iob
.Information
== -1, "expected -1, got %Id\n", iob
.Information
);
4413 SetFilePointer(hfile
, sizeof(contents
) - 4, NULL
, FILE_BEGIN
);
4416 iob
.Information
= -1;
4417 offset
.QuadPart
= (LONGLONG
)-2 /* FILE_USE_FILE_POINTER_POSITION */;
4418 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, "DCBA", 4, &offset
, NULL
);
4419 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#lx\n", status
);
4420 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iob
).Status
);
4421 ok(iob
.Information
== 4, "expected 4, got %Iu\n", iob
.Information
);
4423 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4424 ok(off
== sizeof(contents
), "expected sizeof(contents), got %lu\n", off
);
4427 iob
.Information
= -1;
4428 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), NULL
, NULL
);
4429 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", status
);
4430 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", U(iob
).Status
);
4431 ok(iob
.Information
== 0, "expected 0, got %Iu\n", iob
.Information
);
4433 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
4436 SetLastError(0xdeadbeef);
4437 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
4438 ok(ret
, "ReadFile error %ld\n", GetLastError());
4439 ok(bytes
== sizeof(contents
), "bytes %lu\n", bytes
);
4440 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
4441 ok(!memcmp(buf
+ sizeof(contents
) - 4, "DCBA", 4), "file contents mismatch\n");
4443 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4444 ok(off
== sizeof(contents
), "expected sizeof(contents), got %lu\n", off
);
4446 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
4449 SetLastError(0xdeadbeef);
4450 ret
= WriteFile(hfile
, contents
, sizeof(contents
), &bytes
, NULL
);
4451 ok(ret
, "WriteFile error %ld\n", GetLastError());
4452 ok(bytes
== sizeof(contents
), "bytes %lu\n", bytes
);
4454 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4455 ok(off
== sizeof(contents
), "expected sizeof(contents), got %lu\n", off
);
4457 /* test reading beyond EOF */
4459 SetLastError(0xdeadbeef);
4460 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
4461 ok(ret
, "ReadFile error %ld\n", GetLastError());
4462 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %ld\n", GetLastError());
4463 ok(bytes
== 0, "bytes %lu\n", bytes
);
4466 SetLastError(0xdeadbeef);
4467 ret
= ReadFile(hfile
, buf
, 0, &bytes
, NULL
);
4468 ok(ret
, "ReadFile error %ld\n", GetLastError());
4469 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %ld\n", GetLastError());
4470 ok(bytes
== 0, "bytes %lu\n", bytes
);
4473 SetLastError(0xdeadbeef);
4474 ret
= ReadFile(hfile
, NULL
, 0, &bytes
, NULL
);
4475 ok(ret
, "ReadFile error %ld\n", GetLastError());
4476 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %ld\n", GetLastError());
4477 ok(bytes
== 0, "bytes %lu\n", bytes
);
4479 S(U(ovl
)).Offset
= sizeof(contents
);
4480 S(U(ovl
)).OffsetHigh
= 0;
4482 ovl
.InternalHigh
= -1;
4485 SetLastError(0xdeadbeef);
4486 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4487 ok(!ret
, "ReadFile should fail\n");
4488 ok(GetLastError() == ERROR_HANDLE_EOF
, "expected ERROR_HANDLE_EOF, got %ld\n", GetLastError());
4489 ok(bytes
== 0, "bytes %lu\n", bytes
);
4490 ok((NTSTATUS
)ovl
.Internal
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#Ix\n", ovl
.Internal
);
4491 ok(ovl
.InternalHigh
== 0, "expected 0, got %Iu\n", ovl
.InternalHigh
);
4493 S(U(ovl
)).Offset
= sizeof(contents
);
4494 S(U(ovl
)).OffsetHigh
= 0;
4496 ovl
.InternalHigh
= -1;
4499 SetLastError(0xdeadbeef);
4500 ret
= ReadFile(hfile
, buf
, 0, &bytes
, &ovl
);
4501 ok(ret
, "ReadFile error %ld\n", GetLastError());
4502 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %ld\n", GetLastError());
4503 ok(bytes
== 0, "bytes %lu\n", bytes
);
4504 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#Ix\n", ovl
.Internal
);
4505 ok(ovl
.InternalHigh
== 0, "expected 0, got %Iu\n", ovl
.InternalHigh
);
4508 iob
.Information
= -1;
4509 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), NULL
, NULL
);
4510 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", status
);
4511 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", U(iob
).Status
);
4512 ok(iob
.Information
== 0, "expected 0, got %Iu\n", iob
.Information
);
4515 iob
.Information
= -1;
4516 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, NULL
, NULL
);
4517 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#lx\n", status
);
4518 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iob
).Status
);
4519 ok(iob
.Information
== 0, "expected 0, got %Iu\n", iob
.Information
);
4522 iob
.Information
= -1;
4523 offset
.QuadPart
= sizeof(contents
);
4524 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4525 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", status
);
4526 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", U(iob
).Status
);
4527 ok(iob
.Information
== 0, "expected 0, got %Iu\n", iob
.Information
);
4530 iob
.Information
= -1;
4531 offset
.QuadPart
= sizeof(contents
);
4532 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, &offset
, NULL
);
4533 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#lx\n", status
);
4534 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iob
).Status
);
4535 ok(iob
.Information
== 0, "expected 0, got %Iu\n", iob
.Information
);
4538 iob
.Information
= -1;
4539 offset
.QuadPart
= (LONGLONG
)-2 /* FILE_USE_FILE_POINTER_POSITION */;
4540 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4541 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", status
);
4542 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", U(iob
).Status
);
4543 ok(iob
.Information
== 0, "expected 0, got %Iu\n", iob
.Information
);
4546 iob
.Information
= -1;
4547 offset
.QuadPart
= (LONGLONG
)-2 /* FILE_USE_FILE_POINTER_POSITION */;
4548 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, &offset
, NULL
);
4549 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#lx\n", status
);
4550 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iob
).Status
);
4551 ok(iob
.Information
== 0, "expected 0, got %Iu\n", iob
.Information
);
4553 for (i
= -20; i
< 0; i
++)
4555 if (i
== -2) continue;
4558 iob
.Information
= -1;
4559 offset
.QuadPart
= (LONGLONG
)i
;
4560 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4561 ok(status
== STATUS_INVALID_PARAMETER
, "%ld: expected STATUS_INVALID_PARAMETER, got %#lx\n", i
, status
);
4562 ok(U(iob
).Status
== -1, "expected -1, got %#lx\n", U(iob
).Status
);
4563 ok(iob
.Information
== -1, "expected -1, got %Id\n", iob
.Information
);
4566 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
4569 SetLastError(0xdeadbeef);
4570 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
4571 ok(ret
, "ReadFile error %ld\n", GetLastError());
4572 ok(bytes
== sizeof(contents
), "bytes %lu\n", bytes
);
4573 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
4575 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4576 ok(off
== sizeof(contents
), "expected sizeof(contents), got %lu\n", off
);
4579 iob
.Information
= -1;
4580 offset
.QuadPart
= 0;
4581 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4582 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#lx\n", status
);
4583 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iob
).Status
);
4584 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %Iu\n", iob
.Information
);
4585 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
4587 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4588 ok(off
== sizeof(contents
), "expected sizeof(contents), got %lu\n", off
);
4591 iob
.Information
= -1;
4592 offset
.QuadPart
= sizeof(contents
) - 4;
4593 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, "DCBA", 4, &offset
, NULL
);
4594 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#lx\n", status
);
4595 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iob
).Status
);
4596 ok(iob
.Information
== 4, "expected 4, got %Iu\n", iob
.Information
);
4598 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4599 ok(off
== sizeof(contents
), "expected sizeof(contents), got %lu\n", off
);
4602 iob
.Information
= -1;
4603 offset
.QuadPart
= 0;
4604 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4605 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#lx\n", status
);
4606 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iob
).Status
);
4607 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %Iu\n", iob
.Information
);
4608 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
4609 ok(!memcmp(buf
+ sizeof(contents
) - 4, "DCBA", 4), "file contents mismatch\n");
4611 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4612 ok(off
== sizeof(contents
), "expected sizeof(contents), got %lu\n", off
);
4614 S(U(ovl
)).Offset
= sizeof(contents
) - 4;
4615 S(U(ovl
)).OffsetHigh
= 0;
4618 SetLastError(0xdeadbeef);
4619 ret
= WriteFile(hfile
, "ABCD", 4, &bytes
, &ovl
);
4620 ok(ret
, "WriteFile error %ld\n", GetLastError());
4621 ok(bytes
== 4, "bytes %lu\n", bytes
);
4623 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4624 ok(off
== sizeof(contents
), "expected sizeof(contents), got %lu\n", off
);
4626 S(U(ovl
)).Offset
= 0;
4627 S(U(ovl
)).OffsetHigh
= 0;
4629 ovl
.InternalHigh
= -1;
4632 SetLastError(0xdeadbeef);
4633 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4634 ok(ret
, "ReadFile error %ld\n", GetLastError());
4635 ok(bytes
== sizeof(contents
), "bytes %lu\n", bytes
);
4636 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#Ix\n", ovl
.Internal
);
4637 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %Iu\n", ovl
.InternalHigh
);
4638 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
4639 ok(!memcmp(buf
+ sizeof(contents
) - 4, "ABCD", 4), "file contents mismatch\n");
4641 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4642 ok(off
== sizeof(contents
), "expected sizeof(contents), got %lu\n", off
);
4646 hfile
= create_temp_file(FILE_FLAG_OVERLAPPED
);
4650 SetLastError(0xdeadbeef);
4651 ret
= ReadFile(INVALID_HANDLE_VALUE
, buf
, 0, &bytes
, NULL
);
4652 ok(!ret
, "ReadFile should fail\n");
4653 ok(GetLastError() == ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError());
4654 ok(bytes
== 0, "bytes %lu\n", bytes
);
4656 S(U(ovl
)).Offset
= 0;
4657 S(U(ovl
)).OffsetHigh
= 0;
4659 ovl
.InternalHigh
= -1;
4662 SetLastError(0xdeadbeef);
4663 /* ReadFile return value depends on Windows version and testing it is not practical */
4664 ReadFile(hfile
, buf
, 0, &bytes
, &ovl
);
4665 ok(bytes
== 0, "bytes %lu\n", bytes
);
4666 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#Ix\n", ovl
.Internal
);
4667 ok(ovl
.InternalHigh
== 0, "expected 0, got %Iu\n", ovl
.InternalHigh
);
4670 SetLastError(0xdeadbeef);
4671 ret
= WriteFile(hfile
, contents
, sizeof(contents
), &bytes
, NULL
);
4672 ok(!ret
, "WriteFile should fail\n");
4673 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
4674 ok(bytes
== 0, "bytes %lu\n", bytes
);
4677 iob
.Information
= -1;
4678 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), NULL
, NULL
);
4679 ok(status
== STATUS_INVALID_PARAMETER
, "expected STATUS_INVALID_PARAMETER, got %#lx\n", status
);
4680 ok(U(iob
).Status
== -1, "expected -1, got %#lx\n", U(iob
).Status
);
4681 ok(iob
.Information
== -1, "expected -1, got %Id\n", iob
.Information
);
4683 for (i
= -20; i
< -1; i
++)
4686 iob
.Information
= -1;
4687 offset
.QuadPart
= (LONGLONG
)i
;
4688 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), &offset
, NULL
);
4689 ok(status
== STATUS_INVALID_PARAMETER
, "%ld: expected STATUS_INVALID_PARAMETER, got %#lx\n", i
, status
);
4690 ok(U(iob
).Status
== -1, "expected -1, got %#lx\n", U(iob
).Status
);
4691 ok(iob
.Information
== -1, "expected -1, got %Id\n", iob
.Information
);
4695 iob
.Information
= -1;
4696 offset
.QuadPart
= 0;
4697 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), &offset
, NULL
);
4698 ok(status
== STATUS_PENDING
|| broken(status
== STATUS_SUCCESS
) /* before Vista */,
4699 "expected STATUS_PENDING, got %#lx.\n", status
);
4700 if (status
== STATUS_PENDING
)
4702 ret
= WaitForSingleObject(hfile
, 3000);
4703 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %ld\n", ret
);
4705 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iob
).Status
);
4706 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %Iu\n", iob
.Information
);
4708 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4709 ok(off
== 0, "expected 0, got %lu\n", off
);
4712 SetLastError(0xdeadbeef);
4713 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
4714 ok(!ret
, "ReadFile should fail\n");
4715 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
4716 ok(bytes
== 0, "bytes %lu\n", bytes
);
4719 iob
.Information
= -1;
4720 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), NULL
, NULL
);
4721 ok(status
== STATUS_INVALID_PARAMETER
, "expected STATUS_INVALID_PARAMETER, got %#lx\n", status
);
4722 ok(U(iob
).Status
== -1, "expected -1, got %#lx\n", U(iob
).Status
);
4723 ok(iob
.Information
== -1, "expected -1, got %Id\n", iob
.Information
);
4725 for (i
= -20; i
< 0; i
++)
4728 iob
.Information
= -1;
4729 offset
.QuadPart
= (LONGLONG
)i
;
4730 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4731 ok(status
== STATUS_INVALID_PARAMETER
, "%ld: expected STATUS_INVALID_PARAMETER, got %#lx\n", i
, status
);
4732 ok(U(iob
).Status
== -1, "expected -1, got %#lx\n", U(iob
).Status
);
4733 ok(iob
.Information
== -1, "expected -1, got %Id\n", iob
.Information
);
4736 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4737 ok(off
== 0, "expected 0, got %lu\n", off
);
4739 /* test reading beyond EOF */
4740 offset
.QuadPart
= sizeof(contents
);
4741 S(U(ovl
)).Offset
= offset
.u
.LowPart
;
4742 S(U(ovl
)).OffsetHigh
= offset
.u
.HighPart
;
4744 ovl
.InternalHigh
= -1;
4747 SetLastError(0xdeadbeef);
4748 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4749 ok(!ret
, "ReadFile should fail\n");
4750 ret
= GetLastError();
4751 ok(ret
== ERROR_IO_PENDING
|| broken(ret
== ERROR_HANDLE_EOF
) /* before Vista */,
4752 "expected ERROR_IO_PENDING, got %ld\n", ret
);
4753 ok(bytes
== 0, "bytes %lu\n", bytes
);
4755 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4756 ok(off
== 0, "expected 0, got %lu\n", off
);
4758 if (ret
== ERROR_IO_PENDING
)
4761 SetLastError(0xdeadbeef);
4762 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4763 ok(!ret
, "GetOverlappedResult should report FALSE\n");
4764 ok(GetLastError() == ERROR_HANDLE_EOF
, "expected ERROR_HANDLE_EOF, got %ld\n", GetLastError());
4765 ok(bytes
== 0, "expected 0, read %lu\n", bytes
);
4766 ok((NTSTATUS
)ovl
.Internal
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#Ix\n", ovl
.Internal
);
4767 ok(ovl
.InternalHigh
== 0, "expected 0, got %Iu\n", ovl
.InternalHigh
);
4770 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4771 ok(off
== 0, "expected 0, got %lu\n", off
);
4773 offset
.QuadPart
= sizeof(contents
);
4774 S(U(ovl
)).Offset
= offset
.u
.LowPart
;
4775 S(U(ovl
)).OffsetHigh
= offset
.u
.HighPart
;
4777 ovl
.InternalHigh
= -1;
4780 SetLastError(0xdeadbeef);
4781 ret
= ReadFile(hfile
, buf
, 0, &bytes
, &ovl
);
4782 ok((!ret
&& GetLastError() == ERROR_IO_PENDING
) || broken(ret
) /* before Vista */,
4783 "Unexpected result, ret %#lx, GetLastError() %lu.\n", ret
, GetLastError());
4784 ret
= GetLastError();
4785 ok(bytes
== 0, "bytes %lu\n", bytes
);
4787 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4788 ok(off
== 0, "expected 0, got %lu\n", off
);
4790 if (ret
== ERROR_IO_PENDING
)
4793 SetLastError(0xdeadbeef);
4794 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4795 ok(ret
, "GetOverlappedResult returned FALSE with %lu (expected TRUE)\n", GetLastError());
4796 ok(bytes
== 0, "expected 0, read %lu\n", bytes
);
4797 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#Ix\n", ovl
.Internal
);
4798 ok(ovl
.InternalHigh
== 0, "expected 0, got %Iu\n", ovl
.InternalHigh
);
4801 offset
.QuadPart
= sizeof(contents
);
4802 S(U(ovl
)).Offset
= offset
.u
.LowPart
;
4803 S(U(ovl
)).OffsetHigh
= offset
.u
.HighPart
;
4805 ovl
.InternalHigh
= -1;
4808 SetLastError(0xdeadbeef);
4809 ret
= ReadFile(hfile
, NULL
, 0, &bytes
, &ovl
);
4810 ok((!ret
&& GetLastError() == ERROR_IO_PENDING
) || broken(ret
) /* before Vista */,
4811 "Unexpected result, ret %#lx, GetLastError() %lu.\n", ret
, GetLastError());
4812 ret
= GetLastError();
4813 ok(bytes
== 0, "bytes %lu\n", bytes
);
4815 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4816 ok(off
== 0, "expected 0, got %lu\n", off
);
4818 if (ret
== ERROR_IO_PENDING
)
4821 SetLastError(0xdeadbeef);
4822 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4823 ok(ret
, "GetOverlappedResult returned FALSE with %lu (expected TRUE)\n", GetLastError());
4824 ok(bytes
== 0, "expected 0, read %lu\n", bytes
);
4825 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#Ix\n", ovl
.Internal
);
4826 ok(ovl
.InternalHigh
== 0, "expected 0, got %Iu\n", ovl
.InternalHigh
);
4830 iob
.Information
= -1;
4831 offset
.QuadPart
= sizeof(contents
);
4832 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4833 if (status
== STATUS_PENDING
)
4835 ret
= WaitForSingleObject(hfile
, 3000);
4836 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %ld\n", ret
);
4837 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", U(iob
).Status
);
4838 ok(iob
.Information
== 0, "expected 0, got %Iu\n", iob
.Information
);
4842 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", status
);
4843 ok(U(iob
).Status
== -1, "expected -1, got %#lx\n", U(iob
).Status
);
4844 ok(iob
.Information
== -1, "expected -1, got %Iu\n", iob
.Information
);
4847 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4848 ok(off
== 0, "expected 0, got %lu\n", off
);
4851 iob
.Information
= -1;
4852 offset
.QuadPart
= sizeof(contents
);
4853 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, &offset
, NULL
);
4854 ok(status
== STATUS_PENDING
|| broken(status
== STATUS_SUCCESS
) /* before Vista */,
4855 "expected STATUS_PENDING, got %#lx.\n", status
);
4856 if (status
== STATUS_PENDING
)
4858 ret
= WaitForSingleObject(hfile
, 3000);
4859 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %ld\n", ret
);
4860 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iob
).Status
);
4861 ok(iob
.Information
== 0, "expected 0, got %Iu\n", iob
.Information
);
4865 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iob
).Status
);
4866 ok(iob
.Information
== 0, "expected 0, got %Iu\n", iob
.Information
);
4869 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4870 ok(off
== 0, "expected 0, got %lu\n", off
);
4872 S(U(ovl
)).Offset
= 0;
4873 S(U(ovl
)).OffsetHigh
= 0;
4875 ovl
.InternalHigh
= -1;
4878 SetLastError(0xdeadbeef);
4879 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4880 ok((!ret
&& GetLastError() == ERROR_IO_PENDING
) || broken(ret
) /* before Vista */,
4881 "Unexpected result, ret %#lx, GetLastError() %lu.\n", ret
, GetLastError());
4883 ok(bytes
== 0, "bytes %lu\n", bytes
);
4885 ok(bytes
== 14, "bytes %lu\n", bytes
);
4886 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#Ix\n", ovl
.Internal
);
4887 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %Iu\n", ovl
.InternalHigh
);
4889 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4890 ok(off
== 0, "expected 0, got %lu\n", off
);
4893 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4894 ok(ret
, "GetOverlappedResult error %ld\n", GetLastError());
4895 ok(bytes
== sizeof(contents
), "bytes %lu\n", bytes
);
4896 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#Ix\n", ovl
.Internal
);
4897 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %Iu\n", ovl
.InternalHigh
);
4898 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
4900 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4901 ok(off
== 0, "expected 0, got %lu\n", off
);
4903 SetFilePointer(hfile
, sizeof(contents
) - 4, NULL
, FILE_BEGIN
);
4904 SetEndOfFile(hfile
);
4905 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
4908 iob
.Information
= -1;
4909 offset
.QuadPart
= (LONGLONG
)-1 /* FILE_WRITE_TO_END_OF_FILE */;
4910 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, "DCBA", 4, &offset
, NULL
);
4911 ok(status
== STATUS_PENDING
|| broken(status
== STATUS_SUCCESS
) /* before Vista */,
4912 "expected STATUS_PENDING, got %#lx.\n", status
);
4913 if (status
== STATUS_PENDING
)
4915 ret
= WaitForSingleObject(hfile
, 3000);
4916 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %ld\n", ret
);
4918 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iob
).Status
);
4919 ok(iob
.Information
== 4, "expected 4, got %Iu\n", iob
.Information
);
4921 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4922 ok(off
== 0, "expected 0, got %lu\n", off
);
4925 iob
.Information
= -1;
4926 offset
.QuadPart
= 0;
4927 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4928 ok(status
== STATUS_PENDING
|| broken(status
== STATUS_SUCCESS
) /* before Vista */,
4929 "expected STATUS_PENDING, got %#lx.\n", status
);
4930 if (status
== STATUS_PENDING
)
4932 ret
= WaitForSingleObject(hfile
, 3000);
4933 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %ld\n", ret
);
4935 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", U(iob
).Status
);
4936 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %Iu\n", iob
.Information
);
4938 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4939 ok(off
== 0, "expected 0, got %lu\n", off
);
4941 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
4942 ok(!memcmp(buf
+ sizeof(contents
) - 4, "DCBA", 4), "file contents mismatch\n");
4944 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4945 ok(off
== 0, "expected 0, got %lu\n", off
);
4947 S(U(ovl
)).Offset
= sizeof(contents
) - 4;
4948 S(U(ovl
)).OffsetHigh
= 0;
4950 ovl
.InternalHigh
= -1;
4953 SetLastError(0xdeadbeef);
4954 ret
= WriteFile(hfile
, "ABCD", 4, &bytes
, &ovl
);
4955 ok((!ret
&& GetLastError() == ERROR_IO_PENDING
) || broken(ret
) /* before Vista */,
4956 "Unexpected result %#lx, GetLastError() %lu.\n", ret
, GetLastError());
4959 ok(bytes
== 0, "bytes %lu\n", bytes
);
4960 ret
= WaitForSingleObject(hfile
, 3000);
4961 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %ld\n", ret
);
4963 else ok(bytes
== 4, "bytes %lu\n", bytes
);
4964 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#Ix\n", ovl
.Internal
);
4965 ok(ovl
.InternalHigh
== 4, "expected 4, got %Iu\n", ovl
.InternalHigh
);
4967 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4968 ok(off
== 0, "expected 0, got %lu\n", off
);
4971 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4972 ok(ret
, "GetOverlappedResult error %ld\n", GetLastError());
4973 ok(bytes
== 4, "bytes %lu\n", bytes
);
4974 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#Ix\n", ovl
.Internal
);
4975 ok(ovl
.InternalHigh
== 4, "expected 4, got %Iu\n", ovl
.InternalHigh
);
4977 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4978 ok(off
== 0, "expected 0, got %lu\n", off
);
4980 S(U(ovl
)).Offset
= 0;
4981 S(U(ovl
)).OffsetHigh
= 0;
4983 ovl
.InternalHigh
= -1;
4986 SetLastError(0xdeadbeef);
4987 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4988 ok((!ret
&& GetLastError() == ERROR_IO_PENDING
) || broken(ret
) /* before Vista */,
4989 "Unexpected result %#lx, GetLastError() %lu.\n", ret
, GetLastError());
4992 ok(bytes
== 0, "bytes %lu\n", bytes
);
4993 ret
= WaitForSingleObject(hfile
, 3000);
4994 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %ld\n", ret
);
4996 else ok(bytes
== 14, "bytes %lu\n", bytes
);
4997 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#Ix\n", ovl
.Internal
);
4998 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %Iu\n", ovl
.InternalHigh
);
5000 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
5001 ok(off
== 0, "expected 0, got %lu\n", off
);
5004 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
5005 ok(ret
, "GetOverlappedResult error %ld\n", GetLastError());
5006 ok(bytes
== sizeof(contents
), "bytes %lu\n", bytes
);
5007 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#Ix\n", ovl
.Internal
);
5008 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %Iu\n", ovl
.InternalHigh
);
5009 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
5010 ok(!memcmp(buf
+ sizeof(contents
) - 4, "ABCD", 4), "file contents mismatch\n");
5012 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
5013 ok(off
== 0, "expected 0, got %lu\n", off
);
5019 static void test_ioctl(void)
5021 HANDLE event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
5022 FILE_PIPE_PEEK_BUFFER peek_buf
;
5023 IO_STATUS_BLOCK iosb
;
5027 file
= create_temp_file(FILE_FLAG_OVERLAPPED
);
5028 ok(file
!= INVALID_HANDLE_VALUE
, "could not create temp file\n");
5031 status
= pNtFsControlFile(file
, event
, NULL
, NULL
, &iosb
, 0xdeadbeef, 0, 0, 0, 0);
5033 ok(status
== STATUS_INVALID_DEVICE_REQUEST
, "NtFsControlFile returned %lx\n", status
);
5034 ok(!is_signaled(event
), "event is signaled\n");
5036 status
= pNtFsControlFile(file
, (HANDLE
)0xdeadbeef, NULL
, NULL
, &iosb
, 0xdeadbeef, 0, 0, 0, 0);
5037 ok(status
== STATUS_INVALID_HANDLE
, "NtFsControlFile returned %lx\n", status
);
5039 memset(&iosb
, 0x55, sizeof(iosb
));
5040 status
= pNtFsControlFile(file
, NULL
, NULL
, NULL
, &iosb
, FSCTL_PIPE_PEEK
, NULL
, 0,
5041 &peek_buf
, sizeof(peek_buf
));
5043 ok(status
== STATUS_INVALID_DEVICE_REQUEST
, "NtFsControlFile failed: %lx\n", status
);
5044 ok(iosb
.Status
== 0x55555555, "iosb.Status = %lx\n", iosb
.Status
);
5050 static void test_flush_buffers_file(void)
5052 char path
[MAX_PATH
], buffer
[MAX_PATH
];
5053 HANDLE hfile
, hfileread
;
5055 IO_STATUS_BLOCK io_status_block
;
5057 GetTempPathA(MAX_PATH
, path
);
5058 GetTempFileNameA(path
, "foo", 0, buffer
);
5059 hfile
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
, FILE_SHARE_READ
, NULL
, CREATE_ALWAYS
,
5060 FILE_ATTRIBUTE_NORMAL
, 0);
5061 ok(hfile
!= INVALID_HANDLE_VALUE
, "failed to create temp file.\n" );
5063 hfileread
= CreateFileA(buffer
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
5064 OPEN_EXISTING
, 0, NULL
);
5065 ok(hfileread
!= INVALID_HANDLE_VALUE
, "could not open temp file, error %ld.\n", GetLastError());
5067 status
= pNtFlushBuffersFile(hfile
, NULL
);
5068 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#lx.\n", status
);
5070 status
= pNtFlushBuffersFile(hfile
, (IO_STATUS_BLOCK
*)0xdeadbeaf);
5071 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#lx.\n", status
);
5073 io_status_block
.Information
= 0xdeadbeef;
5074 io_status_block
.Status
= 0xdeadbeef;
5075 status
= pNtFlushBuffersFile(hfile
, &io_status_block
);
5076 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx.\n", status
);
5077 ok(io_status_block
.Status
== STATUS_SUCCESS
, "Got unexpected io_status_block.Status %#lx.\n",
5078 io_status_block
.Status
);
5079 ok(!io_status_block
.Information
, "Got unexpected io_status_block.Information %#Ix.\n",
5080 io_status_block
.Information
);
5082 status
= pNtFlushBuffersFile(hfileread
, &io_status_block
);
5083 ok(status
== STATUS_ACCESS_DENIED
, "expected STATUS_ACCESS_DENIED, got %#lx.\n", status
);
5085 io_status_block
.Information
= 0xdeadbeef;
5086 io_status_block
.Status
= 0xdeadbeef;
5087 status
= pNtFlushBuffersFile(NULL
, &io_status_block
);
5088 ok(status
== STATUS_INVALID_HANDLE
, "expected STATUS_INVALID_HANDLE, got %#lx.\n", status
);
5089 ok(io_status_block
.Status
== 0xdeadbeef, "Got unexpected io_status_block.Status %#lx.\n",
5090 io_status_block
.Status
);
5091 ok(io_status_block
.Information
== 0xdeadbeef, "Got unexpected io_status_block.Information %#Ix.\n",
5092 io_status_block
.Information
);
5094 CloseHandle(hfileread
);
5096 hfile
= CreateFileA(buffer
, FILE_APPEND_DATA
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
5097 OPEN_EXISTING
, 0, NULL
);
5098 ok(hfile
!= INVALID_HANDLE_VALUE
, "could not open temp file, error %ld.\n", GetLastError());
5100 status
= pNtFlushBuffersFile(hfile
, &io_status_block
);
5101 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx.\n", status
);
5103 io_status_block
.Information
= 0xdeadbeef;
5104 io_status_block
.Status
= 0xdeadbeef;
5105 status
= pNtFlushBuffersFile((HANDLE
)0xdeadbeef, &io_status_block
);
5106 ok(status
== STATUS_INVALID_HANDLE
, "expected STATUS_INVALID_HANDLE, got %#lx.\n", status
);
5107 ok(io_status_block
.Status
== 0xdeadbeef, "Got unexpected io_status_block.Status %#lx.\n",
5108 io_status_block
.Status
);
5109 ok(io_status_block
.Information
== 0xdeadbeef, "Got unexpected io_status_block.Information %#Ix.\n",
5110 io_status_block
.Information
);
5113 DeleteFileA(buffer
);
5116 static void test_query_ea(void)
5118 #define EA_BUFFER_SIZE 4097
5119 unsigned char data
[EA_BUFFER_SIZE
+ 8];
5120 unsigned char *buffer
= (void *)(((DWORD_PTR
)data
+ 7) & ~7);
5121 DWORD buffer_len
, i
;
5126 if (!(handle
= create_temp_file(0))) return;
5128 /* test with INVALID_HANDLE_VALUE */
5129 U(io
).Status
= 0xdeadbeef;
5130 io
.Information
= 0xdeadbeef;
5131 memset(buffer
, 0xcc, EA_BUFFER_SIZE
);
5132 buffer_len
= EA_BUFFER_SIZE
- 1;
5133 status
= pNtQueryEaFile(INVALID_HANDLE_VALUE
, &io
, buffer
, buffer_len
, TRUE
, NULL
, 0, NULL
, FALSE
);
5134 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#lx\n", status
);
5135 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %#lx\n", U(io
).Status
);
5136 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %#Ix\n", io
.Information
);
5137 ok(buffer
[0] == 0xcc, "data at position 0 overwritten\n");
5139 /* test with 0xdeadbeef */
5140 U(io
).Status
= 0xdeadbeef;
5141 io
.Information
= 0xdeadbeef;
5142 memset(buffer
, 0xcc, EA_BUFFER_SIZE
);
5143 buffer_len
= EA_BUFFER_SIZE
- 1;
5144 status
= pNtQueryEaFile((void *)0xdeadbeef, &io
, buffer
, buffer_len
, TRUE
, NULL
, 0, NULL
, FALSE
);
5145 ok(status
== STATUS_INVALID_HANDLE
, "expected STATUS_INVALID_HANDLE, got %#lx\n", status
);
5146 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %#lx\n", U(io
).Status
);
5147 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %#Ix\n", io
.Information
);
5148 ok(buffer
[0] == 0xcc, "data at position 0 overwritten\n");
5150 /* test without buffer */
5151 U(io
).Status
= 0xdeadbeef;
5152 io
.Information
= 0xdeadbeef;
5153 status
= pNtQueryEaFile(handle
, &io
, NULL
, 0, TRUE
, NULL
, 0, NULL
, FALSE
);
5154 ok(status
== STATUS_NO_EAS_ON_FILE
, "expected STATUS_NO_EAS_ON_FILE, got %#lx\n", status
);
5155 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %#lx\n", U(io
).Status
);
5156 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %#Ix\n", io
.Information
);
5158 /* test with zero buffer */
5159 U(io
).Status
= 0xdeadbeef;
5160 io
.Information
= 0xdeadbeef;
5161 status
= pNtQueryEaFile(handle
, &io
, buffer
, 0, TRUE
, NULL
, 0, NULL
, FALSE
);
5162 ok(status
== STATUS_NO_EAS_ON_FILE
, "expected STATUS_NO_EAS_ON_FILE, got %#lx\n", status
);
5163 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %#lx\n", U(io
).Status
);
5164 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %#Ix\n", io
.Information
);
5166 /* test with very small buffer */
5167 U(io
).Status
= 0xdeadbeef;
5168 io
.Information
= 0xdeadbeef;
5169 memset(buffer
, 0xcc, EA_BUFFER_SIZE
);
5171 status
= pNtQueryEaFile(handle
, &io
, buffer
, buffer_len
, TRUE
, NULL
, 0, NULL
, FALSE
);
5172 ok(status
== STATUS_NO_EAS_ON_FILE
, "expected STATUS_NO_EAS_ON_FILE, got %#lx\n", status
);
5173 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %#lx\n", U(io
).Status
);
5174 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %#Ix\n", io
.Information
);
5175 for (i
= 0; i
< buffer_len
&& !buffer
[i
]; i
++);
5176 ok(i
== buffer_len
, "expected %lu bytes filled with 0x00, got %lu bytes\n", buffer_len
, i
);
5177 ok(buffer
[i
] == 0xcc, "data at position %u overwritten\n", buffer
[i
]);
5179 /* test with very big buffer */
5180 U(io
).Status
= 0xdeadbeef;
5181 io
.Information
= 0xdeadbeef;
5182 memset(buffer
, 0xcc, EA_BUFFER_SIZE
);
5183 buffer_len
= EA_BUFFER_SIZE
- 1;
5184 status
= pNtQueryEaFile(handle
, &io
, buffer
, buffer_len
, TRUE
, NULL
, 0, NULL
, FALSE
);
5185 ok(status
== STATUS_NO_EAS_ON_FILE
, "expected STATUS_NO_EAS_ON_FILE, got %#lx\n", status
);
5186 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %#lx\n", U(io
).Status
);
5187 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %#Ix\n", io
.Information
);
5188 for (i
= 0; i
< buffer_len
&& !buffer
[i
]; i
++);
5189 ok(i
== buffer_len
, "expected %lu bytes filled with 0x00, got %lu bytes\n", buffer_len
, i
);
5190 ok(buffer
[i
] == 0xcc, "data at position %u overwritten\n", buffer
[i
]);
5192 CloseHandle(handle
);
5193 #undef EA_BUFFER_SIZE
5196 static void test_file_readonly_access(void)
5198 static const DWORD default_sharing
= FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
;
5199 static const WCHAR fooW
[] = {'f', 'o', 'o', 0};
5200 WCHAR path
[MAX_PATH
];
5201 OBJECT_ATTRIBUTES attr
;
5202 UNICODE_STRING nameW
;
5209 GetTempPathW(MAX_PATH
, path
);
5210 GetTempFileNameW(path
, fooW
, 0, path
);
5212 pRtlDosPathNameToNtPathName_U(path
, &nameW
, NULL
, NULL
);
5214 attr
.Length
= sizeof(attr
);
5215 attr
.RootDirectory
= NULL
;
5216 attr
.ObjectName
= &nameW
;
5217 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
5218 attr
.SecurityDescriptor
= NULL
;
5219 attr
.SecurityQualityOfService
= NULL
;
5221 status
= pNtCreateFile(&handle
, FILE_GENERIC_WRITE
, &attr
, &io
, NULL
, FILE_ATTRIBUTE_READONLY
, default_sharing
,
5222 FILE_CREATE
, 0, NULL
, 0);
5223 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx.\n", status
);
5224 CloseHandle(handle
);
5226 /* NtCreateFile FILE_GENERIC_WRITE */
5227 status
= pNtCreateFile(&handle
, FILE_GENERIC_WRITE
, &attr
, &io
, NULL
, FILE_ATTRIBUTE_NORMAL
, default_sharing
,
5228 FILE_OPEN
, FILE_NON_DIRECTORY_FILE
, NULL
, 0);
5229 ok(status
== STATUS_ACCESS_DENIED
, "expected STATUS_ACCESS_DENIED, got %#lx.\n", status
);
5231 /* NtCreateFile DELETE without FILE_DELETE_ON_CLOSE */
5232 status
= pNtCreateFile(&handle
, DELETE
, &attr
, &io
, NULL
, FILE_ATTRIBUTE_NORMAL
, default_sharing
, FILE_OPEN
,
5233 FILE_NON_DIRECTORY_FILE
, NULL
, 0);
5234 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx.\n", status
);
5235 CloseHandle(handle
);
5237 /* NtCreateFile DELETE with FILE_DELETE_ON_CLOSE */
5238 status
= pNtCreateFile(&handle
, SYNCHRONIZE
| DELETE
, &attr
, &io
, NULL
, FILE_ATTRIBUTE_NORMAL
, default_sharing
,
5239 FILE_OPEN
, FILE_DELETE_ON_CLOSE
| FILE_NON_DIRECTORY_FILE
, NULL
, 0);
5240 ok(status
== STATUS_CANNOT_DELETE
, "expected STATUS_CANNOT_DELETE, got %#lx.\n", status
);
5242 /* NtOpenFile GENERIC_WRITE */
5243 status
= pNtOpenFile(&handle
, GENERIC_WRITE
, &attr
, &io
, default_sharing
, FILE_NON_DIRECTORY_FILE
);
5244 ok(status
== STATUS_ACCESS_DENIED
, "expected STATUS_ACCESS_DENIED, got %#lx.\n", status
);
5246 /* NtOpenFile DELETE without FILE_DELETE_ON_CLOSE */
5247 status
= pNtOpenFile(&handle
, DELETE
, &attr
, &io
, default_sharing
, FILE_NON_DIRECTORY_FILE
);
5248 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx.\n", status
);
5249 CloseHandle(handle
);
5251 /* NtOpenFile DELETE with FILE_DELETE_ON_CLOSE */
5252 status
= pNtOpenFile(&handle
, DELETE
, &attr
, &io
, default_sharing
, FILE_DELETE_ON_CLOSE
| FILE_NON_DIRECTORY_FILE
);
5253 ok(status
== STATUS_CANNOT_DELETE
, "expected STATUS_CANNOT_DELETE, got %#lx.\n", status
);
5255 ret
= GetFileAttributesW(path
);
5256 ok(ret
& FILE_ATTRIBUTE_READONLY
, "got wrong attribute: %#lx.\n", ret
);
5259 pRtlFreeUnicodeString(&nameW
);
5260 SetFileAttributesW(path
, FILE_ATTRIBUTE_NORMAL
);
5264 static void test_mailslot_name(void)
5266 char buffer
[1024] = {0};
5267 const FILE_NAME_INFORMATION
*name
= (const FILE_NAME_INFORMATION
*)buffer
;
5268 HANDLE server
, client
, device
;
5272 server
= CreateMailslotA( "\\\\.\\mailslot\\winetest", 100, 1000, NULL
);
5273 ok(server
!= INVALID_HANDLE_VALUE
, "got error %lu\n", GetLastError());
5275 ret
= NtQueryInformationFile( server
, &io
, buffer
, 0, FileNameInformation
);
5276 ok(ret
== STATUS_INFO_LENGTH_MISMATCH
, "got %#lx\n", ret
);
5278 memset(buffer
, 0xcc, sizeof(buffer
));
5279 ret
= NtQueryInformationFile( server
, &io
, buffer
,
5280 offsetof(FILE_NAME_INFORMATION
, FileName
[5]), FileNameInformation
);
5281 todo_wine
ok(ret
== STATUS_BUFFER_OVERFLOW
, "got %#lx\n", ret
);
5282 if (ret
== STATUS_BUFFER_OVERFLOW
)
5284 ok(name
->FileNameLength
== 18, "got length %lu\n", name
->FileNameLength
);
5285 ok(!memcmp(name
->FileName
, L
"\\wine", 10), "got %s\n",
5286 debugstr_wn(name
->FileName
, name
->FileNameLength
/ sizeof(WCHAR
)));
5289 memset(buffer
, 0xcc, sizeof(buffer
));
5290 ret
= NtQueryInformationFile( server
, &io
, buffer
, sizeof(buffer
), FileNameInformation
);
5291 todo_wine
ok(!ret
, "got %#lx\n", ret
);
5294 ok(name
->FileNameLength
== 18, "got length %lu\n", name
->FileNameLength
);
5295 ok(!memcmp(name
->FileName
, L
"\\winetest", 18), "got %s\n",
5296 debugstr_wn(name
->FileName
, name
->FileNameLength
/ sizeof(WCHAR
)));
5299 client
= CreateFileA( "\\\\.\\mailslot\\winetest", 0, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
5300 ok(client
!= INVALID_HANDLE_VALUE
, "got error %lu\n", GetLastError());
5302 ret
= NtQueryInformationFile( client
, &io
, buffer
, 0, FileNameInformation
);
5303 ok(ret
== STATUS_INFO_LENGTH_MISMATCH
, "got %#lx\n", ret
);
5305 ret
= NtQueryInformationFile( client
, &io
, buffer
, sizeof(buffer
), FileNameInformation
);
5306 todo_wine
ok(ret
== STATUS_INVALID_PARAMETER
|| !ret
/* win8+ */, "got %#lx\n", ret
);
5309 ok(name
->FileNameLength
== 18, "got length %lu\n", name
->FileNameLength
);
5310 ok(!memcmp(name
->FileName
, L
"\\winetest", 18), "got %s\n",
5311 debugstr_wn(name
->FileName
, name
->FileNameLength
/ sizeof(WCHAR
)));
5314 CloseHandle( server
);
5315 CloseHandle( client
);
5317 device
= CreateFileA("\\\\.\\mailslot", 0, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
5318 ok(device
!= INVALID_HANDLE_VALUE
, "got error %lu\n", GetLastError());
5320 ret
= NtQueryInformationFile( device
, &io
, buffer
, 0, FileNameInformation
);
5321 ok(ret
== STATUS_INFO_LENGTH_MISMATCH
, "got %#lx\n", ret
);
5323 ret
= NtQueryInformationFile( device
, &io
, buffer
, sizeof(buffer
), FileNameInformation
);
5324 todo_wine
ok(ret
== STATUS_INVALID_PARAMETER
, "got %#lx\n", ret
);
5326 CloseHandle( device
);
5331 HMODULE hkernel32
= GetModuleHandleA("kernel32.dll");
5332 HMODULE hntdll
= GetModuleHandleA("ntdll.dll");
5335 skip("not running on NT, skipping test\n");
5339 pGetVolumePathNameW
= (void *)GetProcAddress(hkernel32
, "GetVolumePathNameW");
5340 pGetSystemWow64DirectoryW
= (void *)GetProcAddress(hkernel32
, "GetSystemWow64DirectoryW");
5342 pRtlFreeUnicodeString
= (void *)GetProcAddress(hntdll
, "RtlFreeUnicodeString");
5343 pRtlInitUnicodeString
= (void *)GetProcAddress(hntdll
, "RtlInitUnicodeString");
5344 pRtlDosPathNameToNtPathName_U
= (void *)GetProcAddress(hntdll
, "RtlDosPathNameToNtPathName_U");
5345 pRtlWow64EnableFsRedirectionEx
= (void *)GetProcAddress(hntdll
, "RtlWow64EnableFsRedirectionEx");
5346 pNtCreateMailslotFile
= (void *)GetProcAddress(hntdll
, "NtCreateMailslotFile");
5347 pNtCreateFile
= (void *)GetProcAddress(hntdll
, "NtCreateFile");
5348 pNtOpenFile
= (void *)GetProcAddress(hntdll
, "NtOpenFile");
5349 pNtDeleteFile
= (void *)GetProcAddress(hntdll
, "NtDeleteFile");
5350 pNtReadFile
= (void *)GetProcAddress(hntdll
, "NtReadFile");
5351 pNtWriteFile
= (void *)GetProcAddress(hntdll
, "NtWriteFile");
5352 pNtCancelIoFile
= (void *)GetProcAddress(hntdll
, "NtCancelIoFile");
5353 pNtCancelIoFileEx
= (void *)GetProcAddress(hntdll
, "NtCancelIoFileEx");
5354 pNtClose
= (void *)GetProcAddress(hntdll
, "NtClose");
5355 pNtFsControlFile
= (void *)GetProcAddress(hntdll
, "NtFsControlFile");
5356 pNtCreateIoCompletion
= (void *)GetProcAddress(hntdll
, "NtCreateIoCompletion");
5357 pNtOpenIoCompletion
= (void *)GetProcAddress(hntdll
, "NtOpenIoCompletion");
5358 pNtQueryIoCompletion
= (void *)GetProcAddress(hntdll
, "NtQueryIoCompletion");
5359 pNtRemoveIoCompletion
= (void *)GetProcAddress(hntdll
, "NtRemoveIoCompletion");
5360 pNtRemoveIoCompletionEx
= (void *)GetProcAddress(hntdll
, "NtRemoveIoCompletionEx");
5361 pNtSetIoCompletion
= (void *)GetProcAddress(hntdll
, "NtSetIoCompletion");
5362 pNtSetInformationFile
= (void *)GetProcAddress(hntdll
, "NtSetInformationFile");
5363 pNtQueryAttributesFile
= (void *)GetProcAddress(hntdll
, "NtQueryAttributesFile");
5364 pNtQueryInformationFile
= (void *)GetProcAddress(hntdll
, "NtQueryInformationFile");
5365 pNtQueryDirectoryFile
= (void *)GetProcAddress(hntdll
, "NtQueryDirectoryFile");
5366 pNtQueryVolumeInformationFile
= (void *)GetProcAddress(hntdll
, "NtQueryVolumeInformationFile");
5367 pNtQueryFullAttributesFile
= (void *)GetProcAddress(hntdll
, "NtQueryFullAttributesFile");
5368 pNtFlushBuffersFile
= (void *)GetProcAddress(hntdll
, "NtFlushBuffersFile");
5369 pNtQueryEaFile
= (void *)GetProcAddress(hntdll
, "NtQueryEaFile");
5372 test_NtCreateFile();
5379 test_set_io_completion();
5380 test_file_io_completion();
5381 test_file_basic_information();
5382 test_file_all_information();
5383 test_file_both_information();
5384 test_file_name_information();
5385 test_file_full_size_information();
5386 test_file_all_name_information();
5387 test_file_rename_information();
5388 test_file_link_information();
5389 test_file_disposition_information();
5390 test_file_completion_information();
5391 test_file_id_information();
5392 test_file_access_information();
5393 test_file_attribute_tag_information();
5395 test_file_readonly_access();
5396 test_query_volume_information_file();
5397 test_query_attribute_information_file();
5400 test_flush_buffers_file();
5401 test_mailslot_name();