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
*);
88 static inline BOOL
is_signaled( HANDLE obj
)
90 return WaitForSingleObject( obj
, 0 ) == WAIT_OBJECT_0
;
93 #define TEST_BUF_LEN 3
95 static HANDLE
create_temp_file( ULONG flags
)
97 char path
[MAX_PATH
], buffer
[MAX_PATH
];
100 GetTempPathA( MAX_PATH
, path
);
101 GetTempFileNameA( path
, "foo", 0, buffer
);
102 handle
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
103 flags
| FILE_FLAG_DELETE_ON_CLOSE
, 0);
104 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
105 return (handle
== INVALID_HANDLE_VALUE
) ? 0 : handle
;
108 #define CVALUE_FIRST 0xfffabbcc
109 #define CKEY_FIRST 0x1030341
110 #define CKEY_SECOND 0x132E46
112 static ULONG
get_pending_msgs(HANDLE h
)
117 res
= pNtQueryIoCompletion( h
, IoCompletionBasicInformation
, &a
, sizeof(a
), &req
);
118 ok( res
== STATUS_SUCCESS
, "NtQueryIoCompletion failed: %x\n", res
);
119 if (res
!= STATUS_SUCCESS
) return -1;
120 ok( req
== sizeof(a
), "Unexpected response size: %x\n", req
);
124 static void WINAPI
apc( void *arg
, IO_STATUS_BLOCK
*iosb
, ULONG reserved
)
128 trace( "apc called block %p iosb.status %x iosb.info %lu\n",
129 iosb
, U(*iosb
).Status
, iosb
->Information
);
131 ok( !reserved
, "reserved is not 0: %x\n", reserved
);
134 static void create_file_test(void)
136 static const WCHAR systemrootW
[] = {'\\','S','y','s','t','e','m','R','o','o','t',
137 '\\','f','a','i','l','i','n','g',0};
138 static const WCHAR questionmarkInvalidNameW
[] = {'a','f','i','l','e','?',0};
139 static const WCHAR pipeInvalidNameW
[] = {'a','|','b',0};
140 static const WCHAR pathInvalidNtW
[] = {'\\','\\','?','\\',0};
141 static const WCHAR pathInvalidNt2W
[] = {'\\','?','?','\\',0};
142 static const WCHAR pathInvalidDosW
[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0};
143 static const char testdata
[] = "Hello World";
144 FILE_NETWORK_OPEN_INFORMATION info
;
147 WCHAR path
[MAX_PATH
];
148 OBJECT_ATTRIBUTES attr
;
150 UNICODE_STRING nameW
;
151 LARGE_INTEGER offset
;
155 GetCurrentDirectoryW( MAX_PATH
, path
);
156 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
157 attr
.Length
= sizeof(attr
);
158 attr
.RootDirectory
= 0;
159 attr
.ObjectName
= &nameW
;
160 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
161 attr
.SecurityDescriptor
= NULL
;
162 attr
.SecurityQualityOfService
= NULL
;
164 /* try various open modes and options on directories */
165 status
= pNtCreateFile( &dir
, GENERIC_READ
|GENERIC_WRITE
, &attr
, &io
, NULL
, 0,
166 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, FILE_DIRECTORY_FILE
, NULL
, 0 );
167 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
169 U(io
).Status
= 0xdeadbeef;
171 status
= pNtReadFile( dir
, NULL
, NULL
, NULL
, &io
, buf
, sizeof(buf
), &offset
, NULL
);
173 ok( status
== STATUS_INVALID_DEVICE_REQUEST
|| status
== STATUS_PENDING
, "NtReadFile error %08x\n", status
);
174 if (status
== STATUS_PENDING
)
176 ret
= WaitForSingleObject( dir
, 1000 );
177 ok( ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %u\n", ret
);
178 ok( U(io
).Status
== STATUS_INVALID_DEVICE_REQUEST
,
179 "expected STATUS_INVALID_DEVICE_REQUEST, got %08x\n", U(io
).Status
);
182 U(io
).Status
= 0xdeadbeef;
184 status
= pNtWriteFile( dir
, NULL
, NULL
, NULL
, &io
, testdata
, sizeof(testdata
), &offset
, NULL
);
186 ok( status
== STATUS_INVALID_DEVICE_REQUEST
|| status
== STATUS_PENDING
, "NtWriteFile error %08x\n", status
);
187 if (status
== STATUS_PENDING
)
189 ret
= WaitForSingleObject( dir
, 1000 );
190 ok( ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %u\n", ret
);
191 ok( U(io
).Status
== STATUS_INVALID_DEVICE_REQUEST
,
192 "expected STATUS_INVALID_DEVICE_REQUEST, got %08x\n", U(io
).Status
);
197 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
198 FILE_CREATE
, FILE_DIRECTORY_FILE
, NULL
, 0 );
199 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
200 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
202 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
203 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, NULL
, 0 );
204 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
207 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
208 FILE_SUPERSEDE
, FILE_DIRECTORY_FILE
, NULL
, 0 );
209 ok( status
== STATUS_INVALID_PARAMETER
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
211 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
212 FILE_OVERWRITE
, FILE_DIRECTORY_FILE
, NULL
, 0 );
213 ok( status
== STATUS_INVALID_PARAMETER
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
215 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
216 FILE_OVERWRITE_IF
, FILE_DIRECTORY_FILE
, NULL
, 0 );
217 ok( status
== STATUS_INVALID_PARAMETER
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
219 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
220 FILE_OPEN
, 0, NULL
, 0 );
221 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
224 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
225 FILE_CREATE
, 0, NULL
, 0 );
226 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
227 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
229 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
230 FILE_OPEN_IF
, 0, NULL
, 0 );
231 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
234 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
235 FILE_SUPERSEDE
, 0, NULL
, 0 );
236 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
237 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
239 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
240 FILE_OVERWRITE
, 0, NULL
, 0 );
241 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
242 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
244 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
245 FILE_OVERWRITE_IF
, 0, NULL
, 0 );
246 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
247 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
249 pRtlFreeUnicodeString( &nameW
);
251 pRtlInitUnicodeString( &nameW
, systemrootW
);
252 attr
.Length
= sizeof(attr
);
253 attr
.RootDirectory
= NULL
;
254 attr
.ObjectName
= &nameW
;
255 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
256 attr
.SecurityDescriptor
= NULL
;
257 attr
.SecurityQualityOfService
= NULL
;
259 status
= pNtCreateFile( &dir
, FILE_APPEND_DATA
, &attr
, &io
, NULL
, FILE_ATTRIBUTE_NORMAL
, 0,
260 FILE_OPEN_IF
, FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
262 ok( status
== STATUS_INVALID_PARAMETER
,
263 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
265 /* Invalid chars in file/dirnames */
266 pRtlDosPathNameToNtPathName_U(questionmarkInvalidNameW
, &nameW
, NULL
, NULL
);
267 attr
.ObjectName
= &nameW
;
268 status
= pNtCreateFile(&dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
269 FILE_SHARE_READ
, FILE_CREATE
,
270 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
271 ok(status
== STATUS_OBJECT_NAME_INVALID
,
272 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
274 status
= pNtCreateFile(&file
, GENERIC_WRITE
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
276 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
277 ok(status
== STATUS_OBJECT_NAME_INVALID
,
278 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
279 pRtlFreeUnicodeString(&nameW
);
281 pRtlDosPathNameToNtPathName_U(pipeInvalidNameW
, &nameW
, NULL
, NULL
);
282 attr
.ObjectName
= &nameW
;
283 status
= pNtCreateFile(&dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
284 FILE_SHARE_READ
, FILE_CREATE
,
285 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
286 ok(status
== STATUS_OBJECT_NAME_INVALID
,
287 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
289 status
= pNtCreateFile(&file
, GENERIC_WRITE
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
291 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
292 ok(status
== STATUS_OBJECT_NAME_INVALID
,
293 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
294 pRtlFreeUnicodeString(&nameW
);
296 pRtlInitUnicodeString( &nameW
, pathInvalidNtW
);
297 status
= pNtCreateFile( &dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
298 FILE_SHARE_READ
, FILE_CREATE
,
299 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
300 ok( status
== STATUS_OBJECT_NAME_INVALID
,
301 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
303 status
= pNtQueryFullAttributesFile( &attr
, &info
);
304 todo_wine
ok( status
== STATUS_OBJECT_NAME_INVALID
,
305 "query %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
307 pRtlInitUnicodeString( &nameW
, pathInvalidNt2W
);
308 status
= pNtCreateFile( &dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
309 FILE_SHARE_READ
, FILE_CREATE
,
310 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
311 ok( status
== STATUS_OBJECT_NAME_INVALID
,
312 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
314 status
= pNtQueryFullAttributesFile( &attr
, &info
);
315 ok( status
== STATUS_OBJECT_NAME_INVALID
,
316 "query %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
318 pRtlInitUnicodeString( &nameW
, pathInvalidDosW
);
319 status
= pNtCreateFile( &dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
320 FILE_SHARE_READ
, FILE_CREATE
,
321 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
322 ok( status
== STATUS_OBJECT_NAME_INVALID
,
323 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
325 status
= pNtQueryFullAttributesFile( &attr
, &info
);
326 ok( status
== STATUS_OBJECT_NAME_INVALID
,
327 "query %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
330 static void open_file_test(void)
332 static const WCHAR testdirW
[] = {'o','p','e','n','f','i','l','e','t','e','s','t',0};
333 static const char testdata
[] = "Hello World";
334 static WCHAR fooW
[] = {'f','o','o',0};
336 HANDLE dir
, root
, handle
, file
;
337 WCHAR path
[MAX_PATH
], tmpfile
[MAX_PATH
];
339 OBJECT_ATTRIBUTES attr
;
341 UNICODE_STRING nameW
;
343 BOOL ret
, restart
= TRUE
;
346 len
= GetWindowsDirectoryW( path
, MAX_PATH
);
347 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
348 attr
.Length
= sizeof(attr
);
349 attr
.RootDirectory
= 0;
350 attr
.ObjectName
= &nameW
;
351 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
352 attr
.SecurityDescriptor
= NULL
;
353 attr
.SecurityQualityOfService
= NULL
;
354 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
355 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
356 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
357 pRtlFreeUnicodeString( &nameW
);
359 path
[3] = 0; /* root of the drive */
360 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
361 status
= pNtOpenFile( &root
, GENERIC_READ
, &attr
, &io
,
362 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
363 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
364 pRtlFreeUnicodeString( &nameW
);
366 /* test opening system dir with RootDirectory set to windows dir */
367 GetSystemDirectoryW( path
, MAX_PATH
);
368 while (path
[len
] == '\\') len
++;
369 nameW
.Buffer
= path
+ len
;
370 nameW
.Length
= lstrlenW(path
+ len
) * sizeof(WCHAR
);
371 attr
.RootDirectory
= dir
;
372 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
373 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
374 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
375 CloseHandle( handle
);
377 /* try uppercase name */
378 for (i
= len
; path
[i
]; i
++) if (path
[i
] >= 'a' && path
[i
] <= 'z') path
[i
] -= 'a' - 'A';
379 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
380 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
381 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
382 CloseHandle( handle
);
384 /* try with leading backslash */
386 nameW
.Length
+= sizeof(WCHAR
);
387 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
388 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
389 ok( status
== STATUS_INVALID_PARAMETER
||
390 status
== STATUS_OBJECT_NAME_INVALID
||
391 status
== STATUS_OBJECT_PATH_SYNTAX_BAD
,
392 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
393 if (!status
) CloseHandle( handle
);
395 /* try with empty name */
397 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
398 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
399 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
400 CloseHandle( handle
);
403 GetTempPathW( MAX_PATH
, path
);
404 lstrcatW( path
, testdirW
);
405 CreateDirectoryW( path
, NULL
);
407 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
408 attr
.RootDirectory
= NULL
;
409 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
410 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
411 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
412 pRtlFreeUnicodeString( &nameW
);
414 GetTempFileNameW( path
, fooW
, 0, tmpfile
);
415 file
= CreateFileW( tmpfile
, FILE_WRITE_DATA
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
416 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError() );
417 numbytes
= 0xdeadbeef;
418 ret
= WriteFile( file
, testdata
, sizeof(testdata
) - 1, &numbytes
, NULL
);
419 ok( ret
, "WriteFile failed with error %u\n", GetLastError() );
420 ok( numbytes
== sizeof(testdata
) - 1, "failed to write all data\n" );
423 /* try open by file id */
425 while (!pNtQueryDirectoryFile( dir
, NULL
, NULL
, NULL
, &io
, data
, sizeof(data
),
426 FileIdBothDirectoryInformation
, TRUE
, NULL
, restart
))
428 FILE_ID_BOTH_DIRECTORY_INFORMATION
*info
= (FILE_ID_BOTH_DIRECTORY_INFORMATION
*)data
;
432 if (!info
->FileId
.QuadPart
) continue;
434 nameW
.Buffer
= (WCHAR
*)&info
->FileId
;
435 nameW
.Length
= sizeof(info
->FileId
);
436 info
->FileName
[info
->FileNameLength
/sizeof(WCHAR
)] = 0;
437 attr
.RootDirectory
= dir
;
438 /* We skip 'open' files by not specifying FILE_SHARE_WRITE */
439 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
441 FILE_OPEN_BY_FILE_ID
|
442 ((info
->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) ? FILE_DIRECTORY_FILE
: 0) );
443 ok( status
== STATUS_SUCCESS
, "open %s failed %x\n", wine_dbgstr_w(info
->FileName
), status
);
446 BYTE buf
[sizeof(FILE_ALL_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
)];
448 if (!pNtQueryInformationFile( handle
, &io
, buf
, sizeof(buf
), FileAllInformation
))
450 FILE_ALL_INFORMATION
*fai
= (FILE_ALL_INFORMATION
*)buf
;
452 /* check that it's the same file/directory */
454 /* don't check the size for directories */
455 if (!(info
->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
456 ok( info
->EndOfFile
.QuadPart
== fai
->StandardInformation
.EndOfFile
.QuadPart
,
457 "mismatched file size for %s\n", wine_dbgstr_w(info
->FileName
));
459 ok( info
->CreationTime
.QuadPart
== fai
->BasicInformation
.CreationTime
.QuadPart
,
460 "mismatched creation time for %s\n", wine_dbgstr_w(info
->FileName
));
462 CloseHandle( handle
);
464 /* try same thing from drive root */
465 attr
.RootDirectory
= root
;
466 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
467 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
468 FILE_OPEN_BY_FILE_ID
|
469 ((info
->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) ? FILE_DIRECTORY_FILE
: 0) );
470 ok( status
== STATUS_SUCCESS
|| status
== STATUS_NOT_IMPLEMENTED
,
471 "open %s failed %x\n", wine_dbgstr_w(info
->FileName
), status
);
472 if (!status
) CloseHandle( handle
);
479 pRtlDosPathNameToNtPathName_U( tmpfile
, &nameW
, NULL
, NULL
);
480 attr
.Length
= sizeof(attr
);
481 attr
.RootDirectory
= 0;
482 attr
.ObjectName
= &nameW
;
483 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
484 attr
.SecurityDescriptor
= NULL
;
485 attr
.SecurityQualityOfService
= NULL
;
486 status
= pNtOpenFile( &file
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
487 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
);
488 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
489 pRtlFreeUnicodeString( &nameW
);
491 numbytes
= 0xdeadbeef;
492 memset( data
, 0, sizeof(data
) );
493 ret
= ReadFile( file
, data
, sizeof(data
), &numbytes
, NULL
);
494 ok( ret
, "ReadFile failed with error %u\n", GetLastError() );
495 ok( numbytes
== sizeof(testdata
) - 1, "failed to read all data\n" );
496 ok( !memcmp( data
, testdata
, sizeof(testdata
) - 1 ), "testdata doesn't match\n" );
498 nameW
.Length
= sizeof(fooW
) - sizeof(WCHAR
);
500 attr
.RootDirectory
= file
;
501 attr
.ObjectName
= &nameW
;
502 status
= pNtOpenFile( &root
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
503 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
);
504 ok( status
== STATUS_OBJECT_PATH_NOT_FOUND
,
505 "expected STATUS_OBJECT_PATH_NOT_FOUND, got %08x\n", status
);
509 attr
.RootDirectory
= file
;
510 attr
.ObjectName
= &nameW
;
511 status
= pNtOpenFile( &root
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
512 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
);
513 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(tmpfile
), status
);
515 numbytes
= SetFilePointer( file
, 0, 0, FILE_CURRENT
);
516 ok( numbytes
== sizeof(testdata
) - 1, "SetFilePointer returned %u\n", numbytes
);
517 numbytes
= SetFilePointer( root
, 0, 0, FILE_CURRENT
);
518 ok( numbytes
== 0, "SetFilePointer returned %u\n", numbytes
);
520 numbytes
= 0xdeadbeef;
521 memset( data
, 0, sizeof(data
) );
522 ret
= ReadFile( root
, data
, sizeof(data
), &numbytes
, NULL
);
523 ok( ret
, "ReadFile failed with error %u\n", GetLastError() );
524 ok( numbytes
== sizeof(testdata
) - 1, "failed to read all data\n" );
525 ok( !memcmp( data
, testdata
, sizeof(testdata
) - 1 ), "testdata doesn't match\n" );
527 numbytes
= SetFilePointer( file
, 0, 0, FILE_CURRENT
);
528 ok( numbytes
== sizeof(testdata
) - 1, "SetFilePointer returned %u\n", numbytes
);
529 numbytes
= SetFilePointer( root
, 0, 0, FILE_CURRENT
);
530 ok( numbytes
== sizeof(testdata
) - 1, "SetFilePointer returned %u\n", numbytes
);
534 DeleteFileW( tmpfile
);
535 RemoveDirectoryW( path
);
538 static void delete_file_test(void)
541 OBJECT_ATTRIBUTES attr
;
542 UNICODE_STRING nameW
;
543 WCHAR pathW
[MAX_PATH
];
544 WCHAR pathsubW
[MAX_PATH
];
545 static const WCHAR testdirW
[] = {'n','t','d','e','l','e','t','e','f','i','l','e',0};
546 static const WCHAR subdirW
[] = {'\\','s','u','b',0};
548 ret
= GetTempPathW(MAX_PATH
, pathW
);
551 ok(0, "couldn't get temp dir\n");
554 if (ret
+ ARRAY_SIZE(testdirW
)-1 + ARRAY_SIZE(subdirW
)-1 >= MAX_PATH
)
556 ok(0, "MAX_PATH exceeded in constructing paths\n");
560 lstrcatW(pathW
, testdirW
);
561 lstrcpyW(pathsubW
, pathW
);
562 lstrcatW(pathsubW
, subdirW
);
564 ret
= CreateDirectoryW(pathW
, NULL
);
565 ok(ret
== TRUE
, "couldn't create directory ntdeletefile\n");
566 if (!pRtlDosPathNameToNtPathName_U(pathW
, &nameW
, NULL
, NULL
))
568 ok(0,"RtlDosPathNametoNtPathName_U failed\n");
572 attr
.Length
= sizeof(attr
);
573 attr
.RootDirectory
= 0;
574 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
575 attr
.ObjectName
= &nameW
;
576 attr
.SecurityDescriptor
= NULL
;
577 attr
.SecurityQualityOfService
= NULL
;
579 /* test NtDeleteFile on an empty directory */
580 ret
= pNtDeleteFile(&attr
);
581 ok(ret
== STATUS_SUCCESS
, "NtDeleteFile should succeed in removing an empty directory\n");
582 ret
= RemoveDirectoryW(pathW
);
583 ok(ret
== FALSE
, "expected to fail removing directory, NtDeleteFile should have removed it\n");
585 /* test NtDeleteFile on a non-empty directory */
586 ret
= CreateDirectoryW(pathW
, NULL
);
587 ok(ret
== TRUE
, "couldn't create directory ntdeletefile ?!\n");
588 ret
= CreateDirectoryW(pathsubW
, NULL
);
589 ok(ret
== TRUE
, "couldn't create directory subdir\n");
590 ret
= pNtDeleteFile(&attr
);
591 ok(ret
== STATUS_SUCCESS
, "expected NtDeleteFile to ret STATUS_SUCCESS\n");
592 ret
= RemoveDirectoryW(pathsubW
);
593 ok(ret
== TRUE
, "expected to remove directory ntdeletefile\\sub\n");
594 ret
= RemoveDirectoryW(pathW
);
595 ok(ret
== TRUE
, "expected to remove directory ntdeletefile, NtDeleteFile failed.\n");
597 pRtlFreeUnicodeString( &nameW
);
600 static void read_file_test(void)
602 const char text
[] = "foobar";
604 IO_STATUS_BLOCK iosb
;
608 LARGE_INTEGER offset
;
609 HANDLE event
= CreateEventA( NULL
, TRUE
, FALSE
, NULL
);
611 if (!(handle
= create_temp_file( FILE_FLAG_OVERLAPPED
))) return;
613 U(iosb
).Status
= 0xdeadbabe;
614 iosb
.Information
= 0xdeadbeef;
617 status
= pNtWriteFile( handle
, event
, apc
, &apc_count
, &iosb
, text
, strlen(text
), &offset
, NULL
);
618 ok( status
== STATUS_SUCCESS
|| status
== STATUS_PENDING
, "wrong status %x\n", status
);
619 if (status
== STATUS_PENDING
) WaitForSingleObject( event
, 1000 );
620 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
621 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
622 ok( is_signaled( event
), "event is not signaled\n" );
623 ok( !apc_count
, "apc was called\n" );
624 SleepEx( 1, TRUE
); /* alertable sleep */
625 ok( apc_count
== 1, "apc was not called\n" );
628 U(iosb
).Status
= 0xdeadbabe;
629 iosb
.Information
= 0xdeadbeef;
632 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, strlen(text
) + 10, &offset
, NULL
);
633 ok( status
== STATUS_SUCCESS
||
634 status
== STATUS_PENDING
, /* vista */
635 "wrong status %x\n", status
);
636 if (status
== STATUS_PENDING
) WaitForSingleObject( event
, 1000 );
637 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
638 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
639 ok( is_signaled( event
), "event is not signaled\n" );
640 ok( !apc_count
, "apc was called\n" );
641 SleepEx( 1, TRUE
); /* alertable sleep */
642 ok( apc_count
== 1, "apc was not called\n" );
644 /* read beyond eof */
646 U(iosb
).Status
= 0xdeadbabe;
647 iosb
.Information
= 0xdeadbeef;
648 offset
.QuadPart
= strlen(text
) + 2;
649 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, &offset
, NULL
);
650 ok(status
== STATUS_PENDING
|| status
== STATUS_END_OF_FILE
/* before Vista */, "expected STATUS_PENDING or STATUS_END_OF_FILE, got %#x\n", status
);
651 if (status
== STATUS_PENDING
) /* vista */
653 WaitForSingleObject( event
, 1000 );
654 ok( U(iosb
).Status
== STATUS_END_OF_FILE
, "wrong status %x\n", U(iosb
).Status
);
655 ok( iosb
.Information
== 0, "wrong info %lu\n", iosb
.Information
);
656 ok( is_signaled( event
), "event is not signaled\n" );
657 ok( !apc_count
, "apc was called\n" );
658 SleepEx( 1, TRUE
); /* alertable sleep */
659 ok( apc_count
== 1, "apc was not called\n" );
661 CloseHandle( handle
);
663 /* now a non-overlapped file */
664 if (!(handle
= create_temp_file(0))) return;
666 U(iosb
).Status
= 0xdeadbabe;
667 iosb
.Information
= 0xdeadbeef;
669 status
= pNtWriteFile( handle
, event
, apc
, &apc_count
, &iosb
, text
, strlen(text
), &offset
, NULL
);
670 ok( status
== STATUS_END_OF_FILE
||
671 status
== STATUS_SUCCESS
||
672 status
== STATUS_PENDING
, /* vista */
673 "wrong status %x\n", status
);
674 if (status
== STATUS_PENDING
) WaitForSingleObject( event
, 1000 );
675 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
676 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
677 ok( is_signaled( event
), "event is not signaled\n" );
678 ok( !apc_count
, "apc was called\n" );
679 SleepEx( 1, TRUE
); /* alertable sleep */
680 ok( apc_count
== 1, "apc was not called\n" );
683 U(iosb
).Status
= 0xdeadbabe;
684 iosb
.Information
= 0xdeadbeef;
687 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, strlen(text
) + 10, &offset
, NULL
);
688 ok( status
== STATUS_SUCCESS
, "wrong status %x\n", status
);
689 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
690 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
691 ok( is_signaled( event
), "event is not signaled\n" );
692 ok( !apc_count
, "apc was called\n" );
693 SleepEx( 1, TRUE
); /* alertable sleep */
694 todo_wine
ok( !apc_count
, "apc was called\n" );
696 /* read beyond eof */
698 U(iosb
).Status
= 0xdeadbabe;
699 iosb
.Information
= 0xdeadbeef;
700 offset
.QuadPart
= strlen(text
) + 2;
702 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, &offset
, NULL
);
703 ok( status
== STATUS_END_OF_FILE
, "wrong status %x\n", status
);
704 ok( U(iosb
).Status
== STATUS_END_OF_FILE
, "wrong status %x\n", U(iosb
).Status
);
705 ok( iosb
.Information
== 0, "wrong info %lu\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
, "apc was called\n" );
711 CloseHandle( handle
);
713 CloseHandle( event
);
716 static void append_file_test(void)
718 static const char text
[6] = "foobar";
721 IO_STATUS_BLOCK iosb
;
722 LARGE_INTEGER offset
;
723 char path
[MAX_PATH
], buffer
[MAX_PATH
], buf
[16];
726 GetTempPathA( MAX_PATH
, path
);
727 GetTempFileNameA( path
, "foo", 0, buffer
);
729 handle
= CreateFileA(buffer
, FILE_WRITE_DATA
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
730 ok(handle
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError());
733 iosb
.Information
= -1;
734 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
, 2, NULL
, NULL
);
735 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
736 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
737 ok(iosb
.Information
== 2, "expected 2, got %lu\n", iosb
.Information
);
741 /* It is possible to open a file with only FILE_APPEND_DATA access flags.
742 It matches the O_WRONLY|O_APPEND open() posix behavior */
743 handle
= CreateFileA(buffer
, FILE_APPEND_DATA
, 0, NULL
, OPEN_EXISTING
, 0, 0);
744 ok(handle
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError());
747 iosb
.Information
= -1;
749 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
+ 2, 2, &offset
, NULL
);
750 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
751 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
752 ok(iosb
.Information
== 2, "expected 2, got %lu\n", iosb
.Information
);
754 ret
= SetFilePointer(handle
, 0, NULL
, FILE_CURRENT
);
755 ok(ret
== 4, "expected 4, got %u\n", ret
);
758 iosb
.Information
= -1;
760 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
+ 4, 2, &offset
, NULL
);
761 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
762 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
763 ok(iosb
.Information
== 2, "expected 2, got %lu\n", iosb
.Information
);
765 ret
= SetFilePointer(handle
, 0, NULL
, FILE_CURRENT
);
766 ok(ret
== 6, "expected 6, got %u\n", ret
);
770 handle
= CreateFileA(buffer
, FILE_READ_DATA
| FILE_WRITE_DATA
| FILE_APPEND_DATA
, 0, NULL
, OPEN_EXISTING
, 0, 0);
771 ok(handle
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError());
773 memset(buf
, 0, sizeof(buf
));
775 iosb
.Information
= -1;
777 status
= pNtReadFile(handle
, 0, NULL
, NULL
, &iosb
, buf
, sizeof(buf
), &offset
, NULL
);
778 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
779 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
780 ok(iosb
.Information
== 6, "expected 6, got %lu\n", iosb
.Information
);
782 ok(memcmp(buf
, text
, 6) == 0, "wrong file contents: %s\n", buf
);
785 iosb
.Information
= -1;
787 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
+ 3, 3, &offset
, NULL
);
788 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
789 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
790 ok(iosb
.Information
== 3, "expected 3, got %lu\n", iosb
.Information
);
792 memset(buf
, 0, sizeof(buf
));
794 iosb
.Information
= -1;
796 status
= pNtReadFile(handle
, 0, NULL
, NULL
, &iosb
, buf
, sizeof(buf
), &offset
, NULL
);
797 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
798 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
799 ok(iosb
.Information
== 6, "expected 6, got %lu\n", iosb
.Information
);
801 ok(memcmp(buf
, "barbar", 6) == 0, "wrong file contents: %s\n", buf
);
807 static void nt_mailslot_test(void)
810 ACCESS_MASK DesiredAccess
;
811 OBJECT_ATTRIBUTES attr
;
815 ULONG MaxMessageSize
;
816 LARGE_INTEGER TimeOut
;
817 IO_STATUS_BLOCK IoStatusBlock
;
820 WCHAR buffer1
[] = { '\\','?','?','\\','M','A','I','L','S','L','O','T','\\',
821 'R',':','\\','F','R','E','D','\0' };
823 TimeOut
.QuadPart
= -1;
825 pRtlInitUnicodeString(&str
, buffer1
);
826 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
827 CreateOptions
= MailslotQuota
= MaxMessageSize
= 0;
828 DesiredAccess
= GENERIC_READ
;
831 * Check for NULL pointer handling
833 rc
= pNtCreateMailslotFile(NULL
, DesiredAccess
,
834 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
836 ok( rc
== STATUS_ACCESS_VIOLATION
||
837 rc
== STATUS_INVALID_PARAMETER
, /* win2k3 */
838 "rc = %x not STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER\n", rc
);
841 * Test to see if the Timeout can be NULL
843 hslot
= (HANDLE
)0xdeadbeef;
844 rc
= pNtCreateMailslotFile(&hslot
, DesiredAccess
,
845 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
847 ok( rc
== STATUS_SUCCESS
||
848 rc
== STATUS_INVALID_PARAMETER
, /* win2k3 */
849 "rc = %x not STATUS_SUCCESS or STATUS_INVALID_PARAMETER\n", rc
);
850 ok( hslot
!= 0, "Handle is invalid\n");
852 if ( rc
== STATUS_SUCCESS
) pNtClose(hslot
);
857 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
858 rc
= pNtCreateMailslotFile(&hslot
, DesiredAccess
,
859 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
861 ok( rc
== STATUS_SUCCESS
, "Create MailslotFile failed rc = %x\n", rc
);
862 ok( hslot
!= 0, "Handle is invalid\n");
864 rc
= pNtClose(hslot
);
865 ok( rc
== STATUS_SUCCESS
, "NtClose failed\n");
868 static void WINAPI
user_apc_proc(ULONG_PTR arg
)
870 unsigned int *apc_count
= (unsigned int *)arg
;
874 static void test_set_io_completion(void)
876 FILE_IO_COMPLETION_INFORMATION info
[2] = {{0}};
877 LARGE_INTEGER timeout
= {{0}};
878 unsigned int apc_count
;
879 IO_STATUS_BLOCK iosb
;
880 ULONG_PTR key
, value
;
886 if (sizeof(size
) > 4) size
|= (ULONGLONG
)0x12345678 << 32;
888 res
= pNtCreateIoCompletion( &h
, IO_COMPLETION_ALL_ACCESS
, NULL
, 0 );
889 ok( res
== STATUS_SUCCESS
, "NtCreateIoCompletion failed: %#x\n", res
);
890 ok( h
&& h
!= INVALID_HANDLE_VALUE
, "got invalid handle %p\n", h
);
892 res
= pNtRemoveIoCompletion( h
, &key
, &value
, &iosb
, &timeout
);
893 ok( res
== STATUS_TIMEOUT
, "NtRemoveIoCompletion failed: %#x\n", res
);
895 res
= pNtSetIoCompletion( h
, CKEY_FIRST
, CVALUE_FIRST
, STATUS_INVALID_DEVICE_REQUEST
, size
);
896 ok( res
== STATUS_SUCCESS
, "NtSetIoCompletion failed: %x\n", res
);
898 count
= get_pending_msgs(h
);
899 ok( count
== 1, "Unexpected msg count: %d\n", count
);
901 res
= pNtRemoveIoCompletion( h
, &key
, &value
, &iosb
, &timeout
);
902 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletion failed: %#x\n", res
);
903 ok( key
== CKEY_FIRST
, "Invalid completion key: %#lx\n", key
);
904 ok( iosb
.Information
== size
, "Invalid iosb.Information: %lu\n", iosb
.Information
);
905 ok( U(iosb
).Status
== STATUS_INVALID_DEVICE_REQUEST
, "Invalid iosb.Status: %#x\n", U(iosb
).Status
);
906 ok( value
== CVALUE_FIRST
, "Invalid completion value: %#lx\n", value
);
908 count
= get_pending_msgs(h
);
909 ok( !count
, "Unexpected msg count: %d\n", count
);
911 if (!pNtRemoveIoCompletionEx
)
913 skip("NtRemoveIoCompletionEx() not present\n");
919 res
= pNtRemoveIoCompletionEx( h
, info
, 2, &count
, &timeout
, FALSE
);
920 ok( res
== STATUS_TIMEOUT
, "NtRemoveIoCompletionEx failed: %#x\n", res
);
921 ok( count
== 1, "wrong count %u\n", count
);
923 res
= pNtSetIoCompletion( h
, 123, 456, 789, size
);
924 ok( res
== STATUS_SUCCESS
, "NtSetIoCompletion failed: %#x\n", res
);
927 res
= pNtRemoveIoCompletionEx( h
, info
, 2, &count
, &timeout
, FALSE
);
928 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletionEx failed: %#x\n", res
);
929 ok( count
== 1, "wrong count %u\n", count
);
930 ok( info
[0].CompletionKey
== 123, "wrong key %#lx\n", info
[0].CompletionKey
);
931 ok( info
[0].CompletionValue
== 456, "wrong value %#lx\n", info
[0].CompletionValue
);
932 ok( info
[0].IoStatusBlock
.Information
== size
, "wrong information %#lx\n",
933 info
[0].IoStatusBlock
.Information
);
934 ok( U(info
[0].IoStatusBlock
).Status
== 789, "wrong status %#x\n", U(info
[0].IoStatusBlock
).Status
);
936 res
= pNtSetIoCompletion( h
, 123, 456, 789, size
);
937 ok( res
== STATUS_SUCCESS
, "NtSetIoCompletion failed: %#x\n", res
);
939 res
= pNtSetIoCompletion( h
, 12, 34, 56, size
);
940 ok( res
== STATUS_SUCCESS
, "NtSetIoCompletion failed: %#x\n", res
);
943 res
= pNtRemoveIoCompletionEx( h
, info
, 2, &count
, &timeout
, FALSE
);
944 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletionEx failed: %#x\n", res
);
945 ok( count
== 2, "wrong count %u\n", count
);
946 ok( info
[0].CompletionKey
== 123, "wrong key %#lx\n", info
[0].CompletionKey
);
947 ok( info
[0].CompletionValue
== 456, "wrong value %#lx\n", info
[0].CompletionValue
);
948 ok( info
[0].IoStatusBlock
.Information
== size
, "wrong information %#lx\n",
949 info
[0].IoStatusBlock
.Information
);
950 ok( U(info
[0].IoStatusBlock
).Status
== 789, "wrong status %#x\n", U(info
[0].IoStatusBlock
).Status
);
951 ok( info
[1].CompletionKey
== 12, "wrong key %#lx\n", info
[1].CompletionKey
);
952 ok( info
[1].CompletionValue
== 34, "wrong value %#lx\n", info
[1].CompletionValue
);
953 ok( info
[1].IoStatusBlock
.Information
== size
, "wrong information %#lx\n",
954 info
[1].IoStatusBlock
.Information
);
955 ok( U(info
[1].IoStatusBlock
).Status
== 56, "wrong status %#x\n", U(info
[1].IoStatusBlock
).Status
);
958 QueueUserAPC( user_apc_proc
, GetCurrentThread(), (ULONG_PTR
)&apc_count
);
961 res
= pNtRemoveIoCompletionEx( h
, info
, 2, &count
, &timeout
, FALSE
);
962 ok( res
== STATUS_TIMEOUT
, "NtRemoveIoCompletionEx failed: %#x\n", res
);
963 ok( count
== 1, "wrong count %u\n", count
);
964 ok( !apc_count
, "wrong apc count %d\n", apc_count
);
966 res
= pNtRemoveIoCompletionEx( h
, info
, 2, &count
, &timeout
, TRUE
);
967 ok( res
== STATUS_USER_APC
, "NtRemoveIoCompletionEx failed: %#x\n", res
);
968 ok( count
== 1, "wrong count %u\n", count
);
969 ok( apc_count
== 1, "wrong apc count %u\n", apc_count
);
972 QueueUserAPC( user_apc_proc
, GetCurrentThread(), (ULONG_PTR
)&apc_count
);
974 res
= pNtSetIoCompletion( h
, 123, 456, 789, size
);
975 ok( res
== STATUS_SUCCESS
, "NtSetIoCompletion failed: %#x\n", res
);
977 res
= pNtRemoveIoCompletionEx( h
, info
, 2, &count
, &timeout
, TRUE
);
978 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletionEx failed: %#x\n", res
);
979 ok( count
== 1, "wrong count %u\n", count
);
980 ok( !apc_count
, "wrong apc count %u\n", apc_count
);
987 static void test_file_io_completion(void)
989 static const char pipe_name
[] = "\\\\.\\pipe\\iocompletiontestnamedpipe";
991 IO_STATUS_BLOCK iosb
;
992 BYTE send_buf
[TEST_BUF_LEN
], recv_buf
[TEST_BUF_LEN
];
993 FILE_COMPLETION_INFORMATION fci
;
994 LARGE_INTEGER timeout
= {{0}};
995 HANDLE server
, client
;
996 ULONG_PTR key
, value
;
1004 res
= pNtCreateIoCompletion( &h
, IO_COMPLETION_ALL_ACCESS
, NULL
, 0 );
1005 ok( res
== STATUS_SUCCESS
, "NtCreateIoCompletion failed: %#x\n", res
);
1006 ok( h
&& h
!= INVALID_HANDLE_VALUE
, "got invalid handle %p\n", h
);
1007 fci
.CompletionPort
= h
;
1008 fci
.CompletionKey
= CKEY_SECOND
;
1010 server
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
,
1011 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1012 4, 1024, 1024, 1000, NULL
);
1013 ok( server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed: %u\n", GetLastError() );
1014 client
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
,
1015 FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
1016 ok( client
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %u\n", GetLastError() );
1018 U(iosb
).Status
= 0xdeadbeef;
1019 res
= pNtSetInformationFile( server
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
1020 ok( res
== STATUS_INVALID_PARAMETER
, "NtSetInformationFile failed: %#x\n", res
);
1022 ok( U(iosb
).Status
== 0xdeadbeef, "wrong status %#x\n", U(iosb
).Status
);
1023 CloseHandle( client
);
1024 CloseHandle( server
);
1026 server
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
| FILE_FLAG_OVERLAPPED
,
1027 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1028 4, 1024, 1024, 1000, NULL
);
1029 ok( server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed: %u\n", GetLastError() );
1030 client
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
,
1031 FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
1032 ok( client
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %u\n", GetLastError() );
1034 U(iosb
).Status
= 0xdeadbeef;
1035 res
= pNtSetInformationFile( server
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
1036 ok( res
== STATUS_SUCCESS
, "NtSetInformationFile failed: %#x\n", res
);
1037 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %#x\n", U(iosb
).Status
);
1039 memset( send_buf
, 0, TEST_BUF_LEN
);
1040 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1041 count
= get_pending_msgs(h
);
1042 ok( !count
, "Unexpected msg count: %ld\n", count
);
1043 ReadFile( server
, recv_buf
, TEST_BUF_LEN
, &read
, &o
);
1044 count
= get_pending_msgs(h
);
1045 ok( !count
, "Unexpected msg count: %ld\n", count
);
1046 WriteFile( client
, send_buf
, TEST_BUF_LEN
, &read
, NULL
);
1048 res
= pNtRemoveIoCompletion( h
, &key
, &value
, &iosb
, &timeout
);
1049 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletion failed: %#x\n", res
);
1050 ok( key
== CKEY_SECOND
, "Invalid completion key: %#lx\n", key
);
1051 ok( iosb
.Information
== 3, "Invalid iosb.Information: %ld\n", iosb
.Information
);
1052 ok( U(iosb
).Status
== STATUS_SUCCESS
, "Invalid iosb.Status: %#x\n", U(iosb
).Status
);
1053 ok( value
== (ULONG_PTR
)&o
, "Invalid completion value: %#lx\n", value
);
1054 ok( !memcmp( send_buf
, recv_buf
, TEST_BUF_LEN
),
1055 "Receive buffer (%02x %02x %02x) did not match send buffer (%02x %02x %02x)\n",
1056 recv_buf
[0], recv_buf
[1], recv_buf
[2], send_buf
[0], send_buf
[1], send_buf
[2] );
1057 count
= get_pending_msgs(h
);
1058 ok( !count
, "Unexpected msg count: %ld\n", count
);
1060 memset( send_buf
, 0, TEST_BUF_LEN
);
1061 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1062 WriteFile( client
, send_buf
, 2, &read
, NULL
);
1063 count
= get_pending_msgs(h
);
1064 ok( !count
, "Unexpected msg count: %ld\n", count
);
1065 ReadFile( server
, recv_buf
, 2, &read
, &o
);
1066 count
= get_pending_msgs(h
);
1067 ok( count
== 1, "Unexpected msg count: %ld\n", count
);
1069 res
= pNtRemoveIoCompletion( h
, &key
, &value
, &iosb
, &timeout
);
1070 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletion failed: %#x\n", res
);
1071 ok( key
== CKEY_SECOND
, "Invalid completion key: %#lx\n", key
);
1072 ok( iosb
.Information
== 2, "Invalid iosb.Information: %ld\n", iosb
.Information
);
1073 ok( U(iosb
).Status
== STATUS_SUCCESS
, "Invalid iosb.Status: %#x\n", U(iosb
).Status
);
1074 ok( value
== (ULONG_PTR
)&o
, "Invalid completion value: %#lx\n", value
);
1075 ok( !memcmp( send_buf
, recv_buf
, 2 ),
1076 "Receive buffer (%02x %02x) did not match send buffer (%02x %02x)\n",
1077 recv_buf
[0], recv_buf
[1], send_buf
[0], send_buf
[1] );
1079 ReadFile( server
, recv_buf
, TEST_BUF_LEN
, &read
, &o
);
1080 CloseHandle( server
);
1081 count
= get_pending_msgs(h
);
1082 ok( count
== 1, "Unexpected msg count: %ld\n", count
);
1084 res
= pNtRemoveIoCompletion( h
, &key
, &value
, &iosb
, &timeout
);
1085 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletion failed: %#x\n", res
);
1086 ok( key
== CKEY_SECOND
, "Invalid completion key: %lx\n", key
);
1087 ok( iosb
.Information
== 0, "Invalid iosb.Information: %ld\n", iosb
.Information
);
1088 ok( U(iosb
).Status
== STATUS_PIPE_BROKEN
, "Invalid iosb.Status: %x\n", U(iosb
).Status
);
1089 ok( value
== (ULONG_PTR
)&o
, "Invalid completion value: %lx\n", value
);
1091 CloseHandle( client
);
1093 /* test associating a completion port with a handle after an async is queued */
1094 server
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
| FILE_FLAG_OVERLAPPED
,
1095 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1096 4, 1024, 1024, 1000, NULL
);
1097 ok( server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed: %u\n", GetLastError() );
1098 client
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
,
1099 FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
1100 ok( client
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %u\n", GetLastError() );
1102 memset( send_buf
, 0, TEST_BUF_LEN
);
1103 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1104 count
= get_pending_msgs(h
);
1105 ok( !count
, "Unexpected msg count: %ld\n", count
);
1106 ReadFile( server
, recv_buf
, TEST_BUF_LEN
, &read
, &o
);
1108 U(iosb
).Status
= 0xdeadbeef;
1109 res
= pNtSetInformationFile( server
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
1110 ok( res
== STATUS_SUCCESS
, "NtSetInformationFile failed: %x\n", res
);
1111 ok( U(iosb
).Status
== STATUS_SUCCESS
, "iosb.Status invalid: %x\n", U(iosb
).Status
);
1112 count
= get_pending_msgs(h
);
1113 ok( !count
, "Unexpected msg count: %ld\n", count
);
1115 WriteFile( client
, send_buf
, TEST_BUF_LEN
, &read
, NULL
);
1117 res
= pNtRemoveIoCompletion( h
, &key
, &value
, &iosb
, &timeout
);
1118 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletion failed: %#x\n", res
);
1119 ok( key
== CKEY_SECOND
, "Invalid completion key: %#lx\n", key
);
1120 ok( iosb
.Information
== 3, "Invalid iosb.Information: %ld\n", iosb
.Information
);
1121 ok( U(iosb
).Status
== STATUS_SUCCESS
, "Invalid iosb.Status: %#x\n", U(iosb
).Status
);
1122 ok( value
== (ULONG_PTR
)&o
, "Invalid completion value: %#lx\n", value
);
1123 ok( !memcmp( send_buf
, recv_buf
, TEST_BUF_LEN
),
1124 "Receive buffer (%02x %02x %02x) did not match send buffer (%02x %02x %02x)\n",
1125 recv_buf
[0], recv_buf
[1], recv_buf
[2], send_buf
[0], send_buf
[1], send_buf
[2] );
1127 count
= get_pending_msgs(h
);
1128 ok( !count
, "Unexpected msg count: %ld\n", count
);
1130 /* using APCs on handle with associated completion port is not allowed */
1131 res
= pNtReadFile( server
, NULL
, apc
, &apc_count
, &iosb
, recv_buf
, sizeof(recv_buf
), NULL
, NULL
);
1132 ok(res
== STATUS_INVALID_PARAMETER
, "NtReadFile returned %x\n", res
);
1134 CloseHandle( server
);
1135 CloseHandle( client
);
1137 /* test associating a completion port with a handle after an async using APC is queued */
1138 server
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
| FILE_FLAG_OVERLAPPED
,
1139 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1140 4, 1024, 1024, 1000, NULL
);
1141 ok( server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed: %u\n", GetLastError() );
1142 client
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
,
1143 FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
1144 ok( client
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %u\n", GetLastError() );
1147 memset( send_buf
, 0, TEST_BUF_LEN
);
1148 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1149 count
= get_pending_msgs(h
);
1150 ok( !count
, "Unexpected msg count: %ld\n", count
);
1152 res
= pNtReadFile( server
, NULL
, apc
, &apc_count
, &iosb
, recv_buf
, sizeof(recv_buf
), NULL
, NULL
);
1153 ok(res
== STATUS_PENDING
, "NtReadFile returned %x\n", res
);
1155 U(iosb
).Status
= 0xdeadbeef;
1156 res
= pNtSetInformationFile( server
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
1157 ok( res
== STATUS_SUCCESS
, "NtSetInformationFile failed: %x\n", res
);
1158 ok( U(iosb
).Status
== STATUS_SUCCESS
, "iosb.Status invalid: %x\n", U(iosb
).Status
);
1159 count
= get_pending_msgs(h
);
1160 ok( !count
, "Unexpected msg count: %ld\n", count
);
1162 WriteFile( client
, send_buf
, TEST_BUF_LEN
, &read
, NULL
);
1164 ok(!apc_count
, "apc_count = %u\n", apc_count
);
1165 count
= get_pending_msgs(h
);
1166 ok( !count
, "Unexpected msg count: %ld\n", count
);
1168 SleepEx(1, TRUE
); /* alertable sleep */
1169 ok(apc_count
== 1, "apc was not called\n");
1170 count
= get_pending_msgs(h
);
1171 ok( !count
, "Unexpected msg count: %ld\n", count
);
1173 /* using APCs on handle with associated completion port is not allowed */
1174 res
= pNtReadFile( server
, NULL
, apc
, &apc_count
, &iosb
, recv_buf
, sizeof(recv_buf
), NULL
, NULL
);
1175 ok(res
== STATUS_INVALID_PARAMETER
, "NtReadFile returned %x\n", res
);
1177 CloseHandle( server
);
1178 CloseHandle( client
);
1182 static void test_file_full_size_information(void)
1185 FILE_FS_FULL_SIZE_INFORMATION ffsi
;
1186 FILE_FS_SIZE_INFORMATION fsi
;
1190 if(!(h
= create_temp_file(0))) return ;
1192 memset(&ffsi
,0,sizeof(ffsi
));
1193 memset(&fsi
,0,sizeof(fsi
));
1195 /* Assume No Quota Settings configured on Wine Testbot */
1196 res
= pNtQueryVolumeInformationFile(h
, &io
, &ffsi
, sizeof ffsi
, FileFsFullSizeInformation
);
1197 todo_wine
ok(res
== STATUS_SUCCESS
, "cannot get attributes, res %x\n", res
);
1198 res
= pNtQueryVolumeInformationFile(h
, &io
, &fsi
, sizeof fsi
, FileFsSizeInformation
);
1199 ok(res
== STATUS_SUCCESS
, "cannot get attributes, res %x\n", res
);
1201 /* Test for FileFsSizeInformation */
1202 ok(fsi
.TotalAllocationUnits
.QuadPart
> 0,
1203 "[fsi] TotalAllocationUnits expected positive, got 0x%s\n",
1204 wine_dbgstr_longlong(fsi
.TotalAllocationUnits
.QuadPart
));
1205 ok(fsi
.AvailableAllocationUnits
.QuadPart
> 0,
1206 "[fsi] AvailableAllocationUnits expected positive, got 0x%s\n",
1207 wine_dbgstr_longlong(fsi
.AvailableAllocationUnits
.QuadPart
));
1209 /* Assume file system is NTFS */
1210 ok(fsi
.BytesPerSector
== 512, "[fsi] BytesPerSector expected 512, got %d\n",fsi
.BytesPerSector
);
1211 ok(fsi
.SectorsPerAllocationUnit
== 8, "[fsi] SectorsPerAllocationUnit expected 8, got %d\n",fsi
.SectorsPerAllocationUnit
);
1215 ok(ffsi
.TotalAllocationUnits
.QuadPart
> 0,
1216 "[ffsi] TotalAllocationUnits expected positive, got negative value 0x%s\n",
1217 wine_dbgstr_longlong(ffsi
.TotalAllocationUnits
.QuadPart
));
1218 ok(ffsi
.CallerAvailableAllocationUnits
.QuadPart
> 0,
1219 "[ffsi] CallerAvailableAllocationUnits expected positive, got negative value 0x%s\n",
1220 wine_dbgstr_longlong(ffsi
.CallerAvailableAllocationUnits
.QuadPart
));
1221 ok(ffsi
.ActualAvailableAllocationUnits
.QuadPart
> 0,
1222 "[ffsi] ActualAvailableAllocationUnits expected positive, got negative value 0x%s\n",
1223 wine_dbgstr_longlong(ffsi
.ActualAvailableAllocationUnits
.QuadPart
));
1224 ok(ffsi
.TotalAllocationUnits
.QuadPart
== fsi
.TotalAllocationUnits
.QuadPart
,
1225 "[ffsi] TotalAllocationUnits error fsi:0x%s, ffsi:0x%s\n",
1226 wine_dbgstr_longlong(fsi
.TotalAllocationUnits
.QuadPart
),
1227 wine_dbgstr_longlong(ffsi
.TotalAllocationUnits
.QuadPart
));
1228 ok(ffsi
.CallerAvailableAllocationUnits
.QuadPart
== fsi
.AvailableAllocationUnits
.QuadPart
,
1229 "[ffsi] CallerAvailableAllocationUnits error fsi:0x%s, ffsi: 0x%s\n",
1230 wine_dbgstr_longlong(fsi
.AvailableAllocationUnits
.QuadPart
),
1231 wine_dbgstr_longlong(ffsi
.CallerAvailableAllocationUnits
.QuadPart
));
1234 /* Assume file system is NTFS */
1237 ok(ffsi
.BytesPerSector
== 512, "[ffsi] BytesPerSector expected 512, got %d\n",ffsi
.BytesPerSector
);
1238 ok(ffsi
.SectorsPerAllocationUnit
== 8, "[ffsi] SectorsPerAllocationUnit expected 8, got %d\n",ffsi
.SectorsPerAllocationUnit
);
1244 static void test_file_basic_information(void)
1247 FILE_BASIC_INFORMATION fbi
;
1250 int attrib_mask
= FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_NORMAL
;
1252 if (!(h
= create_temp_file(0))) return;
1254 /* Check default first */
1255 memset(&fbi
, 0, sizeof(fbi
));
1256 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1257 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1258 ok ( (fbi
.FileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) == FILE_ATTRIBUTE_ARCHIVE
,
1259 "attribute %x not expected\n", fbi
.FileAttributes
);
1262 /* Clear fbi to avoid setting times */
1263 memset(&fbi
, 0, sizeof(fbi
));
1264 fbi
.FileAttributes
= FILE_ATTRIBUTE_SYSTEM
;
1265 U(io
).Status
= 0xdeadbeef;
1266 res
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1267 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, NtSetInformationFile returned %x\n", res
);
1268 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status is %x\n", U(io
).Status
);
1270 memset(&fbi
, 0, sizeof(fbi
));
1271 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1272 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1273 todo_wine
ok ( (fbi
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_SYSTEM
, "attribute %x not FILE_ATTRIBUTE_SYSTEM\n", fbi
.FileAttributes
);
1276 memset(&fbi
, 0, sizeof(fbi
));
1277 fbi
.FileAttributes
= FILE_ATTRIBUTE_HIDDEN
;
1278 U(io
).Status
= 0xdeadbeef;
1279 res
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1280 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, NtSetInformationFile returned %x\n", res
);
1281 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status is %x\n", U(io
).Status
);
1283 memset(&fbi
, 0, sizeof(fbi
));
1284 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1285 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1286 todo_wine
ok ( (fbi
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_HIDDEN
, "attribute %x not FILE_ATTRIBUTE_HIDDEN\n", fbi
.FileAttributes
);
1288 /* Check NORMAL last of all (to make sure we can clear attributes) */
1289 memset(&fbi
, 0, sizeof(fbi
));
1290 fbi
.FileAttributes
= FILE_ATTRIBUTE_NORMAL
;
1291 U(io
).Status
= 0xdeadbeef;
1292 res
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1293 ok ( res
== STATUS_SUCCESS
, "can't set normal attribute, NtSetInformationFile returned %x\n", res
);
1294 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set normal attribute, io.Status is %x\n", U(io
).Status
);
1296 memset(&fbi
, 0, sizeof(fbi
));
1297 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1298 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1299 todo_wine
ok ( (fbi
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_NORMAL
, "attribute %x not 0\n", fbi
.FileAttributes
);
1304 static void test_file_all_information(void)
1307 /* FileAllInformation, like FileNameInformation, has a variable-length pathname
1308 * buffer at the end. Vista objects with STATUS_BUFFER_OVERFLOW if you
1309 * don't leave enough room there.
1312 FILE_ALL_INFORMATION fai
;
1317 int attrib_mask
= FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_NORMAL
;
1319 if (!(h
= create_temp_file(0))) return;
1321 /* Check default first */
1322 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1323 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1324 ok ( (fai_buf
.fai
.BasicInformation
.FileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) == FILE_ATTRIBUTE_ARCHIVE
,
1325 "attribute %x not expected\n", fai_buf
.fai
.BasicInformation
.FileAttributes
);
1328 /* Clear fbi to avoid setting times */
1329 memset(&fai_buf
.fai
.BasicInformation
, 0, sizeof(fai_buf
.fai
.BasicInformation
));
1330 fai_buf
.fai
.BasicInformation
.FileAttributes
= FILE_ATTRIBUTE_SYSTEM
;
1331 U(io
).Status
= 0xdeadbeef;
1332 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1333 ok ( res
== STATUS_INVALID_INFO_CLASS
|| broken(res
== STATUS_NOT_IMPLEMENTED
), "shouldn't be able to set FileAllInformation, res %x\n", res
);
1334 todo_wine
ok ( U(io
).Status
== 0xdeadbeef, "shouldn't be able to set FileAllInformation, io.Status is %x\n", U(io
).Status
);
1335 U(io
).Status
= 0xdeadbeef;
1336 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
.BasicInformation
, sizeof fai_buf
.fai
.BasicInformation
, FileBasicInformation
);
1337 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, res: %x\n", res
);
1338 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status: %x\n", U(io
).Status
);
1340 memset(&fai_buf
.fai
, 0, sizeof(fai_buf
.fai
));
1341 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1342 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1343 todo_wine
ok ( (fai_buf
.fai
.BasicInformation
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_SYSTEM
, "attribute %x not FILE_ATTRIBUTE_SYSTEM\n", fai_buf
.fai
.BasicInformation
.FileAttributes
);
1346 memset(&fai_buf
.fai
.BasicInformation
, 0, sizeof(fai_buf
.fai
.BasicInformation
));
1347 fai_buf
.fai
.BasicInformation
.FileAttributes
= FILE_ATTRIBUTE_HIDDEN
;
1348 U(io
).Status
= 0xdeadbeef;
1349 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
.BasicInformation
, sizeof fai_buf
.fai
.BasicInformation
, FileBasicInformation
);
1350 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, res: %x\n", res
);
1351 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status: %x\n", U(io
).Status
);
1353 memset(&fai_buf
.fai
, 0, sizeof(fai_buf
.fai
));
1354 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1355 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1356 todo_wine
ok ( (fai_buf
.fai
.BasicInformation
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_HIDDEN
, "attribute %x not FILE_ATTRIBUTE_HIDDEN\n", fai_buf
.fai
.BasicInformation
.FileAttributes
);
1358 /* Check NORMAL last of all (to make sure we can clear attributes) */
1359 memset(&fai_buf
.fai
.BasicInformation
, 0, sizeof(fai_buf
.fai
.BasicInformation
));
1360 fai_buf
.fai
.BasicInformation
.FileAttributes
= FILE_ATTRIBUTE_NORMAL
;
1361 U(io
).Status
= 0xdeadbeef;
1362 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
.BasicInformation
, sizeof fai_buf
.fai
.BasicInformation
, FileBasicInformation
);
1363 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, res: %x\n", res
);
1364 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status: %x\n", U(io
).Status
);
1366 memset(&fai_buf
.fai
, 0, sizeof(fai_buf
.fai
));
1367 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1368 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1369 todo_wine
ok ( (fai_buf
.fai
.BasicInformation
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_NORMAL
, "attribute %x not FILE_ATTRIBUTE_NORMAL\n", fai_buf
.fai
.BasicInformation
.FileAttributes
);
1374 static void delete_object( WCHAR
*path
)
1376 BOOL ret
= DeleteFileW( path
);
1377 ok( ret
|| GetLastError() == ERROR_FILE_NOT_FOUND
|| GetLastError() == ERROR_ACCESS_DENIED
,
1378 "DeleteFileW failed with %u\n", GetLastError() );
1379 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1381 ret
= RemoveDirectoryW( path
);
1382 ok( ret
, "RemoveDirectoryW failed with %u\n", GetLastError() );
1386 static void test_file_rename_information(void)
1388 static const WCHAR foo_txtW
[] = {'\\','f','o','o','.','t','x','t',0};
1389 static const WCHAR fooW
[] = {'f','o','o',0};
1390 WCHAR tmp_path
[MAX_PATH
], oldpath
[MAX_PATH
+ 16], newpath
[MAX_PATH
+ 16], *filename
, *p
;
1391 FILE_RENAME_INFORMATION
*fri
;
1392 FILE_NAME_INFORMATION
*fni
;
1393 BOOL success
, fileDeleted
;
1394 UNICODE_STRING name_str
;
1395 HANDLE handle
, handle2
;
1399 GetTempPathW( MAX_PATH
, tmp_path
);
1401 /* oldpath is a file, newpath doesn't exist */
1402 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1403 ok( res
!= 0, "failed to create temp file\n" );
1404 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1405 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1407 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1408 ok( res
!= 0, "failed to create temp file\n" );
1409 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1410 DeleteFileW( newpath
);
1411 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1412 fri
->Replace
= FALSE
;
1413 fri
->RootDir
= NULL
;
1414 fri
->FileNameLength
= name_str
.Length
;
1415 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1416 pRtlFreeUnicodeString( &name_str
);
1418 U(io
).Status
= 0xdeadbeef;
1419 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1420 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1421 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1422 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1423 ok( fileDeleted
, "file should not exist\n" );
1424 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1425 ok( !fileDeleted
, "file should exist\n" );
1427 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
1428 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
1429 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1430 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
1431 ok( !lstrcmpiW(fni
->FileName
, newpath
+ 2), "FileName expected %s, got %s\n",
1432 wine_dbgstr_w(newpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
1433 HeapFree( GetProcessHeap(), 0, fni
);
1435 CloseHandle( handle
);
1436 HeapFree( GetProcessHeap(), 0, fri
);
1437 delete_object( oldpath
);
1438 delete_object( newpath
);
1440 /* oldpath is a file, newpath is a file, Replace = FALSE */
1441 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1442 ok( res
!= 0, "failed to create temp file\n" );
1443 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1444 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1446 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1447 ok( res
!= 0, "failed to create temp file\n" );
1448 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1449 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1450 fri
->Replace
= FALSE
;
1451 fri
->RootDir
= NULL
;
1452 fri
->FileNameLength
= name_str
.Length
;
1453 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1454 pRtlFreeUnicodeString( &name_str
);
1456 U(io
).Status
= 0xdeadbeef;
1457 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1458 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1459 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1460 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1461 ok( !fileDeleted
, "file should exist\n" );
1462 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1463 ok( !fileDeleted
, "file should exist\n" );
1465 CloseHandle( handle
);
1466 HeapFree( GetProcessHeap(), 0, fri
);
1467 delete_object( oldpath
);
1468 delete_object( newpath
);
1470 /* oldpath is a file, newpath is a file, Replace = TRUE */
1471 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1472 ok( res
!= 0, "failed to create temp file\n" );
1473 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1474 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1476 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1477 ok( res
!= 0, "failed to create temp file\n" );
1478 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1479 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1480 fri
->Replace
= TRUE
;
1481 fri
->RootDir
= NULL
;
1482 fri
->FileNameLength
= name_str
.Length
;
1483 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1484 pRtlFreeUnicodeString( &name_str
);
1486 U(io
).Status
= 0xdeadbeef;
1487 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1488 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1489 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1490 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1491 ok( fileDeleted
, "file should not exist\n" );
1492 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1493 ok( !fileDeleted
, "file should exist\n" );
1495 CloseHandle( handle
);
1496 HeapFree( GetProcessHeap(), 0, fri
);
1497 delete_object( oldpath
);
1498 delete_object( newpath
);
1500 /* oldpath is a file, newpath is a file, Replace = FALSE, target file opened */
1501 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1502 ok( res
!= 0, "failed to create temp file\n" );
1503 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1504 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1506 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1507 ok( res
!= 0, "failed to create temp file\n" );
1508 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1509 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1511 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1512 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1513 fri
->Replace
= FALSE
;
1514 fri
->RootDir
= NULL
;
1515 fri
->FileNameLength
= name_str
.Length
;
1516 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1517 pRtlFreeUnicodeString( &name_str
);
1519 U(io
).Status
= 0xdeadbeef;
1520 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1521 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1522 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1523 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1524 ok( !fileDeleted
, "file should exist\n" );
1525 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1526 ok( !fileDeleted
, "file should exist\n" );
1528 CloseHandle( handle
);
1529 CloseHandle( handle2
);
1530 HeapFree( GetProcessHeap(), 0, fri
);
1531 delete_object( oldpath
);
1532 delete_object( newpath
);
1534 /* oldpath is a file, newpath is a file, Replace = TRUE, target file opened */
1535 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1536 ok( res
!= 0, "failed to create temp file\n" );
1537 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1538 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1540 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1541 ok( res
!= 0, "failed to create temp file\n" );
1542 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1543 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1545 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1546 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1547 fri
->Replace
= TRUE
;
1548 fri
->RootDir
= NULL
;
1549 fri
->FileNameLength
= name_str
.Length
;
1550 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1551 pRtlFreeUnicodeString( &name_str
);
1553 U(io
).Status
= 0xdeadbeef;
1554 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1555 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1556 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1557 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1558 ok( !fileDeleted
, "file should exist\n" );
1559 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1560 ok( !fileDeleted
, "file should exist\n" );
1562 CloseHandle( handle
);
1563 CloseHandle( handle2
);
1564 HeapFree( GetProcessHeap(), 0, fri
);
1565 delete_object( oldpath
);
1566 delete_object( newpath
);
1568 /* oldpath is a directory, newpath doesn't exist, Replace = FALSE */
1569 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1570 ok( res
!= 0, "failed to create temp file\n" );
1571 DeleteFileW( oldpath
);
1572 success
= CreateDirectoryW( oldpath
, NULL
);
1573 ok( success
!= 0, "failed to create temp directory\n" );
1574 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1575 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1577 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1578 ok( res
!= 0, "failed to create temp file\n" );
1579 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1580 DeleteFileW( newpath
);
1581 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1582 fri
->Replace
= FALSE
;
1583 fri
->RootDir
= NULL
;
1584 fri
->FileNameLength
= name_str
.Length
;
1585 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1586 pRtlFreeUnicodeString( &name_str
);
1588 U(io
).Status
= 0xdeadbeef;
1589 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1590 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1591 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1592 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1593 ok( fileDeleted
, "file should not exist\n" );
1594 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1595 ok( !fileDeleted
, "file should exist\n" );
1597 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
1598 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
1599 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1600 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
1601 ok( !lstrcmpiW(fni
->FileName
, newpath
+ 2), "FileName expected %s, got %s\n",
1602 wine_dbgstr_w(newpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
1603 HeapFree( GetProcessHeap(), 0, fni
);
1605 CloseHandle( handle
);
1606 HeapFree( GetProcessHeap(), 0, fri
);
1607 delete_object( oldpath
);
1608 delete_object( newpath
);
1610 /* oldpath is a directory (but child object opened), newpath doesn't exist, Replace = FALSE */
1611 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1612 ok( res
!= 0, "failed to create temp file\n" );
1613 DeleteFileW( oldpath
);
1614 success
= CreateDirectoryW( oldpath
, NULL
);
1615 ok( success
!= 0, "failed to create temp directory\n" );
1616 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1617 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1619 lstrcpyW( newpath
, oldpath
);
1620 lstrcatW( newpath
, foo_txtW
);
1621 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0 );
1622 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1624 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1625 ok( res
!= 0, "failed to create temp file\n" );
1626 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1627 DeleteFileW( newpath
);
1628 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1629 fri
->Replace
= FALSE
;
1630 fri
->RootDir
= NULL
;
1631 fri
->FileNameLength
= name_str
.Length
;
1632 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1633 pRtlFreeUnicodeString( &name_str
);
1635 U(io
).Status
= 0xdeadbeef;
1636 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1637 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1638 todo_wine
ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1639 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1640 todo_wine
ok( !fileDeleted
, "file should exist\n" );
1641 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1642 todo_wine
ok( fileDeleted
, "file should not exist\n" );
1644 CloseHandle( handle
);
1645 CloseHandle( handle2
);
1646 HeapFree( GetProcessHeap(), 0, fri
);
1647 delete_object( oldpath
);
1648 if (res
== STATUS_SUCCESS
) /* remove when Wine is fixed */
1650 lstrcpyW( oldpath
, newpath
);
1651 lstrcatW( oldpath
, foo_txtW
);
1652 delete_object( oldpath
);
1654 delete_object( newpath
);
1656 /* oldpath is a directory, newpath is a file, Replace = FALSE */
1657 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1658 ok( res
!= 0, "failed to create temp file\n" );
1659 DeleteFileW( oldpath
);
1660 success
= CreateDirectoryW( oldpath
, NULL
);
1661 ok( success
!= 0, "failed to create temp directory\n" );
1662 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1663 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1665 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1666 ok( res
!= 0, "failed to create temp file\n" );
1667 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1668 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1669 fri
->Replace
= FALSE
;
1670 fri
->RootDir
= NULL
;
1671 fri
->FileNameLength
= name_str
.Length
;
1672 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1673 pRtlFreeUnicodeString( &name_str
);
1675 U(io
).Status
= 0xdeadbeef;
1676 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1677 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1678 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1679 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1680 ok( !fileDeleted
, "file should exist\n" );
1681 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1682 ok( !fileDeleted
, "file should exist\n" );
1684 CloseHandle( handle
);
1685 HeapFree( GetProcessHeap(), 0, fri
);
1686 delete_object( oldpath
);
1687 delete_object( newpath
);
1689 /* oldpath is a directory, newpath is a file, Replace = FALSE, target file opened */
1690 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1691 ok( res
!= 0, "failed to create temp file\n" );
1692 DeleteFileW( oldpath
);
1693 success
= CreateDirectoryW( oldpath
, NULL
);
1694 ok( success
!= 0, "failed to create temp directory\n" );
1695 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1696 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1698 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1699 ok( res
!= 0, "failed to create temp file\n" );
1700 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1701 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1703 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1704 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1705 fri
->Replace
= FALSE
;
1706 fri
->RootDir
= 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 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1714 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1715 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1716 ok( !fileDeleted
, "file should exist\n" );
1717 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1718 ok( !fileDeleted
, "file should exist\n" );
1720 CloseHandle( handle
);
1721 CloseHandle( handle2
);
1722 HeapFree( GetProcessHeap(), 0, fri
);
1723 delete_object( oldpath
);
1724 delete_object( newpath
);
1726 /* oldpath is a directory, newpath is a file, Replace = TRUE */
1727 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1728 ok( res
!= 0, "failed to create temp file\n" );
1729 DeleteFileW( oldpath
);
1730 success
= CreateDirectoryW( oldpath
, NULL
);
1731 ok( success
!= 0, "failed to create temp directory\n" );
1732 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1733 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1735 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1736 ok( res
!= 0, "failed to create temp file\n" );
1737 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1738 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1739 fri
->Replace
= TRUE
;
1740 fri
->RootDir
= NULL
;
1741 fri
->FileNameLength
= name_str
.Length
;
1742 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1743 pRtlFreeUnicodeString( &name_str
);
1745 U(io
).Status
= 0xdeadbeef;
1746 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1747 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1748 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1749 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1750 ok( fileDeleted
, "file should not exist\n" );
1751 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1752 ok( !fileDeleted
, "file should exist\n" );
1754 CloseHandle( handle
);
1755 HeapFree( GetProcessHeap(), 0, fri
);
1756 delete_object( oldpath
);
1757 delete_object( newpath
);
1759 /* oldpath is a directory, newpath is a file, Replace = TRUE, target file opened */
1760 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1761 ok( res
!= 0, "failed to create temp file\n" );
1762 DeleteFileW( oldpath
);
1763 success
= CreateDirectoryW( oldpath
, NULL
);
1764 ok( success
!= 0, "failed to create temp directory\n" );
1765 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1766 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1768 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1769 ok( res
!= 0, "failed to create temp file\n" );
1770 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1771 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1773 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1774 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1775 fri
->Replace
= TRUE
;
1776 fri
->RootDir
= NULL
;
1777 fri
->FileNameLength
= name_str
.Length
;
1778 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1779 pRtlFreeUnicodeString( &name_str
);
1781 U(io
).Status
= 0xdeadbeef;
1782 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1783 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1784 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1785 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1786 ok( !fileDeleted
, "file should exist\n" );
1787 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1788 ok( !fileDeleted
, "file should exist\n" );
1790 CloseHandle( handle
);
1791 CloseHandle( handle2
);
1792 HeapFree( GetProcessHeap(), 0, fri
);
1793 delete_object( oldpath
);
1794 delete_object( newpath
);
1796 /* oldpath is a directory, newpath is a directory, Replace = FALSE */
1797 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1798 ok( res
!= 0, "failed to create temp file\n" );
1799 DeleteFileW( oldpath
);
1800 success
= CreateDirectoryW( oldpath
, NULL
);
1801 ok( success
!= 0, "failed to create temp directory\n" );
1802 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1803 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1805 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1806 ok( res
!= 0, "failed to create temp file\n" );
1807 DeleteFileW( newpath
);
1808 success
= CreateDirectoryW( newpath
, NULL
);
1809 ok( success
!= 0, "failed to create temp directory\n" );
1810 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1811 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1812 fri
->Replace
= FALSE
;
1813 fri
->RootDir
= NULL
;
1814 fri
->FileNameLength
= name_str
.Length
;
1815 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1816 pRtlFreeUnicodeString( &name_str
);
1818 U(io
).Status
= 0xdeadbeef;
1819 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1820 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1821 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1822 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1823 ok( !fileDeleted
, "file should exist\n" );
1824 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1825 ok( !fileDeleted
, "file should exist\n" );
1827 CloseHandle( handle
);
1828 HeapFree( GetProcessHeap(), 0, fri
);
1829 delete_object( oldpath
);
1830 delete_object( newpath
);
1832 /* oldpath is a directory, newpath is a directory, Replace = TRUE */
1833 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1834 ok( res
!= 0, "failed to create temp file\n" );
1835 DeleteFileW( oldpath
);
1836 success
= CreateDirectoryW( oldpath
, NULL
);
1837 ok( success
!= 0, "failed to create temp directory\n" );
1838 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1839 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1841 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1842 ok( res
!= 0, "failed to create temp file\n" );
1843 DeleteFileW( newpath
);
1844 success
= CreateDirectoryW( newpath
, NULL
);
1845 ok( success
!= 0, "failed to create temp directory\n" );
1846 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1847 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1848 fri
->Replace
= TRUE
;
1849 fri
->RootDir
= NULL
;
1850 fri
->FileNameLength
= name_str
.Length
;
1851 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1852 pRtlFreeUnicodeString( &name_str
);
1854 U(io
).Status
= 0xdeadbeef;
1855 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1856 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1857 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1858 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1859 ok( !fileDeleted
, "file should exist\n" );
1860 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1861 ok( !fileDeleted
, "file should exist\n" );
1863 CloseHandle( handle
);
1864 HeapFree( GetProcessHeap(), 0, fri
);
1865 delete_object( oldpath
);
1866 delete_object( newpath
);
1868 /* oldpath is a directory, newpath is a directory, Replace = TRUE, target file opened */
1869 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1870 ok( res
!= 0, "failed to create temp file\n" );
1871 DeleteFileW( oldpath
);
1872 success
= CreateDirectoryW( oldpath
, NULL
);
1873 ok( success
!= 0, "failed to create temp directory\n" );
1874 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1875 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1877 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1878 ok( res
!= 0, "failed to create temp file\n" );
1879 DeleteFileW( newpath
);
1880 success
= CreateDirectoryW( newpath
, NULL
);
1881 ok( success
!= 0, "failed to create temp directory\n" );
1882 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1883 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1885 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1886 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1887 fri
->Replace
= TRUE
;
1888 fri
->RootDir
= NULL
;
1889 fri
->FileNameLength
= name_str
.Length
;
1890 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1891 pRtlFreeUnicodeString( &name_str
);
1893 U(io
).Status
= 0xdeadbeef;
1894 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1895 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1896 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1897 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1898 ok( !fileDeleted
, "file should exist\n" );
1899 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1900 ok( !fileDeleted
, "file should exist\n" );
1902 CloseHandle( handle
);
1903 CloseHandle( handle2
);
1904 HeapFree( GetProcessHeap(), 0, fri
);
1905 delete_object( oldpath
);
1906 delete_object( newpath
);
1908 /* oldpath is a file, newpath is a directory, Replace = FALSE */
1909 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1910 ok( res
!= 0, "failed to create temp file\n" );
1911 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1912 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1914 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1915 ok( res
!= 0, "failed to create temp file\n" );
1916 DeleteFileW( newpath
);
1917 success
= CreateDirectoryW( newpath
, NULL
);
1918 ok( success
!= 0, "failed to create temp directory\n" );
1919 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1920 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1921 fri
->Replace
= FALSE
;
1922 fri
->RootDir
= NULL
;
1923 fri
->FileNameLength
= name_str
.Length
;
1924 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1925 pRtlFreeUnicodeString( &name_str
);
1927 U(io
).Status
= 0xdeadbeef;
1928 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1929 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1930 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1931 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1932 ok( !fileDeleted
, "file should exist\n" );
1933 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1934 ok( !fileDeleted
, "file should exist\n" );
1936 CloseHandle( handle
);
1937 HeapFree( GetProcessHeap(), 0, fri
);
1938 delete_object( oldpath
);
1939 delete_object( newpath
);
1941 /* oldpath is a file, newpath is a directory, Replace = TRUE */
1942 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1943 ok( res
!= 0, "failed to create temp file\n" );
1944 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1945 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1947 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1948 ok( res
!= 0, "failed to create temp file\n" );
1949 DeleteFileW( newpath
);
1950 success
= CreateDirectoryW( newpath
, NULL
);
1951 ok( success
!= 0, "failed to create temp directory\n" );
1952 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1953 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1954 fri
->Replace
= TRUE
;
1955 fri
->RootDir
= NULL
;
1956 fri
->FileNameLength
= name_str
.Length
;
1957 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1958 pRtlFreeUnicodeString( &name_str
);
1960 U(io
).Status
= 0xdeadbeef;
1961 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1962 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1963 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1964 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1965 ok( !fileDeleted
, "file should exist\n" );
1966 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1967 ok( !fileDeleted
, "file should exist\n" );
1969 CloseHandle( handle
);
1970 HeapFree( GetProcessHeap(), 0, fri
);
1971 delete_object( oldpath
);
1972 delete_object( newpath
);
1974 /* oldpath is a file, newpath doesn't exist, test with RootDir != NULL */
1975 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1976 ok( res
!= 0, "failed to create temp file\n" );
1977 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1978 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1980 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1981 ok( res
!= 0, "failed to create temp file\n" );
1982 DeleteFileW( newpath
);
1983 for (filename
= newpath
, p
= newpath
; *p
; p
++)
1984 if (*p
== '\\') filename
= p
+ 1;
1985 handle2
= CreateFileW( tmp_path
, 0, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1986 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1988 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + lstrlenW(filename
) * sizeof(WCHAR
) );
1989 fri
->Replace
= FALSE
;
1990 fri
->RootDir
= handle2
;
1991 fri
->FileNameLength
= lstrlenW(filename
) * sizeof(WCHAR
);
1992 memcpy( fri
->FileName
, filename
, fri
->FileNameLength
);
1994 U(io
).Status
= 0xdeadbeef;
1995 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1996 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1997 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1998 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1999 ok( fileDeleted
, "file should not exist\n" );
2000 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2001 ok( !fileDeleted
, "file should exist\n" );
2003 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2004 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2005 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2006 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2007 todo_wine
ok( !lstrcmpiW(fni
->FileName
, newpath
+ 2), "FileName expected %s, got %s\n",
2008 wine_dbgstr_w(newpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2009 HeapFree( GetProcessHeap(), 0, fni
);
2011 CloseHandle( handle
);
2012 CloseHandle( handle2
);
2013 HeapFree( GetProcessHeap(), 0, fri
);
2014 delete_object( oldpath
);
2015 delete_object( newpath
);
2018 static void test_file_link_information(void)
2020 static const WCHAR foo_txtW
[] = {'\\','f','o','o','.','t','x','t',0};
2021 static const WCHAR fooW
[] = {'f','o','o',0};
2022 WCHAR tmp_path
[MAX_PATH
], oldpath
[MAX_PATH
+ 16], newpath
[MAX_PATH
+ 16], *filename
, *p
;
2023 FILE_LINK_INFORMATION
*fli
;
2024 FILE_NAME_INFORMATION
*fni
;
2025 BOOL success
, fileDeleted
;
2026 UNICODE_STRING name_str
;
2027 HANDLE handle
, handle2
;
2031 GetTempPathW( MAX_PATH
, tmp_path
);
2033 /* oldpath is a file, newpath doesn't exist */
2034 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2035 ok( res
!= 0, "failed to create temp file\n" );
2036 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2037 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2039 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2040 ok( res
!= 0, "failed to create temp file\n" );
2041 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2042 DeleteFileW( newpath
);
2043 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2044 fli
->ReplaceIfExists
= FALSE
;
2045 fli
->RootDirectory
= NULL
;
2046 fli
->FileNameLength
= name_str
.Length
;
2047 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2048 pRtlFreeUnicodeString( &name_str
);
2050 U(io
).Status
= 0xdeadbeef;
2051 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2052 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
2053 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\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 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2060 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2061 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2062 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2063 ok( !lstrcmpiW(fni
->FileName
, oldpath
+ 2), "FileName expected %s, got %s\n",
2064 wine_dbgstr_w(oldpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2065 HeapFree( GetProcessHeap(), 0, fni
);
2067 CloseHandle( handle
);
2068 HeapFree( GetProcessHeap(), 0, fli
);
2069 delete_object( oldpath
);
2070 delete_object( newpath
);
2072 /* oldpath is a file, newpath is a file, ReplaceIfExists = FALSE */
2073 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2074 ok( res
!= 0, "failed to create temp file\n" );
2075 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2076 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2078 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2079 ok( res
!= 0, "failed to create temp file\n" );
2080 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2081 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2082 fli
->ReplaceIfExists
= FALSE
;
2083 fli
->RootDirectory
= NULL
;
2084 fli
->FileNameLength
= name_str
.Length
;
2085 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2086 pRtlFreeUnicodeString( &name_str
);
2088 U(io
).Status
= 0xdeadbeef;
2089 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2090 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2091 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
2092 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2093 ok( !fileDeleted
, "file should exist\n" );
2094 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2095 ok( !fileDeleted
, "file should exist\n" );
2097 CloseHandle( handle
);
2098 HeapFree( GetProcessHeap(), 0, fli
);
2099 delete_object( oldpath
);
2100 delete_object( newpath
);
2102 /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE */
2103 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2104 ok( res
!= 0, "failed to create temp file\n" );
2105 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2106 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2108 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2109 ok( res
!= 0, "failed to create temp file\n" );
2110 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2111 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2112 fli
->ReplaceIfExists
= TRUE
;
2113 fli
->RootDirectory
= NULL
;
2114 fli
->FileNameLength
= name_str
.Length
;
2115 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2116 pRtlFreeUnicodeString( &name_str
);
2118 U(io
).Status
= 0xdeadbeef;
2119 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2120 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
2121 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2122 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2123 ok( !fileDeleted
, "file should exist\n" );
2124 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2125 ok( !fileDeleted
, "file should exist\n" );
2127 CloseHandle( handle
);
2128 HeapFree( GetProcessHeap(), 0, fli
);
2129 delete_object( oldpath
);
2130 delete_object( newpath
);
2132 /* oldpath is a file, newpath is a file, ReplaceIfExists = FALSE, target file opened */
2133 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2134 ok( res
!= 0, "failed to create temp file\n" );
2135 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2136 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2138 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2139 ok( res
!= 0, "failed to create temp file\n" );
2140 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2141 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2143 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2144 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2145 fli
->ReplaceIfExists
= FALSE
;
2146 fli
->RootDirectory
= NULL
;
2147 fli
->FileNameLength
= name_str
.Length
;
2148 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2149 pRtlFreeUnicodeString( &name_str
);
2151 U(io
).Status
= 0xdeadbeef;
2152 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2153 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2154 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
2155 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2156 ok( !fileDeleted
, "file should exist\n" );
2157 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2158 ok( !fileDeleted
, "file should exist\n" );
2160 CloseHandle( handle
);
2161 CloseHandle( handle2
);
2162 HeapFree( GetProcessHeap(), 0, fli
);
2163 delete_object( oldpath
);
2164 delete_object( newpath
);
2166 /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE, target file opened */
2167 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2168 ok( res
!= 0, "failed to create temp file\n" );
2169 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2170 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2172 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2173 ok( res
!= 0, "failed to create temp file\n" );
2174 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2175 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2177 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2178 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2179 fli
->ReplaceIfExists
= TRUE
;
2180 fli
->RootDirectory
= NULL
;
2181 fli
->FileNameLength
= name_str
.Length
;
2182 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2183 pRtlFreeUnicodeString( &name_str
);
2185 U(io
).Status
= 0xdeadbeef;
2186 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2187 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2188 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
2189 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2190 ok( !fileDeleted
, "file should exist\n" );
2191 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2192 ok( !fileDeleted
, "file should exist\n" );
2194 CloseHandle( handle
);
2195 CloseHandle( handle2
);
2196 HeapFree( GetProcessHeap(), 0, fli
);
2197 delete_object( oldpath
);
2198 delete_object( newpath
);
2200 /* oldpath is a directory, newpath doesn't exist, ReplaceIfExists = FALSE */
2201 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2202 ok( res
!= 0, "failed to create temp file\n" );
2203 DeleteFileW( oldpath
);
2204 success
= CreateDirectoryW( oldpath
, NULL
);
2205 ok( success
!= 0, "failed to create temp directory\n" );
2206 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2207 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2209 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2210 ok( res
!= 0, "failed to create temp file\n" );
2211 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2212 DeleteFileW( newpath
);
2213 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2214 fli
->ReplaceIfExists
= FALSE
;
2215 fli
->RootDirectory
= NULL
;
2216 fli
->FileNameLength
= name_str
.Length
;
2217 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2218 pRtlFreeUnicodeString( &name_str
);
2220 U(io
).Status
= 0xdeadbeef;
2221 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2222 todo_wine
ok( U(io
).Status
== 0xdeadbeef , "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2223 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2224 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2225 ok( !fileDeleted
, "file should exist\n" );
2226 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2227 ok( fileDeleted
, "file should not exist\n" );
2229 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2230 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2231 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2232 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2233 ok( !lstrcmpiW(fni
->FileName
, oldpath
+ 2), "FileName expected %s, got %s\n",
2234 wine_dbgstr_w(oldpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2235 HeapFree( GetProcessHeap(), 0, fni
);
2237 CloseHandle( handle
);
2238 HeapFree( GetProcessHeap(), 0, fli
);
2239 delete_object( oldpath
);
2240 delete_object( newpath
);
2242 /* oldpath is a directory (but child object opened), newpath doesn't exist, ReplaceIfExists = FALSE */
2243 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2244 ok( res
!= 0, "failed to create temp file\n" );
2245 DeleteFileW( oldpath
);
2246 success
= CreateDirectoryW( oldpath
, NULL
);
2247 ok( success
!= 0, "failed to create temp directory\n" );
2248 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2249 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2251 lstrcpyW( newpath
, oldpath
);
2252 lstrcatW( newpath
, foo_txtW
);
2253 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0 );
2254 ok( handle2
!= 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 DeleteFileW( newpath
);
2260 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2261 fli
->ReplaceIfExists
= FALSE
;
2262 fli
->RootDirectory
= NULL
;
2263 fli
->FileNameLength
= name_str
.Length
;
2264 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2265 pRtlFreeUnicodeString( &name_str
);
2267 U(io
).Status
= 0xdeadbeef;
2268 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2269 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2270 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2271 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2272 ok( !fileDeleted
, "file should exist\n" );
2273 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2274 ok( fileDeleted
, "file should not exist\n" );
2276 CloseHandle( handle
);
2277 CloseHandle( handle2
);
2278 HeapFree( GetProcessHeap(), 0, fli
);
2279 delete_object( oldpath
);
2280 delete_object( newpath
);
2282 /* oldpath is a directory, newpath is a file, ReplaceIfExists = FALSE */
2283 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2284 ok( res
!= 0, "failed to create temp file\n" );
2285 DeleteFileW( oldpath
);
2286 success
= CreateDirectoryW( oldpath
, NULL
);
2287 ok( success
!= 0, "failed to create temp directory\n" );
2288 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2289 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2291 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2292 ok( res
!= 0, "failed to create temp file\n" );
2293 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2294 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2295 fli
->ReplaceIfExists
= FALSE
;
2296 fli
->RootDirectory
= NULL
;
2297 fli
->FileNameLength
= name_str
.Length
;
2298 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2299 pRtlFreeUnicodeString( &name_str
);
2301 U(io
).Status
= 0xdeadbeef;
2302 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2303 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2304 ok( res
== STATUS_OBJECT_NAME_COLLISION
|| res
== STATUS_FILE_IS_A_DIRECTORY
/* > Win XP */,
2305 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2306 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2307 ok( !fileDeleted
, "file should exist\n" );
2308 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2309 ok( !fileDeleted
, "file should exist\n" );
2311 CloseHandle( handle
);
2312 HeapFree( GetProcessHeap(), 0, fli
);
2313 delete_object( oldpath
);
2314 delete_object( newpath
);
2316 /* oldpath is a directory, newpath is a file, ReplaceIfExists = FALSE, target file opened */
2317 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2318 ok( res
!= 0, "failed to create temp file\n" );
2319 DeleteFileW( oldpath
);
2320 success
= CreateDirectoryW( oldpath
, NULL
);
2321 ok( success
!= 0, "failed to create temp directory\n" );
2322 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2323 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2325 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2326 ok( res
!= 0, "failed to create temp file\n" );
2327 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2328 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2330 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2331 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2332 fli
->ReplaceIfExists
= FALSE
;
2333 fli
->RootDirectory
= NULL
;
2334 fli
->FileNameLength
= name_str
.Length
;
2335 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2336 pRtlFreeUnicodeString( &name_str
);
2338 U(io
).Status
= 0xdeadbeef;
2339 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2340 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2341 ok( res
== STATUS_OBJECT_NAME_COLLISION
|| res
== STATUS_FILE_IS_A_DIRECTORY
/* > Win XP */,
2342 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\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 directory, newpath is a file, ReplaceIfExists = TRUE */
2355 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2356 ok( res
!= 0, "failed to create temp file\n" );
2357 DeleteFileW( oldpath
);
2358 success
= CreateDirectoryW( oldpath
, NULL
);
2359 ok( success
!= 0, "failed to create temp directory\n" );
2360 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2361 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2363 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2364 ok( res
!= 0, "failed to create temp file\n" );
2365 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2366 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 %x\n", U(io
).Status
);
2376 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\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 HeapFree( GetProcessHeap(), 0, fli
);
2384 delete_object( oldpath
);
2385 delete_object( newpath
);
2387 /* oldpath is a directory, newpath is a file, ReplaceIfExists = TRUE, target file opened */
2388 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2389 ok( res
!= 0, "failed to create temp file\n" );
2390 DeleteFileW( oldpath
);
2391 success
= CreateDirectoryW( oldpath
, NULL
);
2392 ok( success
!= 0, "failed to create temp directory\n" );
2393 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2394 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2396 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2397 ok( res
!= 0, "failed to create temp file\n" );
2398 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2399 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2401 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2402 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2403 fli
->ReplaceIfExists
= TRUE
;
2404 fli
->RootDirectory
= NULL
;
2405 fli
->FileNameLength
= name_str
.Length
;
2406 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2407 pRtlFreeUnicodeString( &name_str
);
2409 U(io
).Status
= 0xdeadbeef;
2410 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2411 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2412 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2413 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2414 ok( !fileDeleted
, "file should exist\n" );
2415 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2416 ok( !fileDeleted
, "file should exist\n" );
2418 CloseHandle( handle
);
2419 CloseHandle( handle2
);
2420 HeapFree( GetProcessHeap(), 0, fli
);
2421 delete_object( oldpath
);
2422 delete_object( newpath
);
2424 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = FALSE */
2425 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2426 ok( res
!= 0, "failed to create temp file\n" );
2427 DeleteFileW( oldpath
);
2428 success
= CreateDirectoryW( oldpath
, NULL
);
2429 ok( success
!= 0, "failed to create temp directory\n" );
2430 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2431 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2433 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2434 ok( res
!= 0, "failed to create temp file\n" );
2435 DeleteFileW( newpath
);
2436 success
= CreateDirectoryW( newpath
, NULL
);
2437 ok( success
!= 0, "failed to create temp directory\n" );
2438 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2439 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2440 fli
->ReplaceIfExists
= FALSE
;
2441 fli
->RootDirectory
= NULL
;
2442 fli
->FileNameLength
= name_str
.Length
;
2443 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2444 pRtlFreeUnicodeString( &name_str
);
2446 U(io
).Status
= 0xdeadbeef;
2447 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2448 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2449 ok( res
== STATUS_OBJECT_NAME_COLLISION
|| res
== STATUS_FILE_IS_A_DIRECTORY
/* > Win XP */,
2450 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2451 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2452 ok( !fileDeleted
, "file should exist\n" );
2453 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2454 ok( !fileDeleted
, "file should exist\n" );
2456 CloseHandle( handle
);
2457 HeapFree( GetProcessHeap(), 0, fli
);
2458 delete_object( oldpath
);
2459 delete_object( newpath
);
2461 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = TRUE */
2462 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2463 ok( res
!= 0, "failed to create temp file\n" );
2464 DeleteFileW( oldpath
);
2465 success
= CreateDirectoryW( oldpath
, NULL
);
2466 ok( success
!= 0, "failed to create temp directory\n" );
2467 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2468 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2470 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2471 ok( res
!= 0, "failed to create temp file\n" );
2472 DeleteFileW( newpath
);
2473 success
= CreateDirectoryW( newpath
, NULL
);
2474 ok( success
!= 0, "failed to create temp directory\n" );
2475 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2476 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2477 fli
->ReplaceIfExists
= TRUE
;
2478 fli
->RootDirectory
= NULL
;
2479 fli
->FileNameLength
= name_str
.Length
;
2480 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2481 pRtlFreeUnicodeString( &name_str
);
2483 U(io
).Status
= 0xdeadbeef;
2484 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2485 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2486 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2487 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2488 ok( !fileDeleted
, "file should exist\n" );
2489 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2490 ok( !fileDeleted
, "file should exist\n" );
2492 CloseHandle( handle
);
2493 HeapFree( GetProcessHeap(), 0, fli
);
2494 delete_object( oldpath
);
2495 delete_object( newpath
);
2497 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = TRUE, target file opened */
2498 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2499 ok( res
!= 0, "failed to create temp file\n" );
2500 DeleteFileW( oldpath
);
2501 success
= CreateDirectoryW( oldpath
, NULL
);
2502 ok( success
!= 0, "failed to create temp directory\n" );
2503 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2504 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2506 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2507 ok( res
!= 0, "failed to create temp file\n" );
2508 DeleteFileW( newpath
);
2509 success
= CreateDirectoryW( newpath
, NULL
);
2510 ok( success
!= 0, "failed to create temp directory\n" );
2511 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2512 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2514 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2515 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2516 fli
->ReplaceIfExists
= TRUE
;
2517 fli
->RootDirectory
= NULL
;
2518 fli
->FileNameLength
= name_str
.Length
;
2519 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2520 pRtlFreeUnicodeString( &name_str
);
2522 U(io
).Status
= 0xdeadbeef;
2523 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2524 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2525 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2526 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2527 ok( !fileDeleted
, "file should exist\n" );
2528 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2529 ok( !fileDeleted
, "file should exist\n" );
2531 CloseHandle( handle
);
2532 CloseHandle( handle2
);
2533 HeapFree( GetProcessHeap(), 0, fli
);
2534 delete_object( oldpath
);
2535 delete_object( newpath
);
2537 /* oldpath is a file, newpath is a directory, ReplaceIfExists = FALSE */
2538 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2539 ok( res
!= 0, "failed to create temp file\n" );
2540 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2541 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2543 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2544 ok( res
!= 0, "failed to create temp file\n" );
2545 DeleteFileW( newpath
);
2546 success
= CreateDirectoryW( newpath
, NULL
);
2547 ok( success
!= 0, "failed to create temp directory\n" );
2548 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2549 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2550 fli
->ReplaceIfExists
= FALSE
;
2551 fli
->RootDirectory
= NULL
;
2552 fli
->FileNameLength
= name_str
.Length
;
2553 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2554 pRtlFreeUnicodeString( &name_str
);
2556 U(io
).Status
= 0xdeadbeef;
2557 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2558 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2559 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
2560 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2561 ok( !fileDeleted
, "file should exist\n" );
2562 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2563 ok( !fileDeleted
, "file should exist\n" );
2565 CloseHandle( handle
);
2566 HeapFree( GetProcessHeap(), 0, fli
);
2567 delete_object( oldpath
);
2568 delete_object( newpath
);
2570 /* oldpath is a file, newpath is a directory, ReplaceIfExists = TRUE */
2571 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2572 ok( res
!= 0, "failed to create temp file\n" );
2573 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2574 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2576 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2577 ok( res
!= 0, "failed to create temp file\n" );
2578 DeleteFileW( newpath
);
2579 success
= CreateDirectoryW( newpath
, NULL
);
2580 ok( success
!= 0, "failed to create temp directory\n" );
2581 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2582 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2583 fli
->ReplaceIfExists
= TRUE
;
2584 fli
->RootDirectory
= NULL
;
2585 fli
->FileNameLength
= name_str
.Length
;
2586 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2587 pRtlFreeUnicodeString( &name_str
);
2589 U(io
).Status
= 0xdeadbeef;
2590 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2591 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2592 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
2593 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2594 ok( !fileDeleted
, "file should exist\n" );
2595 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2596 ok( !fileDeleted
, "file should exist\n" );
2598 CloseHandle( handle
);
2599 HeapFree( GetProcessHeap(), 0, fli
);
2600 delete_object( oldpath
);
2601 delete_object( newpath
);
2603 /* oldpath is a file, newpath doesn't exist, test with RootDirectory != NULL */
2604 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2605 ok( res
!= 0, "failed to create temp file\n" );
2606 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2607 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2609 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2610 ok( res
!= 0, "failed to create temp file\n" );
2611 DeleteFileW( newpath
);
2612 for (filename
= newpath
, p
= newpath
; *p
; p
++)
2613 if (*p
== '\\') filename
= p
+ 1;
2614 handle2
= CreateFileW( tmp_path
, 0, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2615 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2617 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + lstrlenW(filename
) * sizeof(WCHAR
) );
2618 fli
->ReplaceIfExists
= FALSE
;
2619 fli
->RootDirectory
= handle2
;
2620 fli
->FileNameLength
= lstrlenW(filename
) * sizeof(WCHAR
);
2621 memcpy( fli
->FileName
, filename
, fli
->FileNameLength
);
2623 U(io
).Status
= 0xdeadbeef;
2624 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2625 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
2626 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2627 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2628 ok( !fileDeleted
, "file should exist\n" );
2629 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2630 ok( !fileDeleted
, "file should exist\n" );
2632 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2633 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2634 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2635 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2636 ok( !lstrcmpiW(fni
->FileName
, oldpath
+ 2), "FileName expected %s, got %s\n",
2637 wine_dbgstr_w(oldpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2638 HeapFree( GetProcessHeap(), 0, fni
);
2640 CloseHandle( handle
);
2641 CloseHandle( handle2
);
2642 HeapFree( GetProcessHeap(), 0, fli
);
2643 delete_object( oldpath
);
2644 delete_object( newpath
);
2647 static void test_file_both_information(void)
2650 FILE_BOTH_DIR_INFORMATION fbi
;
2654 if (!(h
= create_temp_file(0))) return;
2656 memset(&fbi
, 0, sizeof(fbi
));
2657 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBothDirectoryInformation
);
2658 ok ( res
== STATUS_INVALID_INFO_CLASS
|| res
== STATUS_NOT_IMPLEMENTED
, "shouldn't be able to query FileBothDirectoryInformation, res %x\n", res
);
2663 static NTSTATUS
nt_get_file_attrs(const char *name
, DWORD
*attrs
)
2665 WCHAR nameW
[MAX_PATH
];
2666 FILE_BASIC_INFORMATION info
;
2667 UNICODE_STRING nt_name
;
2668 OBJECT_ATTRIBUTES attr
;
2671 MultiByteToWideChar( CP_ACP
, 0, name
, -1, nameW
, MAX_PATH
);
2673 *attrs
= INVALID_FILE_ATTRIBUTES
;
2675 if (!pRtlDosPathNameToNtPathName_U( nameW
, &nt_name
, NULL
, NULL
))
2676 return STATUS_UNSUCCESSFUL
;
2678 attr
.Length
= sizeof(attr
);
2679 attr
.RootDirectory
= 0;
2680 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
2681 attr
.ObjectName
= &nt_name
;
2682 attr
.SecurityDescriptor
= NULL
;
2683 attr
.SecurityQualityOfService
= NULL
;
2685 status
= pNtQueryAttributesFile( &attr
, &info
);
2686 pRtlFreeUnicodeString( &nt_name
);
2688 if (status
== STATUS_SUCCESS
)
2689 *attrs
= info
.FileAttributes
;
2694 static void test_file_disposition_information(void)
2696 char tmp_path
[MAX_PATH
], buffer
[MAX_PATH
+ 16];
2698 HANDLE handle
, handle2
, handle3
;
2701 FILE_DISPOSITION_INFORMATION fdi
;
2705 GetTempPathA( MAX_PATH
, tmp_path
);
2707 /* tests for info struct size */
2708 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2709 handle
= CreateFileA( buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2710 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2711 res
= pNtSetInformationFile( handle
, &io
, &fdi
, 0, FileDispositionInformation
);
2713 ok( res
== STATUS_INFO_LENGTH_MISMATCH
, "expected STATUS_INFO_LENGTH_MISMATCH, got %x\n", res
);
2715 res
= pNtSetInformationFile( handle
, &io
, &fdi2
, sizeof(fdi2
), FileDispositionInformation
);
2716 ok( res
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %x\n", res
);
2717 CloseHandle( handle
);
2718 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2719 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2720 DeleteFileA( buffer
);
2722 /* cannot set disposition on file not opened with delete access */
2723 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2724 handle
= CreateFileA(buffer
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2725 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2726 res
= pNtQueryInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2727 ok( res
== STATUS_INVALID_INFO_CLASS
|| res
== STATUS_NOT_IMPLEMENTED
, "Unexpected NtQueryInformationFile result (expected STATUS_INVALID_INFO_CLASS, got %x)\n", res
);
2728 fdi
.DoDeleteFile
= TRUE
;
2729 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2730 ok( res
== STATUS_ACCESS_DENIED
, "unexpected FileDispositionInformation result (expected STATUS_ACCESS_DENIED, got %x)\n", res
);
2731 CloseHandle( handle
);
2732 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2733 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2734 DeleteFileA( buffer
);
2736 /* can set disposition on file opened with proper access */
2737 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2738 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2739 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2740 fdi
.DoDeleteFile
= TRUE
;
2741 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2742 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2743 CloseHandle( handle
);
2744 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2745 ok( fileDeleted
, "File should have been deleted\n" );
2747 /* file exists until all handles to it get closed */
2748 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2749 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, FILE_SHARE_DELETE
, NULL
, CREATE_ALWAYS
, 0, 0);
2750 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2751 handle2
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0);
2752 ok( handle2
!= INVALID_HANDLE_VALUE
, "failed to open temp file\n" );
2753 fdi
.DoDeleteFile
= TRUE
;
2754 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2755 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2756 res
= nt_get_file_attrs( buffer
, &fdi2
);
2758 ok( res
== STATUS_DELETE_PENDING
, "got %#x\n", res
);
2759 /* can't open the deleted file */
2760 handle3
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0);
2762 ok( handle3
== INVALID_HANDLE_VALUE
, "CreateFile should fail\n" );
2763 if (handle3
!= INVALID_HANDLE_VALUE
)
2764 CloseHandle( handle3
);
2766 ok(GetLastError() == ERROR_ACCESS_DENIED
, "got %u\n", GetLastError());
2767 /* can't open the deleted file (wrong sharing mode) */
2768 handle3
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
2769 ok( handle3
== INVALID_HANDLE_VALUE
, "CreateFile should fail\n" );
2771 ok(GetLastError() == ERROR_ACCESS_DENIED
, "got %u\n", GetLastError());
2772 CloseHandle( handle
);
2773 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2774 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2775 CloseHandle( handle2
);
2776 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2777 ok( fileDeleted
, "File should have been deleted\n" );
2779 /* file exists until all handles to it get closed */
2780 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2781 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, FILE_SHARE_DELETE
, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0);
2782 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2783 /* can open the marked for delete file (proper sharing mode) */
2784 handle2
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0);
2785 ok( handle2
!= INVALID_HANDLE_VALUE
, "failed to open temp file\n" );
2786 res
= nt_get_file_attrs( buffer
, &fdi2
);
2787 ok( res
== STATUS_SUCCESS
, "got %#x\n", res
);
2788 /* can't open the marked for delete file (wrong sharing mode) */
2789 handle3
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
2790 ok( handle3
== INVALID_HANDLE_VALUE
, "CreateFile should fail\n" );
2791 ok(GetLastError() == ERROR_SHARING_VIOLATION
, "got %u\n", GetLastError());
2792 CloseHandle( handle
);
2793 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2794 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2795 CloseHandle( handle2
);
2796 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2797 ok( fileDeleted
, "File should have been deleted\n" );
2799 /* cannot set disposition on readonly file */
2800 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2801 DeleteFileA( buffer
);
2802 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_READONLY
, 0);
2803 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2804 fdi
.DoDeleteFile
= TRUE
;
2805 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2806 ok( res
== STATUS_CANNOT_DELETE
, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res
);
2807 CloseHandle( handle
);
2808 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2809 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2810 SetFileAttributesA( buffer
, FILE_ATTRIBUTE_NORMAL
);
2811 DeleteFileA( buffer
);
2813 /* cannot set disposition on readonly file */
2814 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2815 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_READONLY
, 0);
2816 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2817 fdi
.DoDeleteFile
= TRUE
;
2818 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2820 ok( res
== STATUS_CANNOT_DELETE
, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res
);
2821 CloseHandle( handle
);
2822 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2824 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2825 SetFileAttributesA( buffer
, FILE_ATTRIBUTE_NORMAL
);
2826 DeleteFileA( buffer
);
2828 /* can set disposition on file and then reset it */
2829 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2830 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2831 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2832 fdi
.DoDeleteFile
= TRUE
;
2833 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2834 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2835 fdi
.DoDeleteFile
= FALSE
;
2836 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2837 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2838 CloseHandle( handle
);
2839 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2840 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2841 DeleteFileA( buffer
);
2843 /* can't reset disposition if delete-on-close flag is specified */
2844 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2845 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0);
2846 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2847 fdi
.DoDeleteFile
= FALSE
;
2848 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2849 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2850 CloseHandle( handle
);
2851 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2852 ok( fileDeleted
, "File should have been deleted\n" );
2854 /* can't reset disposition on duplicated handle if delete-on-close flag is specified */
2855 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2856 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0);
2857 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2858 ok( DuplicateHandle( GetCurrentProcess(), handle
, GetCurrentProcess(), &handle2
, 0, FALSE
, DUPLICATE_SAME_ACCESS
), "DuplicateHandle failed\n" );
2859 CloseHandle( handle
);
2860 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2861 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2862 fdi
.DoDeleteFile
= FALSE
;
2863 res
= pNtSetInformationFile( handle2
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2864 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2865 CloseHandle( handle2
);
2866 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2867 ok( fileDeleted
, "File should have been deleted\n" );
2869 /* DeleteFile fails for wrong sharing mode */
2870 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2871 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2872 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2873 fileDeleted
= DeleteFileA( buffer
);
2874 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2875 ok(GetLastError() == ERROR_SHARING_VIOLATION
, "got %u\n", GetLastError());
2876 CloseHandle( handle
);
2877 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2878 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2879 DeleteFileA( buffer
);
2881 /* DeleteFile succeeds for proper sharing mode */
2882 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2883 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, FILE_SHARE_DELETE
, NULL
, CREATE_ALWAYS
, 0, 0);
2884 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2885 fileDeleted
= DeleteFileA( buffer
);
2886 ok( fileDeleted
, "File should have been deleted\n" );
2887 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2888 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2889 res
= nt_get_file_attrs( buffer
, &fdi2
);
2891 ok( res
== STATUS_DELETE_PENDING
, "got %#x\n", res
);
2892 /* can't open the deleted file */
2893 handle2
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
, NULL
, OPEN_EXISTING
, 0, 0);
2894 ok( handle2
== INVALID_HANDLE_VALUE
, "CreateFile should fail\n" );
2896 ok(GetLastError() == ERROR_ACCESS_DENIED
, "got %u\n", GetLastError());
2897 CloseHandle( handle
);
2898 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2899 ok( fileDeleted
, "File should have been deleted\n" );
2901 /* can set disposition on a directory opened with proper access */
2902 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2903 DeleteFileA( buffer
);
2904 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
2905 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2906 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
2907 fdi
.DoDeleteFile
= TRUE
;
2908 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2909 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2910 CloseHandle( handle
);
2911 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2912 ok( fileDeleted
, "Directory should have been deleted\n" );
2914 /* RemoveDirectory fails for wrong sharing mode */
2915 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2916 DeleteFileA( buffer
);
2917 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
2918 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2919 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
2920 fileDeleted
= RemoveDirectoryA( buffer
);
2921 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
2922 ok(GetLastError() == ERROR_SHARING_VIOLATION
, "got %u\n", GetLastError());
2923 CloseHandle( handle
);
2924 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2925 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
2926 RemoveDirectoryA( buffer
);
2928 /* RemoveDirectory succeeds for proper sharing mode */
2929 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2930 DeleteFileA( buffer
);
2931 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
2932 handle
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2933 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
2934 fileDeleted
= RemoveDirectoryA( buffer
);
2935 ok( fileDeleted
, "Directory should have been deleted\n" );
2936 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2938 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
2939 res
= nt_get_file_attrs( buffer
, &fdi2
);
2941 ok( res
== STATUS_DELETE_PENDING
, "got %#x\n", res
);
2942 /* can't open the deleted directory */
2943 handle2
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2944 ok( handle2
== INVALID_HANDLE_VALUE
, "CreateFile should fail\n" );
2946 ok(GetLastError() == ERROR_ACCESS_DENIED
, "got %u\n", GetLastError());
2947 CloseHandle( handle
);
2948 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2949 ok( fileDeleted
, "Directory should have been deleted\n" );
2951 /* directory exists until all handles to it get closed */
2952 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2953 DeleteFileA( buffer
);
2954 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
2955 handle
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2956 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
2957 handle2
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2958 ok( handle2
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
2959 fdi
.DoDeleteFile
= TRUE
;
2960 res
= pNtSetInformationFile( handle2
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2961 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2962 res
= nt_get_file_attrs( buffer
, &fdi2
);
2964 ok( res
== STATUS_DELETE_PENDING
, "got %#x\n", res
);
2965 /* can't open the deleted directory */
2966 handle3
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2968 ok( handle3
== INVALID_HANDLE_VALUE
, "CreateFile should fail\n" );
2969 if (handle3
!= INVALID_HANDLE_VALUE
)
2970 CloseHandle( handle3
);
2972 ok(GetLastError() == ERROR_ACCESS_DENIED
, "got %u\n", GetLastError());
2973 /* can't open the deleted directory (wrong sharing mode) */
2974 handle3
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2975 ok( handle3
== INVALID_HANDLE_VALUE
, "CreateFile should fail\n" );
2977 ok(GetLastError() == ERROR_ACCESS_DENIED
, "got %u\n", GetLastError());
2978 CloseHandle( handle2
);
2979 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2980 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
2981 CloseHandle( handle
);
2982 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2983 ok( fileDeleted
, "Directory should have been deleted\n" );
2985 /* directory exists until all handles to it get closed */
2986 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2987 DeleteFileA( buffer
);
2988 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
2989 handle
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
| FILE_FLAG_DELETE_ON_CLOSE
, 0);
2990 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
2991 /* can open the marked for delete directory (proper sharing mode) */
2992 handle2
= CreateFileA(buffer
, DELETE
, FILE_SHARE_DELETE
, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2993 ok( handle2
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
2994 /* can't open the marked for delete file (wrong sharing mode) */
2995 handle3
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2996 ok( handle3
== INVALID_HANDLE_VALUE
, "CreateFile should fail\n" );
2997 ok(GetLastError() == ERROR_SHARING_VIOLATION
, "got %u\n", GetLastError());
2998 CloseHandle( handle
);
2999 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3000 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
3001 CloseHandle( handle2
);
3002 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3003 ok( fileDeleted
, "Directory should have been deleted\n" );
3005 /* can open a non-empty directory with FILE_FLAG_DELETE_ON_CLOSE */
3006 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3007 DeleteFileA( buffer
);
3008 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
3009 dirpos
= lstrlenA( buffer
);
3010 lstrcpyA( buffer
+ dirpos
, "\\tst" );
3011 handle2
= CreateFileA(buffer
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
3012 CloseHandle( handle2
);
3013 buffer
[dirpos
] = '\0';
3014 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
| FILE_FLAG_DELETE_ON_CLOSE
, 0);
3015 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
3016 SetLastError(0xdeadbeef);
3017 CloseHandle( handle
);
3018 ok(GetLastError() == 0xdeadbeef, "got %u\n", GetLastError());
3019 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3020 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
3021 buffer
[dirpos
] = '\\';
3022 fileDeleted
= DeleteFileA( buffer
);
3023 ok( fileDeleted
, "File should have been deleted\n" );
3024 buffer
[dirpos
] = '\0';
3025 fileDeleted
= RemoveDirectoryA( buffer
);
3026 ok( fileDeleted
, "Directory should have been deleted\n" );
3028 /* cannot set disposition on a non-empty directory */
3029 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
3030 DeleteFileA( buffer
);
3031 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
3032 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
3033 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
3034 dirpos
= lstrlenA( buffer
);
3035 lstrcpyA( buffer
+ dirpos
, "\\tst" );
3036 handle2
= CreateFileA(buffer
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
3037 CloseHandle( handle2
);
3038 fdi
.DoDeleteFile
= TRUE
;
3039 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
3041 ok( res
== STATUS_DIRECTORY_NOT_EMPTY
, "unexpected FileDispositionInformation result (expected STATUS_DIRECTORY_NOT_EMPTY, got %x)\n", res
);
3042 fileDeleted
= DeleteFileA( buffer
);
3043 ok( fileDeleted
, "File should have been deleted\n" );
3044 buffer
[dirpos
] = '\0';
3045 CloseHandle( handle
);
3046 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
3048 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
3049 fileDeleted
= RemoveDirectoryA( buffer
);
3051 ok( fileDeleted
, "Directory should have been deleted\n" );
3054 static void test_file_name_information(void)
3056 WCHAR
*file_name
, *volume_prefix
, *expected
;
3057 FILE_NAME_INFORMATION
*info
;
3058 ULONG old_redir
= 1, tmp
;
3059 UINT file_name_size
;
3066 /* GetVolumePathName is not present before w2k */
3067 if (!pGetVolumePathNameW
) {
3068 win_skip("GetVolumePathNameW not found\n");
3072 file_name_size
= GetSystemDirectoryW( NULL
, 0 );
3073 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3074 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3075 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3077 len
= GetSystemDirectoryW( file_name
, file_name_size
);
3078 ok(len
== file_name_size
- 1,
3079 "GetSystemDirectoryW returned %u, expected %u.\n",
3080 len
, file_name_size
- 1);
3082 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3083 ok(len
, "GetVolumePathNameW failed.\n");
3085 len
= lstrlenW( volume_prefix
);
3086 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3087 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3088 expected
[file_name_size
- len
- 1] = '\0';
3090 /* A bit more than we actually need, but it keeps the calculation simple. */
3091 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3092 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3094 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( TRUE
, &old_redir
);
3095 h
= CreateFileW( file_name
, GENERIC_READ
,
3096 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3097 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3098 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( old_redir
, &tmp
);
3099 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3101 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
) - 1, FileNameInformation
);
3102 ok(hr
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryInformationFile returned %#x.\n", hr
);
3104 memset( info
, 0xcc, info_size
);
3105 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
), FileNameInformation
);
3106 ok(hr
== STATUS_BUFFER_OVERFLOW
, "NtQueryInformationFile returned %#x, expected %#x.\n",
3107 hr
, STATUS_BUFFER_OVERFLOW
);
3108 ok(U(io
).Status
== STATUS_BUFFER_OVERFLOW
, "io.Status is %#x, expected %#x.\n",
3109 U(io
).Status
, STATUS_BUFFER_OVERFLOW
);
3110 ok(info
->FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
), "info->FileNameLength is %u\n", info
->FileNameLength
);
3111 ok(info
->FileName
[2] == 0xcccc, "info->FileName[2] is %#x, expected 0xcccc.\n", info
->FileName
[2]);
3112 ok(CharLowerW((LPWSTR
)(UINT_PTR
)info
->FileName
[1]) == CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]),
3113 "info->FileName[1] is %p, expected %p.\n",
3114 CharLowerW((LPWSTR
)(UINT_PTR
)info
->FileName
[1]), CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]));
3115 ok(io
.Information
== sizeof(*info
), "io.Information is %lu\n", io
.Information
);
3117 memset( info
, 0xcc, info_size
);
3118 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileNameInformation
);
3119 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
3120 ok(U(io
).Status
== STATUS_SUCCESS
, "io.Status is %#x, expected %#x.\n", U(io
).Status
, STATUS_SUCCESS
);
3121 ok(info
->FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
), "info->FileNameLength is %u\n", info
->FileNameLength
);
3122 ok(info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)] == 0xcccc, "info->FileName[len] is %#x, expected 0xcccc.\n",
3123 info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)]);
3124 info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)] = '\0';
3125 ok(!lstrcmpiW( info
->FileName
, expected
), "info->FileName is %s, expected %s.\n",
3126 wine_dbgstr_w( info
->FileName
), wine_dbgstr_w( expected
));
3127 ok(io
.Information
== FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
) + info
->FileNameLength
,
3128 "io.Information is %lu, expected %u.\n",
3129 io
.Information
, FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
) + info
->FileNameLength
);
3132 HeapFree( GetProcessHeap(), 0, info
);
3133 HeapFree( GetProcessHeap(), 0, expected
);
3134 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3136 if (old_redir
|| !pGetSystemWow64DirectoryW
|| !(file_name_size
= pGetSystemWow64DirectoryW( NULL
, 0 )))
3138 skip("Not running on WoW64, skipping test.\n");
3139 HeapFree( GetProcessHeap(), 0, file_name
);
3143 h
= CreateFileW( file_name
, GENERIC_READ
,
3144 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3145 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3146 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3147 HeapFree( GetProcessHeap(), 0, file_name
);
3149 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3150 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3151 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*expected
) );
3153 len
= pGetSystemWow64DirectoryW( file_name
, file_name_size
);
3154 ok(len
== file_name_size
- 1,
3155 "GetSystemWow64DirectoryW returned %u, expected %u.\n",
3156 len
, file_name_size
- 1);
3158 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3159 ok(len
, "GetVolumePathNameW failed.\n");
3161 len
= lstrlenW( volume_prefix
);
3162 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3163 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3164 expected
[file_name_size
- len
- 1] = '\0';
3166 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3167 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3169 memset( info
, 0xcc, info_size
);
3170 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileNameInformation
);
3171 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
3172 info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)] = '\0';
3173 ok(!lstrcmpiW( info
->FileName
, expected
), "info->FileName is %s, expected %s.\n",
3174 wine_dbgstr_w( info
->FileName
), wine_dbgstr_w( expected
));
3177 HeapFree( GetProcessHeap(), 0, info
);
3178 HeapFree( GetProcessHeap(), 0, expected
);
3179 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3180 HeapFree( GetProcessHeap(), 0, file_name
);
3183 static void test_file_all_name_information(void)
3185 WCHAR
*file_name
, *volume_prefix
, *expected
;
3186 FILE_ALL_INFORMATION
*info
;
3187 ULONG old_redir
= 1, tmp
;
3188 UINT file_name_size
;
3195 /* GetVolumePathName is not present before w2k */
3196 if (!pGetVolumePathNameW
) {
3197 win_skip("GetVolumePathNameW not found\n");
3201 file_name_size
= GetSystemDirectoryW( NULL
, 0 );
3202 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3203 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3204 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3206 len
= GetSystemDirectoryW( file_name
, file_name_size
);
3207 ok(len
== file_name_size
- 1,
3208 "GetSystemDirectoryW returned %u, expected %u.\n",
3209 len
, file_name_size
- 1);
3211 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3212 ok(len
, "GetVolumePathNameW failed.\n");
3214 len
= lstrlenW( volume_prefix
);
3215 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3216 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3217 expected
[file_name_size
- len
- 1] = '\0';
3219 /* A bit more than we actually need, but it keeps the calculation simple. */
3220 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3221 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3223 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( TRUE
, &old_redir
);
3224 h
= CreateFileW( file_name
, GENERIC_READ
,
3225 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3226 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3227 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( old_redir
, &tmp
);
3228 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3230 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
) - 1, FileAllInformation
);
3231 ok(hr
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryInformationFile returned %#x, expected %#x.\n",
3232 hr
, STATUS_INFO_LENGTH_MISMATCH
);
3234 memset( info
, 0xcc, info_size
);
3235 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
), FileAllInformation
);
3236 ok(hr
== STATUS_BUFFER_OVERFLOW
, "NtQueryInformationFile returned %#x, expected %#x.\n",
3237 hr
, STATUS_BUFFER_OVERFLOW
);
3238 ok(U(io
).Status
== STATUS_BUFFER_OVERFLOW
, "io.Status is %#x, expected %#x.\n",
3239 U(io
).Status
, STATUS_BUFFER_OVERFLOW
);
3240 ok(info
->NameInformation
.FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
),
3241 "info->NameInformation.FileNameLength is %u\n", info
->NameInformation
.FileNameLength
);
3242 ok(info
->NameInformation
.FileName
[2] == 0xcccc,
3243 "info->NameInformation.FileName[2] is %#x, expected 0xcccc.\n", info
->NameInformation
.FileName
[2]);
3244 ok(CharLowerW((LPWSTR
)(UINT_PTR
)info
->NameInformation
.FileName
[1]) == CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]),
3245 "info->NameInformation.FileName[1] is %p, expected %p.\n",
3246 CharLowerW((LPWSTR
)(UINT_PTR
)info
->NameInformation
.FileName
[1]), CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]));
3247 ok(io
.Information
== sizeof(*info
), "io.Information is %lu\n", io
.Information
);
3249 memset( info
, 0xcc, info_size
);
3250 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileAllInformation
);
3251 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
3252 ok(U(io
).Status
== STATUS_SUCCESS
, "io.Status is %#x, expected %#x.\n", U(io
).Status
, STATUS_SUCCESS
);
3253 ok(info
->NameInformation
.FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
),
3254 "info->NameInformation.FileNameLength is %u\n", info
->NameInformation
.FileNameLength
);
3255 ok(info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)] == 0xcccc,
3256 "info->NameInformation.FileName[len] is %#x, expected 0xcccc.\n",
3257 info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)]);
3258 info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)] = '\0';
3259 ok(!lstrcmpiW( info
->NameInformation
.FileName
, expected
),
3260 "info->NameInformation.FileName is %s, expected %s.\n",
3261 wine_dbgstr_w( info
->NameInformation
.FileName
), wine_dbgstr_w( expected
));
3262 ok(io
.Information
== FIELD_OFFSET(FILE_ALL_INFORMATION
, NameInformation
.FileName
)
3263 + info
->NameInformation
.FileNameLength
,
3264 "io.Information is %lu\n", io
.Information
);
3267 HeapFree( GetProcessHeap(), 0, info
);
3268 HeapFree( GetProcessHeap(), 0, expected
);
3269 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3271 if (old_redir
|| !pGetSystemWow64DirectoryW
|| !(file_name_size
= pGetSystemWow64DirectoryW( NULL
, 0 )))
3273 skip("Not running on WoW64, skipping test.\n");
3274 HeapFree( GetProcessHeap(), 0, file_name
);
3278 h
= CreateFileW( file_name
, GENERIC_READ
,
3279 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3280 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3281 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3282 HeapFree( GetProcessHeap(), 0, file_name
);
3284 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3285 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3286 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*expected
) );
3288 len
= pGetSystemWow64DirectoryW( file_name
, file_name_size
);
3289 ok(len
== file_name_size
- 1,
3290 "GetSystemWow64DirectoryW returned %u, expected %u.\n",
3291 len
, file_name_size
- 1);
3293 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3294 ok(len
, "GetVolumePathNameW failed.\n");
3296 len
= lstrlenW( volume_prefix
);
3297 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3298 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3299 expected
[file_name_size
- len
- 1] = '\0';
3301 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3302 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3304 memset( info
, 0xcc, info_size
);
3305 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileAllInformation
);
3306 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
3307 info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)] = '\0';
3308 ok(!lstrcmpiW( info
->NameInformation
.FileName
, expected
), "info->NameInformation.FileName is %s, expected %s.\n",
3309 wine_dbgstr_w( info
->NameInformation
.FileName
), wine_dbgstr_w( expected
));
3312 HeapFree( GetProcessHeap(), 0, info
);
3313 HeapFree( GetProcessHeap(), 0, expected
);
3314 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3315 HeapFree( GetProcessHeap(), 0, file_name
);
3318 static void test_file_completion_information(void)
3320 static const char buf
[] = "testdata";
3321 FILE_IO_COMPLETION_NOTIFICATION_INFORMATION info
;
3322 OVERLAPPED ov
, *pov
;
3331 if (!(h
= create_temp_file(0))) return;
3333 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
) - 1, FileIoCompletionNotificationInformation
);
3335 ok(status
== STATUS_INFO_LENGTH_MISMATCH
|| status
== STATUS_INVALID_INFO_CLASS
/* XP */,
3336 "expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
3337 if (status
== STATUS_INVALID_INFO_CLASS
|| status
== STATUS_NOT_IMPLEMENTED
)
3339 skip("FileIoCompletionNotificationInformation class not supported\n");
3344 info
.Flags
= FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
;
3345 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3346 ok(status
== STATUS_INVALID_PARAMETER
, "expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
3349 if (!(h
= create_temp_file(FILE_FLAG_OVERLAPPED
))) return;
3351 info
.Flags
= FILE_SKIP_SET_EVENT_ON_HANDLE
;
3352 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3353 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3355 info
.Flags
= FILE_SKIP_SET_USER_EVENT_ON_FAST_IO
;
3356 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3357 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3360 if (!(h
= create_temp_file(FILE_FLAG_OVERLAPPED
))) return;
3362 memset(&ov
, 0, sizeof(ov
));
3363 ov
.hEvent
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
3364 port
= CreateIoCompletionPort(h
, NULL
, 0xdeadbeef, 0);
3365 ok(port
!= NULL
, "CreateIoCompletionPort failed, error %u\n", GetLastError());
3367 for (i
= 0; i
< 10; i
++)
3369 SetLastError(0xdeadbeef);
3370 ret
= WriteFile(h
, buf
, sizeof(buf
), &num_bytes
, &ov
);
3371 if (ret
|| GetLastError() != ERROR_IO_PENDING
) break;
3372 ret
= GetOverlappedResult(h
, &ov
, &num_bytes
, TRUE
);
3373 ok(ret
, "GetOverlappedResult failed, error %u\n", GetLastError());
3374 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 1000);
3375 ok(ret
, "GetQueuedCompletionStatus failed, error %u\n", GetLastError());
3380 ok(num_bytes
== sizeof(buf
), "expected sizeof(buf), got %u\n", num_bytes
);
3384 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 1000);
3385 ok(ret
, "GetQueuedCompletionStatus failed, error %u\n", GetLastError());
3386 ok(key
== 0xdeadbeef, "expected 0xdeadbeef, got %lx\n", key
);
3387 ok(pov
== &ov
, "expected %p, got %p\n", &ov
, pov
);
3390 win_skip("WriteFile never returned TRUE\n");
3392 info
.Flags
= FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
;
3393 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3394 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3396 for (i
= 0; i
< 10; i
++)
3398 SetLastError(0xdeadbeef);
3399 ret
= WriteFile(h
, buf
, sizeof(buf
), &num_bytes
, &ov
);
3400 if (ret
|| GetLastError() != ERROR_IO_PENDING
) break;
3401 ret
= GetOverlappedResult(h
, &ov
, &num_bytes
, TRUE
);
3402 ok(ret
, "GetOverlappedResult failed, error %u\n", GetLastError());
3407 ok(num_bytes
== sizeof(buf
), "expected sizeof(buf), got %u\n", num_bytes
);
3409 pov
= (void *)0xdeadbeef;
3410 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 500);
3411 ok(!ret
, "GetQueuedCompletionStatus succeeded\n");
3412 ok(pov
== NULL
, "expected NULL, got %p\n", pov
);
3415 win_skip("WriteFile never returned TRUE\n");
3418 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3419 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3421 for (i
= 0; i
< 10; i
++)
3423 SetLastError(0xdeadbeef);
3424 ret
= WriteFile(h
, buf
, sizeof(buf
), &num_bytes
, &ov
);
3425 if (ret
|| GetLastError() != ERROR_IO_PENDING
) break;
3426 ret
= GetOverlappedResult(h
, &ov
, &num_bytes
, TRUE
);
3427 ok(ret
, "GetOverlappedResult failed, error %u\n", GetLastError());
3428 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 1000);
3429 ok(ret
, "GetQueuedCompletionStatus failed, error %u\n", GetLastError());
3434 ok(num_bytes
== sizeof(buf
), "expected sizeof(buf), got %u\n", num_bytes
);
3436 pov
= (void *)0xdeadbeef;
3437 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 1000);
3438 ok(!ret
, "GetQueuedCompletionStatus succeeded\n");
3439 ok(pov
== NULL
, "expected NULL, got %p\n", pov
);
3442 win_skip("WriteFile never returned TRUE\n");
3444 CloseHandle(ov
.hEvent
);
3449 static void test_file_id_information(void)
3451 BY_HANDLE_FILE_INFORMATION info
;
3452 FILE_ID_INFORMATION fid
;
3459 if (!(h
= create_temp_file(0))) return;
3461 memset( &fid
, 0x11, sizeof(fid
) );
3462 status
= pNtQueryInformationFile( h
, &io
, &fid
, sizeof(fid
), FileIdInformation
);
3463 if (status
== STATUS_NOT_IMPLEMENTED
|| status
== STATUS_INVALID_INFO_CLASS
)
3465 win_skip( "FileIdInformation not supported\n" );
3470 memset( &info
, 0x22, sizeof(info
) );
3471 ret
= GetFileInformationByHandle( h
, &info
);
3472 ok( ret
, "GetFileInformationByHandle failed\n" );
3474 dwords
= (DWORD
*)&fid
.VolumeSerialNumber
;
3475 ok( dwords
[0] == info
.dwVolumeSerialNumber
, "expected %08x, got %08x\n",
3476 info
.dwVolumeSerialNumber
, dwords
[0] );
3477 ok( dwords
[1] != 0x11111111, "expected != 0x11111111\n" );
3479 dwords
= (DWORD
*)&fid
.FileId
;
3480 ok( dwords
[0] == info
.nFileIndexLow
, "expected %08x, got %08x\n", info
.nFileIndexLow
, dwords
[0] );
3481 ok( dwords
[1] == info
.nFileIndexHigh
, "expected %08x, got %08x\n", info
.nFileIndexHigh
, dwords
[1] );
3482 ok( dwords
[2] == 0, "expected 0, got %08x\n", dwords
[2] );
3483 ok( dwords
[3] == 0, "expected 0, got %08x\n", dwords
[3] );
3488 static void test_file_access_information(void)
3490 FILE_ACCESS_INFORMATION info
;
3495 if (!(h
= create_temp_file(0))) return;
3497 status
= pNtQueryInformationFile( h
, &io
, &info
, sizeof(info
) - 1, FileAccessInformation
);
3498 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
3500 status
= pNtQueryInformationFile( (HANDLE
)0xdeadbeef, &io
, &info
, sizeof(info
), FileAccessInformation
);
3501 ok( status
== STATUS_INVALID_HANDLE
, "expected STATUS_INVALID_HANDLE, got %08x\n", status
);
3503 memset(&info
, 0x11, sizeof(info
));
3504 status
= pNtQueryInformationFile( h
, &io
, &info
, sizeof(info
), FileAccessInformation
);
3505 ok( status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3506 ok( info
.AccessFlags
== 0x13019f, "got %08x\n", info
.AccessFlags
);
3511 static void test_query_volume_information_file(void)
3515 WCHAR path
[MAX_PATH
];
3516 OBJECT_ATTRIBUTES attr
;
3518 UNICODE_STRING nameW
;
3519 FILE_FS_VOLUME_INFORMATION
*ffvi
;
3520 BYTE buf
[sizeof(FILE_FS_VOLUME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
)];
3522 GetWindowsDirectoryW( path
, MAX_PATH
);
3523 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
3524 attr
.Length
= sizeof(attr
);
3525 attr
.RootDirectory
= 0;
3526 attr
.ObjectName
= &nameW
;
3527 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
3528 attr
.SecurityDescriptor
= NULL
;
3529 attr
.SecurityQualityOfService
= NULL
;
3531 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
3532 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
3533 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
3534 pRtlFreeUnicodeString( &nameW
);
3536 ZeroMemory( buf
, sizeof(buf
) );
3537 U(io
).Status
= 0xdadadada;
3538 io
.Information
= 0xcacacaca;
3540 status
= pNtQueryVolumeInformationFile( dir
, &io
, buf
, sizeof(buf
), FileFsVolumeInformation
);
3542 ffvi
= (FILE_FS_VOLUME_INFORMATION
*)buf
;
3546 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", status
);
3547 ok(U(io
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", U(io
).Status
);
3549 ok(io
.Information
== (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION
, VolumeLabel
) + ffvi
->VolumeLabelLength
),
3550 "expected %d, got %lu\n", (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION
, VolumeLabel
) + ffvi
->VolumeLabelLength
),
3553 ok(ffvi
->VolumeCreationTime
.QuadPart
!= 0, "Missing VolumeCreationTime\n");
3554 ok(ffvi
->VolumeSerialNumber
!= 0, "Missing VolumeSerialNumber\n");
3555 ok(ffvi
->SupportsObjects
== 1,"expected 1, got %d\n", ffvi
->SupportsObjects
);
3557 ok(ffvi
->VolumeLabelLength
== lstrlenW(ffvi
->VolumeLabel
) * sizeof(WCHAR
), "got %d\n", ffvi
->VolumeLabelLength
);
3559 trace("VolumeSerialNumber: %x VolumeLabelName: %s\n", ffvi
->VolumeSerialNumber
, wine_dbgstr_w(ffvi
->VolumeLabel
));
3564 static void test_query_attribute_information_file(void)
3568 WCHAR path
[MAX_PATH
];
3569 OBJECT_ATTRIBUTES attr
;
3571 UNICODE_STRING nameW
;
3572 FILE_FS_ATTRIBUTE_INFORMATION
*ffai
;
3573 BYTE buf
[sizeof(FILE_FS_ATTRIBUTE_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
)];
3575 GetWindowsDirectoryW( path
, MAX_PATH
);
3576 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
3577 attr
.Length
= sizeof(attr
);
3578 attr
.RootDirectory
= 0;
3579 attr
.ObjectName
= &nameW
;
3580 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
3581 attr
.SecurityDescriptor
= NULL
;
3582 attr
.SecurityQualityOfService
= NULL
;
3584 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
3585 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
3586 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
3587 pRtlFreeUnicodeString( &nameW
);
3589 ZeroMemory( buf
, sizeof(buf
) );
3590 U(io
).Status
= 0xdadadada;
3591 io
.Information
= 0xcacacaca;
3593 status
= pNtQueryVolumeInformationFile( dir
, &io
, buf
, sizeof(buf
), FileFsAttributeInformation
);
3595 ffai
= (FILE_FS_ATTRIBUTE_INFORMATION
*)buf
;
3597 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", status
);
3598 ok(U(io
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", U(io
).Status
);
3599 ok(ffai
->FileSystemAttribute
!= 0, "Missing FileSystemAttribute\n");
3600 ok(ffai
->MaximumComponentNameLength
!= 0, "Missing MaximumComponentNameLength\n");
3601 ok(ffai
->FileSystemNameLength
!= 0, "Missing FileSystemNameLength\n");
3603 trace("FileSystemAttribute: %x MaximumComponentNameLength: %x FileSystemName: %s\n",
3604 ffai
->FileSystemAttribute
, ffai
->MaximumComponentNameLength
,
3605 wine_dbgstr_wn(ffai
->FileSystemName
, ffai
->FileSystemNameLength
/ sizeof(WCHAR
)));
3610 static void test_NtCreateFile(void)
3612 static const struct test_data
3614 DWORD disposition
, attrib_in
, status
, result
, attrib_out
, needs_cleanup
;
3617 /* 0*/{ FILE_CREATE
, FILE_ATTRIBUTE_READONLY
, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3618 /* 1*/{ FILE_CREATE
, 0, STATUS_OBJECT_NAME_COLLISION
, 0, 0, TRUE
},
3619 /* 2*/{ FILE_CREATE
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3620 /* 3*/{ FILE_OPEN
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OPENED
, FILE_ATTRIBUTE_ARCHIVE
, TRUE
},
3621 /* 4*/{ FILE_OPEN
, FILE_ATTRIBUTE_READONLY
, STATUS_OBJECT_NAME_NOT_FOUND
, 0, 0, FALSE
},
3622 /* 5*/{ FILE_OPEN_IF
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3623 /* 6*/{ FILE_OPEN_IF
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OPENED
, FILE_ATTRIBUTE_ARCHIVE
, TRUE
},
3624 /* 7*/{ FILE_OPEN_IF
, FILE_ATTRIBUTE_READONLY
, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3625 /* 8*/{ FILE_OPEN_IF
, 0, 0, FILE_OPENED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3626 /* 9*/{ FILE_OVERWRITE
, 0, STATUS_ACCESS_DENIED
, 0, 0, TRUE
},
3627 /*10*/{ FILE_OVERWRITE
, 0, STATUS_OBJECT_NAME_NOT_FOUND
, 0, 0, FALSE
},
3628 /*11*/{ FILE_CREATE
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3629 /*12*/{ FILE_OVERWRITE
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OVERWRITTEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3630 /*13*/{ FILE_OVERWRITE_IF
, 0, STATUS_ACCESS_DENIED
, 0, 0, TRUE
},
3631 /*14*/{ FILE_OVERWRITE_IF
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3632 /*15*/{ FILE_OVERWRITE_IF
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OVERWRITTEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3633 /*16*/{ FILE_SUPERSEDE
, 0, 0, FILE_SUPERSEDED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3634 /*17*/{ FILE_SUPERSEDE
, FILE_ATTRIBUTE_READONLY
, 0, FILE_SUPERSEDED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, TRUE
},
3635 /*18*/{ FILE_SUPERSEDE
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, TRUE
}
3637 static const WCHAR fooW
[] = {'f','o','o',0};
3640 WCHAR path
[MAX_PATH
];
3641 OBJECT_ATTRIBUTES attr
;
3643 UNICODE_STRING nameW
;
3646 GetTempPathW(MAX_PATH
, path
);
3647 GetTempFileNameW(path
, fooW
, 0, path
);
3649 pRtlDosPathNameToNtPathName_U(path
, &nameW
, NULL
, NULL
);
3651 attr
.Length
= sizeof(attr
);
3652 attr
.RootDirectory
= NULL
;
3653 attr
.ObjectName
= &nameW
;
3654 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
3655 attr
.SecurityDescriptor
= NULL
;
3656 attr
.SecurityQualityOfService
= NULL
;
3658 for (i
= 0; i
< ARRAY_SIZE(td
); i
++)
3660 status
= pNtCreateFile(&handle
, GENERIC_READ
, &attr
, &io
, NULL
,
3661 td
[i
].attrib_in
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
3662 td
[i
].disposition
, 0, NULL
, 0);
3664 ok(status
== td
[i
].status
, "%d: expected %#x got %#x\n", i
, td
[i
].status
, status
);
3668 ok(io
.Information
== td
[i
].result
,"%d: expected %#x got %#lx\n", i
, td
[i
].result
, io
.Information
);
3670 ret
= GetFileAttributesW(path
);
3671 ret
&= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
;
3672 /* FIXME: leave only 'else' case below once Wine is fixed */
3673 if (ret
!= td
[i
].attrib_out
)
3676 ok(ret
== td
[i
].attrib_out
, "%d: expected %#x got %#x\n", i
, td
[i
].attrib_out
, ret
);
3677 SetFileAttributesW(path
, td
[i
].attrib_out
);
3680 ok(ret
== td
[i
].attrib_out
, "%d: expected %#x got %#x\n", i
, td
[i
].attrib_out
, ret
);
3682 CloseHandle(handle
);
3685 if (td
[i
].needs_cleanup
)
3687 SetFileAttributesW(path
, FILE_ATTRIBUTE_ARCHIVE
);
3692 pRtlFreeUnicodeString( &nameW
);
3693 SetFileAttributesW(path
, FILE_ATTRIBUTE_ARCHIVE
);
3694 DeleteFileW( path
);
3697 static void test_read_write(void)
3699 static const char contents
[14] = "1234567890abcd";
3701 HANDLE hfile
, event
;
3703 IO_STATUS_BLOCK iob
;
3704 DWORD ret
, bytes
, status
, off
;
3705 LARGE_INTEGER offset
;
3708 event
= CreateEventA( NULL
, TRUE
, FALSE
, NULL
);
3711 iob
.Information
= -1;
3712 offset
.QuadPart
= 0;
3713 status
= pNtReadFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3714 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status
);
3715 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3716 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3719 iob
.Information
= -1;
3720 offset
.QuadPart
= 0;
3721 status
= pNtReadFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, NULL
, sizeof(buf
), &offset
, NULL
);
3722 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status
);
3723 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3724 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3727 iob
.Information
= -1;
3728 offset
.QuadPart
= 0;
3729 status
= pNtWriteFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3730 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status
);
3731 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3732 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3735 iob
.Information
= -1;
3736 offset
.QuadPart
= 0;
3737 status
= pNtWriteFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3738 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status
);
3739 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3740 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3742 hfile
= create_temp_file(0);
3746 iob
.Information
= -1;
3747 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
3748 ok(status
== STATUS_INVALID_USER_BUFFER
, "expected STATUS_INVALID_USER_BUFFER, got %#x\n", status
);
3749 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3750 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3753 iob
.Information
= -1;
3755 status
= pNtWriteFile(hfile
, event
, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
3756 ok(status
== STATUS_INVALID_USER_BUFFER
, "expected STATUS_INVALID_USER_BUFFER, got %#x\n", status
);
3757 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3758 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3759 ok(!is_signaled(event
), "event is not signaled\n");
3762 iob
.Information
= -1;
3763 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
3764 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#x\n", status
);
3765 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3766 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3769 iob
.Information
= -1;
3771 status
= pNtReadFile(hfile
, event
, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
3772 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#x\n", status
);
3773 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3774 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3775 ok(is_signaled(event
), "event is not signaled\n");
3778 iob
.Information
= -1;
3780 status
= pNtReadFile(hfile
, event
, NULL
, NULL
, &iob
, (void*)0xdeadbeef, sizeof(contents
), NULL
, NULL
);
3781 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#x\n", status
);
3782 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3783 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3784 ok(is_signaled(event
), "event is not signaled\n");
3787 iob
.Information
= -1;
3788 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, 7, NULL
, NULL
);
3789 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
3790 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3791 ok(iob
.Information
== 7, "expected 7, got %lu\n", iob
.Information
);
3793 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3796 iob
.Information
= -1;
3797 offset
.QuadPart
= (LONGLONG
)-1 /* FILE_WRITE_TO_END_OF_FILE */;
3798 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
+ 7, sizeof(contents
) - 7, &offset
, NULL
);
3799 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
3800 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3801 ok(iob
.Information
== sizeof(contents
) - 7, "expected sizeof(contents)-7, got %lu\n", iob
.Information
);
3803 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3804 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3807 SetLastError(0xdeadbeef);
3808 ret
= ReadFile(INVALID_HANDLE_VALUE
, buf
, 0, &bytes
, NULL
);
3809 ok(!ret
, "ReadFile should fail\n");
3810 ok(GetLastError() == ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
3811 ok(bytes
== 0, "bytes %u\n", bytes
);
3814 SetLastError(0xdeadbeef);
3815 ret
= ReadFile(hfile
, buf
, 0, &bytes
, NULL
);
3816 ok(ret
, "ReadFile error %d\n", GetLastError());
3817 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3818 ok(bytes
== 0, "bytes %u\n", bytes
);
3821 SetLastError(0xdeadbeef);
3822 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3823 ok(ret
, "ReadFile error %d\n", GetLastError());
3824 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3825 ok(bytes
== 0, "bytes %u\n", bytes
);
3827 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3830 SetLastError(0xdeadbeef);
3831 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3832 ok(ret
, "ReadFile error %d\n", GetLastError());
3833 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3834 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
3836 for (i
= -20; i
< -1; i
++)
3838 if (i
== -2) continue;
3841 iob
.Information
= -1;
3842 offset
.QuadPart
= (LONGLONG
)i
;
3843 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), &offset
, NULL
);
3844 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
3845 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3846 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
3849 SetFilePointer(hfile
, sizeof(contents
) - 4, NULL
, FILE_BEGIN
);
3852 iob
.Information
= -1;
3853 offset
.QuadPart
= (LONGLONG
)-2 /* FILE_USE_FILE_POINTER_POSITION */;
3854 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, "DCBA", 4, &offset
, NULL
);
3855 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
3856 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3857 ok(iob
.Information
== 4, "expected 4, got %lu\n", iob
.Information
);
3859 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3860 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3863 iob
.Information
= -1;
3864 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), NULL
, NULL
);
3865 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3866 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3867 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3869 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3872 SetLastError(0xdeadbeef);
3873 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3874 ok(ret
, "ReadFile error %d\n", GetLastError());
3875 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3876 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
3877 ok(!memcmp(buf
+ sizeof(contents
) - 4, "DCBA", 4), "file contents mismatch\n");
3879 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3880 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3882 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3885 SetLastError(0xdeadbeef);
3886 ret
= WriteFile(hfile
, contents
, sizeof(contents
), &bytes
, NULL
);
3887 ok(ret
, "WriteFile error %d\n", GetLastError());
3888 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3890 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3891 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3893 /* test reading beyond EOF */
3895 SetLastError(0xdeadbeef);
3896 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3897 ok(ret
, "ReadFile error %d\n", GetLastError());
3898 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3899 ok(bytes
== 0, "bytes %u\n", bytes
);
3902 SetLastError(0xdeadbeef);
3903 ret
= ReadFile(hfile
, buf
, 0, &bytes
, NULL
);
3904 ok(ret
, "ReadFile error %d\n", GetLastError());
3905 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3906 ok(bytes
== 0, "bytes %u\n", bytes
);
3909 SetLastError(0xdeadbeef);
3910 ret
= ReadFile(hfile
, NULL
, 0, &bytes
, NULL
);
3911 ok(ret
, "ReadFile error %d\n", GetLastError());
3912 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3913 ok(bytes
== 0, "bytes %u\n", bytes
);
3915 S(U(ovl
)).Offset
= sizeof(contents
);
3916 S(U(ovl
)).OffsetHigh
= 0;
3918 ovl
.InternalHigh
= -1;
3921 SetLastError(0xdeadbeef);
3922 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
3923 ok(!ret
, "ReadFile should fail\n");
3924 ok(GetLastError() == ERROR_HANDLE_EOF
, "expected ERROR_HANDLE_EOF, got %d\n", GetLastError());
3925 ok(bytes
== 0, "bytes %u\n", bytes
);
3926 ok((NTSTATUS
)ovl
.Internal
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", ovl
.Internal
);
3927 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
3929 S(U(ovl
)).Offset
= sizeof(contents
);
3930 S(U(ovl
)).OffsetHigh
= 0;
3932 ovl
.InternalHigh
= -1;
3935 SetLastError(0xdeadbeef);
3936 ret
= ReadFile(hfile
, buf
, 0, &bytes
, &ovl
);
3937 ok(ret
, "ReadFile error %d\n", GetLastError());
3938 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3939 ok(bytes
== 0, "bytes %u\n", bytes
);
3940 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
3941 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
3944 iob
.Information
= -1;
3945 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), NULL
, NULL
);
3946 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3947 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3948 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3951 iob
.Information
= -1;
3952 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, NULL
, NULL
);
3953 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3954 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3955 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3958 iob
.Information
= -1;
3959 offset
.QuadPart
= sizeof(contents
);
3960 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3961 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3962 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3963 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3966 iob
.Information
= -1;
3967 offset
.QuadPart
= sizeof(contents
);
3968 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, &offset
, NULL
);
3969 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3970 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3971 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3974 iob
.Information
= -1;
3975 offset
.QuadPart
= (LONGLONG
)-2 /* FILE_USE_FILE_POINTER_POSITION */;
3976 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3977 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3978 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3979 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3982 iob
.Information
= -1;
3983 offset
.QuadPart
= (LONGLONG
)-2 /* FILE_USE_FILE_POINTER_POSITION */;
3984 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, &offset
, NULL
);
3985 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3986 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3987 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3989 for (i
= -20; i
< 0; i
++)
3991 if (i
== -2) continue;
3994 iob
.Information
= -1;
3995 offset
.QuadPart
= (LONGLONG
)i
;
3996 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3997 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
3998 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3999 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
4002 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
4005 SetLastError(0xdeadbeef);
4006 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
4007 ok(ret
, "ReadFile error %d\n", GetLastError());
4008 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
4009 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
4011 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4012 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
4015 iob
.Information
= -1;
4016 offset
.QuadPart
= 0;
4017 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4018 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
4019 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4020 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %lu\n", iob
.Information
);
4021 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
4023 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4024 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
4027 iob
.Information
= -1;
4028 offset
.QuadPart
= sizeof(contents
) - 4;
4029 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, "DCBA", 4, &offset
, NULL
);
4030 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
4031 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4032 ok(iob
.Information
== 4, "expected 4, got %lu\n", iob
.Information
);
4034 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4035 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
4038 iob
.Information
= -1;
4039 offset
.QuadPart
= 0;
4040 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4041 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
4042 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4043 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %lu\n", iob
.Information
);
4044 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
4045 ok(!memcmp(buf
+ sizeof(contents
) - 4, "DCBA", 4), "file contents mismatch\n");
4047 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4048 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
4050 S(U(ovl
)).Offset
= sizeof(contents
) - 4;
4051 S(U(ovl
)).OffsetHigh
= 0;
4054 SetLastError(0xdeadbeef);
4055 ret
= WriteFile(hfile
, "ABCD", 4, &bytes
, &ovl
);
4056 ok(ret
, "WriteFile error %d\n", GetLastError());
4057 ok(bytes
== 4, "bytes %u\n", bytes
);
4059 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4060 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
4062 S(U(ovl
)).Offset
= 0;
4063 S(U(ovl
)).OffsetHigh
= 0;
4065 ovl
.InternalHigh
= -1;
4068 SetLastError(0xdeadbeef);
4069 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4070 ok(ret
, "ReadFile error %d\n", GetLastError());
4071 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
4072 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4073 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4074 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
4075 ok(!memcmp(buf
+ sizeof(contents
) - 4, "ABCD", 4), "file contents mismatch\n");
4077 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4078 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
4082 hfile
= create_temp_file(FILE_FLAG_OVERLAPPED
);
4086 SetLastError(0xdeadbeef);
4087 ret
= ReadFile(INVALID_HANDLE_VALUE
, buf
, 0, &bytes
, NULL
);
4088 ok(!ret
, "ReadFile should fail\n");
4089 ok(GetLastError() == ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
4090 ok(bytes
== 0, "bytes %u\n", bytes
);
4092 S(U(ovl
)).Offset
= 0;
4093 S(U(ovl
)).OffsetHigh
= 0;
4095 ovl
.InternalHigh
= -1;
4098 SetLastError(0xdeadbeef);
4099 /* ReadFile return value depends on Windows version and testing it is not practical */
4100 ReadFile(hfile
, buf
, 0, &bytes
, &ovl
);
4101 ok(bytes
== 0, "bytes %u\n", bytes
);
4102 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4103 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
4106 SetLastError(0xdeadbeef);
4107 ret
= WriteFile(hfile
, contents
, sizeof(contents
), &bytes
, NULL
);
4108 ok(!ret
, "WriteFile should fail\n");
4109 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
4110 ok(bytes
== 0, "bytes %u\n", bytes
);
4113 iob
.Information
= -1;
4114 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), NULL
, NULL
);
4115 ok(status
== STATUS_INVALID_PARAMETER
, "expected STATUS_INVALID_PARAMETER, got %#x\n", status
);
4116 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4117 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
4119 for (i
= -20; i
< -1; i
++)
4122 iob
.Information
= -1;
4123 offset
.QuadPart
= (LONGLONG
)i
;
4124 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), &offset
, NULL
);
4125 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
4126 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4127 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
4131 iob
.Information
= -1;
4132 offset
.QuadPart
= 0;
4133 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), &offset
, NULL
);
4134 ok(status
== STATUS_PENDING
|| status
== STATUS_SUCCESS
/* before Vista */, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status
);
4135 if (status
== STATUS_PENDING
)
4137 ret
= WaitForSingleObject(hfile
, 3000);
4138 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4140 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4141 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %lu\n", iob
.Information
);
4143 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4144 ok(off
== 0, "expected 0, got %u\n", off
);
4147 SetLastError(0xdeadbeef);
4148 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
4149 ok(!ret
, "ReadFile should fail\n");
4150 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
4151 ok(bytes
== 0, "bytes %u\n", bytes
);
4154 iob
.Information
= -1;
4155 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), NULL
, NULL
);
4156 ok(status
== STATUS_INVALID_PARAMETER
, "expected STATUS_INVALID_PARAMETER, got %#x\n", status
);
4157 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4158 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
4160 for (i
= -20; i
< 0; i
++)
4163 iob
.Information
= -1;
4164 offset
.QuadPart
= (LONGLONG
)i
;
4165 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4166 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
4167 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4168 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
4171 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4172 ok(off
== 0, "expected 0, got %u\n", off
);
4174 /* test reading beyond EOF */
4175 offset
.QuadPart
= sizeof(contents
);
4176 S(U(ovl
)).Offset
= offset
.u
.LowPart
;
4177 S(U(ovl
)).OffsetHigh
= offset
.u
.HighPart
;
4179 ovl
.InternalHigh
= -1;
4182 SetLastError(0xdeadbeef);
4183 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4184 ok(!ret
, "ReadFile should fail\n");
4185 ret
= GetLastError();
4186 ok(ret
== ERROR_IO_PENDING
|| ret
== ERROR_HANDLE_EOF
/* before Vista */, "expected ERROR_IO_PENDING or ERROR_HANDLE_EOF, got %d\n", ret
);
4187 ok(bytes
== 0, "bytes %u\n", bytes
);
4189 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4190 ok(off
== 0, "expected 0, got %u\n", off
);
4192 if (ret
== ERROR_IO_PENDING
)
4195 SetLastError(0xdeadbeef);
4196 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4197 ok(!ret
, "GetOverlappedResult should report FALSE\n");
4198 ok(GetLastError() == ERROR_HANDLE_EOF
, "expected ERROR_HANDLE_EOF, got %d\n", GetLastError());
4199 ok(bytes
== 0, "expected 0, read %u\n", bytes
);
4200 ok((NTSTATUS
)ovl
.Internal
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", ovl
.Internal
);
4201 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
4204 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4205 ok(off
== 0, "expected 0, got %u\n", off
);
4207 offset
.QuadPart
= sizeof(contents
);
4208 S(U(ovl
)).Offset
= offset
.u
.LowPart
;
4209 S(U(ovl
)).OffsetHigh
= offset
.u
.HighPart
;
4211 ovl
.InternalHigh
= -1;
4214 SetLastError(0xdeadbeef);
4215 ret
= ReadFile(hfile
, buf
, 0, &bytes
, &ovl
);
4216 /* ReadFile return value depends on Windows version and testing it is not practical */
4218 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4219 ret
= GetLastError();
4220 ok(bytes
== 0, "bytes %u\n", bytes
);
4222 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4223 ok(off
== 0, "expected 0, got %u\n", off
);
4225 if (ret
== ERROR_IO_PENDING
)
4228 SetLastError(0xdeadbeef);
4229 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4230 ok(ret
, "GetOverlappedResult should report TRUE\n");
4231 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
4232 ok(bytes
== 0, "expected 0, read %u\n", bytes
);
4233 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4234 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
4237 offset
.QuadPart
= sizeof(contents
);
4238 S(U(ovl
)).Offset
= offset
.u
.LowPart
;
4239 S(U(ovl
)).OffsetHigh
= offset
.u
.HighPart
;
4241 ovl
.InternalHigh
= -1;
4244 SetLastError(0xdeadbeef);
4245 ret
= ReadFile(hfile
, NULL
, 0, &bytes
, &ovl
);
4246 /* ReadFile return value depends on Windows version and testing it is not practical */
4248 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4249 ret
= GetLastError();
4250 ok(bytes
== 0, "bytes %u\n", bytes
);
4252 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4253 ok(off
== 0, "expected 0, got %u\n", off
);
4255 if (ret
== ERROR_IO_PENDING
)
4258 SetLastError(0xdeadbeef);
4259 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4260 ok(ret
, "GetOverlappedResult should report TRUE\n");
4261 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
4262 ok(bytes
== 0, "expected 0, read %u\n", bytes
);
4263 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4264 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
4268 iob
.Information
= -1;
4269 offset
.QuadPart
= sizeof(contents
);
4270 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4271 if (status
== STATUS_PENDING
)
4273 ret
= WaitForSingleObject(hfile
, 3000);
4274 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4275 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
4276 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
4280 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
4281 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4282 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
4285 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4286 ok(off
== 0, "expected 0, got %u\n", off
);
4289 iob
.Information
= -1;
4290 offset
.QuadPart
= sizeof(contents
);
4291 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, &offset
, NULL
);
4292 if (status
== STATUS_PENDING
)
4294 ret
= WaitForSingleObject(hfile
, 3000);
4295 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4296 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4297 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
4301 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", status
);
4302 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4303 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
4306 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4307 ok(off
== 0, "expected 0, got %u\n", off
);
4309 S(U(ovl
)).Offset
= 0;
4310 S(U(ovl
)).OffsetHigh
= 0;
4312 ovl
.InternalHigh
= -1;
4315 SetLastError(0xdeadbeef);
4316 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4317 /* ReadFile return value depends on Windows version and testing it is not practical */
4320 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4321 ok(bytes
== 0, "bytes %u\n", bytes
);
4323 else ok(bytes
== 14, "bytes %u\n", bytes
);
4324 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4325 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4327 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4328 ok(off
== 0, "expected 0, got %u\n", off
);
4331 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4332 ok(ret
, "GetOverlappedResult error %d\n", GetLastError());
4333 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
4334 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4335 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4336 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
4338 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4339 ok(off
== 0, "expected 0, got %u\n", off
);
4341 SetFilePointer(hfile
, sizeof(contents
) - 4, NULL
, FILE_BEGIN
);
4342 SetEndOfFile(hfile
);
4343 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
4346 iob
.Information
= -1;
4347 offset
.QuadPart
= (LONGLONG
)-1 /* FILE_WRITE_TO_END_OF_FILE */;
4348 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, "DCBA", 4, &offset
, NULL
);
4349 ok(status
== STATUS_PENDING
|| status
== STATUS_SUCCESS
/* before Vista */, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status
);
4350 if (status
== STATUS_PENDING
)
4352 ret
= WaitForSingleObject(hfile
, 3000);
4353 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4355 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4356 ok(iob
.Information
== 4, "expected 4, got %lu\n", iob
.Information
);
4358 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4359 ok(off
== 0, "expected 0, got %u\n", off
);
4362 iob
.Information
= -1;
4363 offset
.QuadPart
= 0;
4364 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4365 ok(status
== STATUS_PENDING
|| status
== STATUS_SUCCESS
, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status
);
4366 if (status
== STATUS_PENDING
)
4368 ret
= WaitForSingleObject(hfile
, 3000);
4369 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4371 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4372 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %lu\n", iob
.Information
);
4374 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4375 ok(off
== 0, "expected 0, got %u\n", off
);
4377 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
4378 ok(!memcmp(buf
+ sizeof(contents
) - 4, "DCBA", 4), "file contents mismatch\n");
4380 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4381 ok(off
== 0, "expected 0, got %u\n", off
);
4383 S(U(ovl
)).Offset
= sizeof(contents
) - 4;
4384 S(U(ovl
)).OffsetHigh
= 0;
4386 ovl
.InternalHigh
= -1;
4389 SetLastError(0xdeadbeef);
4390 ret
= WriteFile(hfile
, "ABCD", 4, &bytes
, &ovl
);
4391 /* WriteFile return value depends on Windows version and testing it is not practical */
4394 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4395 ok(bytes
== 0, "bytes %u\n", bytes
);
4396 ret
= WaitForSingleObject(hfile
, 3000);
4397 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4399 else ok(bytes
== 4, "bytes %u\n", bytes
);
4400 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4401 ok(ovl
.InternalHigh
== 4, "expected 4, got %lu\n", ovl
.InternalHigh
);
4403 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4404 ok(off
== 0, "expected 0, got %u\n", off
);
4407 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4408 ok(ret
, "GetOverlappedResult error %d\n", GetLastError());
4409 ok(bytes
== 4, "bytes %u\n", bytes
);
4410 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4411 ok(ovl
.InternalHigh
== 4, "expected 4, got %lu\n", ovl
.InternalHigh
);
4413 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4414 ok(off
== 0, "expected 0, got %u\n", off
);
4416 S(U(ovl
)).Offset
= 0;
4417 S(U(ovl
)).OffsetHigh
= 0;
4419 ovl
.InternalHigh
= -1;
4422 SetLastError(0xdeadbeef);
4423 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4424 /* ReadFile return value depends on Windows version and testing it is not practical */
4427 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4428 ok(bytes
== 0, "bytes %u\n", bytes
);
4429 ret
= WaitForSingleObject(hfile
, 3000);
4430 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4432 else ok(bytes
== 14, "bytes %u\n", bytes
);
4433 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4434 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4436 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4437 ok(off
== 0, "expected 0, got %u\n", off
);
4440 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4441 ok(ret
, "GetOverlappedResult error %d\n", GetLastError());
4442 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
4443 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4444 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4445 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
4446 ok(!memcmp(buf
+ sizeof(contents
) - 4, "ABCD", 4), "file contents mismatch\n");
4448 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4449 ok(off
== 0, "expected 0, got %u\n", off
);
4455 static void test_ioctl(void)
4457 HANDLE event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
4458 FILE_PIPE_PEEK_BUFFER peek_buf
;
4459 IO_STATUS_BLOCK iosb
;
4463 file
= create_temp_file(FILE_FLAG_OVERLAPPED
);
4464 ok(file
!= INVALID_HANDLE_VALUE
, "could not create temp file\n");
4467 status
= pNtFsControlFile(file
, event
, NULL
, NULL
, &iosb
, 0xdeadbeef, 0, 0, 0, 0);
4469 ok(status
== STATUS_INVALID_DEVICE_REQUEST
, "NtFsControlFile returned %x\n", status
);
4470 ok(!is_signaled(event
), "event is signaled\n");
4472 status
= pNtFsControlFile(file
, (HANDLE
)0xdeadbeef, NULL
, NULL
, &iosb
, 0xdeadbeef, 0, 0, 0, 0);
4473 ok(status
== STATUS_INVALID_HANDLE
, "NtFsControlFile returned %x\n", status
);
4475 memset(&iosb
, 0x55, sizeof(iosb
));
4476 status
= pNtFsControlFile(file
, NULL
, NULL
, NULL
, &iosb
, FSCTL_PIPE_PEEK
, NULL
, 0,
4477 &peek_buf
, sizeof(peek_buf
));
4479 ok(status
== STATUS_INVALID_DEVICE_REQUEST
, "NtFsControlFile failed: %x\n", status
);
4480 ok(iosb
.Status
== 0x55555555, "iosb.Status = %x\n", iosb
.Status
);
4486 static void test_flush_buffers_file(void)
4488 char path
[MAX_PATH
], buffer
[MAX_PATH
];
4489 HANDLE hfile
, hfileread
;
4491 IO_STATUS_BLOCK io_status_block
;
4493 GetTempPathA(MAX_PATH
, path
);
4494 GetTempFileNameA(path
, "foo", 0, buffer
);
4495 hfile
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
, FILE_SHARE_READ
, NULL
, CREATE_ALWAYS
,
4496 FILE_ATTRIBUTE_NORMAL
, 0);
4497 ok(hfile
!= INVALID_HANDLE_VALUE
, "failed to create temp file.\n" );
4499 hfileread
= CreateFileA(buffer
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
4500 OPEN_EXISTING
, 0, NULL
);
4501 ok(hfileread
!= INVALID_HANDLE_VALUE
, "could not open temp file, error %d.\n", GetLastError());
4503 status
= pNtFlushBuffersFile(hfile
, NULL
);
4504 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#x.\n", status
);
4506 status
= pNtFlushBuffersFile(hfile
, (IO_STATUS_BLOCK
*)0xdeadbeaf);
4507 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#x.\n", status
);
4509 status
= pNtFlushBuffersFile(hfile
, &io_status_block
);
4510 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x.\n", status
);
4512 status
= pNtFlushBuffersFile(hfileread
, &io_status_block
);
4513 ok(status
== STATUS_ACCESS_DENIED
, "expected STATUS_ACCESS_DENIED, got %#x.\n", status
);
4515 status
= pNtFlushBuffersFile(NULL
, &io_status_block
);
4516 ok(status
== STATUS_INVALID_HANDLE
, "expected STATUS_INVALID_HANDLE, got %#x.\n", status
);
4518 CloseHandle(hfileread
);
4520 hfile
= CreateFileA(buffer
, FILE_APPEND_DATA
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
4521 OPEN_EXISTING
, 0, NULL
);
4522 ok(hfile
!= INVALID_HANDLE_VALUE
, "could not open temp file, error %d.\n", GetLastError());
4524 status
= pNtFlushBuffersFile(hfile
, &io_status_block
);
4525 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x.\n", status
);
4528 DeleteFileA(buffer
);
4533 HMODULE hkernel32
= GetModuleHandleA("kernel32.dll");
4534 HMODULE hntdll
= GetModuleHandleA("ntdll.dll");
4537 skip("not running on NT, skipping test\n");
4541 pGetVolumePathNameW
= (void *)GetProcAddress(hkernel32
, "GetVolumePathNameW");
4542 pGetSystemWow64DirectoryW
= (void *)GetProcAddress(hkernel32
, "GetSystemWow64DirectoryW");
4544 pRtlFreeUnicodeString
= (void *)GetProcAddress(hntdll
, "RtlFreeUnicodeString");
4545 pRtlInitUnicodeString
= (void *)GetProcAddress(hntdll
, "RtlInitUnicodeString");
4546 pRtlDosPathNameToNtPathName_U
= (void *)GetProcAddress(hntdll
, "RtlDosPathNameToNtPathName_U");
4547 pRtlWow64EnableFsRedirectionEx
= (void *)GetProcAddress(hntdll
, "RtlWow64EnableFsRedirectionEx");
4548 pNtCreateMailslotFile
= (void *)GetProcAddress(hntdll
, "NtCreateMailslotFile");
4549 pNtCreateFile
= (void *)GetProcAddress(hntdll
, "NtCreateFile");
4550 pNtOpenFile
= (void *)GetProcAddress(hntdll
, "NtOpenFile");
4551 pNtDeleteFile
= (void *)GetProcAddress(hntdll
, "NtDeleteFile");
4552 pNtReadFile
= (void *)GetProcAddress(hntdll
, "NtReadFile");
4553 pNtWriteFile
= (void *)GetProcAddress(hntdll
, "NtWriteFile");
4554 pNtCancelIoFile
= (void *)GetProcAddress(hntdll
, "NtCancelIoFile");
4555 pNtCancelIoFileEx
= (void *)GetProcAddress(hntdll
, "NtCancelIoFileEx");
4556 pNtClose
= (void *)GetProcAddress(hntdll
, "NtClose");
4557 pNtFsControlFile
= (void *)GetProcAddress(hntdll
, "NtFsControlFile");
4558 pNtCreateIoCompletion
= (void *)GetProcAddress(hntdll
, "NtCreateIoCompletion");
4559 pNtOpenIoCompletion
= (void *)GetProcAddress(hntdll
, "NtOpenIoCompletion");
4560 pNtQueryIoCompletion
= (void *)GetProcAddress(hntdll
, "NtQueryIoCompletion");
4561 pNtRemoveIoCompletion
= (void *)GetProcAddress(hntdll
, "NtRemoveIoCompletion");
4562 pNtRemoveIoCompletionEx
= (void *)GetProcAddress(hntdll
, "NtRemoveIoCompletionEx");
4563 pNtSetIoCompletion
= (void *)GetProcAddress(hntdll
, "NtSetIoCompletion");
4564 pNtSetInformationFile
= (void *)GetProcAddress(hntdll
, "NtSetInformationFile");
4565 pNtQueryAttributesFile
= (void *)GetProcAddress(hntdll
, "NtQueryAttributesFile");
4566 pNtQueryInformationFile
= (void *)GetProcAddress(hntdll
, "NtQueryInformationFile");
4567 pNtQueryDirectoryFile
= (void *)GetProcAddress(hntdll
, "NtQueryDirectoryFile");
4568 pNtQueryVolumeInformationFile
= (void *)GetProcAddress(hntdll
, "NtQueryVolumeInformationFile");
4569 pNtQueryFullAttributesFile
= (void *)GetProcAddress(hntdll
, "NtQueryFullAttributesFile");
4570 pNtFlushBuffersFile
= (void *)GetProcAddress(hntdll
, "NtFlushBuffersFile");
4573 test_NtCreateFile();
4580 test_set_io_completion();
4581 test_file_io_completion();
4582 test_file_basic_information();
4583 test_file_all_information();
4584 test_file_both_information();
4585 test_file_name_information();
4586 test_file_full_size_information();
4587 test_file_all_name_information();
4588 test_file_rename_information();
4589 test_file_link_information();
4590 test_file_disposition_information();
4591 test_file_completion_information();
4592 test_file_id_information();
4593 test_file_access_information();
4594 test_query_volume_information_file();
4595 test_query_attribute_information_file();
4597 test_flush_buffers_file();