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"
44 typedef struct _REPARSE_DATA_BUFFER
{
46 USHORT ReparseDataLength
;
48 _ANONYMOUS_UNION
union {
50 USHORT SubstituteNameOffset
;
51 USHORT SubstituteNameLength
;
52 USHORT PrintNameOffset
;
53 USHORT PrintNameLength
;
56 } SymbolicLinkReparseBuffer
;
58 USHORT SubstituteNameOffset
;
59 USHORT SubstituteNameLength
;
60 USHORT PrintNameOffset
;
61 USHORT PrintNameLength
;
63 } MountPointReparseBuffer
;
66 } GenericReparseBuffer
;
68 } REPARSE_DATA_BUFFER
, *PREPARSE_DATA_BUFFER
;
71 #ifndef IO_COMPLETION_ALL_ACCESS
72 #define IO_COMPLETION_ALL_ACCESS 0x001F0003
75 static BOOL (WINAPI
* pGetVolumePathNameW
)(LPCWSTR
, LPWSTR
, DWORD
);
76 static UINT (WINAPI
*pGetSystemWow64DirectoryW
)( LPWSTR
, UINT
);
78 static VOID (WINAPI
*pRtlFreeUnicodeString
)( PUNICODE_STRING
);
79 static VOID (WINAPI
*pRtlInitUnicodeString
)( PUNICODE_STRING
, LPCWSTR
);
80 static BOOL (WINAPI
*pRtlDosPathNameToNtPathName_U
)( LPCWSTR
, PUNICODE_STRING
, PWSTR
*, CURDIR
* );
81 static NTSTATUS (WINAPI
*pRtlWow64EnableFsRedirectionEx
)( ULONG
, ULONG
* );
83 static NTSTATUS (WINAPI
*pNtCreateMailslotFile
)( PHANDLE
, ULONG
, POBJECT_ATTRIBUTES
, PIO_STATUS_BLOCK
,
84 ULONG
, ULONG
, ULONG
, PLARGE_INTEGER
);
85 static NTSTATUS (WINAPI
*pNtCreateFile
)(PHANDLE
,ACCESS_MASK
,POBJECT_ATTRIBUTES
,PIO_STATUS_BLOCK
,PLARGE_INTEGER
,ULONG
,ULONG
,ULONG
,ULONG
,PVOID
,ULONG
);
86 static NTSTATUS (WINAPI
*pNtOpenFile
)(PHANDLE
,ACCESS_MASK
,POBJECT_ATTRIBUTES
,PIO_STATUS_BLOCK
,ULONG
,ULONG
);
87 static NTSTATUS (WINAPI
*pNtDeleteFile
)(POBJECT_ATTRIBUTES ObjectAttributes
);
88 static NTSTATUS (WINAPI
*pNtReadFile
)(HANDLE hFile
, HANDLE hEvent
,
89 PIO_APC_ROUTINE apc
, void* apc_user
,
90 PIO_STATUS_BLOCK io_status
, void* buffer
, ULONG length
,
91 PLARGE_INTEGER offset
, PULONG key
);
92 static NTSTATUS (WINAPI
*pNtWriteFile
)(HANDLE hFile
, HANDLE hEvent
,
93 PIO_APC_ROUTINE apc
, void* apc_user
,
94 PIO_STATUS_BLOCK io_status
,
95 const void* buffer
, ULONG length
,
96 PLARGE_INTEGER offset
, PULONG key
);
97 static NTSTATUS (WINAPI
*pNtCancelIoFile
)(HANDLE hFile
, PIO_STATUS_BLOCK io_status
);
98 static NTSTATUS (WINAPI
*pNtCancelIoFileEx
)(HANDLE hFile
, PIO_STATUS_BLOCK iosb
, PIO_STATUS_BLOCK io_status
);
99 static NTSTATUS (WINAPI
*pNtClose
)( PHANDLE
);
100 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
);
102 static NTSTATUS (WINAPI
*pNtCreateIoCompletion
)(PHANDLE
, ACCESS_MASK
, POBJECT_ATTRIBUTES
, ULONG
);
103 static NTSTATUS (WINAPI
*pNtOpenIoCompletion
)(PHANDLE
, ACCESS_MASK
, POBJECT_ATTRIBUTES
);
104 static NTSTATUS (WINAPI
*pNtQueryIoCompletion
)(HANDLE
, IO_COMPLETION_INFORMATION_CLASS
, PVOID
, ULONG
, PULONG
);
105 static NTSTATUS (WINAPI
*pNtRemoveIoCompletion
)(HANDLE
, PULONG_PTR
, PULONG_PTR
, PIO_STATUS_BLOCK
, PLARGE_INTEGER
);
106 static NTSTATUS (WINAPI
*pNtSetIoCompletion
)(HANDLE
, ULONG_PTR
, ULONG_PTR
, NTSTATUS
, SIZE_T
);
107 static NTSTATUS (WINAPI
*pNtSetInformationFile
)(HANDLE
, PIO_STATUS_BLOCK
, PVOID
, ULONG
, FILE_INFORMATION_CLASS
);
108 static NTSTATUS (WINAPI
*pNtQueryInformationFile
)(HANDLE
, PIO_STATUS_BLOCK
, PVOID
, ULONG
, FILE_INFORMATION_CLASS
);
109 static NTSTATUS (WINAPI
*pNtQueryDirectoryFile
)(HANDLE
,HANDLE
,PIO_APC_ROUTINE
,PVOID
,PIO_STATUS_BLOCK
,
110 PVOID
,ULONG
,FILE_INFORMATION_CLASS
,BOOLEAN
,PUNICODE_STRING
,BOOLEAN
);
111 static NTSTATUS (WINAPI
*pNtQueryVolumeInformationFile
)(HANDLE
,PIO_STATUS_BLOCK
,PVOID
,ULONG
,FS_INFORMATION_CLASS
);
112 static NTSTATUS (WINAPI
*pNtQueryFullAttributesFile
)(const OBJECT_ATTRIBUTES
*, FILE_NETWORK_OPEN_INFORMATION
*);
113 static NTSTATUS (WINAPI
*pNtFlushBuffersFile
)(HANDLE
, IO_STATUS_BLOCK
*);
114 static NTSTATUS (WINAPI
*pNtQueryEaFile
)(HANDLE
,PIO_STATUS_BLOCK
,PVOID
,ULONG
,BOOLEAN
,PVOID
,ULONG
,PULONG
,BOOLEAN
);
116 static inline BOOL
is_signaled( HANDLE obj
)
118 return WaitForSingleObject( obj
, 0 ) == WAIT_OBJECT_0
;
121 #define TEST_BUF_LEN 3
123 static HANDLE
create_temp_file( ULONG flags
)
125 char path
[MAX_PATH
], buffer
[MAX_PATH
];
128 GetTempPathA( MAX_PATH
, path
);
129 GetTempFileNameA( path
, "foo", 0, buffer
);
130 handle
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
131 flags
| FILE_FLAG_DELETE_ON_CLOSE
, 0);
132 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
133 return (handle
== INVALID_HANDLE_VALUE
) ? 0 : handle
;
136 #define CVALUE_FIRST 0xfffabbcc
137 #define CKEY_FIRST 0x1030341
138 #define CKEY_SECOND 0x132E46
140 static ULONG_PTR completionKey
;
141 static IO_STATUS_BLOCK ioSb
;
142 static ULONG_PTR completionValue
;
144 static ULONG
get_pending_msgs(HANDLE h
)
149 res
= pNtQueryIoCompletion( h
, IoCompletionBasicInformation
, &a
, sizeof(a
), &req
);
150 ok( res
== STATUS_SUCCESS
, "NtQueryIoCompletion failed: %x\n", res
);
151 if (res
!= STATUS_SUCCESS
) return -1;
152 ok( req
== sizeof(a
), "Unexpected response size: %x\n", req
);
156 static BOOL
get_msg(HANDLE h
)
158 LARGE_INTEGER timeout
= {{-10000000*3}};
159 DWORD res
= pNtRemoveIoCompletion( h
, &completionKey
, &completionValue
, &ioSb
, &timeout
);
160 ok( res
== STATUS_SUCCESS
, "NtRemoveIoCompletion failed: %x\n", res
);
161 if (res
!= STATUS_SUCCESS
)
163 completionKey
= completionValue
= 0;
164 memset(&ioSb
, 0, sizeof(ioSb
));
171 static void WINAPI
apc( void *arg
, IO_STATUS_BLOCK
*iosb
, ULONG reserved
)
175 trace( "apc called block %p iosb.status %x iosb.info %lu\n",
176 iosb
, U(*iosb
).Status
, iosb
->Information
);
178 ok( !reserved
, "reserved is not 0: %x\n", reserved
);
181 static void create_file_test(void)
183 static const WCHAR notepadW
[] = {'n','o','t','e','p','a','d','.','e','x','e',0};
184 static const WCHAR systemrootW
[] = {'\\','S','y','s','t','e','m','R','o','o','t',
185 '\\','f','a','i','l','i','n','g',0};
186 static const WCHAR systemrootExplorerW
[] = {'\\','S','y','s','t','e','m','R','o','o','t',
187 '\\','e','x','p','l','o','r','e','r','.','e','x','e',0};
188 static const WCHAR questionmarkInvalidNameW
[] = {'a','f','i','l','e','?',0};
189 static const WCHAR pipeInvalidNameW
[] = {'a','|','b',0};
190 static const WCHAR pathInvalidNtW
[] = {'\\','\\','?','\\',0};
191 static const WCHAR pathInvalidNt2W
[] = {'\\','?','?','\\',0};
192 static const WCHAR pathInvalidDosW
[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0};
193 static const char testdata
[] = "Hello World";
194 static const WCHAR sepW
[] = {'\\',0};
195 FILE_NETWORK_OPEN_INFORMATION info
;
198 WCHAR path
[MAX_PATH
], temp
[MAX_PATH
];
199 OBJECT_ATTRIBUTES attr
;
201 UNICODE_STRING nameW
;
202 LARGE_INTEGER offset
;
206 GetCurrentDirectoryW( MAX_PATH
, path
);
207 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
208 attr
.Length
= sizeof(attr
);
209 attr
.RootDirectory
= 0;
210 attr
.ObjectName
= &nameW
;
211 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
212 attr
.SecurityDescriptor
= NULL
;
213 attr
.SecurityQualityOfService
= NULL
;
215 /* try various open modes and options on directories */
216 status
= pNtCreateFile( &dir
, GENERIC_READ
|GENERIC_WRITE
, &attr
, &io
, NULL
, 0,
217 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, FILE_DIRECTORY_FILE
, NULL
, 0 );
218 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
220 U(io
).Status
= 0xdeadbeef;
222 status
= pNtReadFile( dir
, NULL
, NULL
, NULL
, &io
, buf
, sizeof(buf
), &offset
, NULL
);
223 ok( status
== STATUS_INVALID_DEVICE_REQUEST
|| status
== STATUS_PENDING
, "NtReadFile error %08x\n", status
);
224 if (status
== STATUS_PENDING
)
226 ret
= WaitForSingleObject( dir
, 1000 );
227 ok( ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %u\n", ret
);
228 ok( U(io
).Status
== STATUS_INVALID_DEVICE_REQUEST
,
229 "expected STATUS_INVALID_DEVICE_REQUEST, got %08x\n", U(io
).Status
);
232 U(io
).Status
= 0xdeadbeef;
234 status
= pNtWriteFile( dir
, NULL
, NULL
, NULL
, &io
, testdata
, sizeof(testdata
), &offset
, NULL
);
236 ok( status
== STATUS_INVALID_DEVICE_REQUEST
|| status
== STATUS_PENDING
, "NtWriteFile error %08x\n", status
);
237 if (status
== STATUS_PENDING
)
239 ret
= WaitForSingleObject( dir
, 1000 );
240 ok( ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %u\n", ret
);
241 ok( U(io
).Status
== STATUS_INVALID_DEVICE_REQUEST
,
242 "expected STATUS_INVALID_DEVICE_REQUEST, got %08x\n", U(io
).Status
);
247 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
248 FILE_CREATE
, FILE_DIRECTORY_FILE
, NULL
, 0 );
249 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
250 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
252 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
253 FILE_OPEN_IF
, FILE_DIRECTORY_FILE
, NULL
, 0 );
254 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
257 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
258 FILE_SUPERSEDE
, FILE_DIRECTORY_FILE
, NULL
, 0 );
259 ok( status
== STATUS_INVALID_PARAMETER
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
261 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
262 FILE_OVERWRITE
, FILE_DIRECTORY_FILE
, NULL
, 0 );
263 ok( status
== STATUS_INVALID_PARAMETER
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
265 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
266 FILE_OVERWRITE_IF
, FILE_DIRECTORY_FILE
, NULL
, 0 );
267 ok( status
== STATUS_INVALID_PARAMETER
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
269 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
270 FILE_OPEN
, 0, NULL
, 0 );
271 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
274 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
275 FILE_CREATE
, 0, NULL
, 0 );
276 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
277 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
279 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
280 FILE_OPEN_IF
, 0, NULL
, 0 );
281 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
284 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
285 FILE_SUPERSEDE
, 0, NULL
, 0 );
286 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
287 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
289 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
290 FILE_OVERWRITE
, 0, NULL
, 0 );
291 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
292 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
294 status
= pNtCreateFile( &dir
, GENERIC_READ
, &attr
, &io
, NULL
, 0, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
295 FILE_OVERWRITE_IF
, 0, NULL
, 0 );
296 ok( status
== STATUS_OBJECT_NAME_COLLISION
|| status
== STATUS_ACCESS_DENIED
,
297 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
299 pRtlFreeUnicodeString( &nameW
);
301 pRtlInitUnicodeString( &nameW
, systemrootW
);
302 attr
.Length
= sizeof(attr
);
303 attr
.RootDirectory
= NULL
;
304 attr
.ObjectName
= &nameW
;
305 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
306 attr
.SecurityDescriptor
= NULL
;
307 attr
.SecurityQualityOfService
= NULL
;
309 status
= pNtCreateFile( &dir
, FILE_APPEND_DATA
, &attr
, &io
, NULL
, FILE_ATTRIBUTE_NORMAL
, 0,
310 FILE_OPEN_IF
, FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
312 ok( status
== STATUS_INVALID_PARAMETER
,
313 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
315 /* Invalid chars in file/dirnames */
316 pRtlDosPathNameToNtPathName_U(questionmarkInvalidNameW
, &nameW
, NULL
, NULL
);
317 attr
.ObjectName
= &nameW
;
318 status
= pNtCreateFile(&dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
319 FILE_SHARE_READ
, FILE_CREATE
,
320 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
321 ok(status
== STATUS_OBJECT_NAME_INVALID
,
322 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
324 status
= pNtCreateFile(&file
, GENERIC_WRITE
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
326 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
327 ok(status
== STATUS_OBJECT_NAME_INVALID
,
328 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
329 pRtlFreeUnicodeString(&nameW
);
331 pRtlDosPathNameToNtPathName_U(pipeInvalidNameW
, &nameW
, NULL
, NULL
);
332 attr
.ObjectName
= &nameW
;
333 status
= pNtCreateFile(&dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
334 FILE_SHARE_READ
, FILE_CREATE
,
335 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
336 ok(status
== STATUS_OBJECT_NAME_INVALID
,
337 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
339 status
= pNtCreateFile(&file
, GENERIC_WRITE
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
341 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0);
342 ok(status
== STATUS_OBJECT_NAME_INVALID
,
343 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
344 pRtlFreeUnicodeString(&nameW
);
346 pRtlInitUnicodeString( &nameW
, pathInvalidNtW
);
347 status
= pNtCreateFile( &dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
348 FILE_SHARE_READ
, FILE_CREATE
,
349 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
350 ok( status
== STATUS_OBJECT_NAME_INVALID
,
351 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
353 status
= pNtQueryFullAttributesFile( &attr
, &info
);
354 todo_wine
ok( status
== STATUS_OBJECT_NAME_INVALID
,
355 "query %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
357 pRtlInitUnicodeString( &nameW
, pathInvalidNt2W
);
358 status
= pNtCreateFile( &dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
359 FILE_SHARE_READ
, FILE_CREATE
,
360 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
361 ok( status
== STATUS_OBJECT_NAME_INVALID
,
362 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
364 status
= pNtQueryFullAttributesFile( &attr
, &info
);
365 ok( status
== STATUS_OBJECT_NAME_INVALID
,
366 "query %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
368 pRtlInitUnicodeString( &nameW
, pathInvalidDosW
);
369 status
= pNtCreateFile( &dir
, GENERIC_READ
|SYNCHRONIZE
, &attr
, &io
, NULL
, 0,
370 FILE_SHARE_READ
, FILE_CREATE
,
371 FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
372 ok( status
== STATUS_OBJECT_NAME_INVALID
,
373 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
375 status
= pNtQueryFullAttributesFile( &attr
, &info
);
376 ok( status
== STATUS_OBJECT_NAME_INVALID
,
377 "query %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
379 GetWindowsDirectoryW( path
, MAX_PATH
);
381 ok( QueryDosDeviceW( path
, temp
, MAX_PATH
),
382 "QueryDosDeviceW failed with error %u\n", GetLastError() );
383 lstrcatW( temp
, sepW
);
384 lstrcatW( temp
, path
+3 );
385 lstrcatW( temp
, sepW
);
386 lstrcatW( temp
, notepadW
);
388 pRtlInitUnicodeString( &nameW
, temp
);
389 status
= pNtQueryFullAttributesFile( &attr
, &info
);
390 ok( status
== STATUS_SUCCESS
,
391 "query %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
393 pRtlInitUnicodeString( &nameW
, systemrootExplorerW
);
394 status
= pNtQueryFullAttributesFile( &attr
, &info
);
395 ok( status
== STATUS_SUCCESS
,
396 "query %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
399 static void open_file_test(void)
401 static const char testdata
[] = "Hello World";
402 static WCHAR fooW
[] = {'f','o','o',0};
404 HANDLE dir
, root
, handle
, file
;
405 WCHAR path
[MAX_PATH
], tmpfile
[MAX_PATH
];
407 OBJECT_ATTRIBUTES attr
;
409 UNICODE_STRING nameW
;
411 BOOL ret
, restart
= TRUE
;
414 len
= GetWindowsDirectoryW( path
, MAX_PATH
);
415 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
416 attr
.Length
= sizeof(attr
);
417 attr
.RootDirectory
= 0;
418 attr
.ObjectName
= &nameW
;
419 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
420 attr
.SecurityDescriptor
= NULL
;
421 attr
.SecurityQualityOfService
= NULL
;
422 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
423 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
424 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
425 pRtlFreeUnicodeString( &nameW
);
427 path
[3] = 0; /* root of the drive */
428 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
429 status
= pNtOpenFile( &root
, GENERIC_READ
, &attr
, &io
,
430 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
431 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
432 pRtlFreeUnicodeString( &nameW
);
434 /* test opening system dir with RootDirectory set to windows dir */
435 GetSystemDirectoryW( path
, MAX_PATH
);
436 while (path
[len
] == '\\') len
++;
437 nameW
.Buffer
= path
+ len
;
438 nameW
.Length
= lstrlenW(path
+ len
) * sizeof(WCHAR
);
439 attr
.RootDirectory
= dir
;
440 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
441 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
442 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
443 CloseHandle( handle
);
445 /* try uppercase name */
446 for (i
= len
; path
[i
]; i
++) if (path
[i
] >= 'a' && path
[i
] <= 'z') path
[i
] -= 'a' - 'A';
447 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
448 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
449 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
450 CloseHandle( handle
);
452 /* try with leading backslash */
454 nameW
.Length
+= sizeof(WCHAR
);
455 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
456 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
457 ok( status
== STATUS_INVALID_PARAMETER
||
458 status
== STATUS_OBJECT_NAME_INVALID
||
459 status
== STATUS_OBJECT_PATH_SYNTAX_BAD
,
460 "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
461 if (!status
) CloseHandle( handle
);
463 /* try with empty name */
465 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
466 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
);
467 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
468 CloseHandle( handle
);
470 /* try open by file id */
472 while (!pNtQueryDirectoryFile( dir
, NULL
, NULL
, NULL
, &io
, data
, sizeof(data
),
473 FileIdBothDirectoryInformation
, TRUE
, NULL
, restart
))
475 FILE_ID_BOTH_DIRECTORY_INFORMATION
*info
= (FILE_ID_BOTH_DIRECTORY_INFORMATION
*)data
;
479 if (!info
->FileId
.QuadPart
) continue;
481 nameW
.Buffer
= (WCHAR
*)&info
->FileId
;
482 nameW
.Length
= sizeof(info
->FileId
);
483 info
->FileName
[info
->FileNameLength
/sizeof(WCHAR
)] = 0;
484 attr
.RootDirectory
= dir
;
485 /* We skip 'open' files by not specifying FILE_SHARE_WRITE */
486 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
488 FILE_OPEN_BY_FILE_ID
|
489 ((info
->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) ? FILE_DIRECTORY_FILE
: 0) );
490 ok( status
== STATUS_SUCCESS
|| status
== STATUS_ACCESS_DENIED
|| status
== STATUS_NOT_IMPLEMENTED
|| status
== STATUS_SHARING_VIOLATION
,
491 "open %s failed %x\n", wine_dbgstr_w(info
->FileName
), status
);
492 if (status
== STATUS_NOT_IMPLEMENTED
)
494 win_skip( "FILE_OPEN_BY_FILE_ID not supported\n" );
497 if (status
== STATUS_SHARING_VIOLATION
)
498 trace( "%s is currently open\n", wine_dbgstr_w(info
->FileName
) );
501 BYTE buf
[sizeof(FILE_ALL_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
)];
503 if (!pNtQueryInformationFile( handle
, &io
, buf
, sizeof(buf
), FileAllInformation
))
505 FILE_ALL_INFORMATION
*fai
= (FILE_ALL_INFORMATION
*)buf
;
507 /* check that it's the same file/directory */
509 /* don't check the size for directories */
510 if (!(info
->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
511 ok( info
->EndOfFile
.QuadPart
== fai
->StandardInformation
.EndOfFile
.QuadPart
,
512 "mismatched file size for %s\n", wine_dbgstr_w(info
->FileName
));
514 ok( info
->CreationTime
.QuadPart
== fai
->BasicInformation
.CreationTime
.QuadPart
,
515 "mismatched creation time for %s\n", wine_dbgstr_w(info
->FileName
));
517 CloseHandle( handle
);
519 /* try same thing from drive root */
520 attr
.RootDirectory
= root
;
521 status
= pNtOpenFile( &handle
, GENERIC_READ
, &attr
, &io
,
522 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
523 FILE_OPEN_BY_FILE_ID
|
524 ((info
->FileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) ? FILE_DIRECTORY_FILE
: 0) );
525 ok( status
== STATUS_SUCCESS
|| status
== STATUS_NOT_IMPLEMENTED
,
526 "open %s failed %x\n", wine_dbgstr_w(info
->FileName
), status
);
527 if (!status
) CloseHandle( handle
);
534 GetTempPathW( MAX_PATH
, path
);
535 GetTempFileNameW( path
, fooW
, 0, tmpfile
);
536 pRtlDosPathNameToNtPathName_U( tmpfile
, &nameW
, NULL
, NULL
);
538 file
= CreateFileW( tmpfile
, FILE_WRITE_DATA
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
539 ok( file
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError() );
540 numbytes
= 0xdeadbeef;
541 ret
= WriteFile( file
, testdata
, sizeof(testdata
) - 1, &numbytes
, NULL
);
542 ok( ret
, "WriteFile failed with error %u\n", GetLastError() );
543 ok( numbytes
== sizeof(testdata
) - 1, "failed to write all data\n" );
546 attr
.Length
= sizeof(attr
);
547 attr
.RootDirectory
= 0;
548 attr
.ObjectName
= &nameW
;
549 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
550 attr
.SecurityDescriptor
= NULL
;
551 attr
.SecurityQualityOfService
= NULL
;
552 status
= pNtOpenFile( &file
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
553 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
);
554 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
555 pRtlFreeUnicodeString( &nameW
);
557 numbytes
= 0xdeadbeef;
558 memset( data
, 0, sizeof(data
) );
559 ret
= ReadFile( file
, data
, sizeof(data
), &numbytes
, NULL
);
560 ok( ret
, "ReadFile failed with error %u\n", GetLastError() );
561 ok( numbytes
== sizeof(testdata
) - 1, "failed to read all data\n" );
562 ok( !memcmp( data
, testdata
, sizeof(testdata
) - 1 ), "testdata doesn't match\n" );
564 nameW
.Length
= sizeof(fooW
) - sizeof(WCHAR
);
566 attr
.RootDirectory
= file
;
567 attr
.ObjectName
= &nameW
;
568 status
= pNtOpenFile( &root
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
569 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
);
570 ok( status
== STATUS_OBJECT_PATH_NOT_FOUND
,
571 "expected STATUS_OBJECT_PATH_NOT_FOUND, got %08x\n", status
);
575 attr
.RootDirectory
= file
;
576 attr
.ObjectName
= &nameW
;
577 status
= pNtOpenFile( &root
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
578 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_NONALERT
);
579 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(tmpfile
), status
);
581 numbytes
= SetFilePointer( file
, 0, 0, FILE_CURRENT
);
582 ok( numbytes
== sizeof(testdata
) - 1, "SetFilePointer returned %u\n", numbytes
);
583 numbytes
= SetFilePointer( root
, 0, 0, FILE_CURRENT
);
584 ok( numbytes
== 0, "SetFilePointer returned %u\n", numbytes
);
586 numbytes
= 0xdeadbeef;
587 memset( data
, 0, sizeof(data
) );
588 ret
= ReadFile( root
, data
, sizeof(data
), &numbytes
, NULL
);
589 ok( ret
, "ReadFile failed with error %u\n", GetLastError() );
590 ok( numbytes
== sizeof(testdata
) - 1, "failed to read all data\n" );
591 ok( !memcmp( data
, testdata
, sizeof(testdata
) - 1 ), "testdata doesn't match\n" );
593 numbytes
= SetFilePointer( file
, 0, 0, FILE_CURRENT
);
594 ok( numbytes
== sizeof(testdata
) - 1, "SetFilePointer returned %u\n", numbytes
);
595 numbytes
= SetFilePointer( root
, 0, 0, FILE_CURRENT
);
596 ok( numbytes
== sizeof(testdata
) - 1, "SetFilePointer returned %u\n", numbytes
);
600 DeleteFileW( tmpfile
);
603 static void delete_file_test(void)
606 OBJECT_ATTRIBUTES attr
;
607 UNICODE_STRING nameW
;
608 WCHAR pathW
[MAX_PATH
];
609 WCHAR pathsubW
[MAX_PATH
];
610 static const WCHAR testdirW
[] = {'n','t','d','e','l','e','t','e','f','i','l','e',0};
611 static const WCHAR subdirW
[] = {'\\','s','u','b',0};
613 ret
= GetTempPathW(MAX_PATH
, pathW
);
616 ok(0, "couldn't get temp dir\n");
619 if (ret
+ sizeof(testdirW
)/sizeof(WCHAR
)-1 + sizeof(subdirW
)/sizeof(WCHAR
)-1 >= MAX_PATH
)
621 ok(0, "MAX_PATH exceeded in constructing paths\n");
625 lstrcatW(pathW
, testdirW
);
626 lstrcpyW(pathsubW
, pathW
);
627 lstrcatW(pathsubW
, subdirW
);
629 ret
= CreateDirectoryW(pathW
, NULL
);
630 ok(ret
== TRUE
, "couldn't create directory ntdeletefile\n");
631 if (!pRtlDosPathNameToNtPathName_U(pathW
, &nameW
, NULL
, NULL
))
633 ok(0,"RtlDosPathNametoNtPathName_U failed\n");
637 attr
.Length
= sizeof(attr
);
638 attr
.RootDirectory
= 0;
639 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
640 attr
.ObjectName
= &nameW
;
641 attr
.SecurityDescriptor
= NULL
;
642 attr
.SecurityQualityOfService
= NULL
;
644 /* test NtDeleteFile on an empty directory */
645 ret
= pNtDeleteFile(&attr
);
646 ok(ret
== STATUS_SUCCESS
, "NtDeleteFile should succeed in removing an empty directory\n");
647 ret
= RemoveDirectoryW(pathW
);
648 ok(ret
== FALSE
, "expected to fail removing directory, NtDeleteFile should have removed it\n");
650 /* test NtDeleteFile on a non-empty directory */
651 ret
= CreateDirectoryW(pathW
, NULL
);
652 ok(ret
== TRUE
, "couldn't create directory ntdeletefile ?!\n");
653 ret
= CreateDirectoryW(pathsubW
, NULL
);
654 ok(ret
== TRUE
, "couldn't create directory subdir\n");
655 ret
= pNtDeleteFile(&attr
);
656 ok(ret
== STATUS_SUCCESS
, "expected NtDeleteFile to ret STATUS_SUCCESS\n");
657 ret
= RemoveDirectoryW(pathsubW
);
658 ok(ret
== TRUE
, "expected to remove directory ntdeletefile\\sub\n");
659 ret
= RemoveDirectoryW(pathW
);
660 ok(ret
== TRUE
, "expected to remove directory ntdeletefile, NtDeleteFile failed.\n");
662 pRtlFreeUnicodeString( &nameW
);
665 static void read_file_test(void)
667 const char text
[] = "foobar";
669 IO_STATUS_BLOCK iosb
;
673 LARGE_INTEGER offset
;
674 HANDLE event
= CreateEventA( NULL
, TRUE
, FALSE
, NULL
);
676 if (!(handle
= create_temp_file( FILE_FLAG_OVERLAPPED
))) return;
678 U(iosb
).Status
= 0xdeadbabe;
679 iosb
.Information
= 0xdeadbeef;
682 status
= pNtWriteFile( handle
, event
, apc
, &apc_count
, &iosb
, text
, strlen(text
), &offset
, NULL
);
683 ok( status
== STATUS_SUCCESS
|| status
== STATUS_PENDING
, "wrong status %x\n", status
);
684 if (status
== STATUS_PENDING
) WaitForSingleObject( event
, 1000 );
685 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
686 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
687 ok( is_signaled( event
), "event is not signaled\n" );
688 ok( !apc_count
, "apc was called\n" );
689 SleepEx( 1, TRUE
); /* alertable sleep */
690 ok( apc_count
== 1, "apc was not called\n" );
693 U(iosb
).Status
= 0xdeadbabe;
694 iosb
.Information
= 0xdeadbeef;
697 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, strlen(text
) + 10, &offset
, NULL
);
698 ok( status
== STATUS_SUCCESS
||
699 status
== STATUS_PENDING
, /* vista */
700 "wrong status %x\n", status
);
701 if (status
== STATUS_PENDING
) WaitForSingleObject( event
, 1000 );
702 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
703 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
704 ok( is_signaled( event
), "event is not signaled\n" );
705 ok( !apc_count
, "apc was called\n" );
706 SleepEx( 1, TRUE
); /* alertable sleep */
707 ok( apc_count
== 1, "apc was not called\n" );
709 /* read beyond eof */
711 U(iosb
).Status
= 0xdeadbabe;
712 iosb
.Information
= 0xdeadbeef;
713 offset
.QuadPart
= strlen(text
) + 2;
714 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, &offset
, NULL
);
715 ok(status
== STATUS_PENDING
|| status
== STATUS_END_OF_FILE
/* before Vista */, "expected STATUS_PENDING or STATUS_END_OF_FILE, got %#x\n", status
);
716 if (status
== STATUS_PENDING
) /* vista */
718 WaitForSingleObject( event
, 1000 );
719 ok( U(iosb
).Status
== STATUS_END_OF_FILE
, "wrong status %x\n", U(iosb
).Status
);
720 ok( iosb
.Information
== 0, "wrong info %lu\n", iosb
.Information
);
721 ok( is_signaled( event
), "event is not signaled\n" );
722 ok( !apc_count
, "apc was called\n" );
723 SleepEx( 1, TRUE
); /* alertable sleep */
724 ok( apc_count
== 1, "apc was not called\n" );
726 CloseHandle( handle
);
728 /* now a non-overlapped file */
729 if (!(handle
= create_temp_file(0))) return;
731 U(iosb
).Status
= 0xdeadbabe;
732 iosb
.Information
= 0xdeadbeef;
734 status
= pNtWriteFile( handle
, event
, apc
, &apc_count
, &iosb
, text
, strlen(text
), &offset
, NULL
);
735 ok( status
== STATUS_END_OF_FILE
||
736 status
== STATUS_SUCCESS
||
737 status
== STATUS_PENDING
, /* vista */
738 "wrong status %x\n", status
);
739 if (status
== STATUS_PENDING
) WaitForSingleObject( event
, 1000 );
740 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
741 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
742 ok( is_signaled( event
), "event is not signaled\n" );
743 ok( !apc_count
, "apc was called\n" );
744 SleepEx( 1, TRUE
); /* alertable sleep */
745 ok( apc_count
== 1, "apc was not called\n" );
748 U(iosb
).Status
= 0xdeadbabe;
749 iosb
.Information
= 0xdeadbeef;
752 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, strlen(text
) + 10, &offset
, NULL
);
753 ok( status
== STATUS_SUCCESS
, "wrong status %x\n", status
);
754 ok( U(iosb
).Status
== STATUS_SUCCESS
, "wrong status %x\n", U(iosb
).Status
);
755 ok( iosb
.Information
== strlen(text
), "wrong info %lu\n", iosb
.Information
);
756 ok( is_signaled( event
), "event is not signaled\n" );
757 ok( !apc_count
, "apc was called\n" );
758 SleepEx( 1, TRUE
); /* alertable sleep */
759 todo_wine
ok( !apc_count
, "apc was called\n" );
761 /* read beyond eof */
763 U(iosb
).Status
= 0xdeadbabe;
764 iosb
.Information
= 0xdeadbeef;
765 offset
.QuadPart
= strlen(text
) + 2;
767 status
= pNtReadFile( handle
, event
, apc
, &apc_count
, &iosb
, buffer
, 2, &offset
, NULL
);
768 ok( status
== STATUS_END_OF_FILE
, "wrong status %x\n", status
);
769 ok( U(iosb
).Status
== STATUS_END_OF_FILE
, "wrong status %x\n", U(iosb
).Status
);
770 ok( iosb
.Information
== 0, "wrong info %lu\n", iosb
.Information
);
771 ok( is_signaled( event
), "event is not signaled\n" );
772 ok( !apc_count
, "apc was called\n" );
773 SleepEx( 1, TRUE
); /* alertable sleep */
774 ok( !apc_count
, "apc was called\n" );
776 CloseHandle( handle
);
778 CloseHandle( event
);
781 static void append_file_test(void)
783 static const char text
[6] = "foobar";
786 IO_STATUS_BLOCK iosb
;
787 LARGE_INTEGER offset
;
788 char path
[MAX_PATH
], buffer
[MAX_PATH
], buf
[16];
791 GetTempPathA( MAX_PATH
, path
);
792 GetTempFileNameA( path
, "foo", 0, buffer
);
794 handle
= CreateFileA(buffer
, FILE_WRITE_DATA
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
795 ok(handle
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError());
798 iosb
.Information
= -1;
799 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
, 2, NULL
, NULL
);
800 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
801 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
802 ok(iosb
.Information
== 2, "expected 2, got %lu\n", iosb
.Information
);
806 /* It is possible to open a file with only FILE_APPEND_DATA access flags.
807 It matches the O_WRONLY|O_APPEND open() posix behavior */
808 handle
= CreateFileA(buffer
, FILE_APPEND_DATA
, 0, NULL
, OPEN_EXISTING
, 0, 0);
809 ok(handle
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError());
812 iosb
.Information
= -1;
814 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
+ 2, 2, &offset
, NULL
);
815 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
816 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
817 ok(iosb
.Information
== 2, "expected 2, got %lu\n", iosb
.Information
);
819 ret
= SetFilePointer(handle
, 0, NULL
, FILE_CURRENT
);
820 ok(ret
== 4, "expected 4, got %u\n", ret
);
823 iosb
.Information
= -1;
825 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
+ 4, 2, &offset
, NULL
);
826 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
827 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
828 ok(iosb
.Information
== 2, "expected 2, got %lu\n", iosb
.Information
);
830 ret
= SetFilePointer(handle
, 0, NULL
, FILE_CURRENT
);
831 ok(ret
== 6, "expected 6, got %u\n", ret
);
835 handle
= CreateFileA(buffer
, FILE_READ_DATA
| FILE_WRITE_DATA
| FILE_APPEND_DATA
, 0, NULL
, OPEN_EXISTING
, 0, 0);
836 ok(handle
!= INVALID_HANDLE_VALUE
, "CreateFile error %d\n", GetLastError());
838 memset(buf
, 0, sizeof(buf
));
840 iosb
.Information
= -1;
842 status
= pNtReadFile(handle
, 0, NULL
, NULL
, &iosb
, buf
, sizeof(buf
), &offset
, NULL
);
843 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
844 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
845 ok(iosb
.Information
== 6, "expected 6, got %lu\n", iosb
.Information
);
847 ok(memcmp(buf
, text
, 6) == 0, "wrong file contents: %s\n", buf
);
850 iosb
.Information
= -1;
852 status
= pNtWriteFile(handle
, NULL
, NULL
, NULL
, &iosb
, text
+ 3, 3, &offset
, NULL
);
853 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
854 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
855 ok(iosb
.Information
== 3, "expected 3, got %lu\n", iosb
.Information
);
857 memset(buf
, 0, sizeof(buf
));
859 iosb
.Information
= -1;
861 status
= pNtReadFile(handle
, 0, NULL
, NULL
, &iosb
, buf
, sizeof(buf
), &offset
, NULL
);
862 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
863 ok(U(iosb
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iosb
).Status
);
864 ok(iosb
.Information
== 6, "expected 6, got %lu\n", iosb
.Information
);
866 ok(memcmp(buf
, "barbar", 6) == 0, "wrong file contents: %s\n", buf
);
872 static void nt_mailslot_test(void)
875 ACCESS_MASK DesiredAccess
;
876 OBJECT_ATTRIBUTES attr
;
880 ULONG MaxMessageSize
;
881 LARGE_INTEGER TimeOut
;
882 IO_STATUS_BLOCK IoStatusBlock
;
885 WCHAR buffer1
[] = { '\\','?','?','\\','M','A','I','L','S','L','O','T','\\',
886 'R',':','\\','F','R','E','D','\0' };
888 TimeOut
.QuadPart
= -1;
890 pRtlInitUnicodeString(&str
, buffer1
);
891 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
892 CreateOptions
= MailslotQuota
= MaxMessageSize
= 0;
893 DesiredAccess
= GENERIC_READ
;
896 * Check for NULL pointer handling
898 rc
= pNtCreateMailslotFile(NULL
, DesiredAccess
,
899 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
901 ok( rc
== STATUS_ACCESS_VIOLATION
||
902 rc
== STATUS_INVALID_PARAMETER
, /* win2k3 */
903 "rc = %x not STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER\n", rc
);
906 * Test to see if the Timeout can be NULL
908 hslot
= (HANDLE
)0xdeadbeef;
909 rc
= pNtCreateMailslotFile(&hslot
, DesiredAccess
,
910 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
912 ok( rc
== STATUS_SUCCESS
||
913 rc
== STATUS_INVALID_PARAMETER
, /* win2k3 */
914 "rc = %x not STATUS_SUCCESS or STATUS_INVALID_PARAMETER\n", rc
);
915 ok( hslot
!= 0, "Handle is invalid\n");
917 if ( rc
== STATUS_SUCCESS
) pNtClose(hslot
);
922 InitializeObjectAttributes(&attr
, &str
, OBJ_CASE_INSENSITIVE
, 0, NULL
);
923 rc
= pNtCreateMailslotFile(&hslot
, DesiredAccess
,
924 &attr
, &IoStatusBlock
, CreateOptions
, MailslotQuota
, MaxMessageSize
,
926 ok( rc
== STATUS_SUCCESS
, "Create MailslotFile failed rc = %x\n", rc
);
927 ok( hslot
!= 0, "Handle is invalid\n");
929 rc
= pNtClose(hslot
);
930 ok( rc
== STATUS_SUCCESS
, "NtClose failed\n");
933 static void test_iocp_setcompletion(HANDLE h
)
939 if (sizeof(size
) > 4) size
|= (ULONGLONG
)0x12345678 << 32;
941 res
= pNtSetIoCompletion( h
, CKEY_FIRST
, CVALUE_FIRST
, STATUS_INVALID_DEVICE_REQUEST
, size
);
942 ok( res
== STATUS_SUCCESS
, "NtSetIoCompletion failed: %x\n", res
);
944 count
= get_pending_msgs(h
);
945 ok( count
== 1, "Unexpected msg count: %d\n", count
);
949 ok( completionKey
== CKEY_FIRST
, "Invalid completion key: %lx\n", completionKey
);
950 ok( ioSb
.Information
== size
, "Invalid ioSb.Information: %lu\n", ioSb
.Information
);
951 ok( U(ioSb
).Status
== STATUS_INVALID_DEVICE_REQUEST
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
952 ok( completionValue
== CVALUE_FIRST
, "Invalid completion value: %lx\n", completionValue
);
955 count
= get_pending_msgs(h
);
956 ok( !count
, "Unexpected msg count: %d\n", count
);
959 static void test_iocp_fileio(HANDLE h
)
961 static const char pipe_name
[] = "\\\\.\\pipe\\iocompletiontestnamedpipe";
963 IO_STATUS_BLOCK iosb
;
964 FILE_COMPLETION_INFORMATION fci
= {h
, CKEY_SECOND
};
965 HANDLE hPipeSrv
, hPipeClt
;
968 hPipeSrv
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
, PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
, 4, 1024, 1024, 1000, NULL
);
969 ok( hPipeSrv
!= INVALID_HANDLE_VALUE
, "Cannot create named pipe\n" );
970 if (hPipeSrv
!= INVALID_HANDLE_VALUE
)
972 hPipeClt
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
973 ok( hPipeClt
!= INVALID_HANDLE_VALUE
, "Cannot connect to pipe\n" );
974 if (hPipeClt
!= INVALID_HANDLE_VALUE
)
976 U(iosb
).Status
= 0xdeadbeef;
977 res
= pNtSetInformationFile( hPipeSrv
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
978 ok( res
== STATUS_INVALID_PARAMETER
, "Unexpected NtSetInformationFile on non-overlapped handle: %x\n", res
);
979 ok( U(iosb
).Status
== STATUS_INVALID_PARAMETER
/* 98 */ || U(iosb
).Status
== 0xdeadbeef /* NT4+ */,
980 "Unexpected iosb.Status on non-overlapped handle: %x\n", U(iosb
).Status
);
981 CloseHandle(hPipeClt
);
983 CloseHandle( hPipeSrv
);
986 hPipeSrv
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
| FILE_FLAG_OVERLAPPED
, PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
, 4, 1024, 1024, 1000, NULL
);
987 ok( hPipeSrv
!= INVALID_HANDLE_VALUE
, "Cannot create named pipe\n" );
988 if (hPipeSrv
== INVALID_HANDLE_VALUE
)
991 hPipeClt
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
992 ok( hPipeClt
!= INVALID_HANDLE_VALUE
, "Cannot connect to pipe\n" );
993 if (hPipeClt
!= INVALID_HANDLE_VALUE
)
996 BYTE send_buf
[TEST_BUF_LEN
], recv_buf
[TEST_BUF_LEN
];
1000 U(iosb
).Status
= 0xdeadbeef;
1001 res
= pNtSetInformationFile( hPipeSrv
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
1002 ok( res
== STATUS_SUCCESS
, "NtSetInformationFile failed: %x\n", res
);
1003 ok( U(iosb
).Status
== STATUS_SUCCESS
, "iosb.Status invalid: %x\n", U(iosb
).Status
);
1005 memset( send_buf
, 0, TEST_BUF_LEN
);
1006 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1007 count
= get_pending_msgs(h
);
1008 ok( !count
, "Unexpected msg count: %ld\n", count
);
1009 ReadFile( hPipeSrv
, recv_buf
, TEST_BUF_LEN
, &read
, &o
);
1010 count
= get_pending_msgs(h
);
1011 ok( !count
, "Unexpected msg count: %ld\n", count
);
1012 WriteFile( hPipeClt
, send_buf
, TEST_BUF_LEN
, &read
, NULL
);
1016 ok( completionKey
== CKEY_SECOND
, "Invalid completion key: %lx\n", completionKey
);
1017 ok( ioSb
.Information
== 3, "Invalid ioSb.Information: %ld\n", ioSb
.Information
);
1018 ok( U(ioSb
).Status
== STATUS_SUCCESS
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
1019 ok( completionValue
== (ULONG_PTR
)&o
, "Invalid completion value: %lx\n", completionValue
);
1020 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] );
1022 count
= get_pending_msgs(h
);
1023 ok( !count
, "Unexpected msg count: %ld\n", count
);
1025 memset( send_buf
, 0, TEST_BUF_LEN
);
1026 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1027 WriteFile( hPipeClt
, send_buf
, 2, &read
, NULL
);
1028 count
= get_pending_msgs(h
);
1029 ok( !count
, "Unexpected msg count: %ld\n", count
);
1030 ReadFile( hPipeSrv
, recv_buf
, 2, &read
, &o
);
1031 count
= get_pending_msgs(h
);
1032 ok( count
== 1, "Unexpected msg count: %ld\n", count
);
1035 ok( completionKey
== CKEY_SECOND
, "Invalid completion key: %lx\n", completionKey
);
1036 ok( ioSb
.Information
== 2, "Invalid ioSb.Information: %ld\n", ioSb
.Information
);
1037 ok( U(ioSb
).Status
== STATUS_SUCCESS
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
1038 ok( completionValue
== (ULONG_PTR
)&o
, "Invalid completion value: %lx\n", completionValue
);
1039 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] );
1042 ReadFile( hPipeSrv
, recv_buf
, TEST_BUF_LEN
, &read
, &o
);
1043 CloseHandle( hPipeSrv
);
1044 count
= get_pending_msgs(h
);
1045 ok( count
== 1, "Unexpected msg count: %ld\n", count
);
1048 ok( completionKey
== CKEY_SECOND
, "Invalid completion key: %lx\n", completionKey
);
1049 ok( ioSb
.Information
== 0, "Invalid ioSb.Information: %ld\n", ioSb
.Information
);
1050 /* wine sends wrong status here */
1051 ok( U(ioSb
).Status
== STATUS_PIPE_BROKEN
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
1052 ok( completionValue
== (ULONG_PTR
)&o
, "Invalid completion value: %lx\n", completionValue
);
1056 CloseHandle( hPipeClt
);
1058 /* test associating a completion port with a handle after an async is queued */
1059 hPipeSrv
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
| FILE_FLAG_OVERLAPPED
, PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
, 4, 1024, 1024, 1000, NULL
);
1060 ok( hPipeSrv
!= INVALID_HANDLE_VALUE
, "Cannot create named pipe\n" );
1061 if (hPipeSrv
== INVALID_HANDLE_VALUE
)
1063 hPipeClt
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
1064 ok( hPipeClt
!= INVALID_HANDLE_VALUE
, "Cannot connect to pipe\n" );
1065 if (hPipeClt
!= INVALID_HANDLE_VALUE
)
1067 OVERLAPPED o
= {0,};
1068 BYTE send_buf
[TEST_BUF_LEN
], recv_buf
[TEST_BUF_LEN
];
1073 memset( send_buf
, 0, TEST_BUF_LEN
);
1074 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1075 count
= get_pending_msgs(h
);
1076 ok( !count
, "Unexpected msg count: %ld\n", count
);
1077 ReadFile( hPipeSrv
, recv_buf
, TEST_BUF_LEN
, &read
, &o
);
1079 U(iosb
).Status
= 0xdeadbeef;
1080 res
= pNtSetInformationFile( hPipeSrv
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
1081 ok( res
== STATUS_SUCCESS
, "NtSetInformationFile failed: %x\n", res
);
1082 ok( U(iosb
).Status
== STATUS_SUCCESS
, "iosb.Status invalid: %x\n", U(iosb
).Status
);
1083 count
= get_pending_msgs(h
);
1084 ok( !count
, "Unexpected msg count: %ld\n", count
);
1086 WriteFile( hPipeClt
, send_buf
, TEST_BUF_LEN
, &read
, NULL
);
1090 ok( completionKey
== CKEY_SECOND
, "Invalid completion key: %lx\n", completionKey
);
1091 ok( ioSb
.Information
== 3, "Invalid ioSb.Information: %ld\n", ioSb
.Information
);
1092 ok( U(ioSb
).Status
== STATUS_SUCCESS
, "Invalid ioSb.Status: %x\n", U(ioSb
).Status
);
1093 ok( completionValue
== (ULONG_PTR
)&o
, "Invalid completion value: %lx\n", completionValue
);
1094 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] );
1096 count
= get_pending_msgs(h
);
1097 ok( !count
, "Unexpected msg count: %ld\n", count
);
1099 /* using APCs on handle with associated completion port is not allowed */
1100 res
= NtReadFile( hPipeSrv
, NULL
, apc
, &apc_count
, &iosb
, recv_buf
, sizeof(recv_buf
), NULL
, NULL
);
1101 ok(res
== STATUS_INVALID_PARAMETER
, "NtReadFile returned %x\n", res
);
1104 CloseHandle( hPipeSrv
);
1105 CloseHandle( hPipeClt
);
1107 /* test associating a completion port with a handle after an async using APC is queued */
1108 hPipeSrv
= CreateNamedPipeA( pipe_name
, PIPE_ACCESS_INBOUND
| FILE_FLAG_OVERLAPPED
, PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
, 4, 1024, 1024, 1000, NULL
);
1109 ok( hPipeSrv
!= INVALID_HANDLE_VALUE
, "Cannot create named pipe\n" );
1110 if (hPipeSrv
== INVALID_HANDLE_VALUE
)
1112 hPipeClt
= CreateFileA( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_NO_BUFFERING
| FILE_FLAG_OVERLAPPED
, NULL
);
1113 ok( hPipeClt
!= INVALID_HANDLE_VALUE
, "Cannot connect to pipe\n" );
1114 if (hPipeClt
!= INVALID_HANDLE_VALUE
)
1116 BYTE send_buf
[TEST_BUF_LEN
], recv_buf
[TEST_BUF_LEN
];
1121 memset( send_buf
, 0, TEST_BUF_LEN
);
1122 memset( recv_buf
, 0xde, TEST_BUF_LEN
);
1123 count
= get_pending_msgs(h
);
1124 ok( !count
, "Unexpected msg count: %ld\n", count
);
1126 res
= NtReadFile( hPipeSrv
, NULL
, apc
, &apc_count
, &iosb
, recv_buf
, sizeof(recv_buf
), NULL
, NULL
);
1127 ok(res
== STATUS_PENDING
, "NtReadFile returned %x\n", res
);
1129 U(iosb
).Status
= 0xdeadbeef;
1130 res
= pNtSetInformationFile( hPipeSrv
, &iosb
, &fci
, sizeof(fci
), FileCompletionInformation
);
1131 ok( res
== STATUS_SUCCESS
, "NtSetInformationFile failed: %x\n", res
);
1132 ok( U(iosb
).Status
== STATUS_SUCCESS
, "iosb.Status invalid: %x\n", U(iosb
).Status
);
1133 count
= get_pending_msgs(h
);
1134 ok( !count
, "Unexpected msg count: %ld\n", count
);
1136 WriteFile( hPipeClt
, send_buf
, TEST_BUF_LEN
, &read
, NULL
);
1138 ok(!apc_count
, "apc_count = %u\n", apc_count
);
1139 count
= get_pending_msgs(h
);
1140 ok( !count
, "Unexpected msg count: %ld\n", count
);
1142 SleepEx(1, TRUE
); /* alertable sleep */
1143 ok(apc_count
== 1, "apc was not called\n");
1144 count
= get_pending_msgs(h
);
1145 ok( !count
, "Unexpected msg count: %ld\n", count
);
1147 /* using APCs on handle with associated completion port is not allowed */
1148 res
= NtReadFile( hPipeSrv
, NULL
, apc
, &apc_count
, &iosb
, recv_buf
, sizeof(recv_buf
), NULL
, NULL
);
1149 ok(res
== STATUS_INVALID_PARAMETER
, "NtReadFile returned %x\n", res
);
1152 CloseHandle( hPipeSrv
);
1153 CloseHandle( hPipeClt
);
1156 static void test_file_full_size_information(void)
1159 FILE_FS_FULL_SIZE_INFORMATION ffsi
;
1160 FILE_FS_SIZE_INFORMATION fsi
;
1164 if(!(h
= create_temp_file(0))) return ;
1166 memset(&ffsi
,0,sizeof(ffsi
));
1167 memset(&fsi
,0,sizeof(fsi
));
1169 /* Assume No Quota Settings configured on Wine Testbot */
1170 res
= pNtQueryVolumeInformationFile(h
, &io
, &ffsi
, sizeof ffsi
, FileFsFullSizeInformation
);
1171 ok(res
== STATUS_SUCCESS
, "cannot get attributes, res %x\n", res
);
1172 res
= pNtQueryVolumeInformationFile(h
, &io
, &fsi
, sizeof fsi
, FileFsSizeInformation
);
1173 ok(res
== STATUS_SUCCESS
, "cannot get attributes, res %x\n", res
);
1175 /* Test for FileFsSizeInformation */
1176 ok(fsi
.TotalAllocationUnits
.QuadPart
> 0,
1177 "[fsi] TotalAllocationUnits expected positive, got 0x%s\n",
1178 wine_dbgstr_longlong(fsi
.TotalAllocationUnits
.QuadPart
));
1179 ok(fsi
.AvailableAllocationUnits
.QuadPart
> 0,
1180 "[fsi] AvailableAllocationUnits expected positive, got 0x%s\n",
1181 wine_dbgstr_longlong(fsi
.AvailableAllocationUnits
.QuadPart
));
1183 /* Assume file system is NTFS */
1184 ok(fsi
.BytesPerSector
== 512, "[fsi] BytesPerSector expected 512, got %d\n",fsi
.BytesPerSector
);
1185 ok(fsi
.SectorsPerAllocationUnit
== 8, "[fsi] SectorsPerAllocationUnit expected 8, got %d\n",fsi
.SectorsPerAllocationUnit
);
1187 ok(ffsi
.TotalAllocationUnits
.QuadPart
> 0,
1188 "[ffsi] TotalAllocationUnits expected positive, got negative value 0x%s\n",
1189 wine_dbgstr_longlong(ffsi
.TotalAllocationUnits
.QuadPart
));
1190 ok(ffsi
.CallerAvailableAllocationUnits
.QuadPart
> 0,
1191 "[ffsi] CallerAvailableAllocationUnits expected positive, got negative value 0x%s\n",
1192 wine_dbgstr_longlong(ffsi
.CallerAvailableAllocationUnits
.QuadPart
));
1193 ok(ffsi
.ActualAvailableAllocationUnits
.QuadPart
> 0,
1194 "[ffsi] ActualAvailableAllocationUnits expected positive, got negative value 0x%s\n",
1195 wine_dbgstr_longlong(ffsi
.ActualAvailableAllocationUnits
.QuadPart
));
1196 ok(ffsi
.TotalAllocationUnits
.QuadPart
== fsi
.TotalAllocationUnits
.QuadPart
,
1197 "[ffsi] TotalAllocationUnits error fsi:0x%s, ffsi:0x%s\n",
1198 wine_dbgstr_longlong(fsi
.TotalAllocationUnits
.QuadPart
),
1199 wine_dbgstr_longlong(ffsi
.TotalAllocationUnits
.QuadPart
));
1200 ok(ffsi
.CallerAvailableAllocationUnits
.QuadPart
== fsi
.AvailableAllocationUnits
.QuadPart
,
1201 "[ffsi] CallerAvailableAllocationUnits error fsi:0x%s, ffsi: 0x%s\n",
1202 wine_dbgstr_longlong(fsi
.AvailableAllocationUnits
.QuadPart
),
1203 wine_dbgstr_longlong(ffsi
.CallerAvailableAllocationUnits
.QuadPart
));
1205 /* Assume file system is NTFS */
1206 ok(ffsi
.BytesPerSector
== 512, "[ffsi] BytesPerSector expected 512, got %d\n",ffsi
.BytesPerSector
);
1207 ok(ffsi
.SectorsPerAllocationUnit
== 8, "[ffsi] SectorsPerAllocationUnit expected 8, got %d\n",ffsi
.SectorsPerAllocationUnit
);
1212 static void test_file_basic_information(void)
1215 FILE_BASIC_INFORMATION fbi
;
1218 int attrib_mask
= FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_NORMAL
;
1220 if (!(h
= create_temp_file(0))) return;
1222 /* Check default first */
1223 memset(&fbi
, 0, sizeof(fbi
));
1224 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1225 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1226 ok ( (fbi
.FileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) == FILE_ATTRIBUTE_ARCHIVE
,
1227 "attribute %x not expected\n", fbi
.FileAttributes
);
1230 /* Clear fbi to avoid setting times */
1231 memset(&fbi
, 0, sizeof(fbi
));
1232 fbi
.FileAttributes
= FILE_ATTRIBUTE_SYSTEM
;
1233 U(io
).Status
= 0xdeadbeef;
1234 res
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1235 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, NtSetInformationFile returned %x\n", res
);
1236 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status is %x\n", U(io
).Status
);
1238 memset(&fbi
, 0, sizeof(fbi
));
1239 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1240 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1241 ok ( (fbi
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_SYSTEM
, "attribute %x not FILE_ATTRIBUTE_SYSTEM (ok in old linux without xattr)\n", fbi
.FileAttributes
);
1244 memset(&fbi
, 0, sizeof(fbi
));
1245 fbi
.FileAttributes
= FILE_ATTRIBUTE_HIDDEN
;
1246 U(io
).Status
= 0xdeadbeef;
1247 res
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1248 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, NtSetInformationFile returned %x\n", res
);
1249 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status is %x\n", U(io
).Status
);
1251 memset(&fbi
, 0, sizeof(fbi
));
1252 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1253 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1254 ok ( (fbi
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_HIDDEN
, "attribute %x not FILE_ATTRIBUTE_HIDDEN (ok in old linux without xattr)\n", fbi
.FileAttributes
);
1256 /* Check NORMAL last of all (to make sure we can clear attributes) */
1257 memset(&fbi
, 0, sizeof(fbi
));
1258 fbi
.FileAttributes
= FILE_ATTRIBUTE_NORMAL
;
1259 U(io
).Status
= 0xdeadbeef;
1260 res
= pNtSetInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1261 ok ( res
== STATUS_SUCCESS
, "can't set normal attribute, NtSetInformationFile returned %x\n", res
);
1262 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set normal attribute, io.Status is %x\n", U(io
).Status
);
1264 memset(&fbi
, 0, sizeof(fbi
));
1265 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBasicInformation
);
1266 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1267 todo_wine
ok ( (fbi
.FileAttributes
& attrib_mask
) == FILE_ATTRIBUTE_NORMAL
, "attribute %x not 0\n", fbi
.FileAttributes
);
1272 static void test_file_all_information(void)
1275 /* FileAllInformation, like FileNameInformation, has a variable-length pathname
1276 * buffer at the end. Vista objects with STATUS_BUFFER_OVERFLOW if you
1277 * don't leave enough room there.
1280 FILE_ALL_INFORMATION fai
;
1285 int attrib_mask
= FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_NORMAL
;
1287 if (!(h
= create_temp_file(0))) return;
1289 /* Check default first */
1290 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1291 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1292 ok ( (fai_buf
.fai
.BasicInformation
.FileAttributes
& FILE_ATTRIBUTE_ARCHIVE
) == FILE_ATTRIBUTE_ARCHIVE
,
1293 "attribute %x not expected\n", fai_buf
.fai
.BasicInformation
.FileAttributes
);
1296 /* Clear fbi to avoid setting times */
1297 memset(&fai_buf
.fai
.BasicInformation
, 0, sizeof(fai_buf
.fai
.BasicInformation
));
1298 fai_buf
.fai
.BasicInformation
.FileAttributes
= FILE_ATTRIBUTE_SYSTEM
;
1299 U(io
).Status
= 0xdeadbeef;
1300 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1301 ok ( res
== STATUS_INVALID_INFO_CLASS
|| broken(res
== STATUS_NOT_IMPLEMENTED
), "shouldn't be able to set FileAllInformation, res %x\n", res
);
1302 todo_wine
ok ( U(io
).Status
== 0xdeadbeef, "shouldn't be able to set FileAllInformation, io.Status is %x\n", U(io
).Status
);
1303 U(io
).Status
= 0xdeadbeef;
1304 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
.BasicInformation
, sizeof fai_buf
.fai
.BasicInformation
, FileBasicInformation
);
1305 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, res: %x\n", res
);
1306 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status: %x\n", U(io
).Status
);
1308 memset(&fai_buf
.fai
, 0, sizeof(fai_buf
.fai
));
1309 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1310 ok ( res
== STATUS_SUCCESS
, "can't get attributes, res %x\n", res
);
1311 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
);
1314 memset(&fai_buf
.fai
.BasicInformation
, 0, sizeof(fai_buf
.fai
.BasicInformation
));
1315 fai_buf
.fai
.BasicInformation
.FileAttributes
= FILE_ATTRIBUTE_HIDDEN
;
1316 U(io
).Status
= 0xdeadbeef;
1317 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
.BasicInformation
, sizeof fai_buf
.fai
.BasicInformation
, FileBasicInformation
);
1318 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, res: %x\n", res
);
1319 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status: %x\n", U(io
).Status
);
1321 memset(&fai_buf
.fai
, 0, sizeof(fai_buf
.fai
));
1322 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1323 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1324 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
);
1326 /* Check NORMAL last of all (to make sure we can clear attributes) */
1327 memset(&fai_buf
.fai
.BasicInformation
, 0, sizeof(fai_buf
.fai
.BasicInformation
));
1328 fai_buf
.fai
.BasicInformation
.FileAttributes
= FILE_ATTRIBUTE_NORMAL
;
1329 U(io
).Status
= 0xdeadbeef;
1330 res
= pNtSetInformationFile(h
, &io
, &fai_buf
.fai
.BasicInformation
, sizeof fai_buf
.fai
.BasicInformation
, FileBasicInformation
);
1331 ok ( res
== STATUS_SUCCESS
, "can't set system attribute, res: %x\n", res
);
1332 ok ( U(io
).Status
== STATUS_SUCCESS
, "can't set system attribute, io.Status: %x\n", U(io
).Status
);
1334 memset(&fai_buf
.fai
, 0, sizeof(fai_buf
.fai
));
1335 res
= pNtQueryInformationFile(h
, &io
, &fai_buf
.fai
, sizeof fai_buf
, FileAllInformation
);
1336 ok ( res
== STATUS_SUCCESS
, "can't get attributes\n");
1337 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
);
1342 static void delete_object( WCHAR
*path
)
1344 BOOL ret
= DeleteFileW( path
);
1345 ok( ret
|| GetLastError() == ERROR_FILE_NOT_FOUND
|| GetLastError() == ERROR_ACCESS_DENIED
,
1346 "DeleteFileW failed with %u\n", GetLastError() );
1347 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1349 ret
= RemoveDirectoryW( path
);
1350 ok( ret
, "RemoveDirectoryW failed with %u\n", GetLastError() );
1354 static void test_file_rename_information(void)
1356 static const WCHAR foo_txtW
[] = {'\\','f','o','o','.','t','x','t',0};
1357 static const WCHAR fooW
[] = {'f','o','o',0};
1358 WCHAR tmp_path
[MAX_PATH
], oldpath
[MAX_PATH
+ 16], newpath
[MAX_PATH
+ 16], *filename
, *p
;
1359 FILE_RENAME_INFORMATION
*fri
;
1360 FILE_NAME_INFORMATION
*fni
;
1361 BOOL success
, fileDeleted
;
1362 UNICODE_STRING name_str
;
1363 HANDLE handle
, handle2
;
1367 GetTempPathW( MAX_PATH
, tmp_path
);
1369 /* oldpath is a file, newpath doesn't exist */
1370 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1371 ok( res
!= 0, "failed to create temp file\n" );
1372 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1373 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1375 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1376 ok( res
!= 0, "failed to create temp file\n" );
1377 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1378 DeleteFileW( newpath
);
1379 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1380 fri
->Replace
= FALSE
;
1381 fri
->RootDir
= NULL
;
1382 fri
->FileNameLength
= name_str
.Length
;
1383 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1384 pRtlFreeUnicodeString( &name_str
);
1386 U(io
).Status
= 0xdeadbeef;
1387 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1388 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1389 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1390 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1391 ok( fileDeleted
, "file should not exist\n" );
1392 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1393 ok( !fileDeleted
, "file should exist\n" );
1395 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
1396 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
1397 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1398 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
1399 ok( !lstrcmpiW(fni
->FileName
, newpath
+ 2), "FileName expected %s, got %s\n",
1400 wine_dbgstr_w(newpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
1401 HeapFree( GetProcessHeap(), 0, fni
);
1403 CloseHandle( handle
);
1404 HeapFree( GetProcessHeap(), 0, fri
);
1405 delete_object( oldpath
);
1406 delete_object( newpath
);
1408 /* oldpath is a file, newpath is a file, Replace = FALSE */
1409 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1410 ok( res
!= 0, "failed to create temp file\n" );
1411 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1412 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1414 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1415 ok( res
!= 0, "failed to create temp file\n" );
1416 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1417 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1418 fri
->Replace
= FALSE
;
1419 fri
->RootDir
= NULL
;
1420 fri
->FileNameLength
= name_str
.Length
;
1421 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1422 pRtlFreeUnicodeString( &name_str
);
1424 U(io
).Status
= 0xdeadbeef;
1425 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1426 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1427 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1428 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1429 ok( !fileDeleted
, "file should exist\n" );
1430 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1431 ok( !fileDeleted
, "file should exist\n" );
1433 CloseHandle( handle
);
1434 HeapFree( GetProcessHeap(), 0, fri
);
1435 delete_object( oldpath
);
1436 delete_object( newpath
);
1438 /* oldpath is a file, newpath is a file, Replace = TRUE */
1439 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1440 ok( res
!= 0, "failed to create temp file\n" );
1441 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1442 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1444 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1445 ok( res
!= 0, "failed to create temp file\n" );
1446 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1447 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1448 fri
->Replace
= TRUE
;
1449 fri
->RootDir
= NULL
;
1450 fri
->FileNameLength
= name_str
.Length
;
1451 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1452 pRtlFreeUnicodeString( &name_str
);
1454 U(io
).Status
= 0xdeadbeef;
1455 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1456 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1457 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1458 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1459 ok( fileDeleted
, "file should not exist\n" );
1460 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1461 ok( !fileDeleted
, "file should exist\n" );
1463 CloseHandle( handle
);
1464 HeapFree( GetProcessHeap(), 0, fri
);
1465 delete_object( oldpath
);
1466 delete_object( newpath
);
1468 /* oldpath is a file, newpath is a file, Replace = FALSE, target file opened */
1469 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1470 ok( res
!= 0, "failed to create temp file\n" );
1471 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1472 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1474 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1475 ok( res
!= 0, "failed to create temp file\n" );
1476 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1477 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1479 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1480 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1481 fri
->Replace
= FALSE
;
1482 fri
->RootDir
= NULL
;
1483 fri
->FileNameLength
= name_str
.Length
;
1484 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1485 pRtlFreeUnicodeString( &name_str
);
1487 U(io
).Status
= 0xdeadbeef;
1488 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1489 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1490 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1491 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1492 ok( !fileDeleted
, "file should exist\n" );
1493 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1494 ok( !fileDeleted
, "file should exist\n" );
1496 CloseHandle( handle
);
1497 CloseHandle( handle2
);
1498 HeapFree( GetProcessHeap(), 0, fri
);
1499 delete_object( oldpath
);
1500 delete_object( newpath
);
1502 /* oldpath is a file, newpath is a file, Replace = TRUE, target file opened */
1503 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1504 ok( res
!= 0, "failed to create temp file\n" );
1505 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1506 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1508 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1509 ok( res
!= 0, "failed to create temp file\n" );
1510 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1511 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1513 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1514 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1515 fri
->Replace
= TRUE
;
1516 fri
->RootDir
= NULL
;
1517 fri
->FileNameLength
= name_str
.Length
;
1518 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1519 pRtlFreeUnicodeString( &name_str
);
1521 U(io
).Status
= 0xdeadbeef;
1522 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1523 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1524 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1525 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1526 ok( !fileDeleted
, "file should exist\n" );
1527 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1528 ok( !fileDeleted
, "file should exist\n" );
1530 CloseHandle( handle
);
1531 CloseHandle( handle2
);
1532 HeapFree( GetProcessHeap(), 0, fri
);
1533 delete_object( oldpath
);
1534 delete_object( newpath
);
1536 /* oldpath is a directory, newpath doesn't exist, Replace = FALSE */
1537 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1538 ok( res
!= 0, "failed to create temp file\n" );
1539 DeleteFileW( oldpath
);
1540 success
= CreateDirectoryW( oldpath
, NULL
);
1541 ok( success
!= 0, "failed to create temp directory\n" );
1542 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1543 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1545 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1546 ok( res
!= 0, "failed to create temp file\n" );
1547 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1548 DeleteFileW( newpath
);
1549 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1550 fri
->Replace
= FALSE
;
1551 fri
->RootDir
= NULL
;
1552 fri
->FileNameLength
= name_str
.Length
;
1553 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1554 pRtlFreeUnicodeString( &name_str
);
1556 U(io
).Status
= 0xdeadbeef;
1557 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1558 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1559 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1560 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1561 ok( fileDeleted
, "file should not exist\n" );
1562 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1563 ok( !fileDeleted
, "file should exist\n" );
1565 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
1566 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
1567 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1568 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
1569 ok( !lstrcmpiW(fni
->FileName
, newpath
+ 2), "FileName expected %s, got %s\n",
1570 wine_dbgstr_w(newpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
1571 HeapFree( GetProcessHeap(), 0, fni
);
1573 CloseHandle( handle
);
1574 HeapFree( GetProcessHeap(), 0, fri
);
1575 delete_object( oldpath
);
1576 delete_object( newpath
);
1578 /* oldpath is a directory (but child object opened), newpath doesn't exist, Replace = FALSE */
1579 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1580 ok( res
!= 0, "failed to create temp file\n" );
1581 DeleteFileW( oldpath
);
1582 success
= CreateDirectoryW( oldpath
, NULL
);
1583 ok( success
!= 0, "failed to create temp directory\n" );
1584 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1585 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1587 lstrcpyW( newpath
, oldpath
);
1588 lstrcatW( newpath
, foo_txtW
);
1589 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0 );
1590 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1592 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1593 ok( res
!= 0, "failed to create temp file\n" );
1594 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1595 DeleteFileW( newpath
);
1596 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1597 fri
->Replace
= FALSE
;
1598 fri
->RootDir
= NULL
;
1599 fri
->FileNameLength
= name_str
.Length
;
1600 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1601 pRtlFreeUnicodeString( &name_str
);
1603 U(io
).Status
= 0xdeadbeef;
1604 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1605 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1606 todo_wine
ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1607 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1608 todo_wine
ok( !fileDeleted
, "file should exist\n" );
1609 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1610 todo_wine
ok( fileDeleted
, "file should not exist\n" );
1612 CloseHandle( handle
);
1613 CloseHandle( handle2
);
1614 HeapFree( GetProcessHeap(), 0, fri
);
1615 delete_object( oldpath
);
1616 if (res
== STATUS_SUCCESS
) /* remove when Wine is fixed */
1618 lstrcpyW( oldpath
, newpath
);
1619 lstrcatW( oldpath
, foo_txtW
);
1620 delete_object( oldpath
);
1622 delete_object( newpath
);
1624 /* oldpath is a directory, newpath is a file, Replace = FALSE */
1625 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1626 ok( res
!= 0, "failed to create temp file\n" );
1627 DeleteFileW( oldpath
);
1628 success
= CreateDirectoryW( oldpath
, NULL
);
1629 ok( success
!= 0, "failed to create temp directory\n" );
1630 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1631 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1633 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1634 ok( res
!= 0, "failed to create temp file\n" );
1635 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1636 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1637 fri
->Replace
= FALSE
;
1638 fri
->RootDir
= NULL
;
1639 fri
->FileNameLength
= name_str
.Length
;
1640 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1641 pRtlFreeUnicodeString( &name_str
);
1643 U(io
).Status
= 0xdeadbeef;
1644 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1645 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1646 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1647 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1648 ok( !fileDeleted
, "file should exist\n" );
1649 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1650 ok( !fileDeleted
, "file should exist\n" );
1652 CloseHandle( handle
);
1653 HeapFree( GetProcessHeap(), 0, fri
);
1654 delete_object( oldpath
);
1655 delete_object( newpath
);
1657 /* oldpath is a directory, newpath is a file, Replace = FALSE, target file opened */
1658 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1659 ok( res
!= 0, "failed to create temp file\n" );
1660 DeleteFileW( oldpath
);
1661 success
= CreateDirectoryW( oldpath
, NULL
);
1662 ok( success
!= 0, "failed to create temp directory\n" );
1663 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1664 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1666 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1667 ok( res
!= 0, "failed to create temp file\n" );
1668 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1669 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1671 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1672 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1673 fri
->Replace
= FALSE
;
1674 fri
->RootDir
= NULL
;
1675 fri
->FileNameLength
= name_str
.Length
;
1676 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1677 pRtlFreeUnicodeString( &name_str
);
1679 U(io
).Status
= 0xdeadbeef;
1680 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1681 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1682 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1683 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1684 ok( !fileDeleted
, "file should exist\n" );
1685 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1686 ok( !fileDeleted
, "file should exist\n" );
1688 CloseHandle( handle
);
1689 CloseHandle( handle2
);
1690 HeapFree( GetProcessHeap(), 0, fri
);
1691 delete_object( oldpath
);
1692 delete_object( newpath
);
1694 /* oldpath is a directory, newpath is a file, Replace = TRUE */
1695 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1696 ok( res
!= 0, "failed to create temp file\n" );
1697 DeleteFileW( oldpath
);
1698 success
= CreateDirectoryW( oldpath
, NULL
);
1699 ok( success
!= 0, "failed to create temp directory\n" );
1700 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1701 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1703 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1704 ok( res
!= 0, "failed to create temp file\n" );
1705 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1706 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1707 fri
->Replace
= TRUE
;
1708 fri
->RootDir
= NULL
;
1709 fri
->FileNameLength
= name_str
.Length
;
1710 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1711 pRtlFreeUnicodeString( &name_str
);
1713 U(io
).Status
= 0xdeadbeef;
1714 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1715 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1716 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1717 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1718 ok( fileDeleted
, "file should not exist\n" );
1719 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1720 ok( !fileDeleted
, "file should exist\n" );
1722 CloseHandle( handle
);
1723 HeapFree( GetProcessHeap(), 0, fri
);
1724 delete_object( oldpath
);
1725 delete_object( newpath
);
1727 /* oldpath is a directory, newpath is a file, Replace = TRUE, target file opened */
1728 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1729 ok( res
!= 0, "failed to create temp file\n" );
1730 DeleteFileW( oldpath
);
1731 success
= CreateDirectoryW( oldpath
, NULL
);
1732 ok( success
!= 0, "failed to create temp directory\n" );
1733 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1734 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1736 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1737 ok( res
!= 0, "failed to create temp file\n" );
1738 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1739 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1741 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1742 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1743 fri
->Replace
= TRUE
;
1744 fri
->RootDir
= NULL
;
1745 fri
->FileNameLength
= name_str
.Length
;
1746 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1747 pRtlFreeUnicodeString( &name_str
);
1749 U(io
).Status
= 0xdeadbeef;
1750 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1751 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1752 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1753 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1754 ok( !fileDeleted
, "file should exist\n" );
1755 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1756 ok( !fileDeleted
, "file should exist\n" );
1758 CloseHandle( handle
);
1759 CloseHandle( handle2
);
1760 HeapFree( GetProcessHeap(), 0, fri
);
1761 delete_object( oldpath
);
1762 delete_object( newpath
);
1764 /* oldpath is a directory, newpath is a directory, Replace = FALSE */
1765 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1766 ok( res
!= 0, "failed to create temp file\n" );
1767 DeleteFileW( oldpath
);
1768 success
= CreateDirectoryW( oldpath
, NULL
);
1769 ok( success
!= 0, "failed to create temp directory\n" );
1770 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1771 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1773 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1774 ok( res
!= 0, "failed to create temp file\n" );
1775 DeleteFileW( newpath
);
1776 success
= CreateDirectoryW( newpath
, NULL
);
1777 ok( success
!= 0, "failed to create temp directory\n" );
1778 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1779 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1780 fri
->Replace
= FALSE
;
1781 fri
->RootDir
= NULL
;
1782 fri
->FileNameLength
= name_str
.Length
;
1783 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1784 pRtlFreeUnicodeString( &name_str
);
1786 U(io
).Status
= 0xdeadbeef;
1787 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1788 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1789 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1790 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1791 ok( !fileDeleted
, "file should exist\n" );
1792 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1793 ok( !fileDeleted
, "file should exist\n" );
1795 CloseHandle( handle
);
1796 HeapFree( GetProcessHeap(), 0, fri
);
1797 delete_object( oldpath
);
1798 delete_object( newpath
);
1800 /* oldpath is a directory, newpath is a directory, Replace = TRUE */
1801 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1802 ok( res
!= 0, "failed to create temp file\n" );
1803 DeleteFileW( oldpath
);
1804 success
= CreateDirectoryW( oldpath
, NULL
);
1805 ok( success
!= 0, "failed to create temp directory\n" );
1806 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1807 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1809 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1810 ok( res
!= 0, "failed to create temp file\n" );
1811 DeleteFileW( newpath
);
1812 success
= CreateDirectoryW( newpath
, NULL
);
1813 ok( success
!= 0, "failed to create temp directory\n" );
1814 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1815 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1816 fri
->Replace
= TRUE
;
1817 fri
->RootDir
= NULL
;
1818 fri
->FileNameLength
= name_str
.Length
;
1819 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1820 pRtlFreeUnicodeString( &name_str
);
1822 U(io
).Status
= 0xdeadbeef;
1823 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1824 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1825 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1826 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1827 ok( !fileDeleted
, "file should exist\n" );
1828 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1829 ok( !fileDeleted
, "file should exist\n" );
1831 CloseHandle( handle
);
1832 HeapFree( GetProcessHeap(), 0, fri
);
1833 delete_object( oldpath
);
1834 delete_object( newpath
);
1836 /* oldpath is a directory, newpath is a directory, Replace = TRUE, target file opened */
1837 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1838 ok( res
!= 0, "failed to create temp file\n" );
1839 DeleteFileW( oldpath
);
1840 success
= CreateDirectoryW( oldpath
, NULL
);
1841 ok( success
!= 0, "failed to create temp directory\n" );
1842 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1843 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1845 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1846 ok( res
!= 0, "failed to create temp file\n" );
1847 DeleteFileW( newpath
);
1848 success
= CreateDirectoryW( newpath
, NULL
);
1849 ok( success
!= 0, "failed to create temp directory\n" );
1850 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1851 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1853 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1854 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1855 fri
->Replace
= TRUE
;
1856 fri
->RootDir
= NULL
;
1857 fri
->FileNameLength
= name_str
.Length
;
1858 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1859 pRtlFreeUnicodeString( &name_str
);
1861 U(io
).Status
= 0xdeadbeef;
1862 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1863 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1864 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1865 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1866 ok( !fileDeleted
, "file should exist\n" );
1867 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1868 ok( !fileDeleted
, "file should exist\n" );
1870 CloseHandle( handle
);
1871 CloseHandle( handle2
);
1872 HeapFree( GetProcessHeap(), 0, fri
);
1873 delete_object( oldpath
);
1874 delete_object( newpath
);
1876 /* oldpath is a file, newpath is a directory, Replace = FALSE */
1877 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1878 ok( res
!= 0, "failed to create temp file\n" );
1879 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1880 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1882 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1883 ok( res
!= 0, "failed to create temp file\n" );
1884 DeleteFileW( newpath
);
1885 success
= CreateDirectoryW( newpath
, NULL
);
1886 ok( success
!= 0, "failed to create temp directory\n" );
1887 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1888 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1889 fri
->Replace
= FALSE
;
1890 fri
->RootDir
= NULL
;
1891 fri
->FileNameLength
= name_str
.Length
;
1892 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1893 pRtlFreeUnicodeString( &name_str
);
1895 U(io
).Status
= 0xdeadbeef;
1896 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1897 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1898 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
1899 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1900 ok( !fileDeleted
, "file should exist\n" );
1901 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1902 ok( !fileDeleted
, "file should exist\n" );
1904 CloseHandle( handle
);
1905 HeapFree( GetProcessHeap(), 0, fri
);
1906 delete_object( oldpath
);
1907 delete_object( newpath
);
1909 /* oldpath is a file, newpath is a directory, Replace = TRUE */
1910 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1911 ok( res
!= 0, "failed to create temp file\n" );
1912 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1913 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1915 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1916 ok( res
!= 0, "failed to create temp file\n" );
1917 DeleteFileW( newpath
);
1918 success
= CreateDirectoryW( newpath
, NULL
);
1919 ok( success
!= 0, "failed to create temp directory\n" );
1920 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
1921 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + name_str
.Length
);
1922 fri
->Replace
= TRUE
;
1923 fri
->RootDir
= NULL
;
1924 fri
->FileNameLength
= name_str
.Length
;
1925 memcpy( fri
->FileName
, name_str
.Buffer
, name_str
.Length
);
1926 pRtlFreeUnicodeString( &name_str
);
1928 U(io
).Status
= 0xdeadbeef;
1929 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1930 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
1931 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
1932 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1933 ok( !fileDeleted
, "file should exist\n" );
1934 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1935 ok( !fileDeleted
, "file should exist\n" );
1937 CloseHandle( handle
);
1938 HeapFree( GetProcessHeap(), 0, fri
);
1939 delete_object( oldpath
);
1940 delete_object( newpath
);
1942 /* oldpath is a file, newpath doesn't exist, test with RootDir != NULL */
1943 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
1944 ok( res
!= 0, "failed to create temp file\n" );
1945 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
1946 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1948 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
1949 ok( res
!= 0, "failed to create temp file\n" );
1950 DeleteFileW( newpath
);
1951 for (filename
= newpath
, p
= newpath
; *p
; p
++)
1952 if (*p
== '\\') filename
= p
+ 1;
1953 handle2
= CreateFileW( tmp_path
, 0, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
1954 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
1956 fri
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION
) + lstrlenW(filename
) * sizeof(WCHAR
) );
1957 fri
->Replace
= FALSE
;
1958 fri
->RootDir
= handle2
;
1959 fri
->FileNameLength
= lstrlenW(filename
) * sizeof(WCHAR
);
1960 memcpy( fri
->FileName
, filename
, fri
->FileNameLength
);
1962 U(io
).Status
= 0xdeadbeef;
1963 res
= pNtSetInformationFile( handle
, &io
, fri
, sizeof(FILE_RENAME_INFORMATION
) + fri
->FileNameLength
, FileRenameInformation
);
1964 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
1965 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1966 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1967 ok( fileDeleted
, "file should not exist\n" );
1968 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
1969 ok( !fileDeleted
, "file should exist\n" );
1971 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
1972 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
1973 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
1974 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
1975 ok( !lstrcmpiW(fni
->FileName
, newpath
+ 2), "FileName expected %s, got %s\n",
1976 wine_dbgstr_w(newpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
1977 HeapFree( GetProcessHeap(), 0, fni
);
1979 CloseHandle( handle
);
1980 CloseHandle( handle2
);
1981 HeapFree( GetProcessHeap(), 0, fri
);
1982 delete_object( oldpath
);
1983 delete_object( newpath
);
1986 static void test_file_link_information(void)
1988 static const WCHAR foo_txtW
[] = {'\\','f','o','o','.','t','x','t',0};
1989 static const WCHAR fooW
[] = {'f','o','o',0};
1990 WCHAR tmp_path
[MAX_PATH
], oldpath
[MAX_PATH
+ 16], newpath
[MAX_PATH
+ 16], *filename
, *p
;
1991 FILE_LINK_INFORMATION
*fli
;
1992 FILE_NAME_INFORMATION
*fni
;
1993 BOOL success
, fileDeleted
;
1994 UNICODE_STRING name_str
;
1995 HANDLE handle
, handle2
;
1999 GetTempPathW( MAX_PATH
, tmp_path
);
2001 /* oldpath is a file, newpath doesn't exist */
2002 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2003 ok( res
!= 0, "failed to create temp file\n" );
2004 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2005 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2007 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2008 ok( res
!= 0, "failed to create temp file\n" );
2009 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2010 DeleteFileW( newpath
);
2011 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2012 fli
->ReplaceIfExists
= FALSE
;
2013 fli
->RootDirectory
= NULL
;
2014 fli
->FileNameLength
= name_str
.Length
;
2015 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2016 pRtlFreeUnicodeString( &name_str
);
2018 U(io
).Status
= 0xdeadbeef;
2019 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2020 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
2021 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2022 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2023 ok( !fileDeleted
, "file should exist\n" );
2024 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2025 ok( !fileDeleted
, "file should exist\n" );
2027 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2028 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2029 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2030 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2031 ok( !lstrcmpiW(fni
->FileName
, oldpath
+ 2), "FileName expected %s, got %s\n",
2032 wine_dbgstr_w(oldpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2033 HeapFree( GetProcessHeap(), 0, fni
);
2035 CloseHandle( handle
);
2036 HeapFree( GetProcessHeap(), 0, fli
);
2037 delete_object( oldpath
);
2038 delete_object( newpath
);
2040 /* oldpath is a file, newpath is a file, ReplaceIfExists = FALSE */
2041 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2042 ok( res
!= 0, "failed to create temp file\n" );
2043 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2044 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2046 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2047 ok( res
!= 0, "failed to create temp file\n" );
2048 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2049 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2050 fli
->ReplaceIfExists
= FALSE
;
2051 fli
->RootDirectory
= NULL
;
2052 fli
->FileNameLength
= name_str
.Length
;
2053 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2054 pRtlFreeUnicodeString( &name_str
);
2056 U(io
).Status
= 0xdeadbeef;
2057 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2058 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2059 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
2060 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2061 ok( !fileDeleted
, "file should exist\n" );
2062 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2063 ok( !fileDeleted
, "file should exist\n" );
2065 CloseHandle( handle
);
2066 HeapFree( GetProcessHeap(), 0, fli
);
2067 delete_object( oldpath
);
2068 delete_object( newpath
);
2070 /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE */
2071 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2072 ok( res
!= 0, "failed to create temp file\n" );
2073 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2074 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2076 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2077 ok( res
!= 0, "failed to create temp file\n" );
2078 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2079 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2080 fli
->ReplaceIfExists
= TRUE
;
2081 fli
->RootDirectory
= NULL
;
2082 fli
->FileNameLength
= name_str
.Length
;
2083 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2084 pRtlFreeUnicodeString( &name_str
);
2086 U(io
).Status
= 0xdeadbeef;
2087 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2088 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
2089 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2090 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2091 ok( !fileDeleted
, "file should exist\n" );
2092 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2093 ok( !fileDeleted
, "file should exist\n" );
2095 CloseHandle( handle
);
2096 HeapFree( GetProcessHeap(), 0, fli
);
2097 delete_object( oldpath
);
2098 delete_object( newpath
);
2100 /* oldpath is a file, newpath is a file, ReplaceIfExists = FALSE, target file opened */
2101 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2102 ok( res
!= 0, "failed to create temp file\n" );
2103 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2104 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2106 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2107 ok( res
!= 0, "failed to create temp file\n" );
2108 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2109 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2111 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2112 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2113 fli
->ReplaceIfExists
= FALSE
;
2114 fli
->RootDirectory
= NULL
;
2115 fli
->FileNameLength
= name_str
.Length
;
2116 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2117 pRtlFreeUnicodeString( &name_str
);
2119 U(io
).Status
= 0xdeadbeef;
2120 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2121 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2122 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
2123 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2124 ok( !fileDeleted
, "file should exist\n" );
2125 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2126 ok( !fileDeleted
, "file should exist\n" );
2128 CloseHandle( handle
);
2129 CloseHandle( handle2
);
2130 HeapFree( GetProcessHeap(), 0, fli
);
2131 delete_object( oldpath
);
2132 delete_object( newpath
);
2134 /* oldpath is a file, newpath is a file, ReplaceIfExists = TRUE, target file opened */
2135 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2136 ok( res
!= 0, "failed to create temp file\n" );
2137 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2138 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2140 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2141 ok( res
!= 0, "failed to create temp file\n" );
2142 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2143 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2145 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2146 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2147 fli
->ReplaceIfExists
= TRUE
;
2148 fli
->RootDirectory
= NULL
;
2149 fli
->FileNameLength
= name_str
.Length
;
2150 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2151 pRtlFreeUnicodeString( &name_str
);
2153 U(io
).Status
= 0xdeadbeef;
2154 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2155 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2156 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
2157 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2158 ok( !fileDeleted
, "file should exist\n" );
2159 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2160 ok( !fileDeleted
, "file should exist\n" );
2162 CloseHandle( handle
);
2163 CloseHandle( handle2
);
2164 HeapFree( GetProcessHeap(), 0, fli
);
2165 delete_object( oldpath
);
2166 delete_object( newpath
);
2168 /* oldpath is a directory, newpath doesn't exist, ReplaceIfExists = FALSE */
2169 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2170 ok( res
!= 0, "failed to create temp file\n" );
2171 DeleteFileW( oldpath
);
2172 success
= CreateDirectoryW( oldpath
, NULL
);
2173 ok( success
!= 0, "failed to create temp directory\n" );
2174 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2175 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2177 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2178 ok( res
!= 0, "failed to create temp file\n" );
2179 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2180 DeleteFileW( newpath
);
2181 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2182 fli
->ReplaceIfExists
= FALSE
;
2183 fli
->RootDirectory
= NULL
;
2184 fli
->FileNameLength
= name_str
.Length
;
2185 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2186 pRtlFreeUnicodeString( &name_str
);
2188 U(io
).Status
= 0xdeadbeef;
2189 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2190 todo_wine
ok( U(io
).Status
== 0xdeadbeef , "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2191 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2192 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2193 ok( !fileDeleted
, "file should exist\n" );
2194 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2195 ok( fileDeleted
, "file should not exist\n" );
2197 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2198 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2199 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2200 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2201 ok( !lstrcmpiW(fni
->FileName
, oldpath
+ 2), "FileName expected %s, got %s\n",
2202 wine_dbgstr_w(oldpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2203 HeapFree( GetProcessHeap(), 0, fni
);
2205 CloseHandle( handle
);
2206 HeapFree( GetProcessHeap(), 0, fli
);
2207 delete_object( oldpath
);
2208 delete_object( newpath
);
2210 /* oldpath is a directory (but child object opened), newpath doesn't exist, ReplaceIfExists = FALSE */
2211 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2212 ok( res
!= 0, "failed to create temp file\n" );
2213 DeleteFileW( oldpath
);
2214 success
= CreateDirectoryW( oldpath
, NULL
);
2215 ok( success
!= 0, "failed to create temp directory\n" );
2216 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2217 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2219 lstrcpyW( newpath
, oldpath
);
2220 lstrcatW( newpath
, foo_txtW
);
2221 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0 );
2222 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2224 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2225 ok( res
!= 0, "failed to create temp file\n" );
2226 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2227 DeleteFileW( newpath
);
2228 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2229 fli
->ReplaceIfExists
= FALSE
;
2230 fli
->RootDirectory
= NULL
;
2231 fli
->FileNameLength
= name_str
.Length
;
2232 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2233 pRtlFreeUnicodeString( &name_str
);
2235 U(io
).Status
= 0xdeadbeef;
2236 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2237 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2238 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2239 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2240 ok( !fileDeleted
, "file should exist\n" );
2241 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2242 ok( fileDeleted
, "file should not exist\n" );
2244 CloseHandle( handle
);
2245 CloseHandle( handle2
);
2246 HeapFree( GetProcessHeap(), 0, fli
);
2247 delete_object( oldpath
);
2248 delete_object( newpath
);
2250 /* oldpath is a directory, newpath is a file, ReplaceIfExists = FALSE */
2251 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2252 ok( res
!= 0, "failed to create temp file\n" );
2253 DeleteFileW( oldpath
);
2254 success
= CreateDirectoryW( oldpath
, NULL
);
2255 ok( success
!= 0, "failed to create temp directory\n" );
2256 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2257 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2259 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2260 ok( res
!= 0, "failed to create temp file\n" );
2261 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2262 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2263 fli
->ReplaceIfExists
= FALSE
;
2264 fli
->RootDirectory
= NULL
;
2265 fli
->FileNameLength
= name_str
.Length
;
2266 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2267 pRtlFreeUnicodeString( &name_str
);
2269 U(io
).Status
= 0xdeadbeef;
2270 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2271 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2272 ok( res
== STATUS_OBJECT_NAME_COLLISION
|| res
== STATUS_FILE_IS_A_DIRECTORY
/* > Win XP */,
2273 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2274 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2275 ok( !fileDeleted
, "file should exist\n" );
2276 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2277 ok( !fileDeleted
, "file should exist\n" );
2279 CloseHandle( handle
);
2280 HeapFree( GetProcessHeap(), 0, fli
);
2281 delete_object( oldpath
);
2282 delete_object( newpath
);
2284 /* oldpath is a directory, newpath is a file, ReplaceIfExists = FALSE, target file opened */
2285 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2286 ok( res
!= 0, "failed to create temp file\n" );
2287 DeleteFileW( oldpath
);
2288 success
= CreateDirectoryW( oldpath
, NULL
);
2289 ok( success
!= 0, "failed to create temp directory\n" );
2290 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2291 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2293 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2294 ok( res
!= 0, "failed to create temp file\n" );
2295 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2296 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2298 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2299 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2300 fli
->ReplaceIfExists
= FALSE
;
2301 fli
->RootDirectory
= NULL
;
2302 fli
->FileNameLength
= name_str
.Length
;
2303 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2304 pRtlFreeUnicodeString( &name_str
);
2306 U(io
).Status
= 0xdeadbeef;
2307 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2308 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2309 ok( res
== STATUS_OBJECT_NAME_COLLISION
|| res
== STATUS_FILE_IS_A_DIRECTORY
/* > Win XP */,
2310 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2311 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2312 ok( !fileDeleted
, "file should exist\n" );
2313 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2314 ok( !fileDeleted
, "file should exist\n" );
2316 CloseHandle( handle
);
2317 CloseHandle( handle2
);
2318 HeapFree( GetProcessHeap(), 0, fli
);
2319 delete_object( oldpath
);
2320 delete_object( newpath
);
2322 /* oldpath is a directory, newpath is a file, ReplaceIfExists = TRUE */
2323 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2324 ok( res
!= 0, "failed to create temp file\n" );
2325 DeleteFileW( oldpath
);
2326 success
= CreateDirectoryW( oldpath
, NULL
);
2327 ok( success
!= 0, "failed to create temp directory\n" );
2328 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2329 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2331 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2332 ok( res
!= 0, "failed to create temp file\n" );
2333 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2334 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2335 fli
->ReplaceIfExists
= TRUE
;
2336 fli
->RootDirectory
= NULL
;
2337 fli
->FileNameLength
= name_str
.Length
;
2338 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2339 pRtlFreeUnicodeString( &name_str
);
2341 U(io
).Status
= 0xdeadbeef;
2342 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2343 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2344 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2345 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2346 ok( !fileDeleted
, "file should exist\n" );
2347 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2348 ok( !fileDeleted
, "file should exist\n" );
2350 CloseHandle( handle
);
2351 HeapFree( GetProcessHeap(), 0, fli
);
2352 delete_object( oldpath
);
2353 delete_object( newpath
);
2355 /* oldpath is a directory, newpath is a file, ReplaceIfExists = TRUE, target file opened */
2356 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2357 ok( res
!= 0, "failed to create temp file\n" );
2358 DeleteFileW( oldpath
);
2359 success
= CreateDirectoryW( oldpath
, NULL
);
2360 ok( success
!= 0, "failed to create temp directory\n" );
2361 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2362 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2364 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2365 ok( res
!= 0, "failed to create temp file\n" );
2366 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2367 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2369 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2370 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2371 fli
->ReplaceIfExists
= TRUE
;
2372 fli
->RootDirectory
= NULL
;
2373 fli
->FileNameLength
= name_str
.Length
;
2374 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2375 pRtlFreeUnicodeString( &name_str
);
2377 U(io
).Status
= 0xdeadbeef;
2378 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2379 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2380 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2381 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2382 ok( !fileDeleted
, "file should exist\n" );
2383 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2384 ok( !fileDeleted
, "file should exist\n" );
2386 CloseHandle( handle
);
2387 CloseHandle( handle2
);
2388 HeapFree( GetProcessHeap(), 0, fli
);
2389 delete_object( oldpath
);
2390 delete_object( newpath
);
2392 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = FALSE */
2393 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2394 ok( res
!= 0, "failed to create temp file\n" );
2395 DeleteFileW( oldpath
);
2396 success
= CreateDirectoryW( oldpath
, NULL
);
2397 ok( success
!= 0, "failed to create temp directory\n" );
2398 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2399 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2401 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2402 ok( res
!= 0, "failed to create temp file\n" );
2403 DeleteFileW( newpath
);
2404 success
= CreateDirectoryW( newpath
, NULL
);
2405 ok( success
!= 0, "failed to create temp directory\n" );
2406 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2407 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2408 fli
->ReplaceIfExists
= FALSE
;
2409 fli
->RootDirectory
= NULL
;
2410 fli
->FileNameLength
= name_str
.Length
;
2411 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2412 pRtlFreeUnicodeString( &name_str
);
2414 U(io
).Status
= 0xdeadbeef;
2415 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2416 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2417 ok( res
== STATUS_OBJECT_NAME_COLLISION
|| res
== STATUS_FILE_IS_A_DIRECTORY
/* > Win XP */,
2418 "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2419 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2420 ok( !fileDeleted
, "file should exist\n" );
2421 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2422 ok( !fileDeleted
, "file should exist\n" );
2424 CloseHandle( handle
);
2425 HeapFree( GetProcessHeap(), 0, fli
);
2426 delete_object( oldpath
);
2427 delete_object( newpath
);
2429 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = TRUE */
2430 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2431 ok( res
!= 0, "failed to create temp file\n" );
2432 DeleteFileW( oldpath
);
2433 success
= CreateDirectoryW( oldpath
, NULL
);
2434 ok( success
!= 0, "failed to create temp directory\n" );
2435 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2436 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2438 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2439 ok( res
!= 0, "failed to create temp file\n" );
2440 DeleteFileW( newpath
);
2441 success
= CreateDirectoryW( newpath
, NULL
);
2442 ok( success
!= 0, "failed to create temp directory\n" );
2443 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2444 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2445 fli
->ReplaceIfExists
= TRUE
;
2446 fli
->RootDirectory
= NULL
;
2447 fli
->FileNameLength
= name_str
.Length
;
2448 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2449 pRtlFreeUnicodeString( &name_str
);
2451 U(io
).Status
= 0xdeadbeef;
2452 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2453 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2454 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2455 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2456 ok( !fileDeleted
, "file should exist\n" );
2457 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2458 ok( !fileDeleted
, "file should exist\n" );
2460 CloseHandle( handle
);
2461 HeapFree( GetProcessHeap(), 0, fli
);
2462 delete_object( oldpath
);
2463 delete_object( newpath
);
2465 /* oldpath is a directory, newpath is a directory, ReplaceIfExists = TRUE, target file opened */
2466 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2467 ok( res
!= 0, "failed to create temp file\n" );
2468 DeleteFileW( oldpath
);
2469 success
= CreateDirectoryW( oldpath
, NULL
);
2470 ok( success
!= 0, "failed to create temp directory\n" );
2471 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2472 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2474 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2475 ok( res
!= 0, "failed to create temp file\n" );
2476 DeleteFileW( newpath
);
2477 success
= CreateDirectoryW( newpath
, NULL
);
2478 ok( success
!= 0, "failed to create temp directory\n" );
2479 handle2
= CreateFileW( newpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2480 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2482 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2483 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2484 fli
->ReplaceIfExists
= TRUE
;
2485 fli
->RootDirectory
= NULL
;
2486 fli
->FileNameLength
= name_str
.Length
;
2487 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2488 pRtlFreeUnicodeString( &name_str
);
2490 U(io
).Status
= 0xdeadbeef;
2491 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2492 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2493 ok( res
== STATUS_FILE_IS_A_DIRECTORY
, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res
);
2494 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2495 ok( !fileDeleted
, "file should exist\n" );
2496 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2497 ok( !fileDeleted
, "file should exist\n" );
2499 CloseHandle( handle
);
2500 CloseHandle( handle2
);
2501 HeapFree( GetProcessHeap(), 0, fli
);
2502 delete_object( oldpath
);
2503 delete_object( newpath
);
2505 /* oldpath is a file, newpath is a directory, ReplaceIfExists = FALSE */
2506 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2507 ok( res
!= 0, "failed to create temp file\n" );
2508 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2509 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2511 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2512 ok( res
!= 0, "failed to create temp file\n" );
2513 DeleteFileW( newpath
);
2514 success
= CreateDirectoryW( newpath
, NULL
);
2515 ok( success
!= 0, "failed to create temp directory\n" );
2516 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2517 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2518 fli
->ReplaceIfExists
= FALSE
;
2519 fli
->RootDirectory
= NULL
;
2520 fli
->FileNameLength
= name_str
.Length
;
2521 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2522 pRtlFreeUnicodeString( &name_str
);
2524 U(io
).Status
= 0xdeadbeef;
2525 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2526 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2527 ok( res
== STATUS_OBJECT_NAME_COLLISION
, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res
);
2528 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2529 ok( !fileDeleted
, "file should exist\n" );
2530 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2531 ok( !fileDeleted
, "file should exist\n" );
2533 CloseHandle( handle
);
2534 HeapFree( GetProcessHeap(), 0, fli
);
2535 delete_object( oldpath
);
2536 delete_object( newpath
);
2538 /* oldpath is a file, newpath is a directory, ReplaceIfExists = TRUE */
2539 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2540 ok( res
!= 0, "failed to create temp file\n" );
2541 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2542 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2544 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2545 ok( res
!= 0, "failed to create temp file\n" );
2546 DeleteFileW( newpath
);
2547 success
= CreateDirectoryW( newpath
, NULL
);
2548 ok( success
!= 0, "failed to create temp directory\n" );
2549 pRtlDosPathNameToNtPathName_U( newpath
, &name_str
, NULL
, NULL
);
2550 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + name_str
.Length
);
2551 fli
->ReplaceIfExists
= TRUE
;
2552 fli
->RootDirectory
= NULL
;
2553 fli
->FileNameLength
= name_str
.Length
;
2554 memcpy( fli
->FileName
, name_str
.Buffer
, name_str
.Length
);
2555 pRtlFreeUnicodeString( &name_str
);
2557 U(io
).Status
= 0xdeadbeef;
2558 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2559 todo_wine
ok( U(io
).Status
== 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io
).Status
);
2560 ok( res
== STATUS_ACCESS_DENIED
, "res expected STATUS_ACCESS_DENIED, got %x\n", res
);
2561 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2562 ok( !fileDeleted
, "file should exist\n" );
2563 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2564 ok( !fileDeleted
, "file should exist\n" );
2566 CloseHandle( handle
);
2567 HeapFree( GetProcessHeap(), 0, fli
);
2568 delete_object( oldpath
);
2569 delete_object( newpath
);
2571 /* oldpath is a file, newpath doesn't exist, test with RootDirectory != NULL */
2572 res
= GetTempFileNameW( tmp_path
, fooW
, 0, oldpath
);
2573 ok( res
!= 0, "failed to create temp file\n" );
2574 handle
= CreateFileW( oldpath
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2575 ok( handle
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2577 res
= GetTempFileNameW( tmp_path
, fooW
, 0, newpath
);
2578 ok( res
!= 0, "failed to create temp file\n" );
2579 DeleteFileW( newpath
);
2580 for (filename
= newpath
, p
= newpath
; *p
; p
++)
2581 if (*p
== '\\') filename
= p
+ 1;
2582 handle2
= CreateFileW( tmp_path
, 0, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2583 ok( handle2
!= INVALID_HANDLE_VALUE
, "CreateFileW failed\n" );
2585 fli
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_LINK_INFORMATION
) + lstrlenW(filename
) * sizeof(WCHAR
) );
2586 fli
->ReplaceIfExists
= FALSE
;
2587 fli
->RootDirectory
= handle2
;
2588 fli
->FileNameLength
= lstrlenW(filename
) * sizeof(WCHAR
);
2589 memcpy( fli
->FileName
, filename
, fli
->FileNameLength
);
2591 U(io
).Status
= 0xdeadbeef;
2592 res
= pNtSetInformationFile( handle
, &io
, fli
, sizeof(FILE_LINK_INFORMATION
) + fli
->FileNameLength
, FileLinkInformation
);
2593 ok( U(io
).Status
== STATUS_SUCCESS
, "io.Status expected STATUS_SUCCESS, got %x\n", U(io
).Status
);
2594 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2595 fileDeleted
= GetFileAttributesW( oldpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2596 ok( !fileDeleted
, "file should exist\n" );
2597 fileDeleted
= GetFileAttributesW( newpath
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2598 ok( !fileDeleted
, "file should exist\n" );
2600 fni
= HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
) );
2601 res
= pNtQueryInformationFile( handle
, &io
, fni
, sizeof(FILE_NAME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
), FileNameInformation
);
2602 ok( res
== STATUS_SUCCESS
, "res expected STATUS_SUCCESS, got %x\n", res
);
2603 fni
->FileName
[ fni
->FileNameLength
/ sizeof(WCHAR
) ] = 0;
2604 ok( !lstrcmpiW(fni
->FileName
, oldpath
+ 2), "FileName expected %s, got %s\n",
2605 wine_dbgstr_w(oldpath
+ 2), wine_dbgstr_w(fni
->FileName
) );
2606 HeapFree( GetProcessHeap(), 0, fni
);
2608 CloseHandle( handle
);
2609 CloseHandle( handle2
);
2610 HeapFree( GetProcessHeap(), 0, fli
);
2611 delete_object( oldpath
);
2612 delete_object( newpath
);
2615 static void test_file_both_information(void)
2618 FILE_BOTH_DIR_INFORMATION fbi
;
2622 if (!(h
= create_temp_file(0))) return;
2624 memset(&fbi
, 0, sizeof(fbi
));
2625 res
= pNtQueryInformationFile(h
, &io
, &fbi
, sizeof fbi
, FileBothDirectoryInformation
);
2626 ok ( res
== STATUS_INVALID_INFO_CLASS
|| res
== STATUS_NOT_IMPLEMENTED
, "shouldn't be able to query FileBothDirectoryInformation, res %x\n", res
);
2631 static void test_file_disposition_information(void)
2633 char tmp_path
[MAX_PATH
], buffer
[MAX_PATH
+ 16];
2635 HANDLE handle
, handle2
, mapping
;
2638 FILE_DISPOSITION_INFORMATION fdi
;
2643 GetTempPathA( MAX_PATH
, tmp_path
);
2645 /* tests for info struct size */
2646 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2647 handle
= CreateFileA( buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0 );
2648 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2649 res
= pNtSetInformationFile( handle
, &io
, &fdi
, 0, FileDispositionInformation
);
2651 ok( res
== STATUS_INFO_LENGTH_MISMATCH
, "expected STATUS_INFO_LENGTH_MISMATCH, got %x\n", res
);
2653 res
= pNtSetInformationFile( handle
, &io
, &fdi2
, sizeof(fdi2
), FileDispositionInformation
);
2654 ok( res
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %x\n", res
);
2655 CloseHandle( handle
);
2656 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2657 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2658 DeleteFileA( buffer
);
2660 /* cannot set disposition on file not opened with delete access */
2661 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2662 handle
= CreateFileA(buffer
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2663 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2664 res
= pNtQueryInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2665 ok( res
== STATUS_INVALID_INFO_CLASS
|| res
== STATUS_NOT_IMPLEMENTED
, "Unexpected NtQueryInformationFile result (expected STATUS_INVALID_INFO_CLASS, got %x)\n", res
);
2666 fdi
.DoDeleteFile
= TRUE
;
2667 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2668 ok( res
== STATUS_ACCESS_DENIED
, "unexpected FileDispositionInformation result (expected STATUS_ACCESS_DENIED, got %x)\n", res
);
2669 CloseHandle( handle
);
2670 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2671 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2672 DeleteFileA( buffer
);
2674 /* can set disposition on file opened with proper access */
2675 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2676 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2677 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2678 fdi
.DoDeleteFile
= TRUE
;
2679 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2680 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2681 CloseHandle( handle
);
2682 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2683 ok( fileDeleted
, "File should have been deleted\n" );
2684 DeleteFileA( buffer
);
2686 /* cannot set disposition on readonly file */
2687 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2688 DeleteFileA( buffer
);
2689 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_READONLY
, 0);
2690 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2691 fdi
.DoDeleteFile
= TRUE
;
2692 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2693 ok( res
== STATUS_CANNOT_DELETE
, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res
);
2694 CloseHandle( handle
);
2695 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2696 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2697 SetFileAttributesA( buffer
, FILE_ATTRIBUTE_NORMAL
);
2698 DeleteFileA( buffer
);
2700 /* cannot set disposition on readonly file */
2701 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2702 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_READONLY
, 0);
2703 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2704 fdi
.DoDeleteFile
= TRUE
;
2705 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2707 ok( res
== STATUS_CANNOT_DELETE
, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res
);
2708 CloseHandle( handle
);
2709 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2711 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2712 SetFileAttributesA( buffer
, FILE_ATTRIBUTE_NORMAL
);
2713 DeleteFileA( buffer
);
2715 /* can set disposition on file and then reset it */
2716 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2717 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2718 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2719 fdi
.DoDeleteFile
= TRUE
;
2720 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2721 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2722 fdi
.DoDeleteFile
= FALSE
;
2723 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2724 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2725 CloseHandle( handle
);
2726 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2727 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2728 DeleteFileA( buffer
);
2730 /* Delete-on-close flag doesn't change file disposition until a handle is closed */
2731 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2732 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0);
2733 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2734 fdi
.DoDeleteFile
= FALSE
;
2735 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2736 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2737 CloseHandle( handle
);
2738 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2739 ok( fileDeleted
, "File should have been deleted\n" );
2740 DeleteFileA( buffer
);
2742 /* Delete-on-close flag sets disposition when a handle is closed and then it could be changed back */
2743 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2744 handle
= CreateFileA(buffer
, GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, FILE_FLAG_DELETE_ON_CLOSE
, 0);
2745 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2746 ok( DuplicateHandle( GetCurrentProcess(), handle
, GetCurrentProcess(), &handle2
, 0, FALSE
, DUPLICATE_SAME_ACCESS
), "DuplicateHandle failed\n" );
2747 CloseHandle( handle
);
2748 fdi
.DoDeleteFile
= FALSE
;
2749 res
= pNtSetInformationFile( handle2
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2750 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2751 CloseHandle( handle2
);
2752 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2753 ok( fileDeleted
, "File should have been deleted\n" );
2754 DeleteFileA( buffer
);
2756 /* can set disposition on a directory opened with proper access */
2757 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2758 DeleteFileA( buffer
);
2759 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
2760 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2761 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
2762 fdi
.DoDeleteFile
= TRUE
;
2763 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2764 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2765 CloseHandle( handle
);
2766 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2767 ok( fileDeleted
, "Directory should have been deleted\n" );
2768 RemoveDirectoryA( buffer
);
2770 /* RemoveDirectory sets directory disposition and it can be undone */
2771 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2772 DeleteFileA( buffer
);
2773 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
2774 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2775 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
2776 RemoveDirectoryA( buffer
);
2777 fdi
.DoDeleteFile
= FALSE
;
2778 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2779 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2780 CloseHandle( handle
);
2781 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2782 ok( !fileDeleted
, "Directory shouldn't have been deleted\n" );
2783 RemoveDirectoryA( buffer
);
2785 /* cannot set disposition on a non-empty directory */
2786 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2787 DeleteFileA( buffer
);
2788 ok( CreateDirectoryA( buffer
, NULL
), "CreateDirectory failed\n" );
2789 handle
= CreateFileA(buffer
, DELETE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0);
2790 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to open a directory\n" );
2791 dirpos
= lstrlenA( buffer
);
2792 lstrcpyA( buffer
+ dirpos
, "\\tst" );
2793 handle2
= CreateFileA(buffer
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2794 CloseHandle( handle2
);
2795 fdi
.DoDeleteFile
= TRUE
;
2796 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2798 ok( res
== STATUS_DIRECTORY_NOT_EMPTY
, "unexpected FileDispositionInformation result (expected STATUS_DIRECTORY_NOT_EMPTY, got %x)\n", res
);
2799 DeleteFileA( buffer
);
2800 buffer
[dirpos
] = '\0';
2801 CloseHandle( handle
);
2802 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 file with file mapping opened */
2808 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2809 handle
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2810 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2811 mapping
= CreateFileMappingA( handle
, NULL
, PAGE_READWRITE
, 0, 64 * 1024, "DelFileTest" );
2812 ok( mapping
!= NULL
, "failed to create file mapping\n");
2813 fdi
.DoDeleteFile
= TRUE
;
2814 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2815 ok( res
== STATUS_CANNOT_DELETE
, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res
);
2816 CloseHandle( handle
);
2817 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2818 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2819 CloseHandle( mapping
);
2820 DeleteFileA( buffer
);
2822 /* can set disposition on file with file mapping closed */
2823 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2824 handle
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2825 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2826 mapping
= CreateFileMappingA( handle
, NULL
, PAGE_READWRITE
, 0, 64 * 1024, "DelFileTest" );
2827 ok( mapping
!= NULL
, "failed to create file mapping\n");
2828 CloseHandle( mapping
);
2829 fdi
.DoDeleteFile
= TRUE
;
2830 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2831 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2832 CloseHandle( handle
);
2833 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2834 ok( fileDeleted
, "File should have been deleted\n" );
2835 DeleteFileA( buffer
);
2837 /* cannot set disposition on file which is mapped to memory */
2838 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2839 handle
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2840 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2841 mapping
= CreateFileMappingA( handle
, NULL
, PAGE_READWRITE
, 0, 64 * 1024, "DelFileTest" );
2842 ok( mapping
!= NULL
, "failed to create file mapping\n");
2843 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
2844 ok( ptr
!= NULL
, "MapViewOfFile failed\n");
2845 CloseHandle( mapping
);
2846 fdi
.DoDeleteFile
= TRUE
;
2847 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2848 ok( res
== STATUS_CANNOT_DELETE
, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res
);
2849 CloseHandle( handle
);
2850 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2851 ok( !fileDeleted
, "File shouldn't have been deleted\n" );
2852 UnmapViewOfFile( ptr
);
2853 DeleteFileA( buffer
);
2855 /* can set disposition on file which is mapped to memory and unmapped again */
2856 GetTempFileNameA( tmp_path
, "dis", 0, buffer
);
2857 handle
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
| DELETE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
2858 ok( handle
!= INVALID_HANDLE_VALUE
, "failed to create temp file\n" );
2859 mapping
= CreateFileMappingA( handle
, NULL
, PAGE_READWRITE
, 0, 64 * 1024, "DelFileTest" );
2860 ok( mapping
!= NULL
, "failed to create file mapping\n");
2861 ptr
= MapViewOfFile( mapping
, FILE_MAP_READ
, 0, 0, 4096 );
2862 ok( ptr
!= NULL
, "MapViewOfFile failed\n");
2863 CloseHandle( mapping
);
2864 UnmapViewOfFile( ptr
);
2865 fdi
.DoDeleteFile
= TRUE
;
2866 res
= pNtSetInformationFile( handle
, &io
, &fdi
, sizeof fdi
, FileDispositionInformation
);
2867 ok( res
== STATUS_SUCCESS
, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res
);
2868 CloseHandle( handle
);
2869 fileDeleted
= GetFileAttributesA( buffer
) == INVALID_FILE_ATTRIBUTES
&& GetLastError() == ERROR_FILE_NOT_FOUND
;
2870 ok( fileDeleted
, "File should have been deleted\n" );
2871 DeleteFileA( buffer
);
2874 static void test_iocompletion(void)
2876 HANDLE h
= INVALID_HANDLE_VALUE
;
2879 res
= pNtCreateIoCompletion( &h
, IO_COMPLETION_ALL_ACCESS
, NULL
, 0);
2881 ok( res
== 0, "NtCreateIoCompletion anonymous failed: %x\n", res
);
2882 ok( h
&& h
!= INVALID_HANDLE_VALUE
, "Invalid handle returned\n" );
2884 if ( h
&& h
!= INVALID_HANDLE_VALUE
)
2886 test_iocp_setcompletion(h
);
2887 test_iocp_fileio(h
);
2892 static void test_file_name_information(void)
2894 WCHAR
*file_name
, *volume_prefix
, *expected
;
2895 FILE_NAME_INFORMATION
*info
;
2896 ULONG old_redir
= 1, tmp
;
2897 UINT file_name_size
;
2904 /* GetVolumePathName is not present before w2k */
2905 if (!pGetVolumePathNameW
) {
2906 win_skip("GetVolumePathNameW not found\n");
2910 file_name_size
= GetSystemDirectoryW( NULL
, 0 );
2911 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
2912 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
2913 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
2915 len
= GetSystemDirectoryW( file_name
, file_name_size
);
2916 ok(len
== file_name_size
- 1,
2917 "GetSystemDirectoryW returned %u, expected %u.\n",
2918 len
, file_name_size
- 1);
2920 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
2921 ok(len
, "GetVolumePathNameW failed.\n");
2923 len
= lstrlenW( volume_prefix
);
2924 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
2925 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
2926 expected
[file_name_size
- len
- 1] = '\0';
2928 /* A bit more than we actually need, but it keeps the calculation simple. */
2929 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
2930 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
2932 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( TRUE
, &old_redir
);
2933 h
= CreateFileW( file_name
, GENERIC_READ
,
2934 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
2935 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2936 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( old_redir
, &tmp
);
2937 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
2939 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
) - 1, FileNameInformation
);
2940 ok(hr
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryInformationFile returned %#x.\n", hr
);
2942 memset( info
, 0xcc, info_size
);
2943 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
), FileNameInformation
);
2944 ok(hr
== STATUS_BUFFER_OVERFLOW
, "NtQueryInformationFile returned %#x, expected %#x.\n",
2945 hr
, STATUS_BUFFER_OVERFLOW
);
2946 ok(U(io
).Status
== STATUS_BUFFER_OVERFLOW
, "io.Status is %#x, expected %#x.\n",
2947 U(io
).Status
, STATUS_BUFFER_OVERFLOW
);
2948 ok(info
->FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
), "info->FileNameLength is %u\n", info
->FileNameLength
);
2949 ok(info
->FileName
[2] == 0xcccc, "info->FileName[2] is %#x, expected 0xcccc.\n", info
->FileName
[2]);
2950 ok(CharLowerW((LPWSTR
)(UINT_PTR
)info
->FileName
[1]) == CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]),
2951 "info->FileName[1] is %p, expected %p.\n",
2952 CharLowerW((LPWSTR
)(UINT_PTR
)info
->FileName
[1]), CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]));
2953 ok(io
.Information
== sizeof(*info
), "io.Information is %lu\n", io
.Information
);
2955 memset( info
, 0xcc, info_size
);
2956 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileNameInformation
);
2957 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
2958 ok(U(io
).Status
== STATUS_SUCCESS
, "io.Status is %#x, expected %#x.\n", U(io
).Status
, STATUS_SUCCESS
);
2959 ok(info
->FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
), "info->FileNameLength is %u\n", info
->FileNameLength
);
2960 ok(info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)] == 0xcccc, "info->FileName[len] is %#x, expected 0xcccc.\n",
2961 info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)]);
2962 info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)] = '\0';
2963 ok(!lstrcmpiW( info
->FileName
, expected
), "info->FileName is %s, expected %s.\n",
2964 wine_dbgstr_w( info
->FileName
), wine_dbgstr_w( expected
));
2965 ok(io
.Information
== FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
) + info
->FileNameLength
,
2966 "io.Information is %lu, expected %u.\n",
2967 io
.Information
, FIELD_OFFSET(FILE_NAME_INFORMATION
, FileName
) + info
->FileNameLength
);
2970 HeapFree( GetProcessHeap(), 0, info
);
2971 HeapFree( GetProcessHeap(), 0, expected
);
2972 HeapFree( GetProcessHeap(), 0, volume_prefix
);
2974 if (old_redir
|| !pGetSystemWow64DirectoryW
|| !(file_name_size
= pGetSystemWow64DirectoryW( NULL
, 0 )))
2976 skip("Not running on WoW64, skipping test.\n");
2977 HeapFree( GetProcessHeap(), 0, file_name
);
2981 h
= CreateFileW( file_name
, GENERIC_READ
,
2982 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
2983 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
2984 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
2985 HeapFree( GetProcessHeap(), 0, file_name
);
2987 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
2988 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
2989 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*expected
) );
2991 len
= pGetSystemWow64DirectoryW( file_name
, file_name_size
);
2992 ok(len
== file_name_size
- 1,
2993 "GetSystemWow64DirectoryW returned %u, expected %u.\n",
2994 len
, file_name_size
- 1);
2996 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
2997 ok(len
, "GetVolumePathNameW failed.\n");
2999 len
= lstrlenW( volume_prefix
);
3000 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3001 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3002 expected
[file_name_size
- len
- 1] = '\0';
3004 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3005 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3007 memset( info
, 0xcc, info_size
);
3008 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileNameInformation
);
3009 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
3010 info
->FileName
[info
->FileNameLength
/ sizeof(WCHAR
)] = '\0';
3011 ok(!lstrcmpiW( info
->FileName
, expected
), "info->FileName is %s, expected %s.\n",
3012 wine_dbgstr_w( info
->FileName
), wine_dbgstr_w( expected
));
3015 HeapFree( GetProcessHeap(), 0, info
);
3016 HeapFree( GetProcessHeap(), 0, expected
);
3017 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3018 HeapFree( GetProcessHeap(), 0, file_name
);
3021 static void test_file_all_name_information(void)
3023 WCHAR
*file_name
, *volume_prefix
, *expected
;
3024 FILE_ALL_INFORMATION
*info
;
3025 ULONG old_redir
= 1, tmp
;
3026 UINT file_name_size
;
3033 /* GetVolumePathName is not present before w2k */
3034 if (!pGetVolumePathNameW
) {
3035 win_skip("GetVolumePathNameW not found\n");
3039 file_name_size
= GetSystemDirectoryW( NULL
, 0 );
3040 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3041 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3042 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3044 len
= GetSystemDirectoryW( file_name
, file_name_size
);
3045 ok(len
== file_name_size
- 1,
3046 "GetSystemDirectoryW returned %u, expected %u.\n",
3047 len
, file_name_size
- 1);
3049 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3050 ok(len
, "GetVolumePathNameW failed.\n");
3052 len
= lstrlenW( volume_prefix
);
3053 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3054 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3055 expected
[file_name_size
- len
- 1] = '\0';
3057 /* A bit more than we actually need, but it keeps the calculation simple. */
3058 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3059 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3061 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( TRUE
, &old_redir
);
3062 h
= CreateFileW( file_name
, GENERIC_READ
,
3063 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3064 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3065 if (pRtlWow64EnableFsRedirectionEx
) pRtlWow64EnableFsRedirectionEx( old_redir
, &tmp
);
3066 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3068 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
) - 1, FileAllInformation
);
3069 ok(hr
== STATUS_INFO_LENGTH_MISMATCH
, "NtQueryInformationFile returned %#x, expected %#x.\n",
3070 hr
, STATUS_INFO_LENGTH_MISMATCH
);
3072 memset( info
, 0xcc, info_size
);
3073 hr
= pNtQueryInformationFile( h
, &io
, info
, sizeof(*info
), FileAllInformation
);
3074 ok(hr
== STATUS_BUFFER_OVERFLOW
, "NtQueryInformationFile returned %#x, expected %#x.\n",
3075 hr
, STATUS_BUFFER_OVERFLOW
);
3076 ok(U(io
).Status
== STATUS_BUFFER_OVERFLOW
, "io.Status is %#x, expected %#x.\n",
3077 U(io
).Status
, STATUS_BUFFER_OVERFLOW
);
3078 ok(info
->NameInformation
.FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
),
3079 "info->NameInformation.FileNameLength is %u\n", info
->NameInformation
.FileNameLength
);
3080 ok(info
->NameInformation
.FileName
[2] == 0xcccc,
3081 "info->NameInformation.FileName[2] is %#x, expected 0xcccc.\n", info
->NameInformation
.FileName
[2]);
3082 ok(CharLowerW((LPWSTR
)(UINT_PTR
)info
->NameInformation
.FileName
[1]) == CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]),
3083 "info->NameInformation.FileName[1] is %p, expected %p.\n",
3084 CharLowerW((LPWSTR
)(UINT_PTR
)info
->NameInformation
.FileName
[1]), CharLowerW((LPWSTR
)(UINT_PTR
)expected
[1]));
3085 ok(io
.Information
== sizeof(*info
), "io.Information is %lu\n", io
.Information
);
3087 memset( info
, 0xcc, info_size
);
3088 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileAllInformation
);
3089 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
3090 ok(U(io
).Status
== STATUS_SUCCESS
, "io.Status is %#x, expected %#x.\n", U(io
).Status
, STATUS_SUCCESS
);
3091 ok(info
->NameInformation
.FileNameLength
== lstrlenW( expected
) * sizeof(WCHAR
),
3092 "info->NameInformation.FileNameLength is %u\n", info
->NameInformation
.FileNameLength
);
3093 ok(info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)] == 0xcccc,
3094 "info->NameInformation.FileName[len] is %#x, expected 0xcccc.\n",
3095 info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)]);
3096 info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)] = '\0';
3097 ok(!lstrcmpiW( info
->NameInformation
.FileName
, expected
),
3098 "info->NameInformation.FileName is %s, expected %s.\n",
3099 wine_dbgstr_w( info
->NameInformation
.FileName
), wine_dbgstr_w( expected
));
3100 ok(io
.Information
== FIELD_OFFSET(FILE_ALL_INFORMATION
, NameInformation
.FileName
)
3101 + info
->NameInformation
.FileNameLength
,
3102 "io.Information is %lu\n", io
.Information
);
3105 HeapFree( GetProcessHeap(), 0, info
);
3106 HeapFree( GetProcessHeap(), 0, expected
);
3107 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3109 if (old_redir
|| !pGetSystemWow64DirectoryW
|| !(file_name_size
= pGetSystemWow64DirectoryW( NULL
, 0 )))
3111 skip("Not running on WoW64, skipping test.\n");
3112 HeapFree( GetProcessHeap(), 0, file_name
);
3116 h
= CreateFileW( file_name
, GENERIC_READ
,
3117 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
3118 NULL
, OPEN_EXISTING
, FILE_FLAG_BACKUP_SEMANTICS
, 0 );
3119 ok(h
!= INVALID_HANDLE_VALUE
, "Failed to open file.\n");
3120 HeapFree( GetProcessHeap(), 0, file_name
);
3122 file_name
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*file_name
) );
3123 volume_prefix
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*volume_prefix
) );
3124 expected
= HeapAlloc( GetProcessHeap(), 0, file_name_size
* sizeof(*expected
) );
3126 len
= pGetSystemWow64DirectoryW( file_name
, file_name_size
);
3127 ok(len
== file_name_size
- 1,
3128 "GetSystemWow64DirectoryW returned %u, expected %u.\n",
3129 len
, file_name_size
- 1);
3131 len
= pGetVolumePathNameW( file_name
, volume_prefix
, file_name_size
);
3132 ok(len
, "GetVolumePathNameW failed.\n");
3134 len
= lstrlenW( volume_prefix
);
3135 if (len
&& volume_prefix
[len
- 1] == '\\') --len
;
3136 memcpy( expected
, file_name
+ len
, (file_name_size
- len
- 1) * sizeof(WCHAR
) );
3137 expected
[file_name_size
- len
- 1] = '\0';
3139 info_size
= sizeof(*info
) + (file_name_size
* sizeof(WCHAR
));
3140 info
= HeapAlloc( GetProcessHeap(), 0, info_size
);
3142 memset( info
, 0xcc, info_size
);
3143 hr
= pNtQueryInformationFile( h
, &io
, info
, info_size
, FileAllInformation
);
3144 ok(hr
== STATUS_SUCCESS
, "NtQueryInformationFile returned %#x, expected %#x.\n", hr
, STATUS_SUCCESS
);
3145 info
->NameInformation
.FileName
[info
->NameInformation
.FileNameLength
/ sizeof(WCHAR
)] = '\0';
3146 ok(!lstrcmpiW( info
->NameInformation
.FileName
, expected
), "info->NameInformation.FileName is %s, expected %s.\n",
3147 wine_dbgstr_w( info
->NameInformation
.FileName
), wine_dbgstr_w( expected
));
3150 HeapFree( GetProcessHeap(), 0, info
);
3151 HeapFree( GetProcessHeap(), 0, expected
);
3152 HeapFree( GetProcessHeap(), 0, volume_prefix
);
3153 HeapFree( GetProcessHeap(), 0, file_name
);
3156 static void test_file_completion_information(void)
3158 static const char buf
[] = "testdata";
3159 FILE_IO_COMPLETION_NOTIFICATION_INFORMATION info
;
3160 OVERLAPPED ov
, *pov
;
3169 if (!(h
= create_temp_file(0))) return;
3171 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
) - 1, FileIoCompletionNotificationInformation
);
3172 ok(status
== STATUS_INFO_LENGTH_MISMATCH
|| status
== STATUS_INVALID_INFO_CLASS
/* XP */,
3173 "expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
3174 if (status
== STATUS_INVALID_INFO_CLASS
|| status
== STATUS_NOT_IMPLEMENTED
)
3176 win_skip("FileIoCompletionNotificationInformation class not supported\n");
3181 info
.Flags
= FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
;
3182 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3183 ok(status
== STATUS_INVALID_PARAMETER
, "expected STATUS_INVALID_PARAMETER, got %08x\n", status
);
3186 if (!(h
= create_temp_file(FILE_FLAG_OVERLAPPED
))) return;
3188 info
.Flags
= FILE_SKIP_SET_EVENT_ON_HANDLE
;
3189 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3190 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3192 info
.Flags
= FILE_SKIP_SET_USER_EVENT_ON_FAST_IO
;
3193 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3194 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3197 if (!(h
= create_temp_file(FILE_FLAG_OVERLAPPED
))) return;
3200 status
= pNtQueryInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3201 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3202 ok(!(info
.Flags
& FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
), "got %08x\n", info
.Flags
);
3204 memset(&ov
, 0, sizeof(ov
));
3205 ov
.hEvent
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
3206 port
= CreateIoCompletionPort(h
, NULL
, 0xdeadbeef, 0);
3207 ok(port
!= NULL
, "CreateIoCompletionPort failed, error %u\n", GetLastError());
3209 for (i
= 0; i
< 10; i
++)
3211 SetLastError(0xdeadbeef);
3212 ret
= WriteFile(h
, buf
, sizeof(buf
), &num_bytes
, &ov
);
3213 if (ret
|| GetLastError() != ERROR_IO_PENDING
) break;
3214 ret
= GetOverlappedResult(h
, &ov
, &num_bytes
, TRUE
);
3215 ok(ret
, "GetOverlappedResult failed, error %u\n", GetLastError());
3216 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 1000);
3217 ok(ret
, "GetQueuedCompletionStatus failed, error %u\n", GetLastError());
3222 ok(num_bytes
== sizeof(buf
), "expected sizeof(buf), got %u\n", num_bytes
);
3226 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 1000);
3227 ok(ret
, "GetQueuedCompletionStatus failed, error %u\n", GetLastError());
3228 ok(key
== 0xdeadbeef, "expected 0xdeadbeef, got %lx\n", key
);
3229 ok(pov
== &ov
, "expected %p, got %p\n", &ov
, pov
);
3232 win_skip("WriteFile never returned TRUE\n");
3234 info
.Flags
= FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
;
3235 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3236 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3239 status
= pNtQueryInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3240 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3241 ok((info
.Flags
& FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
) != 0, "got %08x\n", info
.Flags
);
3243 for (i
= 0; i
< 10; i
++)
3245 SetLastError(0xdeadbeef);
3246 ret
= WriteFile(h
, buf
, sizeof(buf
), &num_bytes
, &ov
);
3247 if (ret
|| GetLastError() != ERROR_IO_PENDING
) break;
3248 ret
= GetOverlappedResult(h
, &ov
, &num_bytes
, TRUE
);
3249 ok(ret
, "GetOverlappedResult failed, error %u\n", GetLastError());
3254 ok(num_bytes
== sizeof(buf
), "expected sizeof(buf), got %u\n", num_bytes
);
3256 pov
= (void *)0xdeadbeef;
3257 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 500);
3258 ok(!ret
, "GetQueuedCompletionStatus succeeded\n");
3259 ok(pov
== NULL
, "expected NULL, got %p\n", pov
);
3262 win_skip("WriteFile never returned TRUE\n");
3265 status
= pNtSetInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3266 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3269 status
= pNtQueryInformationFile(h
, &io
, &info
, sizeof(info
), FileIoCompletionNotificationInformation
);
3270 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3271 ok((info
.Flags
& FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
) != 0, "got %08x\n", info
.Flags
);
3273 for (i
= 0; i
< 10; i
++)
3275 SetLastError(0xdeadbeef);
3276 ret
= WriteFile(h
, buf
, sizeof(buf
), &num_bytes
, &ov
);
3277 if (ret
|| GetLastError() != ERROR_IO_PENDING
) break;
3278 ret
= GetOverlappedResult(h
, &ov
, &num_bytes
, TRUE
);
3279 ok(ret
, "GetOverlappedResult failed, error %u\n", GetLastError());
3280 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 1000);
3281 ok(ret
, "GetQueuedCompletionStatus failed, error %u\n", GetLastError());
3286 ok(num_bytes
== sizeof(buf
), "expected sizeof(buf), got %u\n", num_bytes
);
3288 pov
= (void *)0xdeadbeef;
3289 ret
= GetQueuedCompletionStatus(port
, &num_bytes
, &key
, &pov
, 1000);
3290 ok(!ret
, "GetQueuedCompletionStatus succeeded\n");
3291 ok(pov
== NULL
, "expected NULL, got %p\n", pov
);
3294 win_skip("WriteFile never returned TRUE\n");
3296 CloseHandle(ov
.hEvent
);
3301 static void test_file_id_information(void)
3303 BY_HANDLE_FILE_INFORMATION info
;
3304 FILE_ID_INFORMATION fid
;
3311 if (!(h
= create_temp_file(0))) return;
3313 memset( &fid
, 0x11, sizeof(fid
) );
3314 status
= pNtQueryInformationFile( h
, &io
, &fid
, sizeof(fid
), FileIdInformation
);
3315 if (status
== STATUS_NOT_IMPLEMENTED
|| status
== STATUS_INVALID_INFO_CLASS
)
3317 win_skip( "FileIdInformation not supported\n" );
3322 memset( &info
, 0x22, sizeof(info
) );
3323 ret
= GetFileInformationByHandle( h
, &info
);
3324 ok( ret
, "GetFileInformationByHandle failed\n" );
3326 dwords
= (DWORD
*)&fid
.VolumeSerialNumber
;
3327 ok( dwords
[0] == info
.dwVolumeSerialNumber
, "expected %08x, got %08x\n",
3328 info
.dwVolumeSerialNumber
, dwords
[0] );
3329 ok( dwords
[1] != 0x11111111, "expected != 0x11111111\n" );
3331 dwords
= (DWORD
*)&fid
.FileId
;
3332 ok( dwords
[0] == info
.nFileIndexLow
, "expected %08x, got %08x\n", info
.nFileIndexLow
, dwords
[0] );
3333 ok( dwords
[1] == info
.nFileIndexHigh
, "expected %08x, got %08x\n", info
.nFileIndexHigh
, dwords
[1] );
3334 ok( dwords
[2] == 0, "expected 0, got %08x\n", dwords
[2] );
3335 ok( dwords
[3] == 0, "expected 0, got %08x\n", dwords
[3] );
3340 static void test_file_access_information(void)
3342 FILE_ACCESS_INFORMATION info
;
3347 if (!(h
= create_temp_file(0))) return;
3349 status
= pNtQueryInformationFile( h
, &io
, &info
, sizeof(info
) - 1, FileAccessInformation
);
3350 ok( status
== STATUS_INFO_LENGTH_MISMATCH
, "expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status
);
3352 status
= pNtQueryInformationFile( (HANDLE
)0xdeadbeef, &io
, &info
, sizeof(info
), FileAccessInformation
);
3353 ok( status
== STATUS_INVALID_HANDLE
, "expected STATUS_INVALID_HANDLE, got %08x\n", status
);
3355 memset(&info
, 0x11, sizeof(info
));
3356 status
= pNtQueryInformationFile( h
, &io
, &info
, sizeof(info
), FileAccessInformation
);
3357 ok( status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
3358 ok( info
.AccessFlags
== 0x13019f, "got %08x\n", info
.AccessFlags
);
3363 static void test_query_volume_information_file(void)
3367 WCHAR path
[MAX_PATH
];
3368 OBJECT_ATTRIBUTES attr
;
3370 UNICODE_STRING nameW
;
3371 FILE_FS_VOLUME_INFORMATION
*ffvi
;
3372 BYTE buf
[sizeof(FILE_FS_VOLUME_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
)];
3374 GetWindowsDirectoryW( path
, MAX_PATH
);
3375 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
3376 attr
.Length
= sizeof(attr
);
3377 attr
.RootDirectory
= 0;
3378 attr
.ObjectName
= &nameW
;
3379 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
3380 attr
.SecurityDescriptor
= NULL
;
3381 attr
.SecurityQualityOfService
= NULL
;
3383 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
3384 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
3385 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
3386 pRtlFreeUnicodeString( &nameW
);
3388 ZeroMemory( buf
, sizeof(buf
) );
3389 U(io
).Status
= 0xdadadada;
3390 io
.Information
= 0xcacacaca;
3392 status
= pNtQueryVolumeInformationFile( dir
, &io
, buf
, sizeof(buf
), FileFsVolumeInformation
);
3394 ffvi
= (FILE_FS_VOLUME_INFORMATION
*)buf
;
3396 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", status
);
3397 ok(U(io
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", U(io
).Status
);
3401 ok(io
.Information
== (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION
, VolumeLabel
) + ffvi
->VolumeLabelLength
),
3402 "expected %d, got %lu\n", (FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION
, VolumeLabel
) + ffvi
->VolumeLabelLength
),
3405 ok(ffvi
->VolumeCreationTime
.QuadPart
!= 0, "Missing VolumeCreationTime\n");
3406 ok(ffvi
->VolumeSerialNumber
!= 0, "Missing VolumeSerialNumber\n");
3407 ok(ffvi
->SupportsObjects
== 1,"expected 1, got %d\n", ffvi
->SupportsObjects
);
3409 ok(ffvi
->VolumeLabelLength
== lstrlenW(ffvi
->VolumeLabel
) * sizeof(WCHAR
), "got %d\n", ffvi
->VolumeLabelLength
);
3411 trace("VolumeSerialNumber: %x VolumeLabelName: %s\n", ffvi
->VolumeSerialNumber
, wine_dbgstr_w(ffvi
->VolumeLabel
));
3416 static void test_query_attribute_information_file(void)
3420 WCHAR path
[MAX_PATH
];
3421 OBJECT_ATTRIBUTES attr
;
3423 UNICODE_STRING nameW
;
3424 FILE_FS_ATTRIBUTE_INFORMATION
*ffai
;
3425 BYTE buf
[sizeof(FILE_FS_ATTRIBUTE_INFORMATION
) + MAX_PATH
* sizeof(WCHAR
)];
3427 GetWindowsDirectoryW( path
, MAX_PATH
);
3428 pRtlDosPathNameToNtPathName_U( path
, &nameW
, NULL
, NULL
);
3429 attr
.Length
= sizeof(attr
);
3430 attr
.RootDirectory
= 0;
3431 attr
.ObjectName
= &nameW
;
3432 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
3433 attr
.SecurityDescriptor
= NULL
;
3434 attr
.SecurityQualityOfService
= NULL
;
3436 status
= pNtOpenFile( &dir
, SYNCHRONIZE
|FILE_LIST_DIRECTORY
, &attr
, &io
,
3437 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
3438 ok( !status
, "open %s failed %x\n", wine_dbgstr_w(nameW
.Buffer
), status
);
3439 pRtlFreeUnicodeString( &nameW
);
3441 ZeroMemory( buf
, sizeof(buf
) );
3442 U(io
).Status
= 0xdadadada;
3443 io
.Information
= 0xcacacaca;
3445 status
= pNtQueryVolumeInformationFile( dir
, &io
, buf
, sizeof(buf
), FileFsAttributeInformation
);
3447 ffai
= (FILE_FS_ATTRIBUTE_INFORMATION
*)buf
;
3449 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", status
);
3450 ok(U(io
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %d\n", U(io
).Status
);
3451 ok(ffai
->FileSystemAttribute
!= 0, "Missing FileSystemAttribute\n");
3452 ok(ffai
->MaximumComponentNameLength
!= 0, "Missing MaximumComponentNameLength\n");
3453 ok(ffai
->FileSystemNameLength
!= 0, "Missing FileSystemNameLength\n");
3455 trace("FileSystemAttribute: %x MaximumComponentNameLength: %x FileSystemName: %s\n",
3456 ffai
->FileSystemAttribute
, ffai
->MaximumComponentNameLength
,
3457 wine_dbgstr_wn(ffai
->FileSystemName
, ffai
->FileSystemNameLength
/ sizeof(WCHAR
)));
3462 static void test_NtCreateFile(void)
3464 static const struct test_data
3466 DWORD disposition
, attrib_in
, status
, result
, attrib_out
, needs_cleanup
;
3469 /* 0*/{ FILE_CREATE
, FILE_ATTRIBUTE_READONLY
, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3470 /* 1*/{ FILE_CREATE
, 0, STATUS_OBJECT_NAME_COLLISION
, 0, 0, TRUE
},
3471 /* 2*/{ FILE_CREATE
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3472 /* 3*/{ FILE_OPEN
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OPENED
, FILE_ATTRIBUTE_ARCHIVE
, TRUE
},
3473 /* 4*/{ FILE_OPEN
, FILE_ATTRIBUTE_READONLY
, STATUS_OBJECT_NAME_NOT_FOUND
, 0, 0, FALSE
},
3474 /* 5*/{ FILE_OPEN_IF
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3475 /* 6*/{ FILE_OPEN_IF
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OPENED
, FILE_ATTRIBUTE_ARCHIVE
, TRUE
},
3476 /* 7*/{ FILE_OPEN_IF
, FILE_ATTRIBUTE_READONLY
, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3477 /* 8*/{ FILE_OPEN_IF
, 0, 0, FILE_OPENED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3478 /* 9*/{ FILE_OVERWRITE
, 0, STATUS_ACCESS_DENIED
, 0, 0, TRUE
},
3479 /*10*/{ FILE_OVERWRITE
, 0, STATUS_OBJECT_NAME_NOT_FOUND
, 0, 0, FALSE
},
3480 /*11*/{ FILE_CREATE
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3481 /*12*/{ FILE_OVERWRITE
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OVERWRITTEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3482 /*13*/{ FILE_OVERWRITE_IF
, 0, STATUS_ACCESS_DENIED
, 0, 0, TRUE
},
3483 /*14*/{ FILE_OVERWRITE_IF
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3484 /*15*/{ FILE_OVERWRITE_IF
, FILE_ATTRIBUTE_READONLY
, 0, FILE_OVERWRITTEN
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, FALSE
},
3485 /*16*/{ FILE_SUPERSEDE
, 0, 0, FILE_SUPERSEDED
, FILE_ATTRIBUTE_ARCHIVE
, FALSE
},
3486 /*17*/{ FILE_SUPERSEDE
, FILE_ATTRIBUTE_READONLY
, 0, FILE_SUPERSEDED
, FILE_ATTRIBUTE_ARCHIVE
|FILE_ATTRIBUTE_READONLY
, TRUE
},
3487 /*18*/{ FILE_SUPERSEDE
, 0, 0, FILE_CREATED
, FILE_ATTRIBUTE_ARCHIVE
, TRUE
}
3489 static const WCHAR fooW
[] = {'f','o','o',0};
3492 WCHAR path
[MAX_PATH
];
3493 OBJECT_ATTRIBUTES attr
;
3495 UNICODE_STRING nameW
;
3498 GetTempPathW(MAX_PATH
, path
);
3499 GetTempFileNameW(path
, fooW
, 0, path
);
3501 pRtlDosPathNameToNtPathName_U(path
, &nameW
, NULL
, NULL
);
3503 attr
.Length
= sizeof(attr
);
3504 attr
.RootDirectory
= NULL
;
3505 attr
.ObjectName
= &nameW
;
3506 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
3507 attr
.SecurityDescriptor
= NULL
;
3508 attr
.SecurityQualityOfService
= NULL
;
3510 for (i
= 0; i
< sizeof(td
)/sizeof(td
[0]); i
++)
3512 status
= pNtCreateFile(&handle
, GENERIC_READ
, &attr
, &io
, NULL
,
3513 td
[i
].attrib_in
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
3514 td
[i
].disposition
, 0, NULL
, 0);
3516 ok(status
== td
[i
].status
, "%d: expected %#x got %#x\n", i
, td
[i
].status
, status
);
3520 ok(io
.Information
== td
[i
].result
,"%d: expected %#x got %#lx\n", i
, td
[i
].result
, io
.Information
);
3522 ret
= GetFileAttributesW(path
);
3523 ret
&= ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
;
3524 /* FIXME: leave only 'else' case below once Wine is fixed */
3525 if (ret
!= td
[i
].attrib_out
)
3528 ok(ret
== td
[i
].attrib_out
, "%d: expected %#x got %#x\n", i
, td
[i
].attrib_out
, ret
);
3529 SetFileAttributesW(path
, td
[i
].attrib_out
);
3532 ok(ret
== td
[i
].attrib_out
, "%d: expected %#x got %#x\n", i
, td
[i
].attrib_out
, ret
);
3534 CloseHandle(handle
);
3537 if (td
[i
].needs_cleanup
)
3539 SetFileAttributesW(path
, FILE_ATTRIBUTE_ARCHIVE
);
3544 pRtlFreeUnicodeString( &nameW
);
3545 SetFileAttributesW(path
, FILE_ATTRIBUTE_ARCHIVE
);
3546 DeleteFileW( path
);
3549 static void test_readonly(void)
3551 static const WCHAR fooW
[] = {'f','o','o',0};
3554 WCHAR path
[MAX_PATH
];
3555 OBJECT_ATTRIBUTES attr
;
3557 UNICODE_STRING nameW
;
3559 GetTempPathW(MAX_PATH
, path
);
3560 GetTempFileNameW(path
, fooW
, 0, path
);
3562 pRtlDosPathNameToNtPathName_U(path
, &nameW
, NULL
, NULL
);
3564 attr
.Length
= sizeof(attr
);
3565 attr
.RootDirectory
= NULL
;
3566 attr
.ObjectName
= &nameW
;
3567 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
3568 attr
.SecurityDescriptor
= NULL
;
3569 attr
.SecurityQualityOfService
= NULL
;
3571 status
= pNtCreateFile(&handle
, GENERIC_READ
, &attr
, &io
, NULL
, FILE_ATTRIBUTE_READONLY
,
3572 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_CREATE
, 0, NULL
, 0);
3573 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3574 CloseHandle(handle
);
3576 status
= pNtOpenFile(&handle
, GENERIC_WRITE
, &attr
, &io
,
3577 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3578 ok(status
== STATUS_ACCESS_DENIED
, "got %#x\n", status
);
3579 CloseHandle(handle
);
3581 status
= pNtOpenFile(&handle
, GENERIC_READ
, &attr
, &io
,
3582 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3583 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3584 CloseHandle(handle
);
3586 status
= pNtOpenFile(&handle
, FILE_READ_ATTRIBUTES
, &attr
, &io
,
3587 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3588 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3589 CloseHandle(handle
);
3591 status
= pNtOpenFile(&handle
, FILE_WRITE_ATTRIBUTES
, &attr
, &io
,
3592 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3593 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3594 CloseHandle(handle
);
3596 status
= pNtOpenFile(&handle
, DELETE
, &attr
, &io
,
3597 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3598 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3599 CloseHandle(handle
);
3601 status
= pNtOpenFile(&handle
, READ_CONTROL
, &attr
, &io
,
3602 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3603 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3604 CloseHandle(handle
);
3606 status
= pNtOpenFile(&handle
, WRITE_DAC
, &attr
, &io
,
3607 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3608 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3609 CloseHandle(handle
);
3611 status
= pNtOpenFile(&handle
, WRITE_OWNER
, &attr
, &io
,
3612 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3613 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3614 CloseHandle(handle
);
3616 status
= pNtOpenFile(&handle
, SYNCHRONIZE
, &attr
, &io
,
3617 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN_FOR_BACKUP_INTENT
);
3618 ok(status
== STATUS_SUCCESS
, "got %#x\n", status
);
3619 CloseHandle( handle
);
3621 pRtlFreeUnicodeString(&nameW
);
3622 SetFileAttributesW(path
, FILE_ATTRIBUTE_ARCHIVE
);
3626 static void test_read_write(void)
3628 static const char contents
[14] = "1234567890abcd";
3630 HANDLE hfile
, event
;
3632 IO_STATUS_BLOCK iob
;
3633 DWORD ret
, bytes
, status
, off
;
3634 LARGE_INTEGER offset
;
3637 event
= CreateEventA( NULL
, TRUE
, FALSE
, NULL
);
3640 iob
.Information
= -1;
3641 offset
.QuadPart
= 0;
3642 status
= pNtReadFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3643 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status
);
3644 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3645 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3648 iob
.Information
= -1;
3649 offset
.QuadPart
= 0;
3650 status
= pNtReadFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, NULL
, sizeof(buf
), &offset
, NULL
);
3651 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status
);
3652 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3653 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3656 iob
.Information
= -1;
3657 offset
.QuadPart
= 0;
3658 status
= pNtWriteFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3659 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status
);
3660 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3661 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3664 iob
.Information
= -1;
3665 offset
.QuadPart
= 0;
3666 status
= pNtWriteFile(INVALID_HANDLE_VALUE
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3667 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
|| status
== STATUS_INVALID_HANDLE
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %#x\n", status
);
3668 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3669 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3671 hfile
= create_temp_file(0);
3675 iob
.Information
= -1;
3676 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
3677 ok(status
== STATUS_INVALID_USER_BUFFER
, "expected STATUS_INVALID_USER_BUFFER, got %#x\n", status
);
3678 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3679 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3682 iob
.Information
= -1;
3684 status
= pNtWriteFile(hfile
, event
, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
3685 ok(status
== STATUS_INVALID_USER_BUFFER
, "expected STATUS_INVALID_USER_BUFFER, got %#x\n", status
);
3686 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3687 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3688 ok(!is_signaled(event
), "event is not signaled\n");
3691 iob
.Information
= -1;
3692 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
3693 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#x\n", status
);
3694 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3695 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3698 iob
.Information
= -1;
3700 status
= pNtReadFile(hfile
, event
, NULL
, NULL
, &iob
, NULL
, sizeof(contents
), NULL
, NULL
);
3701 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#x\n", status
);
3702 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3703 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3704 ok(is_signaled(event
), "event is not signaled\n");
3707 iob
.Information
= -1;
3709 status
= pNtReadFile(hfile
, event
, NULL
, NULL
, &iob
, (void*)0xdeadbeef, sizeof(contents
), NULL
, NULL
);
3710 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#x\n", status
);
3711 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3712 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
3713 ok(is_signaled(event
), "event is not signaled\n");
3716 iob
.Information
= -1;
3717 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, 7, NULL
, NULL
);
3718 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
3719 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3720 ok(iob
.Information
== 7, "expected 7, got %lu\n", iob
.Information
);
3722 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3725 iob
.Information
= -1;
3726 offset
.QuadPart
= (LONGLONG
)-1 /* FILE_WRITE_TO_END_OF_FILE */;
3727 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
+ 7, sizeof(contents
) - 7, &offset
, NULL
);
3728 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
3729 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3730 ok(iob
.Information
== sizeof(contents
) - 7, "expected sizeof(contents)-7, got %lu\n", iob
.Information
);
3732 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3733 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3736 SetLastError(0xdeadbeef);
3737 ret
= ReadFile(INVALID_HANDLE_VALUE
, buf
, 0, &bytes
, NULL
);
3738 ok(!ret
, "ReadFile should fail\n");
3739 ok(GetLastError() == ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
3740 ok(bytes
== 0, "bytes %u\n", bytes
);
3743 SetLastError(0xdeadbeef);
3744 ret
= ReadFile(hfile
, buf
, 0, &bytes
, NULL
);
3745 ok(ret
, "ReadFile error %d\n", GetLastError());
3746 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3747 ok(bytes
== 0, "bytes %u\n", bytes
);
3750 SetLastError(0xdeadbeef);
3751 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3752 ok(ret
, "ReadFile error %d\n", GetLastError());
3753 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3754 ok(bytes
== 0, "bytes %u\n", bytes
);
3756 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3759 SetLastError(0xdeadbeef);
3760 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3761 ok(ret
, "ReadFile error %d\n", GetLastError());
3762 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3763 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
3765 for (i
= -20; i
< -1; i
++)
3767 if (i
== -2) continue;
3770 iob
.Information
= -1;
3771 offset
.QuadPart
= (LONGLONG
)i
;
3772 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), &offset
, NULL
);
3773 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
3774 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3775 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
3778 SetFilePointer(hfile
, sizeof(contents
) - 4, NULL
, FILE_BEGIN
);
3781 iob
.Information
= -1;
3782 offset
.QuadPart
= (LONGLONG
)-2 /* FILE_USE_FILE_POINTER_POSITION */;
3783 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, "DCBA", 4, &offset
, NULL
);
3784 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
3785 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3786 ok(iob
.Information
== 4, "expected 4, got %lu\n", iob
.Information
);
3788 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3789 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3792 iob
.Information
= -1;
3793 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), NULL
, NULL
);
3794 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3795 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3796 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3798 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3801 SetLastError(0xdeadbeef);
3802 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3803 ok(ret
, "ReadFile error %d\n", GetLastError());
3804 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3805 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
3806 ok(!memcmp(buf
+ sizeof(contents
) - 4, "DCBA", 4), "file contents mismatch\n");
3808 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3809 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3811 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3814 SetLastError(0xdeadbeef);
3815 ret
= WriteFile(hfile
, contents
, sizeof(contents
), &bytes
, NULL
);
3816 ok(ret
, "WriteFile error %d\n", GetLastError());
3817 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3819 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3820 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3822 /* test reading beyond EOF */
3824 SetLastError(0xdeadbeef);
3825 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3826 ok(ret
, "ReadFile error %d\n", GetLastError());
3827 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3828 ok(bytes
== 0, "bytes %u\n", bytes
);
3831 SetLastError(0xdeadbeef);
3832 ret
= ReadFile(hfile
, buf
, 0, &bytes
, NULL
);
3833 ok(ret
, "ReadFile error %d\n", GetLastError());
3834 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3835 ok(bytes
== 0, "bytes %u\n", bytes
);
3838 SetLastError(0xdeadbeef);
3839 ret
= ReadFile(hfile
, NULL
, 0, &bytes
, NULL
);
3840 ok(ret
, "ReadFile error %d\n", GetLastError());
3841 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3842 ok(bytes
== 0, "bytes %u\n", bytes
);
3844 S(U(ovl
)).Offset
= sizeof(contents
);
3845 S(U(ovl
)).OffsetHigh
= 0;
3847 ovl
.InternalHigh
= -1;
3850 SetLastError(0xdeadbeef);
3851 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
3852 ok(!ret
, "ReadFile should fail\n");
3853 ok(GetLastError() == ERROR_HANDLE_EOF
, "expected ERROR_HANDLE_EOF, got %d\n", GetLastError());
3854 ok(bytes
== 0, "bytes %u\n", bytes
);
3855 ok((NTSTATUS
)ovl
.Internal
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", ovl
.Internal
);
3856 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
3858 S(U(ovl
)).Offset
= sizeof(contents
);
3859 S(U(ovl
)).OffsetHigh
= 0;
3861 ovl
.InternalHigh
= -1;
3864 SetLastError(0xdeadbeef);
3865 ret
= ReadFile(hfile
, buf
, 0, &bytes
, &ovl
);
3866 ok(ret
, "ReadFile error %d\n", GetLastError());
3867 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
3868 ok(bytes
== 0, "bytes %u\n", bytes
);
3869 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
3870 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
3873 iob
.Information
= -1;
3874 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), NULL
, NULL
);
3875 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3876 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3877 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3880 iob
.Information
= -1;
3881 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, NULL
, NULL
);
3882 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3883 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3884 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3887 iob
.Information
= -1;
3888 offset
.QuadPart
= sizeof(contents
);
3889 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3890 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3891 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3892 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3895 iob
.Information
= -1;
3896 offset
.QuadPart
= sizeof(contents
);
3897 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, &offset
, NULL
);
3898 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3899 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3900 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3903 iob
.Information
= -1;
3904 offset
.QuadPart
= (LONGLONG
)-2 /* FILE_USE_FILE_POINTER_POSITION */;
3905 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3906 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
3907 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
3908 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3911 iob
.Information
= -1;
3912 offset
.QuadPart
= (LONGLONG
)-2 /* FILE_USE_FILE_POINTER_POSITION */;
3913 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, &offset
, NULL
);
3914 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3915 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3916 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
3918 for (i
= -20; i
< 0; i
++)
3920 if (i
== -2) continue;
3923 iob
.Information
= -1;
3924 offset
.QuadPart
= (LONGLONG
)i
;
3925 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3926 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
3927 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
3928 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
3931 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
3934 SetLastError(0xdeadbeef);
3935 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
3936 ok(ret
, "ReadFile error %d\n", GetLastError());
3937 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
3938 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
3940 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3941 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3944 iob
.Information
= -1;
3945 offset
.QuadPart
= 0;
3946 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3947 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3948 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3949 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %lu\n", iob
.Information
);
3950 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
3952 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3953 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3956 iob
.Information
= -1;
3957 offset
.QuadPart
= sizeof(contents
) - 4;
3958 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, "DCBA", 4, &offset
, NULL
);
3959 ok(status
== STATUS_SUCCESS
, "NtWriteFile error %#x\n", status
);
3960 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3961 ok(iob
.Information
== 4, "expected 4, got %lu\n", iob
.Information
);
3963 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3964 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3967 iob
.Information
= -1;
3968 offset
.QuadPart
= 0;
3969 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
3970 ok(status
== STATUS_SUCCESS
, "NtReadFile error %#x\n", status
);
3971 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
3972 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %lu\n", iob
.Information
);
3973 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
3974 ok(!memcmp(buf
+ sizeof(contents
) - 4, "DCBA", 4), "file contents mismatch\n");
3976 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3977 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3979 S(U(ovl
)).Offset
= sizeof(contents
) - 4;
3980 S(U(ovl
)).OffsetHigh
= 0;
3983 SetLastError(0xdeadbeef);
3984 ret
= WriteFile(hfile
, "ABCD", 4, &bytes
, &ovl
);
3985 ok(ret
, "WriteFile error %d\n", GetLastError());
3986 ok(bytes
== 4, "bytes %u\n", bytes
);
3988 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
3989 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
3991 S(U(ovl
)).Offset
= 0;
3992 S(U(ovl
)).OffsetHigh
= 0;
3994 ovl
.InternalHigh
= -1;
3997 SetLastError(0xdeadbeef);
3998 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
3999 ok(ret
, "ReadFile error %d\n", GetLastError());
4000 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
4001 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4002 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4003 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
4004 ok(!memcmp(buf
+ sizeof(contents
) - 4, "ABCD", 4), "file contents mismatch\n");
4006 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4007 ok(off
== sizeof(contents
), "expected sizeof(contents), got %u\n", off
);
4011 hfile
= create_temp_file(FILE_FLAG_OVERLAPPED
);
4015 SetLastError(0xdeadbeef);
4016 ret
= ReadFile(INVALID_HANDLE_VALUE
, buf
, 0, &bytes
, NULL
);
4017 ok(!ret
, "ReadFile should fail\n");
4018 ok(GetLastError() == ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
4019 ok(bytes
== 0, "bytes %u\n", bytes
);
4021 S(U(ovl
)).Offset
= 0;
4022 S(U(ovl
)).OffsetHigh
= 0;
4024 ovl
.InternalHigh
= -1;
4027 SetLastError(0xdeadbeef);
4028 /* ReadFile return value depends on Windows version and testing it is not practical */
4029 ReadFile(hfile
, buf
, 0, &bytes
, &ovl
);
4030 ok(bytes
== 0, "bytes %u\n", bytes
);
4031 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4032 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
4035 SetLastError(0xdeadbeef);
4036 ret
= WriteFile(hfile
, contents
, sizeof(contents
), &bytes
, NULL
);
4037 ok(!ret
, "WriteFile should fail\n");
4038 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
4039 ok(bytes
== 0, "bytes %u\n", bytes
);
4042 iob
.Information
= -1;
4043 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), NULL
, NULL
);
4044 ok(status
== STATUS_INVALID_PARAMETER
, "expected STATUS_INVALID_PARAMETER, got %#x\n", status
);
4045 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4046 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
4048 for (i
= -20; i
< -1; i
++)
4051 iob
.Information
= -1;
4052 offset
.QuadPart
= (LONGLONG
)i
;
4053 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), &offset
, NULL
);
4054 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
4055 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4056 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
4060 iob
.Information
= -1;
4061 offset
.QuadPart
= 0;
4062 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, contents
, sizeof(contents
), &offset
, NULL
);
4063 ok(status
== STATUS_PENDING
|| status
== STATUS_SUCCESS
/* before Vista */, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status
);
4064 if (status
== STATUS_PENDING
)
4066 ret
= WaitForSingleObject(hfile
, 3000);
4067 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4069 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4070 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %lu\n", iob
.Information
);
4072 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4073 ok(off
== 0, "expected 0, got %u\n", off
);
4076 SetLastError(0xdeadbeef);
4077 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, NULL
);
4078 ok(!ret
, "ReadFile should fail\n");
4079 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
4080 ok(bytes
== 0, "bytes %u\n", bytes
);
4083 iob
.Information
= -1;
4084 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), NULL
, NULL
);
4085 ok(status
== STATUS_INVALID_PARAMETER
, "expected STATUS_INVALID_PARAMETER, got %#x\n", status
);
4086 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4087 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
4089 for (i
= -20; i
< 0; i
++)
4092 iob
.Information
= -1;
4093 offset
.QuadPart
= (LONGLONG
)i
;
4094 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4095 ok(status
== STATUS_INVALID_PARAMETER
, "%d: expected STATUS_INVALID_PARAMETER, got %#x\n", i
, status
);
4096 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4097 ok(iob
.Information
== -1, "expected -1, got %ld\n", iob
.Information
);
4100 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4101 ok(off
== 0, "expected 0, got %u\n", off
);
4103 /* test reading beyond EOF */
4104 offset
.QuadPart
= sizeof(contents
);
4105 S(U(ovl
)).Offset
= offset
.u
.LowPart
;
4106 S(U(ovl
)).OffsetHigh
= offset
.u
.HighPart
;
4108 ovl
.InternalHigh
= -1;
4111 SetLastError(0xdeadbeef);
4112 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4113 ok(!ret
, "ReadFile should fail\n");
4114 ret
= GetLastError();
4115 ok(ret
== ERROR_IO_PENDING
|| ret
== ERROR_HANDLE_EOF
/* before Vista */, "expected ERROR_IO_PENDING or ERROR_HANDLE_EOF, got %d\n", ret
);
4116 ok(bytes
== 0, "bytes %u\n", bytes
);
4118 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4119 ok(off
== 0, "expected 0, got %u\n", off
);
4121 if (ret
== ERROR_IO_PENDING
)
4124 SetLastError(0xdeadbeef);
4125 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4126 ok(!ret
, "GetOverlappedResult should report FALSE\n");
4127 ok(GetLastError() == ERROR_HANDLE_EOF
, "expected ERROR_HANDLE_EOF, got %d\n", GetLastError());
4128 ok(bytes
== 0, "expected 0, read %u\n", bytes
);
4129 ok((NTSTATUS
)ovl
.Internal
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#lx\n", ovl
.Internal
);
4130 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
4133 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4134 ok(off
== 0, "expected 0, got %u\n", off
);
4136 offset
.QuadPart
= sizeof(contents
);
4137 S(U(ovl
)).Offset
= offset
.u
.LowPart
;
4138 S(U(ovl
)).OffsetHigh
= offset
.u
.HighPart
;
4140 ovl
.InternalHigh
= -1;
4143 SetLastError(0xdeadbeef);
4144 ret
= ReadFile(hfile
, buf
, 0, &bytes
, &ovl
);
4145 /* ReadFile return value depends on Windows version and testing it is not practical */
4147 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4148 ret
= GetLastError();
4149 ok(bytes
== 0, "bytes %u\n", bytes
);
4151 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4152 ok(off
== 0, "expected 0, got %u\n", off
);
4154 if (ret
== ERROR_IO_PENDING
)
4157 SetLastError(0xdeadbeef);
4158 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4159 ok(ret
, "GetOverlappedResult should report TRUE\n");
4160 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
4161 ok(bytes
== 0, "expected 0, read %u\n", bytes
);
4162 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4163 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
4166 offset
.QuadPart
= sizeof(contents
);
4167 S(U(ovl
)).Offset
= offset
.u
.LowPart
;
4168 S(U(ovl
)).OffsetHigh
= offset
.u
.HighPart
;
4170 ovl
.InternalHigh
= -1;
4173 SetLastError(0xdeadbeef);
4174 ret
= ReadFile(hfile
, NULL
, 0, &bytes
, &ovl
);
4175 /* ReadFile return value depends on Windows version and testing it is not practical */
4177 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4178 ret
= GetLastError();
4179 ok(bytes
== 0, "bytes %u\n", bytes
);
4181 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4182 ok(off
== 0, "expected 0, got %u\n", off
);
4184 if (ret
== ERROR_IO_PENDING
)
4187 SetLastError(0xdeadbeef);
4188 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4189 ok(ret
, "GetOverlappedResult should report TRUE\n");
4190 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
4191 ok(bytes
== 0, "expected 0, read %u\n", bytes
);
4192 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4193 ok(ovl
.InternalHigh
== 0, "expected 0, got %lu\n", ovl
.InternalHigh
);
4197 iob
.Information
= -1;
4198 offset
.QuadPart
= sizeof(contents
);
4199 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4200 if (status
== STATUS_PENDING
)
4202 ret
= WaitForSingleObject(hfile
, 3000);
4203 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4204 ok(U(iob
).Status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", U(iob
).Status
);
4205 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
4209 ok(status
== STATUS_END_OF_FILE
, "expected STATUS_END_OF_FILE, got %#x\n", status
);
4210 ok(U(iob
).Status
== -1, "expected -1, got %#x\n", U(iob
).Status
);
4211 ok(iob
.Information
== -1, "expected -1, got %lu\n", iob
.Information
);
4214 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4215 ok(off
== 0, "expected 0, got %u\n", off
);
4218 iob
.Information
= -1;
4219 offset
.QuadPart
= sizeof(contents
);
4220 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, 0, &offset
, NULL
);
4221 if (status
== STATUS_PENDING
)
4223 ret
= WaitForSingleObject(hfile
, 3000);
4224 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4225 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4226 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
4230 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", status
);
4231 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4232 ok(iob
.Information
== 0, "expected 0, got %lu\n", iob
.Information
);
4235 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4236 ok(off
== 0, "expected 0, got %u\n", off
);
4238 S(U(ovl
)).Offset
= 0;
4239 S(U(ovl
)).OffsetHigh
= 0;
4241 ovl
.InternalHigh
= -1;
4244 SetLastError(0xdeadbeef);
4245 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4246 /* ReadFile return value depends on Windows version and testing it is not practical */
4249 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4250 ok(bytes
== 0, "bytes %u\n", bytes
);
4252 else ok(bytes
== 14, "bytes %u\n", bytes
);
4253 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4254 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4256 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4257 ok(off
== 0, "expected 0, got %u\n", off
);
4260 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4261 ok(ret
, "GetOverlappedResult error %d\n", GetLastError());
4262 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
4263 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4264 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4265 ok(!memcmp(contents
, buf
, sizeof(contents
)), "file contents mismatch\n");
4267 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4268 ok(off
== 0, "expected 0, got %u\n", off
);
4270 SetFilePointer(hfile
, sizeof(contents
) - 4, NULL
, FILE_BEGIN
);
4271 SetEndOfFile(hfile
);
4272 SetFilePointer(hfile
, 0, NULL
, FILE_BEGIN
);
4275 iob
.Information
= -1;
4276 offset
.QuadPart
= (LONGLONG
)-1 /* FILE_WRITE_TO_END_OF_FILE */;
4277 status
= pNtWriteFile(hfile
, 0, NULL
, NULL
, &iob
, "DCBA", 4, &offset
, NULL
);
4278 ok(status
== STATUS_PENDING
|| status
== STATUS_SUCCESS
/* before Vista */, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status
);
4279 if (status
== STATUS_PENDING
)
4281 ret
= WaitForSingleObject(hfile
, 3000);
4282 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4284 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4285 ok(iob
.Information
== 4, "expected 4, got %lu\n", iob
.Information
);
4287 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4288 ok(off
== 0, "expected 0, got %u\n", off
);
4291 iob
.Information
= -1;
4292 offset
.QuadPart
= 0;
4293 status
= pNtReadFile(hfile
, 0, NULL
, NULL
, &iob
, buf
, sizeof(buf
), &offset
, NULL
);
4294 ok(status
== STATUS_PENDING
|| status
== STATUS_SUCCESS
, "expected STATUS_PENDING or STATUS_SUCCESS, got %#x\n", status
);
4295 if (status
== STATUS_PENDING
)
4297 ret
= WaitForSingleObject(hfile
, 3000);
4298 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4300 ok(U(iob
).Status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x\n", U(iob
).Status
);
4301 ok(iob
.Information
== sizeof(contents
), "expected sizeof(contents), got %lu\n", iob
.Information
);
4303 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4304 ok(off
== 0, "expected 0, got %u\n", off
);
4306 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
4307 ok(!memcmp(buf
+ sizeof(contents
) - 4, "DCBA", 4), "file contents mismatch\n");
4309 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4310 ok(off
== 0, "expected 0, got %u\n", off
);
4312 S(U(ovl
)).Offset
= sizeof(contents
) - 4;
4313 S(U(ovl
)).OffsetHigh
= 0;
4315 ovl
.InternalHigh
= -1;
4318 SetLastError(0xdeadbeef);
4319 ret
= WriteFile(hfile
, "ABCD", 4, &bytes
, &ovl
);
4320 /* WriteFile return value depends on Windows version and testing it is not practical */
4323 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4324 ok(bytes
== 0, "bytes %u\n", bytes
);
4325 ret
= WaitForSingleObject(hfile
, 3000);
4326 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4328 else ok(bytes
== 4, "bytes %u\n", bytes
);
4329 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4330 ok(ovl
.InternalHigh
== 4, "expected 4, got %lu\n", ovl
.InternalHigh
);
4332 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4333 ok(off
== 0, "expected 0, got %u\n", off
);
4336 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4337 ok(ret
, "GetOverlappedResult error %d\n", GetLastError());
4338 ok(bytes
== 4, "bytes %u\n", bytes
);
4339 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4340 ok(ovl
.InternalHigh
== 4, "expected 4, got %lu\n", ovl
.InternalHigh
);
4342 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4343 ok(off
== 0, "expected 0, got %u\n", off
);
4345 S(U(ovl
)).Offset
= 0;
4346 S(U(ovl
)).OffsetHigh
= 0;
4348 ovl
.InternalHigh
= -1;
4351 SetLastError(0xdeadbeef);
4352 ret
= ReadFile(hfile
, buf
, sizeof(buf
), &bytes
, &ovl
);
4353 /* ReadFile return value depends on Windows version and testing it is not practical */
4356 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
4357 ok(bytes
== 0, "bytes %u\n", bytes
);
4358 ret
= WaitForSingleObject(hfile
, 3000);
4359 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject error %d\n", ret
);
4361 else ok(bytes
== 14, "bytes %u\n", bytes
);
4362 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4363 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4365 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4366 ok(off
== 0, "expected 0, got %u\n", off
);
4369 ret
= GetOverlappedResult(hfile
, &ovl
, &bytes
, TRUE
);
4370 ok(ret
, "GetOverlappedResult error %d\n", GetLastError());
4371 ok(bytes
== sizeof(contents
), "bytes %u\n", bytes
);
4372 ok((NTSTATUS
)ovl
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", ovl
.Internal
);
4373 ok(ovl
.InternalHigh
== sizeof(contents
), "expected sizeof(contents), got %lu\n", ovl
.InternalHigh
);
4374 ok(!memcmp(contents
, buf
, sizeof(contents
) - 4), "file contents mismatch\n");
4375 ok(!memcmp(buf
+ sizeof(contents
) - 4, "ABCD", 4), "file contents mismatch\n");
4377 off
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
4378 ok(off
== 0, "expected 0, got %u\n", off
);
4384 static void test_ioctl(void)
4386 HANDLE event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
4387 FILE_PIPE_PEEK_BUFFER peek_buf
;
4388 IO_STATUS_BLOCK iosb
;
4392 file
= create_temp_file(FILE_FLAG_OVERLAPPED
);
4393 ok(file
!= INVALID_HANDLE_VALUE
, "could not create temp file\n");
4396 status
= pNtFsControlFile(file
, event
, NULL
, NULL
, &iosb
, 0xdeadbeef, 0, 0, 0, 0);
4398 ok(status
== STATUS_INVALID_DEVICE_REQUEST
, "NtFsControlFile returned %x\n", status
);
4399 ok(!is_signaled(event
), "event is signaled\n");
4401 status
= pNtFsControlFile(file
, (HANDLE
)0xdeadbeef, NULL
, NULL
, &iosb
, 0xdeadbeef, 0, 0, 0, 0);
4402 ok(status
== STATUS_INVALID_HANDLE
, "NtFsControlFile returned %x\n", status
);
4404 memset(&iosb
, 0x55, sizeof(iosb
));
4405 status
= NtFsControlFile(file
, NULL
, NULL
, NULL
, &iosb
, FSCTL_PIPE_PEEK
, NULL
, 0,
4406 &peek_buf
, sizeof(peek_buf
));
4408 ok(status
== STATUS_INVALID_DEVICE_REQUEST
, "NtFsControlFile failed: %x\n", status
);
4409 ok(iosb
.Status
== 0x55555555, "iosb.Status = %x\n", iosb
.Status
);
4415 static void test_flush_buffers_file(void)
4417 char path
[MAX_PATH
], buffer
[MAX_PATH
];
4418 HANDLE hfile
, hfileread
;
4420 IO_STATUS_BLOCK io_status_block
;
4422 GetTempPathA(MAX_PATH
, path
);
4423 GetTempFileNameA(path
, "foo", 0, buffer
);
4424 hfile
= CreateFileA(buffer
, GENERIC_READ
| GENERIC_WRITE
, FILE_SHARE_READ
, NULL
, CREATE_ALWAYS
,
4425 FILE_ATTRIBUTE_NORMAL
, 0);
4426 ok(hfile
!= INVALID_HANDLE_VALUE
, "failed to create temp file.\n" );
4428 hfileread
= CreateFileA(buffer
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
4429 OPEN_EXISTING
, 0, NULL
);
4430 ok(hfileread
!= INVALID_HANDLE_VALUE
, "could not open temp file, error %d.\n", GetLastError());
4432 status
= pNtFlushBuffersFile(hfile
, NULL
);
4434 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#x.\n", status
);
4436 status
= pNtFlushBuffersFile(hfile
, (IO_STATUS_BLOCK
*)0xdeadbeaf);
4438 ok(status
== STATUS_ACCESS_VIOLATION
, "expected STATUS_ACCESS_VIOLATION, got %#x.\n", status
);
4440 status
= pNtFlushBuffersFile(hfile
, &io_status_block
);
4441 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x.\n", status
);
4443 status
= pNtFlushBuffersFile(hfileread
, &io_status_block
);
4444 ok(status
== STATUS_ACCESS_DENIED
, "expected STATUS_ACCESS_DENIED, got %#x.\n", status
);
4446 status
= pNtFlushBuffersFile(NULL
, &io_status_block
);
4447 ok(status
== STATUS_INVALID_HANDLE
, "expected STATUS_INVALID_HANDLE, got %#x.\n", status
);
4449 CloseHandle(hfileread
);
4451 hfile
= CreateFileA(buffer
, FILE_APPEND_DATA
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
4452 OPEN_EXISTING
, 0, NULL
);
4453 ok(hfile
!= INVALID_HANDLE_VALUE
, "could not open temp file, error %d.\n", GetLastError());
4455 status
= pNtFlushBuffersFile(hfile
, &io_status_block
);
4456 ok(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#x.\n", status
);
4459 DeleteFileA(buffer
);
4462 static void test_query_ea(void)
4464 #define EA_BUFFER_SIZE 4097
4465 unsigned char data
[EA_BUFFER_SIZE
+ 8];
4466 unsigned char *buffer
= (void *)(((DWORD_PTR
)data
+ 7) & ~7);
4467 DWORD buffer_len
, i
;
4472 if (!(handle
= create_temp_file(0))) return;
4474 /* test with INVALID_HANDLE_VALUE */
4475 U(io
).Status
= 0xdeadbeef;
4476 io
.Information
= 0xdeadbeef;
4477 memset(buffer
, 0xcc, EA_BUFFER_SIZE
);
4478 buffer_len
= EA_BUFFER_SIZE
- 1;
4479 status
= pNtQueryEaFile(INVALID_HANDLE_VALUE
, &io
, buffer
, buffer_len
, TRUE
, NULL
, 0, NULL
, FALSE
);
4480 ok(status
== STATUS_OBJECT_TYPE_MISMATCH
, "expected STATUS_OBJECT_TYPE_MISMATCH, got %x\n", status
);
4481 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io
).Status
);
4482 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io
.Information
);
4483 ok(buffer
[0] == 0xcc, "data at position 0 overwritten\n");
4485 /* test with 0xdeadbeef */
4486 U(io
).Status
= 0xdeadbeef;
4487 io
.Information
= 0xdeadbeef;
4488 memset(buffer
, 0xcc, EA_BUFFER_SIZE
);
4489 buffer_len
= EA_BUFFER_SIZE
- 1;
4490 status
= pNtQueryEaFile((void *)0xdeadbeef, &io
, buffer
, buffer_len
, TRUE
, NULL
, 0, NULL
, FALSE
);
4491 ok(status
== STATUS_INVALID_HANDLE
, "expected STATUS_INVALID_HANDLE, got %x\n", status
);
4492 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io
).Status
);
4493 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io
.Information
);
4494 ok(buffer
[0] == 0xcc, "data at position 0 overwritten\n");
4496 /* test without buffer */
4497 U(io
).Status
= 0xdeadbeef;
4498 io
.Information
= 0xdeadbeef;
4499 status
= pNtQueryEaFile(handle
, &io
, NULL
, 0, TRUE
, NULL
, 0, NULL
, FALSE
);
4500 ok(status
== STATUS_NO_EAS_ON_FILE
, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status
);
4501 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io
).Status
);
4502 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io
.Information
);
4504 /* test with zero buffer */
4505 U(io
).Status
= 0xdeadbeef;
4506 io
.Information
= 0xdeadbeef;
4507 status
= pNtQueryEaFile(handle
, &io
, buffer
, 0, TRUE
, NULL
, 0, NULL
, FALSE
);
4508 ok(status
== STATUS_NO_EAS_ON_FILE
, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status
);
4509 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io
).Status
);
4510 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io
.Information
);
4512 /* test with very small buffer */
4513 U(io
).Status
= 0xdeadbeef;
4514 io
.Information
= 0xdeadbeef;
4515 memset(buffer
, 0xcc, EA_BUFFER_SIZE
);
4517 status
= pNtQueryEaFile(handle
, &io
, buffer
, buffer_len
, TRUE
, NULL
, 0, NULL
, FALSE
);
4518 ok(status
== STATUS_NO_EAS_ON_FILE
, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status
);
4519 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io
).Status
);
4520 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io
.Information
);
4521 for (i
= 0; i
< buffer_len
&& !buffer
[i
]; i
++);
4522 ok(i
== buffer_len
, "expected %u bytes filled with 0x00, got %u bytes\n", buffer_len
, i
);
4523 ok(buffer
[i
] == 0xcc, "data at position %u overwritten\n", buffer
[i
]);
4525 /* test with very big buffer */
4526 U(io
).Status
= 0xdeadbeef;
4527 io
.Information
= 0xdeadbeef;
4528 memset(buffer
, 0xcc, EA_BUFFER_SIZE
);
4529 buffer_len
= EA_BUFFER_SIZE
- 1;
4530 status
= pNtQueryEaFile(handle
, &io
, buffer
, buffer_len
, TRUE
, NULL
, 0, NULL
, FALSE
);
4531 ok(status
== STATUS_NO_EAS_ON_FILE
, "expected STATUS_NO_EAS_ON_FILE, got %x\n", status
);
4532 ok(U(io
).Status
== 0xdeadbeef, "expected 0xdeadbeef, got %x\n", U(io
).Status
);
4533 ok(io
.Information
== 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", io
.Information
);
4534 for (i
= 0; i
< buffer_len
&& !buffer
[i
]; i
++);
4535 ok(i
== buffer_len
, "expected %u bytes filled with 0x00, got %u bytes\n", buffer_len
, i
);
4536 ok(buffer
[i
] == 0xcc, "data at position %u overwritten\n", buffer
[i
]);
4538 CloseHandle(handle
);
4539 #undef EA_BUFFER_SIZE
4542 static INT
build_reparse_buffer(WCHAR
*filename
, REPARSE_DATA_BUFFER
**pbuffer
)
4544 REPARSE_DATA_BUFFER
*buffer
;
4545 INT buffer_len
, string_len
;
4548 string_len
= (lstrlenW(filename
)+1)*sizeof(WCHAR
);
4549 buffer_len
= FIELD_OFFSET(REPARSE_DATA_BUFFER
, MountPointReparseBuffer
.PathBuffer
[1]) + string_len
;
4550 buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, buffer_len
);
4551 buffer
->ReparseTag
= IO_REPARSE_TAG_MOUNT_POINT
;
4552 buffer
->ReparseDataLength
= sizeof(buffer
->MountPointReparseBuffer
) + string_len
;
4553 buffer
->MountPointReparseBuffer
.SubstituteNameLength
= string_len
- sizeof(WCHAR
);
4554 buffer
->MountPointReparseBuffer
.PrintNameOffset
= string_len
;
4555 dest
= &buffer
->MountPointReparseBuffer
.PathBuffer
[0];
4556 memcpy(dest
, filename
, string_len
);
4561 static void test_junction_points(void)
4563 static const WCHAR junctionW
[] = {'\\','j','u','n','c','t','i','o','n',0};
4564 WCHAR path
[MAX_PATH
], junction_path
[MAX_PATH
], target_path
[MAX_PATH
];
4565 static const WCHAR targetW
[] = {'\\','t','a','r','g','e','t',0};
4566 FILE_BASIC_INFORMATION old_attrib
, new_attrib
;
4567 static const WCHAR fooW
[] = {'f','o','o',0};
4568 static WCHAR volW
[] = {'c',':','\\',0};
4569 REPARSE_GUID_DATA_BUFFER guid_buffer
;
4570 static const WCHAR dotW
[] = {'.',0};
4571 REPARSE_DATA_BUFFER
*buffer
= NULL
;
4572 DWORD dwret
, dwLen
, dwFlags
, err
;
4573 INT buffer_len
, string_len
;
4574 IO_STATUS_BLOCK iosb
;
4575 UNICODE_STRING nameW
;
4580 /* Create a temporary folder for the junction point tests */
4581 GetTempFileNameW(dotW
, fooW
, 0, path
);
4583 if (!CreateDirectoryW(path
, NULL
))
4585 win_skip("Unable to create a temporary junction point directory.\n");
4589 /* Check that the volume this folder is located on supports junction points */
4590 pRtlDosPathNameToNtPathName_U(path
, &nameW
, NULL
, NULL
);
4591 volW
[0] = nameW
.Buffer
[4];
4592 pRtlFreeUnicodeString( &nameW
);
4593 GetVolumeInformationW(volW
, 0, 0, 0, &dwLen
, &dwFlags
, 0, 0);
4594 if (!(dwFlags
& FILE_SUPPORTS_REPARSE_POINTS
))
4596 skip("File system does not support junction points.\n");
4597 RemoveDirectoryW(path
);
4601 /* Create the folder to be replaced by a junction point */
4602 lstrcpyW(junction_path
, path
);
4603 lstrcatW(junction_path
, junctionW
);
4604 bret
= CreateDirectoryW(junction_path
, NULL
);
4605 ok(bret
, "Failed to create junction point directory.\n");
4607 /* Create a destination folder for the junction point to target */
4608 lstrcpyW(target_path
, path
);
4609 lstrcatW(target_path
, targetW
);
4610 bret
= CreateDirectoryW(target_path
, NULL
);
4611 ok(bret
, "Failed to create junction point target directory.\n");
4612 pRtlDosPathNameToNtPathName_U(target_path
, &nameW
, NULL
, NULL
);
4614 /* Create the junction point */
4615 hJunction
= CreateFileW(junction_path
, GENERIC_READ
| GENERIC_WRITE
, 0, 0, OPEN_EXISTING
,
4616 FILE_FLAG_BACKUP_SEMANTICS
| FILE_FLAG_OPEN_REPARSE_POINT
, 0);
4617 if (hJunction
== INVALID_HANDLE_VALUE
)
4619 win_skip("Failed to open junction point directory handle (0x%x).\n", GetLastError());
4622 dwret
= NtQueryInformationFile(hJunction
, &iosb
, &old_attrib
, sizeof(old_attrib
), FileBasicInformation
);
4623 ok(dwret
== STATUS_SUCCESS
, "Failed to get junction point folder's attributes (0x%x).\n", dwret
);
4624 buffer_len
= build_reparse_buffer(nameW
.Buffer
, &buffer
);
4625 bret
= DeviceIoControl(hJunction
, FSCTL_SET_REPARSE_POINT
, (LPVOID
)buffer
, buffer_len
, NULL
, 0, &dwret
, 0);
4626 ok(bret
, "Failed to create junction point! (0x%x)\n", GetLastError());
4628 /* Check the file attributes of the junction point */
4629 dwret
= GetFileAttributesW(junction_path
);
4630 ok(dwret
!= (DWORD
)~0, "Junction point doesn't exist (attributes: 0x%x)!\n", dwret
);
4631 ok(dwret
& FILE_ATTRIBUTE_REPARSE_POINT
, "File is not a junction point! (attributes: %d)\n", dwret
);
4633 /* Read back the junction point */
4634 HeapFree(GetProcessHeap(), 0, buffer
);
4635 buffer_len
= sizeof(*buffer
) + MAX_PATH
*sizeof(WCHAR
);
4636 buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, buffer_len
);
4637 bret
= DeviceIoControl(hJunction
, FSCTL_GET_REPARSE_POINT
, NULL
, 0, (LPVOID
)buffer
, buffer_len
, &dwret
, 0);
4638 string_len
= buffer
->MountPointReparseBuffer
.SubstituteNameLength
;
4639 dest
= &buffer
->MountPointReparseBuffer
.PathBuffer
[buffer
->MountPointReparseBuffer
.SubstituteNameOffset
/sizeof(WCHAR
)];
4640 ok(bret
, "Failed to read junction point!\n");
4641 ok((memcmp(dest
, nameW
.Buffer
, string_len
) == 0), "Junction point destination does not match ('%s' != '%s')!\n",
4642 wine_dbgstr_w(dest
), wine_dbgstr_w(nameW
.Buffer
));
4644 /* Delete the junction point */
4645 memset(&old_attrib
, 0x00, sizeof(old_attrib
));
4646 old_attrib
.LastAccessTime
.QuadPart
= 0x200deadcafebeef;
4647 dwret
= NtSetInformationFile(hJunction
, &iosb
, &old_attrib
, sizeof(old_attrib
), FileBasicInformation
);
4648 ok(dwret
== STATUS_SUCCESS
, "Failed to set junction point folder's attributes (0x%x).\n", dwret
);
4649 memset(&guid_buffer
, 0x00, sizeof(guid_buffer
));
4650 guid_buffer
.ReparseTag
= IO_REPARSE_TAG_MOUNT_POINT
;
4651 bret
= DeviceIoControl(hJunction
, FSCTL_DELETE_REPARSE_POINT
, (LPVOID
)&guid_buffer
,
4652 REPARSE_GUID_DATA_BUFFER_HEADER_SIZE
, NULL
, 0, &dwret
, 0);
4653 ok(bret
, "Failed to delete junction point! (0x%x)\n", GetLastError());
4654 memset(&new_attrib
, 0x00, sizeof(new_attrib
));
4655 dwret
= NtQueryInformationFile(hJunction
, &iosb
, &new_attrib
, sizeof(new_attrib
), FileBasicInformation
);
4656 ok(dwret
== STATUS_SUCCESS
, "Failed to get junction point folder's attributes (0x%x).\n", dwret
);
4657 ok(old_attrib
.LastAccessTime
.QuadPart
== new_attrib
.LastAccessTime
.QuadPart
,
4658 "Junction point folder's access time does not match.\n");
4659 CloseHandle(hJunction
);
4661 /* Check deleting a junction point as if it were a directory */
4662 HeapFree(GetProcessHeap(), 0, buffer
);
4663 hJunction
= CreateFileW(junction_path
, GENERIC_READ
| GENERIC_WRITE
, 0, 0, OPEN_EXISTING
,
4664 FILE_FLAG_BACKUP_SEMANTICS
| FILE_FLAG_OPEN_REPARSE_POINT
, 0);
4665 buffer_len
= build_reparse_buffer(nameW
.Buffer
, &buffer
);
4666 bret
= DeviceIoControl(hJunction
, FSCTL_SET_REPARSE_POINT
, (LPVOID
)buffer
, buffer_len
, NULL
, 0, &dwret
, 0);
4667 ok(bret
, "Failed to create junction point! (0x%x)\n", GetLastError());
4668 CloseHandle(hJunction
);
4669 bret
= RemoveDirectoryW(junction_path
);
4670 ok(bret
, "Failed to delete junction point as directory!\n");
4671 dwret
= GetFileAttributesW(junction_path
);
4672 ok(dwret
== (DWORD
)~0, "Junction point still exists (attributes: 0x%x)!\n", dwret
);
4674 /* Check deleting a junction point as if it were a file */
4675 HeapFree(GetProcessHeap(), 0, buffer
);
4676 bret
= CreateDirectoryW(junction_path
, NULL
);
4677 ok(bret
, "Failed to create junction point target directory.\n");
4678 hJunction
= CreateFileW(junction_path
, GENERIC_READ
| GENERIC_WRITE
, 0, 0, OPEN_EXISTING
,
4679 FILE_FLAG_BACKUP_SEMANTICS
| FILE_FLAG_OPEN_REPARSE_POINT
, 0);
4680 buffer_len
= build_reparse_buffer(nameW
.Buffer
, &buffer
);
4681 bret
= DeviceIoControl(hJunction
, FSCTL_SET_REPARSE_POINT
, (LPVOID
)buffer
, buffer_len
, NULL
, 0, &dwret
, 0);
4682 ok(bret
, "Failed to create junction point! (0x%x)\n", GetLastError());
4683 CloseHandle(hJunction
);
4684 bret
= DeleteFileW(junction_path
);
4685 ok(!bret
, "Succeeded in deleting junction point as file!\n");
4686 err
= GetLastError();
4687 ok(err
== ERROR_ACCESS_DENIED
, "Expected last error 0x%x for DeleteFile on junction point (actually 0x%x)!\n",
4688 ERROR_ACCESS_DENIED
, err
);
4689 dwret
= GetFileAttributesW(junction_path
);
4690 ok(dwret
!= (DWORD
)~0, "Junction point doesn't exist (attributes: 0x%x)!\n", dwret
);
4691 ok(dwret
& FILE_ATTRIBUTE_REPARSE_POINT
, "File is not a junction point! (attributes: 0x%x)\n", dwret
);
4693 /* Test deleting a junction point's target */
4694 dwret
= GetFileAttributesW(junction_path
);
4695 ok(dwret
== 0x410 || broken(dwret
== 0x430) /* win2k */,
4696 "Unexpected junction point attributes (0x%x != 0x410)!\n", dwret
);
4697 bret
= RemoveDirectoryW(target_path
);
4698 ok(bret
, "Failed to delete junction point target!\n");
4699 bret
= CreateDirectoryW(target_path
, NULL
);
4700 ok(bret
, "Failed to create junction point target directory.\n");
4704 pRtlFreeUnicodeString( &nameW
);
4705 HeapFree(GetProcessHeap(), 0, buffer
);
4706 bret
= RemoveDirectoryW(junction_path
);
4707 ok(bret
, "Failed to remove temporary junction point directory!\n");
4708 bret
= RemoveDirectoryW(target_path
);
4709 ok(bret
, "Failed to remove temporary target directory!\n");
4710 RemoveDirectoryW(path
);
4715 HMODULE hkernel32
= GetModuleHandleA("kernel32.dll");
4716 HMODULE hntdll
= GetModuleHandleA("ntdll.dll");
4719 skip("not running on NT, skipping test\n");
4723 pGetVolumePathNameW
= (void *)GetProcAddress(hkernel32
, "GetVolumePathNameW");
4724 pGetSystemWow64DirectoryW
= (void *)GetProcAddress(hkernel32
, "GetSystemWow64DirectoryW");
4726 pRtlFreeUnicodeString
= (void *)GetProcAddress(hntdll
, "RtlFreeUnicodeString");
4727 pRtlInitUnicodeString
= (void *)GetProcAddress(hntdll
, "RtlInitUnicodeString");
4728 pRtlDosPathNameToNtPathName_U
= (void *)GetProcAddress(hntdll
, "RtlDosPathNameToNtPathName_U");
4729 pRtlWow64EnableFsRedirectionEx
= (void *)GetProcAddress(hntdll
, "RtlWow64EnableFsRedirectionEx");
4730 pNtCreateMailslotFile
= (void *)GetProcAddress(hntdll
, "NtCreateMailslotFile");
4731 pNtCreateFile
= (void *)GetProcAddress(hntdll
, "NtCreateFile");
4732 pNtOpenFile
= (void *)GetProcAddress(hntdll
, "NtOpenFile");
4733 pNtDeleteFile
= (void *)GetProcAddress(hntdll
, "NtDeleteFile");
4734 pNtReadFile
= (void *)GetProcAddress(hntdll
, "NtReadFile");
4735 pNtWriteFile
= (void *)GetProcAddress(hntdll
, "NtWriteFile");
4736 pNtCancelIoFile
= (void *)GetProcAddress(hntdll
, "NtCancelIoFile");
4737 pNtCancelIoFileEx
= (void *)GetProcAddress(hntdll
, "NtCancelIoFileEx");
4738 pNtClose
= (void *)GetProcAddress(hntdll
, "NtClose");
4739 pNtFsControlFile
= (void *)GetProcAddress(hntdll
, "NtFsControlFile");
4740 pNtCreateIoCompletion
= (void *)GetProcAddress(hntdll
, "NtCreateIoCompletion");
4741 pNtOpenIoCompletion
= (void *)GetProcAddress(hntdll
, "NtOpenIoCompletion");
4742 pNtQueryIoCompletion
= (void *)GetProcAddress(hntdll
, "NtQueryIoCompletion");
4743 pNtRemoveIoCompletion
= (void *)GetProcAddress(hntdll
, "NtRemoveIoCompletion");
4744 pNtSetIoCompletion
= (void *)GetProcAddress(hntdll
, "NtSetIoCompletion");
4745 pNtSetInformationFile
= (void *)GetProcAddress(hntdll
, "NtSetInformationFile");
4746 pNtQueryInformationFile
= (void *)GetProcAddress(hntdll
, "NtQueryInformationFile");
4747 pNtQueryDirectoryFile
= (void *)GetProcAddress(hntdll
, "NtQueryDirectoryFile");
4748 pNtQueryVolumeInformationFile
= (void *)GetProcAddress(hntdll
, "NtQueryVolumeInformationFile");
4749 pNtQueryFullAttributesFile
= (void *)GetProcAddress(hntdll
, "NtQueryFullAttributesFile");
4750 pNtFlushBuffersFile
= (void *)GetProcAddress(hntdll
, "NtFlushBuffersFile");
4751 pNtQueryEaFile
= (void *)GetProcAddress(hntdll
, "NtQueryEaFile");
4754 test_NtCreateFile();
4762 test_iocompletion();
4763 test_file_basic_information();
4764 test_file_all_information();
4765 test_file_both_information();
4766 test_file_name_information();
4767 test_file_full_size_information();
4768 test_file_all_name_information();
4769 test_file_rename_information();
4770 test_file_link_information();
4771 test_file_disposition_information();
4772 test_file_completion_information();
4773 test_file_id_information();
4774 test_file_access_information();
4775 test_query_volume_information_file();
4776 test_query_attribute_information_file();
4778 test_flush_buffers_file();
4780 test_junction_points();