1 /* Unit test suite for Ntdll file functions
3 * Copyright 2007 Jeff Latimer
4 * Copyright 2007 Andrey Turkin
5 * Copyright 2008 Jeff Zaroyko
6 * Copyright 2011 Dmitry Timoshkov
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * We use function pointers here as there is no import library for NTDLL on
31 /* Define WIN32_NO_STATUS so MSVC does not give us duplicate macro
32 * definition errors when we get to winnt.h
34 #define WIN32_NO_STATUS
36 #include "wine/test.h"
37 #include "wine/winternl.h"
39 #include "wine/winioctl.h"
42 typedef struct _REPARSE_DATA_BUFFER
{
44 USHORT ReparseDataLength
;
46 _ANONYMOUS_UNION
union {
48 USHORT SubstituteNameOffset
;
49 USHORT SubstituteNameLength
;
50 USHORT PrintNameOffset
;
51 USHORT PrintNameLength
;
54 } SymbolicLinkReparseBuffer
;
56 USHORT SubstituteNameOffset
;
57 USHORT SubstituteNameLength
;
58 USHORT PrintNameOffset
;
59 USHORT PrintNameLength
;
61 } MountPointReparseBuffer
;
64 } GenericReparseBuffer
;
66 } REPARSE_DATA_BUFFER
, *PREPARSE_DATA_BUFFER
;
68 #ifndef IO_COMPLETION_ALL_ACCESS
69 #define IO_COMPLETION_ALL_ACCESS 0x001F0003
72 static BOOL (WINAPI
* pGetVolumePathNameW
)(LPCWSTR
, LPWSTR
, DWORD
);
73 static UINT (WINAPI
*pGetSystemWow64DirectoryW
)( LPWSTR
, UINT
);
75 static VOID (WINAPI
*pRtlFreeUnicodeString
)( PUNICODE_STRING
);
76 static VOID (WINAPI
*pRtlInitUnicodeString
)( PUNICODE_STRING
, LPCWSTR
);
77 static BOOL (WINAPI
*pRtlDosPathNameToNtPathName_U
)( LPCWSTR
, PUNICODE_STRING
, PWSTR
*, CURDIR
* );
78 static NTSTATUS (WINAPI
*pRtlWow64EnableFsRedirectionEx
)( ULONG
, ULONG
* );
80 static NTSTATUS (WINAPI
*pNtCreateMailslotFile
)( PHANDLE
, ULONG
, POBJECT_ATTRIBUTES
, PIO_STATUS_BLOCK
,
81 ULONG
, ULONG
, ULONG
, PLARGE_INTEGER
);
82 static NTSTATUS (WINAPI
*pNtCreateFile
)(PHANDLE
,ACCESS_MASK
,POBJECT_ATTRIBUTES
,PIO_STATUS_BLOCK
,PLARGE_INTEGER
,ULONG
,ULONG
,ULONG
,ULONG
,PVOID
,ULONG
);
83 static NTSTATUS (WINAPI
*pNtOpenFile
)(PHANDLE
,ACCESS_MASK
,POBJECT_ATTRIBUTES
,PIO_STATUS_BLOCK
,ULONG
,ULONG
);
84 static NTSTATUS (WINAPI
*pNtDeleteFile
)(POBJECT_ATTRIBUTES ObjectAttributes
);
85 static NTSTATUS (WINAPI
*pNtReadFile
)(HANDLE hFile
, HANDLE hEvent
,
86 PIO_APC_ROUTINE apc
, void* apc_user
,
87 PIO_STATUS_BLOCK io_status
, void* buffer
, ULONG length
,
88 PLARGE_INTEGER offset
, PULONG key
);
89 static NTSTATUS (WINAPI
*pNtWriteFile
)(HANDLE hFile
, HANDLE hEvent
,
90 PIO_APC_ROUTINE apc
, void* apc_user
,
91 PIO_STATUS_BLOCK io_status
,
92 const void* buffer
, ULONG length
,
93 PLARGE_INTEGER offset
, PULONG key
);
94 static NTSTATUS (WINAPI
*pNtCancelIoFile
)(HANDLE hFile
, PIO_STATUS_BLOCK io_status
);
95 static NTSTATUS (WINAPI
*pNtCancelIoFileEx
)(HANDLE hFile
, PIO_STATUS_BLOCK iosb
, PIO_STATUS_BLOCK io_status
);
96 static NTSTATUS (WINAPI
*pNtClose
)( PHANDLE
);
97 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
);
99 static NTSTATUS (WINAPI
*pNtCreateIoCompletion
)(PHANDLE
, ACCESS_MASK
, POBJECT_ATTRIBUTES
, ULONG
);
100 static NTSTATUS (WINAPI
*pNtOpenIoCompletion
)(PHANDLE
, ACCESS_MASK
, POBJECT_ATTRIBUTES
);
101 static NTSTATUS (WINAPI
*pNtQueryIoCompletion
)(HANDLE
, IO_COMPLETION_INFORMATION_CLASS
, PVOID
, ULONG
, PULONG
);
102 static NTSTATUS (WINAPI
*pNtRemoveIoCompletion
)(HANDLE
, PULONG_PTR
, PULONG_PTR
, PIO_STATUS_BLOCK
, PLARGE_INTEGER
);
103 static NTSTATUS (WINAPI
*pNtSetIoCompletion
)(HANDLE
, ULONG_PTR
, ULONG_PTR
, NTSTATUS
, SIZE_T
);
104 static NTSTATUS (WINAPI
*pNtSetInformationFile
)(HANDLE
, PIO_STATUS_BLOCK
, PVOID
, ULONG
, FILE_INFORMATION_CLASS
);
105 static NTSTATUS (WINAPI
*pNtQueryInformationFile
)(HANDLE
, PIO_STATUS_BLOCK
, PVOID
, ULONG
, FILE_INFORMATION_CLASS
);
106 static NTSTATUS (WINAPI
*pNtQueryDirectoryFile
)(HANDLE
,HANDLE
,PIO_APC_ROUTINE
,PVOID
,PIO_STATUS_BLOCK
,
107 PVOID
,ULONG
,FILE_INFORMATION_CLASS
,BOOLEAN
,PUNICODE_STRING
,BOOLEAN
);
108 static NTSTATUS (WINAPI
*pNtQueryVolumeInformationFile
)(HANDLE
,PIO_STATUS_BLOCK
,PVOID
,ULONG
,FS_INFORMATION_CLASS
);
109 static NTSTATUS (WINAPI
*pNtQueryFullAttributesFile
)(const OBJECT_ATTRIBUTES
*, FILE_NETWORK_OPEN_INFORMATION
*);
110 static NTSTATUS (WINAPI
*pNtFlushBuffersFile
)(HANDLE
, IO_STATUS_BLOCK
*);
111 static NTSTATUS (WINAPI
*pNtQueryEaFile
)(HANDLE
,PIO_STATUS_BLOCK
,PVOID
,ULONG
,BOOLEAN
,PVOID
,ULONG
,PULONG
,BOOLEAN
);
113 static inline BOOL
is_signaled( HANDLE obj
)
115 return WaitForSingleObject( obj
, 0 ) == WAIT_OBJECT_0
;
118 #define TEST_BUF_LEN 3
120 static HANDLE
create_temp_file( ULONG flags
)
122 char path
[MAX_PATH
], buffer
[MAX_PATH
];
125 GetTempPathA( MAX_PATH
, path
);
126 GetTempFileNameA( path
, "foo", 0, buffer
);
127 handle
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
128 flags
| FILE_FLAG_DELETE_ON_CLOSE
, 0);
129 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
130 return (handle
== INVALID_HANDLE_VALUE
) ? 0 : handle
;
133 #define CVALUE_FIRST 0xfffabbcc
134 #define CKEY_FIRST 0x1030341
135 #define CKEY_SECOND 0x132E46
137 static ULONG_PTR completionKey
;
138 static IO_STATUS_BLOCK ioSb
;
139 static ULONG_PTR completionValue
;
141 static ULONG
get_pending_msgs(HANDLE h
)
146 res
= pNtQueryIoCompletion( h
, IoCompletionBasicInformation
, &a
, sizeof(a
), &req
);
147 ok( res
== STATUS_SUCCESS
, "NtQueryIoCompletion failed: %x\n", res
);
148 if (res
!= STATUS_SUCCESS
) return -1;
149 ok( req
== sizeof(a
), "Unexpected response size: %x\n", req
);
153 static BOOL
get_msg(HANDLE h
)
155 LARGE_INTEGER timeout
= {{-10000000*3}};
156 DWORD res
= pNtRemoveIoCompletion( h
, &completionKey
, &completionValue
, &ioSb
, &timeout
);
157 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletion failed: %x\n", res
);
158 if (res
!= STATUS_SUCCESS
)
160 completionKey
= completionValue
= 0;
161 memset(&ioSb
, 0, sizeof(ioSb
));
168 static void WINAPI
apc( void *arg
, IO_STATUS_BLOCK
*iosb
, ULONG reserved
)
172 trace( "apc called block %p iosb.status %x iosb.info %lu\n",
173 iosb
, U(*iosb
).Status
, iosb
->Information
);
175 ok( !reserved
, "reserved is not 0: %x\n", reserved
);
178 static void create_file_test(void)
180 static const WCHAR notepadW
[] = {'n','o','t','e','p','a','d','.','e','x','e',0};
181 static const WCHAR systemrootW
[] = {'\\','S','y','s','t','e','m','R','o','o','t',
182 '\\','f','a','i','l','i','n','g',0};
183 static const WCHAR systemrootExplorerW
[] = {'\\','S','y','s','t','e','m','R','o','o','t',
184 '\\','e','x','p','l','o','r','e','r','.','e','x','e',0};
185 static const WCHAR questionmarkInvalidNameW
[] = {'a','f','i','l','e','?',0};
186 static const WCHAR pipeInvalidNameW
[] = {'a','|','b',0};
187 static const WCHAR pathInvalidNtW
[] = {'\\','\\','?','\\',0};
188 static const WCHAR pathInvalidNt2W
[] = {'\\','?','?','\\',0};
189 static const WCHAR pathInvalidDosW
[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0};
190 static const char testdata
[] = "Hello World";
191 static const WCHAR sepW
[] = {'\\',0};
192 FILE_NETWORK_OPEN_INFORMATION info
;
195 WCHAR path
[MAX_PATH
], temp
[MAX_PATH
];
196 OBJECT_ATTRIBUTES attr
;
198 UNICODE_STRING nameW
;
199 LARGE_INTEGER offset
;
203 GetCurrentDirectoryW( MAX_PATH
, path
);
204 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
205 attr
.Length
= sizeof(attr
);
206 attr
.RootDirectory
= 0;
207 attr
.ObjectName
= &nameW
;
208 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
209 attr
.SecurityDescriptor
= NULL
;
210 attr
.SecurityQualityOfService
= NULL
;
212 /* try various open modes and options on directories */
213 status
= pNtCreateFile( &dir
, GENERIC_READ
|GENERIC_WRITE
, &attr
, &io
, NULL
, 0,
214 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, FILE_DIRECTORY_FILE
, NULL
, 0 );
215 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
217 U(io
).Status
= 0xdeadbeef;
219 status
= pNtReadFile( dir
, NULL
, NULL
, NULL
, &io
, buf
, sizeof(buf
), &offset
, NULL
);
220 ok( status
== STATUS_INVALID_DEVICE_REQUEST
|| status
== STATUS_PENDING
, "NtReadFile error %08x\n", status
);
221 if (status
== STATUS_PENDING
)
223 ret
= WaitForSingleObject( dir
, 1000 );
224 ok( ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %u\n", ret
);
225 ok( U(io
).Status
== STATUS_INVALID_DEVICE_REQUEST
,
226 "expected STATUS_INVALID_DEVICE_REQUEST, got %08x\n", U(io
).Status
);
229 U(io
).Status
= 0xdeadbeef;
231 status
= pNtWriteFile( dir
, NULL
, NULL
, NULL
, &io
, testdata
, sizeof(testdata
), &offset
, NULL
);
233 ok( status
== STATUS_INVALID_DEVICE_REQUEST
|| status
== STATUS_PENDING
, "NtWriteFile error %08x\n", status
);
234 if (status
== STATUS_PENDING
)
236 ret
= WaitForSingleObject( dir
, 1000 );
237 ok( ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %u\n", ret
);
238 ok( U(io
).Status
== STATUS_INVALID_DEVICE_REQUEST
,
239 "expected STATUS_INVALID_DEVICE_REQUEST, got %08x\n", U(io
).Status
);
244 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
245 FILE_CREATE
, FILE_DIRECTORY_FILE
, 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 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
250 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, NULL
, 0 );
251 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
254 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
255 FILE_SUPERSEDE
, FILE_DIRECTORY_FILE
, NULL
, 0 );
256 ok( status
== STATUS_INVALID_PARAMETER
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
258 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
259 FILE_OVERWRITE
, FILE_DIRECTORY_FILE
, NULL
, 0 );
260 ok( status
== STATUS_INVALID_PARAMETER
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
262 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
263 FILE_OVERWRITE_IF
, FILE_DIRECTORY_FILE
, NULL
, 0 );
264 ok( status
== STATUS_INVALID_PARAMETER
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
266 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
267 FILE_OPEN
, 0, NULL
, 0 );
268 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
271 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
272 FILE_CREATE
, 0, NULL
, 0 );
273 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
274 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
276 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
277 FILE_OPEN_IF
, 0, NULL
, 0 );
278 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
281 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
282 FILE_SUPERSEDE
, 0, NULL
, 0 );
283 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
284 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
286 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
287 FILE_OVERWRITE
, 0, NULL
, 0 );
288 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
289 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
291 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
292 FILE_OVERWRITE_IF
, 0, NULL
, 0 );
293 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
294 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
296 pRtlFreeUnicodeString( &nameW
);
298 pRtlInitUnicodeString( &nameW
, systemrootW
);
299 attr
.Length
= sizeof(attr
);
300 attr
.RootDirectory
= NULL
;
301 attr
.ObjectName
= &nameW
;
302 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
303 attr
.SecurityDescriptor
= NULL
;
304 attr
.SecurityQualityOfService
= NULL
;
306 status
= pNtCreateFile( &dir
, FILE_APPEND_DATA
, &attr
, &io
, NULL
, FILE_ATTRIBUTE_NORMAL
, 0,
307 FILE_OPEN_IF
, FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
309 ok( status
== STATUS_INVALID_PARAMETER
,
310 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
312 /* Invalid chars in file/dirnames */
313 pRtlDosPathNameToNtPathName_U(questionmarkInvalidNameW
, &nameW
, NULL
, NULL
);
314 attr
.ObjectName
= &nameW
;
315 status
= pNtCreateFile(&dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
316 FILE_SHARE_READ
, FILE_CREATE
,
317 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
318 ok(status
== STATUS_OBJECT_NAME_INVALID
,
319 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
321 status
= pNtCreateFile(&file
, GENERIC_WRITE
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
323 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
324 ok(status
== STATUS_OBJECT_NAME_INVALID
,
325 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
326 pRtlFreeUnicodeString(&nameW
);
328 pRtlDosPathNameToNtPathName_U(pipeInvalidNameW
, &nameW
, NULL
, NULL
);
329 attr
.ObjectName
= &nameW
;
330 status
= pNtCreateFile(&dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
331 FILE_SHARE_READ
, FILE_CREATE
,
332 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
333 ok(status
== STATUS_OBJECT_NAME_INVALID
,
334 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
336 status
= pNtCreateFile(&file
, GENERIC_WRITE
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
338 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
339 ok(status
== STATUS_OBJECT_NAME_INVALID
,
340 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
341 pRtlFreeUnicodeString(&nameW
);
343 pRtlInitUnicodeString( &nameW
, pathInvalidNtW
);
344 status
= pNtCreateFile( &dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
345 FILE_SHARE_READ
, FILE_CREATE
,
346 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
347 ok( status
== STATUS_OBJECT_NAME_INVALID
,
348 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
350 status
= pNtQueryFullAttributesFile( &attr
, &info
);
351 todo_wine
ok( status
== STATUS_OBJECT_NAME_INVALID
,
352 "query %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
354 pRtlInitUnicodeString( &nameW
, pathInvalidNt2W
);
355 status
= pNtCreateFile( &dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
356 FILE_SHARE_READ
, FILE_CREATE
,
357 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
358 ok( status
== STATUS_OBJECT_NAME_INVALID
,
359 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
361 status
= pNtQueryFullAttributesFile( &attr
, &info
);
362 ok( status
== STATUS_OBJECT_NAME_INVALID
,
363 "query %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
365 pRtlInitUnicodeString( &nameW
, pathInvalidDosW
);
366 status
= pNtCreateFile( &dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
367 FILE_SHARE_READ
, FILE_CREATE
,
368 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
369 ok( status
== STATUS_OBJECT_NAME_INVALID
,
370 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
372 status
= pNtQueryFullAttributesFile( &attr
, &info
);
373 ok( status
== STATUS_OBJECT_NAME_INVALID
,
374 "query %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
376 GetWindowsDirectoryW( path
, MAX_PATH
);
378 ok( QueryDosDeviceW( path
, temp
, MAX_PATH
),
379 "QueryDosDeviceW failed with error %u\n", GetLastError() );
380 lstrcatW( temp
, sepW
);
381 lstrcatW( temp
, path
+3 );
382 lstrcatW( temp
, sepW
);
383 lstrcatW( temp
, notepadW
);
385 pRtlInitUnicodeString( &nameW
, temp
);
386 status
= pNtQueryFullAttributesFile( &attr
, &info
);
387 ok( status
== STATUS_SUCCESS
,
388 "query %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
390 pRtlInitUnicodeString( &nameW
, systemrootExplorerW
);
391 status
= pNtQueryFullAttributesFile( &attr
, &info
);
392 ok( status
== STATUS_SUCCESS
,
393 "query %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
396 static void open_file_test(void)
398 static const char testdata
[] = "Hello World";
399 static WCHAR fooW
[] = {'f','o','o',0};
401 HANDLE dir
, root
, handle
, file
;
402 WCHAR path
[MAX_PATH
], tmpfile
[MAX_PATH
];
404 OBJECT_ATTRIBUTES attr
;
406 UNICODE_STRING nameW
;
408 BOOL ret
, restart
= TRUE
;
411 len
= GetWindowsDirectoryW( path
, MAX_PATH
);
412 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
413 attr
.Length
= sizeof(attr
);
414 attr
.RootDirectory
= 0;
415 attr
.ObjectName
= &nameW
;
416 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
417 attr
.SecurityDescriptor
= NULL
;
418 attr
.SecurityQualityOfService
= NULL
;
419 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
420 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
421 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
422 pRtlFreeUnicodeString( &nameW
);
424 path
[3] = 0; /* root of the drive */
425 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
426 status
= pNtOpenFile( &root
, GENERIC_READ
, &attr
, &io
,
427 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
428 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
429 pRtlFreeUnicodeString( &nameW
);
431 /* test opening system dir with RootDirectory set to windows dir */
432 GetSystemDirectoryW( path
, MAX_PATH
);
433 while (path
[len
] == '\\') len
++;
434 nameW
.Buffer
= path
+ len
;
435 nameW
.Length
= lstrlenW(path
+ len
) * sizeof(WCHAR
);
436 attr
.RootDirectory
= dir
;
437 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
438 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
439 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
440 CloseHandle( handle
);
442 /* try uppercase name */
443 for (i
= len
; path
[i
]; i
++) if (path
[i
] >= 'a' && path
[i
] <= 'z') path
[i
] -= 'a' - 'A';
444 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
445 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
446 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
447 CloseHandle( handle
);
449 /* try with leading backslash */
451 nameW
.Length
+= sizeof(WCHAR
);
452 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
453 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
454 ok( status
== STATUS_INVALID_PARAMETER
||
455 status
== STATUS_OBJECT_NAME_INVALID
||
456 status
== STATUS_OBJECT_PATH_SYNTAX_BAD
,
457 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
458 if (!status
) CloseHandle( handle
);
460 /* try with empty name */
462 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
463 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
464 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
465 CloseHandle( handle
);
467 /* try open by file id */
469 while (!pNtQueryDirectoryFile( dir
, NULL
, NULL
, NULL
, &io
, data
, sizeof(data
),
470 FileIdBothDirectoryInformation
, TRUE
, NULL
, restart
))
472 FILE_ID_BOTH_DIRECTORY_INFORMATION
*info
= (FILE_ID_BOTH_DIRECTORY_INFORMATION
*)data
;
476 if (!info
->FileId
.QuadPart
) continue;
478 nameW
.Buffer
= (WCHAR
*)&info
->FileId
;
479 nameW
.Length
= sizeof(info
->FileId
);
480 info
->FileName
[info
->FileNameLength
/sizeof(WCHAR
)] = 0;
481 attr
.RootDirectory
= dir
;
482 /* We skip 'open' files by not specifying FILE_SHARE_WRITE */
483 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
485 FILE_OPEN_BY_FILE_ID
|
486 ((info
->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) ? FILE_DIRECTORY_FILE
: 0) );
487 ok( status
== STATUS_SUCCESS
|| status
== STATUS_ACCESS_DENIED
|| status
== STATUS_NOT_IMPLEMENTED
|| status
== STATUS_SHARING_VIOLATION
,
488 "open %s failed %x\n", wine_dbgstr_w(info
->FileName
), status
);
489 if (status
== STATUS_NOT_IMPLEMENTED
)
491 win_skip( "FILE_OPEN_BY_FILE_ID not supported\n" );
494 if (status
== STATUS_SHARING_VIOLATION
)
495 trace( "%s is currently open\n", wine_dbgstr_w(info
->FileName
) );
498 BYTE buf
[sizeof(FILE_ALL_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
)];
500 if (!pNtQueryInformationFile( handle
, &io
, buf
, sizeof(buf
), FileAllInformation
))
502 FILE_ALL_INFORMATION
*fai
= (FILE_ALL_INFORMATION
*)buf
;
504 /* check that it's the same file/directory */
506 /* don't check the size for directories */
507 if (!(info
->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
508 ok( info
->EndOfFile
.QuadPart
== fai
->StandardInformation
.EndOfFile
.QuadPart
,
509 "mismatched file size for %s\n", wine_dbgstr_w(info
->FileName
));
511 ok( info
->CreationTime
.QuadPart
== fai
->BasicInformation
.CreationTime
.QuadPart
,
512 "mismatched creation time for %s\n", wine_dbgstr_w(info
->FileName
));
514 CloseHandle( handle
);
516 /* try same thing from drive root */
517 attr
.RootDirectory
= root
;
518 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
519 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
520 FILE_OPEN_BY_FILE_ID
|
521 ((info
->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) ? FILE_DIRECTORY_FILE
: 0) );
522 ok( status
== STATUS_SUCCESS
|| status
== STATUS_NOT_IMPLEMENTED
,
523 "open %s failed %x\n", wine_dbgstr_w(info
->FileName
), status
);
524 if (!status
) CloseHandle( handle
);
531 GetTempPathW( MAX_PATH
, path
);
532 GetTempFileNameW( path
, fooW
, 0, tmpfile
);
533 pRtlDosPathNameToNtPathName_U( tmpfile
, &nameW
, NULL
, NULL
);
535 file
= CreateFileW( tmpfile
, FILE_WRITE_DATA
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
536 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError() );
537 numbytes
= 0xdeadbeef;
538 ret
= WriteFile( file
, testdata
, sizeof(testdata
) - 1, &numbytes
, NULL
);
539 ok( ret
, "WriteFile failed with error %u\n", GetLastError() );
540 ok( numbytes
== sizeof(testdata
) - 1, "failed to write all data\n" );
543 attr
.Length
= sizeof(attr
);
544 attr
.RootDirectory
= 0;
545 attr
.ObjectName
= &nameW
;
546 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
547 attr
.SecurityDescriptor
= NULL
;
548 attr
.SecurityQualityOfService
= NULL
;
549 status
= pNtOpenFile( &file
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
550 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
);
551 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
552 pRtlFreeUnicodeString( &nameW
);
554 numbytes
= 0xdeadbeef;
555 memset( data
, 0, sizeof(data
) );
556 ret
= ReadFile( file
, data
, sizeof(data
), &numbytes
, NULL
);
557 ok( ret
, "ReadFile failed with error %u\n", GetLastError() );
558 ok( numbytes
== sizeof(testdata
) - 1, "failed to read all data\n" );
559 ok( !memcmp( data
, testdata
, sizeof(testdata
) - 1 ), "testdata doesn't match\n" );
561 nameW
.Length
= sizeof(fooW
) - sizeof(WCHAR
);
563 attr
.RootDirectory
= file
;
564 attr
.ObjectName
= &nameW
;
565 status
= pNtOpenFile( &root
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
566 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
);
567 ok( status
== STATUS_OBJECT_PATH_NOT_FOUND
,
568 "expected STATUS_OBJECT_PATH_NOT_FOUND, got %08x\n", status
);
572 attr
.RootDirectory
= file
;
573 attr
.ObjectName
= &nameW
;
574 status
= pNtOpenFile( &root
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
575 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
);
576 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(tmpfile
), status
);
578 numbytes
= SetFilePointer( file
, 0, 0, FILE_CURRENT
);
579 ok( numbytes
== sizeof(testdata
) - 1, "SetFilePointer returned %u\n", numbytes
);
580 numbytes
= SetFilePointer( root
, 0, 0, FILE_CURRENT
);
581 ok( numbytes
== 0, "SetFilePointer returned %u\n", numbytes
);
583 numbytes
= 0xdeadbeef;
584 memset( data
, 0, sizeof(data
) );
585 ret
= ReadFile( root
, data
, sizeof(data
), &numbytes
, NULL
);
586 ok( ret
, "ReadFile failed with error %u\n", GetLastError() );
587 ok( numbytes
== sizeof(testdata
) - 1, "failed to read all data\n" );
588 ok( !memcmp( data
, testdata
, sizeof(testdata
) - 1 ), "testdata doesn't match\n" );
590 numbytes
= SetFilePointer( file
, 0, 0, FILE_CURRENT
);
591 ok( numbytes
== sizeof(testdata
) - 1, "SetFilePointer returned %u\n", numbytes
);
592 numbytes
= SetFilePointer( root
, 0, 0, FILE_CURRENT
);
593 ok( numbytes
== sizeof(testdata
) - 1, "SetFilePointer returned %u\n", numbytes
);
597 DeleteFileW( tmpfile
);
600 static void delete_file_test(void)
603 OBJECT_ATTRIBUTES attr
;
604 UNICODE_STRING nameW
;
605 WCHAR pathW
[MAX_PATH
];
606 WCHAR pathsubW
[MAX_PATH
];
607 static const WCHAR testdirW
[] = {'n','t','d','e','l','e','t','e','f','i','l','e',0};
608 static const WCHAR subdirW
[] = {'\\','s','u','b',0};
610 ret
= GetTempPathW(MAX_PATH
, pathW
);
613 ok(0, "couldn't get temp dir\n");
616 if (ret
+ sizeof(testdirW
)/sizeof(WCHAR
)-1 + sizeof(subdirW
)/sizeof(WCHAR
)-1 >= MAX_PATH
)
618 ok(0, "MAX_PATH exceeded in constructing paths\n");
622 lstrcatW(pathW
, testdirW
);
623 lstrcpyW(pathsubW
, pathW
);
624 lstrcatW(pathsubW
, subdirW
);
626 ret
= CreateDirectoryW(pathW
, NULL
);
627 ok(ret
== TRUE
, "couldn't create directory ntdeletefile\n");
628 if (!pRtlDosPathNameToNtPathName_U(pathW
, &nameW
, NULL
, NULL
))
630 ok(0,"RtlDosPathNametoNtPathName_U failed\n");
634 attr
.Length
= sizeof(attr
);
635 attr
.RootDirectory
= 0;
636 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
637 attr
.ObjectName
= &nameW
;
638 attr
.SecurityDescriptor
= NULL
;
639 attr
.SecurityQualityOfService
= NULL
;
641 /* test NtDeleteFile on an empty directory */
642 ret
= pNtDeleteFile(&attr
);
643 ok(ret
== STATUS_SUCCESS
, "NtDeleteFile should succeed in removing an empty directory\n");
644 ret
= RemoveDirectoryW(pathW
);
645 ok(ret
== FALSE
, "expected to fail removing directory, NtDeleteFile should have removed it\n");
647 /* test NtDeleteFile on a non-empty directory */
648 ret
= CreateDirectoryW(pathW
, NULL
);
649 ok(ret
== TRUE
, "couldn't create directory ntdeletefile ?!\n");
650 ret
= CreateDirectoryW(pathsubW
, NULL
);
651 ok(ret
== TRUE
, "couldn't create directory subdir\n");
652 ret
= pNtDeleteFile(&attr
);
653 ok(ret
== STATUS_SUCCESS
, "expected NtDeleteFile to ret STATUS_SUCCESS\n");
654 ret
= RemoveDirectoryW(pathsubW
);
655 ok(ret
== TRUE
, "expected to remove directory ntdeletefile\\sub\n");
656 ret
= RemoveDirectoryW(pathW
);
657 ok(ret
== TRUE
, "expected to remove directory ntdeletefile, NtDeleteFile failed.\n");
659 pRtlFreeUnicodeString( &nameW
);
662 static void read_file_test(void)
664 const char text
[] = "foobar";
666 IO_STATUS_BLOCK iosb
;
670 LARGE_INTEGER offset
;
671 HANDLE event
= CreateEventA( NULL
, TRUE
, FALSE
, NULL
);
673 if (!(handle
= create_temp_file( FILE_FLAG_OVERLAPPED
))) return;
675 U(iosb
).Status
= 0xdeadbabe;
676 iosb
.Information
= 0xdeadbeef;
679 status
= pNtWriteFile( handle
, event
, apc
, &apc_count
, &iosb
, text
, strlen(text
), &offset
, NULL
);
680 ok( status
== STATUS_SUCCESS
|| status
== STATUS_PENDING
, "wrong status %x\n", status
);
681 if (status
== STATUS_PENDING
) WaitForSingleObject( event
, 1000 );
682 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
683 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
684 ok( is_signaled( event
), "event is not signaled\n" );
685 ok( !apc_count
, "apc was called\n" );
686 SleepEx( 1, TRUE
); /* alertable sleep */
687 ok( apc_count
== 1, "apc was not called\n" );
690 U(iosb
).Status
= 0xdeadbabe;
691 iosb
.Information
= 0xdeadbeef;
694 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, strlen(text
) + 10, &offset
, NULL
);
695 ok( status
== STATUS_SUCCESS
||
696 status
== STATUS_PENDING
, /* vista */
697 "wrong status %x\n", status
);
698 if (status
== STATUS_PENDING
) WaitForSingleObject( event
, 1000 );
699 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
700 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
701 ok( is_signaled( event
), "event is not signaled\n" );
702 ok( !apc_count
, "apc was called\n" );
703 SleepEx( 1, TRUE
); /* alertable sleep */
704 ok( apc_count
== 1, "apc was not called\n" );
706 /* read beyond eof */
708 U(iosb
).Status
= 0xdeadbabe;
709 iosb
.Information
= 0xdeadbeef;
710 offset
.QuadPart
= strlen(text
) + 2;
711 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, &offset
, NULL
);
712 ok(status
== STATUS_PENDING
|| status
== STATUS_END_OF_FILE
/* before Vista */, "expected STATUS_PENDING or STATUS_END_OF_FILE, got %#x\n", status
);
713 if (status
== STATUS_PENDING
) /* vista */
715 WaitForSingleObject( event
, 1000 );
716 ok( U(iosb
).Status
== STATUS_END_OF_FILE
, "wrong status %x\n", U(iosb
).Status
);
717 ok( iosb
.Information
== 0, "wrong info %lu\n", iosb
.Information
);
718 ok( is_signaled( event
), "event is not signaled\n" );
719 ok( !apc_count
, "apc was called\n" );
720 SleepEx( 1, TRUE
); /* alertable sleep */
721 ok( apc_count
== 1, "apc was not called\n" );
723 CloseHandle( handle
);
725 /* now a non-overlapped file */
726 if (!(handle
= create_temp_file(0))) return;
728 U(iosb
).Status
= 0xdeadbabe;
729 iosb
.Information
= 0xdeadbeef;
731 status
= pNtWriteFile( handle
, event
, apc
, &apc_count
, &iosb
, text
, strlen(text
), &offset
, NULL
);
732 ok( status
== STATUS_END_OF_FILE
||
733 status
== STATUS_SUCCESS
||
734 status
== STATUS_PENDING
, /* vista */
735 "wrong status %x\n", status
);
736 if (status
== STATUS_PENDING
) WaitForSingleObject( event
, 1000 );
737 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
738 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
739 ok( is_signaled( event
), "event is not signaled\n" );
740 ok( !apc_count
, "apc was called\n" );
741 SleepEx( 1, TRUE
); /* alertable sleep */
742 ok( apc_count
== 1, "apc was not called\n" );
745 U(iosb
).Status
= 0xdeadbabe;
746 iosb
.Information
= 0xdeadbeef;
749 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, strlen(text
) + 10, &offset
, NULL
);
750 ok( status
== STATUS_SUCCESS
, "wrong status %x\n", status
);
751 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
752 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
753 ok( is_signaled( event
), "event is not signaled\n" );
754 ok( !apc_count
, "apc was called\n" );
755 SleepEx( 1, TRUE
); /* alertable sleep */
756 todo_wine
ok( !apc_count
, "apc was called\n" );
758 /* read beyond eof */
760 U(iosb
).Status
= 0xdeadbabe;
761 iosb
.Information
= 0xdeadbeef;
762 offset
.QuadPart
= strlen(text
) + 2;
764 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, &offset
, NULL
);
765 ok( status
== STATUS_END_OF_FILE
, "wrong status %x\n", status
);
766 ok( U(iosb
).Status
== STATUS_END_OF_FILE
, "wrong status %x\n", U(iosb
).Status
);
767 ok( iosb
.Information
== 0, "wrong info %lu\n", iosb
.Information
);
768 ok( is_signaled( event
), "event is not signaled\n" );
769 ok( !apc_count
, "apc was called\n" );
770 SleepEx( 1, TRUE
); /* alertable sleep */
771 ok( !apc_count
, "apc was called\n" );
773 CloseHandle( handle
);
775 CloseHandle( event
);
778 static void append_file_test(void)
780 static const char text
[6] = "foobar";
783 IO_STATUS_BLOCK iosb
;
784 LARGE_INTEGER offset
;
785 char path
[MAX_PATH
], buffer
[MAX_PATH
], buf
[16];
788 GetTempPathA( MAX_PATH
, path
);
789 GetTempFileNameA( path
, "foo", 0, buffer
);
791 handle
= CreateFileA(buffer
, FILE_WRITE_DATA
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
792 ok(handle
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError());
795 iosb
.Information
= -1;
796 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
, 2, NULL
, NULL
);
797 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
798 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
799 ok(iosb
.Information
== 2, "expected 2, got %lu\n", iosb
.Information
);
803 /* It is possible to open a file with only FILE_APPEND_DATA access flags.
804 It matches the O_WRONLY|O_APPEND open() posix behavior */
805 handle
= CreateFileA(buffer
, FILE_APPEND_DATA
, 0, NULL
, OPEN_EXISTING
, 0, 0);
806 ok(handle
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError());
809 iosb
.Information
= -1;
811 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
+ 2, 2, &offset
, NULL
);
812 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
813 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
814 ok(iosb
.Information
== 2, "expected 2, got %lu\n", iosb
.Information
);
816 ret
= SetFilePointer(handle
, 0, NULL
, FILE_CURRENT
);
817 ok(ret
== 4, "expected 4, got %u\n", ret
);
820 iosb
.Information
= -1;
822 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
+ 4, 2, &offset
, NULL
);
823 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
824 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
825 ok(iosb
.Information
== 2, "expected 2, got %lu\n", iosb
.Information
);
827 ret
= SetFilePointer(handle
, 0, NULL
, FILE_CURRENT
);
828 ok(ret
== 6, "expected 6, got %u\n", ret
);
832 handle
= CreateFileA(buffer
, FILE_READ_DATA
| FILE_WRITE_DATA
| FILE_APPEND_DATA
, 0, NULL
, OPEN_EXISTING
, 0, 0);
833 ok(handle
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError());
835 memset(buf
, 0, sizeof(buf
));
837 iosb
.Information
= -1;
839 status
= pNtReadFile(handle
, 0, NULL
, NULL
, &iosb
, buf
, sizeof(buf
), &offset
, NULL
);
840 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
841 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
842 ok(iosb
.Information
== 6, "expected 6, got %lu\n", iosb
.Information
);
844 ok(memcmp(buf
, text
, 6) == 0, "wrong file contents: %s\n", buf
);
847 iosb
.Information
= -1;
849 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
+ 3, 3, &offset
, NULL
);
850 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
851 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
852 ok(iosb
.Information
== 3, "expected 3, got %lu\n", iosb
.Information
);
854 memset(buf
, 0, sizeof(buf
));
856 iosb
.Information
= -1;
858 status
= pNtReadFile(handle
, 0, NULL
, NULL
, &iosb
, buf
, sizeof(buf
), &offset
, NULL
);
859 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
860 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
861 ok(iosb
.Information
== 6, "expected 6, got %lu\n", iosb
.Information
);
863 ok(memcmp(buf
, "barbar", 6) == 0, "wrong file contents: %s\n", buf
);
869 static void nt_mailslot_test(void)
872 ACCESS_MASK DesiredAccess
;
873 OBJECT_ATTRIBUTES attr
;
877 ULONG MaxMessageSize
;
878 LARGE_INTEGER TimeOut
;
879 IO_STATUS_BLOCK IoStatusBlock
;
882 WCHAR buffer1
[] = { '\\','?','?','\\','M','A','I','L','S','L','O','T','\\',
883 'R',':','\\','F','R','E','D','\0' };
885 TimeOut
.QuadPart
= -1;
887 pRtlInitUnicodeString(&str
, buffer1
);
888 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
889 CreateOptions
= MailslotQuota
= MaxMessageSize
= 0;
890 DesiredAccess
= GENERIC_READ
;
893 * Check for NULL pointer handling
895 rc
= pNtCreateMailslotFile(NULL
, DesiredAccess
,
896 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
898 ok( rc
== STATUS_ACCESS_VIOLATION
||
899 rc
== STATUS_INVALID_PARAMETER
, /* win2k3 */
900 "rc = %x not STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER\n", rc
);
903 * Test to see if the Timeout can be NULL
905 hslot
= (HANDLE
)0xdeadbeef;
906 rc
= pNtCreateMailslotFile(&hslot
, DesiredAccess
,
907 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
909 ok( rc
== STATUS_SUCCESS
||
910 rc
== STATUS_INVALID_PARAMETER
, /* win2k3 */
911 "rc = %x not STATUS_SUCCESS or STATUS_INVALID_PARAMETER\n", rc
);
912 ok( hslot
!= 0, "Handle is invalid\n");
914 if ( rc
== STATUS_SUCCESS
) pNtClose(hslot
);
919 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
920 rc
= pNtCreateMailslotFile(&hslot
, DesiredAccess
,
921 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
923 ok( rc
== STATUS_SUCCESS
, "Create MailslotFile failed rc = %x\n", rc
);
924 ok( hslot
!= 0, "Handle is invalid\n");
926 rc
= pNtClose(hslot
);
927 ok( rc
== STATUS_SUCCESS
, "NtClose failed\n");
930 static void test_iocp_setcompletion(HANDLE h
)
936 if (sizeof(size
) > 4) size
|= (ULONGLONG
)0x12345678 << 32;
938 res
= pNtSetIoCompletion( h
, CKEY_FIRST
, CVALUE_FIRST
, STATUS_INVALID_DEVICE_REQUEST
, size
);
939 ok( res
== STATUS_SUCCESS
, "NtSetIoCompletion failed: %x\n", res
);
941 count
= get_pending_msgs(h
);
942 ok( count
== 1, "Unexpected msg count: %d\n", count
);
946 ok( completionKey
== CKEY_FIRST
, "Invalid completion key: %lx\n", completionKey
);
947 ok( ioSb
.Information
== size
, "Invalid ioSb.Information: %lu\n", ioSb
.Information
);
948 ok( U(ioSb
).Status
== STATUS_INVALID_DEVICE_REQUEST
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
949 ok( completionValue
== CVALUE_FIRST
, "Invalid completion value: %lx\n", completionValue
);
952 count
= get_pending_msgs(h
);
953 ok( !count
, "Unexpected msg count: %d\n", count
);
956 static void test_iocp_fileio(HANDLE h
)
958 static const char pipe_name
[] = "\\\\.\\pipe\\iocompletiontestnamedpipe";
960 IO_STATUS_BLOCK iosb
;
961 FILE_COMPLETION_INFORMATION fci
= {h
, CKEY_SECOND
};
962 HANDLE hPipeSrv
, hPipeClt
;
965 hPipeSrv
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
, PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
, 4, 1024, 1024, 1000, NULL
);
966 ok( hPipeSrv
!= INVALID_HANDLE_VALUE
, "Cannot create named pipe\n" );
967 if (hPipeSrv
!= INVALID_HANDLE_VALUE
)
969 hPipeClt
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
970 ok( hPipeClt
!= INVALID_HANDLE_VALUE
, "Cannot connect to pipe\n" );
971 if (hPipeClt
!= INVALID_HANDLE_VALUE
)
973 U(iosb
).Status
= 0xdeadbeef;
974 res
= pNtSetInformationFile( hPipeSrv
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
975 ok( res
== STATUS_INVALID_PARAMETER
, "Unexpected NtSetInformationFile on non-overlapped handle: %x\n", res
);
976 ok( U(iosb
).Status
== STATUS_INVALID_PARAMETER
/* 98 */ || U(iosb
).Status
== 0xdeadbeef /* NT4+ */,
977 "Unexpected iosb.Status on non-overlapped handle: %x\n", U(iosb
).Status
);
978 CloseHandle(hPipeClt
);
980 CloseHandle( hPipeSrv
);
983 hPipeSrv
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
| FILE_FLAG_OVERLAPPED
, PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
, 4, 1024, 1024, 1000, NULL
);
984 ok( hPipeSrv
!= INVALID_HANDLE_VALUE
, "Cannot create named pipe\n" );
985 if (hPipeSrv
== INVALID_HANDLE_VALUE
)
988 hPipeClt
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
989 ok( hPipeClt
!= INVALID_HANDLE_VALUE
, "Cannot connect to pipe\n" );
990 if (hPipeClt
!= INVALID_HANDLE_VALUE
)
993 BYTE send_buf
[TEST_BUF_LEN
], recv_buf
[TEST_BUF_LEN
];
997 U(iosb
).Status
= 0xdeadbeef;
998 res
= pNtSetInformationFile( hPipeSrv
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
999 ok( res
== STATUS_SUCCESS
, "NtSetInformationFile failed: %x\n", res
);
1000 ok( U(iosb
).Status
== STATUS_SUCCESS
, "iosb.Status invalid: %x\n", U(iosb
).Status
);
1002 memset( send_buf
, 0, TEST_BUF_LEN
);
1003 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1004 count
= get_pending_msgs(h
);
1005 ok( !count
, "Unexpected msg count: %ld\n", count
);
1006 ReadFile( hPipeSrv
, recv_buf
, TEST_BUF_LEN
, &read
, &o
);
1007 count
= get_pending_msgs(h
);
1008 ok( !count
, "Unexpected msg count: %ld\n", count
);
1009 WriteFile( hPipeClt
, send_buf
, TEST_BUF_LEN
, &read
, NULL
);
1013 ok( completionKey
== CKEY_SECOND
, "Invalid completion key: %lx\n", completionKey
);
1014 ok( ioSb
.Information
== 3, "Invalid ioSb.Information: %ld\n", ioSb
.Information
);
1015 ok( U(ioSb
).Status
== STATUS_SUCCESS
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
1016 ok( completionValue
== (ULONG_PTR
)&o
, "Invalid completion value: %lx\n", completionValue
);
1017 ok( !memcmp( send_buf
, recv_buf
, TEST_BUF_LEN
), "Receive buffer (%x %x %x) did not match send buffer (%x %x %x)\n", recv_buf
[0], recv_buf
[1], recv_buf
[2], send_buf
[0], send_buf
[1], send_buf
[2] );
1019 count
= get_pending_msgs(h
);
1020 ok( !count
, "Unexpected msg count: %ld\n", count
);
1022 memset( send_buf
, 0, TEST_BUF_LEN
);
1023 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1024 WriteFile( hPipeClt
, send_buf
, 2, &read
, NULL
);
1025 count
= get_pending_msgs(h
);
1026 ok( !count
, "Unexpected msg count: %ld\n", count
);
1027 ReadFile( hPipeSrv
, recv_buf
, 2, &read
, &o
);
1028 count
= get_pending_msgs(h
);
1029 ok( count
== 1, "Unexpected msg count: %ld\n", count
);
1032 ok( completionKey
== CKEY_SECOND
, "Invalid completion key: %lx\n", completionKey
);
1033 ok( ioSb
.Information
== 2, "Invalid ioSb.Information: %ld\n", ioSb
.Information
);
1034 ok( U(ioSb
).Status
== STATUS_SUCCESS
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
1035 ok( completionValue
== (ULONG_PTR
)&o
, "Invalid completion value: %lx\n", completionValue
);
1036 ok( !memcmp( send_buf
, recv_buf
, 2 ), "Receive buffer (%x %x) did not match send buffer (%x %x)\n", recv_buf
[0], recv_buf
[1], send_buf
[0], send_buf
[1] );
1039 ReadFile( hPipeSrv
, recv_buf
, TEST_BUF_LEN
, &read
, &o
);
1040 CloseHandle( hPipeSrv
);
1041 count
= get_pending_msgs(h
);
1042 ok( count
== 1, "Unexpected msg count: %ld\n", count
);
1045 ok( completionKey
== CKEY_SECOND
, "Invalid completion key: %lx\n", completionKey
);
1046 ok( ioSb
.Information
== 0, "Invalid ioSb.Information: %ld\n", ioSb
.Information
);
1047 /* wine sends wrong status here */
1048 ok( U(ioSb
).Status
== STATUS_PIPE_BROKEN
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
1049 ok( completionValue
== (ULONG_PTR
)&o
, "Invalid completion value: %lx\n", completionValue
);
1053 CloseHandle( hPipeClt
);
1055 /* test associating a completion port with a handle after an async is queued */
1056 hPipeSrv
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
| FILE_FLAG_OVERLAPPED
, PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
, 4, 1024, 1024, 1000, NULL
);
1057 ok( hPipeSrv
!= INVALID_HANDLE_VALUE
, "Cannot create named pipe\n" );
1058 if (hPipeSrv
== INVALID_HANDLE_VALUE
)
1060 hPipeClt
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
1061 ok( hPipeClt
!= INVALID_HANDLE_VALUE
, "Cannot connect to pipe\n" );
1062 if (hPipeClt
!= INVALID_HANDLE_VALUE
)
1064 OVERLAPPED o
= {0,};
1065 BYTE send_buf
[TEST_BUF_LEN
], recv_buf
[TEST_BUF_LEN
];
1070 memset( send_buf
, 0, TEST_BUF_LEN
);
1071 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1072 count
= get_pending_msgs(h
);
1073 ok( !count
, "Unexpected msg count: %ld\n", count
);
1074 ReadFile( hPipeSrv
, recv_buf
, TEST_BUF_LEN
, &read
, &o
);
1076 U(iosb
).Status
= 0xdeadbeef;
1077 res
= pNtSetInformationFile( hPipeSrv
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
1078 ok( res
== STATUS_SUCCESS
, "NtSetInformationFile failed: %x\n", res
);
1079 ok( U(iosb
).Status
== STATUS_SUCCESS
, "iosb.Status invalid: %x\n", U(iosb
).Status
);
1080 count
= get_pending_msgs(h
);
1081 ok( !count
, "Unexpected msg count: %ld\n", count
);
1083 WriteFile( hPipeClt
, send_buf
, TEST_BUF_LEN
, &read
, NULL
);
1087 ok( completionKey
== CKEY_SECOND
, "Invalid completion key: %lx\n", completionKey
);
1088 ok( ioSb
.Information
== 3, "Invalid ioSb.Information: %ld\n", ioSb
.Information
);
1089 ok( U(ioSb
).Status
== STATUS_SUCCESS
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
1090 ok( completionValue
== (ULONG_PTR
)&o
, "Invalid completion value: %lx\n", completionValue
);
1091 ok( !memcmp( send_buf
, recv_buf
, TEST_BUF_LEN
), "Receive buffer (%x %x %x) did not match send buffer (%x %x %x)\n", recv_buf
[0], recv_buf
[1], recv_buf
[2], send_buf
[0], send_buf
[1], send_buf
[2] );
1093 count
= get_pending_msgs(h
);
1094 ok( !count
, "Unexpected msg count: %ld\n", count
);
1096 /* using APCs on handle with associated completion port is not allowed */
1097 res
= NtReadFile( hPipeSrv
, NULL
, apc
, &apc_count
, &iosb
, recv_buf
, sizeof(recv_buf
), NULL
, NULL
);
1098 ok(res
== STATUS_INVALID_PARAMETER
, "NtReadFile returned %x\n", res
);
1101 CloseHandle( hPipeSrv
);
1102 CloseHandle( hPipeClt
);
1104 /* test associating a completion port with a handle after an async using APC is queued */
1105 hPipeSrv
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
| FILE_FLAG_OVERLAPPED
, PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
, 4, 1024, 1024, 1000, NULL
);
1106 ok( hPipeSrv
!= INVALID_HANDLE_VALUE
, "Cannot create named pipe\n" );
1107 if (hPipeSrv
== INVALID_HANDLE_VALUE
)
1109 hPipeClt
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
1110 ok( hPipeClt
!= INVALID_HANDLE_VALUE
, "Cannot connect to pipe\n" );
1111 if (hPipeClt
!= INVALID_HANDLE_VALUE
)
1113 BYTE send_buf
[TEST_BUF_LEN
], recv_buf
[TEST_BUF_LEN
];
1118 memset( send_buf
, 0, TEST_BUF_LEN
);
1119 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1120 count
= get_pending_msgs(h
);
1121 ok( !count
, "Unexpected msg count: %ld\n", count
);
1123 res
= NtReadFile( hPipeSrv
, NULL
, apc
, &apc_count
, &iosb
, recv_buf
, sizeof(recv_buf
), NULL
, NULL
);
1124 ok(res
== STATUS_PENDING
, "NtReadFile returned %x\n", res
);
1126 U(iosb
).Status
= 0xdeadbeef;
1127 res
= pNtSetInformationFile( hPipeSrv
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
1128 ok( res
== STATUS_SUCCESS
, "NtSetInformationFile failed: %x\n", res
);
1129 ok( U(iosb
).Status
== STATUS_SUCCESS
, "iosb.Status invalid: %x\n", U(iosb
).Status
);
1130 count
= get_pending_msgs(h
);
1131 ok( !count
, "Unexpected msg count: %ld\n", count
);
1133 WriteFile( hPipeClt
, send_buf
, TEST_BUF_LEN
, &read
, NULL
);
1135 ok(!apc_count
, "apc_count = %u\n", apc_count
);
1136 count
= get_pending_msgs(h
);
1137 ok( !count
, "Unexpected msg count: %ld\n", count
);
1139 SleepEx(1, TRUE
); /* alertable sleep */
1140 ok(apc_count
== 1, "apc was not called\n");
1141 count
= get_pending_msgs(h
);
1142 ok( !count
, "Unexpected msg count: %ld\n", count
);
1144 /* using APCs on handle with associated completion port is not allowed */
1145 res
= NtReadFile( hPipeSrv
, NULL
, apc
, &apc_count
, &iosb
, recv_buf
, sizeof(recv_buf
), NULL
, NULL
);
1146 ok(res
== STATUS_INVALID_PARAMETER
, "NtReadFile returned %x\n", res
);
1149 CloseHandle( hPipeSrv
);
1150 CloseHandle( hPipeClt
);
1153 static void test_file_full_size_information(void)
1156 FILE_FS_FULL_SIZE_INFORMATION ffsi
;
1157 FILE_FS_SIZE_INFORMATION fsi
;
1161 if(!(h
= create_temp_file(0))) return ;
1163 memset(&ffsi
,0,sizeof(ffsi
));
1164 memset(&fsi
,0,sizeof(fsi
));
1166 /* Assume No Quota Settings configured on Wine Testbot */
1167 res
= pNtQueryVolumeInformationFile(h
, &io
, &ffsi
, sizeof ffsi
, FileFsFullSizeInformation
);
1168 ok(res
== STATUS_SUCCESS
, "cannot get attributes, res %x\n", res
);
1169 res
= pNtQueryVolumeInformationFile(h
, &io
, &fsi
, sizeof fsi
, FileFsSizeInformation
);
1170 ok(res
== STATUS_SUCCESS
, "cannot get attributes, res %x\n", res
);
1172 /* Test for FileFsSizeInformation */
1173 ok(fsi
.TotalAllocationUnits
.QuadPart
> 0,
1174 "[fsi] TotalAllocationUnits expected positive, got 0x%s\n",
1175 wine_dbgstr_longlong(fsi
.TotalAllocationUnits
.QuadPart
));
1176 ok(fsi
.AvailableAllocationUnits
.QuadPart
> 0,
1177 "[fsi] AvailableAllocationUnits expected positive, got 0x%s\n",
1178 wine_dbgstr_longlong(fsi
.AvailableAllocationUnits
.QuadPart
));
1180 /* Assume file system is NTFS */
1181 ok(fsi
.BytesPerSector
== 512, "[fsi] BytesPerSector expected 512, got %d\n",fsi
.BytesPerSector
);
1182 ok(fsi
.SectorsPerAllocationUnit
== 8, "[fsi] SectorsPerAllocationUnit expected 8, got %d\n",fsi
.SectorsPerAllocationUnit
);
1184 ok(ffsi
.TotalAllocationUnits
.QuadPart
> 0,
1185 "[ffsi] TotalAllocationUnits expected positive, got negative value 0x%s\n",
1186 wine_dbgstr_longlong(ffsi
.TotalAllocationUnits
.QuadPart
));
1187 ok(ffsi
.CallerAvailableAllocationUnits
.QuadPart
> 0,
1188 "[ffsi] CallerAvailableAllocationUnits expected positive, got negative value 0x%s\n",
1189 wine_dbgstr_longlong(ffsi
.CallerAvailableAllocationUnits
.QuadPart
));
1190 ok(ffsi
.ActualAvailableAllocationUnits
.QuadPart
> 0,
1191 "[ffsi] ActualAvailableAllocationUnits expected positive, got negative value 0x%s\n",
1192 wine_dbgstr_longlong(ffsi
.ActualAvailableAllocationUnits
.QuadPart
));
1193 ok(ffsi
.TotalAllocationUnits
.QuadPart
== fsi
.TotalAllocationUnits
.QuadPart
,
1194 "[ffsi] TotalAllocationUnits error fsi:0x%s, ffsi:0x%s\n",
1195 wine_dbgstr_longlong(fsi
.TotalAllocationUnits
.QuadPart
),
1196 wine_dbgstr_longlong(ffsi
.TotalAllocationUnits
.QuadPart
));
1197 ok(ffsi
.CallerAvailableAllocationUnits
.QuadPart
== fsi
.AvailableAllocationUnits
.QuadPart
,
1198 "[ffsi] CallerAvailableAllocationUnits error fsi:0x%s, ffsi: 0x%s\n",
1199 wine_dbgstr_longlong(fsi
.AvailableAllocationUnits
.QuadPart
),
1200 wine_dbgstr_longlong(ffsi
.CallerAvailableAllocationUnits
.QuadPart
));
1202 /* Assume file system is NTFS */
1203 ok(ffsi
.BytesPerSector
== 512, "[ffsi] BytesPerSector expected 512, got %d\n",ffsi
.BytesPerSector
);
1204 ok(ffsi
.SectorsPerAllocationUnit
== 8, "[ffsi] SectorsPerAllocationUnit expected 8, got %d\n",ffsi
.SectorsPerAllocationUnit
);
1209 static void test_file_basic_information(void)
1212 FILE_BASIC_INFORMATION fbi
;
1215 int attrib_mask
= FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_NORMAL
;
1217 if (!(h
= create_temp_file(0))) return;
1219 /* Check default first */
1220 memset(&fbi
, 0, sizeof(fbi
));
1221 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1222 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1223 ok ( (fbi
.FileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) == FILE_ATTRIBUTE_ARCHIVE
,
1224 "attribute %x not expected\n", fbi
.FileAttributes
);
1227 /* Clear fbi to avoid setting times */
1228 memset(&fbi
, 0, sizeof(fbi
));
1229 fbi
.FileAttributes
= FILE_ATTRIBUTE_SYSTEM
;
1230 U(io
).Status
= 0xdeadbeef;
1231 res
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1232 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, NtSetInformationFile returned %x\n", res
);
1233 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status is %x\n", U(io
).Status
);
1235 memset(&fbi
, 0, sizeof(fbi
));
1236 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1237 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1238 ok ( (fbi
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_SYSTEM
, "attribute %x not FILE_ATTRIBUTE_SYSTEM (ok in old linux without xattr)\n", fbi
.FileAttributes
);
1241 memset(&fbi
, 0, sizeof(fbi
));
1242 fbi
.FileAttributes
= FILE_ATTRIBUTE_HIDDEN
;
1243 U(io
).Status
= 0xdeadbeef;
1244 res
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1245 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, NtSetInformationFile returned %x\n", res
);
1246 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status is %x\n", U(io
).Status
);
1248 memset(&fbi
, 0, sizeof(fbi
));
1249 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1250 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1251 ok ( (fbi
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_HIDDEN
, "attribute %x not FILE_ATTRIBUTE_HIDDEN (ok in old linux without xattr)\n", fbi
.FileAttributes
);
1253 /* Check NORMAL last of all (to make sure we can clear attributes) */
1254 memset(&fbi
, 0, sizeof(fbi
));
1255 fbi
.FileAttributes
= FILE_ATTRIBUTE_NORMAL
;
1256 U(io
).Status
= 0xdeadbeef;
1257 res
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1258 ok ( res
== STATUS_SUCCESS
, "can't set normal attribute, NtSetInformationFile returned %x\n", res
);
1259 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set normal attribute, io.Status is %x\n", U(io
).Status
);
1261 memset(&fbi
, 0, sizeof(fbi
));
1262 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1263 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1264 todo_wine
ok ( (fbi
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_NORMAL
, "attribute %x not 0\n", fbi
.FileAttributes
);
1269 static void test_file_all_information(void)
1272 /* FileAllInformation, like FileNameInformation, has a variable-length pathname
1273 * buffer at the end. Vista objects with STATUS_BUFFER_OVERFLOW if you
1274 * don't leave enough room there.
1277 FILE_ALL_INFORMATION fai
;
1282 int attrib_mask
= FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_NORMAL
;
1284 if (!(h
= create_temp_file(0))) return;
1286 /* Check default first */
1287 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1288 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1289 ok ( (fai_buf
.fai
.BasicInformation
.FileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) == FILE_ATTRIBUTE_ARCHIVE
,
1290 "attribute %x not expected\n", fai_buf
.fai
.BasicInformation
.FileAttributes
);
1293 /* Clear fbi to avoid setting times */
1294 memset(&fai_buf
.fai
.BasicInformation
, 0, sizeof(fai_buf
.fai
.BasicInformation
));
1295 fai_buf
.fai
.BasicInformation
.FileAttributes
= FILE_ATTRIBUTE_SYSTEM
;
1296 U(io
).Status
= 0xdeadbeef;
1297 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1298 ok ( res
== STATUS_INVALID_INFO_CLASS
|| broken(res
== STATUS_NOT_IMPLEMENTED
), "shouldn't be able to set FileAllInformation, res %x\n", res
);
1299 todo_wine
ok ( U(io
).Status
== 0xdeadbeef, "shouldn't be able to set FileAllInformation, io.Status is %x\n", U(io
).Status
);
1300 U(io
).Status
= 0xdeadbeef;
1301 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
.BasicInformation
, sizeof fai_buf
.fai
.BasicInformation
, FileBasicInformation
);
1302 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, res: %x\n", res
);
1303 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status: %x\n", U(io
).Status
);
1305 memset(&fai_buf
.fai
, 0, sizeof(fai_buf
.fai
));
1306 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1307 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1308 ok ( (fai_buf
.fai
.BasicInformation
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_SYSTEM
, "attribute %x not FILE_ATTRIBUTE_SYSTEM (ok in old linux without xattr)\n", fai_buf
.fai
.BasicInformation
.FileAttributes
);
1311 memset(&fai_buf
.fai
.BasicInformation
, 0, sizeof(fai_buf
.fai
.BasicInformation
));
1312 fai_buf
.fai
.BasicInformation
.FileAttributes
= FILE_ATTRIBUTE_HIDDEN
;
1313 U(io
).Status
= 0xdeadbeef;
1314 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
.BasicInformation
, sizeof fai_buf
.fai
.BasicInformation
, FileBasicInformation
);
1315 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, res: %x\n", res
);
1316 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status: %x\n", U(io
).Status
);
1318 memset(&fai_buf
.fai
, 0, sizeof(fai_buf
.fai
));
1319 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1320 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1321 ok ( (fai_buf
.fai
.BasicInformation
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_HIDDEN
, "attribute %x not FILE_ATTRIBUTE_HIDDEN (ok in old linux without xattr)\n", fai_buf
.fai
.BasicInformation
.FileAttributes
);
1323 /* Check NORMAL last of all (to make sure we can clear attributes) */
1324 memset(&fai_buf
.fai
.BasicInformation
, 0, sizeof(fai_buf
.fai
.BasicInformation
));
1325 fai_buf
.fai
.BasicInformation
.FileAttributes
= FILE_ATTRIBUTE_NORMAL
;
1326 U(io
).Status
= 0xdeadbeef;
1327 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
.BasicInformation
, sizeof fai_buf
.fai
.BasicInformation
, FileBasicInformation
);
1328 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, res: %x\n", res
);
1329 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status: %x\n", U(io
).Status
);
1331 memset(&fai_buf
.fai
, 0, sizeof(fai_buf
.fai
));
1332 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1333 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1334 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
);
1339 static void delete_object( WCHAR
*path
)
1341 BOOL ret
= DeleteFileW( path
);
1342 ok( ret
|| GetLastError() == ERROR_FILE_NOT_FOUND
|| GetLastError() == ERROR_ACCESS_DENIED
,
1343 "DeleteFileW failed with %u\n", GetLastError() );
1344 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1346 ret
= RemoveDirectoryW( path
);
1347 ok( ret
, "RemoveDirectoryW failed with %u\n", GetLastError() );
1351 static void test_file_rename_information(void)
1353 static const WCHAR foo_txtW
[] = {'\\','f','o','o','.','t','x','t',0};
1354 static const WCHAR fooW
[] = {'f','o','o',0};
1355 WCHAR tmp_path
[MAX_PATH
], oldpath
[MAX_PATH
+ 16], newpath
[MAX_PATH
+ 16], *filename
, *p
;
1356 FILE_RENAME_INFORMATION
*fri
;
1357 FILE_NAME_INFORMATION
*fni
;
1358 BOOL success
, fileDeleted
;
1359 UNICODE_STRING name_str
;
1360 HANDLE handle
, handle2
;
1364 GetTempPathW( MAX_PATH
, tmp_path
);
1366 /* oldpath is a file, newpath doesn't exist */
1367 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1368 ok( res
!= 0, "failed to create temp file\n" );
1369 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1370 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1372 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1373 ok( res
!= 0, "failed to create temp file\n" );
1374 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1375 DeleteFileW( newpath
);
1376 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1377 fri
->Replace
= FALSE
;
1378 fri
->RootDir
= NULL
;
1379 fri
->FileNameLength
= name_str
.Length
;
1380 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1381 pRtlFreeUnicodeString( &name_str
);
1383 U(io
).Status
= 0xdeadbeef;
1384 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1385 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1386 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1387 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1388 ok( fileDeleted
, "file should not exist\n" );
1389 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1390 ok( !fileDeleted
, "file should exist\n" );
1392 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
1393 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
1394 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1395 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
1396 ok( !lstrcmpiW(fni
->FileName
, newpath
+ 2), "FileName expected %s, got %s\n",
1397 wine_dbgstr_w(newpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
1398 HeapFree( GetProcessHeap(), 0, fni
);
1400 CloseHandle( handle
);
1401 HeapFree( GetProcessHeap(), 0, fri
);
1402 delete_object( oldpath
);
1403 delete_object( newpath
);
1405 /* oldpath is a file, newpath is a file, Replace = FALSE */
1406 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1407 ok( res
!= 0, "failed to create temp file\n" );
1408 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1409 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1411 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1412 ok( res
!= 0, "failed to create temp file\n" );
1413 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1414 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1415 fri
->Replace
= FALSE
;
1416 fri
->RootDir
= NULL
;
1417 fri
->FileNameLength
= name_str
.Length
;
1418 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1419 pRtlFreeUnicodeString( &name_str
);
1421 U(io
).Status
= 0xdeadbeef;
1422 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1423 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1424 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1425 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1426 ok( !fileDeleted
, "file should exist\n" );
1427 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1428 ok( !fileDeleted
, "file should exist\n" );
1430 CloseHandle( handle
);
1431 HeapFree( GetProcessHeap(), 0, fri
);
1432 delete_object( oldpath
);
1433 delete_object( newpath
);
1435 /* oldpath is a file, newpath is a file, Replace = TRUE */
1436 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1437 ok( res
!= 0, "failed to create temp file\n" );
1438 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1439 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1441 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1442 ok( res
!= 0, "failed to create temp file\n" );
1443 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1444 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1445 fri
->Replace
= TRUE
;
1446 fri
->RootDir
= NULL
;
1447 fri
->FileNameLength
= name_str
.Length
;
1448 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1449 pRtlFreeUnicodeString( &name_str
);
1451 U(io
).Status
= 0xdeadbeef;
1452 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1453 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1454 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1455 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1456 ok( fileDeleted
, "file should not exist\n" );
1457 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1458 ok( !fileDeleted
, "file should exist\n" );
1460 CloseHandle( handle
);
1461 HeapFree( GetProcessHeap(), 0, fri
);
1462 delete_object( oldpath
);
1463 delete_object( newpath
);
1465 /* oldpath is a file, newpath is a file, Replace = FALSE, target file opened */
1466 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1467 ok( res
!= 0, "failed to create temp file\n" );
1468 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1469 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1471 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1472 ok( res
!= 0, "failed to create temp file\n" );
1473 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1474 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1476 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1477 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1478 fri
->Replace
= FALSE
;
1479 fri
->RootDir
= NULL
;
1480 fri
->FileNameLength
= name_str
.Length
;
1481 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1482 pRtlFreeUnicodeString( &name_str
);
1484 U(io
).Status
= 0xdeadbeef;
1485 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1486 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1487 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1488 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1489 ok( !fileDeleted
, "file should exist\n" );
1490 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1491 ok( !fileDeleted
, "file should exist\n" );
1493 CloseHandle( handle
);
1494 CloseHandle( handle2
);
1495 HeapFree( GetProcessHeap(), 0, fri
);
1496 delete_object( oldpath
);
1497 delete_object( newpath
);
1499 /* oldpath is a file, newpath is a file, Replace = TRUE, target file opened */
1500 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1501 ok( res
!= 0, "failed to create temp file\n" );
1502 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1503 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1505 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1506 ok( res
!= 0, "failed to create temp file\n" );
1507 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1508 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1510 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1511 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1512 fri
->Replace
= TRUE
;
1513 fri
->RootDir
= NULL
;
1514 fri
->FileNameLength
= name_str
.Length
;
1515 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1516 pRtlFreeUnicodeString( &name_str
);
1518 U(io
).Status
= 0xdeadbeef;
1519 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1520 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1521 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1522 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1523 ok( !fileDeleted
, "file should exist\n" );
1524 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1525 ok( !fileDeleted
, "file should exist\n" );
1527 CloseHandle( handle
);
1528 CloseHandle( handle2
);
1529 HeapFree( GetProcessHeap(), 0, fri
);
1530 delete_object( oldpath
);
1531 delete_object( newpath
);
1533 /* oldpath is a directory, newpath doesn't exist, Replace = FALSE */
1534 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1535 ok( res
!= 0, "failed to create temp file\n" );
1536 DeleteFileW( oldpath
);
1537 success
= CreateDirectoryW( oldpath
, NULL
);
1538 ok( success
!= 0, "failed to create temp directory\n" );
1539 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1540 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1542 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1543 ok( res
!= 0, "failed to create temp file\n" );
1544 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1545 DeleteFileW( newpath
);
1546 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1547 fri
->Replace
= FALSE
;
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 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1556 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1557 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1558 ok( fileDeleted
, "file should not exist\n" );
1559 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1560 ok( !fileDeleted
, "file should exist\n" );
1562 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
1563 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
1564 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1565 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
1566 ok( !lstrcmpiW(fni
->FileName
, newpath
+ 2), "FileName expected %s, got %s\n",
1567 wine_dbgstr_w(newpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
1568 HeapFree( GetProcessHeap(), 0, fni
);
1570 CloseHandle( handle
);
1571 HeapFree( GetProcessHeap(), 0, fri
);
1572 delete_object( oldpath
);
1573 delete_object( newpath
);
1575 /* oldpath is a directory (but child object opened), newpath doesn't exist, Replace = FALSE */
1576 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1577 ok( res
!= 0, "failed to create temp file\n" );
1578 DeleteFileW( oldpath
);
1579 success
= CreateDirectoryW( oldpath
, NULL
);
1580 ok( success
!= 0, "failed to create temp directory\n" );
1581 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1582 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1584 lstrcpyW( newpath
, oldpath
);
1585 lstrcatW( newpath
, foo_txtW
);
1586 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0 );
1587 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1589 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1590 ok( res
!= 0, "failed to create temp file\n" );
1591 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1592 DeleteFileW( newpath
);
1593 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1594 fri
->Replace
= FALSE
;
1595 fri
->RootDir
= NULL
;
1596 fri
->FileNameLength
= name_str
.Length
;
1597 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1598 pRtlFreeUnicodeString( &name_str
);
1600 U(io
).Status
= 0xdeadbeef;
1601 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1602 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1603 todo_wine
ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1604 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1605 todo_wine
ok( !fileDeleted
, "file should exist\n" );
1606 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1607 todo_wine
ok( fileDeleted
, "file should not exist\n" );
1609 CloseHandle( handle
);
1610 CloseHandle( handle2
);
1611 HeapFree( GetProcessHeap(), 0, fri
);
1612 delete_object( oldpath
);
1613 if (res
== STATUS_SUCCESS
) /* remove when Wine is fixed */
1615 lstrcpyW( oldpath
, newpath
);
1616 lstrcatW( oldpath
, foo_txtW
);
1617 delete_object( oldpath
);
1619 delete_object( newpath
);
1621 /* oldpath is a directory, newpath is a file, Replace = FALSE */
1622 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1623 ok( res
!= 0, "failed to create temp file\n" );
1624 DeleteFileW( oldpath
);
1625 success
= CreateDirectoryW( oldpath
, NULL
);
1626 ok( success
!= 0, "failed to create temp directory\n" );
1627 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1628 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1630 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1631 ok( res
!= 0, "failed to create temp file\n" );
1632 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1633 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1634 fri
->Replace
= FALSE
;
1635 fri
->RootDir
= NULL
;
1636 fri
->FileNameLength
= name_str
.Length
;
1637 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1638 pRtlFreeUnicodeString( &name_str
);
1640 U(io
).Status
= 0xdeadbeef;
1641 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1642 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1643 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1644 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1645 ok( !fileDeleted
, "file should exist\n" );
1646 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1647 ok( !fileDeleted
, "file should exist\n" );
1649 CloseHandle( handle
);
1650 HeapFree( GetProcessHeap(), 0, fri
);
1651 delete_object( oldpath
);
1652 delete_object( newpath
);
1654 /* oldpath is a directory, newpath is a file, Replace = FALSE, target file opened */
1655 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1656 ok( res
!= 0, "failed to create temp file\n" );
1657 DeleteFileW( oldpath
);
1658 success
= CreateDirectoryW( oldpath
, NULL
);
1659 ok( success
!= 0, "failed to create temp directory\n" );
1660 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1661 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1663 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1664 ok( res
!= 0, "failed to create temp file\n" );
1665 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1666 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1668 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1669 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1670 fri
->Replace
= FALSE
;
1671 fri
->RootDir
= NULL
;
1672 fri
->FileNameLength
= name_str
.Length
;
1673 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1674 pRtlFreeUnicodeString( &name_str
);
1676 U(io
).Status
= 0xdeadbeef;
1677 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1678 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1679 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1680 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1681 ok( !fileDeleted
, "file should exist\n" );
1682 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1683 ok( !fileDeleted
, "file should exist\n" );
1685 CloseHandle( handle
);
1686 CloseHandle( handle2
);
1687 HeapFree( GetProcessHeap(), 0, fri
);
1688 delete_object( oldpath
);
1689 delete_object( newpath
);
1691 /* oldpath is a directory, newpath is a file, Replace = TRUE */
1692 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1693 ok( res
!= 0, "failed to create temp file\n" );
1694 DeleteFileW( oldpath
);
1695 success
= CreateDirectoryW( oldpath
, NULL
);
1696 ok( success
!= 0, "failed to create temp directory\n" );
1697 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1698 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1700 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1701 ok( res
!= 0, "failed to create temp file\n" );
1702 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1703 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1704 fri
->Replace
= TRUE
;
1705 fri
->RootDir
= NULL
;
1706 fri
->FileNameLength
= name_str
.Length
;
1707 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1708 pRtlFreeUnicodeString( &name_str
);
1710 U(io
).Status
= 0xdeadbeef;
1711 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1712 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1713 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1714 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1715 ok( fileDeleted
, "file should not exist\n" );
1716 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1717 ok( !fileDeleted
, "file should exist\n" );
1719 CloseHandle( handle
);
1720 HeapFree( GetProcessHeap(), 0, fri
);
1721 delete_object( oldpath
);
1722 delete_object( newpath
);
1724 /* oldpath is a directory, newpath is a file, Replace = TRUE, target file opened */
1725 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1726 ok( res
!= 0, "failed to create temp file\n" );
1727 DeleteFileW( oldpath
);
1728 success
= CreateDirectoryW( oldpath
, NULL
);
1729 ok( success
!= 0, "failed to create temp directory\n" );
1730 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1731 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1733 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1734 ok( res
!= 0, "failed to create temp file\n" );
1735 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1736 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1738 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1739 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1740 fri
->Replace
= TRUE
;
1741 fri
->RootDir
= NULL
;
1742 fri
->FileNameLength
= name_str
.Length
;
1743 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1744 pRtlFreeUnicodeString( &name_str
);
1746 U(io
).Status
= 0xdeadbeef;
1747 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1748 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1749 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1750 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1751 ok( !fileDeleted
, "file should exist\n" );
1752 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1753 ok( !fileDeleted
, "file should exist\n" );
1755 CloseHandle( handle
);
1756 CloseHandle( handle2
);
1757 HeapFree( GetProcessHeap(), 0, fri
);
1758 delete_object( oldpath
);
1759 delete_object( newpath
);
1761 /* oldpath is a directory, newpath is a directory, Replace = FALSE */
1762 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1763 ok( res
!= 0, "failed to create temp file\n" );
1764 DeleteFileW( oldpath
);
1765 success
= CreateDirectoryW( oldpath
, NULL
);
1766 ok( success
!= 0, "failed to create temp directory\n" );
1767 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1768 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1770 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1771 ok( res
!= 0, "failed to create temp file\n" );
1772 DeleteFileW( newpath
);
1773 success
= CreateDirectoryW( newpath
, NULL
);
1774 ok( success
!= 0, "failed to create temp directory\n" );
1775 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1776 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1777 fri
->Replace
= FALSE
;
1778 fri
->RootDir
= NULL
;
1779 fri
->FileNameLength
= name_str
.Length
;
1780 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1781 pRtlFreeUnicodeString( &name_str
);
1783 U(io
).Status
= 0xdeadbeef;
1784 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1785 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1786 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1787 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1788 ok( !fileDeleted
, "file should exist\n" );
1789 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1790 ok( !fileDeleted
, "file should exist\n" );
1792 CloseHandle( handle
);
1793 HeapFree( GetProcessHeap(), 0, fri
);
1794 delete_object( oldpath
);
1795 delete_object( newpath
);
1797 /* oldpath is a directory, newpath is a directory, Replace = TRUE */
1798 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1799 ok( res
!= 0, "failed to create temp file\n" );
1800 DeleteFileW( oldpath
);
1801 success
= CreateDirectoryW( oldpath
, NULL
);
1802 ok( success
!= 0, "failed to create temp directory\n" );
1803 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1804 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1806 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1807 ok( res
!= 0, "failed to create temp file\n" );
1808 DeleteFileW( newpath
);
1809 success
= CreateDirectoryW( newpath
, NULL
);
1810 ok( success
!= 0, "failed to create temp directory\n" );
1811 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1812 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1813 fri
->Replace
= TRUE
;
1814 fri
->RootDir
= NULL
;
1815 fri
->FileNameLength
= name_str
.Length
;
1816 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1817 pRtlFreeUnicodeString( &name_str
);
1819 U(io
).Status
= 0xdeadbeef;
1820 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1821 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1822 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1823 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1824 ok( !fileDeleted
, "file should exist\n" );
1825 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1826 ok( !fileDeleted
, "file should exist\n" );
1828 CloseHandle( handle
);
1829 HeapFree( GetProcessHeap(), 0, fri
);
1830 delete_object( oldpath
);
1831 delete_object( newpath
);
1833 /* oldpath is a directory, newpath is a directory, Replace = TRUE, target file opened */
1834 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1835 ok( res
!= 0, "failed to create temp file\n" );
1836 DeleteFileW( oldpath
);
1837 success
= CreateDirectoryW( oldpath
, NULL
);
1838 ok( success
!= 0, "failed to create temp directory\n" );
1839 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1840 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1842 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1843 ok( res
!= 0, "failed to create temp file\n" );
1844 DeleteFileW( newpath
);
1845 success
= CreateDirectoryW( newpath
, NULL
);
1846 ok( success
!= 0, "failed to create temp directory\n" );
1847 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1848 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1850 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1851 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1852 fri
->Replace
= TRUE
;
1853 fri
->RootDir
= NULL
;
1854 fri
->FileNameLength
= name_str
.Length
;
1855 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1856 pRtlFreeUnicodeString( &name_str
);
1858 U(io
).Status
= 0xdeadbeef;
1859 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1860 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1861 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1862 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1863 ok( !fileDeleted
, "file should exist\n" );
1864 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1865 ok( !fileDeleted
, "file should exist\n" );
1867 CloseHandle( handle
);
1868 CloseHandle( handle2
);
1869 HeapFree( GetProcessHeap(), 0, fri
);
1870 delete_object( oldpath
);
1871 delete_object( newpath
);
1873 /* oldpath is a file, newpath is a directory, Replace = FALSE */
1874 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1875 ok( res
!= 0, "failed to create temp file\n" );
1876 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1877 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1879 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1880 ok( res
!= 0, "failed to create temp file\n" );
1881 DeleteFileW( newpath
);
1882 success
= CreateDirectoryW( newpath
, NULL
);
1883 ok( success
!= 0, "failed to create temp directory\n" );
1884 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1885 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1886 fri
->Replace
= FALSE
;
1887 fri
->RootDir
= NULL
;
1888 fri
->FileNameLength
= name_str
.Length
;
1889 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1890 pRtlFreeUnicodeString( &name_str
);
1892 U(io
).Status
= 0xdeadbeef;
1893 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1894 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1895 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1896 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1897 ok( !fileDeleted
, "file should exist\n" );
1898 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1899 ok( !fileDeleted
, "file should exist\n" );
1901 CloseHandle( handle
);
1902 HeapFree( GetProcessHeap(), 0, fri
);
1903 delete_object( oldpath
);
1904 delete_object( newpath
);
1906 /* oldpath is a file, newpath is a directory, Replace = TRUE */
1907 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1908 ok( res
!= 0, "failed to create temp file\n" );
1909 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1910 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1912 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1913 ok( res
!= 0, "failed to create temp file\n" );
1914 DeleteFileW( newpath
);
1915 success
= CreateDirectoryW( newpath
, NULL
);
1916 ok( success
!= 0, "failed to create temp directory\n" );
1917 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1918 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1919 fri
->Replace
= TRUE
;
1920 fri
->RootDir
= NULL
;
1921 fri
->FileNameLength
= name_str
.Length
;
1922 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1923 pRtlFreeUnicodeString( &name_str
);
1925 U(io
).Status
= 0xdeadbeef;
1926 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1927 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1928 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1929 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1930 ok( !fileDeleted
, "file should exist\n" );
1931 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1932 ok( !fileDeleted
, "file should exist\n" );
1934 CloseHandle( handle
);
1935 HeapFree( GetProcessHeap(), 0, fri
);
1936 delete_object( oldpath
);
1937 delete_object( newpath
);
1939 /* oldpath is a file, newpath doesn't exist, test with RootDir != NULL */
1940 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1941 ok( res
!= 0, "failed to create temp file\n" );
1942 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1943 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1945 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1946 ok( res
!= 0, "failed to create temp file\n" );
1947 DeleteFileW( newpath
);
1948 for (filename
= newpath
, p
= newpath
; *p
; p
++)
1949 if (*p
== '\\') filename
= p
+ 1;
1950 handle2
= CreateFileW( tmp_path
, 0, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1951 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1953 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + lstrlenW(filename
) * sizeof(WCHAR
) );
1954 fri
->Replace
= FALSE
;
1955 fri
->RootDir
= handle2
;
1956 fri
->FileNameLength
= lstrlenW(filename
) * sizeof(WCHAR
);
1957 memcpy( fri
->FileName
, filename
, fri
->FileNameLength
);
1959 U(io
).Status
= 0xdeadbeef;
1960 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1961 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1962 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1963 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1964 ok( fileDeleted
, "file should not exist\n" );
1965 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1966 ok( !fileDeleted
, "file should exist\n" );
1968 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
1969 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
1970 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1971 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
1972 ok( !lstrcmpiW(fni
->FileName
, newpath
+ 2), "FileName expected %s, got %s\n",
1973 wine_dbgstr_w(newpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
1974 HeapFree( GetProcessHeap(), 0, fni
);
1976 CloseHandle( handle
);
1977 CloseHandle( handle2
);
1978 HeapFree( GetProcessHeap(), 0, fri
);
1979 delete_object( oldpath
);
1980 delete_object( newpath
);
1983 static void test_file_link_information(void)
1985 static const WCHAR pipeW
[] = {'\\','\\','.','\\','p','i','p','e','\\','w','i','n','e','_','t','e','s','t',0};
1986 static const WCHAR foo_txtW
[] = {'\\','f','o','o','.','t','x','t',0};
1987 static const WCHAR fooW
[] = {'f','o','o',0};
1988 WCHAR tmp_path
[MAX_PATH
], oldpath
[MAX_PATH
+ 16], newpath
[MAX_PATH
+ 16], *filename
, *p
;
1989 FILE_LINK_INFORMATION
*fli
;
1990 FILE_NAME_INFORMATION
*fni
;
1991 BOOL success
, fileDeleted
;
1992 UNICODE_STRING name_str
;
1993 HANDLE handle
, handle2
;
1997 GetTempPathW( MAX_PATH
, tmp_path
);
1999 /* oldpath is a file, newpath doesn't exist */
2000 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2001 ok( res
!= 0, "failed to create temp file\n" );
2002 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2003 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2005 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2006 ok( res
!= 0, "failed to create temp file\n" );
2007 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2008 DeleteFileW( newpath
);
2009 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2010 fli
->ReplaceIfExists
= FALSE
;
2011 fli
->RootDirectory
= NULL
;
2012 fli
->FileNameLength
= name_str
.Length
;
2013 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2014 pRtlFreeUnicodeString( &name_str
);
2016 U(io
).Status
= 0xdeadbeef;
2017 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2018 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
2019 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2020 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2021 ok( !fileDeleted
, "file should exist\n" );
2022 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2023 ok( !fileDeleted
, "file should exist\n" );
2025 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2026 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2027 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2028 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2029 ok( !lstrcmpiW(fni
->FileName
, oldpath
+ 2), "FileName expected %s, got %s\n",
2030 wine_dbgstr_w(oldpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2031 HeapFree( GetProcessHeap(), 0, fni
);
2033 CloseHandle( handle
);
2034 HeapFree( GetProcessHeap(), 0, fli
);
2035 delete_object( oldpath
);
2036 delete_object( newpath
);
2038 /* oldpath is a file, newpath is a file, ReplaceIfExists = FALSE */
2039 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2040 ok( res
!= 0, "failed to create temp file\n" );
2041 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2042 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2044 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2045 ok( res
!= 0, "failed to create temp file\n" );
2046 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2047 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2048 fli
->ReplaceIfExists
= FALSE
;
2049 fli
->RootDirectory
= NULL
;
2050 fli
->FileNameLength
= name_str
.Length
;
2051 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2052 pRtlFreeUnicodeString( &name_str
);
2054 U(io
).Status
= 0xdeadbeef;
2055 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2056 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2057 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
2058 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2059 ok( !fileDeleted
, "file should exist\n" );
2060 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2061 ok( !fileDeleted
, "file should exist\n" );
2063 CloseHandle( handle
);
2064 HeapFree( GetProcessHeap(), 0, fli
);
2065 delete_object( oldpath
);
2066 delete_object( newpath
);
2068 /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE */
2069 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2070 ok( res
!= 0, "failed to create temp file\n" );
2071 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2072 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2074 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2075 ok( res
!= 0, "failed to create temp file\n" );
2076 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2077 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2078 fli
->ReplaceIfExists
= TRUE
;
2079 fli
->RootDirectory
= NULL
;
2080 fli
->FileNameLength
= name_str
.Length
;
2081 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2082 pRtlFreeUnicodeString( &name_str
);
2084 U(io
).Status
= 0xdeadbeef;
2085 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2086 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
2087 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2088 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2089 ok( !fileDeleted
, "file should exist\n" );
2090 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2091 ok( !fileDeleted
, "file should exist\n" );
2093 CloseHandle( handle
);
2094 HeapFree( GetProcessHeap(), 0, fli
);
2095 delete_object( oldpath
);
2096 delete_object( newpath
);
2098 /* oldpath is a file, newpath is a file, ReplaceIfExists = FALSE, target file opened */
2099 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2100 ok( res
!= 0, "failed to create temp file\n" );
2101 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2102 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2104 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2105 ok( res
!= 0, "failed to create temp file\n" );
2106 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2107 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2109 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2110 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2111 fli
->ReplaceIfExists
= FALSE
;
2112 fli
->RootDirectory
= NULL
;
2113 fli
->FileNameLength
= name_str
.Length
;
2114 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2115 pRtlFreeUnicodeString( &name_str
);
2117 U(io
).Status
= 0xdeadbeef;
2118 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2119 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2120 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
2121 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2122 ok( !fileDeleted
, "file should exist\n" );
2123 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2124 ok( !fileDeleted
, "file should exist\n" );
2126 CloseHandle( handle
);
2127 CloseHandle( handle2
);
2128 HeapFree( GetProcessHeap(), 0, fli
);
2129 delete_object( oldpath
);
2130 delete_object( newpath
);
2132 /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE, 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
= TRUE
;
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_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, 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 directory, newpath doesn't exist, ReplaceIfExists = FALSE */
2167 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2168 ok( res
!= 0, "failed to create temp file\n" );
2169 DeleteFileW( oldpath
);
2170 success
= CreateDirectoryW( oldpath
, NULL
);
2171 ok( success
!= 0, "failed to create temp directory\n" );
2172 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2173 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2175 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2176 ok( res
!= 0, "failed to create temp file\n" );
2177 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2178 DeleteFileW( newpath
);
2179 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2180 fli
->ReplaceIfExists
= FALSE
;
2181 fli
->RootDirectory
= NULL
;
2182 fli
->FileNameLength
= name_str
.Length
;
2183 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2184 pRtlFreeUnicodeString( &name_str
);
2186 U(io
).Status
= 0xdeadbeef;
2187 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2188 todo_wine
ok( U(io
).Status
== 0xdeadbeef , "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2189 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2190 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2191 ok( !fileDeleted
, "file should exist\n" );
2192 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2193 ok( fileDeleted
, "file should not exist\n" );
2195 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2196 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2197 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2198 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2199 ok( !lstrcmpiW(fni
->FileName
, oldpath
+ 2), "FileName expected %s, got %s\n",
2200 wine_dbgstr_w(oldpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2201 HeapFree( GetProcessHeap(), 0, fni
);
2203 CloseHandle( handle
);
2204 HeapFree( GetProcessHeap(), 0, fli
);
2205 delete_object( oldpath
);
2206 delete_object( newpath
);
2208 /* oldpath is a directory (but child object opened), newpath doesn't exist, ReplaceIfExists = FALSE */
2209 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2210 ok( res
!= 0, "failed to create temp file\n" );
2211 DeleteFileW( oldpath
);
2212 success
= CreateDirectoryW( oldpath
, NULL
);
2213 ok( success
!= 0, "failed to create temp directory\n" );
2214 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2215 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2217 lstrcpyW( newpath
, oldpath
);
2218 lstrcatW( newpath
, foo_txtW
);
2219 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0 );
2220 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2222 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2223 ok( res
!= 0, "failed to create temp file\n" );
2224 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2225 DeleteFileW( newpath
);
2226 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2227 fli
->ReplaceIfExists
= FALSE
;
2228 fli
->RootDirectory
= NULL
;
2229 fli
->FileNameLength
= name_str
.Length
;
2230 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2231 pRtlFreeUnicodeString( &name_str
);
2233 U(io
).Status
= 0xdeadbeef;
2234 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2235 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2236 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2237 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2238 ok( !fileDeleted
, "file should exist\n" );
2239 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2240 ok( fileDeleted
, "file should not exist\n" );
2242 CloseHandle( handle
);
2243 CloseHandle( handle2
);
2244 HeapFree( GetProcessHeap(), 0, fli
);
2245 delete_object( oldpath
);
2246 delete_object( newpath
);
2248 /* oldpath is a directory, newpath is a file, ReplaceIfExists = FALSE */
2249 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2250 ok( res
!= 0, "failed to create temp file\n" );
2251 DeleteFileW( oldpath
);
2252 success
= CreateDirectoryW( oldpath
, NULL
);
2253 ok( success
!= 0, "failed to create temp directory\n" );
2254 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2255 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2257 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2258 ok( res
!= 0, "failed to create temp file\n" );
2259 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
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_OBJECT_NAME_COLLISION
|| res
== STATUS_FILE_IS_A_DIRECTORY
/* > Win XP */,
2271 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2272 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2273 ok( !fileDeleted
, "file should exist\n" );
2274 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2275 ok( !fileDeleted
, "file should exist\n" );
2277 CloseHandle( handle
);
2278 HeapFree( GetProcessHeap(), 0, fli
);
2279 delete_object( oldpath
);
2280 delete_object( newpath
);
2282 /* oldpath is a directory, newpath is a file, ReplaceIfExists = FALSE, target file opened */
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 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2294 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2296 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2297 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2298 fli
->ReplaceIfExists
= FALSE
;
2299 fli
->RootDirectory
= NULL
;
2300 fli
->FileNameLength
= name_str
.Length
;
2301 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2302 pRtlFreeUnicodeString( &name_str
);
2304 U(io
).Status
= 0xdeadbeef;
2305 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2306 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2307 ok( res
== STATUS_OBJECT_NAME_COLLISION
|| res
== STATUS_FILE_IS_A_DIRECTORY
/* > Win XP */,
2308 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2309 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2310 ok( !fileDeleted
, "file should exist\n" );
2311 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2312 ok( !fileDeleted
, "file should exist\n" );
2314 CloseHandle( handle
);
2315 CloseHandle( handle2
);
2316 HeapFree( GetProcessHeap(), 0, fli
);
2317 delete_object( oldpath
);
2318 delete_object( newpath
);
2320 /* oldpath is a directory, newpath is a file, ReplaceIfExists = TRUE */
2321 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2322 ok( res
!= 0, "failed to create temp file\n" );
2323 DeleteFileW( oldpath
);
2324 success
= CreateDirectoryW( oldpath
, NULL
);
2325 ok( success
!= 0, "failed to create temp directory\n" );
2326 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2327 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2329 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2330 ok( res
!= 0, "failed to create temp file\n" );
2331 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2332 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2333 fli
->ReplaceIfExists
= TRUE
;
2334 fli
->RootDirectory
= NULL
;
2335 fli
->FileNameLength
= name_str
.Length
;
2336 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2337 pRtlFreeUnicodeString( &name_str
);
2339 U(io
).Status
= 0xdeadbeef;
2340 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2341 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2342 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected 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 HeapFree( GetProcessHeap(), 0, fli
);
2350 delete_object( oldpath
);
2351 delete_object( newpath
);
2353 /* oldpath is a directory, newpath is a file, ReplaceIfExists = TRUE, target file opened */
2354 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2355 ok( res
!= 0, "failed to create temp file\n" );
2356 DeleteFileW( oldpath
);
2357 success
= CreateDirectoryW( oldpath
, NULL
);
2358 ok( success
!= 0, "failed to create temp directory\n" );
2359 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2360 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2362 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2363 ok( res
!= 0, "failed to create temp file\n" );
2364 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2365 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2367 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2368 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2369 fli
->ReplaceIfExists
= TRUE
;
2370 fli
->RootDirectory
= NULL
;
2371 fli
->FileNameLength
= name_str
.Length
;
2372 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2373 pRtlFreeUnicodeString( &name_str
);
2375 U(io
).Status
= 0xdeadbeef;
2376 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2377 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2378 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2379 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2380 ok( !fileDeleted
, "file should exist\n" );
2381 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2382 ok( !fileDeleted
, "file should exist\n" );
2384 CloseHandle( handle
);
2385 CloseHandle( handle2
);
2386 HeapFree( GetProcessHeap(), 0, fli
);
2387 delete_object( oldpath
);
2388 delete_object( newpath
);
2390 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = FALSE */
2391 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2392 ok( res
!= 0, "failed to create temp file\n" );
2393 DeleteFileW( oldpath
);
2394 success
= CreateDirectoryW( oldpath
, NULL
);
2395 ok( success
!= 0, "failed to create temp directory\n" );
2396 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2397 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2399 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2400 ok( res
!= 0, "failed to create temp file\n" );
2401 DeleteFileW( newpath
);
2402 success
= CreateDirectoryW( newpath
, NULL
);
2403 ok( success
!= 0, "failed to create temp directory\n" );
2404 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2405 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2406 fli
->ReplaceIfExists
= FALSE
;
2407 fli
->RootDirectory
= NULL
;
2408 fli
->FileNameLength
= name_str
.Length
;
2409 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2410 pRtlFreeUnicodeString( &name_str
);
2412 U(io
).Status
= 0xdeadbeef;
2413 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2414 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2415 ok( res
== STATUS_OBJECT_NAME_COLLISION
|| res
== STATUS_FILE_IS_A_DIRECTORY
/* > Win XP */,
2416 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2417 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2418 ok( !fileDeleted
, "file should exist\n" );
2419 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2420 ok( !fileDeleted
, "file should exist\n" );
2422 CloseHandle( handle
);
2423 HeapFree( GetProcessHeap(), 0, fli
);
2424 delete_object( oldpath
);
2425 delete_object( newpath
);
2427 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = TRUE */
2428 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2429 ok( res
!= 0, "failed to create temp file\n" );
2430 DeleteFileW( oldpath
);
2431 success
= CreateDirectoryW( oldpath
, NULL
);
2432 ok( success
!= 0, "failed to create temp directory\n" );
2433 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2434 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2436 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2437 ok( res
!= 0, "failed to create temp file\n" );
2438 DeleteFileW( newpath
);
2439 success
= CreateDirectoryW( newpath
, NULL
);
2440 ok( success
!= 0, "failed to create temp directory\n" );
2441 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2442 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2443 fli
->ReplaceIfExists
= TRUE
;
2444 fli
->RootDirectory
= NULL
;
2445 fli
->FileNameLength
= name_str
.Length
;
2446 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2447 pRtlFreeUnicodeString( &name_str
);
2449 U(io
).Status
= 0xdeadbeef;
2450 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2451 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2452 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2453 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2454 ok( !fileDeleted
, "file should exist\n" );
2455 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2456 ok( !fileDeleted
, "file should exist\n" );
2458 CloseHandle( handle
);
2459 HeapFree( GetProcessHeap(), 0, fli
);
2460 delete_object( oldpath
);
2461 delete_object( newpath
);
2463 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = TRUE, target file opened */
2464 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2465 ok( res
!= 0, "failed to create temp file\n" );
2466 DeleteFileW( oldpath
);
2467 success
= CreateDirectoryW( oldpath
, NULL
);
2468 ok( success
!= 0, "failed to create temp directory\n" );
2469 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2470 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2472 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2473 ok( res
!= 0, "failed to create temp file\n" );
2474 DeleteFileW( newpath
);
2475 success
= CreateDirectoryW( newpath
, NULL
);
2476 ok( success
!= 0, "failed to create temp directory\n" );
2477 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2478 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2480 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2481 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2482 fli
->ReplaceIfExists
= TRUE
;
2483 fli
->RootDirectory
= NULL
;
2484 fli
->FileNameLength
= name_str
.Length
;
2485 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2486 pRtlFreeUnicodeString( &name_str
);
2488 U(io
).Status
= 0xdeadbeef;
2489 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2490 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2491 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2492 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2493 ok( !fileDeleted
, "file should exist\n" );
2494 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2495 ok( !fileDeleted
, "file should exist\n" );
2497 CloseHandle( handle
);
2498 CloseHandle( handle2
);
2499 HeapFree( GetProcessHeap(), 0, fli
);
2500 delete_object( oldpath
);
2501 delete_object( newpath
);
2503 /* oldpath is a file, newpath is a directory, ReplaceIfExists = FALSE */
2504 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2505 ok( res
!= 0, "failed to create temp file\n" );
2506 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2507 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2509 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2510 ok( res
!= 0, "failed to create temp file\n" );
2511 DeleteFileW( newpath
);
2512 success
= CreateDirectoryW( newpath
, NULL
);
2513 ok( success
!= 0, "failed to create temp directory\n" );
2514 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2515 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2516 fli
->ReplaceIfExists
= FALSE
;
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_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, 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 HeapFree( GetProcessHeap(), 0, fli
);
2533 delete_object( oldpath
);
2534 delete_object( newpath
);
2536 /* oldpath is a file, newpath is a directory, ReplaceIfExists = TRUE */
2537 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2538 ok( res
!= 0, "failed to create temp file\n" );
2539 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2540 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2542 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2543 ok( res
!= 0, "failed to create temp file\n" );
2544 DeleteFileW( newpath
);
2545 success
= CreateDirectoryW( newpath
, NULL
);
2546 ok( success
!= 0, "failed to create temp directory\n" );
2547 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2548 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2549 fli
->ReplaceIfExists
= TRUE
;
2550 fli
->RootDirectory
= NULL
;
2551 fli
->FileNameLength
= name_str
.Length
;
2552 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2553 pRtlFreeUnicodeString( &name_str
);
2555 U(io
).Status
= 0xdeadbeef;
2556 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2557 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2558 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
2559 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2560 ok( !fileDeleted
, "file should exist\n" );
2561 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2562 ok( !fileDeleted
, "file should exist\n" );
2564 CloseHandle( handle
);
2565 HeapFree( GetProcessHeap(), 0, fli
);
2566 delete_object( oldpath
);
2567 delete_object( newpath
);
2569 /* oldpath is a file, newpath doesn't exist, test with RootDirectory != NULL */
2570 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2571 ok( res
!= 0, "failed to create temp file\n" );
2572 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2573 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2575 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2576 ok( res
!= 0, "failed to create temp file\n" );
2577 DeleteFileW( newpath
);
2578 for (filename
= newpath
, p
= newpath
; *p
; p
++)
2579 if (*p
== '\\') filename
= p
+ 1;
2580 handle2
= CreateFileW( tmp_path
, 0, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2581 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2583 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + lstrlenW(filename
) * sizeof(WCHAR
) );
2584 fli
->ReplaceIfExists
= FALSE
;
2585 fli
->RootDirectory
= handle2
;
2586 fli
->FileNameLength
= lstrlenW(filename
) * sizeof(WCHAR
);
2587 memcpy( fli
->FileName
, filename
, fli
->FileNameLength
);
2589 U(io
).Status
= 0xdeadbeef;
2590 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2591 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
2592 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, 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 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2599 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2600 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2601 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2602 ok( !lstrcmpiW(fni
->FileName
, oldpath
+ 2), "FileName expected %s, got %s\n",
2603 wine_dbgstr_w(oldpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2604 HeapFree( GetProcessHeap(), 0, fni
);
2606 CloseHandle( handle
);
2607 CloseHandle( handle2
);
2609 handle
= CreateEventA( NULL
, FALSE
, FALSE
, "wine_test_event" );
2610 ok( !!handle
, "Failed to create event: %u\n", GetLastError());
2612 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2613 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2614 ok( res
== STATUS_OBJECT_TYPE_MISMATCH
, "res expected STATUS_OBJECT_TYPE_MISMATCH, got %x\n", res
);
2615 HeapFree( GetProcessHeap(), 0, fni
);
2617 CloseHandle( handle
);
2619 handle
= CreateNamedPipeW( pipeW
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
|PIPE_READMODE_BYTE
, 10, 512, 512, 0, NULL
);
2620 ok( handle
!= INVALID_HANDLE_VALUE
, "Failed to create named pipe: %u\n", GetLastError());
2622 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2623 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2624 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2625 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2626 ok( !lstrcmpiW(fni
->FileName
, pipeW
+ 8), "FileName expected %s, got %s\n",
2627 wine_dbgstr_w(pipeW
+ 8), wine_dbgstr_w(fni
->FileName
) );
2628 HeapFree( GetProcessHeap(), 0, fni
);
2630 CloseHandle( handle
);
2632 HeapFree( GetProcessHeap(), 0, fli
);
2633 delete_object( oldpath
);
2634 delete_object( newpath
);
2637 static void test_file_both_information(void)
2640 FILE_BOTH_DIR_INFORMATION fbi
;
2644 if (!(h
= create_temp_file(0))) return;
2646 memset(&fbi
, 0, sizeof(fbi
));
2647 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBothDirectoryInformation
);
2648 ok ( res
== STATUS_INVALID_INFO_CLASS
|| res
== STATUS_NOT_IMPLEMENTED
, "shouldn't be able to query FileBothDirectoryInformation, res %x\n", res
);
2653 static void test_file_disposition_information(void)
2655 char tmp_path
[MAX_PATH
], buffer
[MAX_PATH
+ 16];
2657 HANDLE handle
, handle2
, mapping
;
2660 FILE_DISPOSITION_INFORMATION fdi
;
2665 GetTempPathA( MAX_PATH
, tmp_path
);
2667 /* tests for info struct size */
2668 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2669 handle
= CreateFileA( buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2670 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2671 res
= pNtSetInformationFile( handle
, &io
, &fdi
, 0, FileDispositionInformation
);
2673 ok( res
== STATUS_INFO_LENGTH_MISMATCH
, "expected STATUS_INFO_LENGTH_MISMATCH, got %x\n", res
);
2675 res
= pNtSetInformationFile( handle
, &io
, &fdi2
, sizeof(fdi2
), FileDispositionInformation
);
2676 ok( res
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %x\n", res
);
2677 CloseHandle( handle
);
2678 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2679 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2680 DeleteFileA( buffer
);
2682 /* cannot set disposition on file not opened with delete access */
2683 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2684 handle
= CreateFileA(buffer
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2685 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2686 res
= pNtQueryInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2687 ok( res
== STATUS_INVALID_INFO_CLASS
|| res
== STATUS_NOT_IMPLEMENTED
, "Unexpected NtQueryInformationFile result (expected STATUS_INVALID_INFO_CLASS, got %x)\n", res
);
2688 fdi
.DoDeleteFile
= TRUE
;
2689 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2690 ok( res
== STATUS_ACCESS_DENIED
, "unexpected FileDispositionInformation result (expected STATUS_ACCESS_DENIED, got %x)\n", res
);
2691 CloseHandle( handle
);
2692 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2693 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2694 DeleteFileA( buffer
);
2696 /* can set disposition on file opened with proper access */
2697 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2698 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2699 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2700 fdi
.DoDeleteFile
= TRUE
;
2701 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2702 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2703 CloseHandle( handle
);
2704 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2705 ok( fileDeleted
, "File should have been deleted\n" );
2706 DeleteFileA( buffer
);
2708 /* cannot set disposition on readonly file */
2709 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2710 DeleteFileA( buffer
);
2711 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_READONLY
, 0);
2712 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2713 fdi
.DoDeleteFile
= TRUE
;
2714 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2715 ok( res
== STATUS_CANNOT_DELETE
, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res
);
2716 CloseHandle( handle
);
2717 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2718 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2719 SetFileAttributesA( buffer
, FILE_ATTRIBUTE_NORMAL
);
2720 DeleteFileA( buffer
);
2722 /* cannot set disposition on readonly file */
2723 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2724 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_READONLY
, 0);
2725 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2726 fdi
.DoDeleteFile
= TRUE
;
2727 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2729 ok( res
== STATUS_CANNOT_DELETE
, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res
);
2730 CloseHandle( handle
);
2731 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2733 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2734 SetFileAttributesA( buffer
, FILE_ATTRIBUTE_NORMAL
);
2735 DeleteFileA( buffer
);
2737 /* can set disposition on file and then reset it */
2738 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2739 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2740 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2741 fdi
.DoDeleteFile
= TRUE
;
2742 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2743 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2744 fdi
.DoDeleteFile
= FALSE
;
2745 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2746 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2747 CloseHandle( handle
);
2748 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2749 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2750 DeleteFileA( buffer
);
2752 /* Delete-on-close flag doesn't change file disposition until a handle is closed */
2753 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2754 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0);
2755 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2756 fdi
.DoDeleteFile
= FALSE
;
2757 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2758 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2759 CloseHandle( handle
);
2760 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2761 ok( fileDeleted
, "File should have been deleted\n" );
2762 DeleteFileA( buffer
);
2764 /* Delete-on-close flag sets disposition when a handle is closed and then it could be changed back */
2765 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2766 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0);
2767 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2768 ok( DuplicateHandle( GetCurrentProcess(), handle
, GetCurrentProcess(), &handle2
, 0, FALSE
, DUPLICATE_SAME_ACCESS
), "DuplicateHandle failed\n" );
2769 CloseHandle( handle
);
2770 fdi
.DoDeleteFile
= FALSE
;
2771 res
= pNtSetInformationFile( handle2
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2772 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2773 CloseHandle( handle2
);
2774 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2775 ok( fileDeleted
, "File should have been deleted\n" );
2776 DeleteFileA( buffer
);
2778 /* can set disposition on a directory opened with proper access */
2779 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2780 DeleteFileA( buffer
);
2781 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
2782 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2783 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
2784 fdi
.DoDeleteFile
= TRUE
;
2785 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2786 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2787 CloseHandle( handle
);
2788 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2789 ok( fileDeleted
, "Directory should have been deleted\n" );
2790 RemoveDirectoryA( buffer
);
2792 /* RemoveDirectory sets directory disposition and it can be undone */
2793 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2794 DeleteFileA( buffer
);
2795 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
2796 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2797 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
2798 RemoveDirectoryA( buffer
);
2799 fdi
.DoDeleteFile
= FALSE
;
2800 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2801 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2802 CloseHandle( handle
);
2803 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2804 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
2805 RemoveDirectoryA( buffer
);
2807 /* cannot set disposition on a non-empty directory */
2808 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2809 DeleteFileA( buffer
);
2810 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
2811 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2812 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
2813 dirpos
= lstrlenA( buffer
);
2814 lstrcpyA( buffer
+ dirpos
, "\\tst" );
2815 handle2
= CreateFileA(buffer
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2816 CloseHandle( handle2
);
2817 fdi
.DoDeleteFile
= TRUE
;
2818 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2820 ok( res
== STATUS_DIRECTORY_NOT_EMPTY
, "unexpected FileDispositionInformation result (expected STATUS_DIRECTORY_NOT_EMPTY, got %x)\n", res
);
2821 DeleteFileA( buffer
);
2822 buffer
[dirpos
] = '\0';
2823 CloseHandle( handle
);
2824 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2826 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
2827 RemoveDirectoryA( buffer
);
2829 /* cannot set disposition on file with file mapping opened */
2830 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2831 handle
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2832 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2833 mapping
= CreateFileMappingA( handle
, NULL
, PAGE_READWRITE
, 0, 64 * 1024, "DelFileTest" );
2834 ok( mapping
!= NULL
, "failed to create file mapping\n");
2835 fdi
.DoDeleteFile
= TRUE
;
2836 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2837 ok( res
== STATUS_CANNOT_DELETE
, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, 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 CloseHandle( mapping
);
2842 DeleteFileA( buffer
);
2844 /* can set disposition on file with file mapping closed */
2845 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2846 handle
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2847 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2848 mapping
= CreateFileMappingA( handle
, NULL
, PAGE_READWRITE
, 0, 64 * 1024, "DelFileTest" );
2849 ok( mapping
!= NULL
, "failed to create file mapping\n");
2850 CloseHandle( mapping
);
2851 fdi
.DoDeleteFile
= TRUE
;
2852 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2853 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2854 CloseHandle( handle
);
2855 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2856 ok( fileDeleted
, "File should have been deleted\n" );
2857 DeleteFileA( buffer
);
2859 /* cannot set disposition on file which is mapped to memory */
2860 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2861 handle
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2862 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2863 mapping
= CreateFileMappingA( handle
, NULL
, PAGE_READWRITE
, 0, 64 * 1024, "DelFileTest" );
2864 ok( mapping
!= NULL
, "failed to create file mapping\n");
2865 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
2866 ok( ptr
!= NULL
, "MapViewOfFile failed\n");
2867 CloseHandle( mapping
);
2868 fdi
.DoDeleteFile
= TRUE
;
2869 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2870 ok( res
== STATUS_CANNOT_DELETE
, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res
);
2871 CloseHandle( handle
);
2872 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2873 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2874 UnmapViewOfFile( ptr
);
2875 DeleteFileA( buffer
);
2877 /* can set disposition on file which is mapped to memory and unmapped again */
2878 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2879 handle
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2880 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2881 mapping
= CreateFileMappingA( handle
, NULL
, PAGE_READWRITE
, 0, 64 * 1024, "DelFileTest" );
2882 ok( mapping
!= NULL
, "failed to create file mapping\n");
2883 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
2884 ok( ptr
!= NULL
, "MapViewOfFile failed\n");
2885 CloseHandle( mapping
);
2886 UnmapViewOfFile( ptr
);
2887 fdi
.DoDeleteFile
= TRUE
;
2888 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2889 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2890 CloseHandle( handle
);
2891 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2892 ok( fileDeleted
, "File should have been deleted\n" );
2893 DeleteFileA( buffer
);
2896 static void test_iocompletion(void)
2898 HANDLE h
= INVALID_HANDLE_VALUE
;
2901 res
= pNtCreateIoCompletion( &h
, IO_COMPLETION_ALL_ACCESS
, NULL
, 0);
2903 ok( res
== 0, "NtCreateIoCompletion anonymous failed: %x\n", res
);
2904 ok( h
&& h
!= INVALID_HANDLE_VALUE
, "Invalid handle returned\n" );
2906 if ( h
&& h
!= INVALID_HANDLE_VALUE
)
2908 test_iocp_setcompletion(h
);
2909 test_iocp_fileio(h
);
2914 static void test_file_name_information(void)
2916 WCHAR
*file_name
, *volume_prefix
, *expected
;
2917 FILE_NAME_INFORMATION
*info
;
2918 ULONG old_redir
= 1, tmp
;
2919 UINT file_name_size
;
2926 /* GetVolumePathName is not present before w2k */
2927 if (!pGetVolumePathNameW
) {
2928 win_skip("GetVolumePathNameW not found\n");
2932 file_name_size
= GetSystemDirectoryW( NULL
, 0 );
2933 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
2934 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
2935 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
2937 len
= GetSystemDirectoryW( file_name
, file_name_size
);
2938 ok(len
== file_name_size
- 1,
2939 "GetSystemDirectoryW returned %u, expected %u.\n",
2940 len
, file_name_size
- 1);
2942 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
2943 ok(len
, "GetVolumePathNameW failed.\n");
2945 len
= lstrlenW( volume_prefix
);
2946 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
2947 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
2948 expected
[file_name_size
- len
- 1] = '\0';
2950 /* A bit more than we actually need, but it keeps the calculation simple. */
2951 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
2952 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
2954 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( TRUE
, &old_redir
);
2955 h
= CreateFileW( file_name
, GENERIC_READ
,
2956 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
2957 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2958 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( old_redir
, &tmp
);
2959 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
2961 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
) - 1, FileNameInformation
);
2962 ok(hr
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryInformationFile returned %#x.\n", hr
);
2964 memset( info
, 0xcc, info_size
);
2965 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
), FileNameInformation
);
2966 ok(hr
== STATUS_BUFFER_OVERFLOW
, "NtQueryInformationFile returned %#x, expected %#x.\n",
2967 hr
, STATUS_BUFFER_OVERFLOW
);
2968 ok(U(io
).Status
== STATUS_BUFFER_OVERFLOW
, "io.Status is %#x, expected %#x.\n",
2969 U(io
).Status
, STATUS_BUFFER_OVERFLOW
);
2970 ok(info
->FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
), "info->FileNameLength is %u\n", info
->FileNameLength
);
2971 ok(info
->FileName
[2] == 0xcccc, "info->FileName[2] is %#x, expected 0xcccc.\n", info
->FileName
[2]);
2972 ok(CharLowerW((LPWSTR
)(UINT_PTR
)info
->FileName
[1]) == CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]),
2973 "info->FileName[1] is %p, expected %p.\n",
2974 CharLowerW((LPWSTR
)(UINT_PTR
)info
->FileName
[1]), CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]));
2975 ok(io
.Information
== sizeof(*info
), "io.Information is %lu\n", io
.Information
);
2977 memset( info
, 0xcc, info_size
);
2978 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileNameInformation
);
2979 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
2980 ok(U(io
).Status
== STATUS_SUCCESS
, "io.Status is %#x, expected %#x.\n", U(io
).Status
, STATUS_SUCCESS
);
2981 ok(info
->FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
), "info->FileNameLength is %u\n", info
->FileNameLength
);
2982 ok(info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)] == 0xcccc, "info->FileName[len] is %#x, expected 0xcccc.\n",
2983 info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)]);
2984 info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)] = '\0';
2985 ok(!lstrcmpiW( info
->FileName
, expected
), "info->FileName is %s, expected %s.\n",
2986 wine_dbgstr_w( info
->FileName
), wine_dbgstr_w( expected
));
2987 ok(io
.Information
== FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
) + info
->FileNameLength
,
2988 "io.Information is %lu, expected %u.\n",
2989 io
.Information
, FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
) + info
->FileNameLength
);
2992 HeapFree( GetProcessHeap(), 0, info
);
2993 HeapFree( GetProcessHeap(), 0, expected
);
2994 HeapFree( GetProcessHeap(), 0, volume_prefix
);
2996 if (old_redir
|| !pGetSystemWow64DirectoryW
|| !(file_name_size
= pGetSystemWow64DirectoryW( NULL
, 0 )))
2998 skip("Not running on WoW64, skipping test.\n");
2999 HeapFree( GetProcessHeap(), 0, file_name
);
3003 h
= CreateFileW( file_name
, GENERIC_READ
,
3004 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3005 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3006 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3007 HeapFree( GetProcessHeap(), 0, file_name
);
3009 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3010 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3011 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*expected
) );
3013 len
= pGetSystemWow64DirectoryW( file_name
, file_name_size
);
3014 ok(len
== file_name_size
- 1,
3015 "GetSystemWow64DirectoryW returned %u, expected %u.\n",
3016 len
, file_name_size
- 1);
3018 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3019 ok(len
, "GetVolumePathNameW failed.\n");
3021 len
= lstrlenW( volume_prefix
);
3022 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3023 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3024 expected
[file_name_size
- len
- 1] = '\0';
3026 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3027 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3029 memset( info
, 0xcc, info_size
);
3030 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileNameInformation
);
3031 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
3032 info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)] = '\0';
3033 ok(!lstrcmpiW( info
->FileName
, expected
), "info->FileName is %s, expected %s.\n",
3034 wine_dbgstr_w( info
->FileName
), wine_dbgstr_w( expected
));
3037 HeapFree( GetProcessHeap(), 0, info
);
3038 HeapFree( GetProcessHeap(), 0, expected
);
3039 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3040 HeapFree( GetProcessHeap(), 0, file_name
);
3043 static void test_file_all_name_information(void)
3045 WCHAR
*file_name
, *volume_prefix
, *expected
;
3046 FILE_ALL_INFORMATION
*info
;
3047 ULONG old_redir
= 1, tmp
;
3048 UINT file_name_size
;
3055 /* GetVolumePathName is not present before w2k */
3056 if (!pGetVolumePathNameW
) {
3057 win_skip("GetVolumePathNameW not found\n");
3061 file_name_size
= GetSystemDirectoryW( NULL
, 0 );
3062 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3063 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3064 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3066 len
= GetSystemDirectoryW( file_name
, file_name_size
);
3067 ok(len
== file_name_size
- 1,
3068 "GetSystemDirectoryW returned %u, expected %u.\n",
3069 len
, file_name_size
- 1);
3071 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3072 ok(len
, "GetVolumePathNameW failed.\n");
3074 len
= lstrlenW( volume_prefix
);
3075 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3076 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3077 expected
[file_name_size
- len
- 1] = '\0';
3079 /* A bit more than we actually need, but it keeps the calculation simple. */
3080 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3081 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3083 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( TRUE
, &old_redir
);
3084 h
= CreateFileW( file_name
, GENERIC_READ
,
3085 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3086 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3087 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( old_redir
, &tmp
);
3088 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3090 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
) - 1, FileAllInformation
);
3091 ok(hr
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryInformationFile returned %#x, expected %#x.\n",
3092 hr
, STATUS_INFO_LENGTH_MISMATCH
);
3094 memset( info
, 0xcc, info_size
);
3095 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
), FileAllInformation
);
3096 ok(hr
== STATUS_BUFFER_OVERFLOW
, "NtQueryInformationFile returned %#x, expected %#x.\n",
3097 hr
, STATUS_BUFFER_OVERFLOW
);
3098 ok(U(io
).Status
== STATUS_BUFFER_OVERFLOW
, "io.Status is %#x, expected %#x.\n",
3099 U(io
).Status
, STATUS_BUFFER_OVERFLOW
);
3100 ok(info
->NameInformation
.FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
),
3101 "info->NameInformation.FileNameLength is %u\n", info
->NameInformation
.FileNameLength
);
3102 ok(info
->NameInformation
.FileName
[2] == 0xcccc,
3103 "info->NameInformation.FileName[2] is %#x, expected 0xcccc.\n", info
->NameInformation
.FileName
[2]);
3104 ok(CharLowerW((LPWSTR
)(UINT_PTR
)info
->NameInformation
.FileName
[1]) == CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]),
3105 "info->NameInformation.FileName[1] is %p, expected %p.\n",
3106 CharLowerW((LPWSTR
)(UINT_PTR
)info
->NameInformation
.FileName
[1]), CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]));
3107 ok(io
.Information
== sizeof(*info
), "io.Information is %lu\n", io
.Information
);
3109 memset( info
, 0xcc, info_size
);
3110 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileAllInformation
);
3111 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
3112 ok(U(io
).Status
== STATUS_SUCCESS
, "io.Status is %#x, expected %#x.\n", U(io
).Status
, STATUS_SUCCESS
);
3113 ok(info
->NameInformation
.FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
),
3114 "info->NameInformation.FileNameLength is %u\n", info
->NameInformation
.FileNameLength
);
3115 ok(info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)] == 0xcccc,
3116 "info->NameInformation.FileName[len] is %#x, expected 0xcccc.\n",
3117 info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)]);
3118 info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)] = '\0';
3119 ok(!lstrcmpiW( info
->NameInformation
.FileName
, expected
),
3120 "info->NameInformation.FileName is %s, expected %s.\n",
3121 wine_dbgstr_w( info
->NameInformation
.FileName
), wine_dbgstr_w( expected
));
3122 ok(io
.Information
== FIELD_OFFSET(FILE_ALL_INFORMATION
, NameInformation
.FileName
)
3123 + info
->NameInformation
.FileNameLength
,
3124 "io.Information is %lu\n", io
.Information
);
3127 HeapFree( GetProcessHeap(), 0, info
);
3128 HeapFree( GetProcessHeap(), 0, expected
);
3129 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3131 if (old_redir
|| !pGetSystemWow64DirectoryW
|| !(file_name_size
= pGetSystemWow64DirectoryW( NULL
, 0 )))
3133 skip("Not running on WoW64, skipping test.\n");
3134 HeapFree( GetProcessHeap(), 0, file_name
);
3138 h
= CreateFileW( file_name
, GENERIC_READ
,
3139 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3140 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3141 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3142 HeapFree( GetProcessHeap(), 0, file_name
);
3144 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3145 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3146 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*expected
) );
3148 len
= pGetSystemWow64DirectoryW( file_name
, file_name_size
);
3149 ok(len
== file_name_size
- 1,
3150 "GetSystemWow64DirectoryW returned %u, expected %u.\n",
3151 len
, file_name_size
- 1);
3153 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3154 ok(len
, "GetVolumePathNameW failed.\n");
3156 len
= lstrlenW( volume_prefix
);
3157 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3158 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3159 expected
[file_name_size
- len
- 1] = '\0';
3161 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3162 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3164 memset( info
, 0xcc, info_size
);
3165 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileAllInformation
);
3166 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
3167 info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)] = '\0';
3168 ok(!lstrcmpiW( info
->NameInformation
.FileName
, expected
), "info->NameInformation.FileName is %s, expected %s.\n",
3169 wine_dbgstr_w( info
->NameInformation
.FileName
), wine_dbgstr_w( expected
));
3172 HeapFree( GetProcessHeap(), 0, info
);
3173 HeapFree( GetProcessHeap(), 0, expected
);
3174 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3175 HeapFree( GetProcessHeap(), 0, file_name
);
3178 static void test_file_completion_information(void)
3180 static const char buf
[] = "testdata";
3181 FILE_IO_COMPLETION_NOTIFICATION_INFORMATION info
;
3182 OVERLAPPED ov
, *pov
;
3191 if (!(h
= create_temp_file(0))) return;
3193 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
) - 1, FileIoCompletionNotificationInformation
);
3194 ok(status
== STATUS_INFO_LENGTH_MISMATCH
|| status
== STATUS_INVALID_INFO_CLASS
/* XP */,
3195 "expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
3196 if (status
== STATUS_INVALID_INFO_CLASS
|| status
== STATUS_NOT_IMPLEMENTED
)
3198 win_skip("FileIoCompletionNotificationInformation class not supported\n");
3203 info
.Flags
= FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
;
3204 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3205 ok(status
== STATUS_INVALID_PARAMETER
, "expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
3208 if (!(h
= create_temp_file(FILE_FLAG_OVERLAPPED
))) return;
3210 info
.Flags
= FILE_SKIP_SET_EVENT_ON_HANDLE
;
3211 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3212 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3214 info
.Flags
= FILE_SKIP_SET_USER_EVENT_ON_FAST_IO
;
3215 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3216 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3219 if (!(h
= create_temp_file(FILE_FLAG_OVERLAPPED
))) return;
3222 status
= pNtQueryInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3223 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3224 ok(!(info
.Flags
& FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
), "got %08x\n", info
.Flags
);
3226 memset(&ov
, 0, sizeof(ov
));
3227 ov
.hEvent
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
3228 port
= CreateIoCompletionPort(h
, NULL
, 0xdeadbeef, 0);
3229 ok(port
!= NULL
, "CreateIoCompletionPort failed, error %u\n", GetLastError());
3231 for (i
= 0; i
< 10; i
++)
3233 SetLastError(0xdeadbeef);
3234 ret
= WriteFile(h
, buf
, sizeof(buf
), &num_bytes
, &ov
);
3235 if (ret
|| GetLastError() != ERROR_IO_PENDING
) break;
3236 ret
= GetOverlappedResult(h
, &ov
, &num_bytes
, TRUE
);
3237 ok(ret
, "GetOverlappedResult failed, error %u\n", GetLastError());
3238 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 1000);
3239 ok(ret
, "GetQueuedCompletionStatus failed, error %u\n", GetLastError());
3244 ok(num_bytes
== sizeof(buf
), "expected sizeof(buf), got %u\n", num_bytes
);
3248 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 1000);
3249 ok(ret
, "GetQueuedCompletionStatus failed, error %u\n", GetLastError());
3250 ok(key
== 0xdeadbeef, "expected 0xdeadbeef, got %lx\n", key
);
3251 ok(pov
== &ov
, "expected %p, got %p\n", &ov
, pov
);
3254 win_skip("WriteFile never returned TRUE\n");
3256 info
.Flags
= FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
;
3257 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3258 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3261 status
= pNtQueryInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3262 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3263 ok((info
.Flags
& FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
) != 0, "got %08x\n", info
.Flags
);
3265 for (i
= 0; i
< 10; i
++)
3267 SetLastError(0xdeadbeef);
3268 ret
= WriteFile(h
, buf
, sizeof(buf
), &num_bytes
, &ov
);
3269 if (ret
|| GetLastError() != ERROR_IO_PENDING
) break;
3270 ret
= GetOverlappedResult(h
, &ov
, &num_bytes
, TRUE
);
3271 ok(ret
, "GetOverlappedResult failed, error %u\n", GetLastError());
3276 ok(num_bytes
== sizeof(buf
), "expected sizeof(buf), got %u\n", num_bytes
);
3278 pov
= (void *)0xdeadbeef;
3279 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 500);
3280 ok(!ret
, "GetQueuedCompletionStatus succeeded\n");
3281 ok(pov
== NULL
, "expected NULL, got %p\n", pov
);
3284 win_skip("WriteFile never returned TRUE\n");
3287 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3288 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3291 status
= pNtQueryInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3292 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3293 ok((info
.Flags
& FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
) != 0, "got %08x\n", info
.Flags
);
3295 for (i
= 0; i
< 10; i
++)
3297 SetLastError(0xdeadbeef);
3298 ret
= WriteFile(h
, buf
, sizeof(buf
), &num_bytes
, &ov
);
3299 if (ret
|| GetLastError() != ERROR_IO_PENDING
) break;
3300 ret
= GetOverlappedResult(h
, &ov
, &num_bytes
, TRUE
);
3301 ok(ret
, "GetOverlappedResult failed, error %u\n", GetLastError());
3302 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 1000);
3303 ok(ret
, "GetQueuedCompletionStatus failed, error %u\n", GetLastError());
3308 ok(num_bytes
== sizeof(buf
), "expected sizeof(buf), got %u\n", num_bytes
);
3310 pov
= (void *)0xdeadbeef;
3311 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 1000);
3312 ok(!ret
, "GetQueuedCompletionStatus succeeded\n");
3313 ok(pov
== NULL
, "expected NULL, got %p\n", pov
);
3316 win_skip("WriteFile never returned TRUE\n");
3318 CloseHandle(ov
.hEvent
);
3323 static void test_file_id_information(void)
3325 BY_HANDLE_FILE_INFORMATION info
;
3326 FILE_ID_INFORMATION fid
;
3333 if (!(h
= create_temp_file(0))) return;
3335 memset( &fid
, 0x11, sizeof(fid
) );
3336 status
= pNtQueryInformationFile( h
, &io
, &fid
, sizeof(fid
), FileIdInformation
);
3337 if (status
== STATUS_NOT_IMPLEMENTED
|| status
== STATUS_INVALID_INFO_CLASS
)
3339 win_skip( "FileIdInformation not supported\n" );
3344 memset( &info
, 0x22, sizeof(info
) );
3345 ret
= GetFileInformationByHandle( h
, &info
);
3346 ok( ret
, "GetFileInformationByHandle failed\n" );
3348 dwords
= (DWORD
*)&fid
.VolumeSerialNumber
;
3349 ok( dwords
[0] == info
.dwVolumeSerialNumber
, "expected %08x, got %08x\n",
3350 info
.dwVolumeSerialNumber
, dwords
[0] );
3351 ok( dwords
[1] != 0x11111111, "expected != 0x11111111\n" );
3353 dwords
= (DWORD
*)&fid
.FileId
;
3354 ok( dwords
[0] == info
.nFileIndexLow
, "expected %08x, got %08x\n", info
.nFileIndexLow
, dwords
[0] );
3355 ok( dwords
[1] == info
.nFileIndexHigh
, "expected %08x, got %08x\n", info
.nFileIndexHigh
, dwords
[1] );
3356 ok( dwords
[2] == 0, "expected 0, got %08x\n", dwords
[2] );
3357 ok( dwords
[3] == 0, "expected 0, got %08x\n", dwords
[3] );
3362 static void test_file_access_information(void)
3364 FILE_ACCESS_INFORMATION info
;
3369 if (!(h
= create_temp_file(0))) return;
3371 status
= pNtQueryInformationFile( h
, &io
, &info
, sizeof(info
) - 1, FileAccessInformation
);
3372 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
3374 status
= pNtQueryInformationFile( (HANDLE
)0xdeadbeef, &io
, &info
, sizeof(info
), FileAccessInformation
);
3375 ok( status
== STATUS_INVALID_HANDLE
, "expected STATUS_INVALID_HANDLE, got %08x\n", status
);
3377 memset(&info
, 0x11, sizeof(info
));
3378 status
= pNtQueryInformationFile( h
, &io
, &info
, sizeof(info
), FileAccessInformation
);
3379 ok( status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3380 ok( info
.AccessFlags
== 0x13019f, "got %08x\n", info
.AccessFlags
);
3385 static void test_query_volume_information_file(void)
3389 WCHAR path
[MAX_PATH
];
3390 OBJECT_ATTRIBUTES attr
;
3392 UNICODE_STRING nameW
;
3393 FILE_FS_VOLUME_INFORMATION
*ffvi
;
3394 BYTE buf
[sizeof(FILE_FS_VOLUME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
)];
3396 GetWindowsDirectoryW( path
, MAX_PATH
);
3397 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
3398 attr
.Length
= sizeof(attr
);
3399 attr
.RootDirectory
= 0;
3400 attr
.ObjectName
= &nameW
;
3401 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
3402 attr
.SecurityDescriptor
= NULL
;
3403 attr
.SecurityQualityOfService
= NULL
;
3405 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
3406 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
3407 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
3408 pRtlFreeUnicodeString( &nameW
);
3410 ZeroMemory( buf
, sizeof(buf
) );
3411 U(io
).Status
= 0xdadadada;
3412 io
.Information
= 0xcacacaca;
3414 status
= pNtQueryVolumeInformationFile( dir
, &io
, buf
, sizeof(buf
), FileFsVolumeInformation
);
3416 ffvi
= (FILE_FS_VOLUME_INFORMATION
*)buf
;
3418 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", status
);
3419 ok(U(io
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", U(io
).Status
);
3423 ok(io
.Information
== (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION
, VolumeLabel
) + ffvi
->VolumeLabelLength
),
3424 "expected %d, got %lu\n", (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION
, VolumeLabel
) + ffvi
->VolumeLabelLength
),
3427 ok(ffvi
->VolumeCreationTime
.QuadPart
!= 0, "Missing VolumeCreationTime\n");
3428 ok(ffvi
->VolumeSerialNumber
!= 0, "Missing VolumeSerialNumber\n");
3429 ok(ffvi
->SupportsObjects
== 1,"expected 1, got %d\n", ffvi
->SupportsObjects
);
3431 ok(ffvi
->VolumeLabelLength
== lstrlenW(ffvi
->VolumeLabel
) * sizeof(WCHAR
), "got %d\n", ffvi
->VolumeLabelLength
);
3433 trace("VolumeSerialNumber: %x VolumeLabelName: %s\n", ffvi
->VolumeSerialNumber
, wine_dbgstr_w(ffvi
->VolumeLabel
));
3438 static void test_query_attribute_information_file(void)
3442 WCHAR path
[MAX_PATH
];
3443 OBJECT_ATTRIBUTES attr
;
3445 UNICODE_STRING nameW
;
3446 FILE_FS_ATTRIBUTE_INFORMATION
*ffai
;
3447 BYTE buf
[sizeof(FILE_FS_ATTRIBUTE_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
)];
3449 GetWindowsDirectoryW( path
, MAX_PATH
);
3450 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
3451 attr
.Length
= sizeof(attr
);
3452 attr
.RootDirectory
= 0;
3453 attr
.ObjectName
= &nameW
;
3454 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
3455 attr
.SecurityDescriptor
= NULL
;
3456 attr
.SecurityQualityOfService
= NULL
;
3458 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
3459 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
3460 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
3461 pRtlFreeUnicodeString( &nameW
);
3463 ZeroMemory( buf
, sizeof(buf
) );
3464 U(io
).Status
= 0xdadadada;
3465 io
.Information
= 0xcacacaca;
3467 status
= pNtQueryVolumeInformationFile( dir
, &io
, buf
, sizeof(buf
), FileFsAttributeInformation
);
3469 ffai
= (FILE_FS_ATTRIBUTE_INFORMATION
*)buf
;
3471 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", status
);
3472 ok(U(io
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", U(io
).Status
);
3473 ok(ffai
->FileSystemAttribute
!= 0, "Missing FileSystemAttribute\n");
3474 ok(ffai
->MaximumComponentNameLength
!= 0, "Missing MaximumComponentNameLength\n");
3475 ok(ffai
->FileSystemNameLength
!= 0, "Missing FileSystemNameLength\n");
3477 trace("FileSystemAttribute: %x MaximumComponentNameLength: %x FileSystemName: %s\n",
3478 ffai
->FileSystemAttribute
, ffai
->MaximumComponentNameLength
,
3479 wine_dbgstr_wn(ffai
->FileSystemName
, ffai
->FileSystemNameLength
/ sizeof(WCHAR
)));
3484 static void test_NtCreateFile(void)
3486 static const struct test_data
3488 DWORD disposition
, attrib_in
, status
, result
, attrib_out
, needs_cleanup
;
3491 /* 0*/{ FILE_CREATE
, FILE_ATTRIBUTE_READONLY
, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3492 /* 1*/{ FILE_CREATE
, 0, STATUS_OBJECT_NAME_COLLISION
, 0, 0, TRUE
},
3493 /* 2*/{ FILE_CREATE
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3494 /* 3*/{ FILE_OPEN
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OPENED
, FILE_ATTRIBUTE_ARCHIVE
, TRUE
},
3495 /* 4*/{ FILE_OPEN
, FILE_ATTRIBUTE_READONLY
, STATUS_OBJECT_NAME_NOT_FOUND
, 0, 0, FALSE
},
3496 /* 5*/{ FILE_OPEN_IF
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3497 /* 6*/{ FILE_OPEN_IF
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OPENED
, FILE_ATTRIBUTE_ARCHIVE
, TRUE
},
3498 /* 7*/{ FILE_OPEN_IF
, FILE_ATTRIBUTE_READONLY
, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3499 /* 8*/{ FILE_OPEN_IF
, 0, 0, FILE_OPENED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3500 /* 9*/{ FILE_OVERWRITE
, 0, STATUS_ACCESS_DENIED
, 0, 0, TRUE
},
3501 /*10*/{ FILE_OVERWRITE
, 0, STATUS_OBJECT_NAME_NOT_FOUND
, 0, 0, FALSE
},
3502 /*11*/{ FILE_CREATE
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3503 /*12*/{ FILE_OVERWRITE
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OVERWRITTEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3504 /*13*/{ FILE_OVERWRITE_IF
, 0, STATUS_ACCESS_DENIED
, 0, 0, TRUE
},
3505 /*14*/{ FILE_OVERWRITE_IF
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3506 /*15*/{ FILE_OVERWRITE_IF
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OVERWRITTEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3507 /*16*/{ FILE_SUPERSEDE
, 0, 0, FILE_SUPERSEDED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3508 /*17*/{ FILE_SUPERSEDE
, FILE_ATTRIBUTE_READONLY
, 0, FILE_SUPERSEDED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, TRUE
},
3509 /*18*/{ FILE_SUPERSEDE
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, TRUE
}
3511 static const WCHAR fooW
[] = {'f','o','o',0};
3514 WCHAR path
[MAX_PATH
];
3515 OBJECT_ATTRIBUTES attr
;
3517 UNICODE_STRING nameW
;
3520 GetTempPathW(MAX_PATH
, path
);
3521 GetTempFileNameW(path
, fooW
, 0, path
);
3523 pRtlDosPathNameToNtPathName_U(path
, &nameW
, NULL
, NULL
);
3525 attr
.Length
= sizeof(attr
);
3526 attr
.RootDirectory
= NULL
;
3527 attr
.ObjectName
= &nameW
;
3528 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
3529 attr
.SecurityDescriptor
= NULL
;
3530 attr
.SecurityQualityOfService
= NULL
;
3532 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3534 status
= pNtCreateFile(&handle
, GENERIC_READ
, &attr
, &io
, NULL
,
3535 td
[i
].attrib_in
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
3536 td
[i
].disposition
, 0, NULL
, 0);
3538 ok(status
== td
[i
].status
, "%d: expected %#x got %#x\n", i
, td
[i
].status
, status
);
3542 ok(io
.Information
== td
[i
].result
,"%d: expected %#x got %#lx\n", i
, td
[i
].result
, io
.Information
);
3544 ret
= GetFileAttributesW(path
);
3545 ret
&= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
;
3546 /* FIXME: leave only 'else' case below once Wine is fixed */
3547 if (ret
!= td
[i
].attrib_out
)
3550 ok(ret
== td
[i
].attrib_out
, "%d: expected %#x got %#x\n", i
, td
[i
].attrib_out
, ret
);
3551 SetFileAttributesW(path
, td
[i
].attrib_out
);
3554 ok(ret
== td
[i
].attrib_out
, "%d: expected %#x got %#x\n", i
, td
[i
].attrib_out
, ret
);
3556 CloseHandle(handle
);
3559 if (td
[i
].needs_cleanup
)
3561 SetFileAttributesW(path
, FILE_ATTRIBUTE_ARCHIVE
);
3566 pRtlFreeUnicodeString( &nameW
);
3567 SetFileAttributesW(path
, FILE_ATTRIBUTE_ARCHIVE
);
3568 DeleteFileW( path
);
3571 static void test_readonly(void)
3573 static const WCHAR fooW
[] = {'f','o','o',0};
3576 WCHAR path
[MAX_PATH
];
3577 OBJECT_ATTRIBUTES attr
;
3579 UNICODE_STRING nameW
;
3581 GetTempPathW(MAX_PATH
, path
);
3582 GetTempFileNameW(path
, fooW
, 0, path
);
3584 pRtlDosPathNameToNtPathName_U(path
, &nameW
, NULL
, NULL
);
3586 attr
.Length
= sizeof(attr
);
3587 attr
.RootDirectory
= NULL
;
3588 attr
.ObjectName
= &nameW
;
3589 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
3590 attr
.SecurityDescriptor
= NULL
;
3591 attr
.SecurityQualityOfService
= NULL
;
3593 status
= pNtCreateFile(&handle
, GENERIC_READ
, &attr
, &io
, NULL
, FILE_ATTRIBUTE_READONLY
,
3594 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_CREATE
, 0, NULL
, 0);
3595 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3596 CloseHandle(handle
);
3598 status
= pNtOpenFile(&handle
, GENERIC_WRITE
, &attr
, &io
,
3599 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3600 ok(status
== STATUS_ACCESS_DENIED
, "got %#x\n", status
);
3601 CloseHandle(handle
);
3603 status
= pNtOpenFile(&handle
, GENERIC_READ
, &attr
, &io
,
3604 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3605 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3606 CloseHandle(handle
);
3608 status
= pNtOpenFile(&handle
, FILE_READ_ATTRIBUTES
, &attr
, &io
,
3609 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3610 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3611 CloseHandle(handle
);
3613 status
= pNtOpenFile(&handle
, FILE_WRITE_ATTRIBUTES
, &attr
, &io
,
3614 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3615 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3616 CloseHandle(handle
);
3618 status
= pNtOpenFile(&handle
, DELETE
, &attr
, &io
,
3619 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3620 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3621 CloseHandle(handle
);
3623 status
= pNtOpenFile(&handle
, READ_CONTROL
, &attr
, &io
,
3624 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3625 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3626 CloseHandle(handle
);
3628 status
= pNtOpenFile(&handle
, WRITE_DAC
, &attr
, &io
,
3629 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3630 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3631 CloseHandle(handle
);
3633 status
= pNtOpenFile(&handle
, WRITE_OWNER
, &attr
, &io
,
3634 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3635 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3636 CloseHandle(handle
);
3638 status
= pNtOpenFile(&handle
, SYNCHRONIZE
, &attr
, &io
,
3639 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3640 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3641 CloseHandle( handle
);
3643 pRtlFreeUnicodeString(&nameW
);
3644 SetFileAttributesW(path
, FILE_ATTRIBUTE_ARCHIVE
);
3648 static void test_read_write(void)
3650 static const char contents
[14] = "1234567890abcd";
3652 HANDLE hfile
, event
;
3654 IO_STATUS_BLOCK iob
;
3655 DWORD ret
, bytes
, status
, off
;
3656 LARGE_INTEGER offset
;
3659 event
= CreateEventA( NULL
, TRUE
, FALSE
, NULL
);
3662 iob
.Information
= -1;
3663 offset
.QuadPart
= 0;
3664 status
= pNtReadFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3665 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status
);
3666 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3667 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3670 iob
.Information
= -1;
3671 offset
.QuadPart
= 0;
3672 status
= pNtReadFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, NULL
, sizeof(buf
), &offset
, NULL
);
3673 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status
);
3674 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3675 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3678 iob
.Information
= -1;
3679 offset
.QuadPart
= 0;
3680 status
= pNtWriteFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3681 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status
);
3682 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3683 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3686 iob
.Information
= -1;
3687 offset
.QuadPart
= 0;
3688 status
= pNtWriteFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3689 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status
);
3690 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3691 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3693 hfile
= create_temp_file(0);
3697 iob
.Information
= -1;
3698 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
3699 ok(status
== STATUS_INVALID_USER_BUFFER
, "expected STATUS_INVALID_USER_BUFFER, got %#x\n", status
);
3700 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3701 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3704 iob
.Information
= -1;
3706 status
= pNtWriteFile(hfile
, event
, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
3707 ok(status
== STATUS_INVALID_USER_BUFFER
, "expected STATUS_INVALID_USER_BUFFER, got %#x\n", status
);
3708 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3709 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3710 ok(!is_signaled(event
), "event is not signaled\n");
3713 iob
.Information
= -1;
3714 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
3715 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#x\n", status
);
3716 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3717 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3720 iob
.Information
= -1;
3722 status
= pNtReadFile(hfile
, event
, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
3723 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#x\n", status
);
3724 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3725 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3726 ok(is_signaled(event
), "event is not signaled\n");
3729 iob
.Information
= -1;
3731 status
= pNtReadFile(hfile
, event
, NULL
, NULL
, &iob
, (void*)0xdeadbeef, sizeof(contents
), NULL
, NULL
);
3732 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#x\n", status
);
3733 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3734 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3735 ok(is_signaled(event
), "event is not signaled\n");
3738 iob
.Information
= -1;
3739 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, 7, NULL
, NULL
);
3740 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
3741 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3742 ok(iob
.Information
== 7, "expected 7, got %lu\n", iob
.Information
);
3744 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3747 iob
.Information
= -1;
3748 offset
.QuadPart
= (LONGLONG
)-1 /* FILE_WRITE_TO_END_OF_FILE */;
3749 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
+ 7, sizeof(contents
) - 7, &offset
, NULL
);
3750 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
3751 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3752 ok(iob
.Information
== sizeof(contents
) - 7, "expected sizeof(contents)-7, got %lu\n", iob
.Information
);
3754 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3755 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3758 SetLastError(0xdeadbeef);
3759 ret
= ReadFile(INVALID_HANDLE_VALUE
, buf
, 0, &bytes
, NULL
);
3760 ok(!ret
, "ReadFile should fail\n");
3761 ok(GetLastError() == ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
3762 ok(bytes
== 0, "bytes %u\n", bytes
);
3765 SetLastError(0xdeadbeef);
3766 ret
= ReadFile(hfile
, buf
, 0, &bytes
, NULL
);
3767 ok(ret
, "ReadFile error %d\n", GetLastError());
3768 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3769 ok(bytes
== 0, "bytes %u\n", bytes
);
3772 SetLastError(0xdeadbeef);
3773 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3774 ok(ret
, "ReadFile error %d\n", GetLastError());
3775 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3776 ok(bytes
== 0, "bytes %u\n", bytes
);
3778 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3781 SetLastError(0xdeadbeef);
3782 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3783 ok(ret
, "ReadFile error %d\n", GetLastError());
3784 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3785 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
3787 for (i
= -20; i
< -1; i
++)
3789 if (i
== -2) continue;
3792 iob
.Information
= -1;
3793 offset
.QuadPart
= (LONGLONG
)i
;
3794 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), &offset
, NULL
);
3795 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
3796 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3797 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
3800 SetFilePointer(hfile
, sizeof(contents
) - 4, NULL
, FILE_BEGIN
);
3803 iob
.Information
= -1;
3804 offset
.QuadPart
= (LONGLONG
)-2 /* FILE_USE_FILE_POINTER_POSITION */;
3805 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, "DCBA", 4, &offset
, NULL
);
3806 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
3807 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3808 ok(iob
.Information
== 4, "expected 4, got %lu\n", iob
.Information
);
3810 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3811 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3814 iob
.Information
= -1;
3815 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), NULL
, NULL
);
3816 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3817 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3818 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3820 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3823 SetLastError(0xdeadbeef);
3824 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3825 ok(ret
, "ReadFile error %d\n", GetLastError());
3826 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3827 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
3828 ok(!memcmp(buf
+ sizeof(contents
) - 4, "DCBA", 4), "file contents mismatch\n");
3830 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3831 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3833 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3836 SetLastError(0xdeadbeef);
3837 ret
= WriteFile(hfile
, contents
, sizeof(contents
), &bytes
, NULL
);
3838 ok(ret
, "WriteFile error %d\n", GetLastError());
3839 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3841 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3842 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3844 /* test reading beyond EOF */
3846 SetLastError(0xdeadbeef);
3847 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3848 ok(ret
, "ReadFile error %d\n", GetLastError());
3849 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3850 ok(bytes
== 0, "bytes %u\n", bytes
);
3853 SetLastError(0xdeadbeef);
3854 ret
= ReadFile(hfile
, buf
, 0, &bytes
, NULL
);
3855 ok(ret
, "ReadFile error %d\n", GetLastError());
3856 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3857 ok(bytes
== 0, "bytes %u\n", bytes
);
3860 SetLastError(0xdeadbeef);
3861 ret
= ReadFile(hfile
, NULL
, 0, &bytes
, NULL
);
3862 ok(ret
, "ReadFile error %d\n", GetLastError());
3863 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3864 ok(bytes
== 0, "bytes %u\n", bytes
);
3866 S(U(ovl
)).Offset
= sizeof(contents
);
3867 S(U(ovl
)).OffsetHigh
= 0;
3869 ovl
.InternalHigh
= -1;
3872 SetLastError(0xdeadbeef);
3873 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
3874 ok(!ret
, "ReadFile should fail\n");
3875 ok(GetLastError() == ERROR_HANDLE_EOF
, "expected ERROR_HANDLE_EOF, got %d\n", GetLastError());
3876 ok(bytes
== 0, "bytes %u\n", bytes
);
3877 ok((NTSTATUS
)ovl
.Internal
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", ovl
.Internal
);
3878 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
3880 S(U(ovl
)).Offset
= sizeof(contents
);
3881 S(U(ovl
)).OffsetHigh
= 0;
3883 ovl
.InternalHigh
= -1;
3886 SetLastError(0xdeadbeef);
3887 ret
= ReadFile(hfile
, buf
, 0, &bytes
, &ovl
);
3888 ok(ret
, "ReadFile error %d\n", GetLastError());
3889 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3890 ok(bytes
== 0, "bytes %u\n", bytes
);
3891 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
3892 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
3895 iob
.Information
= -1;
3896 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), NULL
, NULL
);
3897 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3898 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3899 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3902 iob
.Information
= -1;
3903 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, NULL
, NULL
);
3904 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3905 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3906 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3909 iob
.Information
= -1;
3910 offset
.QuadPart
= sizeof(contents
);
3911 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3912 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3913 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3914 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3917 iob
.Information
= -1;
3918 offset
.QuadPart
= sizeof(contents
);
3919 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, &offset
, NULL
);
3920 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3921 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3922 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3925 iob
.Information
= -1;
3926 offset
.QuadPart
= (LONGLONG
)-2 /* FILE_USE_FILE_POINTER_POSITION */;
3927 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3928 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3929 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3930 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3933 iob
.Information
= -1;
3934 offset
.QuadPart
= (LONGLONG
)-2 /* FILE_USE_FILE_POINTER_POSITION */;
3935 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, &offset
, NULL
);
3936 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3937 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3938 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3940 for (i
= -20; i
< 0; i
++)
3942 if (i
== -2) continue;
3945 iob
.Information
= -1;
3946 offset
.QuadPart
= (LONGLONG
)i
;
3947 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3948 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
3949 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3950 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
3953 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3956 SetLastError(0xdeadbeef);
3957 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3958 ok(ret
, "ReadFile error %d\n", GetLastError());
3959 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3960 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
3962 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3963 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3966 iob
.Information
= -1;
3967 offset
.QuadPart
= 0;
3968 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &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
== sizeof(contents
), "expected sizeof(contents), got %lu\n", iob
.Information
);
3972 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
3974 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3975 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3978 iob
.Information
= -1;
3979 offset
.QuadPart
= sizeof(contents
) - 4;
3980 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, "DCBA", 4, &offset
, NULL
);
3981 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
3982 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3983 ok(iob
.Information
== 4, "expected 4, got %lu\n", iob
.Information
);
3985 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3986 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3989 iob
.Information
= -1;
3990 offset
.QuadPart
= 0;
3991 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3992 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3993 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3994 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %lu\n", iob
.Information
);
3995 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
3996 ok(!memcmp(buf
+ sizeof(contents
) - 4, "DCBA", 4), "file contents mismatch\n");
3998 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3999 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
4001 S(U(ovl
)).Offset
= sizeof(contents
) - 4;
4002 S(U(ovl
)).OffsetHigh
= 0;
4005 SetLastError(0xdeadbeef);
4006 ret
= WriteFile(hfile
, "ABCD", 4, &bytes
, &ovl
);
4007 ok(ret
, "WriteFile error %d\n", GetLastError());
4008 ok(bytes
== 4, "bytes %u\n", bytes
);
4010 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4011 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
4013 S(U(ovl
)).Offset
= 0;
4014 S(U(ovl
)).OffsetHigh
= 0;
4016 ovl
.InternalHigh
= -1;
4019 SetLastError(0xdeadbeef);
4020 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4021 ok(ret
, "ReadFile error %d\n", GetLastError());
4022 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
4023 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4024 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4025 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
4026 ok(!memcmp(buf
+ sizeof(contents
) - 4, "ABCD", 4), "file contents mismatch\n");
4028 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4029 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
4033 hfile
= create_temp_file(FILE_FLAG_OVERLAPPED
);
4037 SetLastError(0xdeadbeef);
4038 ret
= ReadFile(INVALID_HANDLE_VALUE
, buf
, 0, &bytes
, NULL
);
4039 ok(!ret
, "ReadFile should fail\n");
4040 ok(GetLastError() == ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
4041 ok(bytes
== 0, "bytes %u\n", bytes
);
4043 S(U(ovl
)).Offset
= 0;
4044 S(U(ovl
)).OffsetHigh
= 0;
4046 ovl
.InternalHigh
= -1;
4049 SetLastError(0xdeadbeef);
4050 /* ReadFile return value depends on Windows version and testing it is not practical */
4051 ReadFile(hfile
, buf
, 0, &bytes
, &ovl
);
4052 ok(bytes
== 0, "bytes %u\n", bytes
);
4053 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4054 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
4057 SetLastError(0xdeadbeef);
4058 ret
= WriteFile(hfile
, contents
, sizeof(contents
), &bytes
, NULL
);
4059 ok(!ret
, "WriteFile should fail\n");
4060 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
4061 ok(bytes
== 0, "bytes %u\n", bytes
);
4064 iob
.Information
= -1;
4065 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), NULL
, NULL
);
4066 ok(status
== STATUS_INVALID_PARAMETER
, "expected STATUS_INVALID_PARAMETER, got %#x\n", status
);
4067 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4068 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
4070 for (i
= -20; i
< -1; i
++)
4073 iob
.Information
= -1;
4074 offset
.QuadPart
= (LONGLONG
)i
;
4075 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), &offset
, NULL
);
4076 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
4077 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4078 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
4082 iob
.Information
= -1;
4083 offset
.QuadPart
= 0;
4084 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), &offset
, NULL
);
4085 ok(status
== STATUS_PENDING
|| status
== STATUS_SUCCESS
/* before Vista */, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status
);
4086 if (status
== STATUS_PENDING
)
4088 ret
= WaitForSingleObject(hfile
, 3000);
4089 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4091 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4092 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %lu\n", iob
.Information
);
4094 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4095 ok(off
== 0, "expected 0, got %u\n", off
);
4098 SetLastError(0xdeadbeef);
4099 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
4100 ok(!ret
, "ReadFile should fail\n");
4101 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
4102 ok(bytes
== 0, "bytes %u\n", bytes
);
4105 iob
.Information
= -1;
4106 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), NULL
, NULL
);
4107 ok(status
== STATUS_INVALID_PARAMETER
, "expected STATUS_INVALID_PARAMETER, got %#x\n", status
);
4108 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4109 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
4111 for (i
= -20; i
< 0; i
++)
4114 iob
.Information
= -1;
4115 offset
.QuadPart
= (LONGLONG
)i
;
4116 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4117 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
4118 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4119 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
4122 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4123 ok(off
== 0, "expected 0, got %u\n", off
);
4125 /* test reading beyond EOF */
4126 offset
.QuadPart
= sizeof(contents
);
4127 S(U(ovl
)).Offset
= offset
.u
.LowPart
;
4128 S(U(ovl
)).OffsetHigh
= offset
.u
.HighPart
;
4130 ovl
.InternalHigh
= -1;
4133 SetLastError(0xdeadbeef);
4134 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4135 ok(!ret
, "ReadFile should fail\n");
4136 ret
= GetLastError();
4137 ok(ret
== ERROR_IO_PENDING
|| ret
== ERROR_HANDLE_EOF
/* before Vista */, "expected ERROR_IO_PENDING or ERROR_HANDLE_EOF, got %d\n", ret
);
4138 ok(bytes
== 0, "bytes %u\n", bytes
);
4140 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4141 ok(off
== 0, "expected 0, got %u\n", off
);
4143 if (ret
== ERROR_IO_PENDING
)
4146 SetLastError(0xdeadbeef);
4147 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4148 ok(!ret
, "GetOverlappedResult should report FALSE\n");
4149 ok(GetLastError() == ERROR_HANDLE_EOF
, "expected ERROR_HANDLE_EOF, got %d\n", GetLastError());
4150 ok(bytes
== 0, "expected 0, read %u\n", bytes
);
4151 ok((NTSTATUS
)ovl
.Internal
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", ovl
.Internal
);
4152 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
4155 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4156 ok(off
== 0, "expected 0, got %u\n", off
);
4158 offset
.QuadPart
= sizeof(contents
);
4159 S(U(ovl
)).Offset
= offset
.u
.LowPart
;
4160 S(U(ovl
)).OffsetHigh
= offset
.u
.HighPart
;
4162 ovl
.InternalHigh
= -1;
4165 SetLastError(0xdeadbeef);
4166 ret
= ReadFile(hfile
, buf
, 0, &bytes
, &ovl
);
4167 /* ReadFile return value depends on Windows version and testing it is not practical */
4169 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4170 ret
= GetLastError();
4171 ok(bytes
== 0, "bytes %u\n", bytes
);
4173 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4174 ok(off
== 0, "expected 0, got %u\n", off
);
4176 if (ret
== ERROR_IO_PENDING
)
4179 SetLastError(0xdeadbeef);
4180 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4181 ok(ret
, "GetOverlappedResult should report TRUE\n");
4182 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
4183 ok(bytes
== 0, "expected 0, read %u\n", bytes
);
4184 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4185 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
4188 offset
.QuadPart
= sizeof(contents
);
4189 S(U(ovl
)).Offset
= offset
.u
.LowPart
;
4190 S(U(ovl
)).OffsetHigh
= offset
.u
.HighPart
;
4192 ovl
.InternalHigh
= -1;
4195 SetLastError(0xdeadbeef);
4196 ret
= ReadFile(hfile
, NULL
, 0, &bytes
, &ovl
);
4197 /* ReadFile return value depends on Windows version and testing it is not practical */
4199 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4200 ret
= GetLastError();
4201 ok(bytes
== 0, "bytes %u\n", bytes
);
4203 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4204 ok(off
== 0, "expected 0, got %u\n", off
);
4206 if (ret
== ERROR_IO_PENDING
)
4209 SetLastError(0xdeadbeef);
4210 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4211 ok(ret
, "GetOverlappedResult should report TRUE\n");
4212 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
4213 ok(bytes
== 0, "expected 0, read %u\n", bytes
);
4214 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4215 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
4219 iob
.Information
= -1;
4220 offset
.QuadPart
= sizeof(contents
);
4221 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4222 if (status
== STATUS_PENDING
)
4224 ret
= WaitForSingleObject(hfile
, 3000);
4225 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4226 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
4227 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
4231 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
4232 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4233 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
4236 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4237 ok(off
== 0, "expected 0, got %u\n", off
);
4240 iob
.Information
= -1;
4241 offset
.QuadPart
= sizeof(contents
);
4242 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, &offset
, NULL
);
4243 if (status
== STATUS_PENDING
)
4245 ret
= WaitForSingleObject(hfile
, 3000);
4246 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4247 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4248 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
4252 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", status
);
4253 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4254 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
4257 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4258 ok(off
== 0, "expected 0, got %u\n", off
);
4260 S(U(ovl
)).Offset
= 0;
4261 S(U(ovl
)).OffsetHigh
= 0;
4263 ovl
.InternalHigh
= -1;
4266 SetLastError(0xdeadbeef);
4267 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4268 /* ReadFile return value depends on Windows version and testing it is not practical */
4271 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4272 ok(bytes
== 0, "bytes %u\n", bytes
);
4274 else ok(bytes
== 14, "bytes %u\n", bytes
);
4275 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4276 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4278 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4279 ok(off
== 0, "expected 0, got %u\n", off
);
4282 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4283 ok(ret
, "GetOverlappedResult error %d\n", GetLastError());
4284 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
4285 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4286 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4287 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
4289 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4290 ok(off
== 0, "expected 0, got %u\n", off
);
4292 SetFilePointer(hfile
, sizeof(contents
) - 4, NULL
, FILE_BEGIN
);
4293 SetEndOfFile(hfile
);
4294 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
4297 iob
.Information
= -1;
4298 offset
.QuadPart
= (LONGLONG
)-1 /* FILE_WRITE_TO_END_OF_FILE */;
4299 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, "DCBA", 4, &offset
, NULL
);
4300 ok(status
== STATUS_PENDING
|| status
== STATUS_SUCCESS
/* before Vista */, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status
);
4301 if (status
== STATUS_PENDING
)
4303 ret
= WaitForSingleObject(hfile
, 3000);
4304 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4306 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4307 ok(iob
.Information
== 4, "expected 4, got %lu\n", iob
.Information
);
4309 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4310 ok(off
== 0, "expected 0, got %u\n", off
);
4313 iob
.Information
= -1;
4314 offset
.QuadPart
= 0;
4315 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4316 ok(status
== STATUS_PENDING
|| status
== STATUS_SUCCESS
, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status
);
4317 if (status
== STATUS_PENDING
)
4319 ret
= WaitForSingleObject(hfile
, 3000);
4320 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4322 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4323 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %lu\n", iob
.Information
);
4325 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4326 ok(off
== 0, "expected 0, got %u\n", off
);
4328 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
4329 ok(!memcmp(buf
+ sizeof(contents
) - 4, "DCBA", 4), "file contents mismatch\n");
4331 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4332 ok(off
== 0, "expected 0, got %u\n", off
);
4334 S(U(ovl
)).Offset
= sizeof(contents
) - 4;
4335 S(U(ovl
)).OffsetHigh
= 0;
4337 ovl
.InternalHigh
= -1;
4340 SetLastError(0xdeadbeef);
4341 ret
= WriteFile(hfile
, "ABCD", 4, &bytes
, &ovl
);
4342 /* WriteFile return value depends on Windows version and testing it is not practical */
4345 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4346 ok(bytes
== 0, "bytes %u\n", bytes
);
4347 ret
= WaitForSingleObject(hfile
, 3000);
4348 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4350 else ok(bytes
== 4, "bytes %u\n", bytes
);
4351 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4352 ok(ovl
.InternalHigh
== 4, "expected 4, got %lu\n", ovl
.InternalHigh
);
4354 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4355 ok(off
== 0, "expected 0, got %u\n", off
);
4358 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4359 ok(ret
, "GetOverlappedResult error %d\n", GetLastError());
4360 ok(bytes
== 4, "bytes %u\n", bytes
);
4361 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4362 ok(ovl
.InternalHigh
== 4, "expected 4, got %lu\n", ovl
.InternalHigh
);
4364 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4365 ok(off
== 0, "expected 0, got %u\n", off
);
4367 S(U(ovl
)).Offset
= 0;
4368 S(U(ovl
)).OffsetHigh
= 0;
4370 ovl
.InternalHigh
= -1;
4373 SetLastError(0xdeadbeef);
4374 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4375 /* ReadFile return value depends on Windows version and testing it is not practical */
4378 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4379 ok(bytes
== 0, "bytes %u\n", bytes
);
4380 ret
= WaitForSingleObject(hfile
, 3000);
4381 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4383 else ok(bytes
== 14, "bytes %u\n", bytes
);
4384 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4385 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4387 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4388 ok(off
== 0, "expected 0, got %u\n", off
);
4391 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4392 ok(ret
, "GetOverlappedResult error %d\n", GetLastError());
4393 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
4394 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4395 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4396 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
4397 ok(!memcmp(buf
+ sizeof(contents
) - 4, "ABCD", 4), "file contents mismatch\n");
4399 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4400 ok(off
== 0, "expected 0, got %u\n", off
);
4406 static void test_ioctl(void)
4408 HANDLE event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
4409 IO_STATUS_BLOCK iosb
;
4413 file
= create_temp_file(FILE_FLAG_OVERLAPPED
);
4414 ok(file
!= INVALID_HANDLE_VALUE
, "could not create temp file\n");
4417 status
= pNtFsControlFile(file
, event
, NULL
, NULL
, &iosb
, 0xdeadbeef, 0, 0, 0, 0);
4419 ok(status
== STATUS_INVALID_DEVICE_REQUEST
, "NtFsControlFile returned %x\n", status
);
4420 ok(!is_signaled(event
), "event is signaled\n");
4422 status
= pNtFsControlFile(file
, (HANDLE
)0xdeadbeef, NULL
, NULL
, &iosb
, 0xdeadbeef, 0, 0, 0, 0);
4423 ok(status
== STATUS_INVALID_HANDLE
, "NtFsControlFile returned %x\n", status
);
4429 static void test_flush_buffers_file(void)
4431 char path
[MAX_PATH
], buffer
[MAX_PATH
];
4432 HANDLE hfile
, hfileread
;
4434 IO_STATUS_BLOCK io_status_block
;
4436 GetTempPathA(MAX_PATH
, path
);
4437 GetTempFileNameA(path
, "foo", 0, buffer
);
4438 hfile
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
, FILE_SHARE_READ
, NULL
, CREATE_ALWAYS
,
4439 FILE_ATTRIBUTE_NORMAL
, 0);
4440 ok(hfile
!= INVALID_HANDLE_VALUE
, "failed to create temp file.\n" );
4442 hfileread
= CreateFileA(buffer
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
4443 OPEN_EXISTING
, 0, NULL
);
4444 ok(hfileread
!= INVALID_HANDLE_VALUE
, "could not open temp file, error %d.\n", GetLastError());
4446 status
= pNtFlushBuffersFile(hfile
, NULL
);
4448 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#x.\n", status
);
4450 status
= pNtFlushBuffersFile(hfile
, (IO_STATUS_BLOCK
*)0xdeadbeaf);
4452 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#x.\n", status
);
4454 status
= pNtFlushBuffersFile(hfile
, &io_status_block
);
4455 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x.\n", status
);
4457 status
= pNtFlushBuffersFile(hfileread
, &io_status_block
);
4458 ok(status
== STATUS_ACCESS_DENIED
, "expected STATUS_ACCESS_DENIED, got %#x.\n", status
);
4460 status
= pNtFlushBuffersFile(NULL
, &io_status_block
);
4461 ok(status
== STATUS_INVALID_HANDLE
, "expected STATUS_INVALID_HANDLE, got %#x.\n", status
);
4463 CloseHandle(hfileread
);
4465 hfile
= CreateFileA(buffer
, FILE_APPEND_DATA
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
4466 OPEN_EXISTING
, 0, NULL
);
4467 ok(hfile
!= INVALID_HANDLE_VALUE
, "could not open temp file, error %d.\n", GetLastError());
4469 status
= pNtFlushBuffersFile(hfile
, &io_status_block
);
4470 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x.\n", status
);
4473 DeleteFileA(buffer
);
4476 static void test_query_ea(void)
4478 #define EA_BUFFER_SIZE 4097
4479 unsigned char data
[EA_BUFFER_SIZE
+ 8];
4480 unsigned char *buffer
= (void *)(((DWORD_PTR
)data
+ 7) & ~7);
4481 DWORD buffer_len
, i
;
4486 if (!(handle
= create_temp_file(0))) return;
4488 /* test with INVALID_HANDLE_VALUE */
4489 U(io
).Status
= 0xdeadbeef;
4490 io
.Information
= 0xdeadbeef;
4491 memset(buffer
, 0xcc, EA_BUFFER_SIZE
);
4492 buffer_len
= EA_BUFFER_SIZE
- 1;
4493 status
= pNtQueryEaFile(INVALID_HANDLE_VALUE
, &io
, buffer
, buffer_len
, TRUE
, NULL
, 0, NULL
, FALSE
);
4494 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %x\n", status
);
4495 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io
).Status
);
4496 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io
.Information
);
4497 ok(buffer
[0] == 0xcc, "data at position 0 overwritten\n");
4499 /* test with 0xdeadbeef */
4500 U(io
).Status
= 0xdeadbeef;
4501 io
.Information
= 0xdeadbeef;
4502 memset(buffer
, 0xcc, EA_BUFFER_SIZE
);
4503 buffer_len
= EA_BUFFER_SIZE
- 1;
4504 status
= pNtQueryEaFile((void *)0xdeadbeef, &io
, buffer
, buffer_len
, TRUE
, NULL
, 0, NULL
, FALSE
);
4505 ok(status
== STATUS_INVALID_HANDLE
, "expected STATUS_INVALID_HANDLE, got %x\n", status
);
4506 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io
).Status
);
4507 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io
.Information
);
4508 ok(buffer
[0] == 0xcc, "data at position 0 overwritten\n");
4510 /* test without buffer */
4511 U(io
).Status
= 0xdeadbeef;
4512 io
.Information
= 0xdeadbeef;
4513 status
= pNtQueryEaFile(handle
, &io
, NULL
, 0, TRUE
, NULL
, 0, NULL
, FALSE
);
4514 ok(status
== STATUS_NO_EAS_ON_FILE
, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status
);
4515 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io
).Status
);
4516 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io
.Information
);
4518 /* test with zero buffer */
4519 U(io
).Status
= 0xdeadbeef;
4520 io
.Information
= 0xdeadbeef;
4521 status
= pNtQueryEaFile(handle
, &io
, buffer
, 0, TRUE
, NULL
, 0, NULL
, FALSE
);
4522 ok(status
== STATUS_NO_EAS_ON_FILE
, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status
);
4523 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io
).Status
);
4524 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io
.Information
);
4526 /* test with very small buffer */
4527 U(io
).Status
= 0xdeadbeef;
4528 io
.Information
= 0xdeadbeef;
4529 memset(buffer
, 0xcc, EA_BUFFER_SIZE
);
4531 status
= pNtQueryEaFile(handle
, &io
, buffer
, buffer_len
, TRUE
, NULL
, 0, NULL
, FALSE
);
4532 ok(status
== STATUS_NO_EAS_ON_FILE
, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status
);
4533 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io
).Status
);
4534 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io
.Information
);
4535 for (i
= 0; i
< buffer_len
&& !buffer
[i
]; i
++);
4536 ok(i
== buffer_len
, "expected %u bytes filled with 0x00, got %u bytes\n", buffer_len
, i
);
4537 ok(buffer
[i
] == 0xcc, "data at position %u overwritten\n", buffer
[i
]);
4539 /* test with very big buffer */
4540 U(io
).Status
= 0xdeadbeef;
4541 io
.Information
= 0xdeadbeef;
4542 memset(buffer
, 0xcc, EA_BUFFER_SIZE
);
4543 buffer_len
= EA_BUFFER_SIZE
- 1;
4544 status
= pNtQueryEaFile(handle
, &io
, buffer
, buffer_len
, TRUE
, NULL
, 0, NULL
, FALSE
);
4545 ok(status
== STATUS_NO_EAS_ON_FILE
, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status
);
4546 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io
).Status
);
4547 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io
.Information
);
4548 for (i
= 0; i
< buffer_len
&& !buffer
[i
]; i
++);
4549 ok(i
== buffer_len
, "expected %u bytes filled with 0x00, got %u bytes\n", buffer_len
, i
);
4550 ok(buffer
[i
] == 0xcc, "data at position %u overwritten\n", buffer
[i
]);
4552 CloseHandle(handle
);
4553 #undef EA_BUFFER_SIZE
4556 static INT
build_reparse_buffer(WCHAR
*filename
, REPARSE_DATA_BUFFER
**pbuffer
)
4558 REPARSE_DATA_BUFFER
*buffer
;
4559 INT buffer_len
, string_len
;
4562 string_len
= (lstrlenW(filename
)+1)*sizeof(WCHAR
);
4563 buffer_len
= FIELD_OFFSET(REPARSE_DATA_BUFFER
, MountPointReparseBuffer
.PathBuffer
[1]) + string_len
;
4564 buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, buffer_len
);
4565 buffer
->ReparseTag
= IO_REPARSE_TAG_MOUNT_POINT
;
4566 buffer
->ReparseDataLength
= sizeof(buffer
->MountPointReparseBuffer
) + string_len
;
4567 buffer
->MountPointReparseBuffer
.SubstituteNameLength
= string_len
- sizeof(WCHAR
);
4568 buffer
->MountPointReparseBuffer
.PrintNameOffset
= string_len
;
4569 dest
= &buffer
->MountPointReparseBuffer
.PathBuffer
[0];
4570 memcpy(dest
, filename
, string_len
);
4575 static void test_junction_points(void)
4577 static const WCHAR junctionW
[] = {'\\','j','u','n','c','t','i','o','n',0};
4578 WCHAR path
[MAX_PATH
], junction_path
[MAX_PATH
], target_path
[MAX_PATH
];
4579 static const WCHAR targetW
[] = {'\\','t','a','r','g','e','t',0};
4580 FILE_BASIC_INFORMATION old_attrib
, new_attrib
;
4581 static const WCHAR fooW
[] = {'f','o','o',0};
4582 static WCHAR volW
[] = {'c',':','\\',0};
4583 REPARSE_GUID_DATA_BUFFER guid_buffer
;
4584 static const WCHAR dotW
[] = {'.',0};
4585 REPARSE_DATA_BUFFER
*buffer
= NULL
;
4586 DWORD dwret
, dwLen
, dwFlags
, err
;
4587 INT buffer_len
, string_len
;
4588 IO_STATUS_BLOCK iosb
;
4589 UNICODE_STRING nameW
;
4594 /* Create a temporary folder for the junction point tests */
4595 GetTempFileNameW(dotW
, fooW
, 0, path
);
4597 if (!CreateDirectoryW(path
, NULL
))
4599 win_skip("Unable to create a temporary junction point directory.\n");
4603 /* Check that the volume this folder is located on supports junction points */
4604 pRtlDosPathNameToNtPathName_U(path
, &nameW
, NULL
, NULL
);
4605 volW
[0] = nameW
.Buffer
[4];
4606 pRtlFreeUnicodeString( &nameW
);
4607 GetVolumeInformationW(volW
, 0, 0, 0, &dwLen
, &dwFlags
, 0, 0);
4608 if (!(dwFlags
& FILE_SUPPORTS_REPARSE_POINTS
))
4610 skip("File system does not support junction points.\n");
4611 RemoveDirectoryW(path
);
4615 /* Create the folder to be replaced by a junction point */
4616 lstrcpyW(junction_path
, path
);
4617 lstrcatW(junction_path
, junctionW
);
4618 bret
= CreateDirectoryW(junction_path
, NULL
);
4619 ok(bret
, "Failed to create junction point directory.\n");
4621 /* Create a destination folder for the junction point to target */
4622 lstrcpyW(target_path
, path
);
4623 lstrcatW(target_path
, targetW
);
4624 bret
= CreateDirectoryW(target_path
, NULL
);
4625 ok(bret
, "Failed to create junction point target directory.\n");
4626 pRtlDosPathNameToNtPathName_U(target_path
, &nameW
, NULL
, NULL
);
4628 /* Create the junction point */
4629 hJunction
= CreateFileW(junction_path
, GENERIC_READ
| GENERIC_WRITE
, 0, 0, OPEN_EXISTING
,
4630 FILE_FLAG_BACKUP_SEMANTICS
| FILE_FLAG_OPEN_REPARSE_POINT
, 0);
4631 if (hJunction
== INVALID_HANDLE_VALUE
)
4633 win_skip("Failed to open junction point directory handle (0x%x).\n", GetLastError());
4636 dwret
= NtQueryInformationFile(hJunction
, &iosb
, &old_attrib
, sizeof(old_attrib
), FileBasicInformation
);
4637 ok(dwret
== STATUS_SUCCESS
, "Failed to get junction point folder's attributes (0x%x).\n", dwret
);
4638 buffer_len
= build_reparse_buffer(nameW
.Buffer
, &buffer
);
4639 bret
= DeviceIoControl(hJunction
, FSCTL_SET_REPARSE_POINT
, (LPVOID
)buffer
, buffer_len
, NULL
, 0, &dwret
, 0);
4640 ok(bret
, "Failed to create junction point! (0x%x)\n", GetLastError());
4642 /* Check the file attributes of the junction point */
4643 dwret
= GetFileAttributesW(junction_path
);
4644 ok(dwret
!= (DWORD
)~0, "Junction point doesn't exist (attributes: 0x%x)!\n", dwret
);
4645 ok(dwret
& FILE_ATTRIBUTE_REPARSE_POINT
, "File is not a junction point! (attributes: %d)\n", dwret
);
4647 /* Read back the junction point */
4648 HeapFree(GetProcessHeap(), 0, buffer
);
4649 buffer_len
= sizeof(*buffer
) + MAX_PATH
*sizeof(WCHAR
);
4650 buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, buffer_len
);
4651 bret
= DeviceIoControl(hJunction
, FSCTL_GET_REPARSE_POINT
, NULL
, 0, (LPVOID
)buffer
, buffer_len
, &dwret
, 0);
4652 string_len
= buffer
->MountPointReparseBuffer
.SubstituteNameLength
;
4653 dest
= &buffer
->MountPointReparseBuffer
.PathBuffer
[buffer
->MountPointReparseBuffer
.SubstituteNameOffset
/sizeof(WCHAR
)];
4654 ok(bret
, "Failed to read junction point!\n");
4655 ok((memcmp(dest
, nameW
.Buffer
, string_len
) == 0), "Junction point destination does not match ('%s' != '%s')!\n",
4656 wine_dbgstr_w(dest
), wine_dbgstr_w(nameW
.Buffer
));
4658 /* Delete the junction point */
4659 memset(&old_attrib
, 0x00, sizeof(old_attrib
));
4660 old_attrib
.LastAccessTime
.QuadPart
= 0x200deadcafebeef;
4661 dwret
= NtSetInformationFile(hJunction
, &iosb
, &old_attrib
, sizeof(old_attrib
), FileBasicInformation
);
4662 ok(dwret
== STATUS_SUCCESS
, "Failed to set junction point folder's attributes (0x%x).\n", dwret
);
4663 memset(&guid_buffer
, 0x00, sizeof(guid_buffer
));
4664 guid_buffer
.ReparseTag
= IO_REPARSE_TAG_MOUNT_POINT
;
4665 bret
= DeviceIoControl(hJunction
, FSCTL_DELETE_REPARSE_POINT
, (LPVOID
)&guid_buffer
,
4666 REPARSE_GUID_DATA_BUFFER_HEADER_SIZE
, NULL
, 0, &dwret
, 0);
4667 ok(bret
, "Failed to delete junction point! (0x%x)\n", GetLastError());
4668 memset(&new_attrib
, 0x00, sizeof(new_attrib
));
4669 dwret
= NtQueryInformationFile(hJunction
, &iosb
, &new_attrib
, sizeof(new_attrib
), FileBasicInformation
);
4670 ok(dwret
== STATUS_SUCCESS
, "Failed to get junction point folder's attributes (0x%x).\n", dwret
);
4671 ok(old_attrib
.LastAccessTime
.QuadPart
== new_attrib
.LastAccessTime
.QuadPart
,
4672 "Junction point folder's access time does not match.\n");
4673 CloseHandle(hJunction
);
4675 /* Check deleting a junction point as if it were a directory */
4676 HeapFree(GetProcessHeap(), 0, buffer
);
4677 hJunction
= CreateFileW(junction_path
, GENERIC_READ
| GENERIC_WRITE
, 0, 0, OPEN_EXISTING
,
4678 FILE_FLAG_BACKUP_SEMANTICS
| FILE_FLAG_OPEN_REPARSE_POINT
, 0);
4679 buffer_len
= build_reparse_buffer(nameW
.Buffer
, &buffer
);
4680 bret
= DeviceIoControl(hJunction
, FSCTL_SET_REPARSE_POINT
, (LPVOID
)buffer
, buffer_len
, NULL
, 0, &dwret
, 0);
4681 ok(bret
, "Failed to create junction point! (0x%x)\n", GetLastError());
4682 CloseHandle(hJunction
);
4683 bret
= RemoveDirectoryW(junction_path
);
4684 ok(bret
, "Failed to delete junction point as directory!\n");
4685 dwret
= GetFileAttributesW(junction_path
);
4686 ok(dwret
== (DWORD
)~0, "Junction point still exists (attributes: 0x%x)!\n", dwret
);
4688 /* Check deleting a junction point as if it were a file */
4689 HeapFree(GetProcessHeap(), 0, buffer
);
4690 bret
= CreateDirectoryW(junction_path
, NULL
);
4691 ok(bret
, "Failed to create junction point target directory.\n");
4692 hJunction
= CreateFileW(junction_path
, GENERIC_READ
| GENERIC_WRITE
, 0, 0, OPEN_EXISTING
,
4693 FILE_FLAG_BACKUP_SEMANTICS
| FILE_FLAG_OPEN_REPARSE_POINT
, 0);
4694 buffer_len
= build_reparse_buffer(nameW
.Buffer
, &buffer
);
4695 bret
= DeviceIoControl(hJunction
, FSCTL_SET_REPARSE_POINT
, (LPVOID
)buffer
, buffer_len
, NULL
, 0, &dwret
, 0);
4696 ok(bret
, "Failed to create junction point! (0x%x)\n", GetLastError());
4697 CloseHandle(hJunction
);
4698 bret
= DeleteFileW(junction_path
);
4699 ok(!bret
, "Succeeded in deleting junction point as file!\n");
4700 err
= GetLastError();
4701 ok(err
== ERROR_ACCESS_DENIED
, "Expected last error 0x%x for DeleteFile on junction point (actually 0x%x)!\n",
4702 ERROR_ACCESS_DENIED
, err
);
4703 dwret
= GetFileAttributesW(junction_path
);
4704 ok(dwret
!= (DWORD
)~0, "Junction point doesn't exist (attributes: 0x%x)!\n", dwret
);
4705 ok(dwret
& FILE_ATTRIBUTE_REPARSE_POINT
, "File is not a junction point! (attributes: 0x%x)\n", dwret
);
4707 /* Test deleting a junction point's target */
4708 dwret
= GetFileAttributesW(junction_path
);
4709 ok(dwret
== 0x410 || broken(dwret
== 0x430) /* win2k */,
4710 "Unexpected junction point attributes (0x%x != 0x410)!\n", dwret
);
4711 bret
= RemoveDirectoryW(target_path
);
4712 ok(bret
, "Failed to delete junction point target!\n");
4713 bret
= CreateDirectoryW(target_path
, NULL
);
4714 ok(bret
, "Failed to create junction point target directory.\n");
4718 pRtlFreeUnicodeString( &nameW
);
4719 HeapFree(GetProcessHeap(), 0, buffer
);
4720 bret
= RemoveDirectoryW(junction_path
);
4721 ok(bret
, "Failed to remove temporary junction point directory!\n");
4722 bret
= RemoveDirectoryW(target_path
);
4723 ok(bret
, "Failed to remove temporary target directory!\n");
4724 RemoveDirectoryW(path
);
4729 HMODULE hkernel32
= GetModuleHandleA("kernel32.dll");
4730 HMODULE hntdll
= GetModuleHandleA("ntdll.dll");
4733 skip("not running on NT, skipping test\n");
4737 pGetVolumePathNameW
= (void *)GetProcAddress(hkernel32
, "GetVolumePathNameW");
4738 pGetSystemWow64DirectoryW
= (void *)GetProcAddress(hkernel32
, "GetSystemWow64DirectoryW");
4740 pRtlFreeUnicodeString
= (void *)GetProcAddress(hntdll
, "RtlFreeUnicodeString");
4741 pRtlInitUnicodeString
= (void *)GetProcAddress(hntdll
, "RtlInitUnicodeString");
4742 pRtlDosPathNameToNtPathName_U
= (void *)GetProcAddress(hntdll
, "RtlDosPathNameToNtPathName_U");
4743 pRtlWow64EnableFsRedirectionEx
= (void *)GetProcAddress(hntdll
, "RtlWow64EnableFsRedirectionEx");
4744 pNtCreateMailslotFile
= (void *)GetProcAddress(hntdll
, "NtCreateMailslotFile");
4745 pNtCreateFile
= (void *)GetProcAddress(hntdll
, "NtCreateFile");
4746 pNtOpenFile
= (void *)GetProcAddress(hntdll
, "NtOpenFile");
4747 pNtDeleteFile
= (void *)GetProcAddress(hntdll
, "NtDeleteFile");
4748 pNtReadFile
= (void *)GetProcAddress(hntdll
, "NtReadFile");
4749 pNtWriteFile
= (void *)GetProcAddress(hntdll
, "NtWriteFile");
4750 pNtCancelIoFile
= (void *)GetProcAddress(hntdll
, "NtCancelIoFile");
4751 pNtCancelIoFileEx
= (void *)GetProcAddress(hntdll
, "NtCancelIoFileEx");
4752 pNtClose
= (void *)GetProcAddress(hntdll
, "NtClose");
4753 pNtFsControlFile
= (void *)GetProcAddress(hntdll
, "NtFsControlFile");
4754 pNtCreateIoCompletion
= (void *)GetProcAddress(hntdll
, "NtCreateIoCompletion");
4755 pNtOpenIoCompletion
= (void *)GetProcAddress(hntdll
, "NtOpenIoCompletion");
4756 pNtQueryIoCompletion
= (void *)GetProcAddress(hntdll
, "NtQueryIoCompletion");
4757 pNtRemoveIoCompletion
= (void *)GetProcAddress(hntdll
, "NtRemoveIoCompletion");
4758 pNtSetIoCompletion
= (void *)GetProcAddress(hntdll
, "NtSetIoCompletion");
4759 pNtSetInformationFile
= (void *)GetProcAddress(hntdll
, "NtSetInformationFile");
4760 pNtQueryInformationFile
= (void *)GetProcAddress(hntdll
, "NtQueryInformationFile");
4761 pNtQueryDirectoryFile
= (void *)GetProcAddress(hntdll
, "NtQueryDirectoryFile");
4762 pNtQueryVolumeInformationFile
= (void *)GetProcAddress(hntdll
, "NtQueryVolumeInformationFile");
4763 pNtQueryFullAttributesFile
= (void *)GetProcAddress(hntdll
, "NtQueryFullAttributesFile");
4764 pNtFlushBuffersFile
= (void *)GetProcAddress(hntdll
, "NtFlushBuffersFile");
4765 pNtQueryEaFile
= (void *)GetProcAddress(hntdll
, "NtQueryEaFile");
4768 test_NtCreateFile();
4776 test_iocompletion();
4777 test_file_basic_information();
4778 test_file_all_information();
4779 test_file_both_information();
4780 test_file_name_information();
4781 test_file_full_size_information();
4782 test_file_all_name_information();
4783 test_file_rename_information();
4784 test_file_link_information();
4785 test_file_disposition_information();
4786 test_file_completion_information();
4787 test_file_id_information();
4788 test_file_access_information();
4789 test_query_volume_information_file();
4790 test_query_attribute_information_file();
4792 test_flush_buffers_file();
4794 test_junction_points();